summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikaelpeltier <mikaelpeltier@google.com>2014-06-16 14:28:49 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-06-10 21:31:35 +0000
commit9bc381f6f59e8b443ceb224bb150cae707e859a9 (patch)
tree4c0a745e62f9f709617b5a2a04199db1944c323f
parent481e7ec3c0d38c0f6d792a2a73e1eb9bc5db6da5 (diff)
parent3b91904b9dc9d3215d1130827f8e357696f35ab3 (diff)
downloadtoolchain_jack-9bc381f6f59e8b443ceb224bb150cae707e859a9.zip
toolchain_jack-9bc381f6f59e8b443ceb224bb150cae707e859a9.tar.gz
toolchain_jack-9bc381f6f59e8b443ceb224bb150cae707e859a9.tar.bz2
Merge "Allow to generate one dex file per type" into jack-wip-dev
-rw-r--r--jack/src/com/android/jack/Jack.java21
-rw-r--r--jack/src/com/android/jack/Options.java17
-rw-r--r--jack/src/com/android/jack/backend/dex/OneDexPerTypeWriter.java93
-rw-r--r--jack/src/com/android/jack/scheduling/tags/OneDexPerTypeProduct.java29
4 files changed, 153 insertions, 7 deletions
diff --git a/jack/src/com/android/jack/Jack.java b/jack/src/com/android/jack/Jack.java
index 354b427..67a3106 100644
--- a/jack/src/com/android/jack/Jack.java
+++ b/jack/src/com/android/jack/Jack.java
@@ -39,6 +39,7 @@ import com.android.jack.backend.dex.FieldAnnotationBuilder;
import com.android.jack.backend.dex.FieldInitializerRemover;
import com.android.jack.backend.dex.MethodAnnotationBuilder;
import com.android.jack.backend.dex.MethodBodyRemover;
+import com.android.jack.backend.dex.OneDexPerTypeWriter;
import com.android.jack.backend.dex.annotations.ClassAnnotationSchedulingSeparator;
import com.android.jack.backend.dex.annotations.DefaultValueAnnotationAdder;
import com.android.jack.backend.dex.annotations.ReflectAnnotationsAdder;
@@ -99,6 +100,7 @@ import com.android.jack.scheduling.feature.JackFileOutput;
import com.android.jack.scheduling.feature.Resources;
import com.android.jack.scheduling.feature.SourceVersion7;
import com.android.jack.scheduling.tags.DexFileProduct;
+import com.android.jack.scheduling.tags.OneDexPerTypeProduct;
import com.android.jack.shrob.obfuscation.Mapping;
import com.android.jack.shrob.obfuscation.MappingPrinter;
import com.android.jack.shrob.obfuscation.NameFinalizer;
@@ -476,7 +478,11 @@ public abstract class Jack {
request.addProduction(JackFormatProduct.class);
} else {
assert options.out != null || options.outZip != null;
- request.addProduction(DexFileProduct.class);
+ if (ThreadConfig.get(Options.GENERATE_ONE_DEX_PER_TYPE).booleanValue()) {
+ request.addProduction(OneDexPerTypeProduct.class);
+ } else {
+ request.addProduction(DexFileProduct.class);
+ }
}
ProductionSet targetProduction = request.getTargetProductions();
@@ -512,12 +518,17 @@ public abstract class Jack {
planBuilder.append(DexFileWriter.class);
}
} else {
- assert targetProduction.contains(DexFileProduct.class);
+ assert targetProduction.contains(DexFileProduct.class)
+ || targetProduction.contains(OneDexPerTypeProduct.class);
fillDexPlan(options, planBuilder);
if (features.contains(DexZipOutput.class)) {
planBuilder.append(DexZipWriter.class);
} else {
- planBuilder.append(DexFileWriter.class);
+ if (targetProduction.contains(OneDexPerTypeProduct.class)) {
+ planBuilder.append(OneDexPerTypeWriter.class);
+ } else {
+ planBuilder.append(DexFileWriter.class);
+ }
}
}
@@ -1066,7 +1077,9 @@ public abstract class Jack {
}
}
- planBuilder.append(DexFilePreparer.class);
+ if (!productions.contains(OneDexPerTypeProduct.class)) {
+ planBuilder.append(DexFilePreparer.class);
+ }
}
private static void fillJavaToJaycePlan(@Nonnull PlanBuilder<JSession> planBuilder) {
diff --git a/jack/src/com/android/jack/Options.java b/jack/src/com/android/jack/Options.java
index 25beeaf..28969ce 100644
--- a/jack/src/com/android/jack/Options.java
+++ b/jack/src/com/android/jack/Options.java
@@ -127,9 +127,20 @@ public class Options {
.and(JACK_OUTPUT_CONTAINER_TYPE.is(Container.DIR)));
@Nonnull
- public static final PropertyId<File> DEX_FILE_OUTPUT = PropertyId.create(
- "jack.dex.output", "Dex output file", new PathCodec())
- .requiredIf(GENERATE_DEX_FILE.getValue().isTrue());
+ public static final BooleanPropertyId GENERATE_ONE_DEX_PER_TYPE = BooleanPropertyId.create(
+ "jack.dex.generate.onepertype", "Generate one dex file per type").addDefaultValue(
+ Boolean.FALSE);
+
+ @Nonnull
+ public static final PropertyId<Directory> DEX_FILE_FOLDER = PropertyId.create(
+ "jack.dex.output.folder", "Dex output folder",
+ new DirectoryCodec(Existence.MAY_EXIST, Permission.READ | Permission.WRITE)).requiredIf(
+ GENERATE_ONE_DEX_PER_TYPE.getValue().isTrue());
+
+ @Nonnull
+ public static final PropertyId<File> DEX_FILE_OUTPUT = PropertyId.create("jack.dex.output",
+ "Dex output file", new PathCodec()).requiredIf(
+ GENERATE_DEX_FILE.getValue().isTrue().or(GENERATE_ONE_DEX_PER_TYPE.getValue().isTrue()));
@Nonnull
public static final BooleanPropertyId ENABLE_COMPILED_FILES_STATISTICS = BooleanPropertyId.create(
diff --git a/jack/src/com/android/jack/backend/dex/OneDexPerTypeWriter.java b/jack/src/com/android/jack/backend/dex/OneDexPerTypeWriter.java
new file mode 100644
index 0000000..6ff7317
--- /dev/null
+++ b/jack/src/com/android/jack/backend/dex/OneDexPerTypeWriter.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+package com.android.jack.backend.dex;
+
+import com.android.jack.JackFileException;
+import com.android.jack.Options;
+import com.android.jack.dx.dex.DexOptions;
+import com.android.jack.dx.dex.file.ClassDefItem;
+import com.android.jack.dx.dex.file.DexFile;
+import com.android.jack.ir.ast.JDefinedClassOrInterface;
+import com.android.jack.ir.ast.JSession;
+import com.android.jack.ir.naming.CompositeName;
+import com.android.jack.ir.naming.TypeName;
+import com.android.jack.ir.naming.TypeName.Kind;
+import com.android.jack.scheduling.feature.DexNonZipOutput;
+import com.android.jack.scheduling.marker.ClassDefItemMarker;
+import com.android.jack.scheduling.marker.DexCodeMarker;
+import com.android.jack.scheduling.marker.DexFileMarker;
+import com.android.jack.scheduling.tags.OneDexPerTypeProduct;
+import com.android.sched.item.Description;
+import com.android.sched.schedulable.Constraint;
+import com.android.sched.schedulable.Produce;
+import com.android.sched.schedulable.RunnableSchedulable;
+import com.android.sched.schedulable.Support;
+import com.android.sched.util.config.ThreadConfig;
+import com.android.sched.util.file.Directory;
+import com.android.sched.vfs.OutputVFile;
+import com.android.sched.vfs.VPath;
+import com.android.sched.vfs.direct.OutputDirectDir;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Write one dex file per types.
+ */
+@Description("Write one dex file per types")
+@Constraint(need = {DexCodeMarker.class, DexFileMarker.Complete.class})
+@Produce(OneDexPerTypeProduct.class)
+@Support(DexNonZipOutput.class)
+public class OneDexPerTypeWriter implements RunnableSchedulable<JSession> {
+
+ @Nonnull
+ protected Directory outputDirectory = ThreadConfig.get(Options.DEX_FILE_FOLDER);
+
+ @Override
+ public void run(@Nonnull JSession session) throws Exception {
+ OutputDirectDir odd = new OutputDirectDir(outputDirectory);
+
+ for (JDefinedClassOrInterface type : session.getTypesToEmit()) {
+ OutputVFile vFile = odd.createOutputVFile(getFilePath(type));
+ try {
+ ClassDefItemMarker marker = type.getMarker(ClassDefItemMarker.class);
+ if (marker != null) {
+ OutputStream outStream = vFile.openWrite();
+ try {
+ ClassDefItem cdi = marker.getClassDefItem();
+ DexFile file = new DexFile(new DexOptions());
+ file.add(cdi);
+ file.prepare(null);
+ file.writeTo(outStream, null, false);
+ } finally {
+ outStream.close();
+ }
+ }
+ } catch (IOException e) {
+ throw new JackFileException("Could not write Dex file to output '" + vFile + "'", e);
+ }
+ }
+ }
+
+ @Nonnull
+ protected static VPath getFilePath(@Nonnull JDefinedClassOrInterface type) {
+ return new VPath(new CompositeName(new TypeName(Kind.BINARY_QN, type),
+ ".dex"), '/');
+ }
+}
diff --git a/jack/src/com/android/jack/scheduling/tags/OneDexPerTypeProduct.java b/jack/src/com/android/jack/scheduling/tags/OneDexPerTypeProduct.java
new file mode 100644
index 0000000..24b9357
--- /dev/null
+++ b/jack/src/com/android/jack/scheduling/tags/OneDexPerTypeProduct.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+package com.android.jack.scheduling.tags;
+
+import com.android.jack.ir.ast.JType;
+import com.android.sched.item.Description;
+import com.android.sched.item.Production;
+
+/**
+ * Represents the production of one {@link DexFile} per {@link JType}.
+ */
+@Description("Produce one dex file per type")
+public class OneDexPerTypeProduct implements Production {
+
+}