harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r449227 - in /incubator/harmony/enhanced/drlvm/trunk/vm/vmcore: include/jvmti_internal.h src/exception/exceptions_jit.cpp src/jvmti/jvmti_break.cpp src/jvmti/jvmti_event.cpp src/jvmti/jvmti_pop_frame.cpp src/jvmti/jvmti_step.cpp
Date Sat, 23 Sep 2006 12:53:27 GMT
Author: geirm
Date: Sat Sep 23 05:53:26 2006
New Revision: 449227

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

The following scenario doesn't work:
Do SingleStep for method. Stop in the middle of method. Do PopFrame. Try to enter into the
method again.

It happens because SingleStep event isn't reported for new IP locations when TI agent does
PopFrame.
This patch depends on previous implementation of SingleStep and PopFrame.

Ubuntu 6 - smoke and c-unit



Modified:
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.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
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h?view=diff&rev=449227&r1=449226&r2=449227
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h Sat Sep 23 05:53:26
2006
@@ -93,6 +93,7 @@
 {
     struct Method* method;
     unsigned location;
+    NativeCodePtr native_location;
 };
 
 struct JVMTISingleStepState

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=449227&r1=449226&r2=449227
==============================================================================
--- 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 Sat
Sep 23 05:53:26 2006
@@ -272,12 +272,12 @@
                         LMAutoUnlock lock(&ti->brkpntlst_lock);
 
                         uint16 bc;
+                        NativeCodePtr ip = handler->get_handler_ip();
                         OpenExeJpdaError UNREF result =
-                            jit->get_bc_location_for_native(
-                                method, handler->get_handler_ip(), &bc);
+                            jit->get_bc_location_for_native(method, ip, &bc);
                         assert(EXE_ERROR_NONE == result);
 
