You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2006/10/03 14:53:48 UTC

svn commit: r452466 - in /incubator/harmony/enhanced/drlvm/trunk/vm: port/include/ port/src/lil/em64t/pim/ port/src/lil/ia32/pim/ port/src/lil/ipf/pim/ vmcore/include/ vmcore/src/exception/ vmcore/src/jvmti/

Author: geirm
Date: Tue Oct  3 05:53:47 2006
New Revision: 452466

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

When throwing an exception, MethodExit event callback is called for every frame unwinded from the java stack. Though 
calling GetFrameLocation() from the callback returns information based on the state before exception throwing. Such 
behaviour contradicts JVMTI spec for MethodExit event..

Usual - ubuntu6, smoke, c-unit, ~kernel

We need JVMTI tests :)


Modified:
    incubator/harmony/enhanced/drlvm/trunk/vm/port/include/m2n.h
    incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/port/include/m2n.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/port/include/m2n.h?view=diff&rev=452466&r1=452465&r2=452466
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/port/include/m2n.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/port/include/m2n.h Tue Oct  3 05:53:47 2006
@@ -54,7 +54,9 @@
 
     FRAME_POP_MASK = 0x0700,
 
-    FRAME_SAFE_POINT = 0x0800
+    FRAME_SAFE_POINT = 0x0800,
+
+    FRAME_MODIFIED_STACK = 0x1000
 };
 
 // The pushing and popping of native frames is done only by stubs that

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp?view=diff&rev=452466&r1=452465&r2=452466
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp Tue Oct  3 05:53:47 2006
@@ -345,7 +345,6 @@
 
 void si_copy_to_registers(StackIterator * si, Registers * regs) {
     ASSERT_NO_INTERPRETER    
-    m2n_set_last_frame(si->m2n_frame);
 
     regs->rsp = si->jit_frame_context.rsp;
     regs->rbp = *si->jit_frame_context.p_rbp;

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=452466&r1=452465&r2=452466
==============================================================================
--- 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 Tue Oct  3 05:53:47 2006
@@ -89,7 +89,7 @@
         si->c.p_edi = &m2nfl->regs->edi;
         si->c.p_ebp = &m2nfl->regs->ebp;
     } else if (over_popped &&
-            (FRAME_POP_DONE == (FRAME_POP_MASK & m2n_get_frame_type(m2nfl)))) {
+            (FRAME_MODIFIED_STACK == (FRAME_MODIFIED_STACK & m2n_get_frame_type(m2nfl)))) {
         si->c.esp = m2nfl->pop_regs->esp;
         si->c.p_eip = &(m2nfl->pop_regs->eip);
         si->c.is_ip_past = FALSE;
@@ -495,17 +495,23 @@
     tcs(&local_si);
 }
 
+inline static uint32 unref_reg(uint32* p_reg) {
+    return p_reg ? *p_reg : 0;
+}
+
 void si_copy_to_registers(StackIterator* si, Registers* regs)
 {
     ASSERT_NO_INTERPRETER
-    m2n_set_last_frame(si->m2nfl);
+
     regs->esp = si->c.esp;
-    regs->eip = *si->c.p_eip;
-    regs->ebp = *si->c.p_ebp;
-    regs->edi = *si->c.p_edi;
-    regs->esi = *si->c.p_esi;
-    regs->ebx = *si->c.p_ebx;
-    regs->eax = *si->c.p_eax;
+    regs->eip = unref_reg(si->c.p_eip);
+    regs->ebp = unref_reg(si->c.p_ebp);
+    regs->edi = unref_reg(si->c.p_edi);
+    regs->esi = unref_reg(si->c.p_esi);
+    regs->edx = unref_reg(si->c.p_edx);
+    regs->ecx = unref_reg(si->c.p_ecx);
+    regs->ebx = unref_reg(si->c.p_ebx);
+    regs->eax = unref_reg(si->c.p_eax);
 }
 
 void si_set_callbak(StackIterator* si, NativeCodePtr* callback) {

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp?view=diff&rev=452466&r1=452465&r2=452466
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp Tue Oct  3 05:53:47 2006
@@ -618,7 +618,6 @@
 void si_copy_to_registers(StackIterator* si, Registers*)
 {
     ABORT("Not implemented");
-    m2n_set_last_frame(si->m2nfl);
 }
 
 extern "C" void do_loadrs_asm(int loadrs);

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h?view=diff&rev=452466&r1=452465&r2=452466
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h Tue Oct  3 05:53:47 2006
@@ -132,6 +132,7 @@
     NativeCodePtr native_catch_location);
 VMEXPORT void jvmti_process_method_entry_event(jmethodID method);
 VMEXPORT void jvmti_process_method_exit_event(jmethodID method, jboolean exn_flag, jvalue ret_val);
