summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikaelpeltier <mikaelpeltier@google.com>2014-04-11 09:28:18 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-04-11 09:28:18 +0000
commit18d990d24d1f1daf87d20fee4605ee1de7c4b4ac (patch)
treef57c23036740086d91cb085be986bfdaab4e592a
parent96d2943092031f6201093754c808f29dec7c6e6c (diff)
parentf227060968f467c0aac1a435333d73e938567171 (diff)
downloadtoolchain_jack-18d990d24d1f1daf87d20fee4605ee1de7c4b4ac.zip
toolchain_jack-18d990d24d1f1daf87d20fee4605ee1de7c4b4ac.tar.gz
toolchain_jack-18d990d24d1f1daf87d20fee4605ee1de7c4b4ac.tar.bz2
Merge "Split dex file writing into prepare and writing stage" into jack-wip-dev
-rw-r--r--dx/src/com/android/jack/dx/dex/file/DexFile.java65
-rw-r--r--dx/src/com/android/jack/dx/dex/file/ImportedCodeItem.java14
-rw-r--r--jack/src/com/android/jack/Jack.java5
-rw-r--r--jack/src/com/android/jack/backend/dex/DexFileBuilder.java2
-rw-r--r--jack/src/com/android/jack/backend/dex/DexFilePreparer.java48
-rw-r--r--jack/src/com/android/jack/backend/dex/DexFileWriter.java2
-rw-r--r--jack/src/com/android/jack/backend/dex/DexZipWriter.java2
-rw-r--r--jack/src/com/android/jack/scheduling/marker/DexFileMarker.java9
8 files changed, 115 insertions, 32 deletions
diff --git a/dx/src/com/android/jack/dx/dex/file/DexFile.java b/dx/src/com/android/jack/dx/dex/file/DexFile.java
index 027cb25..413911b 100644
--- a/dx/src/com/android/jack/dx/dex/file/DexFile.java
+++ b/dx/src/com/android/jack/dx/dex/file/DexFile.java
@@ -105,11 +105,10 @@ public final class DexFile {
/** {@code >= 40;} maximum width of the file dump */
private int dumpWidth;
- /** List of constant index mapping that must be used to remap binary */
- private List<CstIndexMap> cstIndexMaps;
-
- public DexFile(DexOptions dexOptions, List<CstIndexMap> cstIndexMaps) {
- this.cstIndexMaps = cstIndexMaps;
+ /**
+ * Constructs an instance. It is initially empty.
+ */
+ public DexFile(DexOptions dexOptions) {
this.dexOptions = dexOptions;
header = new HeaderSection(this);
@@ -149,13 +148,6 @@ public final class DexFile {
}
/**
- * Constructs an instance. It is initially empty.
- */
- public DexFile(DexOptions dexOptions) {
- this(dexOptions, null);
- }
-
- /**
* Returns true if this dex doesn't contain any class defs.
*/
public boolean isEmpty() {
@@ -496,26 +488,23 @@ public final class DexFile {
}
/**
- * Returns the contents of this instance as a {@code .dex} file,
- * in a {@link ByteArrayAnnotatedOutput} instance.
+ * Prepares this instance for writing. This performs any necessary prerequisites, including
+ * particularly adding stuff to other sections and places all the items in this instance at
+ * particular offsets.
*
- * @param annotate whether or not to keep annotations
- * @param verbose if annotating, whether to be verbose
- * @return {@code non-null;} a {@code .dex} file for this instance
+ * @param cstIndexMaps list used to map offsets from a dex file to this instance
*/
- private ByteArrayAnnotatedOutput toDex0(boolean annotate, boolean verbose) {
- /*
- * The following is ordered so that the prepare() calls which
- * add items happen before the calls to the sections that get
- * added to.
- */
-
-if (cstIndexMaps != null) {
+ public void prepare(List<CstIndexMap> cstIndexMaps) {
+ if (cstIndexMaps != null) {
for (CstIndexMap cstIndexMap : cstIndexMaps) {
cstIndexMap.mergeConstantsIntoDexFile(this);
}
}
+ /**
+ * The following is ordered so that the prepare() calls which add items happen before the calls
+ * to the sections that get added to.
+ */
classDefs.prepare();
classData.prepare();
wordData.prepare();
@@ -569,6 +558,32 @@ if (cstIndexMaps != null) {
// Write out all the sections.
fileSize = offset;
+ }
+
+ /**
+ * Returns the contents of this instance as a {@code .dex} file,
+ * in a {@link ByteArrayAnnotatedOutput} instance.
+ *
+ * @param annotate whether or not to keep annotations
+ * @param verbose if annotating, whether to be verbose
+ * @return {@code non-null;} a {@code .dex} file for this instance
+ */
+ private ByteArrayAnnotatedOutput toDex0(boolean annotate, boolean verbose) {
+ classDefs.throwIfNotPrepared();
+ classData.throwIfNotPrepared();
+ wordData.throwIfNotPrepared();
+ byteData.throwIfNotPrepared();
+ methodIds.throwIfNotPrepared();
+ fieldIds.throwIfNotPrepared();
+ protoIds.throwIfNotPrepared();
+ typeLists.throwIfNotPrepared();
+ typeIds.throwIfNotPrepared();
+ stringIds.throwIfNotPrepared();
+ stringData.throwIfNotPrepared();
+ header.throwIfNotPrepared();
+
+ // Write out all the sections.
+ int count = sections.length;
byte[] barr = new byte[fileSize];
ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(barr);
diff --git a/dx/src/com/android/jack/dx/dex/file/ImportedCodeItem.java b/dx/src/com/android/jack/dx/dex/file/ImportedCodeItem.java
index 0bf8a04..09d368b 100644
--- a/dx/src/com/android/jack/dx/dex/file/ImportedCodeItem.java
+++ b/dx/src/com/android/jack/dx/dex/file/ImportedCodeItem.java
@@ -51,7 +51,7 @@ public final class ImportedCodeItem extends OffsettedItem implements
* {@code non-null;} map index values used into code that references {@link Constant} from one
* dex file into index values compliant with another dex file.
*/
- private CstIndexMap cstIndexMap;
+ private final CstIndexMap cstIndexMap;
/** Array of remapped instructions */
private DecodedInstruction[] remappedInstructions;
@@ -314,6 +314,10 @@ public final class ImportedCodeItem extends OffsettedItem implements
throw new AssertionError("Not yet supported");
}
+ public CstIndexMap getCstIndexMap() {
+ return cstIndexMap;
+ }
+
private class GenericVisitor implements CodeReader.Visitor {
@Override
@@ -327,7 +331,7 @@ public final class ImportedCodeItem extends OffsettedItem implements
*/
private class StringRemapper implements CodeReader.Visitor {
- private DexFile file;
+ private final DexFile file;
public StringRemapper(DexFile dex) {
this.file = dex;
@@ -351,7 +355,7 @@ public final class ImportedCodeItem extends OffsettedItem implements
*/
private class FieldRemapper implements CodeReader.Visitor {
- private DexFile file;
+ private final DexFile file;
public FieldRemapper(DexFile dex) {
this.file = dex;
@@ -369,7 +373,7 @@ public final class ImportedCodeItem extends OffsettedItem implements
*/
private class TypeRemapper implements CodeReader.Visitor {
- private DexFile file;
+ private final DexFile file;
public TypeRemapper(DexFile dex) {
this.file = dex;
@@ -387,7 +391,7 @@ public final class ImportedCodeItem extends OffsettedItem implements
*/
private class MethodRemapper implements CodeReader.Visitor {
- private DexFile file;
+ private final DexFile file;
public MethodRemapper(DexFile dex) {
this.file = dex;
diff --git a/jack/src/com/android/jack/Jack.java b/jack/src/com/android/jack/Jack.java
index 240c941..8ada4b7 100644
--- a/jack/src/com/android/jack/Jack.java
+++ b/jack/src/com/android/jack/Jack.java
@@ -30,6 +30,7 @@ import com.android.jack.backend.ResourceWriter;
import com.android.jack.backend.dex.ClassAnnotationBuilder;
import com.android.jack.backend.dex.ClassDefItemBuilder;
import com.android.jack.backend.dex.DexFileBuilder;
+import com.android.jack.backend.dex.DexFilePreparer;
import com.android.jack.backend.dex.DexFileWriter;
import com.android.jack.backend.dex.DexZipWriter;
import com.android.jack.backend.dex.EncodedFieldBuilder;
@@ -972,6 +973,8 @@ public abstract class Jack {
packagePlan.append(PackageChecker.class);
}
}
+
+ planBuilder.append(DexFilePreparer.class);
}
private static void fillJavaToJaycePlan(
@@ -1365,6 +1368,8 @@ public abstract class Jack {
if (hasSanityChecks) {
planBuilder.append(ParentSetterChecker.class);
}
+
+ planBuilder.append(DexFilePreparer.class);
}
@Nonnull
diff --git a/jack/src/com/android/jack/backend/dex/DexFileBuilder.java b/jack/src/com/android/jack/backend/dex/DexFileBuilder.java
index 910f6c0..b331c9a 100644
--- a/jack/src/com/android/jack/backend/dex/DexFileBuilder.java
+++ b/jack/src/com/android/jack/backend/dex/DexFileBuilder.java
@@ -39,6 +39,8 @@ import javax.annotation.Nonnull;
@Name("DexFileBuilder")
@Transform(add = DexFileMarker.class)
public class DexFileBuilder implements RunnableSchedulable<JSession> {
+
+ @Nonnull
private final DexFile dexFile = new DexFile(new DexOptions());
/**
diff --git a/jack/src/com/android/jack/backend/dex/DexFilePreparer.java b/jack/src/com/android/jack/backend/dex/DexFilePreparer.java
new file mode 100644
index 0000000..3709e9a
--- /dev/null
+++ b/jack/src/com/android/jack/backend/dex/DexFilePreparer.java
@@ -0,0 +1,48 @@
+/*
+ * 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.dx.dex.file.DexFile;
+import com.android.jack.ir.ast.JSession;
+import com.android.jack.scheduling.marker.DexCodeMarker;
+import com.android.jack.scheduling.marker.DexFileMarker;
+import com.android.sched.item.Description;
+import com.android.sched.item.Name;
+import com.android.sched.schedulable.Constraint;
+import com.android.sched.schedulable.RunnableSchedulable;
+import com.android.sched.schedulable.Transform;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Prepare dex file to be written later.
+ */
+@Description("Prepare dex file to be written later")
+@Name("DexFilePreparer")
+@Transform(add = {DexFileMarker.Prepared.class})
+@Constraint(need = {DexCodeMarker.class, DexFileMarker.Complete.class})
+public class DexFilePreparer implements RunnableSchedulable<JSession> {
+
+ @Override
+ public void run(@Nonnull JSession session) throws Exception {
+ DexFileMarker dexFileMarker = session.getMarker(DexFileMarker.class);
+ assert dexFileMarker != null;
+ DexFile dexFile = dexFileMarker.getDexFile();
+ assert dexFile != null;
+ dexFile.prepare(null);
+ }
+} \ No newline at end of file
diff --git a/jack/src/com/android/jack/backend/dex/DexFileWriter.java b/jack/src/com/android/jack/backend/dex/DexFileWriter.java
index d158a34..199a3f8 100644
--- a/jack/src/com/android/jack/backend/dex/DexFileWriter.java
+++ b/jack/src/com/android/jack/backend/dex/DexFileWriter.java
@@ -42,7 +42,7 @@ import javax.annotation.Nonnull;
*/
@Description("Write dex into a file")
@Name("DexFileWriter")
-@Constraint(need = {DexFileMarker.Complete.class})
+@Constraint(need = {DexFileMarker.Prepared.class})
@Produce(DexFileProduct.class)
@Support(DexNonZipOutput.class)
public class DexFileWriter implements RunnableSchedulable<JSession> {
diff --git a/jack/src/com/android/jack/backend/dex/DexZipWriter.java b/jack/src/com/android/jack/backend/dex/DexZipWriter.java
index c692c90..99d0e04 100644
--- a/jack/src/com/android/jack/backend/dex/DexZipWriter.java
+++ b/jack/src/com/android/jack/backend/dex/DexZipWriter.java
@@ -46,7 +46,7 @@ import javax.annotation.Nonnull;
*/
@Description("Write dex into a zip")
@Name("DexZipWriter")
-@Constraint(need = {DexFileMarker.Complete.class})
+@Constraint(need = {DexFileMarker.Prepared.class})
@Produce(DexFileProduct.class)
@Support(DexZipOutput.class)
public class DexZipWriter extends DexFileWriter {
diff --git a/jack/src/com/android/jack/scheduling/marker/DexFileMarker.java b/jack/src/com/android/jack/scheduling/marker/DexFileMarker.java
index 5a621b9..f32ef18 100644
--- a/jack/src/com/android/jack/scheduling/marker/DexFileMarker.java
+++ b/jack/src/com/android/jack/scheduling/marker/DexFileMarker.java
@@ -92,6 +92,15 @@ public final class DexFileMarker implements Marker {
public static final class ClassAnnotation implements Tag {
}
+ /**
+ * This tag means that the {@code DexFile}s contained into the {@Code DexFileMarker} are prepared
+ * and ready to be written in an {@code OutputStream}.
+ */
+ @Description("The DexFile contained into the DexFileMarker is prepared.")
+ @Name("DexFileMarker.Prepared")
+ public static final class Prepared implements Tag {
+ }
+
public DexFileMarker(@Nonnull DexFile dexFile) {
this.dexFile = dexFile;
}