harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r447098 - in /incubator/harmony/enhanced/drlvm/trunk/vm: port/src/lil/ia32/pim/stack_iterator_ia32.cpp vmcore/src/jvmti/jvmti_pop_frame.cpp
Date Sun, 17 Sep 2006 17:13:40 GMT
Author: geirm
Date: Sun Sep 17 10:13:39 2006
New Revision: 447098

URL: http://svn.apache.org/viewvc?view=rev&rev=447098
Log:
HARMONY-1454

PopFrame for the current thread
    
Implementation of PopFrame for the current thread, using which jvmti pop frame can be implemented.
Small fix of transfer control stub is included to provide ecx and edx restore. 

tested on ubuntu - smoke and c-unit


Modified:
    incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp?view=diff&rev=447098&r1=447097&r2=447098
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
(original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
Sun Sep 17 10:13:39 2006
@@ -116,7 +116,7 @@
         return addr;
     }
 
-    const int stub_size = 88;
+    const int stub_size = 64;
     char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_COLD,
CAA_Allocate);
 #ifdef _DEBUG
     memset(stub, 0xcc /*int 3*/, stub_size);
@@ -129,31 +129,63 @@
     // changing the esp at the very end of the sequence.
     //
 
-    // ecx will hold the final esp value
-    // edx will hold the pointer to the stack iterator
-
     M_Base_Opnd m1(esp_reg, 4);
     ss = mov(ss,  edx_opnd,  m1);
 
-    // Put esp inot ecx, and restore eax (return value)
-    ss = get_reg(ss, &eax_opnd, eax_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_eax);
+    ss = get_reg(ss, &ebx_opnd, ebx_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_eip);
+
     M_Base_Opnd m2(edx_reg, (int)&((StackIterator*)0)->c.esp);
     ss = mov(ss,  ecx_opnd,  m2);
 
-    // Restore callee saves registers
+    M_Base_Opnd m3(ecx_reg, -4);
+    ss = mov(ss,  m3,  ebx_opnd);
+
+    ss = alu(ss, sub_opc, ecx_opnd, Imm_Opnd(4));
+    ss = mov(ss,  m1,  ecx_opnd);
+
     ss = get_reg(ss, &esi_opnd, esi_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_esi);
     ss = get_reg(ss, &edi_opnd, edi_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_edi);
-    ss = get_reg(ss, &ebx_opnd, ebx_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_ebx);
     ss = get_reg(ss, &ebp_opnd, ebp_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_ebp);
 
-    // Now we are ready, grab the new IP, cut the stack, and jump
-    ss = get_reg(ss, &edx_opnd, edx_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_eip);
-    ss = mov(ss,  esp_opnd,  ecx_opnd);
-    ss = jump(ss,  edx_opnd);
+    ss = get_reg(ss, &eax_opnd, eax_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_eax);
+    ss = get_reg(ss, &ebx_opnd, ebx_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_ebx);
+    ss = get_reg(ss, &ecx_opnd, ecx_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_ecx);
+    ss = get_reg(ss, &edx_opnd, edx_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_edx);
+
+    ss = mov(ss,  esp_opnd,  m1);
+    ss = ret(ss);
 
     addr = (transfer_control_stub_type)stub;
     assert(ss-stub <= stub_size);
 
+    /*
+       The following code will be generated:
+
+        mov         edx,dword ptr [esp+4]
+        mov         ebx,dword ptr [edx+0Ch]
+        mov         ebx,dword ptr [ebx]
+        mov         ecx,dword ptr [edx+4]
+        mov         dword ptr [ecx-4],ebx
+        sub         ecx,4
+        mov         dword ptr [esp+4],ecx
+        mov         esi,dword ptr [edx+14h]
+        mov         esi,dword ptr [esi]
+        mov         edi,dword ptr [edx+10h]
+        mov         edi,dword ptr [edi]
+        mov         ebp,dword ptr [edx+8]
+        mov         ebp,dword ptr [ebp]
+        mov         eax,dword ptr [edx+1Ch]
+        mov         eax,dword ptr [eax]
+        mov         ebx,dword ptr [edx+18h]
+        mov         ebx,dword ptr [ebx]
+        mov         ecx,dword ptr [edx+20h]
+        mov         ecx,dword ptr [ecx]
+        mov         edx,dword ptr [edx+24h]
+        mov         edx,dword ptr [edx]
+        mov         esp,dword ptr [esp+4]
+        ret
+    */
+
     DUMP_STUB(stub, "getaddress__transfer_control", ss - stub);
 
     return addr;
@@ -419,8 +451,19 @@
 /* !!!! NO CXX LOGGER IS ALLOWED IN THIS FUNCTION !!!
  * !!!! RELEASE BUILD WILL BE BROKEN          !!!*/
     // 1. Copy si to stack
+    void* null_pointer = NULL;
     StackIterator local_si;
     memcpy(&local_si, si, sizeof(StackIterator));
