1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-14 04:25:21 +02:00

Bug 395243. More efficient and robust storage of types and template

arguments.
This commit is contained in:
Sergey Prigogin 2012-12-26 17:27:02 -08:00
parent 8c7223be15
commit 6428f07759
22 changed files with 241 additions and 166 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2009, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Thomas Corbat
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -69,9 +70,18 @@ public interface ITypeMarshalBuffer {
ISerializableEvaluation unmarshalEvaluation() throws CoreException;
ICPPTemplateArgument unmarshalTemplateArgument() throws CoreException;
int getByte() throws CoreException;
int getShort() throws CoreException;
int getInt() throws CoreException;
long getLong() throws CoreException;
int getFixedInt() throws CoreException;
/**
* Reads a 32-bit integer stored in the variable length base-128 encoding.
*/
public int getInt() throws CoreException;
/**
* Reads a 64-bit integer stored in the variable length base-128 encoding.
*/
public long getLong() throws CoreException;
char[] getCharArray() throws CoreException;
void marshalType(IType type) throws CoreException;
@ -80,8 +90,53 @@ public interface ITypeMarshalBuffer {
void marshalEvaluation(ISerializableEvaluation eval, boolean includeValue) throws CoreException;
void marshalTemplateArgument(ICPPTemplateArgument arg) throws CoreException;
void putByte(byte data);
void putShort(short data);
void putInt(int data);
void putLong(long data);
void putFixedInt(int data);
/**
* Writes a 32-bit integer in the variable length base-128 encoding. Each byte, except the last
* byte, has the most significant bit set this indicates that there are further bytes to come.
* The lower 7 bits of each byte are used to store the two-complement representation of
* the number in groups of 7 bits, least significant group first.
*
* <p>Here is number of bytes depending on the encoded value:
* <pre>
* Value Number of bytes
* [0,127] 1
* [128,16383] 2
* [16384,2097151] 3
* [2097152,268435455] 4
* [268435456,Integer.MAX_VALUE] 5
* negative 5
* </pre>
*
* @param value the value to write
*/
public void putInt(int value);
/**
* Writes a 64-bit integer in the variable length base-128 encoding. Each byte, except the last
* byte, has the most significant bit set this indicates that there are further bytes to come.
* The lower 7 bits of each byte are used to store the two-complement representation of
* the number in groups of 7 bits, least significant group first.
*
* <p>Here is number of bytes depending on the encoded value:
* <pre>
* Value Number of bytes
* [0,127] 1
* [128,16383] 2
* [16384,2097151] 3
* [2097152,268435455] 4
* [268435456,2^35-1] 5
* [2^35,2^42-1] 6
* [2^42,2^49-1] 7
* [2^49,2^56-1] 8
* [2^56,2^63-1] 9
* negative 10
* </pre>
*
* @param value the value to write
*/
public void putLong(long value);
void putCharArray(char[] data);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2010, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -28,11 +29,11 @@ public class ProblemFunctionType extends ProblemType implements ICPPFunctionType
@Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
buffer.putByte((byte) (ITypeMarshalBuffer.PROBLEM_TYPE | ITypeMarshalBuffer.FLAG1));
buffer.putShort((short) getID());
buffer.putInt(getID());
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
return new ProblemFunctionType(buffer.getShort());
return new ProblemFunctionType(buffer.getInt());
}
@Override

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2010, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -56,13 +57,13 @@ public class ProblemType implements IProblemType, ISerializableType {
@Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.PROBLEM_TYPE);
buffer.putShort((short) getID());
buffer.putInt(getID());
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0)
return ProblemFunctionType.unmarshal(firstByte, buffer);
return new ProblemType(buffer.getShort());
return new ProblemType(buffer.getInt());
}
}

View file

