summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Lamarche <benoitlamarche@google.com>2015-02-09 17:26:47 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-02-09 17:26:47 +0000
commitb3ef71c036980c75656b151789c1c27a1a2d2bab (patch)
treea0f7626d8253e3a72f60391ca9b1348ba048be93
parent6e28e4323f0cb0df9caeaaf603399af0c35c840e (diff)
parentc8b036e3fb5e88eb501e953a8a8838b547f2dab4 (diff)
downloaddalvik-b3ef71c036980c75656b151789c1c27a1a2d2bab.tar.gz
Merge "Revert "Support --num-threads with --multi-dex""
-rw-r--r--dx/src/com/android/dx/command/dexer/Main.java521
-rw-r--r--dx/src/com/android/dx/dex/file/MixedItemSection.java2
-rw-r--r--dx/src/com/android/dx/dex/file/ProtoIdsSection.java2
-rw-r--r--dx/src/com/android/dx/dex/file/StringIdsSection.java4
-rw-r--r--dx/src/com/android/dx/dex/file/TypeIdsSection.java2
-rw-r--r--dx/tests/128-multidex-option-overflow/expected.txt1
-rw-r--r--dx/tests/129-numthread-deterministic/expected.txt1
-rw-r--r--dx/tests/129-numthread-deterministic/info.txt2
-rw-r--r--dx/tests/129-numthread-deterministic/run54
-rw-r--r--dx/tests/130-numthread-multidex-deterministic/expected.txt1
-rw-r--r--dx/tests/130-numthread-multidex-deterministic/info.txt2
-rw-r--r--dx/tests/130-numthread-multidex-deterministic/run54
-rw-r--r--dx/tests/131-perf/ClassGen.java53
-rw-r--r--dx/tests/131-perf/expected.txt1
-rw-r--r--dx/tests/131-perf/info.txt2
-rw-r--r--dx/tests/131-perf/run88
16 files changed, 134 insertions, 656 deletions
diff --git a/dx/src/com/android/dx/command/dexer/Main.java b/dx/src/com/android/dx/command/dexer/Main.java
index fb38d82ae..06ffcedef 100644
--- a/dx/src/com/android/dx/command/dexer/Main.java
+++ b/dx/src/com/android/dx/command/dexer/Main.java
@@ -64,14 +64,12 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
-import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.jar.Attributes;
@@ -181,39 +179,11 @@ public class Main {
/** Library .dex files to merge into the output .dex. */
private static final List<byte[]> libraryDexBuffers = new ArrayList<byte[]>();
- /** Thread pool object used for multi-thread class translation. */
- private static ExecutorService classTranslatorPool;
+ /** thread pool object used for multi-threaded file processing */
+ private static ExecutorService threadPool;
- /** Single thread executor, for collecting results of parallel translation,
- * and adding classes to dex file in original input file order. */
- private static ExecutorService classDefItemConsumer;
-
- /** Futures for {@code classDefItemConsumer} tasks. */
- private static List<Future<Boolean>> addToDexFutures =
- new ArrayList<Future<Boolean>>();
-
- /** Thread pool object used for multi-thread dex conversion (to byte array).
- * Used in combination with multi-dex support, to allow outputing
- * a completed dex file, in parallel with continuing processing. */
- private static ExecutorService dexOutPool;
-
- /** Futures for {@code dexOutPool} task. */
- private static List<Future<byte[]>> dexOutputFutures =
- new ArrayList<Future<byte[]>>();
-
- /** Lock object used to to coordinate dex file rotation, and
- * multi-threaded translation. */
- private static Object dexRotationLock = new Object();
-
- /** Record the number if method indices "reserved" for files
- * committed to translation in the context of the current dex
- * file, but not yet added. */
- private static int maxMethodIdsInProcess = 0;
-
- /** Record the number if field indices "reserved" for files
- * committed to translation in the context of the current dex
- * file, but not yet added. */
- private static int maxFieldIdsInProcess = 0;
+ /** used to handle Errors for multi-threaded file processing */
+ private static List<Future<Void>> parallelProcessorFutures;
/** true if any files are successfully processed */
private static volatile boolean anyFilesProcessed;
@@ -320,7 +290,7 @@ public class Main {
byte[] outArray = null;
if (!outputDex.isEmpty() || (args.humanOutName != null)) {
- outArray = writeDex(outputDex);
+ outArray = writeDex();
if (outArray == null) {
return 2;
@@ -355,14 +325,13 @@ public class Main {
private static int runMultiDex() throws IOException {
assert !args.incremental;
+ assert args.numThreads == 1;
if (args.mainDexListFile != null) {
classesInMainDex = new HashSet<String>();
readPathsFromFile(args.mainDexListFile, classesInMainDex);
}
- dexOutPool = Executors.newFixedThreadPool(args.numThreads);
-
if (!processAllFiles()) {
return 1;
}
@@ -373,31 +342,14 @@ public class Main {
if (outputDex != null) {
// this array is null if no classes were defined
-
- dexOutputFutures.add(dexOutPool.submit(new DexWriter(outputDex)));
+ dexOutputArrays.add(writeDex());
// Effectively free up the (often massive) DexFile memory.
outputDex = null;
}
- try {
- dexOutPool.shutdown();
- if (!dexOutPool.awaitTermination(600L, TimeUnit.SECONDS)) {
- throw new RuntimeException("Timed out waiting for dex writer threads.");
- }
-
- for (Future<byte[]> f : dexOutputFutures) {
- dexOutputArrays.add(f.get());
- }
-
- } catch (InterruptedException ex) {
- dexOutPool.shutdownNow();
- throw new RuntimeException("A dex writer thread has been interrupted.");
- } catch (Exception e) {
- dexOutPool.shutdownNow();
- throw new RuntimeException("Unexpected exception in dex writer thread");
- }
if (args.jarOutput) {
+
for (int i = 0; i < dexOutputArrays.size(); i++) {
outputResources.put(getDexFileName(i),
dexOutputArrays.get(i));
@@ -417,6 +369,7 @@ public class Main {
closeOutput(out);
}
}
+
}
return 0;
@@ -522,14 +475,10 @@ public class Main {
anyFilesProcessed = false;
String[] fileNames = args.fileNames;
- // translate classes in parallel
- classTranslatorPool = new ThreadPoolExecutor(args.numThreads,
- args.numThreads, 0, TimeUnit.SECONDS,
- new ArrayBlockingQueue<Runnable>(2 * args.numThreads, true),
- new ThreadPoolExecutor.CallerRunsPolicy());
- // collect translated and write to dex in order
- classDefItemConsumer = Executors.newSingleThreadExecutor();
-
+ if (args.numThreads > 1) {
+ threadPool = Executors.newFixedThreadPool(args.numThreads);
+ parallelProcessorFutures = new ArrayList<Future<Void>>();
+ }
try {
if (args.mainDexListFile != null) {
@@ -542,25 +491,13 @@ public class Main {
processOne(fileNames[i], mainPassFilter);
}
- if (dexOutputFutures.size() > 0) {
+ if (dexOutputArrays.size() > 0) {
throw new DexException("Too many classes in " + Arguments.MAIN_DEX_LIST_OPTION
+ ", main dex capacity exceeded");
}
if (args.minimalMainDex) {
// start second pass directly in a secondary dex file.
-
- // Wait for classes in progress to complete
- synchronized(dexRotationLock) {
- while(maxMethodIdsInProcess > 0 || maxFieldIdsInProcess > 0) {
- try {
- dexRotationLock.wait();
- } catch(InterruptedException ex) {
- /* ignore */
- }
- }
- }
-
rotateDexFile();
}
@@ -581,36 +518,35 @@ public class Main {
*/
}
- try {
- classTranslatorPool.shutdown();
- classTranslatorPool.awaitTermination(600L, TimeUnit.SECONDS);
- classDefItemConsumer.shutdown();
- classDefItemConsumer.awaitTermination(600L, TimeUnit.SECONDS);
-
- for (Future<Boolean> f : addToDexFutures) {
- try {
- f.get();
- } catch(ExecutionException ex) {
- // Catch any previously uncaught exceptions from
- // class translation and adding to dex.
- int count = errors.incrementAndGet();
- if (count < 10) {
- DxConsole.err.println("Uncaught translation error: " + ex.getCause());
- } else {
- throw new InterruptedException("Too many errors");
- }
+ if (args.numThreads > 1) {
+ try {
+ threadPool.shutdown();
+ if (!threadPool.awaitTermination(600L, TimeUnit.SECONDS)) {
+ throw new RuntimeException("Timed out waiting for threads.");
}
+ } catch (InterruptedException ex) {
+ threadPool.shutdownNow();
+ throw new RuntimeException("A thread has been interrupted.");
}
- } catch (InterruptedException ie) {
- classTranslatorPool.shutdownNow();
- classDefItemConsumer.shutdownNow();
- throw new RuntimeException("Translation has been interrupted", ie);
- } catch (Exception e) {
- classTranslatorPool.shutdownNow();
- classDefItemConsumer.shutdownNow();
- e.printStackTrace(System.out);
- throw new RuntimeException("Unexpected exception in translator thread.", e);
+ try {
+ for (Future<?> future : parallelProcessorFutures) {
+ future.get();
+ }
+ } catch (ExecutionException e) {
+ Throwable cause = e.getCause();
+ // All Exceptions should have been handled in the ParallelProcessor, only Errors
+ // should remain
+ if (cause instanceof Error) {
+ throw (Error) e.getCause();
+ } else {
+ throw new AssertionError(e.getCause());
+ }
+ } catch (InterruptedException e) {
+ // If we're here, it means all threads have completed cleanly, so there should not be
+ // any InterruptedException
+ throw new AssertionError(e);
+ }
}
int errorNum = errors.get();
@@ -646,11 +582,7 @@ public class Main {
private static void rotateDexFile() {
if (outputDex != null) {
- if (dexOutPool != null) {
- dexOutputFutures.add(dexOutPool.submit(new DexWriter(outputDex)));
- } else {
- dexOutputArrays.add(writeDex(outputDex));
- }
+ dexOutputArrays.add(writeDex());
}
createDexFile();
@@ -667,15 +599,46 @@ public class Main {
private static void processOne(String pathname, FileNameFilter filter) {
ClassPathOpener opener;
- opener = new ClassPathOpener(pathname, false, filter, new FileBytesConsumer());
+ opener = new ClassPathOpener(pathname, false, filter,
+ new ClassPathOpener.Consumer() {
- opener.process();
- }
+ @Override
+ public boolean processFileBytes(String name, long lastModified, byte[] bytes) {
+ return Main.processFileBytes(name, lastModified, bytes);
+ }
- private static void updateStatus(boolean res) {
- anyFilesProcessed |= res;
- }
+ @Override
+ public void onException(Exception ex) {
+ if (ex instanceof StopProcessing) {
+ throw (StopProcessing) ex;
+ } else if (ex instanceof SimException) {
+ DxConsole.err.println("\nEXCEPTION FROM SIMULATION:");
+ DxConsole.err.println(ex.getMessage() + "\n");
+ DxConsole.err.println(((SimException) ex).getContext());
+ } else {
+ DxConsole.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
+ ex.printStackTrace(DxConsole.err);
+ }
+ errors.incrementAndGet();
+ }
+
+ @Override
+ public void onProcessArchiveStart(File file) {
+ if (args.verbose) {
+ DxConsole.out.println("processing archive " + file +
+ "...");
+ }
+ }
+ });
+ if (args.numThreads > 1) {
+ parallelProcessorFutures.add(threadPool.submit(new ParallelProcessor(opener)));
+ } else {
+ if (opener.process()) {
+ anyFilesProcessed = true;
+ }
+ }
+ }
/**
* Processes one file, which may be either a class or a resource.
@@ -685,7 +648,6 @@ public class Main {
* @return whether processing was successful
*/
private static boolean processFileBytes(String name, long lastModified, byte[] bytes) {
-
boolean isClass = name.endsWith(".class");
boolean isClassesDex = name.equals(DexFormat.DEX_IN_JAR_NAME);
boolean keepResources = (outputResources != null);
@@ -740,30 +702,42 @@ public class Main {
checkClassName(name);
}
- try {
- new DirectClassFileConsumer(name, bytes, null).call(
- new ClassParserTask(name, bytes).call());
- } catch(Exception ex) {
- throw new RuntimeException("Exception parsing classes", ex);
- }
+ DirectClassFile cf =
+ new DirectClassFile(bytes, name, args.cfOptions.strictNameCheck);
- return true;
- }
-
-
- private static DirectClassFile parseClass(String name, byte[] bytes) {
-
- DirectClassFile cf = new DirectClassFile(bytes, name,
- args.cfOptions.strictNameCheck);
cf.setAttributeFactory(StdAttributeFactory.THE_ONE);
- cf.getMagic(); // triggers the actual parsing
- return cf;
- }
+ cf.getMagic();
+
+ int numMethodIds = outputDex.getMethodIds().items().size();
+ int numFieldIds = outputDex.getFieldIds().items().size();
+ int constantPoolSize = cf.getConstantPool().size();
+
+ int maxMethodIdsInDex = numMethodIds + constantPoolSize + cf.getMethods().size() +
+ MAX_METHOD_ADDED_DURING_DEX_CREATION;
+ int maxFieldIdsInDex = numFieldIds + constantPoolSize + cf.getFields().size() +
+ MAX_FIELD_ADDED_DURING_DEX_CREATION;
+
+ if (args.multiDex
+ // Never switch to the next dex if current dex is already empty
+ && (outputDex.getClassDefs().items().size() > 0)
+ && ((maxMethodIdsInDex > args.maxNumberOfIdxPerDex) ||
+ (maxFieldIdsInDex > args.maxNumberOfIdxPerDex))) {
+ DexFile completeDex = outputDex;
+ rotateDexFile();
+ assert (completeDex.getMethodIds().items().size() <= numMethodIds +
+ MAX_METHOD_ADDED_DURING_DEX_CREATION) &&
+ (completeDex.getFieldIds().items().size() <= numFieldIds +
+ MAX_FIELD_ADDED_DURING_DEX_CREATION);
+ }
- private static ClassDefItem translateClass(byte[] bytes, DirectClassFile cf) {
try {
- return CfTranslator.translate(cf, bytes, args.cfOptions,
- args.dexOptions, outputDex);
+ ClassDefItem clazz =
+ CfTranslator.translate(cf, bytes, args.cfOptions, args.dexOptions, outputDex);
+ synchronized (outputDex) {
+ outputDex.add(clazz);
+ }
+ return true;
+
} catch (ParseException ex) {
DxConsole.err.println("\ntrouble processing:");
if (args.debug) {
@@ -773,14 +747,7 @@ public class Main {
}
}
errors.incrementAndGet();
- return null;
- }
-
- private static boolean addClassToDex(ClassDefItem clazz) {
- synchronized (outputDex) {
- outputDex.add(clazz);
- }
- return true;
+ return false;
}
/**
@@ -830,7 +797,7 @@ public class Main {
* @return {@code null-ok;} the converted {@code byte[]} or {@code null}
* if there was a problem
*/
- private static byte[] writeDex(DexFile outputDex) {
+ private static byte[] writeDex() {
byte[] outArray = null;
try {
@@ -869,6 +836,7 @@ public class Main {
}
return null;
}
+
return outArray;
}
@@ -1584,6 +1552,12 @@ public class Main {
throw new UsageException();
}
+ if (multiDex && numThreads != 1) {
+ System.out.println(NUM_THREADS_OPTION + " is ignored when used with "
+ + MULTI_DEX_OPTION);
+ numThreads = 1;
+ }
+
if (multiDex && incremental) {
System.err.println(INCREMENTAL_OPTION + " is not supported with "
+ MULTI_DEX_OPTION);
@@ -1628,260 +1602,21 @@ public class Main {
}
}
- /**
- * Callback class for processing input file bytes, produced by the
- * ClassPathOpener.
- */
- private static class FileBytesConsumer implements ClassPathOpener.Consumer {
+ /** Callable helper class to process files in multiple threads */
+ private static class ParallelProcessor implements Callable<Void> {
- @Override
- public boolean processFileBytes(String name, long lastModified,
- byte[] bytes) {
- return Main.processFileBytes(name, lastModified, bytes);
- }
+ ClassPathOpener classPathOpener;
- @Override
- public void onException(Exception ex) {
- if (ex instanceof StopProcessing) {
- throw (StopProcessing) ex;
- } else if (ex instanceof SimException) {
- DxConsole.err.println("\nEXCEPTION FROM SIMULATION:");
- DxConsole.err.println(ex.getMessage() + "\n");
- DxConsole.err.println(((SimException) ex).getContext());
- } else {
- DxConsole.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
- ex.printStackTrace(DxConsole.err);
- }
- errors.incrementAndGet();
- }
-
- @Override
- public void onProcessArchiveStart(File file) {
- if (args.verbose) {
- DxConsole.out.println("processing archive " + file + "...");
- }
- }
- }
-
- /** Callable helper class to parse class bytes. */
- private static class ClassParserTask implements Callable<DirectClassFile> {
-
- String name;
- byte[] bytes;
-
- private ClassParserTask(String name, byte[] bytes) {
- this.name = name;
- this.bytes = bytes;
- }
-
- @Override
- public DirectClassFile call() throws Exception {
- DirectClassFile cf = parseClass(name, bytes);
-
- return cf;
- }
- }
-
- /**
- * Callable helper class used to sequentially collect the results of
- * the (optionally parallel) translation phase, in correct input file order.
- * This class is also responsible for coordinating dex file rotation
- * with the ClassDefItemConsumer class.
- * We maintain invariant that the number of indices used in the current
- * dex file plus the max number of indices required by classes passed to
- * the translation phase and not yet added to the dex file, is less than
- * or equal to the dex file limit.
- * For each parsed file, we estimate the maximum number of indices it may
- * require. If passing the file to the translation phase would invalidate
- * the invariant, we wait, until the next class is added to the dex file,
- * and then reevaluate the invariant. If there are no further classes in
- * the translation phase, we rotate the dex file.
- */
- private static class DirectClassFileConsumer implements Callable<Boolean> {
-
- String name;
- byte[] bytes;
- Future<DirectClassFile> dcff;
-
- private DirectClassFileConsumer(String name, byte[] bytes,
- Future<DirectClassFile> dcff) {
- this.name = name;
- this.bytes = bytes;
- this.dcff = dcff;
- }
-
- @Override
- public Boolean call() throws Exception {
-
- DirectClassFile cf = dcff.get();
- return call(cf);
- }
-
- private Boolean call(DirectClassFile cf) {
-
- int maxMethodIdsInClass = 0;
- int maxFieldIdsInClass = 0;
-
- if (args.multiDex) {
-
- // Calculate max number of indices this class will add to the
- // dex file.
- // The constant pool contains at least one entry per method
- // (name and signature), at least one entry per field (name
- // and type), and at least per method/field reference (typed
- // method ref).
-
- int constantPoolSize = cf.getConstantPool().size();
- maxMethodIdsInClass = constantPoolSize - cf.getFields().size()
- + MAX_METHOD_ADDED_DURING_DEX_CREATION;
- maxFieldIdsInClass = constantPoolSize - cf.getMethods().size()
- + MAX_FIELD_ADDED_DURING_DEX_CREATION;
- synchronized(dexRotationLock) {
-
- int numMethodIds;
- int numFieldIds;
- // Number of indices used in current dex file.
- synchronized(outputDex) {
- numMethodIds = outputDex.getMethodIds().items().size();
- numFieldIds = outputDex.getFieldIds().items().size();
- }
- // Wait until we're sure this class will fit in the current
- // dex file.
- while(((numMethodIds + maxMethodIdsInClass + maxMethodIdsInProcess
- > args.maxNumberOfIdxPerDex) ||
- (numFieldIds + maxFieldIdsInClass + maxFieldIdsInProcess
- > args.maxNumberOfIdxPerDex))) {
-
- if (maxMethodIdsInProcess > 0 || maxFieldIdsInProcess > 0) {
- // There are classes in the translation phase that
- // have not yet been added to the dex file, so we
- // wait for the next class to complete.
- try {
- dexRotationLock.wait();
- } catch(InterruptedException ex) {
- /* ignore */
- }
- } else if (outputDex.getClassDefs().items().size() > 0) {
- // There are no further classes in the translation
- // phase, and we have a full dex file. Rotate!
- rotateDexFile();
- } else {
- // The estimated number of indices is too large for
- // an empty dex file. We proceed hoping the actual
- // number of indices needed will fit.
- break;
- }
- synchronized(outputDex) {
- numMethodIds = outputDex.getMethodIds().items().size();
- numFieldIds = outputDex.getFieldIds().items().size();
- }
- }
- // Add our estimate to the total estimate for
- // classes under translation.
- maxMethodIdsInProcess += maxMethodIdsInClass;
- maxFieldIdsInProcess += maxFieldIdsInClass;
- }
- }
-
- // Submit class to translation phase.
- Future<ClassDefItem> cdif = classTranslatorPool.submit(
- new ClassTranslatorTask(name, bytes, cf));
- Future<Boolean> res = classDefItemConsumer.submit(new ClassDefItemConsumer(
- name, cdif, maxMethodIdsInClass, maxFieldIdsInClass));
- addToDexFutures.add(res);
-
- return true;
- }
- }
-
-
- /** Callable helper class to translate classes in parallel */
- private static class ClassTranslatorTask implements Callable<ClassDefItem> {
-
- String name;
- byte[] bytes;
- DirectClassFile classFile;
-
- private ClassTranslatorTask(String name, byte[] bytes,
- DirectClassFile classFile) {
- this.name = name;
- this.bytes = bytes;
- this.classFile = classFile;
+ private ParallelProcessor(ClassPathOpener classPathOpener) {
+ this.classPathOpener = classPathOpener;
}
@Override
- public ClassDefItem call() {
- ClassDefItem clazz = translateClass(bytes, classFile);
- return clazz;
- }
- }
-
- /**
- * Callable helper class used to collect the results of
- * the parallel translation phase, adding the translated classes to
- * the current dex file in correct (deterministic) file order.
- * This class is also responsible for coordinating dex file rotation
- * with the DirectClassFileConsumer class.
- */
- private static class ClassDefItemConsumer implements Callable<Boolean> {
-
- String name;
- Future<ClassDefItem> futureClazz;
- int maxMethodIdsInClass;
- int maxFieldIdsInClass;
-
- private ClassDefItemConsumer(String name, Future<ClassDefItem> futureClazz,
- int maxMethodIdsInClass, int maxFieldIdsInClass) {
- this.name = name;
- this.futureClazz = futureClazz;
- this.maxMethodIdsInClass = maxMethodIdsInClass;
- this.maxFieldIdsInClass = maxFieldIdsInClass;
- }
-
- @Override
- public Boolean call() throws Exception {
- try {
- ClassDefItem clazz = futureClazz.get();
- if (clazz != null) {
- addClassToDex(clazz);
- updateStatus(true);
- }
- return true;
- } catch(ExecutionException ex) {
- // Rethrow previously uncaught translation exceptions.
- // These, as well as any exceptions from addClassToDex,
- // are handled and reported in processAllFiles().
- Throwable t = ex.getCause();
- throw (t instanceof Exception) ? (Exception) t : ex;
- } finally {
- if (args.multiDex) {
- // Having added our actual indicies to the dex file,
- // we subtract our original estimate from the total estimate,
- // and signal the translation phase, which may be paused
- // waiting to determine if more classes can be added to the
- // current dex file, or if a new dex file must be created.
- synchronized(dexRotationLock) {
- maxMethodIdsInProcess -= maxMethodIdsInClass;
- maxFieldIdsInProcess -= maxFieldIdsInClass;
- dexRotationLock.notifyAll();
- }
- }
+ public Void call() throws Exception {
+ if (classPathOpener.process()) {
+ anyFilesProcessed = true;
}
- }
- }
-
- /** Callable helper class to convert dex files in worker threads */
- private static class DexWriter implements Callable<byte[]> {
-
- private DexFile dexFile;
-
- private DexWriter(DexFile dexFile) {
- this.dexFile = dexFile;
- }
-
- @Override
- public byte[] call() throws IOException {
- return writeDex(dexFile);
+ return null;
}
}
}
diff --git a/dx/src/com/android/dx/dex/file/MixedItemSection.java b/dx/src/com/android/dx/dex/file/MixedItemSection.java
index 9053043f9..4edc6b62f 100644
--- a/dx/src/com/android/dx/dex/file/MixedItemSection.java
+++ b/dx/src/com/android/dx/dex/file/MixedItemSection.java
@@ -189,7 +189,7 @@ public final class MixedItemSection extends Section {
* @param item {@code non-null;} the item to intern
* @return {@code non-null;} the equivalent interned instance
*/
- public synchronized <T extends OffsettedItem> T intern(T item) {
+ public <T extends OffsettedItem> T intern(T item) {
throwIfPrepared();
OffsettedItem result = interns.get(item);
diff --git a/dx/src/com/android/dx/dex/file/ProtoIdsSection.java b/dx/src/com/android/dx/dex/file/ProtoIdsSection.java
index b7df10cdd..4b1303b15 100644
--- a/dx/src/com/android/dx/dex/file/ProtoIdsSection.java
+++ b/dx/src/com/android/dx/dex/file/ProtoIdsSection.java
@@ -86,7 +86,7 @@ public final class ProtoIdsSection extends UniformItemSection {
* @param prototype {@code non-null;} the prototype to intern
* @return {@code non-null;} the interned reference
*/
- public synchronized ProtoIdItem intern(Prototype prototype) {
+ public ProtoIdItem intern(Prototype prototype) {
if (prototype == null) {
throw new NullPointerException("prototype == null");
}
diff --git a/dx/src/com/android/dx/dex/file/StringIdsSection.java b/dx/src/com/android/dx/dex/file/StringIdsSection.java
index 6826c5a48..7aff82ea9 100644
--- a/dx/src/com/android/dx/dex/file/StringIdsSection.java
+++ b/dx/src/com/android/dx/dex/file/StringIdsSection.java
@@ -117,7 +117,7 @@ public final class StringIdsSection
* @param string {@code non-null;} the string to intern
* @return {@code non-null;} the interned string
*/
- public synchronized StringIdItem intern(StringIdItem string) {
+ public StringIdItem intern(StringIdItem string) {
if (string == null) {
throw new NullPointerException("string == null");
}
@@ -140,7 +140,7 @@ public final class StringIdsSection
*
* @param nat {@code non-null;} the name-and-type
*/
- public synchronized void intern(CstNat nat) {
+ public void intern(CstNat nat) {
intern(nat.getName());
intern(nat.getDescriptor());
}
diff --git a/dx/src/com/android/dx/dex/file/TypeIdsSection.java b/dx/src/com/android/dx/dex/file/TypeIdsSection.java
index 35d8e661a..c3380f4b8 100644
--- a/dx/src/com/android/dx/dex/file/TypeIdsSection.java
+++ b/dx/src/com/android/dx/dex/file/TypeIdsSection.java
@@ -106,7 +106,7 @@ public final class TypeIdsSection extends UniformItemSection {
* @param type {@code non-null;} the type to intern
* @return {@code non-null;} the interned reference
*/
- public synchronized TypeIdItem intern(Type type) {
+ public TypeIdItem intern(Type type) {
if (type == null) {
throw new NullPointerException("type == null");
}
diff --git a/dx/tests/128-multidex-option-overflow/expected.txt b/dx/tests/128-multidex-option-overflow/expected.txt
index ac448a63d..3d7a649b8 100644
--- a/dx/tests/128-multidex-option-overflow/expected.txt
+++ b/dx/tests/128-multidex-option-overflow/expected.txt
@@ -1,2 +1,3 @@
classes2.dex
+classes3.dex
classes.dex
diff --git a/dx/tests/129-numthread-deterministic/expected.txt b/dx/tests/129-numthread-deterministic/expected.txt
deleted file mode 100644
index 54183385d..000000000
--- a/dx/tests/129-numthread-deterministic/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-Yay!
diff --git a/dx/tests/129-numthread-deterministic/info.txt b/dx/tests/129-numthread-deterministic/info.txt
deleted file mode 100644
index e4885fab3..000000000
--- a/dx/tests/129-numthread-deterministic/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Test that dx generates deterministic output when using --num-threads
-
diff --git a/dx/tests/129-numthread-deterministic/run b/dx/tests/129-numthread-deterministic/run
deleted file mode 100644
index fdc050649..000000000
--- a/dx/tests/129-numthread-deterministic/run
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Stop if something fails.
-set -e
-
-# Write out classes
-mkdir src
-awk '
-BEGIN {
- for (c = 1; c <= 500; c++) {
- writeClass(c);
- }
-}
-function writeClass(name) {
- fileName = "src/Clazz" name ".java";
- printf("public class Clazz%s {\n", name) > fileName;
- for (i = 1; i <= 100; i++) {
- printf(" int field%d;\n", i) > fileName;
- }
- for (i = 1; i <= 100; i++) {
- printf(" void method%d(int param) { }\n", i) > fileName;
- }
- printf("}\n") > fileName;
-}'
-
-
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-mkdir out
-dx -JXmx4g -JXms4g --dex --no-optimize --output=out classes
-mkdir out-multi
-dx -JXmx4g -JXms4g --dex --no-optimize --num-threads=4 --output=out-multi classes
-diff -r out out-multi > unit-out.txt
-
-if [ "$?" = "0" ]; then
- echo "Yay!"
-else
- cat unit-out.txt
-fi
-
diff --git a/dx/tests/130-numthread-multidex-deterministic/expected.txt b/dx/tests/130-numthread-multidex-deterministic/expected.txt
deleted file mode 100644
index 54183385d..000000000
--- a/dx/tests/130-numthread-multidex-deterministic/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-Yay!
diff --git a/dx/tests/130-numthread-multidex-deterministic/info.txt b/dx/tests/130-numthread-multidex-deterministic/info.txt
deleted file mode 100644
index e4885fab3..000000000
--- a/dx/tests/130-numthread-multidex-deterministic/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Test that dx generates deterministic output when using --num-threads
-
diff --git a/dx/tests/130-numthread-multidex-deterministic/run b/dx/tests/130-numthread-multidex-deterministic/run
deleted file mode 100644
index b43ba1f54..000000000
--- a/dx/tests/130-numthread-multidex-deterministic/run
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Stop if something fails.
-set -e
-
-# Write out classes
-mkdir src
-awk '
-BEGIN {
- for (c = 1; c <= 1000; c++) {
- writeClass(c);
- }
-}
-function writeClass(name) {
- fileName = "src/Clazz" name ".java";
- printf("public class Clazz%s {\n", name) > fileName;
- for (i = 1; i <= 100; i++) {
- printf(" int field%d;\n", i) > fileName;
- }
- for (i = 1; i <= 100; i++) {
- printf(" void method%d(int param) { }\n", i) > fileName;
- }
- printf("}\n") > fileName;
-}'
-
-
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-mkdir out
-dx -JXmx4g -JXms4g --dex --no-optimize --multi-dex --output=out classes
-mkdir out-multi
-dx -JXmx4g -JXms4g --dex --no-optimize --multi-dex --num-threads=4 --output=out-multi classes
-diff -r out out-multi > unit-out.txt
-
-if [ "$?" = "0" ]; then
- echo "Yay!"
-else
- cat unit-out.txt
-fi
-
diff --git a/dx/tests/131-perf/ClassGen.java b/dx/tests/131-perf/ClassGen.java
deleted file mode 100644
index c35bbcf82..000000000
--- a/dx/tests/131-perf/ClassGen.java
+++ /dev/null
@@ -1,53 +0,0 @@
-import java.io.File;
-import java.io.PrintWriter;
-
-public class ClassGen {
-
- public static void main(String... args) {
-
- int start = 1;
- int end = 8024;
- int fields = 4;
- int methods = 6;
- if (args.length > 0) {
- start = Integer.parseInt(args[0]);
- }
- if (args.length > 1) {
- end = Integer.parseInt(args[1]);
- }
- if (args.length > 2) {
- fields = Integer.parseInt(args[2]);
- }
- if (args.length > 3) {
- methods = Integer.parseInt(args[3]);
- }
-
- for (int file = start; file <= end; file++) {
- try {
- File f = new File("src/Clazz" + file + ".java");
- PrintWriter pw = new PrintWriter(f);
- pw.println("class Clazz" + file + " {");
- for (int field = 1; field <= fields; field++) {
- pw.println(" public static int f" + field + ";");
- }
- for (int method = 1; method <= methods; method++) {
- pw.println(" boolean m" + method + "_" + (file%(end/2)) + "() {"
-);
- pw.println(" int max = Thread.MAX_PRIORITY;");
- pw.println(" for (int i = 0; i < max; i++) {");
- pw.println(" System.out.println(\"Hello from: \" + Clazz"
- + file + ".class + \".method" + method
- + "() \" + Clazz" + (end-file+1) + ".f1);");
- pw.println(" Thread.dumpStack();");
- pw.println(" }");
- pw.println(" return Thread.holdsLock(this);");
- pw.println(" }");
- }
- pw.println("}");
- pw.close();
- } catch(Exception ex) {
- System.out.println("Ups");
- }
- }
- }
-}
diff --git a/dx/tests/131-perf/expected.txt b/dx/tests/131-perf/expected.txt
deleted file mode 100644
index 54183385d..000000000
--- a/dx/tests/131-perf/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-Yay!
diff --git a/dx/tests/131-perf/info.txt b/dx/tests/131-perf/info.txt
deleted file mode 100644
index f5b6a0cee..000000000
--- a/dx/tests/131-perf/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Script for --multi-dex --num-threads performance testing, default just test options can be used together
-
diff --git a/dx/tests/131-perf/run b/dx/tests/131-perf/run
deleted file mode 100644
index e57545c03..000000000
--- a/dx/tests/131-perf/run
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Stop if something fails.
-set -e
-
-# Write out classes
-
-${JAVAC} ClassGen.java
-
-mkdir src
-mkdir classes
-
-# Heap size, min and max
-MEM=4g
-
-MULTIDEX="--multi-dex"
-THREADS="--num-threads=5"
-
-# Extra statistics, use to calibrate test.
-#EXTRA="--profile-concurrency"
-
-# Test smaller dex files
-#EXTRA="--set-max-idx-number=20000"
-
-# Test GC options
-#GC="-JXX:+UseConcMarkSweepGC"
-
-# Limit HW threads
-#TASKSET="taskset 0x00000fff
-
-# Number of classes, initial
-TEST_SIZE=1000
-
-# number of classes, max
-LIMIT=1000
-
-# Number of additional classes per test
-STEP=100
-
-# Number of fields per classes
-FIELDS=4
-
-# Number of methods per class
-METHODS=6
-
-
-first=1;
-while [ $TEST_SIZE -le $LIMIT ]; do
- rm -rf out
- mkdir out
-
- sleep 2
- java -classpath . ClassGen $first $TEST_SIZE $FIELDS $METHODS
- first=`expr $TEST_SIZE + 1`
-
- ${JAVAC} -d classes `find src -name '*.java'`
- (cd classes; jar cf ../x.jar `find . -name '*.class'`)
- sleep 3
-
- start=`date +'%s%N'`
- $TASKSET dx -JXmx$MEM -JXms$MEM $GC --dex $EXTRA --no-optimize $MULTIDEX $THREADS --output=out x.jar
- end=`date +'%s%N'`
- nsec=`expr $end - $start`
- msec=`expr $nsec / 1000000`
- echo "Classes/msec $TEST_SIZE $msec"
-
- TEST_SIZE=`expr $TEST_SIZE + $STEP`
-done
-
-if [ "$?" = "1" ]; then
- echo "Yay!"
-else
- cat unit-out.txt
-fi