Merge "Compute a length based on heap size instead of card table size." into dalvik-dev
diff --git a/dx/src/com/android/dx/command/dexer/Main.java b/dx/src/com/android/dx/command/dexer/Main.java
index b121668..6e8fa7e 100644
--- a/dx/src/com/android/dx/command/dexer/Main.java
+++ b/dx/src/com/android/dx/command/dexer/Main.java
@@ -59,6 +59,7 @@
 import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
 /**
@@ -208,13 +209,18 @@
             return 0; // this was a no-op incremental build
         }
 
-        byte[] outArray = writeDex();
+        // this array is null if no classes were defined
+        byte[] outArray = null;
 
-        if (outArray == null) {
-            return 2;
+        if (!outputDex.isEmpty()) {
+            outArray = writeDex();
+
+            if (outArray == null) {
+                return 2;
+            }
         }
 
-        if (args.incremental && incrementalOutFile.exists()) {
+        if (args.incremental) {
             outArray = merge(outArray, incrementalOutFile);
         }
 
@@ -225,7 +231,7 @@
             if (!createJar(args.outName, outArray)) {
                 return 3;
             }
-        } else if (args.outName != null) {
+        } else if (outArray != null && args.outName != null) {
             OutputStream out = openOutput(args.outName);
             out.write(outArray);
             closeOutput(out);
@@ -236,27 +242,50 @@
 
     /**
      * Merges the dex files {@code update} and {@code base}, preferring
-     * {@code update}'s definition for types defined in both dex files. Returns
-     * the bytes of the merged dex file.
+     * {@code update}'s definition for types defined in both dex files.
+     *
+     * @return the bytes of the merged dex file, or null if both the update
+     *     and the base dex do not exist.
      */
     private static byte[] merge(byte[] update, File base) throws IOException {
-        DexBuffer dexA = new DexBuffer();
-        dexA.loadFrom(new ByteArrayInputStream(update));
+        DexBuffer dexA = null;
+        DexBuffer dexB = null;
 
-        DexBuffer dexB = new DexBuffer();
-        if (args.jarOutput) {
-            ZipFile zipFile = new ZipFile(base);
-            dexB.loadFrom(zipFile.getInputStream(zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME)));
-            zipFile.close();
-        } else {
-            InputStream in = new FileInputStream(base);
-            dexB.loadFrom(in);
-            in.close();
+        if (update != null) {
+            dexA = new DexBuffer();
+            dexA.loadFrom(new ByteArrayInputStream(update));
         }
 
-        DexBuffer merged = new DexMerger(dexA, dexB).merge();
+        if (base.exists()) {
+            if (args.jarOutput) {
+                ZipFile zipFile = new ZipFile(base);
+                ZipEntry entry = zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME);
+                if (entry != null) {
+                    dexB = new DexBuffer();
+                    dexB.loadFrom(zipFile.getInputStream(entry));
+                    zipFile.close();
+                }
+            } else {
+                InputStream in = new FileInputStream(base);
+                dexB = new DexBuffer();
+                dexB.loadFrom(in);
+                in.close();
+            }
+        }
+
+        DexBuffer result;
+        if (dexA == null && dexB == null) {
+            return null;
+        } else if (dexA == null) {
+            result = dexB;
+        } else if (dexB == null) {
+            result = dexA;
+        } else {
+            result = new DexMerger(dexA, dexB).merge();
+        }
+
         ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
-        merged.writeTo(bytesOut);
+        result.writeTo(bytesOut);
         return bytesOut.toByteArray();
     }
 
@@ -555,8 +584,8 @@
      * Creates a jar file from the resources and given dex file array.
      *
      * @param fileName {@code non-null;} name of the file
-     * @param dexArray {@code non-null;} array containing the dex file
-     * to include
+     * @param dexArray array containing the dex file to include, or null if the
+     *     output contains no class defs.
      * @return whether the creation was successful
      */
     private static boolean createJar(String fileName, byte[] dexArray) {
@@ -571,7 +600,9 @@
             OutputStream out = openOutput(fileName);
             JarOutputStream jarOut = new JarOutputStream(out, manifest);
 
-            outputResources.put(DexFormat.DEX_IN_JAR_NAME, dexArray);
+            if (dexArray != null) {
+                outputResources.put(DexFormat.DEX_IN_JAR_NAME, dexArray);
+            }
 
             try {
                 for (Map.Entry<String, byte[]> e :
diff --git a/dx/src/com/android/dx/command/grep/Grep.java b/dx/src/com/android/dx/command/grep/Grep.java
new file mode 100644
index 0000000..025aa65
--- /dev/null
+++ b/dx/src/com/android/dx/command/grep/Grep.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 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.dx.command.grep;
+
+import com.android.dx.io.ClassData;
+import com.android.dx.io.ClassDef;
+import com.android.dx.io.CodeReader;
+import com.android.dx.io.DexBuffer;
+import com.android.dx.io.EncodedValueReader;
+import com.android.dx.io.MethodId;
+import com.android.dx.io.instructions.DecodedInstruction;
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+public final class Grep {
+    private final DexBuffer dex;
+    private final CodeReader codeReader = new CodeReader();
+    private final Set<Integer> stringIds;
+
+    private final PrintStream out;
+    private int count = 0;
+
+    private ClassDef currentClass;
+    private ClassData.Method currentMethod;
+
+    public Grep(final DexBuffer dex, Pattern pattern, final PrintStream out) {
+        this.dex = dex;
+        this.out = out;
+
+        stringIds = getStringIds(dex, pattern);
+
+        codeReader.setStringVisitor(new CodeReader.Visitor() {
+            public void visit(DecodedInstruction[] all, DecodedInstruction one) {
+                encounterString(one.getIndex());
+            }
+        });
+    }
+
+    private EncodedValueReader newEncodedValueReader(DexBuffer.Section section) {
+        return new EncodedValueReader(section) {
+            @Override protected void visitString(int type, int index) {
+                encounterString(index);
+            }
+        };
+    }
+
+    private void encounterString(int index) {
+        if (stringIds.contains(index)) {
+            out.println(location() + " " + dex.strings().get(index));
+            count++;
+        }
+    }
+
+    private String location() {
+        String className = dex.typeNames().get(currentClass.getTypeIndex());
+        if (currentMethod != null) {
+            MethodId methodId = dex.methodIds().get(currentMethod.getMethodIndex());
+            return className + "." + dex.strings().get(methodId.getNameIndex());
+        } else {
+            return className;
+        }
+    }
+
+    /**
+     * Prints usages to out. Returns the number of matches found.
+     */
+    public int grep() {
+        for (ClassDef classDef : dex.classDefs()) {
+            currentClass = classDef;
+            currentMethod = null;
+
+            if (classDef.getClassDataOffset() == 0) {
+                continue;
+            }
+
+            ClassData classData = dex.readClassData(classDef);
+
+            // find the strings in encoded constants
+            int staticValuesOffset = classDef.getStaticValuesOffset();
+            if (staticValuesOffset != 0) {
+                newEncodedValueReader(dex.open(staticValuesOffset)).readArray();
+            }
+
+            // find the strings in method bodies
+            for (ClassData.Method method : classData.allMethods()) {
+                currentMethod = method;
+                if (method.getCodeOffset() != 0) {
+                    codeReader.visitAll(dex.readCode(method).getInstructions());
+                }
+            }
+        }
+
+        currentClass = null;
+        currentMethod = null;
+        return count;
+    }
+
+    private Set<Integer> getStringIds(DexBuffer dex, Pattern pattern) {
+        Set<Integer> stringIds = new HashSet<Integer>();
+        int stringIndex = 0;
+        for (String s : dex.strings()) {
+            if (pattern.matcher(s).find()) {
+                stringIds.add(stringIndex);
+            }
+            stringIndex++;
+        }
+        return stringIds;
+    }
+}
diff --git a/dx/src/com/android/dx/command/grep/Main.java b/dx/src/com/android/dx/command/grep/Main.java
new file mode 100644
index 0000000..e765a31
--- /dev/null
+++ b/dx/src/com/android/dx/command/grep/Main.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 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.dx.command.grep;
+
+import com.android.dx.dex.DexFormat;
+import com.android.dx.io.DexBuffer;
+import com.android.dx.util.FileUtils;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.regex.Pattern;
+import java.util.zip.ZipFile;
+
+public final class Main {
+    public static void main(String[] args) throws IOException {
+        String dexFile = args[0];
+        String pattern = args[1];
+
+        DexBuffer dex = new DexBuffer();
+        if (FileUtils.hasArchiveSuffix(dexFile)) {
+            ZipFile zip = new ZipFile(dexFile);
+            InputStream in = zip.getInputStream(zip.getEntry(DexFormat.DEX_IN_JAR_NAME));
+            dex.loadFrom(in);
+            zip.close();
+        } else {
+            dex.loadFrom(new File(dexFile));
+        }
+
+        int count = new Grep(dex, Pattern.compile(pattern), System.out).grep();
+        System.exit((count > 0) ? 0 : 1);
+    }
+}
diff --git a/dx/src/com/android/dx/dex/file/DexFile.java b/dx/src/com/android/dx/dex/file/DexFile.java
index 1cc9358..73f0864 100644
--- a/dx/src/com/android/dx/dex/file/DexFile.java
+++ b/dx/src/com/android/dx/dex/file/DexFile.java
@@ -134,6 +134,13 @@
     }
 
     /**
+     * Returns true if this dex doesn't contain any class defs.
+     */
+    public boolean isEmpty() {
+        return classDefs.items().isEmpty();
+    }
+
+    /**
      * Adds a class to this instance. It is illegal to attempt to add more
      * than one class with the same name.
      *
diff --git a/dx/src/com/android/dx/io/EncodedValueReader.java b/dx/src/com/android/dx/io/EncodedValueReader.java
new file mode 100644
index 0000000..6c913a1
--- /dev/null
+++ b/dx/src/com/android/dx/io/EncodedValueReader.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2011 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.dx.io;
+
+/**
+ * SAX-style reader for encoded values.
+ * TODO: convert this to a pull-style reader
+ */
+public class EncodedValueReader {
+    public static final int ENCODED_BYTE = 0x00;
+    public static final int ENCODED_SHORT = 0x02;
+    public static final int ENCODED_CHAR = 0x03;
+    public static final int ENCODED_INT = 0x04;
+    public static final int ENCODED_LONG = 0x06;
+    public static final int ENCODED_FLOAT = 0x10;
+    public static final int ENCODED_DOUBLE = 0x11;
+    public static final int ENCODED_STRING = 0x17;
+    public static final int ENCODED_TYPE = 0x18;
+    public static final int ENCODED_FIELD = 0x19;
+    public static final int ENCODED_ENUM = 0x1b;
+    public static final int ENCODED_METHOD = 0x1a;
+    public static final int ENCODED_ARRAY = 0x1c;
+    public static final int ENCODED_ANNOTATION = 0x1d;
+    public static final int ENCODED_NULL = 0x1e;
+    public static final int ENCODED_BOOLEAN = 0x1f;
+
+    protected final DexBuffer.Section in;
+
+    public EncodedValueReader(DexBuffer.Section in) {
+        this.in = in;
+    }
+
+    public final void readArray() {
+        int size = in.readUleb128();
+        visitArray(size);
+
+        for (int i = 0; i < size; i++) {
+            readValue();
+        }
+    }
+
+    public final void readAnnotation() {
+        int typeIndex = in.readUleb128();
+        int size = in.readUleb128();
+        visitAnnotation(typeIndex, size);
+
+        for (int i = 0; i < size; i++) {
+            visitAnnotationName(in.readUleb128());
+            readValue();
+        }
+    }
+
+    public final void readValue() {
+        int argAndType = in.readByte() & 0xff;
+        int type = argAndType & 0x1f;
+        int arg = (argAndType & 0xe0) >> 5;
+        int size = arg + 1;
+
+        switch (type) {
+        case ENCODED_BYTE:
+        case ENCODED_SHORT:
+        case ENCODED_CHAR:
+        case ENCODED_INT:
+        case ENCODED_LONG:
+        case ENCODED_FLOAT:
+        case ENCODED_DOUBLE:
+            visitPrimitive(argAndType, type, arg, size);
+            break;
+        case ENCODED_STRING:
+            visitString(type, readIndex(in, size));
+            break;
+        case ENCODED_TYPE:
+            visitType(type, readIndex(in, size));
+            break;
+        case ENCODED_FIELD:
+        case ENCODED_ENUM:
+            visitField(type, readIndex(in, size));
+            break;
+        case ENCODED_METHOD:
+            visitMethod(type, readIndex(in, size));
+            break;
+        case ENCODED_ARRAY:
+            visitArrayValue(argAndType);
+            readArray();
+            break;
+        case ENCODED_ANNOTATION:
+            visitAnnotationValue(argAndType);
+            readAnnotation();
+            break;
+        case ENCODED_NULL:
+            visitEncodedNull(argAndType);
+            break;
+        case ENCODED_BOOLEAN:
+            visitEncodedBoolean(argAndType);
+            break;
+        }
+    }
+
+    protected void visitArray(int size) {}
+    protected void visitAnnotation(int typeIndex, int size) {}
+    protected void visitAnnotationName(int nameIndex) {}
+    protected void visitPrimitive(int argAndType, int type, int arg, int size) {
+        for (int i = 0; i < size; i++) {
+            in.readByte();
+        }
+    }
+    protected void visitString(int type, int index) {}
+    protected void visitType(int type, int index) {}
+    protected void visitField(int type, int index) {}
+    protected void visitMethod(int type, int index) {}
+    protected void visitArrayValue(int argAndType) {}
+    protected void visitAnnotationValue(int argAndType) {}
+    protected void visitEncodedBoolean(int argAndType) {}
+    protected void visitEncodedNull(int argAndType) {}
+
+    private int readIndex(DexBuffer.Section in, int byteCount) {
+        int result = 0;
+        int shift = 0;
+        for (int i = 0; i < byteCount; i++) {
+            result += (in.readByte() & 0xff) << shift;
+            shift += 8;
+        }
+        return result;
+    }
+}
diff --git a/dx/src/com/android/dx/merge/DexMerger.java b/dx/src/com/android/dx/merge/DexMerger.java
index 0c24a85..1fe0ff5 100644
--- a/dx/src/com/android/dx/merge/DexMerger.java
+++ b/dx/src/com/android/dx/merge/DexMerger.java
@@ -636,7 +636,7 @@
         // elements
         for (int i = 0; i < size; i++) {
             annotationOut.writeUleb128(indexMap.adjustString(in.readUleb128())); // name
-            new EncodedValueTransformer(indexMap, in, annotationOut).transformValue(); // value
+            new EncodedValueTransformer(in, indexMap, annotationOut).readValue(); // value
         }
     }
 
@@ -751,7 +751,7 @@
 
     private void transformStaticValues(DexBuffer.Section in, IndexMap indexMap) {
         contentsOut.encodedArrays.size++;
-        new EncodedValueTransformer(indexMap, in, encodedArrayOut).transformArray();
+        new EncodedValueTransformer(in, indexMap, encodedArrayOut).readArray();
     }
 
     /**
diff --git a/dx/src/com/android/dx/merge/EncodedValueTransformer.java b/dx/src/com/android/dx/merge/EncodedValueTransformer.java
index bcf0d72..0959f15 100644
--- a/dx/src/com/android/dx/merge/EncodedValueTransformer.java
+++ b/dx/src/com/android/dx/merge/EncodedValueTransformer.java
@@ -17,121 +17,67 @@
 package com.android.dx.merge;
 
 import com.android.dx.io.DexBuffer;
+import com.android.dx.io.EncodedValueReader;
 import com.android.dx.util.Unsigned;
 
-final class EncodedValueTransformer {
-    private static final int ENCODED_BYTE = 0x00;
-    private static final int ENCODED_SHORT = 0x02;
-    private static final int ENCODED_CHAR = 0x03;
-    private static final int ENCODED_INT = 0x04;
-    private static final int ENCODED_LONG = 0x06;
-    private static final int ENCODED_FLOAT = 0x10;
-    private static final int ENCODED_DOUBLE = 0x11;
-    private static final int ENCODED_STRING = 0x17;
-    private static final int ENCODED_TYPE = 0x18;
-    private static final int ENCODED_FIELD = 0x19;
-    private static final int ENCODED_ENUM = 0x1b;
-    private static final int ENCODED_METHOD = 0x1a;
-    private static final int ENCODED_ARRAY = 0x1c;
-    private static final int ENCODED_ANNOTATION = 0x1d;
-    private static final int ENCODED_NULL = 0x1e;
-    private static final int ENCODED_BOOLEAN = 0x1f;
-
+public final class EncodedValueTransformer extends EncodedValueReader {
     private final IndexMap indexMap;
-    private final DexBuffer.Section in;
     private final DexBuffer.Section out;
 
-    public EncodedValueTransformer(IndexMap indexMap, DexBuffer.Section in, DexBuffer.Section out) {
+    public EncodedValueTransformer(DexBuffer.Section in, IndexMap indexMap, DexBuffer.Section out) {
+        super(in);
         this.indexMap = indexMap;
-        this.in = in;
         this.out = out;
     }
 
-    public void transformArray() {
-        int size = in.readUleb128(); // size
+    protected void visitArray(int size) {
         out.writeUleb128(size);
-        for (int i = 0; i < size; i++) {
-            transformValue();
-        }
     }
 
-    public void transformAnnotation() {
-        out.writeUleb128(indexMap.adjustType(in.readUleb128())); // type idx
-
-        int size = in.readUleb128(); // size
+    protected void visitAnnotation(int typeIndex, int size) {
+        out.writeUleb128(indexMap.adjustType(typeIndex));
         out.writeUleb128(size);
-
-        for (int i = 0; i < size; i++) {
-            out.writeUleb128(indexMap.adjustString(in.readUleb128())); // name idx
-            transformValue();
-        }
     }
 
-    public void transformValue() {
-        int argAndType = in.readByte() & 0xff;
-        int type = argAndType & 0x1f;
-        int arg = (argAndType & 0xe0) >> 5;
-        int size = arg + 1;
-
-        switch (type) {
-        case ENCODED_BYTE:
-        case ENCODED_SHORT:
-        case ENCODED_CHAR:
-        case ENCODED_INT:
-        case ENCODED_LONG:
-        case ENCODED_FLOAT:
-        case ENCODED_DOUBLE:
-            out.writeByte(argAndType);
-            copyBytes(in, out, size);
-            break;
-
-        case ENCODED_STRING:
-            int indexIn = readIndex(in, size);
-            int indexOut = indexMap.adjustString(indexIn);
-            writeTypeAndSizeAndIndex(type, indexOut, out);
-            break;
-        case ENCODED_TYPE:
-            indexIn = readIndex(in, size);
-            indexOut = indexMap.adjustType(indexIn);
-            writeTypeAndSizeAndIndex(type, indexOut, out);
-            break;
-        case ENCODED_FIELD:
-        case ENCODED_ENUM:
-            indexIn = readIndex(in, size);
-            indexOut = indexMap.adjustField(indexIn);
-            writeTypeAndSizeAndIndex(type, indexOut, out);
-            break;
-        case ENCODED_METHOD:
-            indexIn = readIndex(in, size);
-            indexOut = indexMap.adjustMethod(indexIn);
-            writeTypeAndSizeAndIndex(type, indexOut, out);
-            break;
-
-        case ENCODED_ARRAY:
-            out.writeByte(argAndType);
-            transformArray();
-            break;
-
-        case ENCODED_ANNOTATION:
-            out.writeByte(argAndType);
-            transformAnnotation();
-            break;
-
-        case ENCODED_NULL:
-        case ENCODED_BOOLEAN:
-            out.writeByte(argAndType);
-            break;
-        }
+    protected void visitAnnotationName(int index) {
+        out.writeUleb128(indexMap.adjustString(index));
     }
 
-    private int readIndex(DexBuffer.Section in, int byteCount) {
-        int result = 0;
-        int shift = 0;
-        for (int i = 0; i < byteCount; i++) {
-            result += (in.readByte() & 0xff) << shift;
-            shift += 8;
-        }
-        return result;
+    protected void visitPrimitive(int argAndType, int type, int arg, int size) {
+        out.writeByte(argAndType);
+        copyBytes(in, out, size);
+    }
+
+    protected void visitString(int type, int index) {
+        writeTypeAndSizeAndIndex(type, indexMap.adjustString(index), out);
+    }
+
+    protected void visitType(int type, int index) {
+        writeTypeAndSizeAndIndex(type, indexMap.adjustType(index), out);
+    }
+
+    protected void visitField(int type, int index) {
+        writeTypeAndSizeAndIndex(type, indexMap.adjustField(index), out);
+    }
+
+    protected void visitMethod(int type, int index) {
+        writeTypeAndSizeAndIndex(type, indexMap.adjustMethod(index), out);
+    }
+
+    protected void visitArrayValue(int argAndType) {
+        out.writeByte(argAndType);
+    }
+
+    protected void visitAnnotationValue(int argAndType) {
+        out.writeByte(argAndType);
+    }
+
+    protected void visitEncodedBoolean(int argAndType) {
+        out.writeByte(argAndType);
+    }
+
+    protected void visitEncodedNull(int argAndType) {
+        out.writeByte(argAndType);
     }
 
     private void writeTypeAndSizeAndIndex(int type, int index, DexBuffer.Section out) {
diff --git a/libdex/DexFile.h b/libdex/DexFile.h
index 06dc864..fd865e2 100644
--- a/libdex/DexFile.h
+++ b/libdex/DexFile.h
@@ -464,10 +464,7 @@
     /* pad for 64-bit alignment if necessary */
 } DexOptHeader;
 
-#define DEX_FLAG_VERIFIED           (1)     /* tried to verify all classes */
 #define DEX_OPT_FLAG_BIG            (1<<1)  /* swapped to big-endian */
-#define DEX_OPT_FLAG_FIELDS         (1<<2)  /* field access optimized */
-#define DEX_OPT_FLAG_INVOCATIONS    (1<<3)  /* method calls optimized */
 
 #define DEX_INTERFACE_CACHE_SIZE    128     /* must be power of 2 */
 
diff --git a/vm/Dvm.mk b/vm/Dvm.mk
index 8c10234..cf1332c 100644
--- a/vm/Dvm.mk
+++ b/vm/Dvm.mk
@@ -98,6 +98,7 @@
 	Hash.c \
 	IndirectRefTable.c.arm \
 	Init.c \
+	InitRefs.c \
 	InlineNative.c.arm \
 	Inlines.c \
 	Intern.c \
diff --git a/vm/DvmDex.c b/vm/DvmDex.c
index 500bf42..c5790e5 100644
--- a/vm/DvmDex.c
+++ b/vm/DvmDex.c
@@ -137,6 +137,7 @@
 
     /* tuck this into the DexFile so it gets released later */
     sysCopyMap(&pDvmDex->memMap, &memMap);
+    pDvmDex->isMappedReadOnly = true;
     *ppDvmDex = pDvmDex;
     result = 0;
 
@@ -175,6 +176,7 @@
         goto bail;
     }
 
+    pDvmDex->isMappedReadOnly = false;
     *ppDvmDex = pDvmDex;
     result = 0;
 
diff --git a/vm/DvmDex.h b/vm/DvmDex.h
index f36940b..ad82e54 100644
--- a/vm/DvmDex.h
+++ b/vm/DvmDex.h
@@ -58,6 +58,7 @@
     struct AtomicCache* pInterfaceCache;
 
     /* shared memory region with file contents */
+    bool                isMappedReadOnly;
     MemMapping          memMap;
 
     /* lock ensuring mutual exclusion during updates */
diff --git a/vm/Exception.c b/vm/Exception.c
index 02e0e2a..aaf97a4 100644
--- a/vm/Exception.c
+++ b/vm/Exception.c
@@ -99,93 +99,16 @@
 static bool initException(Object* exception, const char* msg, Object* cause,
     Thread* self);
 
-/*
- * Format the message into a small buffer and pass it along.
- */
-void dvmThrowExceptionFmtV(const char* exceptionDescriptor, const char* fmt,
-    va_list args)
-{
-    char msgBuf[512];
-
-    vsnprintf(msgBuf, sizeof(msgBuf), fmt, args);
-    dvmThrowChainedException(exceptionDescriptor, msgBuf, NULL);
-}
-
-void dvmThrowExceptionFmtByClassV(ClassObject* exceptionClass,
+void dvmThrowExceptionFmtV(ClassObject* exceptionClass,
     const char* fmt, va_list args)
 {
     char msgBuf[512];
 
     vsnprintf(msgBuf, sizeof(msgBuf), fmt, args);
-    dvmThrowChainedExceptionByClass(exceptionClass, msgBuf, NULL);
+    dvmThrowChainedException(exceptionClass, msgBuf, NULL);
 }
 
-/*
- * Create a Throwable and throw an exception in the current thread (where
- * "throwing" just means "set the thread's exception pointer").
- *
- * "msg" and/or "cause" may be NULL.
- *
- * If we have a bad exception hierarchy -- something in Throwable.<init>
- * is missing -- then every attempt to throw an exception will result
- * in another exception.  Exceptions are generally allowed to "chain"
- * to other exceptions, so it's hard to auto-detect this problem.  It can
- * only happen if the system classes are broken, so it's probably not
- * worth spending cycles to detect it.
- *
- * We do have one case to worry about: if the classpath is completely
- * wrong, we'll go into a death spin during startup because we can't find
- * the initial class and then we can't find NoClassDefFoundError.  We have
- * to handle this case.
- *
- * [Do we want to cache pointers to common exception classes?]
- */
-void dvmThrowChainedException(const char* exceptionDescriptor, const char* msg,
-    Object* cause)
-{
-    ClassObject* excepClass;
-
-    LOGV("THROW '%s' msg='%s' cause=%s\n",
-        exceptionDescriptor, msg,
-        (cause != NULL) ? cause->clazz->descriptor : "(none)");
-
-    if (gDvm.initializing) {
-        if (++gDvm.initExceptionCount >= 2) {
-            LOGE("Too many exceptions during init (failed on '%s' '%s')\n",
-                exceptionDescriptor, msg);
-            dvmAbort();
-        }
-    }
-
-    excepClass = dvmFindSystemClass(exceptionDescriptor);
-    if (excepClass == NULL) {
-        /*
-         * We couldn't find the exception class.  The attempt to find a
-         * nonexistent class should have raised an exception.  If no
-         * exception is currently raised, then we're pretty clearly unable
-         * to throw ANY sort of exception, and we need to pack it in.
-         *
-         * If we were able to throw the "class load failed" exception,
-         * stick with that.  Ideally we'd stuff the original exception
-         * into the "cause" field, but since we can't find it we can't
-         * do that.  The exception class name should be in the "message"
-         * field.
-         */
-        if (!dvmCheckException(dvmThreadSelf())) {
-            LOGE("FATAL: unable to throw exception (failed on '%s' '%s')\n",
-                exceptionDescriptor, msg);
-            dvmAbort();
-        }
-        return;
-    }
-
-    dvmThrowChainedExceptionByClass(excepClass, msg, cause);
-}
-
-/*
- * Start/continue throwing process now that we have a class reference.
- */
-void dvmThrowChainedExceptionByClass(ClassObject* excepClass, const char* msg,
+void dvmThrowChainedException(ClassObject* excepClass, const char* msg,
     Object* cause)
 {
     Thread* self = dvmThreadSelf();
@@ -207,7 +130,7 @@
             excepClass->descriptor);
         if (strcmp(excepClass->descriptor, "Ljava/lang/InternalError;") == 0)
             dvmAbort();
-        dvmThrowChainedExceptionByClass(gDvm.exInternalError,
+        dvmThrowChainedException(gDvm.exInternalError,
             "failed to init original exception class", cause);
         return;
     }
@@ -261,29 +184,13 @@
     dvmReleaseTrackedAlloc(exception, self);
 }
 
-/*
- * Throw the named exception using the human-readable form of the class
- * descriptor as the exception message, and with the specified cause.
- */
-void dvmThrowChainedExceptionWithClassMessage(const char* exceptionDescriptor,
-    const char* messageDescriptor, Object* cause)
-{
-    char* message = dvmHumanReadableDescriptor(messageDescriptor);
-
-    dvmThrowChainedException(exceptionDescriptor, message, cause);
-    free(message);
-}
-
-/*
- * Like dvmThrowException, but take a class object instead of a name
- * and turn the given message into the human-readable form for a descriptor.
- */
-void dvmThrowExceptionByClassWithClassMessage(ClassObject* exceptionClass,
-    const char* messageDescriptor)
+void dvmThrowChainedExceptionWithClassMessage(
+    ClassObject* exceptionClass, const char* messageDescriptor,
+    Object* cause)
 {
     char* message = dvmDescriptorToName(messageDescriptor);
 
-    dvmThrowExceptionByClass(exceptionClass, message);
+    dvmThrowChainedException(exceptionClass, message, cause);
     free(message);
 }
 
@@ -464,7 +371,7 @@
             excepClass->descriptor, msg, initKind);
         assert(strcmp(excepClass->descriptor,
                       "Ljava/lang/RuntimeException;") != 0);
-        dvmThrowChainedExceptionByClass(gDvm.exRuntimeException,
+        dvmThrowChainedException(gDvm.exRuntimeException,
             "re-throw on exception class missing constructor", NULL);
         goto bail;
     }
@@ -544,19 +451,15 @@
 
 
 /*
- * Clear the pending exception and the "initExceptionCount" counter.  This
- * is used by the optimization and verification code, which has to run with
- * "initializing" set to avoid going into a death-spin if the "class not
- * found" exception can't be found.
+ * Clear the pending exception. This is used by the optimization and
+ * verification code, which mostly happens during runs of dexopt.
  *
  * This can also be called when the VM is in a "normal" state, e.g. when
- * verifying classes that couldn't be verified at optimization time.  The
- * reset of initExceptionCount should be harmless in that case.
+ * verifying classes that couldn't be verified at optimization time.
  */
 void dvmClearOptException(Thread* self)
 {
     self->exception = NULL;
-    gDvm.initExceptionCount = 0;
 }
 
 /*
@@ -1300,16 +1203,16 @@
 }
 
 void dvmThrowAbstractMethodError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exAbstractMethodError, msg);
+    dvmThrowException(gDvm.exAbstractMethodError, msg);
 }
 
 void dvmThrowArithmeticException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exArithmeticException, msg);
+    dvmThrowException(gDvm.exArithmeticException, msg);
 }
 
-void dvmThrowArrayIndexOutOfBoundsException(int index, int length)
+void dvmThrowArrayIndexOutOfBoundsException(int length, int index)
 {
-    dvmThrowExceptionFmtByClass(gDvm.exArrayIndexOutOfBoundsException,
+    dvmThrowExceptionFmt(gDvm.exArrayIndexOutOfBoundsException,
         "length=%d; index=%d", length, index);
 }
 
@@ -1323,7 +1226,7 @@
 {
     char* actualClassName = dvmHumanReadableDescriptor(actual->descriptor);
     char* desiredClassName = dvmHumanReadableDescriptor(desired->descriptor);
-    dvmThrowExceptionFmtByClass(exceptionClass, fmt,
+    dvmThrowExceptionFmt(exceptionClass, fmt,
         actualClassName, desiredClassName);
     free(desiredClassName);
     free(actualClassName);
@@ -1343,22 +1246,22 @@
 }
 
 void dvmThrowClassCircularityError(const char* descriptor) {
-    dvmThrowExceptionByClassWithClassMessage(gDvm.exClassCircularityError,
+    dvmThrowExceptionWithClassMessage(gDvm.exClassCircularityError,
             descriptor);
 }
 
 void dvmThrowClassFormatError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exClassFormatError, msg);
+    dvmThrowException(gDvm.exClassFormatError, msg);
 }
 
 void dvmThrowClassNotFoundException(const char* name) {
     // TODO: Should the name be converted into human-readable form?
-    dvmThrowExceptionByClass(gDvm.exClassNotFoundException, name);
+    dvmThrowException(gDvm.exClassNotFoundException, name);
 }
 
 void dvmThrowChainedClassNotFoundException(const char* name, Object* cause) {
     // TODO: Should the name be converted into human-readable form?
-    dvmThrowChainedExceptionByClass(gDvm.exClassNotFoundException, name,
+    dvmThrowChainedException(gDvm.exClassNotFoundException, name,
             cause);
 }
 
@@ -1391,58 +1294,58 @@
     dvmAddTrackedAlloc(exception, self);
     dvmClearException(self);
 
-    dvmThrowChainedExceptionByClass(gDvm.exExceptionInInitializerError,
+    dvmThrowChainedException(gDvm.exExceptionInInitializerError,
             NULL, exception);
     dvmReleaseTrackedAlloc(exception, self);
 }
 
 void dvmThrowFileNotFoundException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exFileNotFoundException, msg);
+    dvmThrowException(gDvm.exFileNotFoundException, msg);
 }
 
 void dvmThrowIOException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exIOException, msg);
+    dvmThrowException(gDvm.exIOException, msg);
 }
 
 void dvmThrowIllegalAccessException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exIllegalAccessException, msg);
+    dvmThrowException(gDvm.exIllegalAccessException, msg);
 }
 
 void dvmThrowIllegalAccessError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exIllegalAccessError, msg);
+    dvmThrowException(gDvm.exIllegalAccessError, msg);
 }
 
 void dvmThrowIllegalArgumentException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exIllegalArgumentException, msg);
+    dvmThrowException(gDvm.exIllegalArgumentException, msg);
 }
 
 void dvmThrowIllegalMonitorStateException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exIllegalMonitorStateException, msg);
+    dvmThrowException(gDvm.exIllegalMonitorStateException, msg);
 }
 
 void dvmThrowIllegalStateException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exIllegalStateException, msg);
+    dvmThrowException(gDvm.exIllegalStateException, msg);
 }
 
 void dvmThrowIllegalThreadStateException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exIllegalThreadStateException, msg);
+    dvmThrowException(gDvm.exIllegalThreadStateException, msg);
 }
 
 void dvmThrowIncompatibleClassChangeError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exIncompatibleClassChangeError, msg);
+    dvmThrowException(gDvm.exIncompatibleClassChangeError, msg);
 }
 
 void dvmThrowIncompatibleClassChangeErrorWithClassMessage(
         const char* descriptor)
 {
-    dvmThrowExceptionByClassWithClassMessage(
+    dvmThrowExceptionWithClassMessage(
             gDvm.exIncompatibleClassChangeError, descriptor);
 }
 
 void dvmThrowInstantiationException(ClassObject* clazz,
         const char* extraDetail) {
     char* className = dvmHumanReadableDescriptor(clazz->descriptor);
-    dvmThrowExceptionFmtByClass(gDvm.exInstantiationException,
+    dvmThrowExceptionFmt(gDvm.exInstantiationException,
             "can't instantiate class %s%s%s", className,
             (extraDetail == NULL) ? "" : "; ",
             (extraDetail == NULL) ? "" : extraDetail);
@@ -1450,84 +1353,90 @@
 }
 
 void dvmThrowInternalError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exInternalError, msg);
+    dvmThrowException(gDvm.exInternalError, msg);
 }
 
 void dvmThrowInterruptedException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exInterruptedException, msg);
+    dvmThrowException(gDvm.exInterruptedException, msg);
 }
 
 void dvmThrowLinkageError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exLinkageError, msg);
+    dvmThrowException(gDvm.exLinkageError, msg);
 }
 
 void dvmThrowNegativeArraySizeException(s4 size) {
-    dvmThrowExceptionFmtByClass(gDvm.exNegativeArraySizeException, "%d", size);
+    dvmThrowExceptionFmt(gDvm.exNegativeArraySizeException, "%d", size);
 }
 
 void dvmThrowNoClassDefFoundError(const char* descriptor) {
-    dvmThrowExceptionByClassWithClassMessage(gDvm.exNoClassDefFoundError,
+    dvmThrowExceptionWithClassMessage(gDvm.exNoClassDefFoundError,
             descriptor);
 }
 
+void dvmThrowChainedNoClassDefFoundError(const char* descriptor,
+        Object* cause) {
+    dvmThrowChainedExceptionWithClassMessage(
+            gDvm.exNoClassDefFoundError, descriptor, cause);
+}
+
 void dvmThrowNoSuchFieldError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exNoSuchFieldError, msg);
+    dvmThrowException(gDvm.exNoSuchFieldError, msg);
 }
 
 void dvmThrowNoSuchFieldException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exNoSuchFieldException, msg);
+    dvmThrowException(gDvm.exNoSuchFieldException, msg);
 }
 
 void dvmThrowNoSuchMethodError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exNoSuchMethodError, msg);
+    dvmThrowException(gDvm.exNoSuchMethodError, msg);
 }
 
 void dvmThrowNullPointerException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exNullPointerException, msg);
+    dvmThrowException(gDvm.exNullPointerException, msg);
 }
 
 void dvmThrowOutOfMemoryError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exOutOfMemoryError, msg);
+    dvmThrowException(gDvm.exOutOfMemoryError, msg);
 }
 
 void dvmThrowRuntimeException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exRuntimeException, msg);
+    dvmThrowException(gDvm.exRuntimeException, msg);
 }
 
 void dvmThrowStaleDexCacheError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exStaleDexCacheError, msg);
+    dvmThrowException(gDvm.exStaleDexCacheError, msg);
 }
 
 void dvmThrowStringIndexOutOfBoundsExceptionWithIndex(jsize stringLength,
         jsize requestIndex) {
-    dvmThrowExceptionFmtByClass(gDvm.exStringIndexOutOfBoundsException,
+    dvmThrowExceptionFmt(gDvm.exStringIndexOutOfBoundsException,
             "length=%d; index=%d", stringLength, requestIndex);
 }
 
 void dvmThrowStringIndexOutOfBoundsExceptionWithRegion(jsize stringLength,
         jsize requestStart, jsize requestLength) {
-    dvmThrowExceptionFmtByClass(gDvm.exStringIndexOutOfBoundsException,
-            "length=%d; regionStart=%d regionLength=%d",
+    dvmThrowExceptionFmt(gDvm.exStringIndexOutOfBoundsException,
+            "length=%d; regionStart=%d; regionLength=%d",
             stringLength, requestStart, requestLength);
 }
 
 void dvmThrowTypeNotPresentException(const char* descriptor) {
-    dvmThrowExceptionByClassWithClassMessage(gDvm.exTypeNotPresentException,
+    dvmThrowExceptionWithClassMessage(gDvm.exTypeNotPresentException,
             descriptor);
 }
 
 void dvmThrowUnsatisfiedLinkError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exUnsatisfiedLinkError, msg);
+    dvmThrowException(gDvm.exUnsatisfiedLinkError, msg);
 }
 
 void dvmThrowUnsupportedOperationException(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exUnsupportedOperationException, msg);
+    dvmThrowException(gDvm.exUnsupportedOperationException, msg);
 }
 
 void dvmThrowVerifyError(const char* descriptor) {
-    dvmThrowExceptionByClassWithClassMessage(gDvm.exVerifyError, descriptor);
+    dvmThrowExceptionWithClassMessage(gDvm.exVerifyError, descriptor);
 }
 
 void dvmThrowVirtualMachineError(const char* msg) {
-    dvmThrowExceptionByClass(gDvm.exVirtualMachineError, msg);
+    dvmThrowException(gDvm.exVirtualMachineError, msg);
 }
diff --git a/vm/Exception.h b/vm/Exception.h
index 6d27437..3022e04 100644
--- a/vm/Exception.h
+++ b/vm/Exception.h
@@ -21,86 +21,70 @@
 #define _DALVIK_EXCEPTION
 
 /*
- * Throw an exception in the current thread, by class descriptor.
+ * Create a Throwable and throw an exception in the current thread (where
+ * "throwing" just means "set the thread's exception pointer").
+ *
+ * "msg" and/or "cause" may be NULL.
+ *
+ * If we have a bad exception hierarchy -- something in Throwable.<init>
+ * is missing -- then every attempt to throw an exception will result
+ * in another exception.  Exceptions are generally allowed to "chain"
+ * to other exceptions, so it's hard to auto-detect this problem.  It can
+ * only happen if the system classes are broken, so it's probably not
+ * worth spending cycles to detect it.
+ *
+ * We do have one case to worry about: if the classpath is completely
+ * wrong, we'll go into a death spin during startup because we can't find
+ * the initial class and then we can't find NoClassDefFoundError.  We have
+ * to handle this case.
  */
-void dvmThrowChainedException(const char* exceptionDescriptor, const char* msg,
-    Object* cause);
-INLINE void dvmThrowException(const char* exceptionDescriptor,
+void dvmThrowChainedException(ClassObject* exceptionClass,
+    const char* msg, Object* cause);
+INLINE void dvmThrowException(ClassObject* exceptionClass,
     const char* msg)
 {
-    dvmThrowChainedException(exceptionDescriptor, msg, NULL);
+    dvmThrowChainedException(exceptionClass, msg, NULL);
 }
 
 /*
  * Like dvmThrowException, but takes printf-style args for the message.
  */
-void dvmThrowExceptionFmtV(const char* exceptionDescriptor, const char* fmt,
-    va_list args);
-void dvmThrowExceptionFmt(const char* exceptionDescriptor, const char* fmt, ...)
-#if defined(__GNUC__)
-    __attribute__ ((format(printf, 2, 3)))
-#endif
-    ;
-INLINE void dvmThrowExceptionFmt(const char* exceptionDescriptor,
-    const char* fmt, ...)
-{
-    va_list args;
-    va_start(args, fmt);
-    dvmThrowExceptionFmtV(exceptionDescriptor, fmt, args);
-    va_end(args);
-}
-
-/*
- * Throw an exception in the current thread, by class object.
- */
-void dvmThrowChainedExceptionByClass(ClassObject* exceptionClass,
-    const char* msg, Object* cause);
-INLINE void dvmThrowExceptionByClass(ClassObject* exceptionClass,
-    const char* msg)
-{
-    dvmThrowChainedExceptionByClass(exceptionClass, msg, NULL);
-}
-
-/*
- * Like dvmThrowExceptionFmt, but takes an exception class object instead
- * of a descriptor string.
- */
-void dvmThrowExceptionFmtByClassV(ClassObject* exceptionClass,
+void dvmThrowExceptionFmtV(ClassObject* exceptionClass,
     const char* fmt, va_list args);
-void dvmThrowExceptionFmtByClass(ClassObject* exceptionClass,
+void dvmThrowExceptionFmt(ClassObject* exceptionClass,
     const char* fmt, ...)
 #if defined(__GNUC__)
     __attribute__ ((format(printf, 2, 3)))
 #endif
     ;
-INLINE void dvmThrowExceptionFmtByClass(ClassObject* exceptionClass,
+INLINE void dvmThrowExceptionFmt(ClassObject* exceptionClass,
     const char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
-    dvmThrowExceptionFmtByClassV(exceptionClass, fmt, args);
+    dvmThrowExceptionFmtV(exceptionClass, fmt, args);
     va_end(args);
 }
 
 /*
- * Throw the named exception using the human-readable form of the class
- * descriptor as the exception message, and with the specified cause.
+ * Like dvmThrowChainedException, but take a class object
+ * instead of a name and turn the given message into the
+ * human-readable form for a descriptor.
  */
-void dvmThrowChainedExceptionWithClassMessage(const char* exceptionDescriptor,
-    const char* messageDescriptor, Object* cause);
-INLINE void dvmThrowExceptionWithClassMessage(const char* exceptionDescriptor,
-    const char* messageDescriptor)
-{
-    dvmThrowChainedExceptionWithClassMessage(exceptionDescriptor,
-        messageDescriptor, NULL);
-}
+void dvmThrowChainedExceptionWithClassMessage(
+    ClassObject* exceptionClass, const char* messageDescriptor,
+    Object* cause);
 
 /*
  * Like dvmThrowException, but take a class object instead of a name
  * and turn the given message into the human-readable form for a descriptor.
  */
-void dvmThrowExceptionByClassWithClassMessage(ClassObject* exceptionClass,
-    const char* messageDescriptor);
+INLINE void dvmThrowExceptionWithClassMessage(
+    ClassObject* exceptionClass, const char* messageDescriptor)
+{
+    dvmThrowChainedExceptionWithClassMessage(exceptionClass,
+            messageDescriptor, NULL);
+}
 
 /*
  * Return the exception being thrown in the current thread, or NULL if
@@ -231,9 +215,9 @@
 
 /*
  * Throw an ArrayIndexOutOfBoundsException in the current thread,
- * using the given index and array length in the detail message.
+ * using the given array length and index in the detail message.
  */
-void dvmThrowArrayIndexOutOfBoundsException(int index, int length);
+void dvmThrowArrayIndexOutOfBoundsException(int length, int index);
 
 /*
  * Throw an ArrayStoreException in the current thread, using the given classes'
@@ -378,6 +362,14 @@
 void dvmThrowNoClassDefFoundError(const char* descriptor);
 
 /**
+ * Throw a NoClassDefFoundError in the current thread, with the given
+ * cause, and the human-readable form of the given descriptor as the
+ * detail message.
+ */
+void dvmThrowChainedNoClassDefFoundError(const char* descriptor,
+        Object* cause);
+
+/**
  * Throw a NoSuchFieldError in the current thread, with the given
  * detail message.
  */
diff --git a/vm/Globals.h b/vm/Globals.h
index a4b47a6..e595df3 100644
--- a/vm/Globals.h
+++ b/vm/Globals.h
@@ -178,7 +178,6 @@
      * VM init management.
      */
     bool        initializing;
-    int         initExceptionCount;
     bool        optimizing;
 
     /*
@@ -286,6 +285,7 @@
     ClassObject* exIllegalStateException;
     ClassObject* exIllegalThreadStateException;
     ClassObject* exIncompatibleClassChangeError;
+    ClassObject* exInstantiationError;
     ClassObject* exInstantiationException;
     ClassObject* exInternalError;
     ClassObject* exInterruptedException;
@@ -506,10 +506,14 @@
      */
 #ifdef USE_INDIRECT_REF
     IndirectRefTable jniGlobalRefTable;
+    IndirectRefTable jniWeakGlobalRefTable;
 #else
     ReferenceTable  jniGlobalRefTable;
 #endif
     pthread_mutex_t jniGlobalRefLock;
+#ifdef USE_INDIRECT_REF
+    pthread_mutex_t jniWeakGlobalRefLock;
+#endif
     int         jniGlobalRefHiMark;
     int         jniGlobalRefLoMark;
 
diff --git a/vm/IndirectRefTable.c b/vm/IndirectRefTable.c
index f940653..0a69f3c 100644
--- a/vm/IndirectRefTable.c
+++ b/vm/IndirectRefTable.c
@@ -27,7 +27,7 @@
 {
     assert(initialCount > 0);
     assert(initialCount <= maxCount);
-    assert(kind == kIndirectKindLocal || kind == kIndirectKindGlobal);
+    assert(kind != kIndirectKindInvalid);
 
     pRef->table = (Object**) malloc(initialCount * sizeof(Object*));
     if (pRef->table == NULL)
diff --git a/vm/Init.c b/vm/Init.c
index e4d05ee..33d808b 100644
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -1145,185 +1145,6 @@
 }
 
 /*
- * Helper for dvmInitRequiredClassesAndMembers(), which looks up
- * classes and stores them to the indicated pointer, returning a
- * failure code (false == failure).
- */
-static bool initRef(ClassObject** pClass, const char* name)
-{
-    ClassObject* result;
-
-    if (*pClass != NULL) {
-        /*
-         * There are a couple cases where it's legit to call this
-         * function with an already-initialized reference, so just
-         * silently tolerate this instead of complaining loudly.
-         */
-        return true;
-    }
-
-    if (name[0] == '[') {
-        result = dvmFindArrayClass(name, NULL);
-    } else {
-        result = dvmFindSystemClassNoInit(name);
-    }
-
-    if (result == NULL) {
-        LOGE("Could not find essential class %s\n", name);
-        return false;
-    }
-
-    *pClass = result;
-    return true;
-}
-
-/* (documented in header) */
-int dvmFindRequiredClassesAndMembers(void) {
-    /*
-     * Note: Under normal VM use, this is called by dvmStartup()
-     * below. For dex optimization, this is called as well, but in
-     * that case, the call is made from DexPrepare.c.
-     */
-
-    bool ok = true;
-
-    /* The corest of the core classes */
-
-    ok &= initRef(&gDvm.classJavaLangClass, "Ljava/lang/Class;");
-    ok &= initRef(&gDvm.classJavaLangObject, "Ljava/lang/Object;");
-
-    ok &= initRef(&gDvm.classJavaLangString, "Ljava/lang/String;");
-    ok &= initRef(&gDvm.classJavaLangThread, "Ljava/lang/Thread;");
-    ok &= initRef(&gDvm.classJavaLangThreadGroup, "Ljava/lang/ThreadGroup;");
-    ok &= initRef(&gDvm.exThrowable, "Ljava/lang/Throwable;");
-    ok &= initRef(&gDvm.classJavaLangVMThread, "Ljava/lang/VMThread;");
-
-    /* Exception classes and related support classes */
-
-    ok &= initRef(&gDvm.exAbstractMethodError,
-            "Ljava/lang/AbstractMethodError;");
-    ok &= initRef(&gDvm.exArithmeticException,
-            "Ljava/lang/ArithmeticException;");
-    ok &= initRef(&gDvm.exArrayIndexOutOfBoundsException,
-            "Ljava/lang/ArrayIndexOutOfBoundsException;");
-    ok &= initRef(&gDvm.exArrayStoreException,
-            "Ljava/lang/ArrayStoreException;");
-    ok &= initRef(&gDvm.exClassCastException,
-            "Ljava/lang/ClassCastException;");
-    ok &= initRef(&gDvm.exClassCircularityError,
-            "Ljava/lang/ClassCircularityError;");
-    ok &= initRef(&gDvm.exClassNotFoundException,
-            "Ljava/lang/ClassNotFoundException;");
-    ok &= initRef(&gDvm.exClassFormatError, "Ljava/lang/ClassFormatError;");
-    ok &= initRef(&gDvm.exError, "Ljava/lang/Error;");
-    ok &= initRef(&gDvm.exExceptionInInitializerError,
-            "Ljava/lang/ExceptionInInitializerError;");
-    ok &= initRef(&gDvm.exFileNotFoundException,
-            "Ljava/io/FileNotFoundException;");
-    ok &= initRef(&gDvm.exIOException, "Ljava/io/IOException;");
-    ok &= initRef(&gDvm.exIllegalAccessError,
-            "Ljava/lang/IllegalAccessError;");
-    ok &= initRef(&gDvm.exIllegalAccessException,
-            "Ljava/lang/IllegalAccessException;");
-    ok &= initRef(&gDvm.exIllegalArgumentException,
-            "Ljava/lang/IllegalArgumentException;");
-    ok &= initRef(&gDvm.exIllegalMonitorStateException,
-            "Ljava/lang/IllegalMonitorStateException;");
-    ok &= initRef(&gDvm.exIllegalStateException,
-            "Ljava/lang/IllegalStateException;");
-    ok &= initRef(&gDvm.exIllegalThreadStateException,
-            "Ljava/lang/IllegalThreadStateException;");
-    ok &= initRef(&gDvm.exIncompatibleClassChangeError,
-            "Ljava/lang/IncompatibleClassChangeError;");
-    ok &= initRef(&gDvm.exInstantiationException,
-            "Ljava/lang/InstantiationException;");
-    ok &= initRef(&gDvm.exInternalError,
-            "Ljava/lang/InternalError;");
-    ok &= initRef(&gDvm.exInterruptedException,
-            "Ljava/lang/InterruptedException;");
-    ok &= initRef(&gDvm.exLinkageError,
-            "Ljava/lang/LinkageError;");
-    ok &= initRef(&gDvm.exNegativeArraySizeException,
-            "Ljava/lang/NegativeArraySizeException;");
-    ok &= initRef(&gDvm.exNoClassDefFoundError,
-            "Ljava/lang/NoClassDefFoundError;");
-    ok &= initRef(&gDvm.exNoSuchFieldError,
-            "Ljava/lang/NoSuchFieldError;");
-    ok &= initRef(&gDvm.exNoSuchFieldException,
-            "Ljava/lang/NoSuchFieldException;");
-    ok &= initRef(&gDvm.exNoSuchMethodError,
-            "Ljava/lang/NoSuchMethodError;");
-    ok &= initRef(&gDvm.exNullPointerException,
-            "Ljava/lang/NullPointerException;");
-    ok &= initRef(&gDvm.exOutOfMemoryError,
-            "Ljava/lang/OutOfMemoryError;");
-    ok &= initRef(&gDvm.exRuntimeException, "Ljava/lang/RuntimeException;");
-    ok &= initRef(&gDvm.exStackOverflowError,
-            "Ljava/lang/StackOverflowError;");
-    ok &= initRef(&gDvm.exStaleDexCacheError,
-            "Ldalvik/system/StaleDexCacheError;");
-    ok &= initRef(&gDvm.exStringIndexOutOfBoundsException,
-            "Ljava/lang/StringIndexOutOfBoundsException;");
-    ok &= initRef(&gDvm.exThrowable, "Ljava/lang/Throwable;");
-    ok &= initRef(&gDvm.exTypeNotPresentException,
-            "Ljava/lang/TypeNotPresentException;");
-    ok &= initRef(&gDvm.exUnsatisfiedLinkError,
-            "Ljava/lang/UnsatisfiedLinkError;");
-    ok &= initRef(&gDvm.exUnsupportedOperationException,
-            "Ljava/lang/UnsupportedOperationException;");
-    ok &= initRef(&gDvm.exVerifyError,
-            "Ljava/lang/VerifyError;");
-    ok &= initRef(&gDvm.exVirtualMachineError,
-            "Ljava/lang/VirtualMachineError;");
-
-    ok &= initRef(&gDvm.classJavaLangStackTraceElement,
-            "Ljava/lang/StackTraceElement;");
-    ok &= initRef(&gDvm.classJavaLangStackTraceElementArray,
-            "[Ljava/lang/StackTraceElement;");
-
-    if (!ok) {
-        return false;
-    }
-
-    /*
-     * Find the StackTraceElement constructor. Note that, unlike other
-     * saved method lookups, we're using a Method* instead of a vtable
-     * offset. This is because constructors don't have vtable offsets.
-     * (Also, since we're creating the object in question, it's
-     * impossible for anyone to sub-class it.)
-     */
-    Method* meth;
-    meth = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangStackTraceElement,
-        "<init>",
-        "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
-    if (meth == NULL) {
-        LOGE("Unable to find constructor for StackTraceElement\n");
-        return false;
-    }
-    gDvm.methJavaLangStackTraceElement_init = meth;
-
-    /* grab an offset for the field Throwable.stackState */
-    gDvm.offJavaLangThrowable_stackState =
-        dvmFindFieldOffset(gDvm.exThrowable,
-            "stackState", "Ljava/lang/Object;");
-    if (gDvm.offJavaLangThrowable_stackState < 0) {
-        LOGE("Unable to find Throwable.stackState\n");
-        return false;
-    }
-
-    /* and one for the field Throwable.cause, just 'cause */
-    gDvm.offJavaLangThrowable_cause =
-        dvmFindFieldOffset(gDvm.exThrowable,
-            "cause", "Ljava/lang/Throwable;");
-    if (gDvm.offJavaLangThrowable_cause < 0) {
-        LOGE("Unable to find Throwable.cause\n");
-        return false;
-    }
-
-    return true;
-}
-
-/*
  * VM initialization.  Pass in any options provided on the command line.
  * Do not pass in the class name or the options for the class.
  *
@@ -1416,10 +1237,6 @@
     if (!dvmFindRequiredClassesAndMembers())
         goto fail;
 
-    if (!dvmBaseClassStartup())
-        goto fail;
-    if (!dvmThreadObjStartup())
-        goto fail;
     if (!dvmStringInternStartup())
         goto fail;
     if (!dvmNativeStartup())
@@ -1428,8 +1245,6 @@
         goto fail;
     if (!dvmJniStartup())
         goto fail;
-    if (!dvmReflectStartup())
-        goto fail;
     if (!dvmProfilingStartup())
         goto fail;
 
@@ -1520,7 +1335,6 @@
 #endif
 
     assert(!dvmCheckException(dvmThreadSelf()));
-    gDvm.initExceptionCount = 0;
 
     return 0;
 
@@ -1837,7 +1651,6 @@
         LOGD("VM cleaning up\n");
 
     dvmDebuggerShutdown();
-    dvmReflectShutdown();
     dvmProfilingShutdown();
     dvmJniShutdown();
     dvmStringInternShutdown();
diff --git a/vm/Init.h b/vm/Init.h
index 06b93af..60f6bf3 100644
--- a/vm/Init.h
+++ b/vm/Init.h
@@ -45,8 +45,10 @@
  * storing references to them into the globals instance. See
  * Globals.h. This function is exposed so that dex optimization may
  * call it (while avoiding doing other unnecessary VM initialization).
+ *
+ * The function returns a success flag (true == success).
  */
-int dvmFindRequiredClassesAndMembers(void);
+bool dvmFindRequiredClassesAndMembers(void);
 
 /*
  * Replacement for fprintf() when we want to send a message to the console.
diff --git a/vm/InitRefs.c b/vm/InitRefs.c
new file mode 100644
index 0000000..242db43
--- /dev/null
+++ b/vm/InitRefs.c
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * Code to initialize references to classes and members for use by
+ * lower-level VM facilities
+ */
+
+#include "Dalvik.h"
+
+/*
+ * Helper for dvmInitRequiredClassesAndMembers(), which looks up
+ * classes and stores them to the indicated pointer, returning a
+ * failure code (false == failure).
+ */
+static bool initRef(ClassObject** pClass, const char* name) {
+    ClassObject* result;
+
+    if (*pClass != NULL) {
+        /*
+         * There are a couple cases where it's legit to call this
+         * function with an already-initialized reference, so just
+         * silently tolerate this instead of complaining loudly.
+         */
+        return true;
+    }
+
+    if (name[0] == '[') {
+        result = dvmFindArrayClass(name, NULL);
+    } else {
+        result = dvmFindSystemClassNoInit(name);
+    }
+
+    if (result == NULL) {
+        LOGE("Could not find essential class %s\n", name);
+        return false;
+    }
+
+    *pClass = result;
+    return true;
+}
+
+static bool find1(void) {
+    /*
+     * Note: Under normal VM use, this is called by dvmStartup()
+     * in Init.c. For dex optimization, this is called as well, but in
+     * that case, the call is made from DexPrepare.c.
+     */
+
+    bool ok = true;
+
+    /* The corest of the core classes */
+
+    ok &= initRef(&gDvm.classJavaLangClass, "Ljava/lang/Class;");
+    ok &= initRef(&gDvm.classJavaLangObject, "Ljava/lang/Object;");
+    ok &= initRef(&gDvm.exThrowable, "Ljava/lang/Throwable;");
+
+    ok &= initRef(&gDvm.classJavaLangString, "Ljava/lang/String;");
+    ok &= initRef(&gDvm.classJavaLangThread, "Ljava/lang/Thread;");
+    ok &= initRef(&gDvm.classJavaLangThreadGroup, "Ljava/lang/ThreadGroup;");
+    ok &= initRef(&gDvm.classJavaLangVMThread, "Ljava/lang/VMThread;");
+
+    /* Exception classes and related support classes */
+
+    ok &= initRef(&gDvm.exAbstractMethodError,
+            "Ljava/lang/AbstractMethodError;");
+    ok &= initRef(&gDvm.exArithmeticException,
+            "Ljava/lang/ArithmeticException;");
+    ok &= initRef(&gDvm.exArrayIndexOutOfBoundsException,
+            "Ljava/lang/ArrayIndexOutOfBoundsException;");
+    ok &= initRef(&gDvm.exArrayStoreException,
+            "Ljava/lang/ArrayStoreException;");
+    ok &= initRef(&gDvm.exClassCastException,
+            "Ljava/lang/ClassCastException;");
+    ok &= initRef(&gDvm.exClassCircularityError,
+            "Ljava/lang/ClassCircularityError;");
+    ok &= initRef(&gDvm.exClassNotFoundException,
+            "Ljava/lang/ClassNotFoundException;");
+    ok &= initRef(&gDvm.exClassFormatError, "Ljava/lang/ClassFormatError;");
+    ok &= initRef(&gDvm.exError, "Ljava/lang/Error;");
+    ok &= initRef(&gDvm.exExceptionInInitializerError,
+            "Ljava/lang/ExceptionInInitializerError;");
+    ok &= initRef(&gDvm.exFileNotFoundException,
+            "Ljava/io/FileNotFoundException;");
+    ok &= initRef(&gDvm.exIOException, "Ljava/io/IOException;");
+    ok &= initRef(&gDvm.exIllegalAccessError,
+            "Ljava/lang/IllegalAccessError;");
+    ok &= initRef(&gDvm.exIllegalAccessException,
+            "Ljava/lang/IllegalAccessException;");
+    ok &= initRef(&gDvm.exIllegalArgumentException,
+            "Ljava/lang/IllegalArgumentException;");
+    ok &= initRef(&gDvm.exIllegalMonitorStateException,
+            "Ljava/lang/IllegalMonitorStateException;");
+    ok &= initRef(&gDvm.exIllegalStateException,
+            "Ljava/lang/IllegalStateException;");
+    ok &= initRef(&gDvm.exIllegalThreadStateException,
+            "Ljava/lang/IllegalThreadStateException;");
+    ok &= initRef(&gDvm.exIncompatibleClassChangeError,
+            "Ljava/lang/IncompatibleClassChangeError;");
+    ok &= initRef(&gDvm.exInstantiationError,
+            "Ljava/lang/InstantiationError;");
+    ok &= initRef(&gDvm.exInstantiationException,
+            "Ljava/lang/InstantiationException;");
+    ok &= initRef(&gDvm.exInternalError,
+            "Ljava/lang/InternalError;");
+    ok &= initRef(&gDvm.exInterruptedException,
+            "Ljava/lang/InterruptedException;");
+    ok &= initRef(&gDvm.exLinkageError,
+            "Ljava/lang/LinkageError;");
+    ok &= initRef(&gDvm.exNegativeArraySizeException,
+            "Ljava/lang/NegativeArraySizeException;");
+    ok &= initRef(&gDvm.exNoClassDefFoundError,
+            "Ljava/lang/NoClassDefFoundError;");
+    ok &= initRef(&gDvm.exNoSuchFieldError,
+            "Ljava/lang/NoSuchFieldError;");
+    ok &= initRef(&gDvm.exNoSuchFieldException,
+            "Ljava/lang/NoSuchFieldException;");
+    ok &= initRef(&gDvm.exNoSuchMethodError,
+            "Ljava/lang/NoSuchMethodError;");
+    ok &= initRef(&gDvm.exNullPointerException,
+            "Ljava/lang/NullPointerException;");
+    ok &= initRef(&gDvm.exOutOfMemoryError,
+            "Ljava/lang/OutOfMemoryError;");
+    ok &= initRef(&gDvm.exRuntimeException, "Ljava/lang/RuntimeException;");
+    ok &= initRef(&gDvm.exStackOverflowError,
+            "Ljava/lang/StackOverflowError;");
+    ok &= initRef(&gDvm.exStaleDexCacheError,
+            "Ldalvik/system/StaleDexCacheError;");
+    ok &= initRef(&gDvm.exStringIndexOutOfBoundsException,
+            "Ljava/lang/StringIndexOutOfBoundsException;");
+    ok &= initRef(&gDvm.exTypeNotPresentException,
+            "Ljava/lang/TypeNotPresentException;");
+    ok &= initRef(&gDvm.exUnsatisfiedLinkError,
+            "Ljava/lang/UnsatisfiedLinkError;");
+    ok &= initRef(&gDvm.exUnsupportedOperationException,
+            "Ljava/lang/UnsupportedOperationException;");
+    ok &= initRef(&gDvm.exVerifyError,
+            "Ljava/lang/VerifyError;");
+    ok &= initRef(&gDvm.exVirtualMachineError,
+            "Ljava/lang/VirtualMachineError;");
+
+    ok &= initRef(&gDvm.classJavaLangStackTraceElement,
+            "Ljava/lang/StackTraceElement;");
+    ok &= initRef(&gDvm.classJavaLangStackTraceElementArray,
+            "[Ljava/lang/StackTraceElement;");
+
+    if (!ok) {
+        return false;
+    }
+
+    /*
+     * Find the StackTraceElement constructor. Note that, unlike other
+     * saved method lookups, we're using a Method* instead of a vtable
+     * offset. This is because constructors don't have vtable offsets.
+     * (Also, since we're creating the object in question, it's
+     * impossible for anyone to sub-class it.)
+     */
+    Method* meth;
+    meth = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangStackTraceElement,
+        "<init>",
+        "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
+    if (meth == NULL) {
+        LOGE("Unable to find constructor for StackTraceElement\n");
+        return false;
+    }
+    gDvm.methJavaLangStackTraceElement_init = meth;
+
+    /* grab an offset for the field Throwable.stackState */
+    gDvm.offJavaLangThrowable_stackState =
+        dvmFindFieldOffset(gDvm.exThrowable,
+            "stackState", "Ljava/lang/Object;");
+    if (gDvm.offJavaLangThrowable_stackState < 0) {
+        LOGE("Unable to find Throwable.stackState\n");
+        return false;
+    }
+
+    /* and one for the field Throwable.cause, just 'cause */
+    gDvm.offJavaLangThrowable_cause =
+        dvmFindFieldOffset(gDvm.exThrowable,
+            "cause", "Ljava/lang/Throwable;");
+    if (gDvm.offJavaLangThrowable_cause < 0) {
+        LOGE("Unable to find Throwable.cause\n");
+        return false;
+    }
+
+    return true;
+}
+
+static bool find2(void) {
+    ClassObject* clClass = dvmFindSystemClassNoInit("Ljava/lang/ClassLoader;");
+    Method* meth = dvmFindVirtualMethodByDescriptor(clClass, "loadClass",
+            "(Ljava/lang/String;)Ljava/lang/Class;");
+    if (meth == NULL) {
+        LOGE("Unable to find loadClass() in java.lang.ClassLoader\n");
+        return false;
+    }
+    gDvm.voffJavaLangClassLoader_loadClass = meth->methodIndex;
+
+    return true;
+}
+
+static bool find3(void) {
+    assert(gDvm.classJavaLangThread != NULL);
+    assert(gDvm.classJavaLangThreadGroup != NULL);
+    assert(gDvm.classJavaLangVMThread != NULL);
+
+    /*
+     * Cache field offsets.  This makes things a little faster, at the
+     * expense of hard-coding non-public field names into the VM.
+     */
+    gDvm.offJavaLangThread_vmThread =
+        dvmFindFieldOffset(gDvm.classJavaLangThread,
+            "vmThread", "Ljava/lang/VMThread;");
+    gDvm.offJavaLangThread_group =
+        dvmFindFieldOffset(gDvm.classJavaLangThread,
+            "group", "Ljava/lang/ThreadGroup;");
+    gDvm.offJavaLangThread_daemon =
+        dvmFindFieldOffset(gDvm.classJavaLangThread, "daemon", "Z");
+    gDvm.offJavaLangThread_name =
+        dvmFindFieldOffset(gDvm.classJavaLangThread,
+            "name", "Ljava/lang/String;");
+    gDvm.offJavaLangThread_priority =
+        dvmFindFieldOffset(gDvm.classJavaLangThread, "priority", "I");
+
+    if (gDvm.offJavaLangThread_vmThread < 0 ||
+        gDvm.offJavaLangThread_group < 0 ||
+        gDvm.offJavaLangThread_daemon < 0 ||
+        gDvm.offJavaLangThread_name < 0 ||
+        gDvm.offJavaLangThread_priority < 0)
+    {
+        LOGE("Unable to find all fields in java.lang.Thread\n");
+        return false;
+    }
+
+    gDvm.offJavaLangVMThread_thread =
+        dvmFindFieldOffset(gDvm.classJavaLangVMThread,
+            "thread", "Ljava/lang/Thread;");
+    gDvm.offJavaLangVMThread_vmData =
+        dvmFindFieldOffset(gDvm.classJavaLangVMThread, "vmData", "I");
+    if (gDvm.offJavaLangVMThread_thread < 0 ||
+        gDvm.offJavaLangVMThread_vmData < 0)
+    {
+        LOGE("Unable to find all fields in java.lang.VMThread\n");
+        return false;
+    }
+
+    /*
+     * Cache the vtable offset for "run()".
+     *
+     * We don't want to keep the Method* because then we won't find see
+     * methods defined in subclasses.
+     */
+    Method* meth;
+    meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThread, "run", "()V");
+    if (meth == NULL) {
+        LOGE("Unable to find run() in java.lang.Thread\n");
+        return false;
+    }
+    gDvm.voffJavaLangThread_run = meth->methodIndex;
+
+    /*
+     * Cache vtable offsets for ThreadGroup methods.
+     */
+    meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThreadGroup,
+        "removeThread", "(Ljava/lang/Thread;)V");
+    if (meth == NULL) {
+        LOGE("Unable to find removeThread(Thread) in java.lang.ThreadGroup\n");
+        return false;
+    }
+    gDvm.voffJavaLangThreadGroup_removeThread = meth->methodIndex;
+
+    return true;
+}
+
+static bool find4(void) {
+    Method* meth;
+
+    /*
+     * Grab the PhantomReference constructor.
+     */
+    gDvm.classJavaLangRefPhantomReference =
+        dvmFindSystemClassNoInit("Ljava/lang/ref/PhantomReference;");
+    if (gDvm.classJavaLangRefPhantomReference == NULL) {
+        LOGE("Unable to find PhantomReference class\n");
+        return false;
+    }
+    meth= dvmFindDirectMethodByDescriptor(gDvm.classJavaLangRefPhantomReference,
+        "<init>", "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V");
+    if (meth == NULL) {
+        LOGE("Unable to find constructor for PhantomReference\n");
+        return false;
+    }
+    gDvm.methJavaLangRefPhantomReference_init = meth;
+
+
+    /*
+     * Look up and cache pointers to some direct buffer classes, fields,
+     * and methods.
+     */
+    ClassObject* readWriteBufferClass =
+        dvmFindSystemClassNoInit("Ljava/nio/ReadWriteDirectByteBuffer;");
+    ClassObject* bufferClass =
+        dvmFindSystemClassNoInit("Ljava/nio/Buffer;");
+
+    if (readWriteBufferClass == NULL || bufferClass == NULL) {
+        LOGE("Unable to find internal direct buffer classes\n");
+        return false;
+    }
+    gDvm.classJavaNioReadWriteDirectByteBuffer = readWriteBufferClass;
+
+    meth = dvmFindDirectMethodByDescriptor(readWriteBufferClass,
+                "<init>",
+                "(II)V");
+    if (meth == NULL) {
+        LOGE("Unable to find ReadWriteDirectByteBuffer.<init>\n");
+        return false;
+    }
+    gDvm.methJavaNioReadWriteDirectByteBuffer_init = meth;
+
+    gDvm.offJavaNioBuffer_capacity =
+        dvmFindFieldOffset(bufferClass, "capacity", "I");
+    if (gDvm.offJavaNioBuffer_capacity < 0) {
+        LOGE("Unable to find Buffer.capacity\n");
+        return false;
+    }
+
+    gDvm.offJavaNioBuffer_effectiveDirectAddress =
+        dvmFindFieldOffset(bufferClass, "effectiveDirectAddress", "I");
+    if (gDvm.offJavaNioBuffer_effectiveDirectAddress < 0) {
+        LOGE("Unable to find Buffer.effectiveDirectAddress\n");
+        return false;
+    }
+
+    return true;
+}
+
+static bool find5(void)
+{
+    gDvm.classJavaLangReflectAccessibleObject =
+        dvmFindSystemClassNoInit("Ljava/lang/reflect/AccessibleObject;");
+    gDvm.classJavaLangReflectConstructor =
+        dvmFindSystemClassNoInit("Ljava/lang/reflect/Constructor;");
+    gDvm.classJavaLangReflectConstructorArray =
+        dvmFindArrayClass("[Ljava/lang/reflect/Constructor;", NULL);
+    gDvm.classJavaLangReflectField =
+        dvmFindSystemClassNoInit("Ljava/lang/reflect/Field;");
+    gDvm.classJavaLangReflectFieldArray =
+        dvmFindArrayClass("[Ljava/lang/reflect/Field;", NULL);
+    gDvm.classJavaLangReflectMethod =
+        dvmFindSystemClassNoInit("Ljava/lang/reflect/Method;");
+    gDvm.classJavaLangReflectMethodArray =
+        dvmFindArrayClass("[Ljava/lang/reflect/Method;", NULL);
+    gDvm.classJavaLangReflectProxy =
+        dvmFindSystemClassNoInit("Ljava/lang/reflect/Proxy;");
+    if (gDvm.classJavaLangReflectAccessibleObject == NULL ||
+        gDvm.classJavaLangReflectConstructor == NULL ||
+        gDvm.classJavaLangReflectConstructorArray == NULL ||
+        gDvm.classJavaLangReflectField == NULL ||
+        gDvm.classJavaLangReflectFieldArray == NULL ||
+        gDvm.classJavaLangReflectMethod == NULL ||
+        gDvm.classJavaLangReflectMethodArray == NULL ||
+        gDvm.classJavaLangReflectProxy == NULL)
+    {
+        LOGE("Could not find one or more reflection classes\n");
+        return false;
+    }
+
+    gDvm.methJavaLangReflectConstructor_init =
+        dvmFindDirectMethodByDescriptor(gDvm.classJavaLangReflectConstructor, "<init>",
+        "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;I)V");
+    gDvm.methJavaLangReflectField_init =
+        dvmFindDirectMethodByDescriptor(gDvm.classJavaLangReflectField, "<init>",
+        "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;I)V");
+    gDvm.methJavaLangReflectMethod_init =
+        dvmFindDirectMethodByDescriptor(gDvm.classJavaLangReflectMethod, "<init>",
+        "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;I)V");
+    if (gDvm.methJavaLangReflectConstructor_init == NULL ||
+        gDvm.methJavaLangReflectField_init == NULL ||
+        gDvm.methJavaLangReflectMethod_init == NULL)
+    {
+        LOGE("Could not find reflection constructors\n");
+        return false;
+    }
+
+    gDvm.classJavaLangClassArray =
+        dvmFindArrayClass("[Ljava/lang/Class;", NULL);
+    gDvm.classJavaLangObjectArray =
+        dvmFindArrayClass("[Ljava/lang/Object;", NULL);
+    if (gDvm.classJavaLangClassArray == NULL ||
+        gDvm.classJavaLangObjectArray == NULL)
+    {
+        LOGE("Could not find class-array or object-array class\n");
+        return false;
+    }
+
+    gDvm.offJavaLangReflectAccessibleObject_flag =
+        dvmFindFieldOffset(gDvm.classJavaLangReflectAccessibleObject, "flag",
+            "Z");
+
+    gDvm.offJavaLangReflectConstructor_slot =
+        dvmFindFieldOffset(gDvm.classJavaLangReflectConstructor, "slot", "I");
+    gDvm.offJavaLangReflectConstructor_declClass =
+        dvmFindFieldOffset(gDvm.classJavaLangReflectConstructor,
+            "declaringClass", "Ljava/lang/Class;");
+
+    gDvm.offJavaLangReflectField_slot =
+        dvmFindFieldOffset(gDvm.classJavaLangReflectField, "slot", "I");
+    gDvm.offJavaLangReflectField_declClass =
+        dvmFindFieldOffset(gDvm.classJavaLangReflectField,
+            "declaringClass", "Ljava/lang/Class;");
+
+    gDvm.offJavaLangReflectMethod_slot =
+        dvmFindFieldOffset(gDvm.classJavaLangReflectMethod, "slot", "I");
+    gDvm.offJavaLangReflectMethod_declClass =
+        dvmFindFieldOffset(gDvm.classJavaLangReflectMethod,
+            "declaringClass", "Ljava/lang/Class;");
+
+    if (gDvm.offJavaLangReflectAccessibleObject_flag < 0 ||
+        gDvm.offJavaLangReflectConstructor_slot < 0 ||
+        gDvm.offJavaLangReflectConstructor_declClass < 0 ||
+        gDvm.offJavaLangReflectField_slot < 0 ||
+        gDvm.offJavaLangReflectField_declClass < 0 ||
+        gDvm.offJavaLangReflectMethod_slot < 0 ||
+        gDvm.offJavaLangReflectMethod_declClass < 0)
+    {
+        LOGE("Could not find reflection fields\n");
+        return false;
+    }
+
+    return true;
+}
+
+static bool find6()
+{
+    /*
+     * Standard methods we must provide in our proxy.
+     */
+    Method* methE;
+    Method* methH;
+    Method* methT;
+    Method* methF;
+    methE = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
+                "equals", "(Ljava/lang/Object;)Z");
+    methH = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
+                "hashCode", "()I");
+    methT = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
+                "toString", "()Ljava/lang/String;");
+    methF = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
+                "finalize", "()V");
+    if (methE == NULL || methH == NULL || methT == NULL || methF == NULL) {
+        LOGE("Could not find equals/hashCode/toString/finalize in Object\n");
+        return false;
+    }
+    gDvm.voffJavaLangObject_equals = methE->methodIndex;
+    gDvm.voffJavaLangObject_hashCode = methH->methodIndex;
+    gDvm.voffJavaLangObject_toString = methT->methodIndex;
+    gDvm.voffJavaLangObject_finalize = methF->methodIndex;
+
+    /*
+     * The prototype signature needs to be cloned from a method in a
+     * "real" DEX file.  We declared this otherwise unused method just
+     * for this purpose.
+     */
+    ClassObject* proxyClass;
+    Method* meth;
+    proxyClass = dvmFindSystemClassNoInit("Ljava/lang/reflect/Proxy;");
+    if (proxyClass == NULL) {
+        LOGE("No java.lang.reflect.Proxy\n");
+        return false;
+    }
+    meth = dvmFindDirectMethodByDescriptor(proxyClass, "constructorPrototype",
+                "(Ljava/lang/reflect/InvocationHandler;)V");
+    if (meth == NULL) {
+        LOGE("Could not find java.lang.Proxy.constructorPrototype()\n");
+        return false;
+    }
+    gDvm.methJavaLangReflectProxy_constructorPrototype = meth;
+
+    /*
+     * Get the offset of the "h" field in Proxy.
+     */
+    gDvm.offJavaLangReflectProxy_h = dvmFindFieldOffset(proxyClass, "h",
+        "Ljava/lang/reflect/InvocationHandler;");
+    if (gDvm.offJavaLangReflectProxy_h < 0) {
+        LOGE("Unable to find 'h' field in java.lang.Proxy\n");
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Perform Annotation setup.
+ */
+static bool find7(void)
+{
+    Method* meth;
+
+    /*
+     * Find some standard Annotation classes.
+     */
+    gDvm.classJavaLangAnnotationAnnotationArray =
+        dvmFindArrayClass("[Ljava/lang/annotation/Annotation;", NULL);
+    gDvm.classJavaLangAnnotationAnnotationArrayArray =
+        dvmFindArrayClass("[[Ljava/lang/annotation/Annotation;", NULL);
+    if (gDvm.classJavaLangAnnotationAnnotationArray == NULL ||
+        gDvm.classJavaLangAnnotationAnnotationArrayArray == NULL)
+    {
+        LOGE("Could not find Annotation-array classes\n");
+        return false;
+    }
+
+    /*
+     * VM-specific annotation classes.
+     */
+    gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory =
+        dvmFindSystemClassNoInit("Lorg/apache/harmony/lang/annotation/AnnotationFactory;");
+    gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember =
+        dvmFindSystemClassNoInit("Lorg/apache/harmony/lang/annotation/AnnotationMember;");
+    gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray =
+        dvmFindArrayClass("[Lorg/apache/harmony/lang/annotation/AnnotationMember;", NULL);
+    if (gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory == NULL ||
+        gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember == NULL ||
+        gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray == NULL)
+    {
+        LOGE("Could not find android.lang annotation classes\n");
+        return false;
+    }
+
+    meth = dvmFindDirectMethodByDescriptor(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory,
+            "createAnnotation",
+            "(Ljava/lang/Class;[Lorg/apache/harmony/lang/annotation/AnnotationMember;)Ljava/lang/annotation/Annotation;");
+    if (meth == NULL) {
+        LOGE("Unable to find createAnnotation() in android AnnotationFactory\n");
+        return false;
+    }
+    gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation = meth;
+
+    meth = dvmFindDirectMethodByDescriptor(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember,
+            "<init>",
+            "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V");
+    if (meth == NULL) {
+        LOGE("Unable to find 4-arg constructor in android AnnotationMember\n");
+        return false;
+    }
+
+    gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init = meth;
+
+    return true;
+}
+
+static bool find8(void) {
+    ClassObject* clazz =
+        dvmFindClassNoInit("Ldalvik/system/VMDebug;", NULL);
+    assert(clazz != NULL);
+    gDvm.methodTrace.gcMethod =
+        dvmFindDirectMethodByDescriptor(clazz, "startGC", "()V");
+    gDvm.methodTrace.classPrepMethod =
+        dvmFindDirectMethodByDescriptor(clazz, "startClassPrep", "()V");
+    if (gDvm.methodTrace.gcMethod == NULL ||
+        gDvm.methodTrace.classPrepMethod == NULL)
+    {
+        LOGE("Unable to find startGC or startClassPrep\n");
+        return false;
+    }
+
+    return true;
+}
+
+/* (documented in header) */
+bool dvmFindRequiredClassesAndMembers(void) {
+    bool ok = true;
+
+    ok &= find1();
+    ok &= find2();
+    ok &= find3();
+    ok &= find4();
+    ok &= find5();
+    ok &= find6();
+    ok &= find7();
+    ok &= find8();
+
+    return ok;
+}
diff --git a/vm/Jni.c b/vm/Jni.c
index 0c8f4ca..b86ace8 100644
--- a/vm/Jni.c
+++ b/vm/Jni.c
@@ -236,7 +236,6 @@
 
 /* fwd */
 static const struct JNINativeInterface gNativeInterface;
-static jobject addGlobalReference(Object* obj);
 
 #ifdef WITH_JNI_STACK_CHECK
 # define COMPUTE_STACK_SUM(_self)   computeStackSum(_self);
@@ -287,6 +286,8 @@
 #define kGrefWaterInterval          100
 #define kTrackGrefUsage             true
 
+#define kWeakGlobalRefsTableInitialSize 16
+
 #define kPinTableInitialSize        16
 #define kPinTableMaxSize            1024
 #define kPinComplainThreshold       10
@@ -299,8 +300,14 @@
 {
 #ifdef USE_INDIRECT_REF
     if (!dvmInitIndirectRefTable(&gDvm.jniGlobalRefTable,
-            kGlobalRefsTableInitialSize, kGlobalRefsTableMaxSize,
-            kIndirectKindGlobal))
+                                 kGlobalRefsTableInitialSize,
+                                 kGlobalRefsTableMaxSize,
+                                 kIndirectKindGlobal))
+        return false;
+    if (!dvmInitIndirectRefTable(&gDvm.jniWeakGlobalRefTable,
+                                 kWeakGlobalRefsTableInitialSize,
+                                 kGlobalRefsTableMaxSize,
+                                 kIndirectKindWeakGlobal))
         return false;
 #else
     if (!dvmInitReferenceTable(&gDvm.jniGlobalRefTable,
@@ -309,6 +316,9 @@
 #endif
 
     dvmInitMutex(&gDvm.jniGlobalRefLock);
+#ifdef USE_INDIRECT_REF
+    dvmInitMutex(&gDvm.jniWeakGlobalRefLock);
+#endif
     gDvm.jniGlobalRefLoMark = 0;
     gDvm.jniGlobalRefHiMark = kGrefWaterInterval * 2;
 
@@ -318,64 +328,6 @@
 
     dvmInitMutex(&gDvm.jniPinRefLock);
 
-    Method* meth;
-
-    /*
-     * Grab the PhantomReference constructor.
-     */
-    gDvm.classJavaLangRefPhantomReference =
-        dvmFindSystemClassNoInit("Ljava/lang/ref/PhantomReference;");
-    if (gDvm.classJavaLangRefPhantomReference == NULL) {
-        LOGE("Unable to find PhantomReference class\n");
-        return false;
-    }
-    meth= dvmFindDirectMethodByDescriptor(gDvm.classJavaLangRefPhantomReference,
-        "<init>", "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V");
-    if (meth == NULL) {
-        LOGE("Unable to find constructor for PhantomReference\n");
-        return false;
-    }
-    gDvm.methJavaLangRefPhantomReference_init = meth;
-
-
-    /*
-     * Look up and cache pointers to some direct buffer classes, fields,
-     * and methods.
-     */
-    ClassObject* readWriteBufferClass =
-        dvmFindSystemClassNoInit("Ljava/nio/ReadWriteDirectByteBuffer;");
-    ClassObject* bufferClass =
-        dvmFindSystemClassNoInit("Ljava/nio/Buffer;");
-
-    if (readWriteBufferClass == NULL || bufferClass == NULL) {
-        LOGE("Unable to find internal direct buffer classes\n");
-        return false;
-    }
-    gDvm.classJavaNioReadWriteDirectByteBuffer = readWriteBufferClass;
-
-    meth = dvmFindDirectMethodByDescriptor(readWriteBufferClass,
-                "<init>",
-                "(II)V");
-    if (meth == NULL) {
-        LOGE("Unable to find ReadWriteDirectByteBuffer.<init>\n");
-        return false;
-    }
-    gDvm.methJavaNioReadWriteDirectByteBuffer_init = meth;
-
-    gDvm.offJavaNioBuffer_capacity =
-        dvmFindFieldOffset(bufferClass, "capacity", "I");
-    if (gDvm.offJavaNioBuffer_capacity < 0) {
-        LOGE("Unable to find Buffer.capacity\n");
-        return false;
-    }
-
-    gDvm.offJavaNioBuffer_effectiveDirectAddress =
-        dvmFindFieldOffset(bufferClass, "effectiveDirectAddress", "I");
-    if (gDvm.offJavaNioBuffer_effectiveDirectAddress < 0) {
-        LOGE("Unable to find Buffer.effectiveDirectAddress\n");
-        return false;
-    }
-
     return true;
 }
 
@@ -540,10 +492,11 @@
         break;
     case kIndirectKindWeakGlobal:
         {
-            // TODO: implement
-            LOGE("weak-global not yet supported\n");
-            result = NULL;
-            dvmAbort();
+            // TODO: find a way to avoid the mutex activity here
+            IndirectRefTable* pRefTable = &gDvm.jniWeakGlobalRefTable;
+            dvmLockMutex(&gDvm.jniWeakGlobalRefLock);
+            result = dvmGetFromIndirectRefTable(pRefTable, jobj);
+            dvmUnlockMutex(&gDvm.jniWeakGlobalRefLock);
         }
         break;
     case kIndirectKindInvalid:
@@ -811,6 +764,36 @@
     return jobj;
 }
 
+#ifdef USE_INDIRECT_REF
+static jobject addWeakGlobalReference(Object* obj)
+{
+    if (obj == NULL)
+        return NULL;
+    dvmLockMutex(&gDvm.jniWeakGlobalRefLock);
+    IndirectRefTable *table = &gDvm.jniWeakGlobalRefTable;
+    jobject jobj = dvmAddToIndirectRefTable(table, IRT_FIRST_SEGMENT, obj);
+    if (jobj == NULL) {
+        dvmDumpIndirectRefTable(table, "JNI weak global");
+        LOGE("Failed adding to JNI weak global ref table (%zd entries)",
+             dvmIndirectRefTableEntries(table));
+    }
+    dvmUnlockMutex(&gDvm.jniWeakGlobalRefLock);
+    return jobj;
+}
+
+static void deleteWeakGlobalReference(jobject jobj)
+{
+    if (jobj == NULL)
+        return;
+    dvmLockMutex(&gDvm.jniWeakGlobalRefLock);
+    IndirectRefTable *table = &gDvm.jniWeakGlobalRefTable;
+    if (!dvmRemoveFromIndirectRefTable(table, IRT_FIRST_SEGMENT, jobj)) {
+        LOGW("JNI: DeleteWeakGlobalRef(%p) failed to find entry", jobj);
+    }
+    dvmUnlockMutex(&gDvm.jniWeakGlobalRefLock);
+}
+#endif
+
 /*
  * Remove a global reference.  In most cases it's the entry most recently
  * added, which makes this pretty quick.
@@ -865,6 +848,7 @@
     dvmUnlockMutex(&gDvm.jniGlobalRefLock);
 }
 
+#ifndef USE_INDIRECT_REF
 /*
  * We create a PhantomReference that references the object, add a
  * global reference to it, and then flip some bits before returning it.
@@ -917,7 +901,9 @@
      * Add it to the global reference table, and mangle the pointer.
      */
     phantomRef = addGlobalReference(phantomObj);
-    return dvmObfuscateWeakGlobalRef(phantomRef);
+    jweak wref = dvmObfuscateWeakGlobalRef(phantomRef);
+    assert(wref == NULL || dvmIsWeakGlobalRef(wref));
+    return wref;
 }
 
 /*
@@ -928,7 +914,7 @@
 {
     if (wref == NULL)
         return;
-
+    assert(dvmIsWeakGlobalRef(wref));
     jobject phantomRef = dvmNormalizeWeakGlobalRef(wref);
     deleteGlobalReference(phantomRef);
 }
@@ -952,7 +938,7 @@
 
     return dvmGetFieldObject(obj, gDvm.offJavaLangRefReference_referent);
 }
-
+#endif
 
 /*
  * Objects don't currently move, so we just need to create a reference
@@ -969,7 +955,7 @@
     if (!dvmAddToReferenceTable(&gDvm.jniPinRefTable, (Object*)arrayObj)) {
         dvmDumpReferenceTable(&gDvm.jniPinRefTable, "JNI pinned array");
         LOGE("Failed adding to JNI pinned array ref table (%d entries)\n",
-            (int) dvmReferenceTableEntries(&gDvm.jniPinRefTable));
+           (int) dvmReferenceTableEntries(&gDvm.jniPinRefTable));
         dvmDumpThread(dvmThreadSelf(), false);
         dvmAbort();
     }
@@ -1031,12 +1017,12 @@
 {
     Thread* self = dvmThreadSelf();
     JNIEnv* env = self->jniEnv;
-    ReferenceTable* pLocalRefs = getLocalRefTable(env);
-
 #ifdef USE_INDIRECT_REF
+    IndirectRefTable* pLocalRefs = getLocalRefTable(env);
     dvmDumpIndirectRefTable(pLocalRefs, "JNI local");
     dvmDumpIndirectRefTable(&gDvm.jniGlobalRefTable, "JNI global");
 #else
+    ReferenceTable* pLocalRefs = getLocalRefTable(env);
     dvmDumpReferenceTable(pLocalRefs, "JNI local");
     dvmDumpReferenceTable(&gDvm.jniGlobalRefTable, "JNI global");
 #endif
@@ -1973,7 +1959,7 @@
     JNI_ENTER();
 
     ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
-    dvmThrowExceptionByClass(clazz, message);
+    dvmThrowException(clazz, message);
     // TODO: should return failure if this didn't work (e.g. OOM)
 
     JNI_EXIT();
@@ -2099,10 +2085,14 @@
     Object* obj;
 
     JNI_ENTER();
+#ifdef USE_INDIRECT_REF
+    obj = dvmDecodeIndirectRef(env, jobj);
+#else
     if (dvmIsWeakGlobalRef(jobj))
         obj = getPhantomReferent(env, (jweak) jobj);
     else
         obj = dvmDecodeIndirectRef(env, jobj);
+#endif
     jobject retval = addGlobalReference(obj);
     JNI_EXIT();
     return retval;
@@ -2127,10 +2117,14 @@
     Object* obj;
 
     JNI_ENTER();
+#ifdef USE_INDIRECT_REF
+    obj = dvmDecodeIndirectRef(env, jobj);
+#else
     if (dvmIsWeakGlobalRef(jobj))
         obj = getPhantomReferent(env, (jweak) jobj);
     else
         obj = dvmDecodeIndirectRef(env, jobj);
+#endif
     jobject retval = addLocalReference(env, obj);
     JNI_EXIT();
     return retval;
@@ -2351,7 +2345,7 @@
     } else if (dvmIsInterfaceClass(clazz)) {
         Method* meth = dvmFindInterfaceMethodHierByDescriptor(clazz, name, sig);
         if (meth == NULL) {
-            dvmThrowExceptionFmt("Ljava/lang/NoSuchMethodError;",
+            dvmThrowExceptionFmt(gDvm.exNoSuchMethodError,
                 "no method with name='%s' signature='%s' in interface %s",
                 name, sig, clazz->descriptor);
         }
@@ -2372,7 +2366,7 @@
             meth = NULL;
         }
         if (meth == NULL) {
-            dvmThrowExceptionFmt("Ljava/lang/NoSuchMethodError;",
+            dvmThrowExceptionFmt(gDvm.exNoSuchMethodError,
                 "no method with name='%s' signature='%s' in class %s",
                 name, sig, clazz->descriptor);
         } else {
@@ -2407,7 +2401,7 @@
     } else {
         id = (jfieldID) dvmFindInstanceFieldHier(clazz, name, sig);
         if (id == NULL) {
-            dvmThrowExceptionFmt("Ljava/lang/NoSuchFieldError;",
+            dvmThrowExceptionFmt(gDvm.exNoSuchFieldError,
                 "no field with name='%s' signature='%s' in class %s",
                 name, sig, clazz->descriptor);
         }
@@ -2449,7 +2443,7 @@
 
         id = (jmethodID) meth;
         if (id == NULL) {
-            dvmThrowExceptionFmt("Ljava/lang/NoSuchMethodError;",
+            dvmThrowExceptionFmt(gDvm.exNoSuchMethodError,
                 "no static method with name='%s' signature='%s' in class %s",
                 name, sig, clazz->descriptor);
         }
@@ -2476,7 +2470,7 @@
     } else {
         id = (jfieldID) dvmFindStaticField(clazz, name, sig);
         if (id == NULL) {
-            dvmThrowExceptionFmt("Ljava/lang/NoSuchFieldError;",
+            dvmThrowExceptionFmt(gDvm.exNoSuchFieldError,
                 "no static field with name='%s' signature='%s' in class %s",
                 name, sig, clazz->descriptor);
         }
@@ -3082,7 +3076,7 @@
 static bool checkArrayElementBounds(ArrayObject* arrayObj, jsize index) {
     assert(arrayObj != NULL);
     if (index < 0 || index >= (int) arrayObj->length) {
-        dvmThrowArrayIndexOutOfBoundsException(index, arrayObj->length);
+        dvmThrowArrayIndexOutOfBoundsException(arrayObj->length, index);
         return false;
     }
     return true;
@@ -3210,7 +3204,7 @@
 static void throwArrayRegionOutOfBounds(ArrayObject* arrayObj, jsize start,
     jsize len, const char* arrayIdentifier)
 {
-    dvmThrowExceptionFmtByClass(gDvm.exArrayIndexOutOfBoundsException,
+    dvmThrowExceptionFmt(gDvm.exArrayIndexOutOfBoundsException,
         "%s offset=%d length=%d %s.length=%d",
         arrayObj->obj.clazz->descriptor, start, len, arrayIdentifier,
         arrayObj->length);
@@ -3505,10 +3499,16 @@
 /*
  * Create a new weak global reference.
  */
-static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
+static jweak NewWeakGlobalRef(JNIEnv* env, jobject jobj)
 {
     JNI_ENTER();
-    jweak wref = createWeakGlobalRef(env, obj);
+#ifdef USE_INDIRECT_REF
+    Object *obj = dvmDecodeIndirectRef(env, jobj);
+    jweak wref = addWeakGlobalReference(obj);
+#else
+    jweak wref = createWeakGlobalRef(env, jobj);
+#endif
+    assert(wref == NULL || dvmIsWeakGlobalRef(wref));
     JNI_EXIT();
     return wref;
 }
@@ -3519,7 +3519,11 @@
 static void DeleteWeakGlobalRef(JNIEnv* env, jweak wref)
 {
     JNI_ENTER();
+#ifdef USE_INDIRECT_REF
+    deleteWeakGlobalReference(wref);
+#else
     deleteWeakGlobalRef(env, wref);
+#endif
     JNI_EXIT();
 }
 
diff --git a/vm/JniInternal.h b/vm/JniInternal.h
index 302dcb0..a9e962b 100644
--- a/vm/JniInternal.h
+++ b/vm/JniInternal.h
@@ -225,14 +225,22 @@
  * "Obfuscate" a weak global reference pointer.
  */
 INLINE jweak dvmObfuscateWeakGlobalRef(jobject jobj) {
+#ifndef USE_INDIRECT_REF
     return (jweak) ((u4) jobj ^ WEAK_GLOBAL_XOR);
+#else
+    return jobj;
+#endif
 }
 
 /*
  * Undo the obfuscation.
  */
 INLINE jobject dvmNormalizeWeakGlobalRef(jweak ref) {
+#ifndef USE_INDIRECT_REF
     return (jobject) ((u4) ref ^ WEAK_GLOBAL_XOR);
+#else
+    return ref;
+#endif
 }
 
 /*
@@ -242,7 +250,11 @@
  * guaranteed by 64-bit alignment of objects).
  */
 INLINE bool dvmIsWeakGlobalRef(jobject jobj) {
+#ifndef USE_INDIRECT_REF
     return (((u4) jobj & 0x07) == 0x07);
+#else
+    return (((u4) jobj & 0x03) == 0x03);
+#endif
 }
 
 #endif /*_DALVIK_JNIINTERNAL*/
diff --git a/vm/Profile.c b/vm/Profile.c
index 1d45715..f1acc97 100644
--- a/vm/Profile.c
+++ b/vm/Profile.c
@@ -146,20 +146,6 @@
     dvmInitMutex(&gDvm.methodTrace.startStopLock);
     pthread_cond_init(&gDvm.methodTrace.threadExitCond, NULL);
 
-    ClassObject* clazz =
-        dvmFindClassNoInit("Ldalvik/system/VMDebug;", NULL);
-    assert(clazz != NULL);
-    gDvm.methodTrace.gcMethod =
-        dvmFindDirectMethodByDescriptor(clazz, "startGC", "()V");
-    gDvm.methodTrace.classPrepMethod =
-        dvmFindDirectMethodByDescriptor(clazz, "startClassPrep", "()V");
-    if (gDvm.methodTrace.gcMethod == NULL ||
-        gDvm.methodTrace.classPrepMethod == NULL)
-    {
-        LOGE("Unable to find startGC or startClassPrep\n");
-        return false;
-    }
-
     assert(!dvmCheckException(dvmThreadSelf()));
 
     /*
@@ -359,7 +345,7 @@
             int err = errno;
             LOGE("Unable to open trace file '%s': %s\n",
                 traceFileName, strerror(err));
-            dvmThrowExceptionFmt("Ljava/lang/RuntimeException;",
+            dvmThrowExceptionFmt(gDvm.exRuntimeException,
                 "Unable to open trace file '%s': %s",
                 traceFileName, strerror(err));
             goto fail;
@@ -636,7 +622,7 @@
             int err = errno;
             LOGE("trace fwrite(%d) failed: %s\n",
                 finalCurOffset, strerror(err));
-            dvmThrowExceptionFmt("Ljava/lang/RuntimeException;",
+            dvmThrowExceptionFmt(gDvm.exRuntimeException,
                 "Trace data write failed: %s", strerror(err));
         }
     }
diff --git a/vm/RawDexFile.c b/vm/RawDexFile.c
index 5da4907..2c73481 100644
--- a/vm/RawDexFile.c
+++ b/vm/RawDexFile.c
@@ -250,11 +250,20 @@
 }
 
 /* See documentation comment in header. */
-int dvmRawDexFileOpenArray(const u1* pBytes, u4 length,
-    RawDexFile** ppDexFile)
+int dvmRawDexFileOpenArray(u1* pBytes, u4 length, RawDexFile** ppRawDexFile)
 {
-    // TODO - should be very similar to what JarFile does.
-    return -1;
+    DvmDex* pDvmDex = NULL;
+
+    if (!dvmPrepareDexInMemory(pBytes, length, &pDvmDex)) {
+        LOGD("Unable to open raw DEX from array\n");
+        return -1;
+    }
+    assert(pDvmDex != NULL);
+
+    *ppRawDexFile = (RawDexFile*) calloc(1, sizeof(RawDexFile));
+    (*ppRawDexFile)->pDvmDex = pDvmDex;
+
+    return 0;
 }
 
 /*
diff --git a/vm/RawDexFile.h b/vm/RawDexFile.h
index f15aac2..cbcb3b6 100644
--- a/vm/RawDexFile.h
+++ b/vm/RawDexFile.h
@@ -49,8 +49,7 @@
  * On success, returns 0 and sets "*ppDexFile" to a newly-allocated DexFile.
  * On failure, returns a meaningful error code [currently just -1].
  */
-int dvmRawDexFileOpenArray(const u1* pBytes, u4 length,
-    RawDexFile** ppDexFile);
+int dvmRawDexFileOpenArray(u1* pBytes, u4 length, RawDexFile** ppDexFile);
 
 /*
  * Free a RawDexFile structure, along with any associated structures.
diff --git a/vm/SignalCatcher.c b/vm/SignalCatcher.c
index 20ead16..b8d9741 100644
--- a/vm/SignalCatcher.c
+++ b/vm/SignalCatcher.c
@@ -169,11 +169,6 @@
     dvmCompilerDumpStats();
 #endif
 
-    if (false) {
-        dvmLockMutex(&gDvm.jniGlobalRefLock);
-        dvmDumpReferenceTable(&gDvm.jniGlobalRefTable, "JNI global");
-        dvmUnlockMutex(&gDvm.jniGlobalRefLock);
-    }
     if (false) dvmDumpTrackedAllocations(true);
 
     dvmResumeAllThreads(SUSPEND_FOR_STACK_DUMP);
diff --git a/vm/Thread.c b/vm/Thread.c
index 8861dff..69d1670 100644
--- a/vm/Thread.c
+++ b/vm/Thread.c
@@ -318,92 +318,6 @@
 }
 
 /*
- * We're a little farther up now, and can load some basic classes.
- *
- * We're far enough along that we can poke at java.lang.Thread and friends,
- * but should not assume that static initializers have run (or cause them
- * to do so).  That means no object allocations yet.
- */
-bool dvmThreadObjStartup(void)
-{
-    /*
-     * TODO: Pull this function's guts into dvmInitRequiredClassesAndMembers()
-     * in Init.c
-     */
-
-    assert(gDvm.classJavaLangThread != NULL);
-    assert(gDvm.classJavaLangThreadGroup != NULL);
-    assert(gDvm.classJavaLangVMThread != NULL);
-
-    /*
-     * Cache field offsets.  This makes things a little faster, at the
-     * expense of hard-coding non-public field names into the VM.
-     */
-    gDvm.offJavaLangThread_vmThread =
-        dvmFindFieldOffset(gDvm.classJavaLangThread,
-            "vmThread", "Ljava/lang/VMThread;");
-    gDvm.offJavaLangThread_group =
-        dvmFindFieldOffset(gDvm.classJavaLangThread,
-            "group", "Ljava/lang/ThreadGroup;");
-    gDvm.offJavaLangThread_daemon =
-        dvmFindFieldOffset(gDvm.classJavaLangThread, "daemon", "Z");
-    gDvm.offJavaLangThread_name =
-        dvmFindFieldOffset(gDvm.classJavaLangThread,
-            "name", "Ljava/lang/String;");
-    gDvm.offJavaLangThread_priority =
-        dvmFindFieldOffset(gDvm.classJavaLangThread, "priority", "I");
-
-    if (gDvm.offJavaLangThread_vmThread < 0 ||
-        gDvm.offJavaLangThread_group < 0 ||
-        gDvm.offJavaLangThread_daemon < 0 ||
-        gDvm.offJavaLangThread_name < 0 ||
-        gDvm.offJavaLangThread_priority < 0)
-    {
-        LOGE("Unable to find all fields in java.lang.Thread\n");
-        return false;
-    }
-
-    gDvm.offJavaLangVMThread_thread =
-        dvmFindFieldOffset(gDvm.classJavaLangVMThread,
-            "thread", "Ljava/lang/Thread;");
-    gDvm.offJavaLangVMThread_vmData =
-        dvmFindFieldOffset(gDvm.classJavaLangVMThread, "vmData", "I");
-    if (gDvm.offJavaLangVMThread_thread < 0 ||
-        gDvm.offJavaLangVMThread_vmData < 0)
-    {
-        LOGE("Unable to find all fields in java.lang.VMThread\n");
-        return false;
-    }
-
-    /*
-     * Cache the vtable offset for "run()".
-     *
-     * We don't want to keep the Method* because then we won't find see
-     * methods defined in subclasses.
-     */
-    Method* meth;
-    meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThread, "run", "()V");
-    if (meth == NULL) {
-        LOGE("Unable to find run() in java.lang.Thread\n");
-        return false;
-    }
-    gDvm.voffJavaLangThread_run = meth->methodIndex;
-
-    /*
-     * Cache vtable offsets for ThreadGroup methods.
-     */
-    meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThreadGroup,
-        "removeThread", "(Ljava/lang/Thread;)V");
-    if (meth == NULL) {
-        LOGE("Unable to find removeThread(Thread) in java.lang.ThreadGroup\n");
-        return false;
-    }
-    gDvm.voffJavaLangThreadGroup_removeThread = meth->methodIndex;
-
-    return true;
-}
-
-/*
  * All threads should be stopped by now.  Clean up some thread globals.
  */
 void dvmThreadShutdown(void)
@@ -1418,7 +1332,7 @@
         char* threadName = dvmCreateCstrFromString(nameStr);
         bool profilerThread = strcmp(threadName, "SamplingProfiler") == 0;
         if (!profilerThread) {
-            dvmThrowExceptionFmtByClass(gDvm.exIllegalStateException,
+            dvmThrowExceptionFmt(gDvm.exIllegalStateException,
                 "No new threads in -Xzygote mode. "
                 "Found thread named '%s'", threadName);
 
diff --git a/vm/Thread.h b/vm/Thread.h
index 4aa2663..a14e400 100644
--- a/vm/Thread.h
+++ b/vm/Thread.h
@@ -67,7 +67,6 @@
 
 /* initialization */
 bool dvmThreadStartup(void);
-bool dvmThreadObjStartup(void);
 void dvmThreadShutdown(void);
 void dvmSlayDaemons(void);
 
diff --git a/vm/alloc/MarkSweep.c b/vm/alloc/MarkSweep.c
index c925225..cd94a7f 100644
--- a/vm/alloc/MarkSweep.c
+++ b/vm/alloc/MarkSweep.c
@@ -1088,6 +1088,22 @@
     return !isMarked((Object *)obj, &gDvm.gcHeap->markContext);
 }
 
+#ifdef USE_INDIRECT_REF
+void sweepWeakJniGlobals(void)
+{
+    IndirectRefTable *table = &gDvm.jniWeakGlobalRefTable;
+    Object **entry = table->table;
+    GcMarkContext *ctx = &gDvm.gcHeap->markContext;
+    int numEntries = dvmIndirectRefTableEntries(table);
+    int i;
+    for (i = 0; i < numEntries; ++i) {
+        if (entry[i] != NULL && !isMarked(entry[i], ctx)) {
+            entry[i] = NULL;
+        }
+    }
+}
+#endif
+
 /*
  * Process all the internal system structures that behave like
  * weakly-held objects.
@@ -1096,6 +1112,9 @@
 {
     dvmGcDetachDeadInternedStrings(isUnmarkedObject);
     dvmSweepMonitorList(&gDvm.monitorList, isUnmarkedObject);
+#ifdef USE_INDIRECT_REF
+    sweepWeakJniGlobals();
+#endif
 }
 
 /*
diff --git a/vm/alloc/Visit.c b/vm/alloc/Visit.c
index a17eea8..a90b0f3 100644
--- a/vm/alloc/Visit.c
+++ b/vm/alloc/Visit.c
@@ -81,6 +81,24 @@
     }
 }
 
+#ifdef USE_INDIRECT_REF
+/*
+ * Visits all entries in the indirect reference table.
+ */
+static void visitIndirectRefTable(RootVisitor *visitor, IndirectRefTable *table,
+                                  u4 threadId, RootType type, void *arg)
+{
+    assert(visitor != NULL);
+    assert(table != NULL);
+    Object **entry = table->table;
+    int numEntries = dvmIndirectRefTableEntries(table);
+    int i;
+    for (i = 0; i < numEntries; ++i) {
+        (*visitor)(&entry[i], threadId, type, arg);
+    }
+}
+#endif
+
 /*
  * Visits a large heap reference table.  These objects are list heads.
  * As such, it is valid for table to be NULL.
@@ -192,7 +210,11 @@
     (*visitor)(&thread->threadObj, threadId, ROOT_THREAD_OBJECT, arg);
     (*visitor)(&thread->exception, threadId, ROOT_NATIVE_STACK, arg);
     visitReferenceTable(visitor, &thread->internalLocalRefTable, threadId, ROOT_NATIVE_STACK, arg);
+#ifdef USE_INDIRECT_REF
+    visitIndirectRefTable(visitor, &thread->jniLocalRefTable, threadId, ROOT_JNI_LOCAL, arg);
+#else
     visitReferenceTable(visitor, &thread->jniLocalRefTable, threadId, ROOT_JNI_LOCAL, arg);
+#endif
     if (thread->jniMonitorRefTable.table != NULL) {
         visitReferenceTable(visitor, &thread->jniMonitorRefTable, threadId, ROOT_JNI_MONITOR, arg);
     }
@@ -231,7 +253,11 @@
         visitHashTable(visitor, gDvm.literalStrings, ROOT_INTERNED_STRING, arg);
     }
     dvmLockMutex(&gDvm.jniGlobalRefLock);
+#ifdef USE_INDIRECT_REF
+    visitIndirectRefTable(visitor, &gDvm.jniGlobalRefTable, 0, ROOT_JNI_GLOBAL, arg);
+#else
     visitReferenceTable(visitor, &gDvm.jniGlobalRefTable, 0, ROOT_JNI_GLOBAL, arg);
+#endif
     dvmUnlockMutex(&gDvm.jniGlobalRefLock);
     dvmLockMutex(&gDvm.jniPinRefLock);
     visitReferenceTable(visitor, &gDvm.jniPinRefTable, 0, ROOT_VM_INTERNAL, arg);
diff --git a/vm/analysis/CodeVerify.c b/vm/analysis/CodeVerify.c
index 1fff44b..1894d5d 100644
--- a/vm/analysis/CodeVerify.c
+++ b/vm/analysis/CodeVerify.c
@@ -3306,10 +3306,10 @@
         /* nothing to do */
         break;
     case 3:
-        dvmDexChangeDex2(meth->clazz->pDvmDex, oldInsns+2, OP_NOP);
+        dvmUpdateCodeUnit(meth, oldInsns+2, OP_NOP);
         break;
     case 5:
-        dvmDexChangeDex2(meth->clazz->pDvmDex, oldInsns+4, OP_NOP);
+        dvmUpdateCodeUnit(meth, oldInsns+4, OP_NOP);
         break;
     default:
         /* whoops */
@@ -3324,15 +3324,15 @@
         assert(width == 4 || width == 5);
         u2 newVal = (u2) ((OP_THROW_VERIFICATION_ERROR_JUMBO << 8) |
                            OP_DISPATCH_FF);
-        dvmDexChangeDex2(meth->clazz->pDvmDex, oldInsns, newVal);
+        dvmUpdateCodeUnit(meth, oldInsns, newVal);
         newVal = failure | (refType << kVerifyErrorRefTypeShift);
-        dvmDexChangeDex2(meth->clazz->pDvmDex, oldInsns+3, newVal);
+        dvmUpdateCodeUnit(meth, oldInsns+3, newVal);
     } else {
         /* encode the opcode, with the failure code in the high byte */
         assert(width == 2 || width == 3);
         u2 newVal = OP_THROW_VERIFICATION_ERROR |
             (failure << 8) | (refType << (8 + kVerifyErrorRefTypeShift));
-        dvmDexChangeDex2(meth->clazz->pDvmDex, oldInsns, newVal);
+        dvmUpdateCodeUnit(meth, oldInsns, newVal);
     }
 
     result = true;
diff --git a/vm/analysis/DexPrepare.c b/vm/analysis/DexPrepare.c
index eb856e8..0f82cbf 100644
--- a/vm/analysis/DexPrepare.c
+++ b/vm/analysis/DexPrepare.c
@@ -42,8 +42,8 @@
 
 
 /* fwd */
-static bool rewriteDex(u1* addr, int len, u4* pHeaderFlags,
-    DexClassLookup** ppClassLookup);
+static bool rewriteDex(u1* addr, int len, bool doVerify, bool doOpt,
+    DexClassLookup** ppClassLookup, DvmDex** ppDvmDex);
 static bool loadAllClasses(DvmDex* pDvmDex);
 static void verifyAndOptimizeClasses(DexFile* pDexFile, bool doVerify,
     bool doOpt);
@@ -479,7 +479,6 @@
 {
     DexClassLookup* pClassLookup = NULL;
     RegisterMapBuilder* pRegMapBuilder = NULL;
-    u4 headerFlags = 0;
 
     assert(gDvm.optimizing);
 
@@ -521,6 +520,24 @@
             goto bail;
         }
 
+        bool doVerify, doOpt;
+        if (gDvm.classVerifyMode == VERIFY_MODE_NONE) {
+            doVerify = false;
+        } else if (gDvm.classVerifyMode == VERIFY_MODE_REMOTE) {
+            doVerify = !gDvm.optimizingBootstrapClass;
+        } else /*if (gDvm.classVerifyMode == VERIFY_MODE_ALL)*/ {
+            doVerify = true;
+        }
+
+        if (gDvm.dexOptMode == OPTIMIZE_MODE_NONE) {
+            doOpt = false;
+        } else if (gDvm.dexOptMode == OPTIMIZE_MODE_VERIFIED ||
+                   gDvm.dexOptMode == OPTIMIZE_MODE_FULL) {
+            doOpt = doVerify;
+        } else /*if (gDvm.dexOptMode == OPTIMIZE_MODE_ALL)*/ {
+            doOpt = true;
+        }
+
         /*
          * Rewrite the file.  Byte reordering, structure realigning,
          * class verification, and bytecode optimization are all performed
@@ -530,11 +547,10 @@
          * In practice this would be annoying to deal with, so the file
          * layout is designed so that it can always be rewritten in place.
          *
-         * This sets "headerFlags" and creates the class lookup table as
-         * part of doing the processing.
+         * This creates the class lookup table as part of doing the processing.
          */
         success = rewriteDex(((u1*) mapAddr) + dexOffset, dexLength,
-                    &headerFlags, &pClassLookup);
+                    doVerify, doOpt, &pClassLookup, NULL);
 
         if (success) {
             DvmDex* pDvmDex = NULL;
@@ -656,8 +672,11 @@
     optHdr.depsLength = (u4) depsLength;
     optHdr.optOffset = (u4) optOffset;
     optHdr.optLength = (u4) optLength;
-
-    optHdr.flags = headerFlags;
+#if __BYTE_ORDER != __LITTLE_ENDIAN
+    optHdr.flags = DEX_OPT_FLAG_BIG;
+#else
+    optHdr.flags = 0;
+#endif
     optHdr.checksum = optChecksum;
 
     fsync(fd);      /* ensure previous writes go before header is written */
@@ -677,52 +696,62 @@
     return result;
 }
 
+/*
+ * Prepare an in-memory DEX file.
+ *
+ * The data was presented to the VM as a byte array rather than a file.
+ * We want to do the same basic set of operations, but we can just leave
+ * them in memory instead of writing them out to a cached optimized DEX file.
+ */
+bool dvmPrepareDexInMemory(u1* addr, size_t len, DvmDex** ppDvmDex)
+{
+    DexClassLookup* pClassLookup = NULL;
+
+    /*
+     * Byte-swap, realign, verify basic DEX file structure.
+     *
+     * We could load + verify + optimize here as well, but that's probably
+     * not desirable.
+     *
+     * (The bulk-verification code is currently only setting the DEX
+     * file's "verified" flag, not updating the ClassObject.  This would
+     * also need to be changed, or we will try to verify the class twice,
+     * and possibly reject it when optimized opcodes are encountered.)
+     */
+    if (!rewriteDex(addr, len, false, false, &pClassLookup, ppDvmDex)) {
+        return false;
+    }
+
+    (*ppDvmDex)->pDexFile->pClassLookup = pClassLookup;
+
+    return true;
+}
 
 /*
  * Perform in-place rewrites on a memory-mapped DEX file.
  *
- * This happens in a short-lived child process, so we can go nutty with
- * loading classes and allocating memory.
+ * If this is called from a short-lived child process (dexopt), we can
+ * go nutty with loading classes and allocating memory.  When it's
+ * called to prepare classes provided in a byte array, we may want to
+ * be more conservative.
+ *
+ * If "ppClassLookup" is non-NULL, a pointer to a newly-allocated
+ * DexClassLookup will be returned on success.
+ *
+ * If "ppDvmDex" is non-NULL, a newly-allocated DvmDex struct will be
+ * returned on success.
  */
-static bool rewriteDex(u1* addr, int len, u4* pHeaderFlags,
-    DexClassLookup** ppClassLookup)
+static bool rewriteDex(u1* addr, int len, bool doVerify, bool doOpt,
+    DexClassLookup** ppClassLookup, DvmDex** ppDvmDex)
 {
+    DexClassLookup* pClassLookup = NULL;
     u8 prepWhen, loadWhen, verifyOptWhen;
     DvmDex* pDvmDex = NULL;
-    bool doVerify, doOpt;
     bool result = false;
 
-    *pHeaderFlags = 0;
-
     /* if the DEX is in the wrong byte order, swap it now */
     if (dexSwapAndVerify(addr, len) != 0)
         goto bail;
-#if __BYTE_ORDER != __LITTLE_ENDIAN
-    *pHeaderFlags |= DEX_OPT_FLAG_BIG;
-#endif
-
-    if (gDvm.classVerifyMode == VERIFY_MODE_NONE) {
-        doVerify = false;
-    } else if (gDvm.classVerifyMode == VERIFY_MODE_REMOTE) {
-        doVerify = !gDvm.optimizingBootstrapClass;
-    } else /*if (gDvm.classVerifyMode == VERIFY_MODE_ALL)*/ {
-        doVerify = true;
-    }
-
-    if (gDvm.dexOptMode == OPTIMIZE_MODE_NONE) {
-        doOpt = false;
-    } else if (gDvm.dexOptMode == OPTIMIZE_MODE_VERIFIED ||
-               gDvm.dexOptMode == OPTIMIZE_MODE_FULL) {
-        doOpt = doVerify;
-    } else /*if (gDvm.dexOptMode == OPTIMIZE_MODE_ALL)*/ {
-        doOpt = true;
-    }
-
-    /* TODO: decide if this is actually useful */
-    if (doVerify)
-        *pHeaderFlags |= DEX_FLAG_VERIFIED;
-    if (doOpt)
-        *pHeaderFlags |= DEX_OPT_FLAG_FIELDS | DEX_OPT_FLAG_INVOCATIONS;
 
     /*
      * Now that the DEX file can be read directly, create a DexFile struct
@@ -736,10 +765,14 @@
     /*
      * Create the class lookup table.  This will eventually be appended
      * to the end of the .odex.
+     *
+     * We create a temporary link from the DexFile for the benefit of
+     * class loading, below.
      */
-    *ppClassLookup = dexCreateClassLookup(pDvmDex->pDexFile);
-    if (*ppClassLookup == NULL)
+    pClassLookup = dexCreateClassLookup(pDvmDex->pDexFile);
+    if (pClassLookup == NULL)
         goto bail;
+    pDvmDex->pDexFile->pClassLookup = pClassLookup;
 
     /*
      * If we're not going to attempt to verify or optimize the classes,
@@ -750,9 +783,6 @@
         goto bail;
     }
 
-    /* this is needed for the next part */
-    pDvmDex->pDexFile->pClassLookup = *ppClassLookup;
-
     prepWhen = dvmGetRelativeTimeUsec();
 
     /*
@@ -798,8 +828,23 @@
     result = true;
 
 bail:
-    /* free up storage */
-    dvmDexFileFree(pDvmDex);
+    /*
+     * On success, return the pieces that the caller asked for.
+     */
+    if (ppDvmDex == NULL || !result) {
+        dvmDexFileFree(pDvmDex);
+    } else {
+        *ppDvmDex = pDvmDex;
+    }
+
+    if (ppClassLookup == NULL || !result) {
+        free(pClassLookup);
+    } else {
+        *ppClassLookup = pClassLookup;
+    }
+
+    /* break link between the two */
+    pDvmDex->pDexFile->pClassLookup = NULL;
 
     return result;
 }
@@ -854,8 +899,8 @@
      * that contains Object, and only when Object comes first in the
      * list, but it costs very little to do it in all cases.)
      */
-    if (dvmFindSystemClass("Ljava/lang/Class;") == NULL) {
-        LOGE("ERROR: java.lang.Class does not exist!\n");
+    if (!dvmInitClass(gDvm.classJavaLangClass)) {
+        LOGE("ERROR: failed to initialize the class Class!\n");
         return false;
     }
 
@@ -1125,29 +1170,13 @@
     /*
      * Do the header flags match up with what we want?
      *
-     * This is useful because it allows us to automatically regenerate
-     * a file when settings change (e.g. verification is now mandatory),
-     * but can cause difficulties if the bootstrap classes we depend upon
-     * were handled differently than the current options specify.  We get
-     * upset because they're not verified or optimized, but we're not able
-     * to regenerate them because the installer won't let us.
-     *
-     * (This is also of limited value when !sourceAvail.)
-     *
-     * So, for now, we essentially ignore "expectVerify" and "expectOpt"
-     * by limiting the match mask.
-     *
-     * The only thing we really can't handle is incorrect byte-ordering.
+     * The only thing we really can't handle is incorrect byte ordering.
      */
     const u4 matchMask = DEX_OPT_FLAG_BIG;
     u4 expectedFlags = 0;
 #if __BYTE_ORDER != __LITTLE_ENDIAN
     expectedFlags |= DEX_OPT_FLAG_BIG;
 #endif
-    if (expectVerify)
-        expectedFlags |= DEX_FLAG_VERIFIED;
-    if (expectOpt)
-        expectedFlags |= DEX_OPT_FLAG_FIELDS | DEX_OPT_FLAG_INVOCATIONS;
     if ((expectedFlags & matchMask) != (optHdr.flags & matchMask)) {
         LOGI("DexOpt: header flag mismatch (0x%02x vs 0x%02x, mask=0x%02x)\n",
             expectedFlags, optHdr.flags, matchMask);
diff --git a/vm/analysis/DexPrepare.h b/vm/analysis/DexPrepare.h
index a424b9c..0ee76e5 100644
--- a/vm/analysis/DexPrepare.h
+++ b/vm/analysis/DexPrepare.h
@@ -124,6 +124,11 @@
     const char* fileName, u4 modWhen, u4 crc, bool isBootstrap);
 
 /*
+ * Prepare DEX data that is only available to the VM as in-memory data.
+ */
+bool dvmPrepareDexInMemory(u1* addr, size_t len, DvmDex** ppDvmDex);
+
+/*
  * Prep data structures.
  */
 bool dvmCreateInlineSubsTable(void);
diff --git a/vm/analysis/Optimize.c b/vm/analysis/Optimize.c
index ae6eebe..2bacc5b 100644
--- a/vm/analysis/Optimize.c
+++ b/vm/analysis/Optimize.c
@@ -338,16 +338,19 @@
 }
 
 /*
- * Update a 16-bit code unit in "meth".
+ * Update a 16-bit code unit in "meth".  The way in which the DEX data was
+ * loaded determines how we go about the write.
  */
-static inline void updateCodeUnit(const Method* meth, u2* ptr, u2 newVal)
+void dvmUpdateCodeUnit(const Method* meth, u2* ptr, u2 newVal)
 {
-    if (gDvm.optimizing) {
-        /* dexopt time, alter the output directly */
+    DvmDex* pDvmDex = meth->clazz->pDvmDex;
+
+    if (!pDvmDex->isMappedReadOnly) {
+        /* in-memory DEX (dexopt or byte[]), alter the output directly */
         *ptr = newVal;
     } else {
-        /* runtime, toggle the page read/write status */
-        dvmDexChangeDex2(meth->clazz->pDvmDex, ptr, newVal);
+        /* memory-mapped file, toggle the page read/write status */
+        dvmDexChangeDex2(pDvmDex, ptr, newVal);
     }
 }
 
@@ -356,7 +359,7 @@
  */
 static inline void updateOpcode(const Method* meth, u2* ptr, Opcode opcode)
 {
-    updateCodeUnit(meth, ptr, (ptr[0] & 0xff00) | (u2) opcode);
+    dvmUpdateCodeUnit(meth, ptr, (ptr[0] & 0xff00) | (u2) opcode);
 }
 
 /*
@@ -671,7 +674,7 @@
             instField->field.clazz->descriptor, instField->field.name);
     } else if (quickOpc != OP_NOP) {
         updateOpcode(method, insns, quickOpc);
-        updateCodeUnit(method, insns+1, (u2) instField->byteOffset);
+        dvmUpdateCodeUnit(method, insns+1, (u2) instField->byteOffset);
         LOGV("DexOpt: rewrote ifield access %s.%s --> %d\n",
             instField->field.clazz->descriptor, instField->field.name,
             instField->byteOffset);
@@ -885,7 +888,7 @@
      * initial load.
      */
     updateOpcode(method, insns, newOpc);
-    updateCodeUnit(method, insns+1, baseMethod->methodIndex);
+    dvmUpdateCodeUnit(method, insns+1, baseMethod->methodIndex);
 
     //LOGI("DexOpt: rewrote call to %s.%s --> %s.%s\n",
     //    method->clazz->descriptor, method->name,
@@ -933,7 +936,8 @@
          */
         u1 origOp = insns[0] & 0xff;
         if (origOp == OP_INVOKE_DIRECT) {
-            updateCodeUnit(method, insns, OP_INVOKE_OBJECT_INIT_RANGE | 0x100);
+            dvmUpdateCodeUnit(method, insns,
+                OP_INVOKE_OBJECT_INIT_RANGE | 0x100);
         } else {
             assert(origOp == OP_INVOKE_DIRECT_RANGE);
             assert((insns[0] >> 8) == 1);
@@ -1053,7 +1057,7 @@
                    (insns[0] & 0xff) == OP_INVOKE_STATIC ||
                    (insns[0] & 0xff) == OP_INVOKE_VIRTUAL);
             updateOpcode(method, insns, OP_EXECUTE_INLINE);
-            updateCodeUnit(method, insns+1, (u2) inlineSubs->inlineIdx);
+            dvmUpdateCodeUnit(method, insns+1, (u2) inlineSubs->inlineIdx);
 
             //LOGI("DexOpt: execute-inline %s.%s --> %s.%s\n",
             //    method->clazz->descriptor, method->name,
@@ -1093,7 +1097,7 @@
                    (insns[0] & 0xff) == OP_INVOKE_STATIC_RANGE ||
                    (insns[0] & 0xff) == OP_INVOKE_VIRTUAL_RANGE);
             updateOpcode(method, insns, OP_EXECUTE_INLINE_RANGE);
-            updateCodeUnit(method, insns+1, (u2) inlineSubs->inlineIdx);
+            dvmUpdateCodeUnit(method, insns+1, (u2) inlineSubs->inlineIdx);
 
             //LOGI("DexOpt: execute-inline/range %s.%s --> %s.%s\n",
             //    method->clazz->descriptor, method->name,
diff --git a/vm/analysis/Optimize.h b/vm/analysis/Optimize.h
index 3b3ba7e..75b6eab 100644
--- a/vm/analysis/Optimize.h
+++ b/vm/analysis/Optimize.h
@@ -26,6 +26,11 @@
 void dvmOptimizeClass(ClassObject* clazz, bool essentialOnly);
 
 /*
+ * Update a 16-bit code unit.
+ */
+void dvmUpdateCodeUnit(const Method* meth, u2* ptr, u2 newVal);
+
+/*
  * Abbreviated resolution functions, for use by optimization and verification
  * code.
  */
diff --git a/vm/interp/Interp.c b/vm/interp/Interp.c
index 9e94449..c671624 100644
--- a/vm/interp/Interp.c
+++ b/vm/interp/Interp.c
@@ -940,7 +940,7 @@
     size = arrayData[2] | (((u4)arrayData[3]) << 16);
 
     if (size > arrayObj->length) {
-        dvmThrowArrayIndexOutOfBoundsException(size, arrayObj->length);
+        dvmThrowArrayIndexOutOfBoundsException(arrayObj->length, size);
         return false;
     }
     copySwappedArrayData(arrayObj->contents, &arrayData[4], size, width);
@@ -1154,43 +1154,43 @@
     const int typeMask = 0xff << kVerifyErrorRefTypeShift;
     VerifyError errorKind = kind & ~typeMask;
     VerifyErrorRefType refType = kind >> kVerifyErrorRefTypeShift;
-    const char* exceptionName = "Ljava/lang/VerifyError;";
+    ClassObject* exceptionClass = gDvm.exVerifyError;
     char* msg = NULL;
 
     switch ((VerifyError) errorKind) {
     case VERIFY_ERROR_NO_CLASS:
-        exceptionName = "Ljava/lang/NoClassDefFoundError;";
+        exceptionClass = gDvm.exNoClassDefFoundError;
         msg = classNameFromIndex(method, ref, refType, 0);
         break;
     case VERIFY_ERROR_NO_FIELD:
-        exceptionName = "Ljava/lang/NoSuchFieldError;";
+        exceptionClass = gDvm.exNoSuchFieldError;
         msg = fieldNameFromIndex(method, ref, refType, 0);
         break;
     case VERIFY_ERROR_NO_METHOD:
-        exceptionName = "Ljava/lang/NoSuchMethodError;";
+        exceptionClass = gDvm.exNoSuchMethodError;
         msg = methodNameFromIndex(method, ref, refType, 0);
         break;
     case VERIFY_ERROR_ACCESS_CLASS:
-        exceptionName = "Ljava/lang/IllegalAccessError;";
+        exceptionClass = gDvm.exIllegalAccessError;
         msg = classNameFromIndex(method, ref, refType,
             kThrowShow_accessFromClass);
         break;
     case VERIFY_ERROR_ACCESS_FIELD:
-        exceptionName = "Ljava/lang/IllegalAccessError;";
+        exceptionClass = gDvm.exIllegalAccessError;
         msg = fieldNameFromIndex(method, ref, refType,
             kThrowShow_accessFromClass);
         break;
     case VERIFY_ERROR_ACCESS_METHOD:
-        exceptionName = "Ljava/lang/IllegalAccessError;";
+        exceptionClass = gDvm.exIllegalAccessError;
         msg = methodNameFromIndex(method, ref, refType,
             kThrowShow_accessFromClass);
         break;
     case VERIFY_ERROR_CLASS_CHANGE:
-        exceptionName = "Ljava/lang/IncompatibleClassChangeError;";
+        exceptionClass = gDvm.exIncompatibleClassChangeError;
         msg = classNameFromIndex(method, ref, refType, 0);
         break;
     case VERIFY_ERROR_INSTANTIATION:
-        exceptionName = "Ljava/lang/InstantiationError;";
+        exceptionClass = gDvm.exInstantiationError;
         msg = classNameFromIndex(method, ref, refType, 0);
         break;
 
@@ -1206,7 +1206,7 @@
     /* no default clause -- want warning if enum updated */
     }
 
-    dvmThrowException(exceptionName, msg);
+    dvmThrowException(exceptionClass, msg);
     free(msg);
 }
 
diff --git a/vm/interp/Stack.c b/vm/interp/Stack.c
index e7bfb68..84984a1 100644
--- a/vm/interp/Stack.c
+++ b/vm/interp/Stack.c
@@ -645,7 +645,7 @@
     char* actualClassName = (arg != NULL)
         ? dvmHumanReadableDescriptor(arg->obj.clazz->descriptor)
         : strdup("null");
-    dvmThrowExceptionFmtByClass(gDvm.exIllegalArgumentException,
+    dvmThrowExceptionFmt(gDvm.exIllegalArgumentException,
         "argument %d should have type %s, got %s",
         argIndex + 1, expectedClassName, actualClassName);
     free(expectedClassName);
@@ -681,7 +681,7 @@
     else
         argListLength = 0;
     if (argListLength != (int) params->length) {
-        dvmThrowExceptionFmtByClass(gDvm.exIllegalArgumentException,
+        dvmThrowExceptionFmt(gDvm.exIllegalArgumentException,
             "wrong number of arguments; expected %d, got %d",
             params->length, argListLength);
         return NULL;
@@ -1064,7 +1064,7 @@
         LOGW("Stack overflow while throwing exception\n");
         dvmClearException(self);
     }
-    dvmThrowChainedExceptionByClass(gDvm.exStackOverflowError, NULL, excep);
+    dvmThrowChainedException(gDvm.exStackOverflowError, NULL, excep);
 }
 
 /*
diff --git a/vm/mterp/armv5te/footer.S b/vm/mterp/armv5te/footer.S
index 0c6b0f4..73e8efa 100644
--- a/vm/mterp/armv5te/footer.S
+++ b/vm/mterp/armv5te/footer.S
@@ -990,14 +990,13 @@
 /*
  * Invalid array index. Note that our calling convention is strange; we use r1
  * and r3 because those just happen to be the registers all our callers are
- * using. We shuffle them here before calling the C function.
+ * using. We move r3 before calling the C function, but r1 happens to match.
  * r1: index
  * r3: size
  */
 common_errArrayIndex:
     EXPORT_PC()
-    mov     r0, r1
-    mov     r1, r3
+    mov     r0, r3
     bl      dvmThrowArrayIndexOutOfBoundsException
     b       common_exceptionThrown
 
diff --git a/vm/mterp/c/OP_APUT_OBJECT.c b/vm/mterp/c/OP_APUT_OBJECT.c
index f4c3326..950f18c 100644
--- a/vm/mterp/c/OP_APUT_OBJECT.c
+++ b/vm/mterp/c/OP_APUT_OBJECT.c
@@ -14,7 +14,7 @@
             GOTO_exceptionThrown();
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {
             dvmThrowArrayIndexOutOfBoundsException(
-                GET_REGISTER(vsrc2), arrayObj->length);
+                arrayObj->length, GET_REGISTER(vsrc2));
             GOTO_exceptionThrown();
         }
         obj = (Object*) GET_REGISTER(vdst);
diff --git a/vm/mterp/c/OP_NEW_INSTANCE.c b/vm/mterp/c/OP_NEW_INSTANCE.c
index e7e2952..155434f 100644
--- a/vm/mterp/c/OP_NEW_INSTANCE.c
+++ b/vm/mterp/c/OP_NEW_INSTANCE.c
@@ -32,7 +32,7 @@
          * Verifier now tests for interface/abstract class.
          */
         //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //    dvmThrowExceptionWithClassMessage(gDvm.exInstantiationError,
         //        clazz->descriptor);
         //    GOTO_exceptionThrown();
         //}
diff --git a/vm/mterp/c/OP_NEW_INSTANCE_JUMBO.c b/vm/mterp/c/OP_NEW_INSTANCE_JUMBO.c
index b49adbf..2464b69 100644
--- a/vm/mterp/c/OP_NEW_INSTANCE_JUMBO.c
+++ b/vm/mterp/c/OP_NEW_INSTANCE_JUMBO.c
@@ -32,7 +32,7 @@
          * Verifier now tests for interface/abstract class.
          */
         //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //    dvmThrowExceptionWithClassMessage(gDvm.exInstantiationError,
         //        clazz->descriptor);
         //    GOTO_exceptionThrown();
         //}
diff --git a/vm/mterp/c/OP_THROW_VERIFICATION_ERROR_JUMBO.c b/vm/mterp/c/OP_THROW_VERIFICATION_ERROR_JUMBO.c
index 764245a..c4607ec 100644
--- a/vm/mterp/c/OP_THROW_VERIFICATION_ERROR_JUMBO.c
+++ b/vm/mterp/c/OP_THROW_VERIFICATION_ERROR_JUMBO.c
@@ -1,7 +1,7 @@
 HANDLE_OPCODE(OP_THROW_VERIFICATION_ERROR_JUMBO)
     EXPORT_PC();
-    vsrc1 = FETCH(1);
-    ref = FETCH(2) | (u4)FETCH(3) << 16;      /* class/field/method ref */
+    vsrc1 = FETCH(3);
+    ref = FETCH(1) | (u4)FETCH(2) << 16;      /* class/field/method ref */
     dvmThrowVerificationError(curMethod, vsrc1, ref);
     GOTO_exceptionThrown();
 OP_END
diff --git a/vm/mterp/c/opcommon.c b/vm/mterp/c/opcommon.c
index 7ee07b3..fc7d9a2 100644
--- a/vm/mterp/c/opcommon.c
+++ b/vm/mterp/c/opcommon.c
@@ -453,7 +453,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         SET_REGISTER##_regsize(vdst,                                        \
@@ -478,7 +478,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
diff --git a/vm/mterp/config-x86-atom b/vm/mterp/config-x86-atom
index 18fb5cd..f99a4d2 100644
--- a/vm/mterp/config-x86-atom
+++ b/vm/mterp/config-x86-atom
@@ -61,7 +61,6 @@
 #op OP_APUT_SHORT c
 #op OP_APUT_WIDE c
 #op OP_ARRAY_LENGTH c
-#op OP_BREAKPOINT c
 #op OP_CHECK_CAST c
 #op OP_CMPG_DOUBLE c
 #op OP_CMPG_FLOAT c
@@ -92,7 +91,6 @@
 #op OP_DOUBLE_TO_FLOAT c
 #op OP_DOUBLE_TO_INT c
 #op OP_DOUBLE_TO_LONG c
-#op OP_EXECUTE_INLINE_RANGE c
 #op OP_EXECUTE_INLINE c
 #op OP_FILL_ARRAY_DATA c
 #op OP_FILLED_NEW_ARRAY_RANGE c
@@ -260,15 +258,6 @@
 #op OP_UNUSED_73 c
 #op OP_UNUSED_79 c
 #op OP_UNUSED_7A c
-#op OP_UNUSED_E3 c
-#op OP_UNUSED_E4 c
-#op OP_UNUSED_E5 c
-#op OP_UNUSED_E6 c
-#op OP_UNUSED_E7 c
-#op OP_UNUSED_E8 c
-#op OP_UNUSED_E9 c
-#op OP_UNUSED_EA c
-#op OP_UNUSED_EB c
 #op OP_UNUSED_F1 c
 #op OP_UNUSED_FC c
 #op OP_UNUSED_FD c
@@ -285,7 +274,10 @@
 #op OP_XOR_INT c
 #op OP_XOR_LONG_2ADDR c
 #op OP_XOR_LONG c
+
 # TODO: provide native implementations
+op OP_BREAKPOINT c
+op OP_EXECUTE_INLINE_RANGE c
 op OP_IGET_VOLATILE c
 op OP_IPUT_VOLATILE c
 op OP_SGET_VOLATILE c
diff --git a/vm/mterp/out/InterpAsm-armv5te-vfp.S b/vm/mterp/out/InterpAsm-armv5te-vfp.S
index c42ca9d..19c152f 100644
--- a/vm/mterp/out/InterpAsm-armv5te-vfp.S
+++ b/vm/mterp/out/InterpAsm-armv5te-vfp.S
@@ -21316,14 +21316,13 @@
 /*
  * Invalid array index. Note that our calling convention is strange; we use r1
  * and r3 because those just happen to be the registers all our callers are
- * using. We shuffle them here before calling the C function.
+ * using. We move r3 before calling the C function, but r1 happens to match.
  * r1: index
  * r3: size
  */
 common_errArrayIndex:
     EXPORT_PC()
-    mov     r0, r1
-    mov     r1, r3
+    mov     r0, r3
     bl      dvmThrowArrayIndexOutOfBoundsException
     b       common_exceptionThrown
 
diff --git a/vm/mterp/out/InterpAsm-armv5te.S b/vm/mterp/out/InterpAsm-armv5te.S
index 627f1a4..a1977ee 100644
--- a/vm/mterp/out/InterpAsm-armv5te.S
+++ b/vm/mterp/out/InterpAsm-armv5te.S
@@ -21774,14 +21774,13 @@
 /*
  * Invalid array index. Note that our calling convention is strange; we use r1
  * and r3 because those just happen to be the registers all our callers are
- * using. We shuffle them here before calling the C function.
+ * using. We move r3 before calling the C function, but r1 happens to match.
  * r1: index
  * r3: size
  */
 common_errArrayIndex:
     EXPORT_PC()
-    mov     r0, r1
-    mov     r1, r3
+    mov     r0, r3
     bl      dvmThrowArrayIndexOutOfBoundsException
     b       common_exceptionThrown
 
diff --git a/vm/mterp/out/InterpAsm-armv7-a-neon.S b/vm/mterp/out/InterpAsm-armv7-a-neon.S
index bbecc54..c7d3707 100644
--- a/vm/mterp/out/InterpAsm-armv7-a-neon.S
+++ b/vm/mterp/out/InterpAsm-armv7-a-neon.S
@@ -21254,14 +21254,13 @@
 /*
  * Invalid array index. Note that our calling convention is strange; we use r1
  * and r3 because those just happen to be the registers all our callers are
- * using. We shuffle them here before calling the C function.
+ * using. We move r3 before calling the C function, but r1 happens to match.
  * r1: index
  * r3: size
  */
 common_errArrayIndex:
     EXPORT_PC()
-    mov     r0, r1
-    mov     r1, r3
+    mov     r0, r3
     bl      dvmThrowArrayIndexOutOfBoundsException
     b       common_exceptionThrown
 
diff --git a/vm/mterp/out/InterpAsm-armv7-a.S b/vm/mterp/out/InterpAsm-armv7-a.S
index ab58120..4756775 100644
--- a/vm/mterp/out/InterpAsm-armv7-a.S
+++ b/vm/mterp/out/InterpAsm-armv7-a.S
@@ -21254,14 +21254,13 @@
 /*
  * Invalid array index. Note that our calling convention is strange; we use r1
  * and r3 because those just happen to be the registers all our callers are
- * using. We shuffle them here before calling the C function.
+ * using. We move r3 before calling the C function, but r1 happens to match.
  * r1: index
  * r3: size
  */
 common_errArrayIndex:
     EXPORT_PC()
-    mov     r0, r1
-    mov     r1, r3
+    mov     r0, r3
     bl      dvmThrowArrayIndexOutOfBoundsException
     b       common_exceptionThrown
 
diff --git a/vm/mterp/out/InterpAsm-x86-atom.S b/vm/mterp/out/InterpAsm-x86-atom.S
index 7a9c7a4..b92c634 100644
--- a/vm/mterp/out/InterpAsm-x86-atom.S
+++ b/vm/mterp/out/InterpAsm-x86-atom.S
@@ -295,44 +295,6 @@
     jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
     .endm
 
-    .macro      FGETOP_JMP2 _rFinish
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-    .macro      OLD_JMP_1 _count _rFinish
-    movzbl      (\_count*2)(rPC), \_rFinish
-    shl         $6, \_rFinish
-    .endm
-
-    .macro      OLD_JMP_2 _rFinish
-    addl        $dvmAsmInstructionStart,\_rFinish
-    .endm
-
-    .macro      OLD_JMP_3 _count
-    addl        $(\_count*2), rPC
-    .endm
-
-    .macro      OLD_JMP_4 _rFinish
-    movzbl      1(rPC), rINST
-    jmp         *\_rFinish
-    .endm
-
-    .macro      OLD_JMP_A_1 _reg _rFinish
-    movzbl      (rPC, \_reg), \_rFinish
-    shl         $6, \_rFinish
-    .endm
-
-    .macro      OLD_JMP_A_2 _rFinish
-    addl        $dvmAsmInstructionStart,\_rFinish
-    .endm
-
-    .macro      OLD_JMP_A_3 _reg _rFinish
-    addl        \_reg, rPC
-    movzbl      1(rPC, \_reg), rINST
-    jmp         *\_rFinish
-    .endm
-
    /*
     * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
     * by using a jump table. _rFinish and _reg should must be the same register for
@@ -571,6 +533,7 @@
     GET_VREG    rINST                   # rINST<- vB
     SET_VREG    rINST, %ecx             # vA<- vB; %edx
     FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_MOVE_FROM16: /* 0x02 */
@@ -693,6 +656,7 @@
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vB
     movq        %xmm0, (rFP, rINST, 4)  # vA<- vB
     FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_MOVE_WIDE_FROM16: /* 0x05 */
@@ -836,6 +800,7 @@
     SET_VREG    rINST, %ecx             # vA<- vB; %edx
     FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
@@ -1362,7 +1327,7 @@
     *
     * For: const/4
     *
-    * Description: Move the given literal value (right-sign-extended to 32
+    * Description: Move the given literal value (right-zero-extended to 32
     *              bits) into the specified register.
     *
     * Format: B|A|op (11n)
@@ -1372,12 +1337,12 @@
 
     movl        rINST, %edx             # %edx<- BA
     andl        $15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next i nstruction hi; fetch, advance
     shl         $24, %edx              # %edx<- B000
-    addl        $2, rPC                  # update PC
     sar         $28, %edx              # %edx<- right-zero-extended B
+    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     SET_VREG    %edx, rINST             # vA<- %edx; literal
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_CONST_16: /* 0x13 */
@@ -1416,6 +1381,7 @@
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     SET_VREG    %edx rINST              # vAA<- BBBB; literal
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_CONST: /* 0x14 */
@@ -1456,6 +1422,7 @@
     FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
     SET_VREG    %ecx, rINST             # vAA<- %ecx; literal
     FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_CONST_HIGH16: /* 0x15 */
@@ -1537,6 +1504,7 @@
     movl        %edx, (rFP, rINST, 4)   # vAA<- ssssBBBB
     movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- ssssssss
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_CONST_WIDE_32: /* 0x17 */
@@ -1580,6 +1548,7 @@
     movl        %edx, (rFP, rINST, 4)   # vAA<-  BBBBBBBB
     movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- ssssssss
     FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_CONST_WIDE: /* 0x18 */
@@ -2038,10 +2007,10 @@
     movl        rINST, %eax             # %eax<- BA
     shr         $4, %eax               # %eax<- B
     andl        $15, rINST             # rINST<- A
-    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
     GET_VREG    %eax                    # %eax<- vB
-    testl       %eax, %eax              # check for null array object
+    cmp         $0, %eax               # check for null array object
     je          common_errNullObject    # handle null array object
+    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
     movl        offArrayObject_length(%eax), %eax # %eax<- array length
     movl        %eax, (rFP, rINST, 4)   # vA<- %eax; array length
     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
@@ -2395,6 +2364,7 @@
     */
 
     movl        rGLUE, %eax             # %eax<- pMterpGlue
+    EXPORT_PC                           # export the pc
     GET_VREG    rINST                   # rINST<- vAA
     cmp         $0, rINST              # check for null
     movl        offGlue_self(%eax), %ecx # %ecx<- glue->self
@@ -2440,7 +2410,7 @@
 
     movsbl      rINSTbl, %edx           # %edx<- +AA
     shl         $1, %edx               # %edx is shifted for byte offset
-    js          common_periodicChecks2  # do check on backwards branch
+    js          common_periodicChecks_backwardBranch  # do check on backwards branch
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
 /* ------------------------------ */
@@ -2479,7 +2449,7 @@
 
     FETCHs      1, %edx                 # %edx<- ssssAAAA (sign-extended)
     shl         $1, %edx               # %edx is doubled to get the byte offset
-    js          common_periodicChecks2  # do check on backwards branch
+    js          common_periodicChecks_backwardBranch  # do check on backwards branch
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
 /* ------------------------------ */
@@ -2521,7 +2491,7 @@
     shl         $16, %ecx              # prepare to create +AAAAAAAA
     or          %ecx, %edx              # %edx<- +AAAAAAAA
     shl         $1, %edx               # %edx is doubled to get the byte offset
-    jle          common_periodicChecks2  # do check on backwards branch
+    jle          common_periodicChecks_backwardBranch  # do check on backwards branch
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
 /* ------------------------------ */
@@ -2574,7 +2544,7 @@
     shl         $1, %eax               # shift for byte offset
     movl        %eax, %edx              # %edx<- offset
     lea         8(%esp), %esp
-    jle         common_periodicChecks2  # do backward branch
+    jle         common_periodicChecks_backwardBranch  # do backward branch
     jmp         .LOP_PACKED_SWITCH_finish
 
 /* ------------------------------ */
@@ -2647,7 +2617,7 @@
     shl         $1, %eax               # shift for byte offset
     movl        %eax, %edx              # %edx<- offset
     lea         8(%esp), %esp
-    jle         common_periodicChecks2  # do backward branch
+    jle         common_periodicChecks_backwardBranch  # do backward branch
     jmp         .LOP_SPARSE_SWITCH_finish
 
 
@@ -2694,15 +2664,9 @@
 
     FETCH_BB    1, %ecx                 # %ecx<- BB
     FETCH_CC    1, %edx                 # %edx<- CC
-
-    flds     (rFP, %edx, 4)
-    flds     (rFP, %ecx, 4)
-
-    fucompp
-    fnstsw      %ax
-    sahf
-
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
+    movss    (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
+    comiss   (rFP, %edx, 4), %xmm0   # do comparison
     ja          .LOP_CMPL_FLOAT_greater
     jp          .LOP_CMPL_FLOAT_finalNan
     jz          .LOP_CMPL_FLOAT_final
@@ -2775,15 +2739,9 @@
 
     FETCH_BB    1, %ecx                 # %ecx<- BB
     FETCH_CC    1, %edx                 # %edx<- CC
-
-    flds     (rFP, %edx, 4)
-    flds     (rFP, %ecx, 4)
-
-    fucompp
-    fnstsw      %ax
-    sahf
-
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
+    movss    (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
+    comiss   (rFP, %edx, 4), %xmm0   # do comparison
     ja          .LOP_CMPG_FLOAT_greater
     jp          .LOP_CMPG_FLOAT_finalNan
     jz          .LOP_CMPG_FLOAT_final
@@ -2857,15 +2815,9 @@
 
     FETCH_BB    1, %ecx                 # %ecx<- BB
     FETCH_CC    1, %edx                 # %edx<- CC
-
-    fldl     (rFP, %edx, 4)
-    fldl     (rFP, %ecx, 4)
-
-    fucompp
-    fnstsw      %ax
-    sahf
-
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
+    movsd    (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
+    comisd   (rFP, %edx, 4), %xmm0   # do comparison
     ja          .LOP_CMPL_DOUBLE_greater
     jp          .LOP_CMPL_DOUBLE_finalNan
     jz          .LOP_CMPL_DOUBLE_final
@@ -2939,15 +2891,9 @@
 
     FETCH_BB    1, %ecx                 # %ecx<- BB
     FETCH_CC    1, %edx                 # %edx<- CC
-
-    fldl     (rFP, %edx, 4)
-    fldl     (rFP, %ecx, 4)
-
-    fucompp
-    fnstsw      %ax
-    sahf
-
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
+    movsd    (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
+    comisd   (rFP, %edx, 4), %xmm0   # do comparison
     ja          .LOP_CMPG_DOUBLE_greater
     jp          .LOP_CMPG_DOUBLE_finalNan
     jz          .LOP_CMPG_DOUBLE_final
@@ -3070,7 +3016,7 @@
                                         # comparison is true
     FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
     sal         $1, %edx
-    js          common_periodicChecks2
+    js          common_periodicChecks_backwardBranch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3140,7 +3086,7 @@
                                         # comparison is true
     FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
     sal         $1, %edx
-    js          common_periodicChecks2
+    js          common_periodicChecks_backwardBranch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3210,7 +3156,7 @@
                                         # comparison is true
     FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
     sal         $1, %edx
-    js          common_periodicChecks2
+    js          common_periodicChecks_backwardBranch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3280,7 +3226,7 @@
                                         # comparison is true
     FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
     sal         $1, %edx
-    js          common_periodicChecks2
+    js          common_periodicChecks_backwardBranch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3350,7 +3296,7 @@
                                         # comparison is true
     FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
     sal         $1, %edx
-    js          common_periodicChecks2
+    js          common_periodicChecks_backwardBranch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3420,7 +3366,7 @@
                                         # comparison is true
     FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
     sal         $1, %edx
-    js          common_periodicChecks2
+    js          common_periodicChecks_backwardBranch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3489,7 +3435,7 @@
     * Inline common_backwardBranch
     */
 
-    js          common_periodicChecks2  # jump on backwards branch
+    js          common_periodicChecks_backwardBranch  # jump on backwards branch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3568,7 +3514,7 @@
     * Inline common_backwardBranch
     */
 
-    js          common_periodicChecks2  # jump on backwards branch
+    js          common_periodicChecks_backwardBranch  # jump on backwards branch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3647,7 +3593,7 @@
     * Inline common_backwardBranch
     */
 
-    js          common_periodicChecks2  # jump on backwards branch
+    js          common_periodicChecks_backwardBranch  # jump on backwards branch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3726,7 +3672,7 @@
     * Inline common_backwardBranch
     */
 
-    js          common_periodicChecks2  # jump on backwards branch
+    js          common_periodicChecks_backwardBranch  # jump on backwards branch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3805,7 +3751,7 @@
     * Inline common_backwardBranch
     */
 
-    js          common_periodicChecks2  # jump on backwards branch
+    js          common_periodicChecks_backwardBranch  # jump on backwards branch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -3884,7 +3830,7 @@
     * Inline common_backwardBranch
     */
 
-    js          common_periodicChecks2  # jump on backwards branch
+    js          common_periodicChecks_backwardBranch  # jump on backwards branch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
@@ -4291,6 +4237,7 @@
                                                 # with one instr was not faster
     SET_VREG    %edx  rINST             # vAA<- %edx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_AGET_WIDE: /* 0x45 */
@@ -4338,6 +4285,7 @@
     movq        offArrayObject_contents(%ecx, %edx, 8), %xmm0 # %xmm0<- vBB[vCC]
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_AGET_OBJECT: /* 0x46 */
@@ -4415,6 +4363,7 @@
     SET_VREG    %edx  rINST             # vAA<- %edx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_AGET_BOOLEAN: /* 0x47 */
@@ -4492,6 +4441,7 @@
     SET_VREG    %edx  rINST             # vAA<- %edx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_AGET_BYTE: /* 0x48 */
@@ -4569,6 +4519,7 @@
     SET_VREG    %edx  rINST             # vAA<- %edx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_AGET_CHAR: /* 0x49 */
@@ -4646,6 +4597,7 @@
     SET_VREG    %edx  rINST             # vAA<- %edx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_AGET_SHORT: /* 0x4a */
@@ -4723,6 +4675,7 @@
     SET_VREG    %edx  rINST             # vAA<- %edx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_APUT: /* 0x4b */
@@ -4776,6 +4729,7 @@
     GET_VREG    rINST                   # rINST<- vAA
     movl     rINST, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_APUT_WIDE: /* 0x4c */
@@ -4823,6 +4777,7 @@
     movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vAA
     movq        %xmm0, offArrayObject_contents(%ecx, %edx, 8) # vBB[vCC]<- %xmm0; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+
 /* ------------------------------ */
     .balign 64
 .L_OP_APUT_OBJECT: /* 0x4d */
@@ -4950,6 +4905,7 @@
     movb     rINSTbl, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_APUT_BYTE: /* 0x4f */
@@ -5024,6 +4980,7 @@
     movb     rINSTbl, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_APUT_CHAR: /* 0x50 */
@@ -5098,6 +5055,7 @@
     movw     rINSTw, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_APUT_SHORT: /* 0x51 */
@@ -5172,6 +5130,7 @@
     movw     rINSTw, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_IGET: /* 0x52 */
@@ -5796,26 +5755,6 @@
     * limitations under the License.
     */
 
-   /*
-    * File: OP_IPUT_OBJECT.S
-    */
-
-/* File: x86-atom/OP_IPUT.S */
-   /* Copyright (C) 2008 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.
-    */
-
     /*
     * File: OP_IPUT.S
     *
@@ -5838,7 +5777,6 @@
     *         op vA, vB, field@CCCC
     */
 
-
     movl        rGLUE, %edx             # %edx<- pMterpGlue
     movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
     FETCH       1, %ecx                 # %ecx<- CCCC
@@ -5849,7 +5787,6 @@
     movl        rGLUE, %edx             # %edx<- pMterpGlue
     jmp         .LOP_IPUT_OBJECT_finish
 
-
 /* ------------------------------ */
     .balign 64
 .L_OP_IPUT_BOOLEAN: /* 0x5c */
@@ -6674,26 +6611,6 @@
 
    /*
     * File: OP_SPUT_OBJECT.S
-    */
-
-/* File: x86-atom/OP_SPUT.S */
-   /* Copyright (C) 2008 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.
-    */
-
-   /*
-    * File: OP_SPUT.S
     *
     * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
     *
@@ -6712,12 +6629,11 @@
     movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- pDvmDex
     FETCH       1, %eax                 # %eax<- BBBB
     movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
-    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField ptr
-    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField ptr
+    cmp         $0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField
+    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField
     je          .LOP_SPUT_OBJECT_resolve
     jmp         .LOP_SPUT_OBJECT_finish
 
-
 /* ------------------------------ */
     .balign 64
 .L_OP_SPUT_BOOLEAN: /* 0x6a */
@@ -7942,6 +7858,7 @@
     SET_VREG    %ecx, rINST             # vA<- result
     FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_NOT_INT: /* 0x7c */
@@ -8009,6 +7926,7 @@
     SET_VREG    %ecx, rINST             # vA<- result
     FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_NEG_LONG: /* 0x7d */
@@ -8212,6 +8130,7 @@
     SET_VREG    %ecx, rINST             # vA<- result
     FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_NEG_DOUBLE: /* 0x80 */
@@ -8471,6 +8390,7 @@
     SET_VREG    rINST, %ecx             # vA<- vB; %edx
     FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_LONG_TO_FLOAT: /* 0x85 */
@@ -8888,6 +8808,7 @@
     SET_VREG    %ecx, rINST             # vA<- result
     FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_INT_TO_CHAR: /* 0x8e */
@@ -8955,6 +8876,7 @@
     SET_VREG    %ecx, rINST             # vA<- result
     FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_INT_TO_SHORT: /* 0x8f */
@@ -9022,6 +8944,7 @@
     SET_VREG    %ecx, rINST             # vA<- result
     FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_ADD_INT: /* 0x90 */
@@ -9077,17 +9000,14 @@
     * Syntax: op vAA, vBB, vCC
     */
 
-
-
     FETCH_BB    1, %ecx                 # %ecx<- BB
-    OLD_JMP_1   2, %eax
-    OLD_JMP_2   %eax
     FETCH_CC    1, %edx                 # %edx<- CC
-    OLD_JMP_3   2
+    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vBB
-    addl     (rFP, %edx, 4), %ecx                              # %ecx<- vBB op vCC
+    GET_VREG    %edx                    # %edx<- vCC
+    addl     %edx, %ecx                              # %ecx<- vBB op vCC
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    OLD_JMP_4   %eax
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
 
 /* ------------------------------ */
@@ -9145,17 +9065,14 @@
     * Syntax: op vAA, vBB, vCC
     */
 
-
-
     FETCH_BB    1, %ecx                 # %ecx<- BB
-    OLD_JMP_1   2, %eax
-    OLD_JMP_2   %eax
     FETCH_CC    1, %edx                 # %edx<- CC
-    OLD_JMP_3   2
+    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vBB
-    subl     (rFP, %edx, 4), %ecx                              # %ecx<- vBB op vCC
+    GET_VREG    %edx                    # %edx<- vCC
+    subl     %edx, %ecx                              # %ecx<- vBB op vCC
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    OLD_JMP_4   %eax
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
 
 /* ------------------------------ */
@@ -9179,10 +9096,33 @@
 
    /*
     * File: OP_MUL_INT.S
+    */
+
+/* File: x86-atom/binop.S */
+   /* Copyright (C) 2008 The Android Open Source Project
     *
-    * Code: 32-bit multiply operation.  Performs "%ecx = %ecx * %edx"
+    * 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
     *
-    * Description: Perform a multiplication operation on two source registers
+    * 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.
+    */
+
+   /*
+    * File: binop.S
+    *
+    * Code: Generic 32-bit binary operation.  Provides an "instr" line to
+    *       specify an instruction that performs "%ecx = %ecx op %edx"
+    *
+    * For: add-int, and-int, mul-int, or-int, sub-int, xor-int
+    *
+    * Description: Perform a binary operation on two source registers
     *              and store the result in a destination register.
     *
     * Format: AA|op CC|BB (23x)
@@ -9194,10 +9134,11 @@
     FETCH_CC    1, %edx                 # %edx<- CC
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vBB
-    addl        $4, rPC                  # update PC
-    imul        (rFP, %edx, 4), %ecx    # %ecx<- vBB * vCC
+    GET_VREG    %edx                    # %edx<- vCC
+    imul     %edx, %ecx                              # %ecx<- vBB op vCC
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+
 
 /* ------------------------------ */
     .balign 64
@@ -9255,29 +9196,25 @@
     */
 
 
-
-    FETCH_CC    1, %ecx                 # %ecx<- CC
     FETCH_BB    1, %eax                 # %eax<- BB
-    GET_VREG    %ecx                    # %ecx<- vCC
-    testl       %ecx, %ecx
+    FETCH_CC    1, %ecx                 # %ecx<- CC
     GET_VREG    %eax                    # %eax<- vBB
+    GET_VREG    %ecx                    # %ecx<- vCC
+    cmp         $0, %ecx               # check for divide by zero
     je          common_errDivideByZero  # handle divide by zero
     cmpl        $-1, %ecx              # handle -1 special case divide error
-    jnz         .LOP_DIV_INT_continue
+    jne         .LOP_DIV_INT_noerror
     cmpl        $0x80000000,%eax       # handle min int special case divide error
     je         .LOP_DIV_INT_break
-.LOP_DIV_INT_continue:
+.LOP_DIV_INT_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
     .if  1
-    FFETCH_ADV 2 %edx
     SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    FGETOP_JMP  2 %edx
     .else
-    FFETCH_ADV  2 %eax
-    SET_VREG %edx rINST  # vAA<- %edx (remainder)
-    FGETOP_JMP  2 %eax
+    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
     .endif
+    jmp         .LOP_DIV_INT_break2
 
 
 /* ------------------------------ */
@@ -9336,29 +9273,25 @@
     */
 
 
-
-    FETCH_CC    1, %ecx                 # %ecx<- CC
     FETCH_BB    1, %eax                 # %eax<- BB
-    GET_VREG    %ecx                    # %ecx<- vCC
-    testl       %ecx, %ecx
+    FETCH_CC    1, %ecx                 # %ecx<- CC
     GET_VREG    %eax                    # %eax<- vBB
+    GET_VREG    %ecx                    # %ecx<- vCC
+    cmp         $0, %ecx               # check for divide by zero
     je          common_errDivideByZero  # handle divide by zero
     cmpl        $-1, %ecx              # handle -1 special case divide error
-    jnz         .LOP_REM_INT_continue
+    jne         .LOP_REM_INT_noerror
     cmpl        $0x80000000,%eax       # handle min int special case divide error
     je         .LOP_REM_INT_break
-.LOP_REM_INT_continue:
+.LOP_REM_INT_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
     .if  0
-    FFETCH_ADV 2 %edx
     SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    FGETOP_JMP  2 %edx
     .else
-    FFETCH_ADV  2 %eax
-    SET_VREG %edx rINST  # vAA<- %edx (remainder)
-    FGETOP_JMP  2 %eax
+    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
     .endif
+    jmp         .LOP_REM_INT_break2
 
 
 /* ------------------------------ */
@@ -9416,17 +9349,14 @@
     * Syntax: op vAA, vBB, vCC
     */
 
-
-
     FETCH_BB    1, %ecx                 # %ecx<- BB
-    OLD_JMP_1   2, %eax
-    OLD_JMP_2   %eax
     FETCH_CC    1, %edx                 # %edx<- CC
-    OLD_JMP_3   2
+    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vBB
-    andl     (rFP, %edx, 4), %ecx                              # %ecx<- vBB op vCC
+    GET_VREG    %edx                    # %edx<- vCC
+    andl     %edx, %ecx                              # %ecx<- vBB op vCC
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    OLD_JMP_4   %eax
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
 
 /* ------------------------------ */
@@ -9484,17 +9414,14 @@
     * Syntax: op vAA, vBB, vCC
     */
 
-
-
     FETCH_BB    1, %ecx                 # %ecx<- BB
-    OLD_JMP_1   2, %eax
-    OLD_JMP_2   %eax
     FETCH_CC    1, %edx                 # %edx<- CC
-    OLD_JMP_3   2
+    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vBB
-    or (rFP, %edx, 4), %ecx                              # %ecx<- vBB op vCC
+    GET_VREG    %edx                    # %edx<- vCC
+    or %edx, %ecx                              # %ecx<- vBB op vCC
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    OLD_JMP_4   %eax
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
 
 /* ------------------------------ */
@@ -9552,17 +9479,14 @@
     * Syntax: op vAA, vBB, vCC
     */
 
-
-
     FETCH_BB    1, %ecx                 # %ecx<- BB
-    OLD_JMP_1   2, %eax
-    OLD_JMP_2   %eax
     FETCH_CC    1, %edx                 # %edx<- CC
-    OLD_JMP_3   2
+    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vBB
-    xor     (rFP, %edx, 4), %ecx                              # %ecx<- vBB op vCC
+    GET_VREG    %edx                    # %edx<- vCC
+    xor     %edx, %ecx                              # %ecx<- vBB op vCC
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    OLD_JMP_4   %eax
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
 
 /* ------------------------------ */
@@ -9620,15 +9544,15 @@
     * Syntax: op vAA, vBB, vCC
     */
 
-    FETCH_CC    1, %ecx                 # %ecx<- CC
     FETCH_BB    1, %edx                 # %edx<- BB
+    FETCH_CC    1, %ecx                 # %ecx<- CC
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    addl        $4, rPC                  # update PC
-    GET_VREG    %ecx                    # %ecx<- vCC
     GET_VREG    %edx                    # %edx<- vBB
+    GET_VREG    %ecx                    # %ecx<- vCC
     sal     %cl, %edx                              # %edx<- vBB op +CC
     SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+
 
 /* ------------------------------ */
     .balign 64
@@ -9685,15 +9609,15 @@
     * Syntax: op vAA, vBB, vCC
     */
 
-    FETCH_CC    1, %ecx                 # %ecx<- CC
     FETCH_BB    1, %edx                 # %edx<- BB
+    FETCH_CC    1, %ecx                 # %ecx<- CC
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    addl        $4, rPC                  # update PC
-    GET_VREG    %ecx                    # %ecx<- vCC
     GET_VREG    %edx                    # %edx<- vBB
+    GET_VREG    %ecx                    # %ecx<- vCC
     sar     %cl, %edx                              # %edx<- vBB op +CC
     SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+
 
 /* ------------------------------ */
     .balign 64
@@ -9750,15 +9674,15 @@
     * Syntax: op vAA, vBB, vCC
     */
 
-    FETCH_CC    1, %ecx                 # %ecx<- CC
     FETCH_BB    1, %edx                 # %edx<- BB
+    FETCH_CC    1, %ecx                 # %ecx<- CC
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    addl        $4, rPC                  # update PC
-    GET_VREG    %ecx                    # %ecx<- vCC
     GET_VREG    %edx                    # %edx<- vBB
+    GET_VREG    %ecx                    # %ecx<- vCC
     shr     %cl, %edx                              # %edx<- vBB op +CC
     SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+
 
 /* ------------------------------ */
     .balign 64
@@ -9825,6 +9749,7 @@
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SUB_LONG: /* 0x9c */
@@ -9890,6 +9815,7 @@
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_MUL_LONG: /* 0x9d */
@@ -10145,6 +10071,7 @@
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_OR_LONG: /* 0xa1 */
@@ -10210,6 +10137,7 @@
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_XOR_LONG: /* 0xa2 */
@@ -10275,6 +10203,7 @@
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SHL_LONG: /* 0xa3 */
@@ -10474,6 +10403,7 @@
     movss       %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SUB_FLOAT: /* 0xa7 */
@@ -10538,6 +10468,7 @@
     movss       %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_MUL_FLOAT: /* 0xa8 */
@@ -10602,6 +10533,7 @@
     movss       %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_DIV_FLOAT: /* 0xa9 */
@@ -10757,6 +10689,7 @@
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SUB_DOUBLE: /* 0xac */
@@ -10822,6 +10755,7 @@
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_MUL_DOUBLE: /* 0xad */
@@ -10887,6 +10821,7 @@
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_DIV_DOUBLE: /* 0xae */
@@ -11036,15 +10971,16 @@
 
     movl        rINST, %edx             # %edx<- BA
     shr         $4, %edx               # %edx<- B
-    #FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    OLD_JMP_1   1, %eax
-    andl $15, rINST  # rINST<- A
-    OLD_JMP_2  %eax
+    andl        $15, rINST             # rINST<- A
+    movl        rINST, %ecx             # %ecx<- A
+    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %edx                    # %edx<- vB
-    OLD_JMP_3   1
-    addl     %edx,  (rFP, rINST, 4)    # %ecx<- vA op vB
-    #FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-    OLD_JMP_4   %eax
+    GET_VREG    %ecx                    # %ecx<- vA
+    addl     %edx, %ecx                              # %ecx<- vA op vB
+    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
+
 
 
 /* ------------------------------ */
@@ -11106,15 +11042,16 @@
 
     movl        rINST, %edx             # %edx<- BA
     shr         $4, %edx               # %edx<- B
-    #FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    OLD_JMP_1   1, %eax
-    andl $15, rINST  # rINST<- A
-    OLD_JMP_2  %eax
+    andl        $15, rINST             # rINST<- A
+    movl        rINST, %ecx             # %ecx<- A
+    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %edx                    # %edx<- vB
-    OLD_JMP_3   1
-    subl     %edx, (rFP, rINST, 4)    # %ecx<- vA op vB
-    #FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-    OLD_JMP_4   %eax
+    GET_VREG    %ecx                    # %ecx<- vA
+    subl     %edx, %ecx                              # %ecx<- vA op vB
+    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
+
 
 
 /* ------------------------------ */
@@ -11140,16 +11077,53 @@
     * File: OP_MUL_INT_2ADDR.S
     */
 
+/* File: x86-atom/binop2addr.S */
+   /* Copyright (C) 2008 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.
+    */
+
+   /*
+    * File: binop2addr.S
+    *
+    * Code: Generic 32-bit "/2addr" binary operation.  Provides an
+    *       "instr" line to specify an instruction that performs
+    *       "%ecx = %ecx op %edx".
+    *
+    * For: add-int/2addr, and-int/2addr, mul-int/2addr, or-int/2addr,
+    *      sub-int/2addr, xor-int/2addr
+    *
+    * Description: Perform a binary operation on two sources registers
+    *              and store the result in the first source register
+    *
+    * Format: B|A|op (12x)
+    *
+    * Syntax: op vA, vB
+    */
+
     movl        rINST, %edx             # %edx<- BA
     shr         $4, %edx               # %edx<- B
     andl        $15, rINST             # rINST<- A
     movl        rINST, %ecx             # %ecx<- A
     FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
+    GET_VREG    %edx                    # %edx<- vB
     GET_VREG    %ecx                    # %ecx<- vA
-    imul        (rFP, %edx, 4), %ecx    # %ecx<- vA * vB
-    addl        $2, rPC                  # update PC
+    imul     %edx, %ecx                              # %ecx<- vA op vB
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
+
+
 
 /* ------------------------------ */
     .balign 64
@@ -11208,30 +11182,28 @@
     */
 
     movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
     andl        $15, rINST             # rINST<- A, to be used as dest
     movl        rINST, %eax             # %eax<- A
-    GET_VREG    %ecx                    # %edx<- vB
-    testl       %ecx, %ecx               # check for divide by zero
+    shr         $4, %ecx               # %ecx<- B
     GET_VREG    %eax                    # %eax<- vA
-    jz          common_errDivideByZero  # handle divide by zero
+    GET_VREG    %ecx                    # %edx<- vB
+    cmp         $0, %ecx               # check for divide by zero
+    je          common_errDivideByZero  # handle divide by zero
     cmpl        $-1, %ecx              # handle -1 special case divide error
-    jnz         .LOP_DIV_INT_2ADDR_continue
-    cmpl        $0x80000000, %eax       # handle min int special case divide error
+    jne         .LOP_DIV_INT_2ADDR_noerror
+    cmpl        $0x80000000,%eax       # handle min int special case divide error
     je         .LOP_DIV_INT_2ADDR_break
-
-.LOP_DIV_INT_2ADDR_continue:
+.LOP_DIV_INT_2ADDR_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
      .if  1
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
     SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
     .else
-    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
     SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
     .endif
+    jmp         .LOP_DIV_INT_2ADDR_break2
+    #FFETCH_ADV 1, %edx  # %ecx<- next instruction hi; fetch, advance
+    #FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
 
 
 
@@ -11292,30 +11264,28 @@
     */
 
     movl        rINST, %ecx             # %ecx<- BA
-    shr         $4, %ecx               # %ecx<- B
     andl        $15, rINST             # rINST<- A, to be used as dest
     movl        rINST, %eax             # %eax<- A
-    GET_VREG    %ecx                    # %edx<- vB
-    testl       %ecx, %ecx               # check for divide by zero
+    shr         $4, %ecx               # %ecx<- B
     GET_VREG    %eax                    # %eax<- vA
-    jz          common_errDivideByZero  # handle divide by zero
+    GET_VREG    %ecx                    # %edx<- vB
+    cmp         $0, %ecx               # check for divide by zero
+    je          common_errDivideByZero  # handle divide by zero
     cmpl        $-1, %ecx              # handle -1 special case divide error
-    jnz         .LOP_REM_INT_2ADDR_continue
-    cmpl        $0x80000000, %eax       # handle min int special case divide error
+    jne         .LOP_REM_INT_2ADDR_noerror
+    cmpl        $0x80000000,%eax       # handle min int special case divide error
     je         .LOP_REM_INT_2ADDR_break
-
-.LOP_REM_INT_2ADDR_continue:
+.LOP_REM_INT_2ADDR_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
      .if  0
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
     SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
     .else
-    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
     SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
     .endif
+    jmp         .LOP_REM_INT_2ADDR_break2
+    #FFETCH_ADV 1, %edx  # %ecx<- next instruction hi; fetch, advance
+    #FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
 
 
 
@@ -11378,15 +11348,16 @@
 
     movl        rINST, %edx             # %edx<- BA
     shr         $4, %edx               # %edx<- B
-    #FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    OLD_JMP_1   1, %eax
-    andl $15, rINST  # rINST<- A
-    OLD_JMP_2  %eax
+    andl        $15, rINST             # rINST<- A
+    movl        rINST, %ecx             # %ecx<- A
+    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %edx                    # %edx<- vB
-    OLD_JMP_3   1
-    andl     %edx, (rFP, rINST, 4)    # %ecx<- vA op vB
-    #FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-    OLD_JMP_4   %eax
+    GET_VREG    %ecx                    # %ecx<- vA
+    andl     %edx, %ecx                              # %ecx<- vA op vB
+    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
+
 
 
 /* ------------------------------ */
@@ -11448,15 +11419,16 @@
 
     movl        rINST, %edx             # %edx<- BA
     shr         $4, %edx               # %edx<- B
-    #FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    OLD_JMP_1   1, %eax
-    andl $15, rINST  # rINST<- A
-    OLD_JMP_2  %eax
+    andl        $15, rINST             # rINST<- A
+    movl        rINST, %ecx             # %ecx<- A
+    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %edx                    # %edx<- vB
-    OLD_JMP_3   1
-    or %edx, (rFP, rINST, 4)    # %ecx<- vA op vB
-    #FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-    OLD_JMP_4   %eax
+    GET_VREG    %ecx                    # %ecx<- vA
+    or %edx, %ecx                              # %ecx<- vA op vB
+    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
+
 
 
 /* ------------------------------ */
@@ -11518,15 +11490,16 @@
 
     movl        rINST, %edx             # %edx<- BA
     shr         $4, %edx               # %edx<- B
-    #FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    OLD_JMP_1   1, %eax
-    andl $15, rINST  # rINST<- A
-    OLD_JMP_2  %eax
+    andl        $15, rINST             # rINST<- A
+    movl        rINST, %ecx             # %ecx<- A
+    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %edx                    # %edx<- vB
-    OLD_JMP_3   1
-    xor     %edx, (rFP, rINST, 4)    # %ecx<- vA op vB
-    #FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-    OLD_JMP_4   %eax
+    GET_VREG    %ecx                    # %ecx<- vA
+    xor     %edx, %ecx                              # %ecx<- vA op vB
+    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
+
 
 
 /* ------------------------------ */
@@ -11587,15 +11560,15 @@
 
     movl        rINST, %ecx             # %ecx<- BA
     shr         $4, %ecx               # %ecx<- B
-    FFETCH_ADV  1, %eax                 # %ecx<- next i nstruction hi; fetch, advance
     andl        $15, rINST             # rINST<- A
-    addl        $2, rPC                  # update PC
     movl        rINST, %edx             # %edx<- A
+    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vB
     GET_VREG    %edx                    # %edx<- vA
     sal     %cl, %edx                              # %edx<- vA op vB
     SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
 
 /* ------------------------------ */
     .balign 64
@@ -11655,15 +11628,15 @@
 
     movl        rINST, %ecx             # %ecx<- BA
     shr         $4, %ecx               # %ecx<- B
-    FFETCH_ADV  1, %eax                 # %ecx<- next i nstruction hi; fetch, advance
     andl        $15, rINST             # rINST<- A
-    addl        $2, rPC                  # update PC
     movl        rINST, %edx             # %edx<- A
+    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vB
     GET_VREG    %edx                    # %edx<- vA
     sar     %cl, %edx                              # %edx<- vA op vB
     SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
 
 /* ------------------------------ */
     .balign 64
@@ -11723,15 +11696,15 @@
 
     movl        rINST, %ecx             # %ecx<- BA
     shr         $4, %ecx               # %ecx<- B
-    FFETCH_ADV  1, %eax                 # %ecx<- next i nstruction hi; fetch, advance
     andl        $15, rINST             # rINST<- A
-    addl        $2, rPC                  # update PC
     movl        rINST, %edx             # %edx<- A
+    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vB
     GET_VREG    %edx                    # %edx<- vA
     shr     %cl, %edx                              # %edx<- vA op vB
     SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
 
 /* ------------------------------ */
     .balign 64
@@ -11793,13 +11766,12 @@
     movl        rINST, %edx             # %edx<- BA
     shr         $4, rINST              # rINST<- B
     andl        $15, %edx              # %edx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
     paddq   %xmm1, %xmm0                              # %xmm0<- vA op vB
     movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    #FINISH      1                      # jump to next instruction
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+    FINISH      1                       # jump to next instruction
+
 
 /* ------------------------------ */
     .balign 64
@@ -11861,13 +11833,12 @@
     movl        rINST, %edx             # %edx<- BA
     shr         $4, rINST              # rINST<- B
     andl        $15, %edx              # %edx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
     psubq    %xmm1, %xmm0                              # %xmm0<- vA op vB
     movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    #FINISH      1                      # jump to next instruction
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+    FINISH      1                       # jump to next instruction
+
 
 /* ------------------------------ */
     .balign 64
@@ -12122,13 +12093,12 @@
     movl        rINST, %edx             # %edx<- BA
     shr         $4, rINST              # rINST<- B
     andl        $15, %edx              # %edx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
     pand   %xmm1, %xmm0                              # %xmm0<- vA op vB
     movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    #FINISH      1                      # jump to next instruction
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+    FINISH      1                       # jump to next instruction
+
 
 /* ------------------------------ */
     .balign 64
@@ -12190,13 +12160,12 @@
     movl        rINST, %edx             # %edx<- BA
     shr         $4, rINST              # rINST<- B
     andl        $15, %edx              # %edx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
     por %xmm1, %xmm0                              # %xmm0<- vA op vB
     movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    #FINISH      1                      # jump to next instruction
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+    FINISH      1                       # jump to next instruction
+
 
 /* ------------------------------ */
     .balign 64
@@ -12258,13 +12227,12 @@
     movl        rINST, %edx             # %edx<- BA
     shr         $4, rINST              # rINST<- B
     andl        $15, %edx              # %edx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
     pxor   %xmm1, %xmm0                              # %xmm0<- vA op vB
     movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    #FINISH      1                      # jump to next instruction
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+    FINISH      1                       # jump to next instruction
+
 
 /* ------------------------------ */
     .balign 64
@@ -12471,6 +12439,7 @@
     movss       %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
@@ -12537,6 +12506,7 @@
     movss       %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
@@ -12603,6 +12573,7 @@
     movss       %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
@@ -12754,13 +12725,12 @@
     movl        rINST, %edx             # %edx<- BA
     shr         $4, rINST              # rINST<- B
     andl        $15, %edx              # %edx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
     addsd   %xmm1, %xmm0                              # %xmm0<- vA op vB
     movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    #FINISH      1                      # jump to next instruction
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+    FINISH      1                       # jump to next instruction
+
 
 /* ------------------------------ */
     .balign 64
@@ -12822,13 +12792,12 @@
     movl        rINST, %edx             # %edx<- BA
     shr         $4, rINST              # rINST<- B
     andl        $15, %edx              # %edx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
     subsd   %xmm1, %xmm0                              # %xmm0<- vA op vB
     movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    #FINISH      1                      # jump to next instruction
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+    FINISH      1                       # jump to next instruction
+
 
 /* ------------------------------ */
     .balign 64
@@ -12890,13 +12859,12 @@
     movl        rINST, %edx             # %edx<- BA
     shr         $4, rINST              # rINST<- B
     andl        $15, %edx              # %edx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
     mulsd   %xmm1, %xmm0                              # %xmm0<- vA op vB
     movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    #FINISH      1                      # jump to next instruction
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+    FINISH      1                       # jump to next instruction
+
 
 /* ------------------------------ */
     .balign 64
@@ -13057,6 +13025,7 @@
     SET_VREG    %ecx, rINST             # vA<- %ecx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_RSUB_INT: /* 0xd1 */
@@ -13100,6 +13069,7 @@
     subl        %ecx, %edx              # %edx<- +CCCC sub vB
     SET_VREG    %edx, rINST             # vA<- %edx; result
     FINISH      2                       # jump to next instruction
+
 /* ------------------------------ */
     .balign 64
 .L_OP_MUL_INT_LIT16: /* 0xd2 */
@@ -13168,6 +13138,7 @@
     SET_VREG    %ecx, rINST             # vA<- %ecx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_DIV_INT_LIT16: /* 0xd3 */
@@ -13228,29 +13199,24 @@
     movl        rINST, %eax             # %eax<- BA
     shr         $4, %eax               # %eax<- B
     FETCHs      1, %ecx                 # %ecx<- +CCCC, sign-extended literal
-    testl       %ecx, %ecx              # check for divide by zero
+    cmp         $0, %ecx               # check for divide by zero
     GET_VREG    %eax                    # %eax<- vB
     je          common_errDivideByZero  # handle divide by zero
-    addl        $4, rPC                # update PC
     andl        $15, rINST             # rINST<- A
     cmpl        $-1, %ecx              # handle -1 special case divide error
-    jnz         .LOP_DIV_INT_LIT16_continue
+    jne         .LOP_DIV_INT_LIT16_noerror
     cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je          .LOP_DIV_INT_LIT16_break
-.LOP_DIV_INT_LIT16_continue:
+    je         .LOP_DIV_INT_LIT16_break
+.LOP_DIV_INT_LIT16_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
+    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
     .if  1
-    movzbl      (rPC), %edx
-    SET_VREG    %eax, rINST             # vA<- %eax (quotient)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+    SET_VREG    %eax rINST              # vA<- %eax (quotient)
     .else
-    movzbl      (rPC), %eax
-    SET_VREG    %edx, rINST             # vA<- %edx (remainder)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %eax, 4)
+    SET_VREG    %edx rINST              # vA<- %edx (remainder)
     .endif
+    jmp         .LOP_DIV_INT_LIT16_break2
 
 
 
@@ -13314,29 +13280,24 @@
     movl        rINST, %eax             # %eax<- BA
     shr         $4, %eax               # %eax<- B
     FETCHs      1, %ecx                 # %ecx<- +CCCC, sign-extended literal
-    testl       %ecx, %ecx              # check for divide by zero
+    cmp         $0, %ecx               # check for divide by zero
     GET_VREG    %eax                    # %eax<- vB
     je          common_errDivideByZero  # handle divide by zero
-    addl        $4, rPC                # update PC
     andl        $15, rINST             # rINST<- A
     cmpl        $-1, %ecx              # handle -1 special case divide error
-    jnz         .LOP_REM_INT_LIT16_continue
+    jne         .LOP_REM_INT_LIT16_noerror
     cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je          .LOP_REM_INT_LIT16_break
-.LOP_REM_INT_LIT16_continue:
+    je         .LOP_REM_INT_LIT16_break
+.LOP_REM_INT_LIT16_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
+    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
     .if  0
-    movzbl      (rPC), %edx
-    SET_VREG    %eax, rINST             # vA<- %eax (quotient)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+    SET_VREG    %eax rINST              # vA<- %eax (quotient)
     .else
-    movzbl      (rPC), %eax
-    SET_VREG    %edx, rINST             # vA<- %edx (remainder)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %eax, 4)
+    SET_VREG    %edx rINST              # vA<- %edx (remainder)
     .endif
+    jmp         .LOP_REM_INT_LIT16_break2
 
 
 
@@ -13408,6 +13369,7 @@
     SET_VREG    %ecx, rINST             # vA<- %ecx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_OR_INT_LIT16: /* 0xd6 */
@@ -13476,6 +13438,7 @@
     SET_VREG    %ecx, rINST             # vA<- %ecx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_XOR_INT_LIT16: /* 0xd7 */
@@ -13544,6 +13507,7 @@
     SET_VREG    %ecx, rINST             # vA<- %ecx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_ADD_INT_LIT8: /* 0xd8 */
@@ -13609,6 +13573,7 @@
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_RSUB_INT_LIT8: /* 0xd9 */
@@ -13715,6 +13680,7 @@
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_DIV_INT_LIT8: /* 0xdb */
@@ -13772,30 +13738,26 @@
     */
 
 
-    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
-    testl       %ecx, %ecx              # handle -1 special case divide error
     FETCH_BB    1, %eax                 # %eax<- BB
-    jz          common_errDivideByZero  # handle divide by zero
-    addl        $4, rPC                # update PC
-    cmpl        $-1, %ecx
+    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
+    cmp         $0, %ecx               # check for divide by zero
     GET_VREG    %eax                    # %eax<- vBB
-    jnz         .LOP_DIV_INT_LIT8_continue
+    je          common_errDivideByZero  # handle divide by zero
+
+    cmpl        $-1, %ecx              # handle -1 special case divide error
+    jne         .LOP_DIV_INT_LIT8_noerror
     cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je          .LOP_DIV_INT_LIT8_break
-.LOP_DIV_INT_LIT8_continue:
+    je         .LOP_DIV_INT_LIT8_break
+.LOP_DIV_INT_LIT8_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
+    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
     .if  1
-    movzbl      (rPC), %edx
-    SET_VREG    %eax, rINST             # vA<- %eax (quotient)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
     .else
-    movzbl      (rPC), %eax
-    SET_VREG    %edx, rINST             # vA<- %edx (remainder)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %eax, 4)
+    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
     .endif
+    jmp         .LOP_DIV_INT_LIT8_break2
 
 
 /* ------------------------------ */
@@ -13855,30 +13817,26 @@
     */
 
 
-    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
-    testl       %ecx, %ecx              # handle -1 special case divide error
     FETCH_BB    1, %eax                 # %eax<- BB
-    jz          common_errDivideByZero  # handle divide by zero
-    addl        $4, rPC                # update PC
-    cmpl        $-1, %ecx
+    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
+    cmp         $0, %ecx               # check for divide by zero
     GET_VREG    %eax                    # %eax<- vBB
-    jnz         .LOP_REM_INT_LIT8_continue
+    je          common_errDivideByZero  # handle divide by zero
+
+    cmpl        $-1, %ecx              # handle -1 special case divide error
+    jne         .LOP_REM_INT_LIT8_noerror
     cmpl        $0x80000000,%eax       # handle min int special case divide error
-    je          .LOP_REM_INT_LIT8_break
-.LOP_REM_INT_LIT8_continue:
+    je         .LOP_REM_INT_LIT8_break
+.LOP_REM_INT_LIT8_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
+    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
     .if  0
-    movzbl      (rPC), %edx
-    SET_VREG    %eax, rINST             # vA<- %eax (quotient)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
     .else
-    movzbl      (rPC), %eax
-    SET_VREG    %edx, rINST             # vA<- %edx (remainder)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %eax, 4)
+    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
     .endif
+    jmp         .LOP_REM_INT_LIT8_break2
 
 
 /* ------------------------------ */
@@ -13946,6 +13904,7 @@
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_OR_INT_LIT8: /* 0xde */
@@ -14011,6 +13970,7 @@
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_XOR_INT_LIT8: /* 0xdf */
@@ -14076,6 +14036,7 @@
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SHL_INT_LIT8: /* 0xe0 */
@@ -14141,6 +14102,7 @@
     SET_VREG    %edx, rINST             # vAA<- %edx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SHR_INT_LIT8: /* 0xe1 */
@@ -14206,6 +14168,7 @@
     SET_VREG    %edx, rINST             # vAA<- %edx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_USHR_INT_LIT8: /* 0xe2 */
@@ -14271,6 +14234,7 @@
     SET_VREG    %edx, rINST             # vAA<- %edx; result
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
+
 /* ------------------------------ */
     .balign 64
 .L_OP_IGET_VOLATILE: /* 0xe3 */
@@ -14526,11 +14490,31 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_BREAKPOINT: /* 0xec */
-/* File: x86-atom/OP_BREAKPOINT.S */
-/* File: x86/unused.S */
-    jmp     common_abort
+   /* Copyright (C) 2008 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.
+    */
 
+   /*
+    * File: stub.S
+    */
 
+    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
+    pushl       rGLUE                   # push parameter glue
+    call        dvmMterp_OP_BREAKPOINT      # call c-based implementation
+    lea         4(%esp), %esp
+    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
+    FINISH_A                            # jump to next instruction
 /* ------------------------------ */
     .balign 64
 .L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
@@ -14565,16 +14549,16 @@
     * Syntax: op vAA, ref@BBBB
     */
 
-    movl        rGLUE, %edx                 # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %ecx  # %ecx<- glue->method
-    EXPORT_PC                               # in case an exception is thrown
-    FETCH       1, %eax                     # %eax<- BBBB
-    movl        %eax, -4(%esp)              # push parameter BBBB; ref
-    movl        rINST, -8(%esp)             # push parameter AA
-    movl        %ecx, -12(%esp)             # push parameter glue->method
+    movl        rGLUE, %edx                  # %edx<- pMterpGlue
+    movl        offGlue_method(%edx), %ecx   # %ecx<- glue->method
+    EXPORT_PC                                # in case an exception is thrown
+    FETCH       1, %eax                      # %eax<- BBBB
+    movl        %eax, -4(%esp)               # push parameter BBBB; ref
+    movl        rINST, -8(%esp)              # push parameter AA
+    movl        %ecx, -12(%esp)              # push parameter glue->method
     lea         -12(%esp), %esp
-    call        dvmThrowVerificationError   # call: (const Method* method, int kind, int ref)
-    jmp     common_exceptionThrown      # failed; handle exception
+    call        dvmThrowVerificationError    # call: (const Method* method, int kind, int ref)
+    jmp         common_exceptionThrown       # failed; handle exception
 
 /* ------------------------------ */
     .balign 64
@@ -14607,14 +14591,14 @@
     *
     * Format:
     *
-    * Syntax: A, {vC, vD, vE, vF}, inline@BBBB
+    * Syntax: vAA, {vC, vD, vE, vF}, inline@BBBB
     */
 
     FETCH       1, %ecx                 # %ecx<- BBBB
     movl        rGLUE, %eax             # %eax<- MterpGlue pointer
     addl        $offGlue_retval, %eax  # %eax<- &glue->retval
     EXPORT_PC
-    shr         $4, rINST              # rINST<- A
+    shr         $4, rINST              # rINST<- B
     movl        %eax, -8(%esp)          # push parameter glue->retval
     lea         -24(%esp), %esp
     jmp         .LOP_EXECUTE_INLINE_continue
@@ -14622,8 +14606,7 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
-/* File: x86-atom/OP_EXECUTE_INLINE_RANGE.S */
-   /* Copyright (C) 2010 The Android Open Source Project
+   /* Copyright (C) 2008 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.
@@ -14639,28 +14622,15 @@
     */
 
    /*
-    * File: OP_EXECUTE_INLINE_RANGE.S
-    *
-    * Code: Executes a "native inline" instruction. Uses no substitutions.
-    *
-    * For: execute-inline
-    *
-    * Description: Executes a "native inline" instruction. This instruction
-    *              is generated by the optimizer.
-    *
-    * Format:
-    *
-    * Syntax: AA, {vCCCC..v(CCCC+AA-1)}, inline@BBBB
+    * File: stub.S
     */
 
-    FETCH       1, %ecx                 # %ecx<- BBBB
-    movl        rGLUE, %eax             # %eax<- MterpGlue pointer
-    addl        $offGlue_retval, %eax  # %eax<- &glue->retval
-    EXPORT_PC
-    movl        %eax, -8(%esp)          # push parameter glue->retval
-    lea         -24(%esp), %esp
-    jmp         .LOP_EXECUTE_INLINE_RANGE_continue
-
+    SAVE_PC_FP_TO_GLUE %edx             # save program counter and frame pointer
+    pushl       rGLUE                   # push parameter glue
+    call        dvmMterp_OP_EXECUTE_INLINE_RANGE      # call c-based implementation
+    lea         4(%esp), %esp
+    LOAD_PC_FP_FROM_GLUE                # restore program counter and frame pointer
+    FINISH_A                            # jump to next instruction
 /* ------------------------------ */
     .balign 64
 .L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
@@ -14972,26 +14942,6 @@
     */
 
    /*
-    * File: OP_IPUT_OBJECT_QUICK.S
-    */
-
-/* File: x86-atom/OP_IPUT_QUICK.S */
-   /* Copyright (C) 2008 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.
-    */
-
-   /*
     * File: OP_IPUT_QUICK.S
     * Code: Optimization for iput
     *
@@ -15012,9 +14962,15 @@
     FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
     GET_VREG    rINST                   # rINST<- vA
     movl        rINST, (%eax, %ecx)     # object field<- vA
+    testl       rINST, rINST            # did we write a null object
+    je          1f
+    movl        rGLUE, %ecx             # get glue
+    movl        offGlue_cardTable(%ecx), %ecx # get card table base
+    shrl        $GC_CARD_SHIFT, %eax   # get gc card index
+    movb        %cl, (%eax, %ecx)       # mark gc card in table
+1:
     FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
 
-
 /* ------------------------------ */
     .balign 64
 .L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
@@ -24907,6 +24863,7 @@
     je          common_exceptionThrown  # resolve failed; exception thrown
     SET_VREG    %eax, rINST             # vAA<- %eax; pResString[BBBB]
     FINISH      3                       # jump to next instruction
+
 /* continuation for OP_CONST_CLASS */
 
    /*
@@ -24932,6 +24889,7 @@
     je          common_exceptionThrown  # handle exception
     SET_VREG    %eax, rINST             # vAA<- resolved class
     FINISH      2                       # jump to next instruction
+
 /* continuation for OP_CHECK_CAST */
 
 .LOP_CHECK_CAST_resolved:
@@ -25247,8 +25205,14 @@
 .LOP_FILLED_NEW_ARRAY_continue:
     movl        offClassObject_descriptor(%eax), %eax # %eax<- arrayClass->descriptor
     movzbl      1(%eax), %eax           # %eax<- descriptor[1]
-    cmp         $'I', %eax             # check if array of ints
+    cmpb        $'I', %al             # check if array of ints
+    je          1f
+    cmpb        $'L', %al
+    je          1f
+    cmpb        $'[', %al
     jne         .LOP_FILLED_NEW_ARRAY_notimpl     # jump to not implemented
+1:
+    movl        %eax, sReg0             # save type
     movl        rINST, -12(%esp)        # push parameter length
     movl        %eax, -16(%esp)         # push parameter descriptor[1]
     movl        $ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags
@@ -25301,6 +25265,14 @@
     jns         1b                      # or continue at 2
     .endif
 2:
+    cmpb        $'I', sReg0            # check for int array
+    je          3f
+    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
+    movl        offGlue_retval(%ecx), %eax # Object head
+    movl        offGlue_cardTable(%ecx), %ecx # card table base
+    shrl        $GC_CARD_SHIFT, %eax   # convert to card num
+    movb        %cl,(%ecx, %eax)        # mark card based on object head
+3:
     FINISH      3                       # jump to next instruction
 
    /*
@@ -25351,8 +25323,14 @@
 .LOP_FILLED_NEW_ARRAY_RANGE_continue:
     movl        offClassObject_descriptor(%eax), %eax # %eax<- arrayClass->descriptor
     movzbl      1(%eax), %eax           # %eax<- descriptor[1]
-    cmp         $'I', %eax             # check if array of ints
+    cmpb        $'I', %al             # check if array of ints
+    je          1f
+    cmpb        $'L', %al
+    je          1f
+    cmpb        $'[', %al
     jne         .LOP_FILLED_NEW_ARRAY_RANGE_notimpl     # jump to not implemented
+1:
+    movl        %eax, sReg0             # save type
     movl        rINST, -12(%esp)        # push parameter length
     movl        %eax, -16(%esp)         # push parameter descriptor[1]
     movl        $ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags
@@ -25405,6 +25383,14 @@
     jns         1b                      # or continue at 2
     .endif
 2:
+    cmpb        $'I', sReg0            # check for int array
+    je          3f
+    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
+    movl        offGlue_retval(%ecx), %eax # Object head
+    movl        offGlue_cardTable(%ecx), %ecx # card table base
+    shrl        $GC_CARD_SHIFT, %eax   # convert to card num
+    movb        %cl,(%ecx, %eax)        # mark card based on object head
+3:
     FINISH      3                       # jump to next instruction
 
    /*
@@ -25507,6 +25493,7 @@
 
 .LOP_APUT_OBJECT_finish:
     movl        %edx, sReg0             # save &vBB[vCC]
+    movl        %eax, sReg1             # save object head
     movl        offObject_clazz(rINST), %edx # %edx<- obj->clazz
     movl        %edx, -8(%esp)          # push parameter obj->clazz
     movl        offObject_clazz(%eax), %eax # %eax<- arrayObj->clazz
@@ -25516,10 +25503,17 @@
                                         # call: ClassObject* elemClass, ClassObject* arrayClass)
                                         # return: bool
     lea         8(%esp), %esp
-    cmp         $0, %eax               # check for invalid array value
+    testl       %eax, %eax              # check for invalid array value
     je          common_errArrayStore    # handle invalid array value
     movl        sReg0, %edx             # restore &vBB[vCC]
-
+    movl        rINST, offArrayObject_contents(%edx)
+    movl        rGLUE, %eax
+    FFETCH_ADV  2, %ecx                 # %ecx<- next instruction hi; fetch, advance
+    movl        offGlue_cardTable(%eax), %eax # get card table base
+    movl        sReg1, %edx             # restore object head
+    shrl        $GC_CARD_SHIFT, %edx   # object head to card number
+    movb        %al, (%eax, %edx)       # mark card using object head
+    FGETOP_JMP  2, %ecx                 # jump to next instruction; getop, jmp
 .LOP_APUT_OBJECT_skip_check:
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     movl        rINST, offArrayObject_contents(%edx)
@@ -25800,10 +25794,17 @@
     cmp         $0, %ecx               # check for null object
     je          common_errNullObject    # handle null object
     movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    rINST                   # rINST<- vA
-    movl     rINST, (%edx, %ecx)     # object field<- vA
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
+    movl        rINST, (%edx, %ecx)     # object field<- vA
+    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
+    movl     rGLUE, %eax             # get glue
+    movl        offGlue_cardTable(%eax), %eax # get card table base
+    testl       rINST, rINST            # test if we stored a null value
+    je          1f                     # skip card mark if null stored
+    shrl        $GC_CARD_SHIFT, %ecx   # set obeject head to card number
+    movb        %al, (%eax, %ecx)
+1:
+    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
 
 /* continuation for OP_IPUT_BOOLEAN */
 
@@ -26138,7 +26139,17 @@
 .LOP_SPUT_OBJECT_finish:
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    rINST                   # rINST<- vAA
+
+
     movl        rINST, offStaticField_value(%ecx) # field value<- vAA
+    testl       rINST, rINST            # stored null object ptr?
+    je          1f
+    movl        rGLUE, %edx             # get glue
+    movl        offField_clazz(%ecx), %ecx # ecx<- field->clazz
+    movl        offGlue_cardTable(%edx), %edx # get card table base
+    shrl        $GC_CARD_SHIFT, %ecx   # head to card number
+    movb        %dl, (%edx, %ecx)       # mark card
+1:
     FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
 
 /* continuation for OP_SPUT_BOOLEAN */
@@ -26342,6 +26353,7 @@
     movl        %eax, %ecx              # %ecx<- method
     jne         common_invokeMethodNoRange # invoke method common code
     jmp         common_errNullObject    # handle null object
+
 /* continuation for OP_INVOKE_STATIC */
 
 .LOP_INVOKE_STATIC_break:
@@ -26490,6 +26502,7 @@
     movl        %eax, %ecx              # %ecx<- method
     jne         common_invokeMethodRange # invoke method common code
     jmp         common_errNullObject    # handle null object
+
 /* continuation for OP_INVOKE_STATIC_RANGE */
 
 .LOP_INVOKE_STATIC_RANGE_break:
@@ -26645,22 +26658,24 @@
 
 /* continuation for OP_DIV_INT */
 .LOP_DIV_INT_break:
-    FFETCH_ADV  2 %eax
     .if  1
     movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $0, (rFP, rINST, 4)    # vAA<- 0
     .endif
-    FGETOP_JMP  2 %eax
+.LOP_DIV_INT_break2:
+    FINISH      2                       # jump to next instruction
+
 /* continuation for OP_REM_INT */
 .LOP_REM_INT_break:
-    FFETCH_ADV  2 %eax
     .if  0
     movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $0, (rFP, rINST, 4)    # vAA<- 0
     .endif
-    FGETOP_JMP  2 %eax
+.LOP_REM_INT_break2:
+    FINISH      2                       # jump to next instruction
+
 /* continuation for OP_MUL_LONG */
 
    /*
@@ -26728,24 +26743,28 @@
 
 /* continuation for OP_DIV_INT_2ADDR */
 .LOP_DIV_INT_2ADDR_break:
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
     .if  1
     movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $0, (rFP, rINST, 4)    # vAA<- 0
     .endif
+.LOP_DIV_INT_2ADDR_break2:
+    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
 
+
 /* continuation for OP_REM_INT_2ADDR */
 .LOP_REM_INT_2ADDR_break:
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
     .if  0
     movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $0, (rFP, rINST, 4)    # vAA<- 0
     .endif
+.LOP_REM_INT_2ADDR_break2:
+    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
 
+
 /* continuation for OP_MUL_LONG_2ADDR */
 
    /*
@@ -26779,6 +26798,7 @@
     movl        %edx, 4(rFP, rINST, 4)  # vA<- return high
     FFETCH_ADV  1, %ecx                 # %ecx<- next instruction hi; fetch, advance
     FGETOP_JMP 1, %ecx                  # jump to next instruction; getop, jmp
+
 /* continuation for OP_REM_LONG_2ADDR */
 .LOP_REM_LONG_2ADDR_break:
     movq        %xmm0, -20(%esp)        # push arg vA, vA+1
@@ -26789,6 +26809,7 @@
     movl        %edx, 4(rFP, rINST, 4)  # vA<- return high
     FFETCH_ADV  1, %ecx                 # %ecx<- next instruction hi; fetch, advance
     FGETOP_JMP 1, %ecx                  # jump to next instruction; getop, jmp
+
 /* continuation for OP_SHR_LONG_2ADDR */
 
 .LOP_SHR_LONG_2ADDR_finish:
@@ -26813,47 +26834,49 @@
 
 /* continuation for OP_DIV_INT_LIT16 */
 .LOP_DIV_INT_LIT16_break:
-    movzbl      (rPC), %edx
     .if  1
     movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $0, (rFP, rINST, 4)    # vAA<- 0
     .endif
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+.LOP_DIV_INT_LIT16_break2:
+
+    FINISH      2                       # jump to next instruction
 
 /* continuation for OP_REM_INT_LIT16 */
 .LOP_REM_INT_LIT16_break:
-    movzbl      (rPC), %edx
     .if  0
     movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $0, (rFP, rINST, 4)    # vAA<- 0
     .endif
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+.LOP_REM_INT_LIT16_break2:
+
+    FINISH      2                       # jump to next instruction
 
 /* continuation for OP_DIV_INT_LIT8 */
 .LOP_DIV_INT_LIT8_break:
-    movzbl      (rPC), %edx
     .if  1
     movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $0, (rFP, rINST, 4)    # vAA<- 0
     .endif
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+
+.LOP_DIV_INT_LIT8_break2:
+    FINISH      2                       # jump to next instruction
+    #FGETOP_JMP 2, %ecx                 # jump to next instruction; getop, jmp
 
 /* continuation for OP_REM_INT_LIT8 */
 .LOP_REM_INT_LIT8_break:
-    movzbl      (rPC), %edx
     .if  0
     movl        $0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $0, (rFP, rINST, 4)    # vAA<- 0
     .endif
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+
+.LOP_REM_INT_LIT8_break2:
+    FINISH      2                       # jump to next instruction
+    #FGETOP_JMP 2, %ecx                 # jump to next instruction; getop, jmp
 
 /* continuation for OP_EXECUTE_INLINE */
 
@@ -26903,44 +26926,6 @@
     lea         24(%esp), %esp          # update stack pointer
     je          common_exceptionThrown  # handle exception
     FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
-/* continuation for OP_EXECUTE_INLINE_RANGE */
-
-   /*
-    * Extract args, call function.
-    *  rINST = #of args (0-4)
-    *  %ecx = call index
-    */
-
-.LOP_EXECUTE_INLINE_RANGE_continue:
-    FETCH       2, %edx                 # %edx<- FEDC
-    cmp         $1, rINST              # determine number of arguments
-    jl          0f                      # handle zero args
-    je          1f                      # handle one arg
-    cmp         $3, rINST
-    jl          2f                      # handle two args
-    je          3f                      # handle three args
-4:
-    movl        12(rFP, %edx, 4), rINST     # rINST<- vF
-    movl        rINST, 12(%esp)         # push parameter vF
-3:
-    movl        8(rFP, %edx, 4), rINST     # rINST<- vE
-    movl        rINST, 8(%esp)          # push parameter E
-2:
-    movl        4(rFP, %edx, 4), rINST     # rINST<- vD
-    movl        rINST, 4(%esp)          # push parameter D
-1:
-    movl        (rFP, %edx, 4), %edx    # rINST<- vC
-    movl        %edx, (%esp)            # push parameter C
-0:
-    shl         $4, %ecx
-    movl        $gDvmInlineOpsTable, %eax # %eax<- address for table of inline operations
-    call        *(%eax, %ecx)           # call function
-
-    cmp         $0, %eax               # check boolean result of inline
-    FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
-    lea         24(%esp), %esp          # update stack pointer
-    je          common_exceptionThrown  # handle exception
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
 
     .size   dvmAsmSisterStart, .-dvmAsmSisterStart
     .global dvmAsmSisterEnd
@@ -26995,13 +26980,6 @@
     */
 
     .macro      MTERP_EXIT
-    #lea                40(%ebp), %esp          # correct stack pointer
-    #movl       24(%ebp), %edi          # restore %edi
-    #movl       28(%ebp), %esi          # restore %esi
-    #movl       32(%ebp), %ebx          # restore %ebx
-    #movl       36(%ebp), %ebp          # restore caller base pointer
-    #ret                                        # return
-
     lea         40(%esp), %esp          # correct stack pointer
     movl        -16(%esp), %edi         # restore %edi
     movl        -12(%esp), %esi         # restore %esi
@@ -27309,11 +27287,11 @@
 .long .L_OP_SHL_INT_LIT8
 .long .L_OP_SHR_INT_LIT8
 .long .L_OP_USHR_INT_LIT8
-.long .L_OP_UNUSED_E3
-.long .L_OP_UNUSED_E4
-.long .L_OP_UNUSED_E5
-.long .L_OP_UNUSED_E6
-.long .L_OP_UNUSED_E7
+.long .L_OP_IGET_VOLATILE
+.long .L_OP_IPUT_VOLATILE
+.long .L_OP_SGET_VOLATILE
+.long .L_OP_SPUT_VOLATILE
+.long .L_OP_IGET_OBJECT_VOLATILE
 .long .L_OP_IGET_WIDE_VOLATILE
 .long .L_OP_IPUT_WIDE_VOLATILE
 .long .L_OP_SGET_WIDE_VOLATILE
@@ -27334,9 +27312,9 @@
 .long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE
 .long .L_OP_INVOKE_SUPER_QUICK
 .long .L_OP_INVOKE_SUPER_QUICK_RANGE
-.long .L_OP_UNUSED_FC
-.long .L_OP_UNUSED_FD
-.long .L_OP_UNUSED_FE
+.long .L_OP_IPUT_OBJECT_VOLATILE
+.long .L_OP_SGET_OBJECT_VOLATILE
+.long .L_OP_SPUT_OBJECT_VOLATILE
 .long .L_OP_DISPATCH_FF
 
 /* File: x86-atom/footer.S */
@@ -27376,26 +27354,22 @@
     movl        rGLUE, %edx             # %edx<- pMterpGlue
     movl        %ebx, -4(%esp)          # save %ebx to the stack
     movl        offGlue_pSelfSuspendCount(%edx), %ebx # %ebx<- pSuspendCount (int)
-#if defined(WITH_DEBUGGER)
+4:
     movl        offGlue_pDebuggerActive(%edx), %eax # %eax<- pDebuggerActive
-    movl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
-    and         $7, %eax               # %eax<- mask for boolean (just how many bits does it take?)
-#endif
+    testl       %eax, %eax
+    je          5f
+    movzbl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
+5:
     cmp         $0, (%ebx)             # check if suspend is pending
     jne         2f                      # handle suspend
-#if defined(WITH_DEBUGGER) || defined(WITH_PROFILER)
-#if defined(WITH_PROFILER)
     movl        offGlue_pActiveProfilers(%edx), %ebx # %ebx<- activeProfilers (int)
-    or          (%ebx), %eax            # %eax<- merge activeProfilers and debuggerActive
-#else
-    cmp         $0, %eax               # check for debuggerActive
-#endif
-    jne         3f                      # debugger or profiler active; switch interp
-#endif
+    orl         (%ebx), %eax            # %eax<- merge activeProfilers and debuggerActive
     movl        -8(%esp), %edx          # %edx<- restore %edx
+    jne         3f                      # debugger or profiler active; switch interp
     movl        -4(%esp), %ebx          # %ebx<- restore %ebx
     ret                                 # return
 2:                                      # check suspended
+    EXPORT_PC
     movl        offGlue_self(%edx), %eax # %eax<- glue->self
     movl        %eax, -12(%esp)         # push parameter boolean
     lea         -12(%esp), %esp
@@ -27404,11 +27378,12 @@
     movl        4(%esp), %edx           # %edx<- restore %edx
     movl        8(%esp), %ebx           # %ebx<- restore %ebx
     lea         12(%esp), %esp
-    ret                                 # return
+    ret
 3:                                      # debugger/profiler enabled, bail out
-    add         -8(%esp), rPC           # rPC<- pc adjustments
-    movl        %ecx, offGlue_entryPoint(%edx) # glue->entryPoint<- reentry type
-    movl        $1, %edx               # switch to interp == true
+    leal        (rPC, %edx, 2), rPC     # adjust pc to show target
+    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
+    movb        $kInterpEntryInstr, offGlue_entryPoint(%ecx)
+    movl        $1, %edx               # switch interpreter
     jmp         common_gotoBail         # bail
 
    /*
@@ -27420,25 +27395,21 @@
     *  %edx is PC adjustment in bytes
     */
 
-common_periodicChecks2:
+common_periodicChecks_backwardBranch:
+    EXPORT_PC
     movl        rGLUE, %ecx             # %ecx<- pMterpGlue
     movl        offGlue_pSelfSuspendCount(%ecx), rINST # %ebx<- pSuspendCount (int)
-#if defined(WITH_DEBUGGER)
-    movl offGlue_pDebuggerActive(%ecx), %eax # %eax<- pDebuggerActive
-    movl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
-    and         $7, %eax               # %eax<- mask for boolean (just how many bits does it take?)
-#endif
+4:
+    movl        offGlue_pDebuggerActive(%ecx), %eax # %eax<- pDebuggerActive
+    testl       %eax, %eax              # test for NULL pointer
+    je          5f
+    movzbl      (%eax), %eax            # %eax<- get debuggerActive count
+5:
     cmp         $0, (rINST)            # check if suspend is pending
     jne         2f                      # handle suspend
-#if defined(WITH_DEBUGGER) || defined(WITH_PROFILER)
-#if defined(WITH_PROFILER)
     movl        offGlue_pActiveProfilers(%ecx), rINST # %edx<- activeProfilers (int)
-    or          (rINST), %eax           # %eax<- merge activeProfilers and debuggerActive
-#else
-    cmp         $0, %eax               # check for debuggerActive
-#endif
+    orl          (rINST), %eax           # %eax<- merge activeProfilers and debuggerActive
     jne         3f                      # debugger or profiler active; switch interp
-#endif
     FINISH_RB   %edx, %ecx              # jump to next instruction
 2:                                      # check suspended
     movl        offGlue_self(%ecx), %eax# %eax<- glue->self
@@ -27449,15 +27420,13 @@
                                         # return: bool
     movl        rINST, %edx             # %edx<- restore %edx
     lea         12(%esp), %esp
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
+    FINISH_RB   %edx, %ecx
 3:                                      # debugger/profiler enabled, bail out
-    add         -8(%esp), rPC           # rPC<- pc adjustments
-    movl        $kInterpEntryInstr, offGlue_entryPoint(%ecx) # glue->entryPoint<- reentry type
-    movl        $1, %edx               # switch to interp<- true
+    leal        (rPC, %edx, 2), rPC     # adjust pc to show target
+    movb        $kInterpEntryInstr, offGlue_entryPoint(%ecx)
+    movl        $1, %edx               # switch interpreter
     jmp         common_gotoBail         # bail
 
-
    /*
     * The equivalent of "goto bail", this calls through the "bail handler".
     * State registers will be saved to the "glue" area before bailing.
@@ -27675,13 +27644,13 @@
     jne         common_exceptionThrown  # handle exception
     FGETOP_JMP  3, %edx                 # jump to next instruction; getop, jmp
 
-.LstackOverflow:  # %ecx=methodToCall
-    movl        %ecx, -4(%esp)          # push parameter method to call
+.LstackOverflow:
+    movl        %ecx, -4(%esp)          # push method to call
     movl        rGLUE, %ecx             # %ecx<- pMterpGlue
     movl        offGlue_self(%ecx), %ecx # %ecx<- glue->self
     movl        %ecx, -8(%esp)          # push parameter self
     lea         -8(%esp), %esp
-    call        dvmHandleStackOverflow  # call: (Thread* self, Method* method)
+    call        dvmHandleStackOverflow  # call: (Thread* self, Method *meth)
                                         # return: void
     lea         8(%esp), %esp
     jmp         common_exceptionThrown  # handle exception
@@ -27703,22 +27672,15 @@
 
     movl        rGLUE, rINST            # %ecx<- pMterpGlue
     movl        offGlue_pSelfSuspendCount(rINST), %edx # %ebx<- pSuspendCount (int)
-#if defined(WITH_DEBUGGER)
     movl        offGlue_pDebuggerActive(rINST), %eax # %eax<- pDebuggerActive
     movl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
     and         $7, %eax               # %eax<- mask for boolean (just how many bits does it take?)
-#endif
     cmp         $0, (%edx)             # check if suspend is pending
     jne         2f                      # handle suspend
-#if defined(WITH_DEBUGGER) || defined(WITH_PROFILER)
-#if defined(WITH_PROFILER)
     movl        offGlue_pActiveProfilers(rINST), %edx # %edx<- activeProfilers (int)
     or          (%edx), %eax            # %eax<- merge activeProfilers and debuggerActive
-#else
     cmp         $0, %eax               # check for debuggerActive
-#endif
     jne         3f                      # debugger or profiler active; switch interp
-#endif
     jmp         4f
 2:                                      # check suspended
     movl        offGlue_self(rINST), %eax# %eax<- glue->self
@@ -27906,7 +27868,7 @@
     jmp         .LdeadFood
 
 .LdeadFood:
-.word 0xdeadf00d
+.int 0xdeadf00d
 
    /*
     * Invalid array index.
diff --git a/vm/mterp/out/InterpAsm-x86.S b/vm/mterp/out/InterpAsm-x86.S
index 13fffb0..e401224 100644
--- a/vm/mterp/out/InterpAsm-x86.S
+++ b/vm/mterp/out/InterpAsm-x86.S
@@ -7955,8 +7955,8 @@
     movl      2(rPC),%eax              # eax<- AAAAAAAA
     movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
     movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses
-    FETCH_INST_OPCODE 4 %ecx
     movl      (%ecx,%eax,4),%eax       # eax<- rResClasses[AAAAAAAA]
+    FETCH_INST_OPCODE 4 %ecx
     testl     %eax,%eax                # resolved yet?
     je        .LOP_CONST_CLASS_JUMBO_resolve
     SET_VREG  %eax rINST               # vBBBB<- rResClasses[AAAAAAAA]
@@ -21928,9 +21928,9 @@
 common_errArrayIndex:
     EXPORT_PC
     movl    offArrayObject_length(%eax), %eax
-    movl    %ecx,OUT_ARG0(%esp)
-    movl    %eax,OUT_ARG1(%esp)
-    call    dvmThrowArrayIndexOutOfBoundsException   # args (index, length)
+    movl    %eax,OUT_ARG0(%esp)
+    movl    %ecx,OUT_ARG1(%esp)
+    call    dvmThrowArrayIndexOutOfBoundsException   # args (length, index)
     jmp     common_exceptionThrown
 
 /*
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index 632d62d..2d08590 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -996,7 +996,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         SET_REGISTER##_regsize(vdst,                                        \
@@ -1021,7 +1021,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
@@ -1802,7 +1802,7 @@
          * Verifier now tests for interface/abstract class.
          */
         //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //    dvmThrowExceptionWithClassMessage(gDvm.exInstantiationError,
         //        clazz->descriptor);
         //    GOTO_exceptionThrown();
         //}
@@ -2169,7 +2169,7 @@
             GOTO_exceptionThrown();
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {
             dvmThrowArrayIndexOutOfBoundsException(
-                GET_REGISTER(vsrc2), arrayObj->length);
+                arrayObj->length, GET_REGISTER(vsrc2));
             GOTO_exceptionThrown();
         }
         obj = (Object*) GET_REGISTER(vdst);
@@ -3276,7 +3276,7 @@
          * Verifier now tests for interface/abstract class.
          */
         //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //    dvmThrowExceptionWithClassMessage(gDvm.exInstantiationError,
         //        clazz->descriptor);
         //    GOTO_exceptionThrown();
         //}
@@ -4351,8 +4351,8 @@
 /* File: c/OP_THROW_VERIFICATION_ERROR_JUMBO.c */
 HANDLE_OPCODE(OP_THROW_VERIFICATION_ERROR_JUMBO)
     EXPORT_PC();
-    vsrc1 = FETCH(1);
-    ref = FETCH(2) | (u4)FETCH(3) << 16;      /* class/field/method ref */
+    vsrc1 = FETCH(3);
+    ref = FETCH(1) | (u4)FETCH(2) << 16;      /* class/field/method ref */
     dvmThrowVerificationError(curMethod, vsrc1, ref);
     GOTO_exceptionThrown();
 OP_END
diff --git a/vm/mterp/out/InterpC-armv5te-vfp.c b/vm/mterp/out/InterpC-armv5te-vfp.c
index 0e13835..e40583f 100644
--- a/vm/mterp/out/InterpC-armv5te-vfp.c
+++ b/vm/mterp/out/InterpC-armv5te-vfp.c
@@ -996,7 +996,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         SET_REGISTER##_regsize(vdst,                                        \
@@ -1021,7 +1021,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
diff --git a/vm/mterp/out/InterpC-armv5te.c b/vm/mterp/out/InterpC-armv5te.c
index 5847600..9cd0580 100644
--- a/vm/mterp/out/InterpC-armv5te.c
+++ b/vm/mterp/out/InterpC-armv5te.c
@@ -996,7 +996,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         SET_REGISTER##_regsize(vdst,                                        \
@@ -1021,7 +1021,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
diff --git a/vm/mterp/out/InterpC-armv7-a-neon.c b/vm/mterp/out/InterpC-armv7-a-neon.c
index 0e87b82..00259c1 100644
--- a/vm/mterp/out/InterpC-armv7-a-neon.c
+++ b/vm/mterp/out/InterpC-armv7-a-neon.c
@@ -996,7 +996,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         SET_REGISTER##_regsize(vdst,                                        \
@@ -1021,7 +1021,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
diff --git a/vm/mterp/out/InterpC-armv7-a.c b/vm/mterp/out/InterpC-armv7-a.c
index 92aeff1..c443bb3 100644
--- a/vm/mterp/out/InterpC-armv7-a.c
+++ b/vm/mterp/out/InterpC-armv7-a.c
@@ -996,7 +996,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         SET_REGISTER##_regsize(vdst,                                        \
@@ -1021,7 +1021,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index 090146f..edf7ec9 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -988,7 +988,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         SET_REGISTER##_regsize(vdst,                                        \
@@ -1013,7 +1013,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
@@ -2165,7 +2165,7 @@
          * Verifier now tests for interface/abstract class.
          */
         //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //    dvmThrowExceptionWithClassMessage(gDvm.exInstantiationError,
         //        clazz->descriptor);
         //    GOTO_exceptionThrown();
         //}
@@ -2532,7 +2532,7 @@
             GOTO_exceptionThrown();
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {
             dvmThrowArrayIndexOutOfBoundsException(
-                GET_REGISTER(vsrc2), arrayObj->length);
+                arrayObj->length, GET_REGISTER(vsrc2));
             GOTO_exceptionThrown();
         }
         obj = (Object*) GET_REGISTER(vdst);
@@ -3639,7 +3639,7 @@
          * Verifier now tests for interface/abstract class.
          */
         //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //    dvmThrowExceptionWithClassMessage(gDvm.exInstantiationError,
         //        clazz->descriptor);
         //    GOTO_exceptionThrown();
         //}
@@ -4714,8 +4714,8 @@
 /* File: c/OP_THROW_VERIFICATION_ERROR_JUMBO.c */
 HANDLE_OPCODE(OP_THROW_VERIFICATION_ERROR_JUMBO)
     EXPORT_PC();
-    vsrc1 = FETCH(1);
-    ref = FETCH(2) | (u4)FETCH(3) << 16;      /* class/field/method ref */
+    vsrc1 = FETCH(3);
+    ref = FETCH(1) | (u4)FETCH(2) << 16;      /* class/field/method ref */
     dvmThrowVerificationError(curMethod, vsrc1, ref);
     GOTO_exceptionThrown();
 OP_END
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index e71511e..0b6ff7c 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -979,7 +979,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         SET_REGISTER##_regsize(vdst,                                        \
@@ -1004,7 +1004,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
@@ -1915,7 +1915,7 @@
          * Verifier now tests for interface/abstract class.
          */
         //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //    dvmThrowExceptionWithClassMessage(gDvm.exInstantiationError,
         //        clazz->descriptor);
         //    GOTO_exceptionThrown();
         //}
@@ -2282,7 +2282,7 @@
             GOTO_exceptionThrown();
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {
             dvmThrowArrayIndexOutOfBoundsException(
-                GET_REGISTER(vsrc2), arrayObj->length);
+                arrayObj->length, GET_REGISTER(vsrc2));
             GOTO_exceptionThrown();
         }
         obj = (Object*) GET_REGISTER(vdst);
@@ -3389,7 +3389,7 @@
          * Verifier now tests for interface/abstract class.
          */
         //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //    dvmThrowExceptionWithClassMessage(gDvm.exInstantiationError,
         //        clazz->descriptor);
         //    GOTO_exceptionThrown();
         //}
@@ -4464,8 +4464,8 @@
 /* File: c/OP_THROW_VERIFICATION_ERROR_JUMBO.c */
 HANDLE_OPCODE(OP_THROW_VERIFICATION_ERROR_JUMBO)
     EXPORT_PC();
-    vsrc1 = FETCH(1);
-    ref = FETCH(2) | (u4)FETCH(3) << 16;      /* class/field/method ref */
+    vsrc1 = FETCH(3);
+    ref = FETCH(1) | (u4)FETCH(2) << 16;      /* class/field/method ref */
     dvmThrowVerificationError(curMethod, vsrc1, ref);
     GOTO_exceptionThrown();
 OP_END
diff --git a/vm/mterp/out/InterpC-x86-atom.c b/vm/mterp/out/InterpC-x86-atom.c
index e8013da..5d5e7a8 100644
--- a/vm/mterp/out/InterpC-x86-atom.c
+++ b/vm/mterp/out/InterpC-x86-atom.c
@@ -996,7 +996,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         SET_REGISTER##_regsize(vdst,                                        \
@@ -1021,7 +1021,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
@@ -1330,6 +1330,82 @@
 HANDLE_SPUT_X(OP_SPUT_WIDE_VOLATILE,    "-wide-volatile", LongVolatile, _WIDE)
 OP_END
 
+/* File: c/OP_BREAKPOINT.c */
+HANDLE_OPCODE(OP_BREAKPOINT)
+#if (INTERP_TYPE == INTERP_DBG)
+    {
+        /*
+         * Restart this instruction with the original opcode.  We do
+         * this by simply jumping to the handler.
+         *
+         * It's probably not necessary to update "inst", but we do it
+         * for the sake of anything that needs to do disambiguation in a
+         * common handler with INST_INST.
+         *
+         * The breakpoint itself is handled over in updateDebugger(),
+         * because we need to detect other events (method entry, single
+         * step) and report them in the same event packet, and we're not
+         * yet handling those through breakpoint instructions.  By the
+         * time we get here, the breakpoint has already been handled and
+         * the thread resumed.
+         */
+        u1 originalOpcode = dvmGetOriginalOpcode(pc);
+        LOGV("+++ break 0x%02x (0x%04x -> 0x%04x)\n", originalOpcode, inst,
+            INST_REPLACE_OP(inst, originalOpcode));
+        inst = INST_REPLACE_OP(inst, originalOpcode);
+        FINISH_BKPT(originalOpcode);
+    }
+#else
+    LOGE("Breakpoint hit in non-debug interpreter\n");
+    dvmAbort();
+#endif
+OP_END
+
+/* File: c/OP_EXECUTE_INLINE_RANGE.c */
+HANDLE_OPCODE(OP_EXECUTE_INLINE_RANGE /*{vCCCC..v(CCCC+AA-1)}, inline@BBBB*/)
+    {
+        u4 arg0, arg1, arg2, arg3;
+        arg0 = arg1 = arg2 = arg3 = 0;      /* placate gcc */
+
+        EXPORT_PC();
+
+        vsrc1 = INST_AA(inst);      /* #of args */
+        ref = FETCH(1);             /* inline call "ref" */
+        vdst = FETCH(2);            /* range base */
+        ILOGV("|execute-inline-range args=%d @%d {regs=v%d-v%d}",
+            vsrc1, ref, vdst, vdst+vsrc1-1);
+
+        assert((vdst >> 16) == 0);  // 16-bit type -or- high 16 bits clear
+        assert(vsrc1 <= 4);
+
+        switch (vsrc1) {
+        case 4:
+            arg3 = GET_REGISTER(vdst+3);
+            /* fall through */
+        case 3:
+            arg2 = GET_REGISTER(vdst+2);
+            /* fall through */
+        case 2:
+            arg1 = GET_REGISTER(vdst+1);
+            /* fall through */
+        case 1:
+            arg0 = GET_REGISTER(vdst+0);
+            /* fall through */
+        default:        // case 0
+            ;
+        }
+
+#if INTERP_TYPE == INTERP_DBG
+        if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
+            GOTO_exceptionThrown();
+#else
+        if (!dvmPerformInlineOp4Std(arg0, arg1, arg2, arg3, &retval, ref))
+            GOTO_exceptionThrown();
+#endif
+    }
+    FINISH(3);
+OP_END
+
 /* File: c/OP_INVOKE_OBJECT_INIT_RANGE.c */
 HANDLE_OPCODE(OP_INVOKE_OBJECT_INIT_RANGE /*{vCCCC..v(CCCC+AA-1)}, meth@BBBB*/)
     {
diff --git a/vm/mterp/out/InterpC-x86.c b/vm/mterp/out/InterpC-x86.c
index 00ac495..c84b236 100644
--- a/vm/mterp/out/InterpC-x86.c
+++ b/vm/mterp/out/InterpC-x86.c
@@ -996,7 +996,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         SET_REGISTER##_regsize(vdst,                                        \
@@ -1021,7 +1021,7 @@
             GOTO_exceptionThrown();                                         \
         if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
             dvmThrowArrayIndexOutOfBoundsException(                         \
-                GET_REGISTER(vsrc2), arrayObj->length);                     \
+                arrayObj->length, GET_REGISTER(vsrc2));                     \
             GOTO_exceptionThrown();                                         \
         }                                                                   \
         ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
diff --git a/vm/mterp/x86-atom/OP_ADD_FLOAT_2ADDR.S b/vm/mterp/x86-atom/OP_ADD_FLOAT_2ADDR.S
index 7d3aa71..3d62703 100644
--- a/vm/mterp/x86-atom/OP_ADD_FLOAT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_ADD_FLOAT_2ADDR.S
@@ -17,4 +17,4 @@
     * File: OP_ADD_FLOAT_2ADDR.S
     */
 
-%include "x86-atom/binopF2addr.S" {"instr":"addss     %xmm1, %xmm0"}
\ No newline at end of file
+%include "x86-atom/binopF2addr.S" {"instr":"addss     %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_ADD_INT.S b/vm/mterp/x86-atom/OP_ADD_INT.S
index 4f14bbd..a423e75 100644
--- a/vm/mterp/x86-atom/OP_ADD_INT.S
+++ b/vm/mterp/x86-atom/OP_ADD_INT.S
@@ -17,4 +17,4 @@
     * File: OP_ADD_INT.S
     */
 
-%include "x86-atom/binop.S" {"instr":"addl     (rFP, %edx, 4), %ecx"}
\ No newline at end of file
+%include "x86-atom/binop.S" {"instr":"addl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_ADD_INT_2ADDR.S b/vm/mterp/x86-atom/OP_ADD_INT_2ADDR.S
index 0bdceaa..2a91f41 100644
--- a/vm/mterp/x86-atom/OP_ADD_INT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_ADD_INT_2ADDR.S
@@ -17,4 +17,4 @@
     * File: OP_ADD_INT_2ADDR.S
     */
 
-%include "x86-atom/binop2addr.S" {"instr":"addl     %edx,  (rFP, rINST, 4)"}
+%include "x86-atom/binop2addr.S" {"instr":"addl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_ADD_INT_LIT16.S b/vm/mterp/x86-atom/OP_ADD_INT_LIT16.S
index dbfddcc..72479ba 100644
--- a/vm/mterp/x86-atom/OP_ADD_INT_LIT16.S
+++ b/vm/mterp/x86-atom/OP_ADD_INT_LIT16.S
@@ -17,4 +17,4 @@
     * File: OP_ADD_INT_LIT16.S
     */
 
-%include "x86-atom/binopLit16.S" {"instr":"addl     %edx, %ecx"}
\ No newline at end of file
+%include "x86-atom/binopLit16.S" {"instr":"addl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_AGET.S b/vm/mterp/x86-atom/OP_AGET.S
index 11e88d1..73a27ab 100644
--- a/vm/mterp/x86-atom/OP_AGET.S
+++ b/vm/mterp/x86-atom/OP_AGET.S
@@ -50,4 +50,4 @@
                                                 # doing this and the previous instr
                                                 # with one instr was not faster
     SET_VREG    %edx  rINST             # vAA<- %edx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_AGET_BOOLEAN.S b/vm/mterp/x86-atom/OP_AGET_BOOLEAN.S
index 1579026..1d28745 100644
--- a/vm/mterp/x86-atom/OP_AGET_BOOLEAN.S
+++ b/vm/mterp/x86-atom/OP_AGET_BOOLEAN.S
@@ -17,4 +17,4 @@
     * File: OP_AGET_BOOLEAN.S
     */
 
-%include "x86-atom/OP_AGET.S" { "mov":"zbl", "scale":"1" }
\ No newline at end of file
+%include "x86-atom/OP_AGET.S" { "mov":"zbl", "scale":"1" }
diff --git a/vm/mterp/x86-atom/OP_AGET_BYTE.S b/vm/mterp/x86-atom/OP_AGET_BYTE.S
index 98df227..60e4266 100644
--- a/vm/mterp/x86-atom/OP_AGET_BYTE.S
+++ b/vm/mterp/x86-atom/OP_AGET_BYTE.S
@@ -17,4 +17,4 @@
     * File: OP_AGET_BYTE.S
     */
 
-%include "x86-atom/OP_AGET.S" {  "mov":"sbl", "scale":"1" }
\ No newline at end of file
+%include "x86-atom/OP_AGET.S" {  "mov":"sbl", "scale":"1" }
diff --git a/vm/mterp/x86-atom/OP_AGET_CHAR.S b/vm/mterp/x86-atom/OP_AGET_CHAR.S
index 3ee5f9f..114d02d 100644
--- a/vm/mterp/x86-atom/OP_AGET_CHAR.S
+++ b/vm/mterp/x86-atom/OP_AGET_CHAR.S
@@ -17,4 +17,4 @@
     * File: OP_AGET_CHAR.S
     */
 
-%include "x86-atom/OP_AGET.S" {  "mov":"zwl", "scale":"2" }
\ No newline at end of file
+%include "x86-atom/OP_AGET.S" {  "mov":"zwl", "scale":"2" }
diff --git a/vm/mterp/x86-atom/OP_AGET_SHORT.S b/vm/mterp/x86-atom/OP_AGET_SHORT.S
index dd05637..3ddb9b9 100644
--- a/vm/mterp/x86-atom/OP_AGET_SHORT.S
+++ b/vm/mterp/x86-atom/OP_AGET_SHORT.S
@@ -17,4 +17,4 @@
     * File: OP_AGET_SHORT.S
     */
 
-%include "x86-atom/OP_AGET.S" {  "mov":"swl", "scale":"2" }
\ No newline at end of file
+%include "x86-atom/OP_AGET.S" {  "mov":"swl", "scale":"2" }
diff --git a/vm/mterp/x86-atom/OP_AGET_WIDE.S b/vm/mterp/x86-atom/OP_AGET_WIDE.S
index 413ea1e..db5a930 100644
--- a/vm/mterp/x86-atom/OP_AGET_WIDE.S
+++ b/vm/mterp/x86-atom/OP_AGET_WIDE.S
@@ -40,4 +40,4 @@
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        offArrayObject_contents(%ecx, %edx, 8), %xmm0 # %xmm0<- vBB[vCC]
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_AND_INT.S b/vm/mterp/x86-atom/OP_AND_INT.S
index 2f84b34..10d223b 100644
--- a/vm/mterp/x86-atom/OP_AND_INT.S
+++ b/vm/mterp/x86-atom/OP_AND_INT.S
@@ -17,4 +17,4 @@
     * File: OP_AND_INT.S
     */
 
-%include "x86-atom/binop.S" {"instr":"andl     (rFP, %edx, 4), %ecx"}
+%include "x86-atom/binop.S" {"instr":"andl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_AND_INT_2ADDR.S b/vm/mterp/x86-atom/OP_AND_INT_2ADDR.S
index bd3ccf5..dcbd531 100644
--- a/vm/mterp/x86-atom/OP_AND_INT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_AND_INT_2ADDR.S
@@ -17,4 +17,4 @@
     * File: OP_AND_INT_2ADDR.S
     */
 
-%include "x86-atom/binop2addr.S" {"instr":"andl     %edx, (rFP, rINST, 4)"}
\ No newline at end of file
+%include "x86-atom/binop2addr.S" {"instr":"andl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_AND_INT_LIT16.S b/vm/mterp/x86-atom/OP_AND_INT_LIT16.S
index 6935ebd..7e6493d 100644
--- a/vm/mterp/x86-atom/OP_AND_INT_LIT16.S
+++ b/vm/mterp/x86-atom/OP_AND_INT_LIT16.S
@@ -17,4 +17,4 @@
     * File: OP_AND_INT_LIT16.S
     */
 
-%include "x86-atom/binopLit16.S" {"instr":"andl     %edx, %ecx"}
\ No newline at end of file
+%include "x86-atom/binopLit16.S" {"instr":"andl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_APUT.S b/vm/mterp/x86-atom/OP_APUT.S
index e46294b..93b3866 100644
--- a/vm/mterp/x86-atom/OP_APUT.S
+++ b/vm/mterp/x86-atom/OP_APUT.S
@@ -47,4 +47,4 @@
     lea         (%ecx, %edx, $scale), %ecx # %ecx<- &vBB[vCC]
     GET_VREG    rINST                   # rINST<- vAA
     mov$mov     $value, offArrayObject_contents(%ecx) # vBB[vCC]<- rINSTx; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_APUT_BYTE.S b/vm/mterp/x86-atom/OP_APUT_BYTE.S
index 8d3c650..29cb708 100644
--- a/vm/mterp/x86-atom/OP_APUT_BYTE.S
+++ b/vm/mterp/x86-atom/OP_APUT_BYTE.S
@@ -17,4 +17,4 @@
     * File: OP_APUT_BYTE.S
     */
 
-%include "x86-atom/OP_APUT.S" { "mov":"b", "scale":"1", "value":"rINSTbl" }
\ No newline at end of file
+%include "x86-atom/OP_APUT.S" { "mov":"b", "scale":"1", "value":"rINSTbl" }
diff --git a/vm/mterp/x86-atom/OP_APUT_CHAR.S b/vm/mterp/x86-atom/OP_APUT_CHAR.S
index 9aa2067..d43e540 100644
--- a/vm/mterp/x86-atom/OP_APUT_CHAR.S
+++ b/vm/mterp/x86-atom/OP_APUT_CHAR.S
@@ -17,4 +17,4 @@
     * File: OP_APUT_CHAR.S
     */
 
-%include "x86-atom/OP_APUT.S" { "mov":"w", "scale":"2", "value":"rINSTw" }
\ No newline at end of file
+%include "x86-atom/OP_APUT.S" { "mov":"w", "scale":"2", "value":"rINSTw" }
diff --git a/vm/mterp/x86-atom/OP_APUT_OBJECT.S b/vm/mterp/x86-atom/OP_APUT_OBJECT.S
index 8d71400..0e23d71 100644
--- a/vm/mterp/x86-atom/OP_APUT_OBJECT.S
+++ b/vm/mterp/x86-atom/OP_APUT_OBJECT.S
@@ -50,6 +50,7 @@
 
 .L${opcode}_finish:
     movl        %edx, sReg0             # save &vBB[vCC]
+    movl        %eax, sReg1             # save object head
     movl        offObject_clazz(rINST), %edx # %edx<- obj->clazz
     movl        %edx, -8(%esp)          # push parameter obj->clazz
     movl        offObject_clazz(%eax), %eax # %eax<- arrayObj->clazz
@@ -59,10 +60,17 @@
                                         # call: ClassObject* elemClass, ClassObject* arrayClass)
                                         # return: bool
     lea         8(%esp), %esp
-    cmp         $$0, %eax               # check for invalid array value
+    testl       %eax, %eax              # check for invalid array value
     je          common_errArrayStore    # handle invalid array value
     movl        sReg0, %edx             # restore &vBB[vCC]
-
+    movl        rINST, offArrayObject_contents(%edx)
+    movl        rGLUE, %eax
+    FFETCH_ADV  2, %ecx                 # %ecx<- next instruction hi; fetch, advance
+    movl        offGlue_cardTable(%eax), %eax # get card table base
+    movl        sReg1, %edx             # restore object head
+    shrl        $$GC_CARD_SHIFT, %edx   # object head to card number
+    movb        %al, (%eax, %edx)       # mark card using object head
+    FGETOP_JMP  2, %ecx                 # jump to next instruction; getop, jmp
 .L${opcode}_skip_check:
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     movl        rINST, offArrayObject_contents(%edx)
diff --git a/vm/mterp/x86-atom/OP_APUT_SHORT.S b/vm/mterp/x86-atom/OP_APUT_SHORT.S
index b6cbc98..daef0d8 100644
--- a/vm/mterp/x86-atom/OP_APUT_SHORT.S
+++ b/vm/mterp/x86-atom/OP_APUT_SHORT.S
@@ -17,4 +17,4 @@
     * File: OP_APUT_SHORT.S
     */
 
-%include "x86-atom/OP_APUT.S" { "mov":"w", "scale":"2", "value":"rINSTw" }
\ No newline at end of file
+%include "x86-atom/OP_APUT.S" { "mov":"w", "scale":"2", "value":"rINSTw" }
diff --git a/vm/mterp/x86-atom/OP_APUT_WIDE.S b/vm/mterp/x86-atom/OP_APUT_WIDE.S
index dceb67b..b1b9e6a 100644
--- a/vm/mterp/x86-atom/OP_APUT_WIDE.S
+++ b/vm/mterp/x86-atom/OP_APUT_WIDE.S
@@ -40,4 +40,4 @@
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, rINST, 4), %xmm0  # %xmm0<- vAA
     movq        %xmm0, offArrayObject_contents(%ecx, %edx, 8) # vBB[vCC]<- %xmm0; value
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_ARRAY_LENGTH.S b/vm/mterp/x86-atom/OP_ARRAY_LENGTH.S
index 16427f2..485f815 100644
--- a/vm/mterp/x86-atom/OP_ARRAY_LENGTH.S
+++ b/vm/mterp/x86-atom/OP_ARRAY_LENGTH.S
@@ -31,10 +31,10 @@
     movl        rINST, %eax             # %eax<- BA
     shr         $$4, %eax               # %eax<- B
     andl        $$15, rINST             # rINST<- A
-    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
     GET_VREG    %eax                    # %eax<- vB
-    testl       %eax, %eax              # check for null array object
+    cmp         $$0, %eax               # check for null array object
     je          common_errNullObject    # handle null array object
+    FFETCH_ADV  1, %edx                 # %edx<- next instruction hi; fetch, advance
     movl        offArrayObject_length(%eax), %eax # %eax<- array length
     movl        %eax, (rFP, rINST, 4)   # vA<- %eax; array length
     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_BREAKPOINT.S b/vm/mterp/x86-atom/OP_BREAKPOINT.S
index 31d98c1..e69de29 100644
--- a/vm/mterp/x86-atom/OP_BREAKPOINT.S
+++ b/vm/mterp/x86-atom/OP_BREAKPOINT.S
@@ -1 +0,0 @@
-%include "x86/unused.S"
diff --git a/vm/mterp/x86-atom/OP_CMPG_DOUBLE.S b/vm/mterp/x86-atom/OP_CMPG_DOUBLE.S
index 7008394..87f8a3b 100644
--- a/vm/mterp/x86-atom/OP_CMPG_DOUBLE.S
+++ b/vm/mterp/x86-atom/OP_CMPG_DOUBLE.S
@@ -17,4 +17,4 @@
     * File: OP_CMPG_DOUBLE.S
     */
 
-%include "x86-atom/OP_CMPL_FLOAT.S" { "nan":"$0x1", "sod":"l"}
+%include "x86-atom/OP_CMPL_FLOAT.S" { "nan":"$0x1", "sod":"d"}
diff --git a/vm/mterp/x86-atom/OP_CMPL_DOUBLE.S b/vm/mterp/x86-atom/OP_CMPL_DOUBLE.S
index 010b266..2a603a4 100644
--- a/vm/mterp/x86-atom/OP_CMPL_DOUBLE.S
+++ b/vm/mterp/x86-atom/OP_CMPL_DOUBLE.S
@@ -17,4 +17,4 @@
     * File: OP_CMPL_DOUBLE.S
     */
 
-%include "x86-atom/OP_CMPL_FLOAT.S" { "sod":"l" }
+%include "x86-atom/OP_CMPL_FLOAT.S" { "sod":"d" }
diff --git a/vm/mterp/x86-atom/OP_CMPL_FLOAT.S b/vm/mterp/x86-atom/OP_CMPL_FLOAT.S
index 2a95e89..5cb3ec7 100644
--- a/vm/mterp/x86-atom/OP_CMPL_FLOAT.S
+++ b/vm/mterp/x86-atom/OP_CMPL_FLOAT.S
@@ -38,15 +38,9 @@
 
     FETCH_BB    1, %ecx                 # %ecx<- BB
     FETCH_CC    1, %edx                 # %edx<- CC
-
-    fld$sod     (rFP, %edx, 4)
-    fld$sod     (rFP, %ecx, 4)
-
-    fucompp
-    fnstsw      %ax
-    sahf
-
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
+    movs$sod    (rFP, %ecx, 4), %xmm0   # %xmm0<- vBB
+    comis$sod   (rFP, %edx, 4), %xmm0   # do comparison
     ja          .L${opcode}_greater
     jp          .L${opcode}_finalNan
     jz          .L${opcode}_final
diff --git a/vm/mterp/x86-atom/OP_CONST.S b/vm/mterp/x86-atom/OP_CONST.S
index 94fe963..7ff4c23 100644
--- a/vm/mterp/x86-atom/OP_CONST.S
+++ b/vm/mterp/x86-atom/OP_CONST.S
@@ -33,4 +33,4 @@
     or          %edx, %ecx              # %ecx<- #+BBBBBBBB
     FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
     SET_VREG    %ecx, rINST             # vAA<- %ecx; literal
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_16.S b/vm/mterp/x86-atom/OP_CONST_16.S
index 13e1cb3..f340696 100644
--- a/vm/mterp/x86-atom/OP_CONST_16.S
+++ b/vm/mterp/x86-atom/OP_CONST_16.S
@@ -31,4 +31,4 @@
     FETCHs      1, %edx                 # %edx<- BBBB
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     SET_VREG    %edx rINST              # vAA<- BBBB; literal
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_4.S b/vm/mterp/x86-atom/OP_CONST_4.S
index d99f151..5396d72 100644
--- a/vm/mterp/x86-atom/OP_CONST_4.S
+++ b/vm/mterp/x86-atom/OP_CONST_4.S
@@ -20,7 +20,7 @@
     *
     * For: const/4
     *
-    * Description: Move the given literal value (right-sign-extended to 32
+    * Description: Move the given literal value (right-zero-extended to 32
     *              bits) into the specified register.
     *
     * Format: B|A|op (11n)
@@ -30,9 +30,8 @@
 
     movl        rINST, %edx             # %edx<- BA
     andl        $$15, rINST             # rINST<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next i nstruction hi; fetch, advance
     shl         $$24, %edx              # %edx<- B000
-    addl        $$2, rPC                  # update PC
     sar         $$28, %edx              # %edx<- right-zero-extended B
+    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     SET_VREG    %edx, rINST             # vA<- %edx; literal
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_CLASS.S b/vm/mterp/x86-atom/OP_CONST_CLASS.S
index 9000e11..bc6657c 100644
--- a/vm/mterp/x86-atom/OP_CONST_CLASS.S
+++ b/vm/mterp/x86-atom/OP_CONST_CLASS.S
@@ -64,4 +64,4 @@
     cmp         $$0, %eax               # check for null pointer
     je          common_exceptionThrown  # handle exception
     SET_VREG    %eax, rINST             # vAA<- resolved class
-    FINISH      2                       # jump to next instruction
\ No newline at end of file
+    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_CONST_STRING_JUMBO.S b/vm/mterp/x86-atom/OP_CONST_STRING_JUMBO.S
index 54e5ea7..09d045d 100644
--- a/vm/mterp/x86-atom/OP_CONST_STRING_JUMBO.S
+++ b/vm/mterp/x86-atom/OP_CONST_STRING_JUMBO.S
@@ -63,4 +63,4 @@
     cmp         $$0, %eax               # check if resolved string failed
     je          common_exceptionThrown  # resolve failed; exception thrown
     SET_VREG    %eax, rINST             # vAA<- %eax; pResString[BBBB]
-    FINISH      3                       # jump to next instruction
\ No newline at end of file
+    FINISH      3                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_CONST_WIDE_16.S b/vm/mterp/x86-atom/OP_CONST_WIDE_16.S
index e2df8f2..c980f10 100644
--- a/vm/mterp/x86-atom/OP_CONST_WIDE_16.S
+++ b/vm/mterp/x86-atom/OP_CONST_WIDE_16.S
@@ -34,4 +34,4 @@
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     movl        %edx, (rFP, rINST, 4)   # vAA<- ssssBBBB
     movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- ssssssss
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_CONST_WIDE_32.S b/vm/mterp/x86-atom/OP_CONST_WIDE_32.S
index 333e991..92f8450 100644
--- a/vm/mterp/x86-atom/OP_CONST_WIDE_32.S
+++ b/vm/mterp/x86-atom/OP_CONST_WIDE_32.S
@@ -36,4 +36,4 @@
     FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
     movl        %edx, (rFP, rINST, 4)   # vAA<-  BBBBBBBB
     movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- ssssssss
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_EXECUTE_INLINE.S b/vm/mterp/x86-atom/OP_EXECUTE_INLINE.S
index 5309c26..4f01cef 100644
--- a/vm/mterp/x86-atom/OP_EXECUTE_INLINE.S
+++ b/vm/mterp/x86-atom/OP_EXECUTE_INLINE.S
@@ -25,14 +25,14 @@
     *
     * Format:
     *
-    * Syntax: A, {vC, vD, vE, vF}, inline@BBBB
+    * Syntax: vAA, {vC, vD, vE, vF}, inline@BBBB
     */
 
     FETCH       1, %ecx                 # %ecx<- BBBB
     movl        rGLUE, %eax             # %eax<- MterpGlue pointer
     addl        $$offGlue_retval, %eax  # %eax<- &glue->retval
     EXPORT_PC
-    shr         $$4, rINST              # rINST<- A
+    shr         $$4, rINST              # rINST<- B
     movl        %eax, -8(%esp)          # push parameter glue->retval
     lea         -24(%esp), %esp
     jmp         .L${opcode}_continue
@@ -83,4 +83,4 @@
     FFETCH_ADV  3, %eax                 # %eax<- next instruction hi; fetch, advance
     lea         24(%esp), %esp          # update stack pointer
     je          common_exceptionThrown  # handle exception
-    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  3, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_FILLED_NEW_ARRAY.S b/vm/mterp/x86-atom/OP_FILLED_NEW_ARRAY.S
index c6236d7..f804f3e 100644
--- a/vm/mterp/x86-atom/OP_FILLED_NEW_ARRAY.S
+++ b/vm/mterp/x86-atom/OP_FILLED_NEW_ARRAY.S
@@ -80,8 +80,14 @@
 .L${opcode}_continue:
     movl        offClassObject_descriptor(%eax), %eax # %eax<- arrayClass->descriptor
     movzbl      1(%eax), %eax           # %eax<- descriptor[1]
-    cmp         $$'I', %eax             # check if array of ints
+    cmpb        $$'I', %al             # check if array of ints
+    je          1f
+    cmpb        $$'L', %al
+    je          1f
+    cmpb        $$'[', %al
     jne         .L${opcode}_notimpl     # jump to not implemented
+1:
+    movl        %eax, sReg0             # save type
     movl        rINST, -12(%esp)        # push parameter length
     movl        %eax, -16(%esp)         # push parameter descriptor[1]
     movl        $$ALLOC_DONT_TRACK, -8(%esp) # push parameter to allocate flags
@@ -134,6 +140,14 @@
     jns         1b                      # or continue at 2
     .endif
 2:
+    cmpb        $$'I', sReg0            # check for int array
+    je          3f
+    movl        rGLUE, %ecx             # %ecx<- MterpGlue pointer
+    movl        offGlue_retval(%ecx), %eax # Object head
+    movl        offGlue_cardTable(%ecx), %ecx # card table base
+    shrl        $$GC_CARD_SHIFT, %eax   # convert to card num
+    movb        %cl,(%ecx, %eax)        # mark card based on object head
+3:
     FINISH      3                       # jump to next instruction
 
    /*
diff --git a/vm/mterp/x86-atom/OP_GOTO.S b/vm/mterp/x86-atom/OP_GOTO.S
index 12d847e..7bd9956 100644
--- a/vm/mterp/x86-atom/OP_GOTO.S
+++ b/vm/mterp/x86-atom/OP_GOTO.S
@@ -32,5 +32,5 @@
 
     movsbl      rINSTbl, %edx           # %edx<- +AA
     shl         $$1, %edx               # %edx is shifted for byte offset
-    js          common_periodicChecks2  # do check on backwards branch
+    js          common_periodicChecks_backwardBranch  # do check on backwards branch
     FINISH_RB   %edx, %ecx              # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_GOTO_16.S b/vm/mterp/x86-atom/OP_GOTO_16.S
index 6e6e0ac..931d215 100644
--- a/vm/mterp/x86-atom/OP_GOTO_16.S
+++ b/vm/mterp/x86-atom/OP_GOTO_16.S
@@ -30,5 +30,5 @@
 
     FETCHs      1, %edx                 # %edx<- ssssAAAA (sign-extended)
     shl         $$1, %edx               # %edx is doubled to get the byte offset
-    js          common_periodicChecks2  # do check on backwards branch
+    js          common_periodicChecks_backwardBranch  # do check on backwards branch
     FINISH_RB   %edx, %ecx              # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_GOTO_32.S b/vm/mterp/x86-atom/OP_GOTO_32.S
index 2dadda6..d00c3a4 100644
--- a/vm/mterp/x86-atom/OP_GOTO_32.S
+++ b/vm/mterp/x86-atom/OP_GOTO_32.S
@@ -33,5 +33,5 @@
     shl         $$16, %ecx              # prepare to create +AAAAAAAA
     or          %ecx, %edx              # %edx<- +AAAAAAAA
     shl         $$1, %edx               # %edx is doubled to get the byte offset
-    jle          common_periodicChecks2  # do check on backwards branch
+    jle          common_periodicChecks_backwardBranch  # do check on backwards branch
     FINISH_RB   %edx, %ecx              # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_IF_EQ.S b/vm/mterp/x86-atom/OP_IF_EQ.S
index ba1a2d2..61781a0 100644
--- a/vm/mterp/x86-atom/OP_IF_EQ.S
+++ b/vm/mterp/x86-atom/OP_IF_EQ.S
@@ -17,4 +17,4 @@
     * File: OP_IF_EQ.S
     */
 
-%include "x86-atom/bincmp.S" { "revcmp":"ne" }
\ No newline at end of file
+%include "x86-atom/bincmp.S" { "revcmp":"ne" }
diff --git a/vm/mterp/x86-atom/OP_IF_EQZ.S b/vm/mterp/x86-atom/OP_IF_EQZ.S
index 5aacfc7..2f7c140 100644
--- a/vm/mterp/x86-atom/OP_IF_EQZ.S
+++ b/vm/mterp/x86-atom/OP_IF_EQZ.S
@@ -17,4 +17,4 @@
     * File: OP_IF_EQZ.S
     */
 
-%include "x86-atom/zcmp.S" { "revcmp":"ne" }
\ No newline at end of file
+%include "x86-atom/zcmp.S" { "revcmp":"ne" }
diff --git a/vm/mterp/x86-atom/OP_IF_GE.S b/vm/mterp/x86-atom/OP_IF_GE.S
index 6fbfca5..e90a1e5 100644
--- a/vm/mterp/x86-atom/OP_IF_GE.S
+++ b/vm/mterp/x86-atom/OP_IF_GE.S
@@ -17,4 +17,4 @@
     * File: OP_IF_GE.S
     */
 
-%include "x86-atom/bincmp.S" { "revcmp":"l" }
\ No newline at end of file
+%include "x86-atom/bincmp.S" { "revcmp":"l" }
diff --git a/vm/mterp/x86-atom/OP_IF_GEZ.S b/vm/mterp/x86-atom/OP_IF_GEZ.S
index a953318..8ee71a8 100644
--- a/vm/mterp/x86-atom/OP_IF_GEZ.S
+++ b/vm/mterp/x86-atom/OP_IF_GEZ.S
@@ -17,4 +17,4 @@
     * File: OP_IF_GEZ.S
     */
 
-%include "x86-atom/zcmp.S" { "revcmp":"l" }
\ No newline at end of file
+%include "x86-atom/zcmp.S" { "revcmp":"l" }
diff --git a/vm/mterp/x86-atom/OP_IF_GT.S b/vm/mterp/x86-atom/OP_IF_GT.S
index fa6f8ee..7f19db9 100644
--- a/vm/mterp/x86-atom/OP_IF_GT.S
+++ b/vm/mterp/x86-atom/OP_IF_GT.S
@@ -17,4 +17,4 @@
     * File: OP_IF_GT.S
     */
 
-%include "x86-atom/bincmp.S" { "revcmp":"le" }
\ No newline at end of file
+%include "x86-atom/bincmp.S" { "revcmp":"le" }
diff --git a/vm/mterp/x86-atom/OP_IF_GTZ.S b/vm/mterp/x86-atom/OP_IF_GTZ.S
index 397561f..3f8039f 100644
--- a/vm/mterp/x86-atom/OP_IF_GTZ.S
+++ b/vm/mterp/x86-atom/OP_IF_GTZ.S
@@ -17,4 +17,4 @@
     * File: OP_IF_GTZ.S
     */
 
-%include "x86-atom/zcmp.S" { "revcmp":"le" }
\ No newline at end of file
+%include "x86-atom/zcmp.S" { "revcmp":"le" }
diff --git a/vm/mterp/x86-atom/OP_IF_LE.S b/vm/mterp/x86-atom/OP_IF_LE.S
index 480c2a1..287bd0d 100644
--- a/vm/mterp/x86-atom/OP_IF_LE.S
+++ b/vm/mterp/x86-atom/OP_IF_LE.S
@@ -17,4 +17,4 @@
     * File: OP_IF_LE.S
     */
 
-%include "x86-atom/bincmp.S" { "revcmp":"g" }
\ No newline at end of file
+%include "x86-atom/bincmp.S" { "revcmp":"g" }
diff --git a/vm/mterp/x86-atom/OP_IF_LEZ.S b/vm/mterp/x86-atom/OP_IF_LEZ.S
index ed9048b..b7d31d1 100644
--- a/vm/mterp/x86-atom/OP_IF_LEZ.S
+++ b/vm/mterp/x86-atom/OP_IF_LEZ.S
@@ -17,4 +17,4 @@
     * File: OP_IF_LEZ.S
     */
 
-%include "x86-atom/zcmp.S" { "revcmp":"g" }
\ No newline at end of file
+%include "x86-atom/zcmp.S" { "revcmp":"g" }
diff --git a/vm/mterp/x86-atom/OP_IF_LT.S b/vm/mterp/x86-atom/OP_IF_LT.S
index 16c86b8..7e58e18 100644
--- a/vm/mterp/x86-atom/OP_IF_LT.S
+++ b/vm/mterp/x86-atom/OP_IF_LT.S
@@ -17,4 +17,4 @@
     * File: OP_IF_LT.S
     */
 
-%include "x86-atom/bincmp.S" { "revcmp":"ge" }
\ No newline at end of file
+%include "x86-atom/bincmp.S" { "revcmp":"ge" }
diff --git a/vm/mterp/x86-atom/OP_IF_LTZ.S b/vm/mterp/x86-atom/OP_IF_LTZ.S
index acdf95e..0a3e56b 100644
--- a/vm/mterp/x86-atom/OP_IF_LTZ.S
+++ b/vm/mterp/x86-atom/OP_IF_LTZ.S
@@ -17,4 +17,4 @@
     * File: OP_IF_LTZ.S
     */
 
-%include "x86-atom/zcmp.S" { "revcmp":"ge" }
\ No newline at end of file
+%include "x86-atom/zcmp.S" { "revcmp":"ge" }
diff --git a/vm/mterp/x86-atom/OP_IF_NE.S b/vm/mterp/x86-atom/OP_IF_NE.S
index 5c3da51..929bd05 100644
--- a/vm/mterp/x86-atom/OP_IF_NE.S
+++ b/vm/mterp/x86-atom/OP_IF_NE.S
@@ -17,4 +17,4 @@
     * File: OP_IF_NE.S
     */
 
-%include "x86-atom/bincmp.S" { "revcmp":"e" }
\ No newline at end of file
+%include "x86-atom/bincmp.S" { "revcmp":"e" }
diff --git a/vm/mterp/x86-atom/OP_IF_NEZ.S b/vm/mterp/x86-atom/OP_IF_NEZ.S
index c3286f0..07f2c87 100644
--- a/vm/mterp/x86-atom/OP_IF_NEZ.S
+++ b/vm/mterp/x86-atom/OP_IF_NEZ.S
@@ -17,4 +17,4 @@
     * File: OP_IF_NEZ.S
     */
 
-%include "x86-atom/zcmp.S" { "revcmp":"e" }
\ No newline at end of file
+%include "x86-atom/zcmp.S" { "revcmp":"e" }
diff --git a/vm/mterp/x86-atom/OP_IGET_OBJECT_VOLATILE.S b/vm/mterp/x86-atom/OP_IGET_OBJECT_VOLATILE.S
new file mode 100644
index 0000000..5de2fa3
--- /dev/null
+++ b/vm/mterp/x86-atom/OP_IGET_OBJECT_VOLATILE.S
@@ -0,0 +1 @@
+%include "x86/OP_IGET.S"
diff --git a/vm/mterp/x86-atom/OP_IGET_VOLATILE.S b/vm/mterp/x86-atom/OP_IGET_VOLATILE.S
new file mode 100644
index 0000000..5de2fa3
--- /dev/null
+++ b/vm/mterp/x86-atom/OP_IGET_VOLATILE.S
@@ -0,0 +1 @@
+%include "x86/OP_IGET.S"
diff --git a/vm/mterp/x86-atom/OP_INT_TO_BYTE.S b/vm/mterp/x86-atom/OP_INT_TO_BYTE.S
index 7d0a89d..27cafe9 100644
--- a/vm/mterp/x86-atom/OP_INT_TO_BYTE.S
+++ b/vm/mterp/x86-atom/OP_INT_TO_BYTE.S
@@ -17,4 +17,4 @@
     * File: OP_INT_TO_BYTE.S
     */
 
-%include "x86-atom/unop.S" { "preinstr":"sal $24, %ecx", "instr":"sar $24, %ecx" }
\ No newline at end of file
+%include "x86-atom/unop.S" { "preinstr":"sal $24, %ecx", "instr":"sar $24, %ecx" }
diff --git a/vm/mterp/x86-atom/OP_INVOKE_DIRECT.S b/vm/mterp/x86-atom/OP_INVOKE_DIRECT.S
index 8f2a987..78b6c06 100644
--- a/vm/mterp/x86-atom/OP_INVOKE_DIRECT.S
+++ b/vm/mterp/x86-atom/OP_INVOKE_DIRECT.S
@@ -89,4 +89,4 @@
     cmp         $$0, %edx               # check for null "this"
     movl        %eax, %ecx              # %ecx<- method
     jne         common_invokeMethod${routine} # invoke method common code
-    jmp         common_errNullObject    # handle null object
\ No newline at end of file
+    jmp         common_errNullObject    # handle null object
diff --git a/vm/mterp/x86-atom/OP_INVOKE_OBJECT_INIT_RANGE.S b/vm/mterp/x86-atom/OP_INVOKE_OBJECT_INIT_RANGE.S
index faf1565..2459a3c 100644
--- a/vm/mterp/x86-atom/OP_INVOKE_OBJECT_INIT_RANGE.S
+++ b/vm/mterp/x86-atom/OP_INVOKE_OBJECT_INIT_RANGE.S
@@ -23,3 +23,7 @@
     * Format: B|A|op CCCC G|F|E|D (35c)
     */
 
+<<<<<<< HEAD:vm/mterp/x86-atom/OP_INVOKE_OBJECT_INIT_RANGE.S
+=======
+    FINISH 3
+>>>>>>> 10185db0:vm/mterp/x86-atom/OP_INVOKE_DIRECT_EMPTY.S
diff --git a/vm/mterp/x86-atom/OP_IPUT_OBJECT.S b/vm/mterp/x86-atom/OP_IPUT_OBJECT.S
index 33727ca..302cf44 100644
--- a/vm/mterp/x86-atom/OP_IPUT_OBJECT.S
+++ b/vm/mterp/x86-atom/OP_IPUT_OBJECT.S
@@ -13,8 +13,69 @@
     * limitations under the License.
     */
 
-   /*
-    * File: OP_IPUT_OBJECT.S
+    /*
+    * File: OP_IPUT.S
+    *
+    * Code: Generic 32-bit instance field "put" operation. Provides a
+    *       "mov" variable which determines the type of mov performed.
+    *       Currently, none of the iput's use this variable - may want
+    *       to change this, but seems ok for now.
+    *
+    * For: iput-boolean, iput-byte, iput-char, iput-object, iput
+    *      iput-short
+    *
+    * Description: Perform the object instance field "get" operation
+    *              with the identified field; load the instance value into
+    *              the value register.
+    *
+    *
+    * Format: B|A|op CCCC (22c)
+    *
+    * Syntax: op vA, vB, type@CCCC
+    *         op vA, vB, field@CCCC
     */
 
-%include "x86-atom/OP_IPUT.S"
+    movl        rGLUE, %edx             # %edx<- pMterpGlue
+    movl        offGlue_methodClassDex(%edx), %edx # %edx<- pDvmDex
+    FETCH       1, %ecx                 # %ecx<- CCCC
+    movl        offDvmDex_pResFields(%edx), %edx # %edx<- pDvmDex->pResFields
+    cmp         $$0, (%edx, %ecx, 4)    # check for null ptr; resolved InstField ptr
+    movl        (%edx, %ecx, 4), %eax   # %eax<- resolved InstField ptr
+    jne         .L${opcode}_finish2
+    movl        rGLUE, %edx             # %edx<- pMterpGlue
+    jmp         .L${opcode}_finish
+%break
+
+.L${opcode}_finish:
+    movl        offGlue_method(%edx), %edx # %edx<- glue->method
+    EXPORT_PC                           # in case an exception is thrown
+    movl        %ecx, -4(%esp)          # push parameter CCCC; field ref
+    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
+    lea         -8(%esp), %esp
+    movl        %edx, (%esp)            # push parameter method->clazz
+    call        dvmResolveInstField     # call: (const ClassObject* referrer, u4 ifieldIdx)
+                                        # return: InstField*
+    lea         8(%esp), %esp
+    cmp         $$0, %eax               # check if resolved
+    jne         .L${opcode}_finish2
+    jmp         common_exceptionThrown  # not resolved; handle exception
+
+.L${opcode}_finish2:
+    movl        rINST, %ecx             # %ecx<- BA+
+    shr         $$4, %ecx               # %ecx<- B
+    and         $$15, rINST             # rINST<- A
+    GET_VREG    %ecx                    # %ecx<- vB
+    cmp         $$0, %ecx               # check for null object
+    je          common_errNullObject    # handle null object
+    movl        offInstField_byteOffset(%eax), %edx # %edx<- field offset
+    GET_VREG    rINST                   # rINST<- vA
+    movl        rINST, (%edx, %ecx)     # object field<- vA
+    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
+    movl     rGLUE, %eax             # get glue
+    movl        offGlue_cardTable(%eax), %eax # get card table base
+    testl       rINST, rINST            # test if we stored a null value
+    je          1f                     # skip card mark if null stored
+    shrl        $$GC_CARD_SHIFT, %ecx   # set obeject head to card number
+    movb        %al, (%eax, %ecx)
+1:
+    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_IPUT_OBJECT_QUICK.S b/vm/mterp/x86-atom/OP_IPUT_OBJECT_QUICK.S
index b1edd5e..eee88e9 100644
--- a/vm/mterp/x86-atom/OP_IPUT_OBJECT_QUICK.S
+++ b/vm/mterp/x86-atom/OP_IPUT_OBJECT_QUICK.S
@@ -14,7 +14,31 @@
     */
 
    /*
-    * File: OP_IPUT_OBJECT_QUICK.S
+    * File: OP_IPUT_QUICK.S
+    * Code: Optimization for iput
+    *
+    * For: iput-quick
+    *
+    * Format: B|A|op CCCC (22c)
+    *
+    * Syntax: op vA, vB, offset@CCCC
     */
 
-%include "x86-atom/OP_IPUT_QUICK.S"
+    movl        rINST, %eax             # %eax<- BA
+    shr         $$4, %eax               # %eax<- B
+    and         $$15, rINST             # rINST<- A
+    GET_VREG    %eax                    # %eax<- vB; object to operate on
+    FETCH       1, %ecx                 # %ecx<- CCCC; field byte offset
+    cmp         $$0, %eax               # check if object is null
+    je          common_errNullObject    # handle null object
+    FFETCH_ADV  2, %edx                 # %edx<- next instruction hi; fetch, advance
+    GET_VREG    rINST                   # rINST<- vA
+    movl        rINST, (%eax, %ecx)     # object field<- vA
+    testl       rINST, rINST            # did we write a null object
+    je          1f
+    movl        rGLUE, %ecx             # get glue
+    movl        offGlue_cardTable(%ecx), %ecx # get card table base
+    shrl        $$GC_CARD_SHIFT, %eax   # get gc card index
+    movb        %cl, (%eax, %ecx)       # mark gc card in table
+1:
+    FGETOP_JMP  2, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_IPUT_OBJECT_VOLATILE.S b/vm/mterp/x86-atom/OP_IPUT_OBJECT_VOLATILE.S
new file mode 100644
index 0000000..4b024d0
--- /dev/null
+++ b/vm/mterp/x86-atom/OP_IPUT_OBJECT_VOLATILE.S
@@ -0,0 +1 @@
+%include "x86/OP_IPUT_OBJECT.S"
diff --git a/vm/mterp/x86-atom/OP_IPUT_VOLATILE.S b/vm/mterp/x86-atom/OP_IPUT_VOLATILE.S
new file mode 100644
index 0000000..475a0c5
--- /dev/null
+++ b/vm/mterp/x86-atom/OP_IPUT_VOLATILE.S
@@ -0,0 +1 @@
+%include "x86/OP_IPUT.S"
diff --git a/vm/mterp/x86-atom/OP_LONG_TO_INT.S b/vm/mterp/x86-atom/OP_LONG_TO_INT.S
index 3397fc2..0984bc0 100644
--- a/vm/mterp/x86-atom/OP_LONG_TO_INT.S
+++ b/vm/mterp/x86-atom/OP_LONG_TO_INT.S
@@ -17,4 +17,4 @@
     * File: OP_LONG_TO_INT.S
     */
 
-%include "x86-atom/OP_MOVE.S"
\ No newline at end of file
+%include "x86-atom/OP_MOVE.S"
diff --git a/vm/mterp/x86-atom/OP_MOVE.S b/vm/mterp/x86-atom/OP_MOVE.S
index ebc4989..9982ced 100644
--- a/vm/mterp/x86-atom/OP_MOVE.S
+++ b/vm/mterp/x86-atom/OP_MOVE.S
@@ -35,4 +35,4 @@
     FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    rINST                   # rINST<- vB
     SET_VREG    rINST, %ecx             # vA<- vB; %edx
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MOVE_OBJECT.S b/vm/mterp/x86-atom/OP_MOVE_OBJECT.S
index 9abc5d0..1cd22cb 100644
--- a/vm/mterp/x86-atom/OP_MOVE_OBJECT.S
+++ b/vm/mterp/x86-atom/OP_MOVE_OBJECT.S
@@ -17,4 +17,4 @@
     * File: OP_MOVE_OBJECT.S
     */
 
-%include "x86-atom/OP_MOVE.S"
\ No newline at end of file
+%include "x86-atom/OP_MOVE.S"
diff --git a/vm/mterp/x86-atom/OP_MOVE_OBJECT_FROM16.S b/vm/mterp/x86-atom/OP_MOVE_OBJECT_FROM16.S
index 1c8e661..bfca7da 100644
--- a/vm/mterp/x86-atom/OP_MOVE_OBJECT_FROM16.S
+++ b/vm/mterp/x86-atom/OP_MOVE_OBJECT_FROM16.S
@@ -17,4 +17,4 @@
     * File: OP_MOVE_OBJECT_FROM16.S
     */
 
-%include "x86-atom/OP_MOVE_FROM16.S"
\ No newline at end of file
+%include "x86-atom/OP_MOVE_FROM16.S"
diff --git a/vm/mterp/x86-atom/OP_MOVE_WIDE.S b/vm/mterp/x86-atom/OP_MOVE_WIDE.S
index 9a91d2a..909243b 100644
--- a/vm/mterp/x86-atom/OP_MOVE_WIDE.S
+++ b/vm/mterp/x86-atom/OP_MOVE_WIDE.S
@@ -34,4 +34,4 @@
     FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vB
     movq        %xmm0, (rFP, rINST, 4)  # vA<- vB
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_MUL_FLOAT.S b/vm/mterp/x86-atom/OP_MUL_FLOAT.S
index 1529dd5..34eba58 100644
--- a/vm/mterp/x86-atom/OP_MUL_FLOAT.S
+++ b/vm/mterp/x86-atom/OP_MUL_FLOAT.S
@@ -17,4 +17,4 @@
     * File: OP_MUL_FLOAT.S
     */
 
-%include "x86-atom/binopF.S" {"instr":"mulss %xmm1, %xmm0"}
\ No newline at end of file
+%include "x86-atom/binopF.S" {"instr":"mulss %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_MUL_FLOAT_2ADDR.S b/vm/mterp/x86-atom/OP_MUL_FLOAT_2ADDR.S
index 4345ce7..dbd615d 100644
--- a/vm/mterp/x86-atom/OP_MUL_FLOAT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_MUL_FLOAT_2ADDR.S
@@ -17,4 +17,4 @@
     * File: OP_MUL_FLOAT_2ADDR.S
     */
 
-%include "x86-atom/binopF2addr.S" {"instr":"mulss %xmm1, %xmm0"}
\ No newline at end of file
+%include "x86-atom/binopF2addr.S" {"instr":"mulss %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_MUL_INT.S b/vm/mterp/x86-atom/OP_MUL_INT.S
index b01ecda..8f5dac5 100644
--- a/vm/mterp/x86-atom/OP_MUL_INT.S
+++ b/vm/mterp/x86-atom/OP_MUL_INT.S
@@ -15,22 +15,6 @@
 
    /*
     * File: OP_MUL_INT.S
-    *
-    * Code: 32-bit multiply operation.  Performs "%ecx = %ecx * %edx"
-    *
-    * Description: Perform a multiplication operation on two source registers
-    *              and store the result in a destination register.
-    *
-    * Format: AA|op CC|BB (23x)
-    *
-    * Syntax: op vAA, vBB, vCC
     */
 
-    FETCH_BB    1, %ecx                 # %ecx<- BB
-    FETCH_CC    1, %edx                 # %edx<- CC
-    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vBB
-    addl        $$4, rPC                  # update PC
-    imul        (rFP, %edx, 4), %ecx    # %ecx<- vBB * vCC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+%include "x86-atom/binop.S" {"instr":"imul     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_MUL_INT_2ADDR.S b/vm/mterp/x86-atom/OP_MUL_INT_2ADDR.S
index e907178..b544df7 100644
--- a/vm/mterp/x86-atom/OP_MUL_INT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_MUL_INT_2ADDR.S
@@ -17,13 +17,4 @@
     * File: OP_MUL_INT_2ADDR.S
     */
 
-    movl        rINST, %edx             # %edx<- BA
-    shr         $$4, %edx               # %edx<- B
-    andl        $$15, rINST             # rINST<- A
-    movl        rINST, %ecx             # %ecx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    GET_VREG    %ecx                    # %ecx<- vA
-    imul        (rFP, %edx, 4), %ecx    # %ecx<- vA * vB
-    addl        $$2, rPC                  # update PC
-    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
+%include "x86-atom/binop2addr.S" {"instr":"imul     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_MUL_INT_LIT16.S b/vm/mterp/x86-atom/OP_MUL_INT_LIT16.S
index 7f3a27a..241531f 100644
--- a/vm/mterp/x86-atom/OP_MUL_INT_LIT16.S
+++ b/vm/mterp/x86-atom/OP_MUL_INT_LIT16.S
@@ -17,4 +17,4 @@
     * File: OP_MUL_INT_LIT16.S
     */
 
-%include "x86-atom/binopLit16.S" {"instr":"imul     %edx, %ecx"}
\ No newline at end of file
+%include "x86-atom/binopLit16.S" {"instr":"imul     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_NEG_INT.S b/vm/mterp/x86-atom/OP_NEG_INT.S
index 6770216..68acb89 100644
--- a/vm/mterp/x86-atom/OP_NEG_INT.S
+++ b/vm/mterp/x86-atom/OP_NEG_INT.S
@@ -17,4 +17,4 @@
     * File: OP_NEG_INT.S
     */
 
-%include "x86-atom/unop.S" {"instr":"neg        %ecx"}
\ No newline at end of file
+%include "x86-atom/unop.S" {"instr":"neg        %ecx"}
diff --git a/vm/mterp/x86-atom/OP_OR_INT.S b/vm/mterp/x86-atom/OP_OR_INT.S
index 59e39a3..0ece38c 100644
--- a/vm/mterp/x86-atom/OP_OR_INT.S
+++ b/vm/mterp/x86-atom/OP_OR_INT.S
@@ -17,4 +17,4 @@
     * File: OP_OR_INT.S
     */
 
-%include "x86-atom/binop.S" {"instr":"or (rFP, %edx, 4), %ecx"}
\ No newline at end of file
+%include "x86-atom/binop.S" {"instr":"or %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_OR_INT_2ADDR.S b/vm/mterp/x86-atom/OP_OR_INT_2ADDR.S
index ddc20ed..693e099 100644
--- a/vm/mterp/x86-atom/OP_OR_INT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_OR_INT_2ADDR.S
@@ -17,4 +17,4 @@
     * File: OP_OR_INT_2ADDR.S
     */
 
-%include "x86-atom/binop2addr.S" {"instr":"or %edx, (rFP, rINST, 4)"}
\ No newline at end of file
+%include "x86-atom/binop2addr.S" {"instr":"or %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_OR_INT_LIT16.S b/vm/mterp/x86-atom/OP_OR_INT_LIT16.S
index 3715781..5c63867 100644
--- a/vm/mterp/x86-atom/OP_OR_INT_LIT16.S
+++ b/vm/mterp/x86-atom/OP_OR_INT_LIT16.S
@@ -17,4 +17,4 @@
     * File: OP_OR_INT_LIT16.S
     */
 
-%include "x86-atom/binopLit16.S" {"instr":"or %edx, %ecx"}
\ No newline at end of file
+%include "x86-atom/binopLit16.S" {"instr":"or %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_PACKED_SWITCH.S b/vm/mterp/x86-atom/OP_PACKED_SWITCH.S
index 7cb6d64..debac02 100644
--- a/vm/mterp/x86-atom/OP_PACKED_SWITCH.S
+++ b/vm/mterp/x86-atom/OP_PACKED_SWITCH.S
@@ -45,7 +45,7 @@
     shl         $$1, %eax               # shift for byte offset
     movl        %eax, %edx              # %edx<- offset
     lea         8(%esp), %esp
-    jle         common_periodicChecks2  # do backward branch
+    jle         common_periodicChecks_backwardBranch  # do backward branch
     jmp         .L${opcode}_finish
 %break
 .L${opcode}_finish:
diff --git a/vm/mterp/x86-atom/OP_REM_INT.S b/vm/mterp/x86-atom/OP_REM_INT.S
index 2cd8a26..5f62d66 100644
--- a/vm/mterp/x86-atom/OP_REM_INT.S
+++ b/vm/mterp/x86-atom/OP_REM_INT.S
@@ -17,4 +17,4 @@
     * File: OP_REM_INT.S
     */
 
-%include "x86-atom/binopD.S" {"div":"0"}
\ No newline at end of file
+%include "x86-atom/binopD.S" {"div":"0"}
diff --git a/vm/mterp/x86-atom/OP_RETURN_OBJECT.S b/vm/mterp/x86-atom/OP_RETURN_OBJECT.S
index 48308df..3b9c10c 100644
--- a/vm/mterp/x86-atom/OP_RETURN_OBJECT.S
+++ b/vm/mterp/x86-atom/OP_RETURN_OBJECT.S
@@ -17,4 +17,4 @@
     * File: OP_RETURN_OBJECT.S
     */
 
-%include "x86-atom/OP_RETURN_COMMON.S"
\ No newline at end of file
+%include "x86-atom/OP_RETURN_COMMON.S"
diff --git a/vm/mterp/x86-atom/OP_RSUB_INT.S b/vm/mterp/x86-atom/OP_RSUB_INT.S
index 647a98e..87498f9 100644
--- a/vm/mterp/x86-atom/OP_RSUB_INT.S
+++ b/vm/mterp/x86-atom/OP_RSUB_INT.S
@@ -36,4 +36,4 @@
     GET_VREG    %ecx                    # %ecx<- vB
     subl        %ecx, %edx              # %edx<- +CCCC sub vB
     SET_VREG    %edx, rINST             # vA<- %edx; result
-    FINISH      2                       # jump to next instruction
\ No newline at end of file
+    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/OP_SGET_OBJECT_VOLATILE.S b/vm/mterp/x86-atom/OP_SGET_OBJECT_VOLATILE.S
new file mode 100644
index 0000000..5f64fb5
--- /dev/null
+++ b/vm/mterp/x86-atom/OP_SGET_OBJECT_VOLATILE.S
@@ -0,0 +1 @@
+%include "x86/OP_SGET.S"
diff --git a/vm/mterp/x86-atom/OP_SGET_VOLATILE.S b/vm/mterp/x86-atom/OP_SGET_VOLATILE.S
new file mode 100644
index 0000000..5f64fb5
--- /dev/null
+++ b/vm/mterp/x86-atom/OP_SGET_VOLATILE.S
@@ -0,0 +1 @@
+%include "x86/OP_SGET.S"
diff --git a/vm/mterp/x86-atom/OP_SHL_INT.S b/vm/mterp/x86-atom/OP_SHL_INT.S
index ac0f0cc..13e4a11 100644
--- a/vm/mterp/x86-atom/OP_SHL_INT.S
+++ b/vm/mterp/x86-atom/OP_SHL_INT.S
@@ -17,4 +17,4 @@
     * File: OP_SHL_INT.S
     */
 
-%include "x86-atom/binopS.S" {"instr":"sal     %cl, %edx"}
\ No newline at end of file
+%include "x86-atom/binopS.S" {"instr":"sal     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHL_INT_2ADDR.S b/vm/mterp/x86-atom/OP_SHL_INT_2ADDR.S
index 27be297..a27e09a 100644
--- a/vm/mterp/x86-atom/OP_SHL_INT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_SHL_INT_2ADDR.S
@@ -17,4 +17,4 @@
     * File: OP_SHL_INT_2ADDR.S
     */
 
-%include "x86-atom/binopS2addr.S" {"instr":"sal     %cl, %edx"}
\ No newline at end of file
+%include "x86-atom/binopS2addr.S" {"instr":"sal     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHL_INT_LIT8.S b/vm/mterp/x86-atom/OP_SHL_INT_LIT8.S
index 6e0e4f8..5141e5c 100644
--- a/vm/mterp/x86-atom/OP_SHL_INT_LIT8.S
+++ b/vm/mterp/x86-atom/OP_SHL_INT_LIT8.S
@@ -17,4 +17,4 @@
     * File: OP_SHL_INT_LIT8.S
     */
 
-%include "x86-atom/binopLit8S.S" {"instr":"sal     %cl, %edx"}
\ No newline at end of file
+%include "x86-atom/binopLit8S.S" {"instr":"sal     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHR_INT.S b/vm/mterp/x86-atom/OP_SHR_INT.S
index 2780f30..e7fd28b 100644
--- a/vm/mterp/x86-atom/OP_SHR_INT.S
+++ b/vm/mterp/x86-atom/OP_SHR_INT.S
@@ -17,4 +17,4 @@
     * File: OP_SHR_INT.S
     */
 
-%include "x86-atom/binopS.S" {"instr":"sar     %cl, %edx"}
\ No newline at end of file
+%include "x86-atom/binopS.S" {"instr":"sar     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHR_INT_2ADDR.S b/vm/mterp/x86-atom/OP_SHR_INT_2ADDR.S
index 4229f7d..0d0b461 100644
--- a/vm/mterp/x86-atom/OP_SHR_INT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_SHR_INT_2ADDR.S
@@ -17,4 +17,4 @@
     * File: OP_SHR_INT_2ADDR.S
     */
 
-%include "x86-atom/binopS2addr.S" {"instr":"sar     %cl, %edx"}
\ No newline at end of file
+%include "x86-atom/binopS2addr.S" {"instr":"sar     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SHR_INT_LIT8.S b/vm/mterp/x86-atom/OP_SHR_INT_LIT8.S
index 2cf2e39..3467bf5 100644
--- a/vm/mterp/x86-atom/OP_SHR_INT_LIT8.S
+++ b/vm/mterp/x86-atom/OP_SHR_INT_LIT8.S
@@ -17,4 +17,4 @@
     * File: OP_SHR_INT_LIT8.S
     */
 
-%include "x86-atom/binopLit8S.S" {"instr":"sar     %cl, %edx"}
\ No newline at end of file
+%include "x86-atom/binopLit8S.S" {"instr":"sar     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_SPUT_OBJECT.S b/vm/mterp/x86-atom/OP_SPUT_OBJECT.S
index 60afb97..88ebaf7 100644
--- a/vm/mterp/x86-atom/OP_SPUT_OBJECT.S
+++ b/vm/mterp/x86-atom/OP_SPUT_OBJECT.S
@@ -15,6 +15,56 @@
 
    /*
     * File: OP_SPUT_OBJECT.S
+    *
+    * Code: Generic 32-bit static field "put" operation. Uses no substitutions.
+    *
+    * For: sput-boolean, sput-byte, sput-char, sput-object, sput, sput-short
+    *
+    * Description: Perform the identified object static field operation
+    *              with the identified static field; store the field value
+    *              register.
+    *
+    * Format: AA|op BBBB (21c)
+    *
+    * Syntax: op vAA, string@BBBB
     */
 
-%include "x86-atom/OP_SPUT.S"
+    movl        rGLUE, %edx             # %edx<- pMterpGlue
+    movl        offGlue_methodClassDex(%edx), %ecx # %ecx<- pDvmDex
+    FETCH       1, %eax                 # %eax<- BBBB
+    movl        offDvmDex_pResFields(%ecx), %ecx # %ecx<- pResFields
+    cmp         $$0, (%ecx, %eax, 4)    # check for null ptr; resolved StaticField
+    movl        (%ecx, %eax, 4), %ecx   # %ecx<- resolved StaticField
+    je          .L${opcode}_resolve
+    jmp         .L${opcode}_finish
+%break
+
+.L${opcode}_resolve:
+    movl        offGlue_method(%edx), %edx # %edx <- glue->method
+    EXPORT_PC                           # in case an exception is thrown
+    movl        %eax, -4(%esp)          # push parameter CCCC; field ref
+    movl        offMethod_clazz(%edx), %edx # %edx<- method->clazz
+    movl        %edx, -8(%esp)          # push parameter method->clazz
+    lea         -8(%esp), %esp
+    call        dvmResolveStaticField   # call: (const ClassObject* referrer, u4 ifieldIdx)
+                                        # return: StaticField*
+    cmp         $$0, %eax               # check if initalization failed
+    lea         8(%esp), %esp
+    je          common_exceptionThrown  # failed; handle exception
+    movl        %eax, %ecx              # %ecx<- result
+
+.L${opcode}_finish:
+    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
+    GET_VREG    rINST                   # rINST<- vAA
+
+
+    movl        rINST, offStaticField_value(%ecx) # field value<- vAA
+    testl       rINST, rINST            # stored null object ptr?
+    je          1f
+    movl        rGLUE, %edx             # get glue
+    movl        offField_clazz(%ecx), %ecx # ecx<- field->clazz
+    movl        offGlue_cardTable(%edx), %edx # get card table base
+    shrl        $$GC_CARD_SHIFT, %ecx   # head to card number
+    movb        %dl, (%edx, %ecx)       # mark card
+1:
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/OP_SPUT_OBJECT_VOLATILE.S b/vm/mterp/x86-atom/OP_SPUT_OBJECT_VOLATILE.S
new file mode 100644
index 0000000..b368e31
--- /dev/null
+++ b/vm/mterp/x86-atom/OP_SPUT_OBJECT_VOLATILE.S
@@ -0,0 +1 @@
+%include "x86/OP_SPUT_OBJECT.S"
diff --git a/vm/mterp/x86-atom/OP_SPUT_VOLATILE.S b/vm/mterp/x86-atom/OP_SPUT_VOLATILE.S
new file mode 100644
index 0000000..7ee4140
--- /dev/null
+++ b/vm/mterp/x86-atom/OP_SPUT_VOLATILE.S
@@ -0,0 +1 @@
+%include "x86/OP_SPUT.S"
diff --git a/vm/mterp/x86-atom/OP_SUB_FLOAT.S b/vm/mterp/x86-atom/OP_SUB_FLOAT.S
index c41f75e..eb79d79 100644
--- a/vm/mterp/x86-atom/OP_SUB_FLOAT.S
+++ b/vm/mterp/x86-atom/OP_SUB_FLOAT.S
@@ -17,4 +17,4 @@
     * File: OP_SUB_FLOAT.S
     */
 
-%include "x86-atom/binopF.S" {"instr":"subss     %xmm1, %xmm0"}
\ No newline at end of file
+%include "x86-atom/binopF.S" {"instr":"subss     %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_SUB_FLOAT_2ADDR.S b/vm/mterp/x86-atom/OP_SUB_FLOAT_2ADDR.S
index dad1b7c..77f23f1 100644
--- a/vm/mterp/x86-atom/OP_SUB_FLOAT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_SUB_FLOAT_2ADDR.S
@@ -17,4 +17,4 @@
     * File: OP_SUB_FLOAT_2ADDR.S
     */
 
-%include "x86-atom/binopF2addr.S" {"instr":"subss     %xmm1, %xmm0"}
\ No newline at end of file
+%include "x86-atom/binopF2addr.S" {"instr":"subss     %xmm1, %xmm0"}
diff --git a/vm/mterp/x86-atom/OP_SUB_INT.S b/vm/mterp/x86-atom/OP_SUB_INT.S
index be530aa..8d342cd 100644
--- a/vm/mterp/x86-atom/OP_SUB_INT.S
+++ b/vm/mterp/x86-atom/OP_SUB_INT.S
@@ -17,4 +17,4 @@
     * File: OP_SUB_INT.S
     */
 
-%include "x86-atom/binop.S" {"instr":"subl     (rFP, %edx, 4), %ecx"}
+%include "x86-atom/binop.S" {"instr":"subl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_SUB_INT_2ADDR.S b/vm/mterp/x86-atom/OP_SUB_INT_2ADDR.S
index 0ecbb57..4d295a4 100644
--- a/vm/mterp/x86-atom/OP_SUB_INT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_SUB_INT_2ADDR.S
@@ -17,4 +17,4 @@
     * File: OP_SUB_INT_2ADDR.S
     */
 
-%include "x86-atom/binop2addr.S" {"instr":"subl     %edx, (rFP, rINST, 4)"}
\ No newline at end of file
+%include "x86-atom/binop2addr.S" {"instr":"subl     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_THROW.S b/vm/mterp/x86-atom/OP_THROW.S
index 85afa7a..120b1e9 100644
--- a/vm/mterp/x86-atom/OP_THROW.S
+++ b/vm/mterp/x86-atom/OP_THROW.S
@@ -28,6 +28,7 @@
     */
 
     movl        rGLUE, %eax             # %eax<- pMterpGlue
+    EXPORT_PC                           # export the pc
     GET_VREG    rINST                   # rINST<- vAA
     cmp         $$0, rINST              # check for null
     movl        offGlue_self(%eax), %ecx # %ecx<- glue->self
diff --git a/vm/mterp/x86-atom/OP_THROW_VERIFICATION_ERROR.S b/vm/mterp/x86-atom/OP_THROW_VERIFICATION_ERROR.S
index fcd42c7..f920b50 100644
--- a/vm/mterp/x86-atom/OP_THROW_VERIFICATION_ERROR.S
+++ b/vm/mterp/x86-atom/OP_THROW_VERIFICATION_ERROR.S
@@ -28,13 +28,13 @@
     * Syntax: op vAA, ref@BBBB
     */
 
-    movl        rGLUE, %edx                 # %edx<- pMterpGlue
-    movl        offGlue_method(%edx), %ecx  # %ecx<- glue->method
-    EXPORT_PC                               # in case an exception is thrown
-    FETCH       1, %eax                     # %eax<- BBBB
-    movl        %eax, -4(%esp)              # push parameter BBBB; ref
-    movl        rINST, -8(%esp)             # push parameter AA
-    movl        %ecx, -12(%esp)             # push parameter glue->method
+    movl        rGLUE, %edx                  # %edx<- pMterpGlue
+    movl        offGlue_method(%edx), %ecx   # %ecx<- glue->method
+    EXPORT_PC                                # in case an exception is thrown
+    FETCH       1, %eax                      # %eax<- BBBB
+    movl        %eax, -4(%esp)               # push parameter BBBB; ref
+    movl        rINST, -8(%esp)              # push parameter AA
+    movl        %ecx, -12(%esp)              # push parameter glue->method
     lea         -12(%esp), %esp
-    call        dvmThrowVerificationError   # call: (const Method* method, int kind, int ref)
-    jmp     common_exceptionThrown      # failed; handle exception
+    call        dvmThrowVerificationError    # call: (const Method* method, int kind, int ref)
+    jmp         common_exceptionThrown       # failed; handle exception
diff --git a/vm/mterp/x86-atom/OP_USHR_INT_LIT8.S b/vm/mterp/x86-atom/OP_USHR_INT_LIT8.S
index 38516c5..5a54df7 100644
--- a/vm/mterp/x86-atom/OP_USHR_INT_LIT8.S
+++ b/vm/mterp/x86-atom/OP_USHR_INT_LIT8.S
@@ -17,4 +17,4 @@
     * File: OP_USHR_INT_LIT8.S
     */
 
-%include "x86-atom/binopLit8S.S" {"instr":"shr     %cl, %edx"}
\ No newline at end of file
+%include "x86-atom/binopLit8S.S" {"instr":"shr     %cl, %edx"}
diff --git a/vm/mterp/x86-atom/OP_XOR_INT.S b/vm/mterp/x86-atom/OP_XOR_INT.S
index 6c8e26d..d36b83f 100644
--- a/vm/mterp/x86-atom/OP_XOR_INT.S
+++ b/vm/mterp/x86-atom/OP_XOR_INT.S
@@ -17,4 +17,4 @@
     * File: OP_XOR_INT.S
     */
 
-%include "x86-atom/binop.S" {"instr":"xor     (rFP, %edx, 4), %ecx"}
\ No newline at end of file
+%include "x86-atom/binop.S" {"instr":"xor     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_XOR_INT_2ADDR.S b/vm/mterp/x86-atom/OP_XOR_INT_2ADDR.S
index d2b8338..0bab865 100644
--- a/vm/mterp/x86-atom/OP_XOR_INT_2ADDR.S
+++ b/vm/mterp/x86-atom/OP_XOR_INT_2ADDR.S
@@ -17,4 +17,4 @@
     * File: OP_XOR_INT_2ADDR.S
     */
 
-%include "x86-atom/binop2addr.S" {"instr":"xor     %edx, (rFP, rINST, 4)"}
\ No newline at end of file
+%include "x86-atom/binop2addr.S" {"instr":"xor     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/OP_XOR_INT_LIT16.S b/vm/mterp/x86-atom/OP_XOR_INT_LIT16.S
index bb841cd..a26bcc5 100644
--- a/vm/mterp/x86-atom/OP_XOR_INT_LIT16.S
+++ b/vm/mterp/x86-atom/OP_XOR_INT_LIT16.S
@@ -17,4 +17,4 @@
     * File: OP_XOR_INT_LIT16.S
     */
 
-%include "x86-atom/binopLit16.S" {"instr":"xor     %edx, %ecx"}
\ No newline at end of file
+%include "x86-atom/binopLit16.S" {"instr":"xor     %edx, %ecx"}
diff --git a/vm/mterp/x86-atom/TODO.txt b/vm/mterp/x86-atom/TODO.txt
index 1c0acc8..da14adc 100644
--- a/vm/mterp/x86-atom/TODO.txt
+++ b/vm/mterp/x86-atom/TODO.txt
@@ -19,7 +19,7 @@
 
 (md) Correct OP_MONITOR_EXIT (need to adjust PC before throw)
 (md) OP_THROW needs to export the PC
-(md) Use dvmThrowArrayIndexOutOfBoundsException(index, length) for
+(md) Use dvmThrowArrayIndexOutOfBoundsException(length, index) for
      array bounds errors.
 (md) Use dvmThrowClassCastException(actual, desired) for class cast errors.
 (md) Use dvmThrowArrayStoreException(actual, desired) for array store errors.
@@ -27,7 +27,6 @@
 (md) Replace any remaining use of dvmThrowException with proper helper function
 
 (lo) Implement OP_BREAKPOINT
-(lo) Implement OP_EXECUTE_INLINE_RANGE
 (lo) Implement OP_*_VOLATILE (12 instructions)
 (lo) Implement OP_RETURN_VOID_BARRIER
 (lo) Implement OP_INVOKE_OBJECT_INIT
diff --git a/vm/mterp/x86-atom/bincmp.S b/vm/mterp/x86-atom/bincmp.S
index b56a0e1..a8fbed5 100644
--- a/vm/mterp/x86-atom/bincmp.S
+++ b/vm/mterp/x86-atom/bincmp.S
@@ -39,6 +39,6 @@
                                         # comparison is true
     FETCHs      1, %edx                 # %edx<- +CCCC, Branch offset
     sal         $$1, %edx
-    js          common_periodicChecks2
+    js          common_periodicChecks_backwardBranch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
diff --git a/vm/mterp/x86-atom/binop.S b/vm/mterp/x86-atom/binop.S
index 0343190..1706b72 100644
--- a/vm/mterp/x86-atom/binop.S
+++ b/vm/mterp/x86-atom/binop.S
@@ -29,14 +29,11 @@
     * Syntax: op vAA, vBB, vCC
     */
 
-
-
     FETCH_BB    1, %ecx                 # %ecx<- BB
-    OLD_JMP_1   2, %eax
-    OLD_JMP_2   %eax
     FETCH_CC    1, %edx                 # %edx<- CC
-    OLD_JMP_3   2
+    FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vBB
+    GET_VREG    %edx                    # %edx<- vCC
     $instr                              # %ecx<- vBB op vCC
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    OLD_JMP_4   %eax
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binop2addr.S b/vm/mterp/x86-atom/binop2addr.S
index af135a7..b26b25a 100644
--- a/vm/mterp/x86-atom/binop2addr.S
+++ b/vm/mterp/x86-atom/binop2addr.S
@@ -33,12 +33,13 @@
 
     movl        rINST, %edx             # %edx<- BA
     shr         $$4, %edx               # %edx<- B
-    #FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
-    OLD_JMP_1   1, %eax
-    andl $$15, rINST  # rINST<- A
-    OLD_JMP_2  %eax
+    andl        $$15, rINST             # rINST<- A
+    movl        rINST, %ecx             # %ecx<- A
+    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     GET_VREG    %edx                    # %edx<- vB
-    OLD_JMP_3   1
-    $instr    # %ecx<- vA op vB
-    #FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
-    OLD_JMP_4   %eax
+    GET_VREG    %ecx                    # %ecx<- vA
+    $instr                              # %ecx<- vA op vB
+    SET_VREG    %ecx, rINST             # vAA<- %ecx; result
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
+
+
diff --git a/vm/mterp/x86-atom/binopD.S b/vm/mterp/x86-atom/binopD.S
index a3565f3..20a2e9a 100644
--- a/vm/mterp/x86-atom/binopD.S
+++ b/vm/mterp/x86-atom/binopD.S
@@ -31,35 +31,31 @@
 
 %default {"div":"1"}
 
-
-    FETCH_CC    1, %ecx                 # %ecx<- CC
     FETCH_BB    1, %eax                 # %eax<- BB
-    GET_VREG    %ecx                    # %ecx<- vCC
-    testl       %ecx, %ecx
+    FETCH_CC    1, %ecx                 # %ecx<- CC
     GET_VREG    %eax                    # %eax<- vBB
+    GET_VREG    %ecx                    # %ecx<- vCC
+    cmp         $$0, %ecx               # check for divide by zero
     je          common_errDivideByZero  # handle divide by zero
     cmpl        $$-1, %ecx              # handle -1 special case divide error
-    jnz         .L${opcode}_continue
+    jne         .L${opcode}_noerror
     cmpl        $$0x80000000,%eax       # handle min int special case divide error
     je         .L${opcode}_break
-.L${opcode}_continue:
+.L${opcode}_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
     .if  $div
-    FFETCH_ADV 2 %edx
     SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    FGETOP_JMP  2 %edx
     .else
-    FFETCH_ADV  2 %eax
-    SET_VREG %edx rINST  # vAA<- %edx (remainder)
-    FGETOP_JMP  2 %eax
+    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
     .endif
+    jmp         .L${opcode}_break2
 %break
 .L${opcode}_break:
-    FFETCH_ADV  2 %eax
     .if  $div
     movl        $$0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $$0, (rFP, rINST, 4)    # vAA<- 0
     .endif
-    FGETOP_JMP  2 %eax
\ No newline at end of file
+.L${opcode}_break2:
+    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/binopD2addr.S b/vm/mterp/x86-atom/binopD2addr.S
index a4fcf65..392b46b 100644
--- a/vm/mterp/x86-atom/binopD2addr.S
+++ b/vm/mterp/x86-atom/binopD2addr.S
@@ -32,37 +32,37 @@
 
 %default {"div":"1"}
     movl        rINST, %ecx             # %ecx<- BA
-    shr         $$4, %ecx               # %ecx<- B
     andl        $$15, rINST             # rINST<- A, to be used as dest
     movl        rINST, %eax             # %eax<- A
-    GET_VREG    %ecx                    # %edx<- vB
-    testl       %ecx, %ecx               # check for divide by zero
+    shr         $$4, %ecx               # %ecx<- B
     GET_VREG    %eax                    # %eax<- vA
-    jz          common_errDivideByZero  # handle divide by zero
+    GET_VREG    %ecx                    # %edx<- vB
+    cmp         $$0, %ecx               # check for divide by zero
+    je          common_errDivideByZero  # handle divide by zero
     cmpl        $$-1, %ecx              # handle -1 special case divide error
-    jnz         .L${opcode}_continue
-    cmpl        $$0x80000000, %eax       # handle min int special case divide error
+    jne         .L${opcode}_noerror
+    cmpl        $$0x80000000,%eax       # handle min int special case divide error
     je         .L${opcode}_break
-
-.L${opcode}_continue:
+.L${opcode}_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
      .if  $div
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
     SET_VREG    %eax rINST              # vAA<- %eax (quotient)
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
     .else
-    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
     SET_VREG    %edx rINST              # vAA<- %edx (remainder)
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
     .endif
+    jmp         .L${opcode}_break2
+    #FFETCH_ADV 1, %edx  # %ecx<- next instruction hi; fetch, advance
+    #FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
 
 %break
 .L${opcode}_break:
-    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
     .if  $div
     movl        $$0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $$0, (rFP, rINST, 4)    # vAA<- 0
     .endif
+.L${opcode}_break2:
+    FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
+
diff --git a/vm/mterp/x86-atom/binopDLit16.S b/vm/mterp/x86-atom/binopDLit16.S
index 86bb937..3e67d0a 100644
--- a/vm/mterp/x86-atom/binopDLit16.S
+++ b/vm/mterp/x86-atom/binopDLit16.S
@@ -35,37 +35,32 @@
     movl        rINST, %eax             # %eax<- BA
     shr         $$4, %eax               # %eax<- B
     FETCHs      1, %ecx                 # %ecx<- +CCCC, sign-extended literal
-    testl       %ecx, %ecx              # check for divide by zero
+    cmp         $$0, %ecx               # check for divide by zero
     GET_VREG    %eax                    # %eax<- vB
     je          common_errDivideByZero  # handle divide by zero
-    addl        $$4, rPC                # update PC
     andl        $$15, rINST             # rINST<- A
     cmpl        $$-1, %ecx              # handle -1 special case divide error
-    jnz         .L${opcode}_continue
+    jne         .L${opcode}_noerror
     cmpl        $$0x80000000,%eax       # handle min int special case divide error
-    je          .L${opcode}_break
-.L${opcode}_continue:
+    je         .L${opcode}_break
+.L${opcode}_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
+    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
     .if  $div
-    movzbl      (rPC), %edx
-    SET_VREG    %eax, rINST             # vA<- %eax (quotient)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+    SET_VREG    %eax rINST              # vA<- %eax (quotient)
     .else
-    movzbl      (rPC), %eax
-    SET_VREG    %edx, rINST             # vA<- %edx (remainder)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %eax, 4)
+    SET_VREG    %edx rINST              # vA<- %edx (remainder)
     .endif
+    jmp         .L${opcode}_break2
 
 %break
 .L${opcode}_break:
-    movzbl      (rPC), %edx
     .if  $div
     movl        $$0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $$0, (rFP, rINST, 4)    # vAA<- 0
     .endif
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+.L${opcode}_break2:
+
+    FINISH      2                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/binopDLit8.S b/vm/mterp/x86-atom/binopDLit8.S
index 295a770..f197714 100644
--- a/vm/mterp/x86-atom/binopDLit8.S
+++ b/vm/mterp/x86-atom/binopDLit8.S
@@ -32,37 +32,34 @@
 
 %default {"div":"1"}
 
-    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
-    testl       %ecx, %ecx              # handle -1 special case divide error
     FETCH_BB    1, %eax                 # %eax<- BB
-    jz          common_errDivideByZero  # handle divide by zero
-    addl        $$4, rPC                # update PC
-    cmpl        $$-1, %ecx
+    FETCH_CCs   1, %ecx                 # %ecx<- +CC, sign-extended literal
+    cmp         $$0, %ecx               # check for divide by zero
     GET_VREG    %eax                    # %eax<- vBB
-    jnz         .L${opcode}_continue
+    je          common_errDivideByZero  # handle divide by zero
+
+    cmpl        $$-1, %ecx              # handle -1 special case divide error
+    jne         .L${opcode}_noerror
     cmpl        $$0x80000000,%eax       # handle min int special case divide error
-    je          .L${opcode}_break
-.L${opcode}_continue:
+    je         .L${opcode}_break
+.L${opcode}_noerror:
     cdq                                 # sign-extend %eax to %edx
     idiv        %ecx                    # divide %edx:%eax by %ecx
+    #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
     .if  $div
-    movzbl      (rPC), %edx
-    SET_VREG    %eax, rINST             # vA<- %eax (quotient)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+    SET_VREG    %eax rINST              # vAA<- %eax (quotient)
     .else
-    movzbl      (rPC), %eax
-    SET_VREG    %edx, rINST             # vA<- %edx (remainder)
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %eax, 4)
+    SET_VREG    %edx rINST              # vAA<- %edx (remainder)
     .endif
+    jmp         .L${opcode}_break2
 %break
 .L${opcode}_break:
-    movzbl      (rPC), %edx
     .if  $div
     movl        $$0x80000000, (rFP, rINST, 4) # vAA<- min int
     .else
     movl        $$0, (rFP, rINST, 4)    # vAA<- 0
     .endif
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(, %edx, 4)
+
+.L${opcode}_break2:
+    FINISH      2                       # jump to next instruction
+    #FGETOP_JMP 2, %ecx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopDivRemLong2Addr.S b/vm/mterp/x86-atom/binopDivRemLong2Addr.S
index d50f776..aa427de 100644
--- a/vm/mterp/x86-atom/binopDivRemLong2Addr.S
+++ b/vm/mterp/x86-atom/binopDivRemLong2Addr.S
@@ -51,4 +51,4 @@
     movl        %eax, (rFP, rINST, 4)   # vA<- return low
     movl        %edx, 4(rFP, rINST, 4)  # vA<- return high
     FFETCH_ADV  1, %ecx                 # %ecx<- next instruction hi; fetch, advance
-    FGETOP_JMP 1, %ecx                  # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP 1, %ecx                  # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopF.S b/vm/mterp/x86-atom/binopF.S
index a2b408f..0c07b97 100644
--- a/vm/mterp/x86-atom/binopF.S
+++ b/vm/mterp/x86-atom/binopF.S
@@ -36,4 +36,4 @@
     movss       (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
     $instr                              # %xmm0<- vBB op vCC
     movss       %xmm0, (rFP, rINST, 4)  # vAA<- %xmm0; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopF2addr.S b/vm/mterp/x86-atom/binopF2addr.S
index df1fdf7..135ca0c 100644
--- a/vm/mterp/x86-atom/binopF2addr.S
+++ b/vm/mterp/x86-atom/binopF2addr.S
@@ -38,4 +38,4 @@
     movss       (rFP, rINST, 4), %xmm1  # %xmm1<- vB
     $instr                              # %xmm0<- vA op vB
     movss       %xmm0, (rFP, %ecx, 4)   # vA<- %xmm0; result
-    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopLit16.S b/vm/mterp/x86-atom/binopLit16.S
index 8b1cbd1..4972b4d 100644
--- a/vm/mterp/x86-atom/binopLit16.S
+++ b/vm/mterp/x86-atom/binopLit16.S
@@ -40,4 +40,4 @@
     GET_VREG    %ecx                    # %ecx<- vB
     $instr                              # %ecx<- vA op vB
     SET_VREG    %ecx, rINST             # vA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopLit8.S b/vm/mterp/x86-atom/binopLit8.S
index f6c4a6b..239e443 100644
--- a/vm/mterp/x86-atom/binopLit8.S
+++ b/vm/mterp/x86-atom/binopLit8.S
@@ -37,4 +37,4 @@
     GET_VREG    %ecx                    # %ecx<- vBB
     $instr                              # %ecx<- vBB op +CC
     SET_VREG    %ecx, rINST             # vAA<- %ecx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopLit8S.S b/vm/mterp/x86-atom/binopLit8S.S
index c400063..c0360aa 100644
--- a/vm/mterp/x86-atom/binopLit8S.S
+++ b/vm/mterp/x86-atom/binopLit8S.S
@@ -37,4 +37,4 @@
     GET_VREG    %edx                    # %edx<- vBB
     $instr                              # %edx<- vBB op +CC
     SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopS.S b/vm/mterp/x86-atom/binopS.S
index b9c3e26..b09f5c2 100644
--- a/vm/mterp/x86-atom/binopS.S
+++ b/vm/mterp/x86-atom/binopS.S
@@ -29,12 +29,11 @@
     * Syntax: op vAA, vBB, vCC
     */
 
-    FETCH_CC    1, %ecx                 # %ecx<- CC
     FETCH_BB    1, %edx                 # %edx<- BB
+    FETCH_CC    1, %ecx                 # %ecx<- CC
     FFETCH_ADV  2, %eax                 # %eax<- next instruction hi; fetch, advance
-    addl        $$4, rPC                  # update PC
-    GET_VREG    %ecx                    # %ecx<- vCC
     GET_VREG    %edx                    # %edx<- vBB
+    GET_VREG    %ecx                    # %ecx<- vCC
     $instr                              # %edx<- vBB op +CC
     SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopS2addr.S b/vm/mterp/x86-atom/binopS2addr.S
index 453f38f..0c3c29a 100644
--- a/vm/mterp/x86-atom/binopS2addr.S
+++ b/vm/mterp/x86-atom/binopS2addr.S
@@ -32,12 +32,11 @@
 
     movl        rINST, %ecx             # %ecx<- BA
     shr         $$4, %ecx               # %ecx<- B
-    FFETCH_ADV  1, %eax                 # %ecx<- next i nstruction hi; fetch, advance
     andl        $$15, rINST             # rINST<- A
-    addl        $$2, rPC                  # update PC
     movl        rINST, %edx             # %edx<- A
+    FFETCH_ADV  1, %eax                 # %ecx<- next instruction hi; fetch, advance
     GET_VREG    %ecx                    # %ecx<- vB
     GET_VREG    %edx                    # %edx<- vA
     $instr                              # %edx<- vA op vB
     SET_VREG    %edx, rINST             # vAA<- %edx; result
-    FGETOP_JMP2 %eax                    # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopWide.S b/vm/mterp/x86-atom/binopWide.S
index 3b27f60..3cd3e52 100644
--- a/vm/mterp/x86-atom/binopWide.S
+++ b/vm/mterp/x86-atom/binopWide.S
@@ -37,4 +37,4 @@
     movq        (rFP, %edx, 4), %xmm1   # %xmm1<- vCC
     $instr                              # %xmm0<- vBB op vCC
     movq        %xmm0, (rFP, rINST, 4)  # vAA<- %ecx
-    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  2, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/binopWide2addr.S b/vm/mterp/x86-atom/binopWide2addr.S
index a051c2b..f9aa29c 100644
--- a/vm/mterp/x86-atom/binopWide2addr.S
+++ b/vm/mterp/x86-atom/binopWide2addr.S
@@ -34,10 +34,8 @@
     movl        rINST, %edx             # %edx<- BA
     shr         $$4, rINST              # rINST<- B
     andl        $$15, %edx              # %edx<- A
-    FFETCH_ADV  1, %eax                 # %eax<- next instruction hi; fetch, advance
     movq        (rFP, rINST, 4), %xmm1  # %xmm1<- vB
     movq        (rFP, %edx, 4), %xmm0   # %xmm0<- vA
     $instr                              # %xmm0<- vA op vB
     movq        %xmm0, (rFP, %edx, 4)   # vA<- %xmm0; result
-    #FINISH      1                      # jump to next instruction
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FINISH      1                       # jump to next instruction
diff --git a/vm/mterp/x86-atom/entry.S b/vm/mterp/x86-atom/entry.S
index ff6ab0b..3b8a3da 100644
--- a/vm/mterp/x86-atom/entry.S
+++ b/vm/mterp/x86-atom/entry.S
@@ -46,13 +46,6 @@
     */
 
     .macro      MTERP_EXIT
-    #lea                40(%ebp), %esp          # correct stack pointer
-    #movl       24(%ebp), %edi          # restore %edi
-    #movl       28(%ebp), %esi          # restore %esi
-    #movl       32(%ebp), %ebx          # restore %ebx
-    #movl       36(%ebp), %ebp          # restore caller base pointer
-    #ret                                        # return
-
     lea         40(%esp), %esp          # correct stack pointer
     movl        -16(%esp), %edi         # restore %edi
     movl        -12(%esp), %esi         # restore %esi
@@ -360,11 +353,11 @@
 .long .L_OP_SHL_INT_LIT8
 .long .L_OP_SHR_INT_LIT8
 .long .L_OP_USHR_INT_LIT8
-.long .L_OP_UNUSED_E3
-.long .L_OP_UNUSED_E4
-.long .L_OP_UNUSED_E5
-.long .L_OP_UNUSED_E6
-.long .L_OP_UNUSED_E7
+.long .L_OP_IGET_VOLATILE
+.long .L_OP_IPUT_VOLATILE
+.long .L_OP_SGET_VOLATILE
+.long .L_OP_SPUT_VOLATILE
+.long .L_OP_IGET_OBJECT_VOLATILE
 .long .L_OP_IGET_WIDE_VOLATILE
 .long .L_OP_IPUT_WIDE_VOLATILE
 .long .L_OP_SGET_WIDE_VOLATILE
@@ -385,7 +378,7 @@
 .long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE
 .long .L_OP_INVOKE_SUPER_QUICK
 .long .L_OP_INVOKE_SUPER_QUICK_RANGE
-.long .L_OP_UNUSED_FC
-.long .L_OP_UNUSED_FD
-.long .L_OP_UNUSED_FE
+.long .L_OP_IPUT_OBJECT_VOLATILE
+.long .L_OP_SGET_OBJECT_VOLATILE
+.long .L_OP_SPUT_OBJECT_VOLATILE
 .long .L_OP_DISPATCH_FF
diff --git a/vm/mterp/x86-atom/footer.S b/vm/mterp/x86-atom/footer.S
index 4b2818c..7b5ed9c 100644
--- a/vm/mterp/x86-atom/footer.S
+++ b/vm/mterp/x86-atom/footer.S
@@ -34,26 +34,22 @@
     movl        rGLUE, %edx             # %edx<- pMterpGlue
     movl        %ebx, -4(%esp)          # save %ebx to the stack
     movl        offGlue_pSelfSuspendCount(%edx), %ebx # %ebx<- pSuspendCount (int)
-#if defined(WITH_DEBUGGER)
+4:
     movl        offGlue_pDebuggerActive(%edx), %eax # %eax<- pDebuggerActive
-    movl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
-    and         $$7, %eax               # %eax<- mask for boolean (just how many bits does it take?)
-#endif
+    testl       %eax, %eax
+    je          5f
+    movzbl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
+5:
     cmp         $$0, (%ebx)             # check if suspend is pending
     jne         2f                      # handle suspend
-#if defined(WITH_DEBUGGER) || defined(WITH_PROFILER)
-#if defined(WITH_PROFILER)
     movl        offGlue_pActiveProfilers(%edx), %ebx # %ebx<- activeProfilers (int)
-    or          (%ebx), %eax            # %eax<- merge activeProfilers and debuggerActive
-#else
-    cmp         $$0, %eax               # check for debuggerActive
-#endif
-    jne         3f                      # debugger or profiler active; switch interp
-#endif
+    orl         (%ebx), %eax            # %eax<- merge activeProfilers and debuggerActive
     movl        -8(%esp), %edx          # %edx<- restore %edx
+    jne         3f                      # debugger or profiler active; switch interp
     movl        -4(%esp), %ebx          # %ebx<- restore %ebx
     ret                                 # return
 2:                                      # check suspended
+    EXPORT_PC
     movl        offGlue_self(%edx), %eax # %eax<- glue->self
     movl        %eax, -12(%esp)         # push parameter boolean
     lea         -12(%esp), %esp
@@ -62,11 +58,12 @@
     movl        4(%esp), %edx           # %edx<- restore %edx
     movl        8(%esp), %ebx           # %ebx<- restore %ebx
     lea         12(%esp), %esp
-    ret                                 # return
+    ret
 3:                                      # debugger/profiler enabled, bail out
-    add         -8(%esp), rPC           # rPC<- pc adjustments
-    movl        %ecx, offGlue_entryPoint(%edx) # glue->entryPoint<- reentry type
-    movl        $$1, %edx               # switch to interp == true
+    leal        (rPC, %edx, 2), rPC     # adjust pc to show target
+    movl        rGLUE, %ecx             # %ecx<- pMterpGlue
+    movb        $$kInterpEntryInstr, offGlue_entryPoint(%ecx)
+    movl        $$1, %edx               # switch interpreter
     jmp         common_gotoBail         # bail
 
    /*
@@ -78,25 +75,21 @@
     *  %edx is PC adjustment in bytes
     */
 
-common_periodicChecks2:
+common_periodicChecks_backwardBranch:
+    EXPORT_PC
     movl        rGLUE, %ecx             # %ecx<- pMterpGlue
     movl        offGlue_pSelfSuspendCount(%ecx), rINST # %ebx<- pSuspendCount (int)
-#if defined(WITH_DEBUGGER)
-    movl offGlue_pDebuggerActive(%ecx), %eax # %eax<- pDebuggerActive
-    movl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
-    and         $$7, %eax               # %eax<- mask for boolean (just how many bits does it take?)
-#endif
+4:
+    movl        offGlue_pDebuggerActive(%ecx), %eax # %eax<- pDebuggerActive
+    testl       %eax, %eax              # test for NULL pointer
+    je          5f
+    movzbl      (%eax), %eax            # %eax<- get debuggerActive count
+5:
     cmp         $$0, (rINST)            # check if suspend is pending
     jne         2f                      # handle suspend
-#if defined(WITH_DEBUGGER) || defined(WITH_PROFILER)
-#if defined(WITH_PROFILER)
     movl        offGlue_pActiveProfilers(%ecx), rINST # %edx<- activeProfilers (int)
-    or          (rINST), %eax           # %eax<- merge activeProfilers and debuggerActive
-#else
-    cmp         $$0, %eax               # check for debuggerActive
-#endif
+    orl          (rINST), %eax           # %eax<- merge activeProfilers and debuggerActive
     jne         3f                      # debugger or profiler active; switch interp
-#endif
     FINISH_RB   %edx, %ecx              # jump to next instruction
 2:                                      # check suspended
     movl        offGlue_self(%ecx), %eax# %eax<- glue->self
@@ -107,15 +100,13 @@
                                         # return: bool
     movl        rINST, %edx             # %edx<- restore %edx
     lea         12(%esp), %esp
-    FINISH_RB   %edx, %ecx              # jump to next instruction
-
+    FINISH_RB   %edx, %ecx
 3:                                      # debugger/profiler enabled, bail out
-    add         -8(%esp), rPC           # rPC<- pc adjustments
-    movl        $$kInterpEntryInstr, offGlue_entryPoint(%ecx) # glue->entryPoint<- reentry type
-    movl        $$1, %edx               # switch to interp<- true
+    leal        (rPC, %edx, 2), rPC     # adjust pc to show target
+    movb        $$kInterpEntryInstr, offGlue_entryPoint(%ecx)
+    movl        $$1, %edx               # switch interpreter
     jmp         common_gotoBail         # bail
 
-
    /*
     * The equivalent of "goto bail", this calls through the "bail handler".
     * State registers will be saved to the "glue" area before bailing.
@@ -333,13 +324,13 @@
     jne         common_exceptionThrown  # handle exception
     FGETOP_JMP  3, %edx                 # jump to next instruction; getop, jmp
 
-.LstackOverflow:  # %ecx=methodToCall
-    movl        %ecx, -4(%esp)          # push parameter method to call
+.LstackOverflow:
+    movl        %ecx, -4(%esp)          # push method to call
     movl        rGLUE, %ecx             # %ecx<- pMterpGlue
     movl        offGlue_self(%ecx), %ecx # %ecx<- glue->self
     movl        %ecx, -8(%esp)          # push parameter self
     lea         -8(%esp), %esp
-    call        dvmHandleStackOverflow  # call: (Thread* self, Method* method)
+    call        dvmHandleStackOverflow  # call: (Thread* self, Method *meth)
                                         # return: void
     lea         8(%esp), %esp
     jmp         common_exceptionThrown  # handle exception
@@ -361,22 +352,15 @@
 
     movl        rGLUE, rINST            # %ecx<- pMterpGlue
     movl        offGlue_pSelfSuspendCount(rINST), %edx # %ebx<- pSuspendCount (int)
-#if defined(WITH_DEBUGGER)
     movl        offGlue_pDebuggerActive(rINST), %eax # %eax<- pDebuggerActive
     movl        (%eax), %eax            # %eax<- get debuggerActive (boolean)
     and         $$7, %eax               # %eax<- mask for boolean (just how many bits does it take?)
-#endif
     cmp         $$0, (%edx)             # check if suspend is pending
     jne         2f                      # handle suspend
-#if defined(WITH_DEBUGGER) || defined(WITH_PROFILER)
-#if defined(WITH_PROFILER)
     movl        offGlue_pActiveProfilers(rINST), %edx # %edx<- activeProfilers (int)
     or          (%edx), %eax            # %eax<- merge activeProfilers and debuggerActive
-#else
     cmp         $$0, %eax               # check for debuggerActive
-#endif
     jne         3f                      # debugger or profiler active; switch interp
-#endif
     jmp         4f
 2:                                      # check suspended
     movl        offGlue_self(rINST), %eax# %eax<- glue->self
@@ -564,7 +548,7 @@
     jmp         .LdeadFood
 
 .LdeadFood:
-.word 0xdeadf00d
+.int 0xdeadf00d
 
    /*
     * Invalid array index.
diff --git a/vm/mterp/x86-atom/header.S b/vm/mterp/x86-atom/header.S
index 5b8303a..28c19d6 100644
--- a/vm/mterp/x86-atom/header.S
+++ b/vm/mterp/x86-atom/header.S
@@ -288,44 +288,6 @@
     jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
     .endm
 
-    .macro      FGETOP_JMP2 _rFinish
-    movzbl      1(rPC), rINST
-    jmp         *dvmAsmInstructionJmpTable(,\_rFinish, 4)
-    .endm
-
-    .macro      OLD_JMP_1 _count _rFinish
-    movzbl      (\_count*2)(rPC), \_rFinish
-    shl         $$${handler_size_bits}, \_rFinish
-    .endm
-
-    .macro      OLD_JMP_2 _rFinish
-    addl        $$dvmAsmInstructionStart,\_rFinish
-    .endm
-
-    .macro      OLD_JMP_3 _count
-    addl        $$(\_count*2), rPC
-    .endm
-
-    .macro      OLD_JMP_4 _rFinish
-    movzbl      1(rPC), rINST
-    jmp         *\_rFinish
-    .endm
-
-    .macro      OLD_JMP_A_1 _reg _rFinish
-    movzbl      (rPC, \_reg), \_rFinish
-    shl         $$${handler_size_bits}, \_rFinish
-    .endm
-
-    .macro      OLD_JMP_A_2 _rFinish
-    addl        $$dvmAsmInstructionStart,\_rFinish
-    .endm
-
-    .macro      OLD_JMP_A_3 _reg _rFinish
-    addl        \_reg, rPC
-    movzbl      1(rPC, \_reg), rINST
-    jmp         *\_rFinish
-    .endm
-
    /*
     * Macro pair attempts to speed up FETCH_INST, GET_INST_OPCODE and GOTO_OPCODE
     * by using a jump table. _rFinish and _reg should must be the same register for
diff --git a/vm/mterp/x86-atom/unop.S b/vm/mterp/x86-atom/unop.S
index 09af3d0..00f9f8d 100644
--- a/vm/mterp/x86-atom/unop.S
+++ b/vm/mterp/x86-atom/unop.S
@@ -40,4 +40,4 @@
     $preinstr                           # do operation part 1
     $instr                              # do operation part 2
     SET_VREG    %ecx, rINST             # vA<- result
-    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
\ No newline at end of file
+    FGETOP_JMP  1, %eax                 # jump to next instruction; getop, jmp
diff --git a/vm/mterp/x86-atom/zcmp.S b/vm/mterp/x86-atom/zcmp.S
index f93566e..6614dba 100644
--- a/vm/mterp/x86-atom/zcmp.S
+++ b/vm/mterp/x86-atom/zcmp.S
@@ -38,7 +38,7 @@
     * Inline common_backwardBranch
     */
 
-    js          common_periodicChecks2  # jump on backwards branch
+    js          common_periodicChecks_backwardBranch  # jump on backwards branch
 1:
     FINISH_RB   %edx, %ecx              # jump to next instruction
 
diff --git a/vm/mterp/x86/OP_CONST_CLASS_JUMBO.S b/vm/mterp/x86/OP_CONST_CLASS_JUMBO.S
index 44162da..ce64823 100644
--- a/vm/mterp/x86/OP_CONST_CLASS_JUMBO.S
+++ b/vm/mterp/x86/OP_CONST_CLASS_JUMBO.S
@@ -6,8 +6,8 @@
     movl      2(rPC),%eax              # eax<- AAAAAAAA
     movl      offThread_methodClassDex(%ecx),%ecx# ecx<- self->methodClassDex
     movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- dvmDex->pResClasses
-    FETCH_INST_OPCODE 4 %ecx
     movl      (%ecx,%eax,4),%eax       # eax<- rResClasses[AAAAAAAA]
+    FETCH_INST_OPCODE 4 %ecx
     testl     %eax,%eax                # resolved yet?
     je        .L${opcode}_resolve
     SET_VREG  %eax rINST               # vBBBB<- rResClasses[AAAAAAAA]
diff --git a/vm/mterp/x86/footer.S b/vm/mterp/x86/footer.S
index a185096..643deb8 100644
--- a/vm/mterp/x86/footer.S
+++ b/vm/mterp/x86/footer.S
@@ -623,9 +623,9 @@
 common_errArrayIndex:
     EXPORT_PC
     movl    offArrayObject_length(%eax), %eax
-    movl    %ecx,OUT_ARG0(%esp)
-    movl    %eax,OUT_ARG1(%esp)
-    call    dvmThrowArrayIndexOutOfBoundsException   # args (index, length)
+    movl    %eax,OUT_ARG0(%esp)
+    movl    %ecx,OUT_ARG1(%esp)
+    call    dvmThrowArrayIndexOutOfBoundsException   # args (length, index)
     jmp     common_exceptionThrown
 
 /*
diff --git a/vm/native/InternalNative.c b/vm/native/InternalNative.c
index 726c391..49e0c08 100644
--- a/vm/native/InternalNative.c
+++ b/vm/native/InternalNative.c
@@ -169,7 +169,7 @@
         char* actualClassName = (obj != NULL)
             ? dvmHumanReadableDescriptor(obj->clazz->descriptor)
             : strdup("null");
-        dvmThrowExceptionFmtByClass(exceptionClass,
+        dvmThrowExceptionFmt(exceptionClass,
             "expected receiver of type %s, but got %s",
             expectedClassName, actualClassName);
         free(expectedClassName);
diff --git a/vm/native/dalvik_system_DexFile.c b/vm/native/dalvik_system_DexFile.c
index af7eb89..9c9a6e1 100644
--- a/vm/native/dalvik_system_DexFile.c
+++ b/vm/native/dalvik_system_DexFile.c
@@ -259,7 +259,7 @@
         RETURN_VOID();
     }
 
-    /* TODO: Avoid making a copy of the array. */
+    /* TODO: Avoid making a copy of the array. (note array *is* modified) */
     length = fileContentsObj->length;
     pBytes = (u1*) malloc(length);
 
@@ -360,7 +360,8 @@
 
     name = dvmCreateCstrFromString(nameObj);
     descriptor = dvmDotToDescriptor(name);
-    LOGV("--- Explicit class load '%s' 0x%08x\n", descriptor, cookie);
+    LOGV("--- Explicit class load '%s' l=%p c=0x%08x\n",
+        descriptor, loader, cookie);
     free(name);
 
     if (!validateCookie(cookie))
diff --git a/vm/native/dalvik_system_VMDebug.c b/vm/native/dalvik_system_VMDebug.c
index 78c12f8..d511a8f 100644
--- a/vm/native/dalvik_system_VMDebug.c
+++ b/vm/native/dalvik_system_VMDebug.c
@@ -280,7 +280,7 @@
 
         fd = dup(origFd);
         if (fd < 0) {
-            dvmThrowExceptionFmt("Ljava/lang/RuntimeException;",
+            dvmThrowExceptionFmt(gDvm.exRuntimeException,
                 "dup(%d) failed: %s", origFd, strerror(errno));
             RETURN_VOID();
         }
diff --git a/vm/native/java_lang_System.c b/vm/native/java_lang_System.c
index c3e7a80..5402a7b 100644
--- a/vm/native/java_lang_System.c
+++ b/vm/native/java_lang_System.c
@@ -136,7 +136,7 @@
 
     /* make sure it's an array */
     if (!dvmIsArray(srcArray) || !dvmIsArray(dstArray)) {
-        dvmThrowExceptionFmtByClass(gDvm.exArrayStoreException,
+        dvmThrowExceptionFmt(gDvm.exArrayStoreException,
             "source and destination must be arrays, but were %s and %s",
             ((Object*)srcArray)->clazz->descriptor,
             ((Object*)dstArray)->clazz->descriptor);
@@ -148,7 +148,7 @@
         srcPos > (int) srcArray->length - length ||
         dstPos > (int) dstArray->length - length)
     {
-        dvmThrowExceptionFmtByClass(gDvm.exArrayIndexOutOfBoundsException,
+        dvmThrowExceptionFmt(gDvm.exArrayIndexOutOfBoundsException,
             "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
             srcArray->length, srcPos, dstArray->length, dstPos, length);
         RETURN_VOID();
@@ -167,7 +167,7 @@
     dstPrim = (dstType != '[' && dstType != 'L');
     if (srcPrim || dstPrim) {
         if (srcPrim != dstPrim || srcType != dstType) {
-            dvmThrowExceptionFmtByClass(gDvm.exArrayStoreException,
+            dvmThrowExceptionFmt(gDvm.exArrayStoreException,
                 "source and destination arrays are incompatible: %s and %s",
                 srcClass->descriptor, dstClass->descriptor);
             RETURN_VOID();
@@ -283,7 +283,7 @@
                 copyCount * width);
             dvmWriteBarrierArray(dstArray, 0, copyCount);
             if (copyCount != length) {
-                dvmThrowExceptionFmtByClass(gDvm.exArrayStoreException,
+                dvmThrowExceptionFmt(gDvm.exArrayStoreException,
                     "source[%d] of type %s cannot be stored in destination array of type %s",
                     copyCount, srcObj[copyCount]->clazz->descriptor,
                     dstClass->descriptor);
diff --git a/vm/oo/Array.c b/vm/oo/Array.c
index 0fa0f80..33b0f97 100644
--- a/vm/oo/Array.c
+++ b/vm/oo/Array.c
@@ -51,9 +51,8 @@
     size_t totalSize = elementSize + headerSize;
     if (elementSize >> elementShift != length || totalSize < elementSize) {
         char *descriptor = dvmHumanReadableDescriptor(arrayClass->descriptor);
-        dvmThrowExceptionFmt("Ljava/lang/OutOfMemoryError;",
-                             "%s of length %zd exceeds the VM limit",
-                             descriptor, length);
+        dvmThrowExceptionFmt(gDvm.exOutOfMemoryError,
+                "%s of length %zd exceeds the VM limit", descriptor, length);
         free(descriptor);
         return NULL;
     }
diff --git a/vm/oo/Class.c b/vm/oo/Class.c
index 3bd0298..16fb5d3 100644
--- a/vm/oo/Class.c
+++ b/vm/oo/Class.c
@@ -363,27 +363,6 @@
 }
 
 /*
- * We should be able to find classes now.  Get the vtable index for
- * the class loader loadClass() method.
- *
- * This doesn't work in dexopt when operating on core.jar, because
- * there aren't any classes to load.
- */
-bool dvmBaseClassStartup(void)
-{
-    ClassObject* clClass = dvmFindSystemClassNoInit("Ljava/lang/ClassLoader;");
-    Method* meth = dvmFindVirtualMethodByDescriptor(clClass, "loadClass",
-            "(Ljava/lang/String;)Ljava/lang/Class;");
-    if (meth == NULL) {
-        LOGE("Unable to find loadClass() in java.lang.ClassLoader\n");
-        return false;
-    }
-    gDvm.voffJavaLangClassLoader_loadClass = meth->methodIndex;
-
-    return true;
-}
-
-/*
  * Clean up.
  */
 void dvmClassShutdown(void)
@@ -1300,8 +1279,7 @@
 #endif
         dvmAddTrackedAlloc(excep, self);
         dvmClearException(self);
-        dvmThrowChainedExceptionWithClassMessage(
-            "Ljava/lang/NoClassDefFoundError;", descriptor, excep);
+        dvmThrowChainedNoClassDefFoundError(descriptor, excep);
         dvmReleaseTrackedAlloc(excep, self);
         clazz = NULL;
         goto bail;
@@ -3717,7 +3695,7 @@
     if (clazz->verifyErrorClass == NULL) {
         dvmThrowNoClassDefFoundError(clazz->descriptor);
     } else {
-        dvmThrowExceptionByClassWithClassMessage(clazz->verifyErrorClass,
+        dvmThrowExceptionWithClassMessage(clazz->verifyErrorClass,
             clazz->descriptor);
     }
 }
diff --git a/vm/oo/Class.h b/vm/oo/Class.h
index 9ec6f12..e27ef79 100644
--- a/vm/oo/Class.h
+++ b/vm/oo/Class.h
@@ -48,7 +48,6 @@
 } ClassPathEntry;
 
 bool dvmClassStartup(void);
-bool dvmBaseClassStartup(void);
 void dvmClassShutdown(void);
 bool dvmPrepBootClassPath(bool isNormalStart);
 
diff --git a/vm/reflect/Annotation.c b/vm/reflect/Annotation.c
index f333fa5..0fcf80d 100644
--- a/vm/reflect/Annotation.c
+++ b/vm/reflect/Annotation.c
@@ -54,67 +54,6 @@
 static const char* kDescrSignature  = "Ldalvik/annotation/Signature;";
 static const char* kDescrThrows     = "Ldalvik/annotation/Throws;";
 
-
-/*
- * Perform Annotation setup.
- */
-bool dvmReflectAnnotationStartup(void)
-{
-    Method* meth;
-
-    /*
-     * Find some standard Annotation classes.
-     */
-    gDvm.classJavaLangAnnotationAnnotationArray =
-        dvmFindArrayClass("[Ljava/lang/annotation/Annotation;", NULL);
-    gDvm.classJavaLangAnnotationAnnotationArrayArray =
-        dvmFindArrayClass("[[Ljava/lang/annotation/Annotation;", NULL);
-    if (gDvm.classJavaLangAnnotationAnnotationArray == NULL ||
-        gDvm.classJavaLangAnnotationAnnotationArrayArray == NULL)
-    {
-        LOGE("Could not find Annotation-array classes\n");
-        return false;
-    }
-
-    /*
-     * VM-specific annotation classes.
-     */
-    gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory =
-        dvmFindSystemClassNoInit("Lorg/apache/harmony/lang/annotation/AnnotationFactory;");
-    gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember =
-        dvmFindSystemClassNoInit("Lorg/apache/harmony/lang/annotation/AnnotationMember;");
-    gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray =
-        dvmFindArrayClass("[Lorg/apache/harmony/lang/annotation/AnnotationMember;", NULL);
-    if (gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory == NULL ||
-        gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember == NULL ||
-        gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray == NULL)
-    {
-        LOGE("Could not find android.lang annotation classes\n");
-        return false;
-    }
-
-    meth = dvmFindDirectMethodByDescriptor(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory,
-            "createAnnotation",
-            "(Ljava/lang/Class;[Lorg/apache/harmony/lang/annotation/AnnotationMember;)Ljava/lang/annotation/Annotation;");
-    if (meth == NULL) {
-        LOGE("Unable to find createAnnotation() in android AnnotationFactory\n");
-        return false;
-    }
-    gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation = meth;
-
-    meth = dvmFindDirectMethodByDescriptor(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember,
-            "<init>",
-            "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V");
-    if (meth == NULL) {
-        LOGE("Unable to find 4-arg constructor in android AnnotationMember\n");
-        return false;
-    }
-
-    gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init = meth;
-
-    return true;
-}
-
 /*
  * Read an unsigned LEB128 value from a buffer.  Advances "pBuf".
  */
diff --git a/vm/reflect/Proxy.c b/vm/reflect/Proxy.c
index e96aa1b..7b41360 100644
--- a/vm/reflect/Proxy.c
+++ b/vm/reflect/Proxy.c
@@ -49,70 +49,6 @@
 #define kThrowsField    0
 #define kProxySFieldCount 1
 
-
-/*
- * Perform Proxy setup.
- */
-bool dvmReflectProxyStartup()
-{
-    /*
-     * Standard methods we must provide in our proxy.
-     */
-    Method* methE;
-    Method* methH;
-    Method* methT;
-    Method* methF;
-    methE = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
-                "equals", "(Ljava/lang/Object;)Z");
-    methH = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
-                "hashCode", "()I");
-    methT = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
-                "toString", "()Ljava/lang/String;");
-    methF = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
-                "finalize", "()V");
-    if (methE == NULL || methH == NULL || methT == NULL || methF == NULL) {
-        LOGE("Could not find equals/hashCode/toString/finalize in Object\n");
-        return false;
-    }
-    gDvm.voffJavaLangObject_equals = methE->methodIndex;
-    gDvm.voffJavaLangObject_hashCode = methH->methodIndex;
-    gDvm.voffJavaLangObject_toString = methT->methodIndex;
-    gDvm.voffJavaLangObject_finalize = methF->methodIndex;
-
-    /*
-     * The prototype signature needs to be cloned from a method in a
-     * "real" DEX file.  We declared this otherwise unused method just
-     * for this purpose.
-     */
-    ClassObject* proxyClass;
-    Method* meth;
-    proxyClass = dvmFindSystemClassNoInit("Ljava/lang/reflect/Proxy;");
-    if (proxyClass == NULL) {
-        LOGE("No java.lang.reflect.Proxy\n");
-        return false;
-    }
-    meth = dvmFindDirectMethodByDescriptor(proxyClass, "constructorPrototype",
-                "(Ljava/lang/reflect/InvocationHandler;)V");
-    if (meth == NULL) {
-        LOGE("Could not find java.lang.Proxy.constructorPrototype()\n");
-        return false;
-    }
-    gDvm.methJavaLangReflectProxy_constructorPrototype = meth;
-
-    /*
-     * Get the offset of the "h" field in Proxy.
-     */
-    gDvm.offJavaLangReflectProxy_h = dvmFindFieldOffset(proxyClass, "h",
-        "Ljava/lang/reflect/InvocationHandler;");
-    if (gDvm.offJavaLangReflectProxy_h < 0) {
-        LOGE("Unable to find 'h' field in java.lang.Proxy\n");
-        return false;
-    }
-
-    return true;
-}
-
-
 /*
  * Generate a proxy class with the specified name, interfaces, and loader.
  * "interfaces" is an array of class objects.
diff --git a/vm/reflect/Reflect.c b/vm/reflect/Reflect.c
index 62e4f67..dd87d44 100644
--- a/vm/reflect/Reflect.c
+++ b/vm/reflect/Reflect.c
@@ -21,118 +21,6 @@
 #include <stdlib.h>
 
 /*
- * Cache some classes.
- */
-bool dvmReflectStartup(void)
-{
-    gDvm.classJavaLangReflectAccessibleObject =
-        dvmFindSystemClassNoInit("Ljava/lang/reflect/AccessibleObject;");
-    gDvm.classJavaLangReflectConstructor =
-        dvmFindSystemClassNoInit("Ljava/lang/reflect/Constructor;");
-    gDvm.classJavaLangReflectConstructorArray =
-        dvmFindArrayClass("[Ljava/lang/reflect/Constructor;", NULL);
-    gDvm.classJavaLangReflectField =
-        dvmFindSystemClassNoInit("Ljava/lang/reflect/Field;");
-    gDvm.classJavaLangReflectFieldArray =
-        dvmFindArrayClass("[Ljava/lang/reflect/Field;", NULL);
-    gDvm.classJavaLangReflectMethod =
-        dvmFindSystemClassNoInit("Ljava/lang/reflect/Method;");
-    gDvm.classJavaLangReflectMethodArray =
-        dvmFindArrayClass("[Ljava/lang/reflect/Method;", NULL);
-    gDvm.classJavaLangReflectProxy =
-        dvmFindSystemClassNoInit("Ljava/lang/reflect/Proxy;");
-    if (gDvm.classJavaLangReflectAccessibleObject == NULL ||
-        gDvm.classJavaLangReflectConstructor == NULL ||
-        gDvm.classJavaLangReflectConstructorArray == NULL ||
-        gDvm.classJavaLangReflectField == NULL ||
-        gDvm.classJavaLangReflectFieldArray == NULL ||
-        gDvm.classJavaLangReflectMethod == NULL ||
-        gDvm.classJavaLangReflectMethodArray == NULL ||
-        gDvm.classJavaLangReflectProxy == NULL)
-    {
-        LOGE("Could not find one or more reflection classes\n");
-        return false;
-    }
-
-    gDvm.methJavaLangReflectConstructor_init =
-        dvmFindDirectMethodByDescriptor(gDvm.classJavaLangReflectConstructor, "<init>",
-        "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;I)V");
-    gDvm.methJavaLangReflectField_init =
-        dvmFindDirectMethodByDescriptor(gDvm.classJavaLangReflectField, "<init>",
-        "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;I)V");
-    gDvm.methJavaLangReflectMethod_init =
-        dvmFindDirectMethodByDescriptor(gDvm.classJavaLangReflectMethod, "<init>",
-        "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;I)V");
-    if (gDvm.methJavaLangReflectConstructor_init == NULL ||
-        gDvm.methJavaLangReflectField_init == NULL ||
-        gDvm.methJavaLangReflectMethod_init == NULL)
-    {
-        LOGE("Could not find reflection constructors\n");
-        return false;
-    }
-
-    gDvm.classJavaLangClassArray =
-        dvmFindArrayClass("[Ljava/lang/Class;", NULL);
-    gDvm.classJavaLangObjectArray =
-        dvmFindArrayClass("[Ljava/lang/Object;", NULL);
-    if (gDvm.classJavaLangClassArray == NULL ||
-        gDvm.classJavaLangObjectArray == NULL)
-    {
-        LOGE("Could not find class-array or object-array class\n");
-        return false;
-    }
-
-    gDvm.offJavaLangReflectAccessibleObject_flag =
-        dvmFindFieldOffset(gDvm.classJavaLangReflectAccessibleObject, "flag",
-            "Z");
-
-    gDvm.offJavaLangReflectConstructor_slot =
-        dvmFindFieldOffset(gDvm.classJavaLangReflectConstructor, "slot", "I");
-    gDvm.offJavaLangReflectConstructor_declClass =
-        dvmFindFieldOffset(gDvm.classJavaLangReflectConstructor,
-            "declaringClass", "Ljava/lang/Class;");
-
-    gDvm.offJavaLangReflectField_slot =
-        dvmFindFieldOffset(gDvm.classJavaLangReflectField, "slot", "I");
-    gDvm.offJavaLangReflectField_declClass =
-        dvmFindFieldOffset(gDvm.classJavaLangReflectField,
-            "declaringClass", "Ljava/lang/Class;");
-
-    gDvm.offJavaLangReflectMethod_slot =
-        dvmFindFieldOffset(gDvm.classJavaLangReflectMethod, "slot", "I");
-    gDvm.offJavaLangReflectMethod_declClass =
-        dvmFindFieldOffset(gDvm.classJavaLangReflectMethod,
-            "declaringClass", "Ljava/lang/Class;");
-
-    if (gDvm.offJavaLangReflectAccessibleObject_flag < 0 ||
-        gDvm.offJavaLangReflectConstructor_slot < 0 ||
-        gDvm.offJavaLangReflectConstructor_declClass < 0 ||
-        gDvm.offJavaLangReflectField_slot < 0 ||
-        gDvm.offJavaLangReflectField_declClass < 0 ||
-        gDvm.offJavaLangReflectMethod_slot < 0 ||
-        gDvm.offJavaLangReflectMethod_declClass < 0)
-    {
-        LOGE("Could not find reflection fields\n");
-        return false;
-    }
-
-    if (!dvmReflectProxyStartup())
-        return false;
-    if (!dvmReflectAnnotationStartup())
-        return false;
-
-    return true;
-}
-
-/*
- * Clean up.
- */
-void dvmReflectShutdown(void)
-{
-    // nothing to do
-}
-
-/*
  * For some of the reflection stuff we need to un-box primitives, e.g.
  * convert a java/lang/Integer to int or even a float.  We assume that
  * the first instance field holds the value.
diff --git a/vm/reflect/Reflect.h b/vm/reflect/Reflect.h
index 42b18c0..1ebdd2a 100644
--- a/vm/reflect/Reflect.h
+++ b/vm/reflect/Reflect.h
@@ -19,11 +19,6 @@
 #ifndef _DALVIK_REFLECT_REFLECT
 #define _DALVIK_REFLECT_REFLECT
 
-bool dvmReflectStartup(void);
-bool dvmReflectProxyStartup(void);
-bool dvmReflectAnnotationStartup(void);
-void dvmReflectShutdown(void);
-
 /*
  * During startup, validate the "box" classes, e.g. java/lang/Integer.
  */