Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Unified Diff: third_party/jmake/src/org/pantsbuild/jmake/BinaryProjectDatabaseWriter.java

Issue 1373723003: Fix javac --incremental by using jmake for dependency analysis (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@aidl
Patch Set: fix license check Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/jmake/src/org/pantsbuild/jmake/BinaryProjectDatabaseWriter.java
diff --git a/third_party/jmake/src/org/pantsbuild/jmake/BinaryProjectDatabaseWriter.java b/third_party/jmake/src/org/pantsbuild/jmake/BinaryProjectDatabaseWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..fafaa39815390366f052268c37a67a7f062abc9f
--- /dev/null
+++ b/third_party/jmake/src/org/pantsbuild/jmake/BinaryProjectDatabaseWriter.java
@@ -0,0 +1,363 @@
+/* Copyright (c) 2002-2008 Sun Microsystems, Inc. All rights reserved
+ *
+ * This program is distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+package org.pantsbuild.jmake;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * This class implements writing into a byte array representing a project database
+ *
+ * @author Misha Dmitriev
+ * 2 March 2005
+ */
+public class BinaryProjectDatabaseWriter extends BinaryFileWriter {
+
+ private Map<String, PCDEntry> pcd = null;
+ private int nOfEntries;
+ private byte[] stringBuf;
+ private int curStringBufPos, stringBufInc, curStringBufWatermark, stringCount;
+ private StringHashTable stringHashTable = null;
+
+ public void writeProjectDatabaseToFile(File outfile, Map<String, PCDEntry> pcd) {
+ try {
+ byte[] buf = new BinaryProjectDatabaseWriter().writeProjectDatabase(pcd);
+ FileOutputStream out = new FileOutputStream(outfile);
+ out.write(buf);
+ out.close();
+ } catch (IOException e) {
+ throw new PrivateException(e);
+ }
+ }
+
+ public byte[] writeProjectDatabase(Map<String, PCDEntry> pcd) {
+ this.pcd = pcd;
+ nOfEntries = pcd.size();
+
+ // So far the constant here is chosen rather arbitrarily
+ initBuf(nOfEntries * 1000);
+
+ stringBuf = new byte[nOfEntries * 300];
+ stringBufInc = stringBuf.length / 5;
+ curStringBufWatermark = stringBuf.length - 20;
+ stringHashTable = new StringHashTable(stringBuf.length / 8);
+
+ for (PCDEntry entry : pcd.values()) {
+ writePCDEntry(entry);
+ }
+
+ // Now we have the string buffer and the main buffer. Write the end result
+ byte[] mainBuf = buf;
+ int mainBufSize = curBufPos;
+ int preambleSize = Utils.MAGIC.length + 8;
+ int stringBufSize = curStringBufPos;
+ int pdbSize = stringBufSize + mainBufSize + 8; // 8 is for nOfEntries and string table size
+ initBuf(preambleSize + pdbSize);
+ setBufferIncreaseMode(false);
+
+ writePreamble(pdbSize);
+ writeStringTable(stringBufSize);
+ System.arraycopy(mainBuf, 0, buf, curBufPos, mainBufSize);
+ return buf;
+ }
+
+ private void writePreamble(int pdbSize) {
+ System.arraycopy(Utils.MAGIC, 0, buf, 0, Utils.MAGIC.length);
+ curBufPos += Utils.MAGIC.length;
+
+ writeInt(Utils.PDB_FORMAT_CODE_LATEST); // Version number
+ writeInt(pdbSize);
+ writeInt(pcd.size());
+ }
+
+ private void writeStringTable(int stringBufSize) {
+ writeInt(stringCount);
+ System.arraycopy(stringBuf, 0, buf, curBufPos, stringBufSize);
+ curBufPos += stringBufSize;
+ }
+
+ private void writePCDEntry(PCDEntry entry) {
+ writeStringRef(entry.className);
+ writeStringRef(entry.javaFileFullPath);
+ writeLong(entry.oldClassFileLastModified);
+ writeLong(entry.oldClassFileFingerprint);
+ writeClassInfo(entry.oldClassInfo);
+ }
+
+ private void writeClassInfo(ClassInfo ci) {
+ int i, j, len;
+
+ writeStringRef(ci.name);
+ writeInt(ci.javacTargetRelease);
+
+ len = ci.cpoolRefsToClasses != null ? ci.cpoolRefsToClasses.length : 0;
+ writeChar(len);
+ if (len > 0) {
+ String cpoolRefsToClasses[] = ci.cpoolRefsToClasses;
+ for (i = 0; i < len; i++) {
+ writeStringRef(cpoolRefsToClasses[i]);
+ }
+ boolean isRefClassArray[] = ci.isRefClassArray;
+ for (i = 0; i < len; i++) {
+ byte b = isRefClassArray[i] ? (byte) 1 : (byte) 0;
+ writeByte(b);
+ }
+ }
+
+ len = ci.cpoolRefsToFieldClasses != null ? ci.cpoolRefsToFieldClasses.length
+ : 0;
+ writeChar(len);
+ if (len > 0) {
+ String cpoolRefsToFieldClasses[] = ci.cpoolRefsToFieldClasses;
+ for (i = 0; i < len; i++) {
+ writeStringRef(cpoolRefsToFieldClasses[i]);
+ }
+ String cpoolRefsToFieldNames[] = ci.cpoolRefsToFieldNames;
+ for (i = 0; i < len; i++) {
+ writeStringRef(cpoolRefsToFieldNames[i]);
+ }
+ String cpoolRefsToFieldSignatures[] = ci.cpoolRefsToFieldSignatures;
+ for (i = 0; i < len; i++) {
+ writeStringRef(cpoolRefsToFieldSignatures[i]);
+ }
+ }
+
+ len = ci.cpoolRefsToMethodClasses != null ? ci.cpoolRefsToMethodClasses.length
+ : 0;
+ writeChar(len);
+ if (len > 0) {
+ String cpoolRefsToMethodClasses[] = ci.cpoolRefsToMethodClasses;
+ for (i = 0; i < len; i++) {
+ writeStringRef(cpoolRefsToMethodClasses[i]);
+ }
+ String cpoolRefsToMethodNames[] = ci.cpoolRefsToMethodNames;
+ for (i = 0; i < len; i++) {
+ writeStringRef(cpoolRefsToMethodNames[i]);
+ }
+ String cpoolRefsToMethodSignatures[] =
+ ci.cpoolRefsToMethodSignatures;
+ for (i = 0; i < len; i++) {
+ writeStringRef(cpoolRefsToMethodSignatures[i]);
+ }
+ }
+
+ writeChar(ci.accessFlags);
+ byte b = ci.isNonMemberNestedClass ? (byte) 1 : (byte) 0;
+ writeByte(b);
+ if (!"java/lang/Object".equals(ci.name)) {
+ writeStringRef(ci.superName);
+ }
+
+ len = ci.interfaces != null ? ci.interfaces.length : 0;
+ writeChar(len);
+ if (len > 0) {
+ String interfaces[] = ci.interfaces;
+ for (i = 0; i < len; i++) {
+ writeStringRef(interfaces[i]);
+ }
+ }
+
+ len = ci.fieldNames != null ? ci.fieldNames.length : 0;
+ writeChar(len);
+ if (len > 0) {
+ String fieldNames[] = ci.fieldNames;
+ for (i = 0; i < len; i++) {
+ writeStringRef(fieldNames[i]);
+ }
+ String fieldSignatures[] = ci.fieldSignatures;
+ for (i = 0; i < len; i++) {
+ writeStringRef(fieldSignatures[i]);
+ }
+ char fieldAccessFlags[] = ci.fieldAccessFlags;
+ for (i = 0; i < len; i++) {
+ writeChar(fieldAccessFlags[i]);
+ }
+ }
+
+ len = ci.primitiveConstantInitValues != null ? ci.primitiveConstantInitValues.length
+ : 0;
+ writeChar(len);
+ if (len > 0) {
+ Object primitiveConstantInitValues[] =
+ ci.primitiveConstantInitValues;
+ for (i = 0; i < len; i++) {
+ Object pc = primitiveConstantInitValues[i];
+ if (pc != null) {
+ if (pc instanceof String) {
+ writeByte((byte)1);
+ writeStringRef((String) pc);
+ } else if (pc instanceof Integer) {
+ writeByte((byte)2);
+ writeInt(((Integer) pc).intValue());
+ } else if (pc instanceof Long) {
+ writeByte((byte)3);
+ writeLong(((Long) pc).longValue());
+ } else if (pc instanceof Float) {
+ writeByte((byte)4);
+ writeFloat(((Float) pc).floatValue());
+ } else if (pc instanceof Double) {
+ writeByte((byte)5);
+ writeDouble(((Double) pc).doubleValue());
+ }
+ } else {
+ writeByte((byte)0);
+ }
+ }
+ }
+
+ len = ci.methodNames != null ? ci.methodNames.length : 0;
+ writeChar(len);
+ if (len > 0) {
+ String methodNames[] = ci.methodNames;
+ for (i = 0; i < len; i++) {
+ writeStringRef(methodNames[i]);
+ }
+ String methodSignatures[] = ci.methodSignatures;
+ for (i = 0; i < len; i++) {
+ writeStringRef(methodSignatures[i]);
+ }
+ char methodAccessFlags[] = ci.methodAccessFlags;
+ for (i = 0; i < len; i++) {
+ writeChar(methodAccessFlags[i]);
+ }
+ }
+
+ len = ci.checkedExceptions != null ? ci.checkedExceptions.length : 0;
+ writeChar(len);
+ if (len > 0) {
+ String checkedExceptions[][] = ci.checkedExceptions;
+ for (i = 0; i < len; i++) {
+ int lenl = checkedExceptions[i] != null ? checkedExceptions[i].length
+ : 0;
+ writeChar(lenl);
+ if (lenl > 0) {
+ for (j = 0; j < lenl; j++) {
+ writeStringRef(checkedExceptions[i][j]);
+ }
+ }
+ }
+ }
+
+ len = ci.nestedClasses != null ? ci.nestedClasses.length : 0;
+ writeChar(len);
+ if (len > 0) {
+ String nestedClasses[] = ci.nestedClasses;
+ for (i = 0; i < len; i++) {
+ writeStringRef(nestedClasses[i]);
+ }
+ }
+ }
+
+ private void writeString(String s) {
+ byte sb[] = s.getBytes();
+ int len = sb.length;
+ if (curStringBufPos + len > curStringBufWatermark) {
+ // May need to adapt stringBufInc
+ if (len >= stringBufInc) {
+ stringBufInc = (stringBufInc + len) * 2;
+ } else {
+ stringBufInc = (stringBufInc * 5) / 4; // Still increase a little - observations show that otherwise we usually get here 20 more times
+ }
+ byte newStringBuf[] = new byte[stringBuf.length + stringBufInc];
+ System.arraycopy(stringBuf, 0, newStringBuf, 0, curStringBufPos);
+ stringBuf = newStringBuf;
+ curStringBufWatermark = stringBuf.length - 20;
+ }
+ stringBuf[curStringBufPos++] = (byte) ((len >> 8) & 255);
+ stringBuf[curStringBufPos++] = (byte) (len & 255);
+ System.arraycopy(sb, 0, stringBuf, curStringBufPos, len);
+ curStringBufPos += len;
+ }
+
+ private void writeStringRef(String s) {
+ int stringRef = stringHashTable.get(s);
+ if (stringRef == -1) {
+ stringHashTable.add(s, stringCount);
+ stringRef = stringCount;
+ writeString(s);
+ stringCount++;
+ }
+ writeInt(stringRef);
+ }
+
+ /** Maps Strings to integer numbers (their positions in String table) */
+ static class StringHashTable {
+
+ String keys[];
+ int values[];
+ int size, nOfElements, watermark;
+
+ StringHashTable(int size) {
+ size = makeLikePrimeNumber(size);
+ this.size = size;
+ keys = new String[size];
+ values = new int[size];
+ nOfElements = 0;
+ watermark = size * 3 / 4;
+ }
+
+ final int get(String key) {
+ int pos = (key.hashCode() & 0x7FFFFFFF) % size;
+
+ while (keys[pos] != null && !keys[pos].equals(key)) {
+ pos = (pos + 3) % size; // Relies on the fact that size % 3 != 0
+ }
+ if (key.equals(keys[pos])) {
+ return values[pos];
+ } else {
+ return -1;
+ }
+ }
+
+ final void add(String key, int value) {
+ if (nOfElements > watermark) {
+ rehash();
+ }
+
+ int pos = (key.hashCode() & 0x7FFFFFFF) % size;
+ while (keys[pos] != null) {
+ pos = (pos + 3) % size; // Relies on the fact that size % 3 != 0
+ }
+ keys[pos] = key;
+ values[pos] = value;
+ nOfElements++;
+ }
+
+ private final void rehash() {
+ String oldKeys[] = keys;
+ int oldValues[] = values;
+ int oldSize = size;
+ size = makeLikePrimeNumber(size * 3 / 2);
+ keys = new String[size];
+ values = new int[size];
+ nOfElements = 0;
+ watermark = size * 3 / 4;
+
+ for (int i = 0; i < oldSize; i++) {
+ if (oldKeys[i] != null) {
+ add(oldKeys[i], oldValues[i]);
+ }
+ }
+ }
+
+ private final int makeLikePrimeNumber(int no) {
+ no = (no / 2) * 2 + 1; // Make it an odd number
+ // Find the nearest "approximately prime" number
+ boolean prime = false;
+ do {
+ no += 2;
+ prime =
+ (no % 3 != 0 && no % 5 != 0 && no % 7 != 0 && no % 11 != 0 &&
+ no % 13 != 0 && no % 17 != 0 && no % 19 != 0 && no % 23 != 0 &&
+ no % 29 != 0 && no % 31 != 0 && no % 37 != 0 && no % 41 != 0);
+ } while (!prime);
+ return no;
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698