@ -154,12 +154,12 @@ public class Value implements IValue {
Long num= numericalValue();
if (num != null) {
long lv= num;
if (lv >= Integer.MIN_VALUE && lv <= Integer.MAX_VALUE) {
if (lv >= 0) {
buf.putByte((byte) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG2));
buf.putInt((int) lv);
buf.putLong(lv);
} else {
buf.putByte((byte) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG3));
buf.putLong(lv);
buf.putLong(-lv);
}
} else if (fFixedValue != null) {
buf.putByte((byte) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG4));
@ -177,18 +177,13 @@ public class Value implements IValue {
return null;
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0)
return Value.UNKNOWN;
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
int val= buf.getInt();
return Value.create(val);
}
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
long val= buf.getLong();
return Value.create(val);
}
if ((firstByte & ITypeMarshalBuffer.FLAG4) != 0) {
char[] fixedValue = buf.getCharArray();
return new Value(fixedValue, null);
}
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0)
return Value.create(buf.getLong());
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0)
return Value.create(-buf.getLong());
if ((firstByte & ITypeMarshalBuffer.FLAG4) != 0)
return new Value(buf.getCharArray(), null);
ISerializableEvaluation eval= buf.unmarshalEvaluation();
if (eval instanceof ICPPEvaluation)
return new Value(null, (ICPPEvaluation) eval);

View file