+VMEXPORT void jvmti_process_method_exception_exit_event(jmethodID method, jboolean exn_flag, jvalue ret_val, StackIterator* si);
 VMEXPORT void jvmti_process_field_access_event(Field_Handle field,
     jmethodID method, jlocation location, ManagedObject* object);
 VMEXPORT void jvmti_process_field_modification_event(Field_Handle field,

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp?view=diff&rev=452466&r1=452465&r2=452466
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp Tue Oct  3 05:53:47 2006
@@ -339,8 +339,8 @@
 
         BEGIN_RAISE_AREA;
         jvalue ret_val = {(jlong)0};
-        jvmti_process_method_exit_event(reinterpret_cast<jmethodID>(method),
-            JNI_TRUE, ret_val);
+        jvmti_process_method_exception_exit_event(
+            reinterpret_cast<jmethodID>(method), JNI_TRUE, ret_val, si);
         END_RAISE_AREA;
 
         // Goto previous frame
@@ -469,6 +469,7 @@
     ManagedObject *local_exn_obj = NULL;
     exn_propagate_exception(si, &local_exn_obj, exn_class, NULL, NULL, NULL);
     si_copy_to_registers(si, regs);
+    m2n_set_last_frame(si_get_m2n(si));
     si_free(si);
     STD_FREE(m2nf);
 #endif

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp?view=diff&rev=452466&r1=452465&r2=452466
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp Tue Oct  3 05:53:47 2006
@@ -38,6 +38,8 @@
 #include "vm_log.h"
 #include "compile.h"
 #include "jvmti_break_intf.h"
+#include "stack_iterator.h"
+#include "m2n.h"
 
 /*
  * Set Event Callbacks
@@ -658,20 +660,12 @@
     tmn_suspend_disable();
 }
 
-VMEXPORT void
-jvmti_process_method_exit_event(jmethodID method, jboolean was_popped_by_exception, jvalue ret_val) {
-    SuspendDisabledChecker sdc;
-
+static void
+jvmti_process_method_exit_event_internal(jmethodID method,
+                                         jboolean was_popped_by_exception,
+                                         jvalue ret_val)
+{
     DebugUtilsTI *ti = VM_Global_State::loader_env->TI;
-    if (!ti->isEnabled() )
-        return;
-
-    if (JVMTI_PHASE_LIVE != ti->getPhase())
-        return;
-
-    if (!ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_METHOD_EXIT))
-        return;
-
     tmn_suspend_enable();
     jvmtiEvent event_type = JVMTI_EVENT_METHOD_EXIT;
     hythread_t curr_native_thread = hythread_self();
@@ -700,7 +694,6 @@
         jthread thread = getCurrentThread();
         JNIEnv *jni_env = (JNIEnv *)jni_native_intf;
         jvmtiEnv *jvmti_env = (jvmtiEnv*) ti_env;
-
         if (NULL != ti_env->event_table.MethodExit)
             ti_env->event_table.MethodExit(jvmti_env, jni_env, thread, method, was_popped_by_exception, ret_val);
         ti_env = next_env;
@@ -720,28 +713,99 @@
     }
 
     VM_thread *curr_thread = p_TLS_vmthread;
-    jvmti_frame_pop_listener *fpl = curr_thread->frame_pop_listener;
     jint UNREF skip;
     jint depth = get_thread_stack_depth(curr_thread, &skip);
 
-    while (fpl)
+    jvmti_frame_pop_listener *last = NULL;
+    for( jvmti_frame_pop_listener *fpl = curr_thread->frame_pop_listener;
+         fpl;
+         last = fpl, (fpl = fpl ? fpl->next : curr_thread->frame_pop_listener) )
     {
-        jvmti_frame_pop_listener *next_fpl = fpl->next;
         if (fpl->depth == depth)
         {
+            jvmti_frame_pop_listener *report = fpl;
+            if(last) {
+                last->next = fpl->next;
+            } else {
+                curr_thread->frame_pop_listener = fpl->next;
+            }
+            fpl = last;
+
+            TRACE2("jvmti.stack", "Calling PopFrame callback for thread: "
+                << curr_thread << ", listener: " << report
+                << ", env: " << report->env << ", depth: " << report->depth
+                << " -> " << class_get_name(method_get_class((Method*)method))
+                << "." << method_get_name((Method*)method)
+                << method_get_descriptor((Method*)method));
+
             jvmti_process_frame_pop_event(
-                reinterpret_cast<jvmtiEnv *>(fpl->env),
+                reinterpret_cast<jvmtiEnv *>(report->env),
                 method,
                 was_popped_by_exception);
-            if( fpl == curr_thread->frame_pop_listener ) {
-                curr_thread->frame_pop_listener = fpl->next;
-            }
-            STD_FREE(fpl);
+            STD_FREE(report);
         }
-        fpl = next_fpl;
     }
 
     tmn_suspend_disable();
+}
+
+VMEXPORT void
+jvmti_process_method_exit_event(jmethodID method,
+                                jboolean was_popped_by_exception,
+                                jvalue ret_val)
+{
+    SuspendDisabledChecker sdc;
+
+    DebugUtilsTI *ti = VM_Global_State::loader_env->TI;
+    if (!ti->isEnabled() )
+        return;
+
+    if (JVMTI_PHASE_LIVE != ti->getPhase())
+        return;
+
+    if (!ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_METHOD_EXIT))
+        return;
+
+    // process method exit event
+    jvmti_process_method_exit_event_internal(method, was_popped_by_exception, ret_val);
+}
+
+VMEXPORT void
+jvmti_process_method_exception_exit_event(jmethodID method,
+                                          jboolean was_popped_by_exception,
+                                          jvalue ret_val,
+                                          StackIterator* si)
+{
+    SuspendDisabledChecker sdc;
+
+    DebugUtilsTI *ti = VM_Global_State::loader_env->TI;
+    if (!ti->isEnabled() )
+        return;
+
+    if (JVMTI_PHASE_LIVE != ti->getPhase())
+        return;
+
+    if (!ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_METHOD_EXIT))
+        return;
+
+    // save context from stack interation to m2n frame
+    Registers regs;
+    si_copy_to_registers(si, &regs);
+    M2nFrame* m2nf = m2n_get_last_frame();
+    set_pop_frame_registers(m2nf, &regs);
+    
+    // save old type of m2n frame
+    frame_type old_type = m2n_get_frame_type(m2nf);
+    
+    // enable modified stack context in m2n frame 
+    m2n_set_frame_type(m2nf, frame_type(FRAME_MODIFIED_STACK | old_type));
+
+    // process method exit event
+    jvmti_process_method_exit_event_internal(method, was_popped_by_exception, ret_val);
+
+    // restore old frame type and switch off context modification
+    m2n_set_frame_type(m2nf, old_type);
+    set_pop_frame_registers(m2nf, NULL);
 }
 
 VMEXPORT void

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=452466&r1=452465&r2=452466
==============================================================================
--- 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 Tue Oct  3 05:53:47 2006
@@ -316,7 +316,7 @@
     }
 
     // set pop done frame state
-    m2n_set_frame_type(top_frame, FRAME_POP_DONE);
+    m2n_set_frame_type(top_frame, frame_type(FRAME_POP_DONE | FRAME_MODIFIED_STACK));
     return;
 }