am d66a8758: Fix x86 slowpath getters and implement proxy.
* commit 'd66a87583bebcd5f89906aeaae9f8fb104ef2ac9':
Fix x86 slowpath getters and implement proxy.
diff --git a/src/asm_support.h b/src/asm_support.h
index 036e67c..e776e53 100644
--- a/src/asm_support.h
+++ b/src/asm_support.h
@@ -36,6 +36,8 @@
#elif defined(__i386__)
// Offset of field Thread::self_ verified in InitCpu
#define THREAD_SELF_OFFSET 112
+// Offset of field Thread::exception_ verified in InitCpu
+#define THREAD_EXCEPTION_OFFSET 120
#endif
#endif // ART_SRC_ASM_SUPPORT_H_
diff --git a/src/oat/runtime/support_proxy.cc b/src/oat/runtime/support_proxy.cc
index cc375ad..e4b7e36 100644
--- a/src/oat/runtime/support_proxy.cc
+++ b/src/oat/runtime/support_proxy.cc
@@ -22,6 +22,15 @@
#include "ScopedLocalRef.h"
+#if defined(__arm__)
+#define SP_OFFSET 12
+#define FRAME_SIZE_IN_BYTES 48u
+#elif defined(__i386__)
+#define SP_OFFSET 8
+#define FRAME_SIZE_IN_BYTES 32u
+#else
+#endif
+
namespace art {
// Handler for invocation on proxy methods. On entry a frame will exist for the proxy object method
@@ -31,11 +40,10 @@
extern "C" void artProxyInvokeHandler(Method* proxy_method, Object* receiver,
Thread* self, byte* stack_args) {
// Register the top of the managed stack
- Method** proxy_sp = reinterpret_cast<Method**>(stack_args - 12);
+ Method** proxy_sp = reinterpret_cast<Method**>(stack_args - SP_OFFSET);
DCHECK_EQ(*proxy_sp, proxy_method);
self->SetTopOfStack(proxy_sp, 0);
- // TODO: ARM specific
- DCHECK_EQ(proxy_method->GetFrameSizeInBytes(), 48u);
+ DCHECK_EQ(proxy_method->GetFrameSizeInBytes(), FRAME_SIZE_IN_BYTES);
// Start new JNI local reference state
JNIEnvExt* env = self->GetJniEnv();
ScopedJniEnvLocalRefState env_state(env);
@@ -67,7 +75,7 @@
param_index++;
}
// Placing into local references incoming arguments from the caller's stack arguments
- cur_arg += 11; // skip callee saves, LR, Method* and out arg spills for R1 to R3
+ cur_arg += FRAME_SIZE_IN_BYTES / 4 - 1; // skip callee saves, LR, Method* and out arg spills for R1 to R3
while (param_index < num_params) {
if (proxy_mh.IsParamAReference(param_index)) {
Object* obj = *reinterpret_cast<Object**>(stack_args + (cur_arg * kPointerSize));
@@ -117,7 +125,7 @@
JValue val = *reinterpret_cast<JValue*>(stack_args + (cur_arg * kPointerSize));
if (cur_arg == 1 && (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble())) {
// long/double split over regs and stack, mask in high half from stack arguments
- uint64_t high_half = *reinterpret_cast<uint32_t*>(stack_args + (13 * kPointerSize));
+ uint64_t high_half = *reinterpret_cast<uint32_t*>(stack_args + ((FRAME_SIZE_IN_BYTES / 4 + 1) * kPointerSize));
val.SetJ((val.GetJ() & 0xffffffffULL) | (high_half << 32));
}
BoxPrimitive(param_type->GetPrimitiveType(), val);
@@ -131,7 +139,7 @@
param_index++;
}
// Placing into local references incoming arguments from the caller's stack arguments
- cur_arg += 11; // skip callee saves, LR, Method* and out arg spills for R1 to R3
+ cur_arg += FRAME_SIZE_IN_BYTES / 4 - 1; // skip callee saves, LR, Method* and out arg spills for R1 to R3
while (param_index < (num_params - 1)) {
Class* param_type = param_types->Get(param_index);
Object* obj;
diff --git a/src/oat/runtime/x86/runtime_support_x86.S b/src/oat/runtime/x86/runtime_support_x86.S
index 74ae8fcc..d35afb7 100644
--- a/src/oat/runtime/x86/runtime_support_x86.S
+++ b/src/oat/runtime/x86/runtime_support_x86.S
@@ -358,6 +358,15 @@
DELIVER_PENDING_EXCEPTION
END_MACRO
+MACRO0(RETURN_OR_DELIVER_PENDING_EXCEPTION)
+ mov %fs:THREAD_EXCEPTION_OFFSET, %ebx // get exception field
+ testl %ebx, %ebx // ebx == 0 ?
+ jnz 1f // if ebx != 0 goto 1
+ ret // return
+1: // deliver exception on current thread
+ DELIVER_PENDING_EXCEPTION
+END_MACRO
+
TWO_ARG_DOWNCALL art_alloc_object_from_code, artAllocObjectFromCode, RETURN_IF_EAX_NOT_ZERO
TWO_ARG_DOWNCALL art_alloc_object_from_code_with_access_check, artAllocObjectFromCodeWithAccessCheck, RETURN_IF_EAX_NOT_ZERO
THREE_ARG_DOWNCALL art_alloc_array_from_code, artAllocArrayFromCode, RETURN_IF_EAX_NOT_ZERO
@@ -592,7 +601,7 @@
call SYMBOL(artGet32InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
addl LITERAL(32), %esp // pop arguments
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_IF_EAX_ZERO // return or deliver exception
+ RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
DEFINE_FUNCTION art_get64_instance_from_code
SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
@@ -607,7 +616,7 @@
call SYMBOL(artGet64InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
addl LITERAL(32), %esp // pop arguments
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_IF_EAX_ZERO // return or deliver exception
+ RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
DEFINE_FUNCTION art_get_obj_instance_from_code
SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
@@ -622,7 +631,7 @@
call SYMBOL(artGetObjInstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
addl LITERAL(32), %esp // pop arguments
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_IF_EAX_ZERO // return or deliver exception
+ RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
DEFINE_FUNCTION art_set32_static_from_code
SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
@@ -681,7 +690,7 @@
call SYMBOL(artGet32StaticFromCode) // (field_idx, referrer, Thread*, SP)
addl LITERAL(16), %esp // pop arguments
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_IF_EAX_ZERO // return or deliver exception
+ RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
DEFINE_FUNCTION art_get64_static_from_code
SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
@@ -694,7 +703,7 @@
call SYMBOL(artGet64StaticFromCode) // (field_idx, referrer, Thread*, SP)
addl LITERAL(16), %esp // pop arguments
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_IF_EAX_ZERO // return or deliver exception
+ RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
DEFINE_FUNCTION art_get_obj_static_from_code
SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
@@ -707,7 +716,20 @@
call SYMBOL(artGetObjStaticFromCode) // (field_idx, referrer, Thread*, SP)
addl LITERAL(16), %esp // pop arguments
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_IF_EAX_ZERO // return or deliver exception
+ RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
+
+DEFINE_FUNCTION art_proxy_invoke_handler
+ SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame
+ lea 8(%esp), %ebx // pointer to r2/r3/LR/caller's Method**/out-args as second arg
+ pushl %ebx // pass args
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ pushl %ecx // pass receiver
+ pushl %eax // pass proxy method
+ call SYMBOL(artProxyInvokeHandler) // (proxy method, receiver, Thread*, args...)
+ mov 24(%esp), %eax // get ret0 which was written into r2 on the stack
+ mov 28(%esp), %edx // get ret1 which was written into r3 on the stack
+ addl LITERAL(44), %esp // pop arguments
+ RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
MACRO1(UNIMPLEMENTED,name)
.globl VAR(name, 0)
@@ -717,7 +739,6 @@
END_MACRO
// TODO: implement these!
-UNIMPLEMENTED art_proxy_invoke_handler
UNIMPLEMENTED art_update_debugger
UNIMPLEMENTED art_indexof
UNIMPLEMENTED art_memcmp16