+
+    if (NULL == si->c.p_eax)
+        local_si.c.p_eax = (uint32*)&null_pointer;
+    if (NULL == si->c.p_ebx)
+        local_si.c.p_ebx = (uint32*)&null_pointer;
+    if (NULL == si->c.p_ecx)
+        local_si.c.p_ecx = (uint32*)&null_pointer;
+    if (NULL == si->c.p_edx)
+        local_si.c.p_edx = (uint32*)&null_pointer;
+
     if (si->c.p_eip == &si->ip)
         local_si.c.p_eip = &local_si.ip;
     si_free(si);

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp?view=diff&rev=447098&r1=447097&r2=447098
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp Sun Sep
17 10:13:39 2006
@@ -25,9 +25,12 @@
 #include "exceptions.h"
 #include "environment.h"
 #include "vm_threads.h"
+#include "jit_intf_cpp.h"
 #include "m2n.h"
+#include "mon_enter_exit.h"
 #include "stack_iterator.h"
-#include "cxxlog.h"
+//#include "cxxlog.h"
+#include "clog.h"
 
 jvmtiError jvmti_jit_pop_frame(VM_thread *thread)
 {
@@ -61,21 +64,117 @@
     type = (frame_type) (type | FRAME_POP_NOW);
     m2n_set_frame_type(top_frame, type);
 
+    si_free(si);
+
     return JVMTI_ERROR_NONE;
 }
 
 void jvmti_jit_do_pop_frame()
 {
-    TRACE("jvmti_jit_do_pop_frame() is called");
+    // Destructive Unwinding!!! NO CXZ Logging put here.
+
+    // create stack iterator from native
+    StackIterator* si = si_create_from_native();
+    si_transfer_all_preserved_registers(si);
+
+    // pop native frame
+    assert(si_is_native(si));
+    si_goto_previous(si);
+
+    // save information about java frame
+    assert(!si_is_native(si));
+    CodeChunkInfo *cci = si_get_code_chunk_info(si);
+    JitFrameContext* jitContext = si_get_jit_context(si);
+
+    // save information about java method
+    assert(cci);
+    Method *method = cci->get_method();
+    Class* method_class = method->get_class();
+    bool is_method_static = method->is_static();
+
+    // free lock of synchronized method
+    /*
+    Currently JIT does not unlock monitors of synchronized blocks relying
+    on compiler which generates pseudo finally statement to unlock them.
+    For correct implementation of PopFrame these monitors will have to be
+    unlocked by VM, so JIT has to store information about these monitors
+    somewhere.
+    */
+    if (method->is_synchronized()) {
+        if (is_method_static) {
+            assert(!hythread_is_suspend_enabled());
+            TRACE2("tm.locks", ("unlock staic sync methods... "));
+            vm_monitor_exit(struct_Class_to_java_lang_Class(method->
+                    get_class()));
+            exn_clear();
+        } else {
+            JIT *jit = cci->get_jit();
+            void **p_this =
+                (void **) jit->get_address_of_this(method, jitContext);
+            TRACE2("tm.locks", ("unlock sync methods...%x" , *p_this));
+            vm_monitor_exit((ManagedObject *) * p_this);
+            exn_clear();
+        }
+    }
+
+    // pop java frame
+    si_goto_previous(si);
+
+    // find correct ip and restore required regiksters context
+    NativeCodePtr current_method_addr = NULL;
+    NativeCodePtr ip = si_get_ip(si);
+    size_t ip_reduce;
+
+    // invoke static
+    if (is_method_static) {
+        ip_reduce = 6;
+
+    // invoke interface
+    } else if (0xd0ff == (*((unsigned short*)(((char*)ip)-2)))) {
+        ip_reduce = 2;
+        current_method_addr = cci->get_code_block_addr();
+        jitContext->p_eax = (uint32*)&current_method_addr;
+
+    // invoke virtual and special
+    } else {
+        VTable_Handle vtable = class_get_vtable( method_class);
+        unsigned short code = (*((unsigned short*)(((char*)ip)-3)));
+
+        // invoke virtual
+        if (0x50ff == code) {
+            jitContext->p_eax = (uint32*) &vtable;
+            ip_reduce = 3;
+        } else if (0x51ff == code) {
+            jitContext->p_ecx = (uint32*) &vtable;
+            ip_reduce = 3;
+        } else if (0x52ff == code) {
+            jitContext->p_edx = (uint32*) &vtable;
+            ip_reduce = 3;
+        } else if (0x53ff == code) {
+            jitContext->p_ebx = (uint32*) &vtable;
+            ip_reduce = 3;
+
+        // invoke special
+        } else{
+            ip_reduce = 6;
+        }
+    }
+
+    // set corrrrect ip
+    ip = (NativeCodePtr)(((char*)ip) - ip_reduce);
+    si_set_ip(si, ip, false);
+
+    // transfer cdontrol
+    si_transfer_control(si);
 }
 
 void jvmti_safe_point()
 {
 //    __asm int 3;
-    TRACE("entering safe_point");
+    TRACE(("entering safe_point"));
     hythread_safe_point();
 
-    TRACE("left safe_point");
+    TRACE(("left safe_point"));
     frame_type type = m2n_get_frame_type(m2n_get_last_frame());
 
     if (FRAME_POP_NOW == (FRAME_POP_NOW & type))
@@ -84,7 +183,7 @@
 
 void jvmti_pop_frame_callback()
 {
-    TRACE("suspend_disable post callback...");
+    TRACE(("suspend_disable post callback..."));
     frame_type type = m2n_get_frame_type(p_TLS_vmthread->last_m2n_frame);
 
     if (FRAME_POP_NOW != (FRAME_POP_NOW & type))



Mime
View raw message