summaryrefslogtreecommitdiff
path: root/src/compiler_llvm/method_compiler.cc
diff options
context:
space:
mode:
author Logan Chien <loganchien@google.com> 2012-05-23 18:37:44 +0800
committer Shih-wei Liao <sliao@google.com> 2012-05-23 08:46:36 -0700
commit82d31cdf122c284ca9c3b4292f09edc9b13a2970 (patch)
tree0aeaf341f53fbc42a81cce090da3cf57293b16fa /src/compiler_llvm/method_compiler.cc
parentd66a87583bebcd5f89906aeaae9f8fb104ef2ac9 (diff)
Fix invoke-direct and invoke-direct/range CTS.
Change-Id: I224d438f1cc74c72cb3c7edee26e2fab0e3bcee6
Diffstat (limited to 'src/compiler_llvm/method_compiler.cc')
-rw-r--r--src/compiler_llvm/method_compiler.cc25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index c29e458d9f..2781598906 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -2765,16 +2765,13 @@ void MethodCompiler::EmitInsn_Invoke(uint32_t dex_pc,
invoke_type, vtable_idx, direct_code, direct_method);
// Load *this* actual parameter
+ uint32_t this_reg = -1u;
llvm::Value* this_addr = NULL;
if (!is_static) {
// Test: Is *this* parameter equal to null?
- uint32_t reg_idx = (arg_fmt == kArgReg) ? dec_insn.arg[0] : (dec_insn.vC + 0);
- this_addr = EmitLoadDalvikReg(reg_idx, kObject, kAccurate);
-
- if (!(method_info_.this_will_not_be_null && reg_idx == method_info_.this_reg_idx)) {
- EmitGuard_NullPointerException(dex_pc, this_addr);
- }
+ this_reg = (arg_fmt == kArgReg) ? dec_insn.arg[0] : (dec_insn.vC + 0);
+ this_addr = EmitLoadDalvikReg(this_reg, kObject, kAccurate);
}
// Load the method object
@@ -2784,7 +2781,23 @@ void MethodCompiler::EmitInsn_Invoke(uint32_t dex_pc,
callee_method_object_addr =
EmitCallRuntimeForCalleeMethodObjectAddr(callee_method_idx, invoke_type,
this_addr, dex_pc, is_fast_path);
+
+ if (!is_static && (!method_info_.this_will_not_be_null ||
+ this_reg != method_info_.this_reg_idx)) {
+ // NOTE: The null pointer test should come after the method resolution.
+ // So that the "NoSuchMethodError" can be thrown before the
+ // "NullPointerException".
+ EmitGuard_NullPointerException(dex_pc, this_addr);
+ }
+
} else {
+ if (!is_static && (!method_info_.this_will_not_be_null ||
+ this_reg != method_info_.this_reg_idx)) {
+ // NOTE: In the fast path, we should do the null pointer check
+ // before the access to the class object and/or direct invocation.
+ EmitGuard_NullPointerException(dex_pc, this_addr);
+ }
+
switch (invoke_type) {
case kStatic:
case kDirect: