From 2372381692de55375b98f353b2458753ff0ff29a Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Fri, 9 Jun 2006 00:59:42 +0000 Subject: [PATCH] Bug 145415 - Made sure we deleted all the info associated with the macro, not just the macro. Also found latent bugs like BTree records not allocating enough memory for themselves (hidden by the block size), and goofy behavior when the PDOM was cleared which I'm sure lead to the truncated chunks not getting reused in certain situations. --- .../eclipse/cdt/internal/core/pdom/PDOM.java | 7 ++- .../cdt/internal/core/pdom/db/BTree.java | 2 +- .../cdt/internal/core/pdom/db/Database.java | 61 +++++++++++-------- .../cdt/internal/core/pdom/db/IString.java | 1 + .../cdt/internal/core/pdom/db/LongString.java | 17 ++++++ .../internal/core/pdom/db/ShortString.java | 6 +- .../cdt/internal/core/pdom/dom/PDOMMacro.java | 5 ++ .../core/pdom/dom/PDOMMacroParameter.java | 8 +++ .../ui/indexview/CountNodeAction.java | 1 + 9 files changed, 81 insertions(+), 27 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 81f3e4a23b7..e91741d33b3 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 @@ -165,9 +165,14 @@ public class PDOM extends PlatformObject public void clear() throws CoreException { Database db = getDB(); + // Clear out the database db.clear(); - db.setVersion(VERSION); + + // Zero out the File Index and Linkages + db.putInt(FILE_INDEX, 0); fileIndex = null; + + db.putInt(LINKAGES, 0); linkageCache.clear(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java index efdfafcb0b0..3782cb691eb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java @@ -173,7 +173,7 @@ public class BTree { } private int allocateNode() throws CoreException { - return db.malloc((2 * NUM_RECORDS - 1) * Database.INT_SIZE); + return db.malloc((2 * NUM_RECORDS + 1) * Database.INT_SIZE); } /** 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 9b0b1d3c9b9..b2aa55a4b0d 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 @@ -27,6 +27,9 @@ public class Database { private final RandomAccessFile file; Chunk[] toc; + private long malloced; + private long freed; + // public for tests only, you shouldn't need these public static final int VERSION_OFFSET = 0; public static final int CHUNK_SIZE = 1024 * 16; @@ -46,31 +49,18 @@ public class Database { // Allocate chunk table, make sure we have at least one long nChunks = file.length() / CHUNK_SIZE; if (nChunks == 0) { - create(); + file.seek(0); + file.write(new byte[CHUNK_SIZE]); // the header chunk ++nChunks; } toc = new Chunk[(int)nChunks]; - init(); + toc[0] = new Chunk(file, 0); } catch (IOException e) { throw new CoreException(new DBStatus(e)); } } - private void create() throws CoreException { - try { - file.seek(0); - file.write(new byte[CHUNK_SIZE]); // the header chunk - } catch (IOException e) { - throw new CoreException(new DBStatus(e)); - } - } - - private void init() throws CoreException { - // Load in the magic chunk zero - toc[0] = new Chunk(file, 0); - } - public int getVersion() { return toc[0].getInt(0); } @@ -84,11 +74,13 @@ public class Database { * @throws CoreException */ public void clear() throws CoreException { - int version = toc[0].getInt(0); - create(); - toc = new Chunk[1]; - init(); - setVersion(version); + // Clear out the memory headers + toc[0].clear(4, DATA_AREA - 4); + // Add the remainder of the chunks backwards + for (int block = (toc.length - 1) * CHUNK_SIZE; block > 0; block -= CHUNK_SIZE) { + addBlock(getChunk(block), CHUNK_SIZE, block); + } + malloced = freed = 0; } /** @@ -153,8 +145,12 @@ public class Database { // Make our size negative to show in use chunk.putInt(freeblock, - matchsize); - - return freeblock + INT_SIZE; + + // Clear out the block, lots of people are expecting this + chunk.clear(freeblock + 4, size); + + malloced += matchsize; + return freeblock + 4; } private int createChunk() throws CoreException { @@ -219,8 +215,8 @@ public class Database { if (blocksize < 0) // already freed throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, 0, "Already Freed", new Exception())); - chunk.clear(offset, blocksize - 4); addBlock(chunk, blocksize, block); + freed += blocksize; } public void putByte(int offset, byte value) throws CoreException { @@ -279,4 +275,21 @@ public class Database { return toc.length; } + public void reportFreeBlocks() throws CoreException { + System.out.println("Allocated size: " + toc.length * CHUNK_SIZE); + System.out.println("malloc'ed: " + malloced); + System.out.println("free'd: " + freed); + System.out.println("wasted: " + (toc.length * CHUNK_SIZE - (malloced - freed))); + System.out.println("Free blocks"); + for (int bs = MIN_SIZE; bs <= CHUNK_SIZE; bs += MIN_SIZE) { + int count = 0; + int block = getFirstBlock(bs); + while (block != 0) { + ++count; + block = getInt(block + NEXT_OFFSET); + } + if (count != 0) + System.out.println("Block size: " + bs + "=" + count); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IString.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IString.java index c0d5eab0759..f799766b37a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IString.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IString.java @@ -32,4 +32,5 @@ public interface IString { public char[] getChars() throws CoreException; public String getString() throws CoreException; + public void delete() throws CoreException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/LongString.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/LongString.java index 351686e9b25..83639841960 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/LongString.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/LongString.java @@ -103,6 +103,23 @@ public class LongString implements IString { return record1; } + public void delete() throws CoreException { + int length = db.getInt(record1 + LENGTH) - NUM_CHARS1; + int nextRecord = db.getInt(record1 + NEXT1); + db.free(record1); + + // Middle records + while (length > NUM_CHARSN) { + length -= NUM_CHARSN; + int nextnext = db.getInt(nextRecord + NEXTN); + db.free(nextRecord); + nextRecord = nextnext; + } + + // Last record + db.free(nextRecord); + } + public boolean equals(Object obj) { throw new PDOMNotImplementedError(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ShortString.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ShortString.java index 609c87dea58..5db3afcf76d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ShortString.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ShortString.java @@ -53,7 +53,7 @@ public class ShortString implements IString { this.record = db.malloc(CHARS + string.length() * 2); Chunk chunk = db.getChunk(record); - chunk.putInt(record + LENGTH, (char)string.length()); + chunk.putInt(record + LENGTH, string.length()); int n = string.length(); int p = record + CHARS; for (int i = 0; i < n; ++i) { @@ -66,6 +66,10 @@ public class ShortString implements IString { return record; } + public void delete() throws CoreException { + db.free(record); + } + public char[] getChars() throws CoreException { Chunk chunk = db.getChunk(record); int length = chunk.getInt(record + LENGTH); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java index 1b8568870b3..be2f2c54891 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java @@ -77,6 +77,11 @@ public class PDOMMacro { } public void delete() throws CoreException { + getName().delete(); + getExpansion().delete(); + PDOMMacroParameter param = getFirstParameter(); + if (param != null) + param.delete(); pdom.getDB().free(record); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroParameter.java index be11d3396c8..fd2df21eb6a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroParameter.java @@ -49,6 +49,14 @@ public class PDOMMacroParameter { return record; } + public void delete() throws CoreException { + PDOMMacroParameter next = getNextParameter(); + if (next != null) + next.delete(); + getName().delete(); + pdom.getDB().free(record); + } + public void setNextParameter(PDOMMacroParameter next) throws CoreException { int rec = next != null ? next.getRecord() : 0; pdom.getDB().putInt(record + NEXT, rec); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java index 30db548f342..f445f39b339 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java @@ -63,6 +63,7 @@ public class CountNodeAction extends IndexAction { ICProject project = (ICProject)objs[i]; final PDOM pdom = (PDOM)CCorePlugin.getPDOMManager().getPDOM(project); + //pdom.getDB().reportFreeBlocks(); pdom.getFileIndex().accept(new IBTreeVisitor() { public int compare(int record) throws CoreException {