@ -1,12 +1,13 @@
/*******************************************************************************
* Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
* Copyright (c) 2004, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Devin Steffler (IBM Corporation) - initial API and implementation
* Contributors:
* Devin Steffler (IBM Corporation) - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -161,7 +162,7 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.ARRAY_TYPE;
int flags= 0;
short nval= -1;
long nval= -1;
IValue val= null;
if (isConst()) flags |= 0x01;
@ -178,9 +179,8 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
firstByte |= ITypeMarshalBuffer.FLAG2;
Long num= val.numericalValue();
if (num != null) {
long l= num;
if (l >= 0 && l <= Short.MAX_VALUE) {
nval= (short) l;
nval= num;
if (nval >= 0) {
firstByte |= ITypeMarshalBuffer.FLAG3;
}
}
@ -190,7 +190,7 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
buffer.putByte((byte) flags);
}
if (nval >= 0) {
buffer.putShort(nval);
buffer.putLong(nval);
} else if (val != null) {
buffer.marshalValue(val);
}
@ -200,11 +200,11 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int flags= 0;
IValue value= null;
if ( (firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
flags= buffer.getByte();
}
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
value = Value.create(buffer.getShort());
value = Value.create(buffer.getLong());
} else if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
value = buffer.unmarshalValue();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors:
* Devin Steffler (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -87,7 +88,7 @@ public class CFunctionType implements IFunctionType, ISerializableType {
} else {
firstByte |= ITypeMarshalBuffer.FLAG4;
buffer.putByte((byte) firstByte);
buffer.putShort((short) len);
buffer.putInt(len);
}
buffer.marshalType(returnType);
@ -99,7 +100,7 @@ public class CFunctionType implements IFunctionType, ISerializableType {
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len;
if (((firstByte & ITypeMarshalBuffer.FLAG4) != 0)) {
len= buffer.getShort();
len= buffer.getInt();
} else {
len= (firstByte & (ITypeMarshalBuffer.FLAG4-1))/ITypeMarshalBuffer.FLAG1;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2010 IBM Corporation and others.
* Copyright (c) 2004, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -122,9 +123,9 @@ public class CPPArrayType implements IArrayType, ITypeContainer, ISerializableTy
Long num= val.numericalValue();
if (num != null) {
long lnum= num;
if (lnum >= 0 && lnum <= Short.MAX_VALUE) {
if (lnum >= 0) {
buffer.putByte((byte) (firstByte | ITypeMarshalBuffer.FLAG1));
buffer.putShort((short) lnum);
buffer.putLong(lnum);
buffer.marshalType(getType());
return;
}
@ -137,7 +138,7 @@ public class CPPArrayType implements IArrayType, ITypeContainer, ISerializableTy
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
IValue value= null;
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
value = Value.create(buffer.getShort());
value = Value.create(buffer.getLong());
} else if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
value = buffer.unmarshalValue();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2011 IBM Corporation and others.
* Copyright (c) 2005, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -230,15 +230,16 @@ public class CPPDeferredClassInstance extends CPPUnknownBinding implements ICPPD
int firstByte= ITypeMarshalBuffer.DEFERRED_CLASS_INSTANCE;
buffer.putByte((byte) firstByte);
buffer.marshalBinding(fClassTemplate);
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPTemplateArgument arg : fArguments) {
buffer.marshalTemplateArgument(arg);
}
}
public static ICPPDeferredClassInstance unmarshal(IIndexFragment fragment, int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
public static ICPPDeferredClassInstance unmarshal(IIndexFragment fragment, int firstByte,
ITypeMarshalBuffer buffer) throws CoreException {
IBinding template= buffer.unmarshalBinding();
int argcount= buffer.getShort() & 0xffff;
int argcount= buffer.getInt();
ICPPTemplateArgument[] args = new ICPPTemplateArgument[argcount];
for (int i = 0; i < argcount; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -140,29 +141,17 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType {
if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2;
if (takesVarArgs()) firstByte |= ITypeMarshalBuffer.FLAG3;
int len= (parameters.length & 0xffff);
if (len > 0xff) {
firstByte |= ITypeMarshalBuffer.FLAG4;
buffer.putByte((byte) firstByte);
buffer.putShort((short) len);
} else {
buffer.putByte((byte) firstByte);
buffer.putByte((byte) len);
}
buffer.putByte((byte) firstByte);
buffer.putInt(parameters.length);
buffer.marshalType(returnType);
for (int i = 0; i < len; i++) {
for (int i = 0; i < parameters.length; i++) {
buffer.marshalType(parameters[i]);
}
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len;
if (((firstByte & ITypeMarshalBuffer.FLAG4) != 0)) {
len= buffer.getShort();
} else {
len= buffer.getByte();
}
int len= buffer.getInt();
IType rt= buffer.unmarshalType();
IType[] pars= new IType[len];
for (int i = 0; i < pars.length; i++) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2010 Google, Inc and others.
* Copyright (c) 2008, 2012 Google, Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -86,7 +86,7 @@ public class CPPUnknownClassInstance extends CPPUnknownMemberClass implements IC
buffer.putByte((byte) firstByte);
buffer.marshalType(getOwnerType());
buffer.putCharArray(getNameCharArray());
buffer.putShort((short) arguments.length);
buffer.putInt(arguments.length);
for (ICPPTemplateArgument arg : arguments) {
buffer.marshalTemplateArgument(arg);
}
@ -95,7 +95,7 @@ public class CPPUnknownClassInstance extends CPPUnknownMemberClass implements IC
public static ICPPUnknownMemberClassInstance unmarshal(IIndexFragment fragment, int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
IType owner= buffer.unmarshalType();
char[] name = buffer.getCharArray();
int argcount= buffer.getShort() & 0xffff;
int argcount= buffer.getInt();
ICPPTemplateArgument[] args = new ICPPTemplateArgument[argcount];
for (int i = 0; i < argcount; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -126,7 +126,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
}
@Override
public void putShort(short value) {
public void putFixedInt(int value) {
appendSeparator();
fBuffer.append(value);
}
@ -192,7 +192,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
}
@Override
public int getShort() throws CoreException {
public int getFixedInt() throws CoreException {
throw new UnsupportedOperationException();
}

View file

@ -300,7 +300,7 @@ public class EvalBinding extends CPPEvaluation {
// function and the parameter position instead.
buffer.putByte((byte) (ITypeMarshalBuffer.EVAL_BINDING | ITypeMarshalBuffer.FLAG1));
buffer.marshalBinding(parameterOwner);
buffer.putShort((short) getFunctionParameterPosition());
buffer.putInt(getFunctionParameterPosition());
} else {
buffer.putByte(firstByte);
buffer.marshalBinding(fBinding);
@ -311,7 +311,7 @@ public class EvalBinding extends CPPEvaluation {
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
ICPPFunction parameterOwner= (ICPPFunction) buffer.unmarshalBinding();
int parameterPosition= buffer.getShort();
int parameterPosition= buffer.getInt();
IType type= buffer.unmarshalType();
return new EvalBinding(parameterOwner, parameterPosition, type);
} else {

View file

@ -155,14 +155,14 @@ public class EvalComma extends CPPEvaluation {
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_COMMA);
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPEvaluation arg : fArguments) {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
int len= buffer.getInt();
ICPPEvaluation[] args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -168,14 +168,14 @@ public class EvalFunctionCall extends CPPEvaluation {
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_FUNCTION_CALL);
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPEvaluation arg : fArguments) {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
int len= buffer.getInt();
ICPPEvaluation[] args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -110,12 +110,12 @@ public class EvalFunctionSet extends CPPEvaluation {
firstByte |= ITypeMarshalBuffer.FLAG2;
buffer.putByte((byte) firstByte);
buffer.putShort((short) bindings.length);
buffer.putInt(bindings.length);
for (ICPPFunction binding : bindings) {
buffer.marshalBinding(binding);
}
if (args != null) {
buffer.putShort((short) args.length);
buffer.putInt(args.length);
for (ICPPTemplateArgument arg : args) {
buffer.marshalTemplateArgument(arg);
}
@ -124,14 +124,14 @@ public class EvalFunctionSet extends CPPEvaluation {
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
final boolean addressOf= (firstByte & ITypeMarshalBuffer.FLAG1) != 0;
int bindingCount= buffer.getShort();
int bindingCount= buffer.getInt();
ICPPFunction[] bindings= new ICPPFunction[bindingCount];
for (int i = 0; i < bindings.length; i++) {
bindings[i]= (ICPPFunction) buffer.unmarshalBinding();
}
ICPPTemplateArgument[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
int len= buffer.getShort();
int len= buffer.getInt();
args = new ICPPTemplateArgument[len];
for (int i = 0; i < args.length; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -151,7 +151,7 @@ public class EvalID extends CPPEvaluation {
buffer.putCharArray(fName);
buffer.marshalBinding(fNameOwner);
if (fTemplateArgs != null) {
buffer.putShort((short) fTemplateArgs.length);
buffer.putInt(fTemplateArgs.length);
for (ICPPTemplateArgument arg : fTemplateArgs) {
buffer.marshalTemplateArgument(arg);
}
@ -166,7 +166,7 @@ public class EvalID extends CPPEvaluation {
IBinding nameOwner= buffer.unmarshalBinding();
ICPPTemplateArgument[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
int len= buffer.getShort();
int len= buffer.getInt();
args = new ICPPTemplateArgument[len];
for (int i = 0; i < args.length; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -87,14 +87,14 @@ public class EvalInitList extends CPPEvaluation {
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_INIT_LIST);
buffer.putShort((short) fClauses.length);
buffer.putInt(fClauses.length);
for (ICPPEvaluation arg : fClauses) {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
int len= buffer.getInt();
ICPPEvaluation[] args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -123,7 +123,7 @@ public class EvalTypeId extends CPPEvaluation {
buffer.putByte((byte) firstByte);
buffer.marshalType(fInputType);
if (includeValue) {
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPEvaluation arg : fArguments) {
buffer.marshalEvaluation(arg, includeValue);
}
@ -134,7 +134,7 @@ public class EvalTypeId extends CPPEvaluation {
IType type= buffer.unmarshalType();
ICPPEvaluation[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
int len= buffer.getShort();
int len= buffer.getInt();
args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -222,10 +222,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 128.0 - Preservation of typedefs in template arguments.
* 129.0 - Merged several changes affecting index from the master branch.
* 130.0 - Constexpr functions, bug 395238.
* 131.0 - More efficient and robust storage of types and template arguments, bug 395243.
*/
private static final int MIN_SUPPORTED_VERSION= version(130, 0);
private static final int MAX_SUPPORTED_VERSION= version(130, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(130, 0);
private static final int MIN_SUPPORTED_VERSION= version(131, 0);
private static final int MAX_SUPPORTED_VERSION= version(131, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(131, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;

View file

@ -76,6 +76,8 @@ public class Database {
public static final int MAX_BLOCK_DELTAS = CHUNK_SIZE / BLOCK_SIZE_DELTA;
public static final int MAX_MALLOC_SIZE = MAX_BLOCK_DELTAS * BLOCK_SIZE_DELTA - BLOCK_HEADER_SIZE;
public static final int PTR_SIZE = 4; // size of a pointer in the database in bytes
// The lower bound for TYPE_SIZE is 1 + PTR_SIZE, but a slightly larger space for types stored
// inline produces in a slightly smaller overall database size.
public static final int TYPE_SIZE = 2 + PTR_SIZE; // size of a type in the database in bytes
public static final int VALUE_SIZE = TYPE_SIZE; // size of a value in the database in bytes
public static final int EVALUATION_SIZE = TYPE_SIZE; // size of an evaluation in the database in bytes

View file

@ -33,7 +33,7 @@ import org.eclipse.core.runtime.CoreException;
/**
* For marshalling types to byte arrays.
*/
public class TypeMarshalBuffer implements ITypeMarshalBuffer {
public final class TypeMarshalBuffer implements ITypeMarshalBuffer {
public static final byte[] EMPTY= { 0, 0, 0, 0, 0, 0 };
public static final byte NULL_TYPE= 0;
public static final byte INDIRECT_TYPE= (byte) -1;
@ -69,6 +69,11 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
return fPos;
}
public void setPosition(int pos) {
assert 0 <= pos && pos <= fPos;
fPos = pos;
}
public byte[] getBuffer() {
return fBuffer;
}
@ -257,23 +262,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
}
@Override
public void putShort(short value) {
request(2);
fBuffer[fPos++]= (byte) (value >> 8);
fBuffer[fPos++]= (byte) (value);
}
@Override
public int getShort() throws CoreException {
if (fPos + 2 > fBuffer.length)
throw unmarshallingError();
final int byte1 = 0xff & fBuffer[fPos++];
final int byte2 = 0xff & fBuffer[fPos++];
return (((byte1 << 8) | (byte2 & 0xff)));
}
@Override
public void putInt(int value) {
public void putFixedInt(int value) {
request(4);
fPos += 4;
int p= fPos;
@ -284,7 +273,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
}
@Override
public int getInt() throws CoreException {
public int getFixedInt() throws CoreException {
if (fPos + 4 > fBuffer.length)
throw unmarshallingError();
int result= 0;
@ -295,35 +284,48 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
return result;
}
@Override
public void putInt(int value) {
do {
int b = value & 0x7F;
value >>>= 7;
if (value != 0)
b |= 0x80;
putByte((byte) b);
} while (value != 0);
}
@Override
public void putLong(long value) {
request(8);
fPos += 8;
int p= fPos;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value);
do {
int b = (int) value & 0x7F;
value >>>= 7;
if (value != 0)
b |= 0x80;
putByte((byte) b);
} while (value != 0);
}
@Override
public int getInt() throws CoreException {
int b = getByte();
int value = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = getByte();
value |= (b & 0x7F) << shift;
}
return value;
}
@Override
public long getLong() throws CoreException {
if (fPos + 8 > fBuffer.length)
throw unmarshallingError();
long result= 0;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff;
return result;
int b = getByte();
long value = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = getByte();
value |= (b & 0x7F) << shift;
}
return value;
}
private void putRecordPointer(long record) {
@ -344,19 +346,19 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
@Override
public void putCharArray(char[] chars) {
putShort((short) chars.length);
putInt(chars.length);
for (char c : chars) {
putShort((short) c);
putInt(c & 0xFFFF);
}
}
@Override
public char[] getCharArray() throws CoreException {
int len= getShort();
char[] expr= new char[len];
for (int i = 0; i < expr.length; i++) {
expr[i]= (char) getShort();
int len= getInt();
char[] chars= new char[len];
for (int i = 0; i < chars.length; i++) {
chars[i]= (char) getInt();
}
return expr;
return chars;
}
}

View file

@ -60,7 +60,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
* link time. These are generally global symbols specific to a given language.
*/
public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage, IIndexBindingConstants {
// record offsets
// Record offsets.
private static final int ID_OFFSET = PDOMNamedNode.RECORD_SIZE + 0;
private static final int NEXT_OFFSET = PDOMNamedNode.RECORD_SIZE + 4;
private static final int INDEX_OFFSET = PDOMNamedNode.RECORD_SIZE + 8;
@ -71,7 +71,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
protected static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 20;
protected static final long[] FILE_LOCAL_REC_DUMMY = new long[]{0};
// node types
// Node types
protected static final int LINKAGE= 0; // special one for myself
private BTree fMacroIndex= null; // No need for volatile, all fields of BTree are final.
@ -447,12 +447,14 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
if (len > 0) {
if (len <= maxInlineSize) {
db.putBytes(offset, buf.getBuffer(), len);
} else {
} else {
db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE);
long chainOffset = offset + 1;
buf.putInt(len);
int lenSize = buf.getPosition() - len;
int bufferPos = 0;
while (bufferPos < len) {
int chunkLength = len - bufferPos + 2;
int chunkLength = bufferPos == 0 ? len + lenSize : len - bufferPos;
boolean chainingRequired = false;
if (chunkLength > Database.MAX_MALLOC_SIZE) {
chunkLength = Database.MAX_MALLOC_SIZE;
@ -460,36 +462,52 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
}
long ptr = db.malloc(chunkLength);
db.putRecPtr(chainOffset, ptr);
db.putShort(ptr, (short) len);
int pos = 2;
if (bufferPos == 0) {
// Write length.
db.putBytes(ptr, buf.getBuffer(), len, lenSize);
ptr += lenSize;
chunkLength -= lenSize;
}
if (chainingRequired) {
// Reserve space for the chaining pointer.
chainOffset = ptr + 2; pos += Database.PTR_SIZE;
chainOffset = ptr;
ptr += Database.PTR_SIZE;
chunkLength -= Database.PTR_SIZE;
}
chunkLength -= pos;
db.putBytes(ptr + pos, buf.getBuffer(), bufferPos, chunkLength);
db.putBytes(ptr, buf.getBuffer(), bufferPos, chunkLength);
bufferPos += chunkLength;
}
buf.setPosition(len); // Restore buffer position.
}
}
}
private byte[] loadLinkedSerializedData(final Database db, long offset) throws CoreException {
long ptr= db.getRecPtr(offset);
int len= db.getShort(ptr) & 0xffff;
// Read the length in variable-length base-128 encoding, see ITypeMarshalBuffer.putInt(int).
int pos = 0;
int b = db.getByte(ptr + pos++);
int len = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = db.getByte(ptr + pos++);
len |= (b & 0x7F) << shift;
}
byte[] data= new byte[len];
int bufferPos = 0;
while (bufferPos < len) {
int chunkLength = len - bufferPos + 2;
int pos = 2;
long chunkPtr = ptr;
int chunkLength = len + pos - bufferPos;
long chunkPtr = ptr + pos;
if (chunkLength > Database.MAX_MALLOC_SIZE) {
chunkLength = Database.MAX_MALLOC_SIZE;
ptr= db.getRecPtr(chunkPtr + pos); pos += Database.PTR_SIZE;
ptr= db.getRecPtr(chunkPtr);
chunkPtr += Database.PTR_SIZE;
chunkLength -= Database.PTR_SIZE;
}
chunkLength -= pos;
db.getBytes(chunkPtr + pos, data, bufferPos, chunkLength);
chunkLength -= pos;
db.getBytes(chunkPtr, data, bufferPos, chunkLength);
bufferPos += chunkLength;
pos = 0;
}
return data;
}
@ -497,18 +515,26 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
private void deleteSerializedData(Database db, long offset, int maxInlineSize) throws CoreException {
byte firstByte= db.getByte(offset);
if (firstByte == TypeMarshalBuffer.INDIRECT_TYPE) {
long ptr= db.getRecPtr(offset + 1);
int len= db.getShort(ptr) & 0xffff;
long chunkPtr= db.getRecPtr(offset + 1);
long ptr = chunkPtr;
// Read the length in variable-length base-128 encoding, see ITypeMarshalBuffer.putInt(int).
int b = db.getByte(ptr++);
int len = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = db.getByte(ptr++);
len |= (b & 0x7F) << shift;
}
len += ptr - chunkPtr;
while (len > 0) {
int chunkLength = len + 2;
int pos = 2;
long chunkPtr = ptr;
int chunkLength = len;
if (chunkLength > Database.MAX_MALLOC_SIZE) {
chunkLength = Database.MAX_MALLOC_SIZE;
ptr= db.getRecPtr(chunkPtr + pos); pos += Database.PTR_SIZE;
ptr= db.getRecPtr(ptr);
chunkLength -= Database.PTR_SIZE;
}
chunkLength -= pos;
db.free(chunkPtr);
chunkPtr = ptr;
len -= chunkLength;
}
}