diff options
author | mikaelpeltier <mikaelpeltier@google.com> | 2014-06-16 14:28:49 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-06-10 21:31:35 +0000 |
commit | 9bc381f6f59e8b443ceb224bb150cae707e859a9 (patch) | |
tree | 4c0a745e62f9f709617b5a2a04199db1944c323f | |
parent | 481e7ec3c0d38c0f6d792a2a73e1eb9bc5db6da5 (diff) | |
parent | 3b91904b9dc9d3215d1130827f8e357696f35ab3 (diff) | |
download | toolchain_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.java | 21 | ||||
-rw-r--r-- | jack/src/com/android/jack/Options.java | 17 | ||||
-rw-r--r-- | jack/src/com/android/jack/backend/dex/OneDexPerTypeWriter.java | 93 | ||||
-rw-r--r-- | jack/src/com/android/jack/scheduling/tags/OneDexPerTypeProduct.java | 29 |
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 { + +} |