aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dx/src/com/android/dx/command/dexer/Main.java4
-rw-r--r--dx/src/com/android/dx/dex/DexOptions.java8
-rw-r--r--dx/src/com/android/dx/dex/code/Dops.java26
-rw-r--r--dx/src/com/android/dx/io/Opcodes.java17
-rw-r--r--vm/Exception.cpp2
-rw-r--r--vm/alloc/HeapSource.cpp2
-rw-r--r--vm/analysis/DexPrepare.cpp2
-rw-r--r--vm/compiler/Frontend.cpp8
-rw-r--r--vm/compiler/codegen/arm/CodegenDriver.cpp5
-rw-r--r--vm/reflect/Annotation.cpp6
10 files changed, 66 insertions, 14 deletions
diff --git a/dx/src/com/android/dx/command/dexer/Main.java b/dx/src/com/android/dx/command/dexer/Main.java
index 947bd4178..653b9bce4 100644
--- a/dx/src/com/android/dx/command/dexer/Main.java
+++ b/dx/src/com/android/dx/command/dexer/Main.java
@@ -1192,6 +1192,9 @@ public class Main {
*/
public boolean keepClassesInJar = false;
+ /** what API level to target */
+ public int targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES;
+
/** how much source position info to preserve */
public int positionInfo = PositionList.LINES;
@@ -1513,6 +1516,7 @@ public class Main {
cfOptions.warn = DxConsole.err;
dexOptions = new DexOptions();
+ dexOptions.targetApiLevel = targetApiLevel;
dexOptions.forceJumbo = forceJumbo;
}
}
diff --git a/dx/src/com/android/dx/dex/DexOptions.java b/dx/src/com/android/dx/dex/DexOptions.java
index 60d83a84e..db0c7a2c5 100644
--- a/dx/src/com/android/dx/dex/DexOptions.java
+++ b/dx/src/com/android/dx/dex/DexOptions.java
@@ -34,4 +34,12 @@ public class DexOptions {
public String getMagic() {
return DexFormat.apiToMagic(targetApiLevel);
}
+
+ /**
+ * Returns whether extended opcodes are allowed. This became
+ * allowed as of Ice Cream Sandwich.
+ */
+ public boolean canUseExtendedOpcodes() {
+ return targetApiLevel >= DexFormat.API_CURRENT;
+ }
}
diff --git a/dx/src/com/android/dx/dex/code/Dops.java b/dx/src/com/android/dx/dex/code/Dops.java
index a84ddc098..cc5c173ed 100644
--- a/dx/src/com/android/dx/dex/code/Dops.java
+++ b/dx/src/com/android/dx/dex/code/Dops.java
@@ -1206,15 +1206,29 @@ public final class Dops {
* the last in its chain
*/
public static Dop getNextOrNull(Dop opcode, DexOptions options) {
- int nextOpcode = opcode.getNextOpcode();
+ boolean suppressExtendedOpcodes = !options.canUseExtendedOpcodes();
- if (nextOpcode == Opcodes.NO_NEXT) {
- return null;
- }
+ for (;;) {
+ int nextOpcode = opcode.getNextOpcode();
- opcode = get(nextOpcode);
+ if (nextOpcode == Opcodes.NO_NEXT) {
+ return null;
+ }
+
+ opcode = get(nextOpcode);
- return opcode;
+ if (suppressExtendedOpcodes && Opcodes.isExtended(nextOpcode)) {
+ /*
+ * Continuing rather than just returning null here
+ * protects against the possibility that an
+ * instruction fitting chain might list non-extended
+ * opcodes after extended ones.
+ */
+ continue;
+ }
+
+ return opcode;
+ }
}
/**
diff --git a/dx/src/com/android/dx/io/Opcodes.java b/dx/src/com/android/dx/io/Opcodes.java
index 611dbda43..6dba49d9e 100644
--- a/dx/src/com/android/dx/io/Opcodes.java
+++ b/dx/src/com/android/dx/io/Opcodes.java
@@ -327,6 +327,23 @@ public final class Opcodes {
}
/**
+ * Gets whether ({@code true}) or not ({@code false}) the given
+ * opcode value is an "extended" opcode (not counting the nop-like
+ * payload opcodes). Extended opcodes require a full 16-bit code
+ * unit to represent, without leaving space for an argument byte.
+ *
+ * @param opcode the opcode value
+ * @return {@code true} iff the opcode is an "extended" opcode
+ */
+ public static boolean isExtended(int opcode) {
+ /*
+ * Note: Extended opcodes all have the form ((byteValue << 8)
+ * | 0xff).
+ */
+ return (opcode >= 0x00ff);
+ }
+
+ /**
* Gets the opcode out of an opcode unit, the latter of which may also
* include one or more argument values.
*
diff --git a/vm/Exception.cpp b/vm/Exception.cpp
index 36f2d20c0..ca7614096 100644
--- a/vm/Exception.cpp
+++ b/vm/Exception.cpp
@@ -1225,7 +1225,7 @@ void dvmThrowArrayStoreExceptionNotArray(ClassObject* actual, const char* label)
void dvmThrowArrayStoreExceptionIncompatibleArrays(ClassObject* source, ClassObject* destination)
{
throwTypeError(gDvm.exArrayStoreException,
- "Incompatible types: src=%s, dst=%s",
+ "%s and %s are incompatible array types",
source, destination);
}
diff --git a/vm/alloc/HeapSource.cpp b/vm/alloc/HeapSource.cpp
index caf30af02..56d392ab3 100644
--- a/vm/alloc/HeapSource.cpp
+++ b/vm/alloc/HeapSource.cpp
@@ -414,7 +414,7 @@ static bool remapNewHeap(HeapSource* hs, Heap* newHeap)
ALOGE("Unable to create an ashmem region for the new heap");
return false;
}
- void* addr = mmap(newHeapBase, rem_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ void* addr = mmap(newHeapBase, rem_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
int ret = close(fd);
if (addr == MAP_FAILED) {
ALOGE("Unable to map an ashmem region for the new heap");
diff --git a/vm/analysis/DexPrepare.cpp b/vm/analysis/DexPrepare.cpp
index 707ac90e1..38954030a 100644
--- a/vm/analysis/DexPrepare.cpp
+++ b/vm/analysis/DexPrepare.cpp
@@ -1153,7 +1153,7 @@ static const u1* getSignature(const ClassPathEntry* cpe)
* If this changes, update DEX_OPT_MAGIC_VERS.
*/
static const size_t kMinDepSize = 4 * 4;
-static const size_t kMaxDepSize = 4 * 4 + 2544; // sanity check
+static const size_t kMaxDepSize = 4 * 4 + 2643; // sanity check
/*
* Read the "opt" header, verify it, then read the dependencies section
diff --git a/vm/compiler/Frontend.cpp b/vm/compiler/Frontend.cpp
index 65ef1ebd9..3cebe8238 100644
--- a/vm/compiler/Frontend.cpp
+++ b/vm/compiler/Frontend.cpp
@@ -1484,6 +1484,11 @@ static bool exhaustTrace(CompilationUnit *cUnit, BasicBlock *curBlock)
return true;
}
+/* placeholder of future passes */
+__attribute__((weak)) void dvmExtraPass(CompilationUnit *cUnit)
+{
+}
+
/* Compile a loop */
static bool compileLoop(CompilationUnit *cUnit, unsigned int startOffset,
JitTraceDescription *desc, int numMaxInsts,
@@ -1574,12 +1579,15 @@ static bool compileLoop(CompilationUnit *cUnit, unsigned int startOffset,
dvmCompilerLoopOpt(cUnit);
+
/*
* Change the backward branch to the backward chaining cell after dataflow
* analsys/optimizations are done.
*/
dvmCompilerInsertBackwardChaining(cUnit);
+ dvmExtraPass(cUnit);
+
#if defined(ARCH_IA32)
/* Convert MIR to LIR, etc. */
dvmCompilerMIR2LIR(cUnit, info);
diff --git a/vm/compiler/codegen/arm/CodegenDriver.cpp b/vm/compiler/codegen/arm/CodegenDriver.cpp
index 93ea6133a..d9da0cd69 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.cpp
+++ b/vm/compiler/codegen/arm/CodegenDriver.cpp
@@ -824,7 +824,7 @@ static bool genArithOpInt(CompilationUnit *cUnit, MIR *mir,
bool checkZero = false;
bool unary = false;
int retReg = r0;
- int (*callTgt)(int, int) = NULL;
+ int (*callTgt)(int, int);
RegLocation rlResult;
bool shiftOp = false;
@@ -4417,7 +4417,8 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
* Append the label pseudo LIR first. Chaining cells will be handled
* separately afterwards.
*/
- dvmCompilerAppendLIR(cUnit, (LIR *) &labelList[i]);
+ if(bb->blockType != kDalvikByteCode || !bb->hidden)
+ dvmCompilerAppendLIR(cUnit, (LIR *) &labelList[i]);
}
if (bb->blockType == kEntryBlock) {
diff --git a/vm/reflect/Annotation.cpp b/vm/reflect/Annotation.cpp
index bbd58e953..942027c7b 100644
--- a/vm/reflect/Annotation.cpp
+++ b/vm/reflect/Annotation.cpp
@@ -1288,7 +1288,7 @@ bool dvmIsClassAnnotationPresent(const ClassObject* clazz,
{
const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForClass(clazz);
if (pAnnoSet == NULL) {
- return false;
+ return NULL;
}
const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
clazz, pAnnoSet, kDexVisibilityRuntime, annotationClazz);
@@ -1743,7 +1743,7 @@ bool dvmIsMethodAnnotationPresent(const ClassObject* clazz,
{
const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForMethod(method);
if (pAnnoSet == NULL) {
- return false;
+ return NULL;
}
const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
clazz, pAnnoSet, kDexVisibilityRuntime, annotationClazz);
@@ -2053,7 +2053,7 @@ bool dvmIsFieldAnnotationPresent(const ClassObject* clazz,
{
const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForField(field);
if (pAnnoSet == NULL) {
- return false;
+ return NULL;
}
const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
clazz, pAnnoSet, kDexVisibilityRuntime, annotationClazz);