diff options
| -rw-r--r-- | src/asm_support.h | 2 | ||||
| -rw-r--r-- | src/oat/runtime/support_proxy.cc | 20 | ||||
| -rw-r--r-- | src/oat/runtime/x86/runtime_support_x86.S | 35 | 
3 files changed, 44 insertions, 13 deletions
diff --git a/src/asm_support.h b/src/asm_support.h index 036e67c0f5..e776e531fc 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 cc375ad6a4..e4b7e362c7 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 @@ namespace art {  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 @@ extern "C" void artProxyInvokeHandler(Method* proxy_method, Object* receiver,      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 @@ extern "C" void artProxyInvokeHandler(Method* proxy_method, Object* receiver,        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 @@ extern "C" void artProxyInvokeHandler(Method* proxy_method, Object* receiver,      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 74ae8fcc78..d35afb70dd 100644 --- a/src/oat/runtime/x86/runtime_support_x86.S +++ b/src/oat/runtime/x86/runtime_support_x86.S @@ -358,6 +358,15 @@ MACRO0(RETURN_IF_EAX_ZERO)      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 @@ DEFINE_FUNCTION art_get32_instance_from_code      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 @@ DEFINE_FUNCTION art_get64_instance_from_code      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 @@ DEFINE_FUNCTION art_get_obj_instance_from_code      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 @@ DEFINE_FUNCTION art_get32_static_from_code      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 @@ DEFINE_FUNCTION art_get64_static_from_code      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 @@ DEFINE_FUNCTION art_get_obj_static_from_code      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 @@ VAR(name, 0):  END_MACRO      // TODO: implement these! -UNIMPLEMENTED art_proxy_invoke_handler  UNIMPLEMENTED art_update_debugger  UNIMPLEMENTED art_indexof  UNIMPLEMENTED art_memcmp16  |