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

Side by Side 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, 2 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 unified diff | Download patch
OLDNEW
(Empty)
1 /* Copyright (c) 2002-2008 Sun Microsystems, Inc. All rights reserved
2 *
3 * This program is distributed under the terms of
4 * the GNU General Public License Version 2. See the LICENSE file
5 * at the top of the source tree.
6 */
7 package org.pantsbuild.jmake;
8
9 import java.io.File;
10 import java.io.FileOutputStream;
11 import java.io.IOException;
12 import java.util.Map;
13
14 /**
15 * This class implements writing into a byte array representing a project databa se
16 *
17 * @author Misha Dmitriev
18 * 2 March 2005
19 */
20 public class BinaryProjectDatabaseWriter extends BinaryFileWriter {
21
22 private Map<String, PCDEntry> pcd = null;
23 private int nOfEntries;
24 private byte[] stringBuf;
25 private int curStringBufPos, stringBufInc, curStringBufWatermark, stringC ount;
26 private StringHashTable stringHashTable = null;
27
28 public void writeProjectDatabaseToFile(File outfile, Map<String, PCDEntry> p cd) {
29 try {
30 byte[] buf = new BinaryProjectDatabaseWriter().writeProjectDatabase( pcd);
31 FileOutputStream out = new FileOutputStream(outfile);
32 out.write(buf);
33 out.close();
34 } catch (IOException e) {
35 throw new PrivateException(e);
36 }
37 }
38
39 public byte[] writeProjectDatabase(Map<String, PCDEntry> pcd) {
40 this.pcd = pcd;
41 nOfEntries = pcd.size();
42
43 // So far the constant here is chosen rather arbitrarily
44 initBuf(nOfEntries * 1000);
45
46 stringBuf = new byte[nOfEntries * 300];
47 stringBufInc = stringBuf.length / 5;
48 curStringBufWatermark = stringBuf.length - 20;
49 stringHashTable = new StringHashTable(stringBuf.length / 8);
50
51 for (PCDEntry entry : pcd.values()) {
52 writePCDEntry(entry);
53 }
54
55 // Now we have the string buffer and the main buffer. Write the end resu lt
56 byte[] mainBuf = buf;
57 int mainBufSize = curBufPos;
58 int preambleSize = Utils.MAGIC.length + 8;
59 int stringBufSize = curStringBufPos;
60 int pdbSize = stringBufSize + mainBufSize + 8; // 8 is for nOfEntries a nd string table size
61 initBuf(preambleSize + pdbSize);
62 setBufferIncreaseMode(false);
63
64 writePreamble(pdbSize);
65 writeStringTable(stringBufSize);
66 System.arraycopy(mainBuf, 0, buf, curBufPos, mainBufSize);
67 return buf;
68 }
69
70 private void writePreamble(int pdbSize) {
71 System.arraycopy(Utils.MAGIC, 0, buf, 0, Utils.MAGIC.length);
72 curBufPos += Utils.MAGIC.length;
73
74 writeInt(Utils.PDB_FORMAT_CODE_LATEST); // Version number
75 writeInt(pdbSize);
76 writeInt(pcd.size());
77 }
78
79 private void writeStringTable(int stringBufSize) {
80 writeInt(stringCount);
81 System.arraycopy(stringBuf, 0, buf, curBufPos, stringBufSize);
82 curBufPos += stringBufSize;
83 }
84
85 private void writePCDEntry(PCDEntry entry) {
86 writeStringRef(entry.className);
87 writeStringRef(entry.javaFileFullPath);
88 writeLong(entry.oldClassFileLastModified);
89 writeLong(entry.oldClassFileFingerprint);
90 writeClassInfo(entry.oldClassInfo);
91 }
92
93 private void writeClassInfo(ClassInfo ci) {
94 int i, j, len;
95
96 writeStringRef(ci.name);
97 writeInt(ci.javacTargetRelease);
98
99 len = ci.cpoolRefsToClasses != null ? ci.cpoolRefsToClasses.length : 0;
100 writeChar(len);
101 if (len > 0) {
102 String cpoolRefsToClasses[] = ci.cpoolRefsToClasses;
103 for (i = 0; i < len; i++) {
104 writeStringRef(cpoolRefsToClasses[i]);
105 }
106 boolean isRefClassArray[] = ci.isRefClassArray;
107 for (i = 0; i < len; i++) {
108 byte b = isRefClassArray[i] ? (byte) 1 : (byte) 0;
109 writeByte(b);
110 }
111 }
112
113 len = ci.cpoolRefsToFieldClasses != null ? ci.cpoolRefsToFieldClasses.le ngth
114 : 0;
115 writeChar(len);
116 if (len > 0) {
117 String cpoolRefsToFieldClasses[] = ci.cpoolRefsToFieldClasses;
118 for (i = 0; i < len; i++) {
119 writeStringRef(cpoolRefsToFieldClasses[i]);
120 }
121 String cpoolRefsToFieldNames[] = ci.cpoolRefsToFieldNames;
122 for (i = 0; i < len; i++) {
123 writeStringRef(cpoolRefsToFieldNames[i]);
124 }
125 String cpoolRefsToFieldSignatures[] = ci.cpoolRefsToFieldSignatures;
126 for (i = 0; i < len; i++) {
127 writeStringRef(cpoolRefsToFieldSignatures[i]);
128 }
129 }
130
131 len = ci.cpoolRefsToMethodClasses != null ? ci.cpoolRefsToMethodClasses. length
132 : 0;
133 writeChar(len);
134 if (len > 0) {
135 String cpoolRefsToMethodClasses[] = ci.cpoolRefsToMethodClasses;
136 for (i = 0; i < len; i++) {
137 writeStringRef(cpoolRefsToMethodClasses[i]);
138 }
139 String cpoolRefsToMethodNames[] = ci.cpoolRefsToMethodNames;
140 for (i = 0; i < len; i++) {
141 writeStringRef(cpoolRefsToMethodNames[i]);
142 }
143 String cpoolRefsToMethodSignatures[] =
144 ci.cpoolRefsToMethodSignatures;
145 for (i = 0; i < len; i++) {
146 writeStringRef(cpoolRefsToMethodSignatures[i]);
147 }
148 }
149
150 writeChar(ci.accessFlags);
151 byte b = ci.isNonMemberNestedClass ? (byte) 1 : (byte) 0;
152 writeByte(b);
153 if (!"java/lang/Object".equals(ci.name)) {
154 writeStringRef(ci.superName);
155 }
156
157 len = ci.interfaces != null ? ci.interfaces.length : 0;
158 writeChar(len);
159 if (len > 0) {
160 String interfaces[] = ci.interfaces;
161 for (i = 0; i < len; i++) {
162 writeStringRef(interfaces[i]);
163 }
164 }
165
166 len = ci.fieldNames != null ? ci.fieldNames.length : 0;
167 writeChar(len);
168 if (len > 0) {
169 String fieldNames[] = ci.fieldNames;
170 for (i = 0; i < len; i++) {
171 writeStringRef(fieldNames[i]);
172 }
173 String fieldSignatures[] = ci.fieldSignatures;
174 for (i = 0; i < len; i++) {
175 writeStringRef(fieldSignatures[i]);
176 }
177 char fieldAccessFlags[] = ci.fieldAccessFlags;
178 for (i = 0; i < len; i++) {
179 writeChar(fieldAccessFlags[i]);
180 }
181 }
182
183 len = ci.primitiveConstantInitValues != null ? ci.primitiveConstantInitV alues.length
184 : 0;
185 writeChar(len);
186 if (len > 0) {
187 Object primitiveConstantInitValues[] =
188 ci.primitiveConstantInitValues;
189 for (i = 0; i < len; i++) {
190 Object pc = primitiveConstantInitValues[i];
191 if (pc != null) {
192 if (pc instanceof String) {
193 writeByte((byte)1);
194 writeStringRef((String) pc);
195 } else if (pc instanceof Integer) {
196 writeByte((byte)2);
197 writeInt(((Integer) pc).intValue());
198 } else if (pc instanceof Long) {
199 writeByte((byte)3);
200 writeLong(((Long) pc).longValue());
201 } else if (pc instanceof Float) {
202 writeByte((byte)4);
203 writeFloat(((Float) pc).floatValue());
204 } else if (pc instanceof Double) {
205 writeByte((byte)5);
206 writeDouble(((Double) pc).doubleValue());
207 }
208 } else {
209 writeByte((byte)0);
210 }
211 }
212 }
213
214 len = ci.methodNames != null ? ci.methodNames.length : 0;
215 writeChar(len);
216 if (len > 0) {
217 String methodNames[] = ci.methodNames;
218 for (i = 0; i < len; i++) {
219 writeStringRef(methodNames[i]);
220 }
221 String methodSignatures[] = ci.methodSignatures;
222 for (i = 0; i < len; i++) {
223 writeStringRef(methodSignatures[i]);
224 }
225 char methodAccessFlags[] = ci.methodAccessFlags;
226 for (i = 0; i < len; i++) {
227 writeChar(methodAccessFlags[i]);
228 }
229 }
230
231 len = ci.checkedExceptions != null ? ci.checkedExceptions.length : 0;
232 writeChar(len);
233 if (len > 0) {
234 String checkedExceptions[][] = ci.checkedExceptions;
235 for (i = 0; i < len; i++) {
236 int lenl = checkedExceptions[i] != null ? checkedExceptions[i].l ength
237 : 0;
238 writeChar(lenl);
239 if (lenl > 0) {
240 for (j = 0; j < lenl; j++) {
241 writeStringRef(checkedExceptions[i][j]);
242 }
243 }
244 }
245 }
246
247 len = ci.nestedClasses != null ? ci.nestedClasses.length : 0;
248 writeChar(len);
249 if (len > 0) {
250 String nestedClasses[] = ci.nestedClasses;
251 for (i = 0; i < len; i++) {
252 writeStringRef(nestedClasses[i]);
253 }
254 }
255 }
256
257 private void writeString(String s) {
258 byte sb[] = s.getBytes();
259 int len = sb.length;
260 if (curStringBufPos + len > curStringBufWatermark) {
261 // May need to adapt stringBufInc
262 if (len >= stringBufInc) {
263 stringBufInc = (stringBufInc + len) * 2;
264 } else {
265 stringBufInc = (stringBufInc * 5) / 4; // Still increase a litt le - observations show that otherwise we usually get here 20 more times
266 }
267 byte newStringBuf[] = new byte[stringBuf.length + stringBufInc];
268 System.arraycopy(stringBuf, 0, newStringBuf, 0, curStringBufPos);
269 stringBuf = newStringBuf;
270 curStringBufWatermark = stringBuf.length - 20;
271 }
272 stringBuf[curStringBufPos++] = (byte) ((len >> 8) & 255);
273 stringBuf[curStringBufPos++] = (byte) (len & 255);
274 System.arraycopy(sb, 0, stringBuf, curStringBufPos, len);
275 curStringBufPos += len;
276 }
277
278 private void writeStringRef(String s) {
279 int stringRef = stringHashTable.get(s);
280 if (stringRef == -1) {
281 stringHashTable.add(s, stringCount);
282 stringRef = stringCount;
283 writeString(s);
284 stringCount++;
285 }
286 writeInt(stringRef);
287 }
288
289 /** Maps Strings to integer numbers (their positions in String table) */
290 static class StringHashTable {
291
292 String keys[];
293 int values[];
294 int size, nOfElements, watermark;
295
296 StringHashTable(int size) {
297 size = makeLikePrimeNumber(size);
298 this.size = size;
299 keys = new String[size];
300 values = new int[size];
301 nOfElements = 0;
302 watermark = size * 3 / 4;
303 }
304
305 final int get(String key) {
306 int pos = (key.hashCode() & 0x7FFFFFFF) % size;
307
308 while (keys[pos] != null && !keys[pos].equals(key)) {
309 pos = (pos + 3) % size; // Relies on the fact that size % 3 != 0
310 }
311 if (key.equals(keys[pos])) {
312 return values[pos];
313 } else {
314 return -1;
315 }
316 }
317
318 final void add(String key, int value) {
319 if (nOfElements > watermark) {
320 rehash();
321 }
322
323 int pos = (key.hashCode() & 0x7FFFFFFF) % size;
324 while (keys[pos] != null) {
325 pos = (pos + 3) % size; // Relies on the fact that size % 3 != 0
326 }
327 keys[pos] = key;
328 values[pos] = value;
329 nOfElements++;
330 }
331
332 private final void rehash() {
333 String oldKeys[] = keys;
334 int oldValues[] = values;
335 int oldSize = size;
336 size = makeLikePrimeNumber(size * 3 / 2);
337 keys = new String[size];
338 values = new int[size];
339 nOfElements = 0;
340 watermark = size * 3 / 4;
341
342 for (int i = 0; i < oldSize; i++) {
343 if (oldKeys[i] != null) {
344 add(oldKeys[i], oldValues[i]);
345 }
346 }
347 }
348
349 private final int makeLikePrimeNumber(int no) {
350 no = (no / 2) * 2 + 1; // Make it an odd number
351 // Find the nearest "approximately prime" number
352 boolean prime = false;
353 do {
354 no += 2;
355 prime =
356 (no % 3 != 0 && no % 5 != 0 && no % 7 != 0 && no % 11 != 0 &&
357 no % 13 != 0 && no % 17 != 0 && no % 19 != 0 && no % 23 != 0 &&
358 no % 29 != 0 && no % 31 != 0 && no % 37 != 0 && no % 41 != 0);
359 } while (!prime);
360 return no;
361 }
362 }
363 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698