Merge "Read input classes in parallel"
diff --git a/build.gradle b/build.gradle
index 722106c..a00c516 100644
--- a/build.gradle
+++ b/build.gradle
@@ -922,6 +922,9 @@
         println "JCTF: compiling only"
         systemProperty 'jctf_compile_only', '1'
     }
+    if (project.hasProperty('test_dir')) {
+        systemProperty 'test_dir', project.property('test_dir')
+    }
 
     if (OperatingSystem.current().isLinux()
             || OperatingSystem.current().isMacOsX()
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/JarState.java b/src/main/java/com/android/tools/r8/ir/conversion/JarState.java
index a6b1f2c..2a3e431 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/JarState.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/JarState.java
@@ -339,12 +339,19 @@
   }
 
   private Local setLocalInfo(int index, Type type, DebugLocalInfo info) {
-    return setLocalInfoForRegister(getLocalRegister(index, type), type, info);
+    return setLocalInfoForRegister(getLocalRegister(index, type), info);
   }
 
-  private Local setLocalInfoForRegister(int register, Type type, DebugLocalInfo info) {
+  private Local setLocalInfoForRegister(int register, DebugLocalInfo info) {
     Local existingLocal = getLocalForRegister(register);
-    Local local = new Local(existingLocal.slot, info);
+    // TODO(ager, zerny): Kotlin debug information contains locals that are not referenced.
+    // That seems broken and we currently do not retain that debug information because
+    // we do not let locals debug information influence code generation. Debug information can
+    // be completely malformed, so we shouldn't let it influence code generation. However, we
+    // need to deal with these unused locals in the debug information. For now we
+    // use a null type for the slot, but we should reconsider that.
+    Slot slot = existingLocal != null ? existingLocal.slot : new Slot(register, null);
+    Local local = new Local(slot, info);
     locals[register] = local;
     return local;
   }
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index fd4cdccb..eee820f 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -314,10 +314,22 @@
     }
   }
 
+  static class RetainedTemporaryFolder extends TemporaryFolder {
+    RetainedTemporaryFolder(java.io.File parentFolder) {
+      super(parentFolder);
+    }
+    protected void after() {} // instead of remove, do nothing
+  }
+
   // For non-Linux platforms create the temporary directory in the repository root to simplify
   // running Art in a docker container
   public static TemporaryFolder getTemporaryFolderForTest() {
-    return new TemporaryFolder(ToolHelper.isLinux() ? null : Paths.get("build", "tmp").toFile());
+    String tmpDir = System.getProperty("test_dir");
+    if (tmpDir == null) {
+      return new TemporaryFolder(ToolHelper.isLinux() ? null : Paths.get("build", "tmp").toFile());
+    } else {
+      return new RetainedTemporaryFolder(new java.io.File(tmpDir));
+    }
   }
 
   public static String getArtBinary() {
diff --git a/tools/test.py b/tools/test.py
index ccc36d8..1da077b 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -44,7 +44,8 @@
       help='Print a line before a tests starts and after it ends to stdout.',
       default=False, action='store_true')
   result.add_option('--tool',
-      help='Tool to run ART tests with: "r8" (default) or "d8". Ignored if "--all_tests" enabled.',
+      help='Tool to run ART tests with: "r8" (default) or "d8". Ignored if'
+          ' "--all_tests" enabled.',
       default=None, choices=["r8", "d8"])
   result.add_option('--jctf',
       help='Run JCTF tests with: "r8" (default) or "d8".',
@@ -56,11 +57,15 @@
       help="Don't run, only compile JCTF tests.",
       default=False, action='store_true')
   result.add_option('--disable_assertions',
-      help="Disable assertions when running tests.",
+      help='Disable assertions when running tests.',
       default=False, action='store_true')
   result.add_option('--with_code_coverage',
-      help="Enable code coverage with Jacoco.",
+      help='Enable code coverage with Jacoco.',
       default=False, action='store_true')
+  result.add_option('--test_dir',
+      help='Use a custom directory for the test artifacts instead of a'
+          ' temporary (which is automatically removed after the test).'
+          ' Note that the directory will not be cleared before the test.')
 
   return result.parse_args()
 
@@ -112,6 +117,10 @@
     gradle_args.append('jctfCommonJar')
     gradle_args.append('-x')
     gradle_args.append('jctfTestsClasses')
+  if options.test_dir:
+    gradle_args.append('-Ptest_dir=' + options.test_dir)
+    if not os.path.exists(options.test_dir):
+      os.makedirs(options.test_dir)
 
   # Add Gradle tasks
   gradle_args.append('cleanTest')