Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Prigogin2012-11-08 18:52:22 +0000
committerSergey Prigogin2012-11-08 21:34:31 +0000
commit62172624543e782b437489f1f2c797be2e318f9e (patch)
tree4b1aaf9e2af70fdcb7017d199ee63e18b81492a1
parent9016a57d56dee959e2dd3ea11e2d8dfadde71ce2 (diff)
downloadorg.eclipse.cdt-62172624543e782b437489f1f2c797be2e318f9e.tar.gz
org.eclipse.cdt-62172624543e782b437489f1f2c797be2e318f9e.tar.xz
org.eclipse.cdt-62172624543e782b437489f1f2c797be2e318f9e.zip
Bug 393513. Fixed serialization of very large types and template
arguments.
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java24
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java186
4 files changed, 112 insertions, 116 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index e7377606f53..30ba6a2ac00 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -226,10 +226,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 134.0 - Storing unknown bindings via direct marshalling, bug 381824.
* 135.0 - Changed marshalling of EvalUnary, bug 391001.
* 136.0 - Extended CPPTemplateTypeArgument to include the original type, bug 392278.
+ * 137.0 - Fixed serialization of very large types and template arguments, bug 392278.
*/
- private static final int MIN_SUPPORTED_VERSION= version(136, 0);
- private static final int MAX_SUPPORTED_VERSION= version(136, Short.MAX_VALUE);
- private static final int DEFAULT_VERSION = version(136, 0);
+ private static final int MIN_SUPPORTED_VERSION= version(137, 0);
+ private static final int MAX_SUPPORTED_VERSION= version(137, Short.MAX_VALUE);
+ private static final int DEFAULT_VERSION = version(137, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
index d4342da6751..a7d5e4ea432 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2009 QNX Software Systems and others.
+ * Copyright (c) 2005, 2012 QNX Software Systems 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
@@ -9,6 +9,7 @@
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
* IBM Corporation
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.db;
@@ -301,21 +302,22 @@ final class Chunk {
}
void put(final long offset, final byte[] data, final int len) {
+ put(offset, data, 0, len);
+ }
+
+ void put(final long offset, final byte[] data, int dataPos, final int len) {
assert fLocked;
- fDirty= true;
+ fDirty = true;
int idx = recPtrToIndex(offset);
- int i= 0;
- while (i < len) {
- fBuffer[idx++]= data[i++];
- }
+ System.arraycopy(data, dataPos, fBuffer, idx, len);
}
public void get(final long offset, byte[] data) {
+ get(offset, data, 0, data.length);
+ }
+
+ public void get(final long offset, byte[] data, int dataPos, int len) {
int idx = recPtrToIndex(offset);
- final int end= idx + data.length;
- int i= 0;
- while (idx < end) {
- data[i++]= fBuffer[idx++];
- }
+ System.arraycopy(fBuffer, idx, data, dataPos, len);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
index 3f7274ce4bb..8743d8b266b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2010 QNX Software Systems and others.
+ * Copyright (c) 2005, 2012 QNX Software Systems 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
@@ -10,6 +10,7 @@
* Symbian - Add some non-javadoc implementation notes
* Markus Schorn (Wind River Systems)
* IBM Corporation
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.db;
@@ -530,10 +531,18 @@ public class Database {
getChunk(offset).put(offset, data, len);
}
+ public void putBytes(long offset, byte[] data, int dataPos, int len) throws CoreException {
+ getChunk(offset).put(offset, data, dataPos, len);
+ }
+
public void getBytes(long offset, byte[] data) throws CoreException {
getChunk(offset).get(offset, data);
}
+ public void getBytes(long offset, byte[] data, int dataPos, int len) throws CoreException {
+ getChunk(offset).get(offset, data, dataPos, len);
+ }
+
public IString newString(String string) throws CoreException {
return newString(string.toCharArray());
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
index ef857541949..2bdfc076faf 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
@@ -11,6 +11,7 @@
* IBM Corporation
* Andrew Ferguson (Symbian)
* Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
@@ -168,7 +169,6 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
}
}
-
@Override
public void addChild(PDOMNode child) throws CoreException {
getIndex().insert(child.getRecord());
@@ -438,46 +438,94 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
if (type != null) {
TypeMarshalBuffer bc= new TypeMarshalBuffer(this);
bc.marshalType(type);
- int len= bc.getPosition();
- if (len > 0) {
- if (len <= Database.TYPE_SIZE) {
- db.putBytes(offset, bc.getBuffer(), len);
- } else if (len <= Database.MAX_MALLOC_SIZE-2){
- long ptr= db.malloc(len+2);
+ storeBuffer(db, offset, bc, Database.TYPE_SIZE);
+ }
+ }
+
+ private void storeBuffer(Database db, long offset, TypeMarshalBuffer buf, int maxInlineSize) throws CoreException {
+ int len= buf.getPosition();
+ if (len > 0) {
+ if (len <= maxInlineSize) {
+ db.putBytes(offset, buf.getBuffer(), len);
+ } else {
+ db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE);
+ long chainOffset = offset + 1;
+ int bufferPos = 0;
+ while (bufferPos < len) {
+ int chunkLength = len - bufferPos + 2;
+ boolean chainingRequired = false;
+ if (chunkLength > Database.MAX_MALLOC_SIZE) {
+ chunkLength = Database.MAX_MALLOC_SIZE;
+ chainingRequired = true;
+ }
+ long ptr = db.malloc(chunkLength);
+ db.putRecPtr(chainOffset, ptr);
db.putShort(ptr, (short) len);
- db.putBytes(ptr+2, bc.getBuffer(), len);
- db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE);
- db.putRecPtr(offset+2, ptr);
+ int pos = 2;
+ if (chainingRequired) {
+ // Reserve space for the chaining pointer.
+ chainOffset = ptr + 2; pos += Database.PTR_SIZE;
+ }
+ chunkLength -= pos;
+ db.putBytes(ptr + pos, buf.getBuffer(), bufferPos, chunkLength);
+ bufferPos += chunkLength;
}
}
}
}
- private void deleteType(Database db, long offset) throws CoreException {
+ private byte[] loadLinkedSerializedData(final Database db, long offset) throws CoreException {
+ long ptr= db.getRecPtr(offset);
+ int len= db.getShort(ptr) & 0xffff;
+ byte[] data= new byte[len];
+ int bufferPos = 0;
+ while (bufferPos < len) {
+ int chunkLength = len - bufferPos + 2;
+ int pos = 2;
+ long chunkPtr = ptr;
+ if (chunkLength > Database.MAX_MALLOC_SIZE) {
+ chunkLength = Database.MAX_MALLOC_SIZE;
+ ptr= db.getRecPtr(chunkPtr + pos); pos += Database.PTR_SIZE;
+ }
+ chunkLength -= pos;
+ db.getBytes(chunkPtr + pos, data, bufferPos, chunkLength);
+ bufferPos += chunkLength;
+ }
+ return data;
+ }
+
+ 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+2);
- clearType(db, offset);
- db.free(ptr);
- } else {
- clearType(db, offset);
+ long ptr= db.getRecPtr(offset + 1);
+ int len= db.getShort(ptr) & 0xffff;
+ while (len > 0) {
+ int chunkLength = len + 2;
+ int pos = 2;
+ long chunkPtr = ptr;
+ if (chunkLength > Database.MAX_MALLOC_SIZE) {
+ chunkLength = Database.MAX_MALLOC_SIZE;
+ ptr= db.getRecPtr(chunkPtr + pos); pos += Database.PTR_SIZE;
+ }
+ chunkLength -= pos;
+ db.free(chunkPtr);
+ len -= chunkLength;
+ }
}
+ db.clearBytes(offset, maxInlineSize);
}
- private void clearType(Database db, long offset) throws CoreException {
- db.clearBytes(offset, Database.TYPE_SIZE);
+ private void deleteType(Database db, long offset) throws CoreException {
+ deleteSerializedData(db, offset, Database.TYPE_SIZE);
}
public IType loadType(long offset) throws CoreException {
final Database db= getDB();
final byte firstByte= db.getByte(offset);
byte[] data= null;
- switch(firstByte) {
+ switch (firstByte) {
case TypeMarshalBuffer.INDIRECT_TYPE:
- long ptr= db.getRecPtr(offset+2);
- int len= db.getShort(ptr) & 0xffff;
- data= new byte[len];
- db.getBytes(ptr+2, data);
+ data = loadLinkedSerializedData(db, offset + 1);
break;
case TypeMarshalBuffer.UNSTORABLE_TYPE:
return TypeMarshalBuffer.UNSTORABLE_TYPE_PROBLEM;
@@ -501,46 +549,21 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
if (binding != null) {
TypeMarshalBuffer bc= new TypeMarshalBuffer(this);
bc.marshalBinding(binding);
- int len= bc.getPosition();
- if (len > 0) {
- if (len <= Database.TYPE_SIZE) {
- db.putBytes(offset, bc.getBuffer(), len);
- } else if (len <= Database.MAX_MALLOC_SIZE-2){
- long ptr= db.malloc(len+2);
- db.putShort(ptr, (short) len);
- db.putBytes(ptr+2, bc.getBuffer(), len);
- db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE);
- db.putRecPtr(offset+2, ptr);
- }
- }
+ storeBuffer(db, offset, bc, Database.TYPE_SIZE);
}
}
private void deleteBinding(Database db, long offset) throws CoreException {
- byte firstByte= db.getByte(offset);
- if (firstByte == TypeMarshalBuffer.INDIRECT_TYPE) {
- long ptr= db.getRecPtr(offset+2);
- clearBinding(db, offset);
- db.free(ptr);
- } else {
- clearBinding(db, offset);
- }
- }
-
- private void clearBinding(Database db, long offset) throws CoreException {
- db.clearBytes(offset, Database.TYPE_SIZE);
+ deleteSerializedData(db, offset, Database.TYPE_SIZE);
}
public IBinding loadBinding(long offset) throws CoreException {
final Database db= getDB();
final byte firstByte= db.getByte(offset);
byte[] data= null;
- switch(firstByte) {
+ switch (firstByte) {
case TypeMarshalBuffer.INDIRECT_TYPE:
- long ptr= db.getRecPtr(offset+2);
- int len= db.getShort(ptr) & 0xffff;
- data= new byte[len];
- db.getBytes(ptr+2, data);
+ data = loadLinkedSerializedData(db, offset + 1);
break;
case TypeMarshalBuffer.UNSTORABLE_TYPE:
return new ProblemBinding(null, ISemanticProblem.TYPE_NOT_PERSISTED);
@@ -564,52 +587,27 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
if (arg != null) {
TypeMarshalBuffer bc= new TypeMarshalBuffer(this);
bc.marshalTemplateArgument(arg);
- int len= bc.getPosition();
- if (len > 0) {
- if (len <= Database.ARGUMENT_SIZE) {
- db.putBytes(offset, bc.getBuffer(), len);
- } else if (len <= Database.MAX_MALLOC_SIZE-2){
- long ptr= db.malloc(len+2);
- db.putShort(ptr, (short) len);
- db.putBytes(ptr+2, bc.getBuffer(), len);
- db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE);
- db.putRecPtr(offset+2, ptr);
- }
- }
+ storeBuffer(db, offset, bc, Database.ARGUMENT_SIZE);
}
}
private void deleteArgument(Database db, long offset) throws CoreException {
- byte firstByte= db.getByte(offset);
- if (firstByte == TypeMarshalBuffer.INDIRECT_TYPE) {
- long ptr= db.getRecPtr(offset+2);
- clearArgument(db, offset);
- db.free(ptr);
- } else {
- clearArgument(db, offset);
- }
- }
-
- private void clearArgument(Database db, long offset) throws CoreException {
- db.clearBytes(offset, Database.ARGUMENT_SIZE);
+ deleteSerializedData(db, offset, Database.ARGUMENT_SIZE);
}
public ICPPTemplateArgument loadTemplateArgument(long offset) throws CoreException {
final Database db= getDB();
final byte firstByte= db.getByte(offset);
byte[] data= null;
- switch(firstByte) {
+ switch (firstByte) {
case TypeMarshalBuffer.INDIRECT_TYPE:
- long ptr= db.getRecPtr(offset+2);
- int len= db.getShort(ptr) & 0xffff;
- data= new byte[len];
- db.getBytes(ptr+2, data);
+ data = loadLinkedSerializedData(db, offset + 1);
break;
case TypeMarshalBuffer.UNSTORABLE_TYPE:
case TypeMarshalBuffer.NULL_TYPE:
return null;
default:
- data= new byte[Database.TYPE_SIZE];
+ data= new byte[Database.ARGUMENT_SIZE];
db.getBytes(offset, data);
break;
}
@@ -626,40 +624,26 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
if (value != null) {
TypeMarshalBuffer bc= new TypeMarshalBuffer(this);
bc.marshalValue(value);
- int len= bc.getPosition();
- if (len > 0) {
- if (len <= Database.TYPE_SIZE) {
- db.putBytes(offset, bc.getBuffer(), len);
- } else if (len <= Database.MAX_MALLOC_SIZE-2){
- long ptr= db.malloc(len+2);
- db.putShort(ptr, (short) len);
- db.putBytes(ptr+2, bc.getBuffer(), len);
- db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE);
- db.putRecPtr(offset+2, ptr);
- }
- }
+ storeBuffer(db, offset, bc, Database.VALUE_SIZE);
}
}
private void deleteValue(Database db, long offset) throws CoreException {
- deleteType(db, offset);
+ deleteSerializedData(db, offset, Database.VALUE_SIZE);
}
public IValue loadValue(long offset) throws CoreException {
final Database db= getDB();
final byte firstByte= db.getByte(offset);
byte[] data= null;
- switch(firstByte) {
+ switch (firstByte) {
case TypeMarshalBuffer.INDIRECT_TYPE:
- long ptr= db.getRecPtr(offset+2);
- int len= db.getShort(ptr) & 0xffff;
- data= new byte[len];
- db.getBytes(ptr+2, data);
+ data = loadLinkedSerializedData(db, offset + 1);
break;
case TypeMarshalBuffer.NULL_TYPE:
return null;
default:
- data= new byte[Database.TYPE_SIZE];
+ data= new byte[Database.VALUE_SIZE];
db.getBytes(offset, data);
break;
}

Back to the top