Merge "Assembler fix" into dalvik-dev
diff --git a/src/calling_convention.h b/src/calling_convention.h
index a1d1b32..8f2a79c 100644
--- a/src/calling_convention.h
+++ b/src/calling_convention.h
@@ -141,7 +141,7 @@
// Returns true if the method register will have been clobbered during argument
// set up
- virtual bool IsMethodRegisterCrushedPreCall() = 0;
+ virtual bool IsMethodRegisterClobberedPreCall() = 0;
// Iterator interface
bool HasNext();
diff --git a/src/calling_convention_arm.cc b/src/calling_convention_arm.cc
index 6e664ca..ed876f0 100644
--- a/src/calling_convention_arm.cc
+++ b/src/calling_convention_arm.cc
@@ -171,7 +171,7 @@
}
// Will reg be crushed by an outgoing argument?
-bool ArmJniCallingConvention::IsMethodRegisterCrushedPreCall() {
+bool ArmJniCallingConvention::IsMethodRegisterClobberedPreCall() {
return true; // The method register R0 is always clobbered by the JNIEnv
}
diff --git a/src/calling_convention_arm.h b/src/calling_convention_arm.h
index 4415254..3d513fe 100644
--- a/src/calling_convention_arm.h
+++ b/src/calling_convention_arm.h
@@ -46,7 +46,7 @@
virtual uint32_t FpSpillMask() const {
return 0; // Floats aren't spilled in JNI down call
}
- virtual bool IsMethodRegisterCrushedPreCall();
+ virtual bool IsMethodRegisterClobberedPreCall();
virtual bool IsCurrentParamInRegister();
virtual bool IsCurrentParamOnStack();
virtual ManagedRegister CurrentParamRegister();
diff --git a/src/calling_convention_x86.cc b/src/calling_convention_x86.cc
index a8f5778..9598647 100644
--- a/src/calling_convention_x86.cc
+++ b/src/calling_convention_x86.cc
@@ -86,7 +86,7 @@
return FrameSize() - kPointerSize;
}
-bool X86JniCallingConvention::IsMethodRegisterCrushedPreCall() {
+bool X86JniCallingConvention::IsMethodRegisterClobberedPreCall() {
return GetMethod()->IsSynchronized(); // Monitor enter crushes the method register
}
diff --git a/src/calling_convention_x86.h b/src/calling_convention_x86.h
index 8c55472..c3bdc40 100644
--- a/src/calling_convention_x86.h
+++ b/src/calling_convention_x86.h
@@ -49,7 +49,7 @@
virtual uint32_t FpSpillMask() const {
return 0;
}
- virtual bool IsMethodRegisterCrushedPreCall();
+ virtual bool IsMethodRegisterClobberedPreCall();
virtual bool IsCurrentParamInRegister();
virtual bool IsCurrentParamOnStack();
virtual ManagedRegister CurrentParamRegister();
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index 712a3a0..c1e666e 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -239,6 +239,7 @@
CompileVirtualMethod(NULL, "java.lang.Throwable","fillInStackTrace","()Ljava/lang/Throwable;");
CompileDirectMethod(NULL, "java.lang.Throwable","nativeFillInStackTrace","()Ljava/lang/Object;");
AssertStaticIntMethod(1579, LoadDex("IntMath"), "IntMath", "catchBlock", "(I)I", 1000);
+ AssertStaticIntMethod(7777, LoadDex("IntMath"), "IntMath", "catchBlock", "(I)I", 7000);
}
TEST_F(CompilerTest, CatchTestNoThrow) {
diff --git a/src/context_arm.cc b/src/context_arm.cc
index 85ada9d..0d25278 100644
--- a/src/context_arm.cc
+++ b/src/context_arm.cc
@@ -9,6 +9,7 @@
ArmContext::ArmContext() {
#ifndef NDEBUG
+ // Initialize registers with easy to spot debug values
for (int i=0; i < 16; i++) {
gprs_[i] = 0xEBAD6070+i;
}
diff --git a/src/context_x86.cc b/src/context_x86.cc
index 04976a5..479b950 100644
--- a/src/context_x86.cc
+++ b/src/context_x86.cc
@@ -8,9 +8,13 @@
namespace x86 {
X86Context::X86Context() {
+#ifndef NDEBUG
+ // Initialize registers with easy to spot debug values
for (int i=0; i < 8; i++) {
gprs_[i] = 0xEBAD6070+i;
}
+ eip_ = 0xEBAD601F;
+#endif
}
void X86Context::FillCalleeSaves(const Frame& fr) {
diff --git a/src/dex_file.cc b/src/dex_file.cc
index c17a225..7c54018 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -435,7 +435,6 @@
}
const DexFile::ClassDef* DexFile::FindClassDef(const StringPiece& descriptor) const {
- CHECK(!descriptor.empty());
Index::const_iterator it = index_.find(descriptor);
if (it == index_.end()) {
return NULL;
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index e0032b2..a800f20 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -3589,7 +3589,7 @@
}
DCHECK_LT(*start_guess, insns_size);
- DCHECK(InsnGetWidth(insn_flags, *start_guess) != 0);
+ DCHECK_NE(InsnGetWidth(insn_flags, *start_guess), 0);
return true;
}
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc
index 3e80c6b..8ad59b4 100644
--- a/src/java_lang_Class.cc
+++ b/src/java_lang_Class.cc
@@ -51,7 +51,7 @@
DCHECK(name->IsString());
Object* signature_obj = Decode<Object*>(env, jsignature);
DCHECK(signature_obj->IsArrayInstance());
- // check that this is a Class[] by checkin that component type is Class
+ // check that this is a Class[] by checking that component type is Class
// foo->GetClass()->GetClass() is an idiom for getting java.lang.Class from an arbitrary object
DCHECK(signature_obj->GetClass()->GetComponentType() == signature_obj->GetClass()->GetClass());
ObjectArray<Class>* signature = down_cast<ObjectArray<Class>*>(signature_obj);
@@ -80,8 +80,8 @@
return AddLocalReference<jobject>(env, method);
}
- for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
- Method* method = klass->GetVirtualMethod(i);
+ for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
+ Method* method = klass->GetDirectMethod(i);
if (!method->GetName()->Equals(name)) {
continue;
}
diff --git a/src/java_lang_System.cc b/src/java_lang_System.cc
index 4eaaa66..8aeefcd 100644
--- a/src/java_lang_System.cc
+++ b/src/java_lang_System.cc
@@ -185,7 +185,7 @@
const size_t width = sizeof(Object*);
if (dstComponentType->IsAssignableFrom(srcComponentType)) {
// Yes. Bulk copy.
- DCHECK_EQ(width, sizeof(uint32_t));
+ COMPILE_ASSERT(sizeof(width) == sizeof(uint32_t), move32_assumes_Object_references_are_32_bit);
move32(dstBytes + dstPos * width, srcBytes + srcPos * width, length * width);
Heap::WriteBarrier(dstArray);
return;
diff --git a/src/jni_compiler.cc b/src/jni_compiler.cc
index 9624246..4d454cf 100644
--- a/src/jni_compiler.cc
+++ b/src/jni_compiler.cc
@@ -273,7 +273,7 @@
}
// 9. Plant call to native code associated with method
- if (!jni_conv->IsMethodRegisterCrushedPreCall()) {
+ if (!jni_conv->IsMethodRegisterClobberedPreCall()) {
// Method register shouldn't have been crushed by setting up outgoing
// arguments
__ Call(mr_conv->MethodRegister(), Method::NativeMethodOffset(),
diff --git a/src/object.cc b/src/object.cc
index 6490797..63c9237 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -579,8 +579,14 @@
// assume that this is some initial value that will always lie in code
return true;
} else {
+#if defined(__arm__)
+ pc &= ~0x1; // clear any possible thumb instruction mode bit
+#endif
uint32_t rel_offset = pc - reinterpret_cast<uintptr_t>(GetCodeArray()->GetData());
- return rel_offset < static_cast<uint32_t>(GetCodeArray()->GetLength());
+ // Strictly the following test should be a less-than, however, if the last
+ // instruction is a call to an exception throw we may see return addresses
+ // that are 1 beyond the end of code.
+ return rel_offset <= static_cast<uint32_t>(GetCodeArray()->GetLength());
}
}
diff --git a/src/runtime_support.S b/src/runtime_support.S
index 8b904b8..5372742 100644
--- a/src/runtime_support.S
+++ b/src/runtime_support.S
@@ -127,7 +127,6 @@
.global art_deliver_exception
.extern artDeliverExceptionHelper
- .extern _ZN3art6Thread5self_E
/*
* Called by managed code, saves callee saves and then calls artThrowExceptionHelper
* that will place a mock Method* at the bottom of the stack.
diff --git a/src/runtime_support.h b/src/runtime_support.h
index 4915314..1f8da91 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -3,13 +3,15 @@
#ifndef ART_SRC_RUNTIME_SUPPORT_H_
#define ART_SRC_RUNTIME_SUPPORT_H_
+/* Helper for both JNI and regular compiled code */
+extern "C" void art_deliver_exception(void*);
+
#if defined(__arm__)
/* Compiler helpers */
extern "C" uint64_t art_shl_long(uint64_t, uint32_t);
extern "C" uint64_t art_shr_long(uint64_t, uint32_t);
extern "C" uint64_t art_ushr_long(uint64_t, uint32_t);
extern "C" void art_invoke_interface_trampoline(void*, void*, void*, void*);
- extern "C" void art_deliver_exception(void*);
/* Conversions */
extern "C" float __aeabi_i2f(int op1); // OP_INT_TO_FLOAT
@@ -45,8 +47,4 @@
#endif
-#if defined(__i386__)
-extern "C" void art_deliver_exception(void*);
-#endif
-
#endif // ART_SRC_RUNTIME_SUPPORT_H_
diff --git a/src/thread.cc b/src/thread.cc
index 92b3d4f..e1207d0 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -68,6 +68,10 @@
// Place a special frame at the TOS that will save all callee saves
*sp = thread->CalleeSaveMethod();
thread->SetTopOfStack(sp, 0);
+ if (exception == NULL) {
+ thread->ThrowNewException("Ljava/lang/NullPointerException;", "throw with null exception");
+ exception = thread->GetException();
+ }
thread->DeliverException(exception);
}
@@ -312,11 +316,8 @@
pLdivmod = __aeabi_ldivmod;
pLmul = __aeabi_lmul;
pInvokeInterfaceTrampoline = art_invoke_interface_trampoline;
- pDeliverException = art_deliver_exception;
#endif
-#if defined(__i386__)
pDeliverException = art_deliver_exception;
-#endif
pF2l = F2L;
pD2l = D2L;
pAllocFromCode = Array::AllocFromCode;
@@ -1304,8 +1305,8 @@
if (catch_finder.native_method_count_ == 1) {
PopSirt();
} else {
- // We only expect the stack crawl to have passed 1 native method as its terminated
- // by a up call
+ // We only expect the stack crawl to have passed 1 native method as it's terminated
+ // by an up call
DCHECK_EQ(catch_finder.native_method_count_, 0u);
}
long_jump_context->SetSP(reinterpret_cast<intptr_t>(catch_finder.handler_frame_.GetSP()));
diff --git a/test/IntMath/IntMath.java b/test/IntMath/IntMath.java
index 4c445b7..bffa894 100644
--- a/test/IntMath/IntMath.java
+++ b/test/IntMath/IntMath.java
@@ -103,10 +103,19 @@
throw new NullPointerException();
}
+ static void throwImplicitNullPointerException() {
+ throw null;
+ }
+
static int catchBlock(int x) {
try {
- x += 123;
- throwNullPointerException();
+ if (x == 1000) {
+ x += 123;
+ throwNullPointerException();
+ } else {
+ x += 321;
+ throwImplicitNullPointerException();
+ }
} catch (NullPointerException npe) {
x += 456;
}