-                        jvmti_StepLocation method_start = {(Method *)method, bc};
+                        jvmti_StepLocation method_start = {(Method *)method, bc, ip};
 
                         jvmtiError UNREF errorCode =
                             jvmti_set_single_step_breakpoints(ti, vm_thread,

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp?view=diff&rev=449227&r1=449226&r2=449227
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp Sat Sep 23
05:53:26 2006
@@ -497,19 +497,21 @@
 {
     // Function is always executed under global TI breakpoints lock
     // Find native location in the method code
-    NativeCodePtr np = NULL;
     Method *m = (Method *)bp->method;
     assert( m->get_state() == Method::ST_Compiled );
 
-    OpenExeJpdaError res = EXE_ERROR_NONE;
-    for (CodeChunkInfo* cci = m->get_first_JIT_specific_info(); cci; cci = cci->_next)
-    {
-        JIT *jit = cci->get_jit();
-        res = jit->get_native_location_for_bc(m, (uint16)bp->location, &np);
-        if (res == EXE_ERROR_NONE)
-            break;
+    NativeCodePtr np = bp->native_location;
+    if( !np ) {
+        OpenExeJpdaError res = EXE_ERROR_NONE;
+        for (CodeChunkInfo* cci = m->get_first_JIT_specific_info(); cci; cci = cci->_next)
+        {
+            JIT *jit = cci->get_jit();
+            res = jit->get_native_location_for_bc(m, (uint16)bp->location, &np);
+            if (res == EXE_ERROR_NONE)
+                break;
+        }
+        assert(res == EXE_ERROR_NONE);
     }
-    assert(res == EXE_ERROR_NONE);
 
     if (NULL == np)
         return JVMTI_ERROR_INTERNAL;

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=449227&r1=449226&r2=449227
==============================================================================
--- 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 Sat Sep 23
05:53:26 2006
@@ -315,6 +315,7 @@
 
                 if (JVMTI_ENABLE == mode && !ti->is_single_step_enabled())
                 {
+                    TRACE2("jvmti.break.ss", "SingleStep event is enabled");
                     jvmtiError errorCode = ti->jvmti_single_step_start();
 
                     if (JVMTI_ERROR_NONE != errorCode)
@@ -323,6 +324,7 @@
                 else if (JVMTI_DISABLE == mode && ti->is_single_step_enabled())
                 {
                     // Check that no environment has SingleStep enabled
+                    TRACE2("jvmti.break.ss", "SingleStep event is disabled");
                     LMAutoUnlock lock(&ti->TIenvs_lock);
                     bool disable = true;
 

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=449227&r1=449226&r2=449227
==============================================================================
--- 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 Sat Sep
23 05:53:26 2006
@@ -34,31 +34,33 @@
 
 static void jvmti_pop_frame_callback()
 {
-    TRACE(("--->>>  JVMTI pop frame callback..."));
+    TRACE(("JVMTI PopFrame callback is called"));
     frame_type type = m2n_get_frame_type(p_TLS_vmthread->last_m2n_frame);
 
     // frame wasn't requested to be popped
-    if (FRAME_POP_NOW != (FRAME_POP_NOW & type))
+    if (FRAME_POP_NOW != (FRAME_POP_NOW & type)) {
+        TRACE(("PopFrame callback is not FRAME_POP_NOW"));
         return;
+    }
 
     // if we are in hythread_safe_point() frame is unwindable
     if (FRAME_SAFE_POINT == (FRAME_SAFE_POINT & type)) {
+        TRACE(("PopFrame callback is FRAME_SAFE_POINT"));
         jvmti_jit_prepare_pop_frame();
 
-    // if we in unwindable frame
     } else if (is_unwindable()) {
-        // wait for resume
-        TRACE(("entering safe_point"));
+        // unwindable frame, wait for resume
+        TRACE(("PopFrame callback is entering safe_point"));
         hythread_safe_point();
-        TRACE(("left safe_point"));
+        TRACE(("PopFrame callback is FRAME_SAFE_POINT"));
 
         // switch execution to the previous frame
         jvmti_jit_do_pop_frame();
         assert(0 /* mustn't get here */);
 
-    // if we in nonunwindable frame
     } else {
-        // raise special exception object
+        // nonunwindable frame, raise special exception object
+        TRACE(("PopFrame callback is raising exception"));
         exn_raise_object(VM_Global_State::loader_env->popFrameException);
     }
 } //jvmti_pop_frame_callback
@@ -66,6 +68,7 @@
 jvmtiError jvmti_jit_pop_frame(jthread java_thread)
 {
     assert(hythread_is_suspend_enabled());
+    TRACE(("Called PopFrame for JIT"));
 
     DebugUtilsTI *ti = VM_Global_State::loader_env->TI;
 
@@ -90,6 +93,11 @@
     // go to 2-d frame & check it's managed
     si_goto_previous(si);
     assert(! si_is_native(si));
+    TRACE(("PopFrame is called for method %s.%s%s :%p",
+        class_get_name(method_get_class(si_get_code_chunk_info(si)->get_method())),
+        method_get_name(si_get_code_chunk_info(si)->get_method()),
+        method_get_descriptor(si_get_code_chunk_info(si)->get_method()),
+        si_get_ip(si) ));
 
     // go to 3-d frame & check its type
     si_goto_previous(si);
@@ -146,6 +154,7 @@
 
 // requires stack iterator and buffer to save intermediate information
 static void jvmti_jit_prepare_pop_frame(StackIterator* si, uint32* buf) {
+    TRACE(("Prepare PopFrame for JIT"));
     // pop native frame
     assert(si_is_native(si));
     si_goto_previous(si);
@@ -160,6 +169,10 @@
     Method *method = cci->get_method();
     Class* method_class = method->get_class();
     bool is_method_static = method->is_static();
+    TRACE(("PopFrame method %s.%s%s, stop IP: %p",
+        class_get_name(method_get_class(cci->get_method())),
+        method_get_name(cci->get_method()),
+        method_get_descriptor(cci->get_method()), si_get_ip(si) ));
 
     // free lock of synchronized method
     /*
@@ -192,6 +205,10 @@
     // find correct ip and restore required regiksters context
     NativeCodePtr current_method_addr = NULL;
     NativeCodePtr ip = si_get_ip(si);
+    TRACE(("PopFrame method %s.%s%s, set IP begin: %p",
+        class_get_name(method_get_class(si_get_code_chunk_info(si)->get_method())),
+        method_get_name(si_get_code_chunk_info(si)->get_method()),
+        method_get_descriptor(si_get_code_chunk_info(si)->get_method()), ip ));
     size_t ip_reduce;
 
     // invoke static
@@ -233,6 +250,10 @@
 
     // set corrrrect ip
     ip = (NativeCodePtr)(((char*)ip) - ip_reduce);
+    TRACE(("PopFrame method %s.%s%s, set IP end: %p",
+        class_get_name(method_get_class(si_get_code_chunk_info(si)->get_method())),
+        method_get_name(si_get_code_chunk_info(si)->get_method()),
+        method_get_descriptor(si_get_code_chunk_info(si)->get_method()), ip ));
     si_set_ip(si, ip, false);
 }
 
@@ -248,6 +269,11 @@
     // create stack iterator from native
     StackIterator* si = si_create_from_native();
     si_transfer_all_preserved_registers(si);
+    TRACE(("PopFrame prepare for method %s.%s%s, IP: %p",
+        class_get_name(method_get_class(si_get_code_chunk_info(si)->get_method())),
+        method_get_name(si_get_code_chunk_info(si)->get_method()),
+        method_get_descriptor(si_get_code_chunk_info(si)->get_method()),
+        si_get_ip(si) ));
 
     // preare pop frame - find regs values
     uint32 buf = 0;
@@ -289,10 +315,44 @@
 
     // set pop done frame state
     m2n_set_frame_type(top_frame, FRAME_POP_DONE);
+    return;
 }
 
+static void
+jvmti_relocate_single_step_breakpoints( StackIterator *si)
+{
+    // relocate single step
+    DebugUtilsTI *ti = VM_Global_State::loader_env->TI;
+    if (ti->isEnabled() && ti->is_single_step_enabled())
+    {
+        VM_thread *vm_thread = p_TLS_vmthread;
+        if (NULL != vm_thread->ss_state) {
+            // remove old single step breakpoints
+            LMAutoUnlock lock(&ti->brkpntlst_lock);
+            jvmti_remove_single_step_breakpoints(ti, vm_thread);
+
+            // set new single step breakpoints
+            CodeChunkInfo *cci = si_get_code_chunk_info(si);
+            Method *method = cci->get_method();
+            NativeCodePtr ip = si_get_ip(si);
+            uint16 bc;
+            JIT *jit = cci->get_jit();
+            OpenExeJpdaError UNREF result =
+                jit->get_bc_location_for_native(method, ip, &bc);
+            assert(EXE_ERROR_NONE == result);
+
+            jvmti_StepLocation locations = {method, bc, ip};
+            jvmtiError UNREF error = jvmti_set_single_step_breakpoints(ti, vm_thread,
+                &locations, 1);
+            assert( error == JVMTI_ERROR_NONE);
+        }
+    }
+    return;
+} // jvmti_relocate_single_step_breakpoints
+
 void jvmti_jit_complete_pop_frame() {
     // Destructive Unwinding!!! NO CXX Logging put here.
+    TRACE(("Complite PopFrame for JIT"));
 
     // Find top m2n frame
     M2nFrame* top_frame = m2n_get_last_frame();
@@ -309,12 +369,17 @@
     assert(si_is_native(si));
     si_goto_previous(si);
 
+    // relocate single step breakpoints
+    jvmti_relocate_single_step_breakpoints(si);
+
     // transfer cdontrol
+    TRACE(("PopFrame transfer control to: %p",  (void*)si_get_ip(si) ));
     si_transfer_control(si);
 }
 
 void jvmti_jit_do_pop_frame() {
     // Destructive Unwinding!!! NO CXX Logging put here.
+    TRACE(("Do PopFrame for JIT"));
 
     // Find top m2n frame
     M2nFrame* top_frame = m2n_get_last_frame();
@@ -331,7 +396,11 @@
     uint32 buf = 0;
     jvmti_jit_prepare_pop_frame(si, &buf);
 
+    // relocate single step breakpoints
+    jvmti_relocate_single_step_breakpoints(si);
+
     // transfer cdontrol
+    TRACE(("PopFrame transfer control to: %p",  (void*)si_get_ip(si) ));
     si_transfer_control(si);
 }
 #endif // _IA32_

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp?view=diff&rev=449227&r1=449226&r2=449227
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp Sat Sep 23 05:53:26
2006
@@ -53,7 +53,7 @@
 {
     ASSERT_NO_INTERPRETER;
 
-#if PLATFORM_NT
+#if _IA32_
     // create stack iterator from native
     StackIterator* si = si_create_from_native( thread );
     si_transfer_all_preserved_registers(si);
@@ -91,10 +91,10 @@
     Method *method = class_get_method_from_vt_offset( vtable, *((char*)ip + 2) );
     return method;
 
-#else // for PLATFORM_POSIX
+#else // for !_IA32_
 
     return NULL;
-#endif // PLATFORM_NT
+#endif // _IA32_
 } // jvmti_get_invoked_virtual_method
 
 void
@@ -160,8 +160,10 @@
             assert( error == JVMTI_ERROR_NONE );
             (*next_step)[0].method = method;
             (*next_step)[0].location = location;
+            (*next_step)[0].native_location = NULL;
             (*next_step)[1].method = method;
             (*next_step)[1].location = offset;
+            (*next_step)[1].native_location = NULL;
             break;
 
         // goto instructions
@@ -174,6 +176,7 @@
             assert( error == JVMTI_ERROR_NONE );
             (*next_step)->method = method;
             (*next_step)->location = offset;
+            (*next_step)->native_location = NULL;
             break;
         case OPCODE_GOTO_W:         /* 0xc8 + s4 */
         case OPCODE_JSR_W:          /* 0xc9 + s4 */
@@ -184,6 +187,7 @@
             assert( error == JVMTI_ERROR_NONE );
             (*next_step)->method = method;
             (*next_step)->location = offset;
+            (*next_step)->native_location = NULL;
             break;
 
         // tableswitch instruction
@@ -201,11 +205,13 @@
                 (*next_step)[0].method = method;
                 (*next_step)[0].location = (int)bytecode_index
                     + jvmti_GetWordValue( bytecode, location );
+                (*next_step)[0].native_location = NULL;
                 location += 12;
                 for( int index = 1; index < number; index++, location += 4 ) {
                     (*next_step)[index].method = method;
                     (*next_step)[index].location = (int)bytecode_index
                         + jvmti_GetWordValue( bytecode, location );
+                    (*next_step)[index].native_location = NULL;
                 }
             }
             break;
@@ -223,11 +229,13 @@
                 (*next_step)[0].method = method;
                 (*next_step)[0].location = (int)bytecode_index
                     + jvmti_GetWordValue( bytecode, location );
+                (*next_step)[0].native_location = NULL;
                 location += 12;
                 for( int index = 1; index < number; index++, location += 8 ) {
                     (*next_step)[index].method = method;
                     (*next_step)[index].location = (int)
                         + jvmti_GetWordValue( bytecode, location );
+                    (*next_step)[index].native_location = NULL;
                 }
             }
             break;
@@ -269,6 +277,7 @@
                     assert( error == JVMTI_ERROR_NONE );
                     (*next_step)->method = klass->const_pool[index].CONSTANT_ref.method;
                     (*next_step)->location = 0;
+                    (*next_step)->native_location = NULL;
                 }
             }
             break;
@@ -284,6 +293,7 @@
                     assert( error == JVMTI_ERROR_NONE );
                     (*next_step)->method = func;
                     (*next_step)->location = 0;
+                    (*next_step)->native_location = NULL;
                 }
             }
             break;
@@ -344,18 +354,20 @@
             assert( error == JVMTI_ERROR_NONE );
             (*next_step)->method = method;
             (*next_step)->location = location;
+            (*next_step)->native_location = NULL;
             break;
 
         // ret instruction
         case OPCODE_RET:            /* 0xa9 + u1|u2  */
             // FIXME - need to obtain return address from stack.
+            DIE2("jvmti", "SingleStepLocation: not implemented ret instruction");
             break;
         }
         break;
     } while( true );
 
     for( unsigned index = 0; index < *count; index++ ) {
-        TRACE2( "jvmti.step", "Step: " << class_get_name(method_get_class(method))
+        TRACE2( "jvmti.break.ss", "Step: " << class_get_name(method_get_class(method))
             << "." << method_get_name(method) << method_get_descriptor(method)
             << " :" << bytecode_index << "\n      -> "
             << class_get_name(method_get_class((*next_step)[index].method))
@@ -387,12 +399,13 @@
         memset( bp, 0, sizeof(BreakPoint));
         bp->method = (jmethodID)locations[iii].method;
         bp->location = locations[iii].location;
+        bp->native_location = locations[iii].native_location;
 
         TRACE2("jvmti.break.ss", "Set single step breakpoint: "
             << class_get_name(method_get_class((Method *)bp->method)) << "."
             << method_get_name((Method *)bp->method)
             << method_get_descriptor((Method *)bp->method)
-            << " :" << bp->location);
+            << " :" << bp->location << " :" << bp->native_location);
 
         errorCode = jvmti_set_breakpoint_for_jit(ti, bp);
         if (JVMTI_ERROR_NONE != errorCode)
@@ -413,6 +426,10 @@
     // Function is always executed under global TI breakpoints lock
     JVMTISingleStepState *ss_state = vm_thread->ss_state;
 
+    if(!ss_state->predicted_bp_count) {
+        // nothing to do
+        return;
+    }
     for (unsigned iii = 0; iii < ss_state->predicted_bp_count; iii++)
     {
         BreakPoint *bp = ss_state->predicted_breakpoints[iii];
@@ -473,6 +490,7 @@
         // which caused call of the method. So next location is the 'bc' which
         // IP points to.
         (*next_step)->location = bc;
+        (*next_step)->native_location = ip;
     }
     si_free(si);
     return JVMTI_ERROR_NONE;



Mime
View raw message