harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r450053 - in /incubator/harmony/enhanced/drlvm/trunk/vm: interpreter/src/ vmcore/include/ vmcore/src/exception/ vmcore/src/jvmti/
Date Tue, 26 Sep 2006 14:10:04 GMT
Author: geirm
Date: Tue Sep 26 07:10:00 2006
New Revision: 450053

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

Processing breakpoints works incorrectly in multi-thread mode.

(See JIRA for full details).

Ubuntu 6, smoke, c-unit


Modified:
    incubator/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter_ti.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/version_svn_tag.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_method.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/interpreter/src/interpreter.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp?view=diff&rev=450053&r1=450052&r2=450053
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp Tue Sep 26 07:10:00 2006
@@ -1781,8 +1781,18 @@
 
     if (field->is_final()) {
         if (!frame.method->is_init()) {
-            throwIAE(field_get_name(field));
-            return;
+
+            // searching for the constructor for this class in stack.
+            for (StackFrame *f = frame.prev; true; f = f->prev) {
+                if (f == NULL) {
+                    throwIAE(field_get_name(field));
+                    return;
+                }
+
+                if (f->This == frame.This && f->method->is_init()) {
+                    break;
+                }
+            }
         }
     }
 
@@ -2513,6 +2523,8 @@
             << frame.method->get_class()->name->bytes
             << " " << frame.method->get_name()->bytes
             << frame.method->get_descriptor()->bytes << endl);
+
+    assert(frame.method->is_static() || frame.This);
 
     M2N_ALLOC_MACRO;
     assert(!check_current_thread_exception());

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter_ti.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter_ti.cpp?view=diff&rev=450053&r1=450052&r2=450053
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter_ti.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter_ti.cpp Tue Sep 26 07:10:00 2006
@@ -356,6 +356,10 @@
     jlocation l = frame.ip - (uint8*)m->get_byte_code_addr();
     M2N_ALLOC_MACRO;
     uint8 b = (uint8) (POINTER_SIZE_INT) jvmti_process_interpreter_breakpoint_event((jmethodID)m, l);
+    if(b == OPCODE_COUNT) {
+        // breakpoint was remove by another thread, get original opcode
+        b = *(frame.ip);
+    }
     M2N_FREE_MACRO;
     return b;
 }

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h?view=diff&rev=450053&r1=450052&r2=450053
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h Tue Sep 26 07:10:00 2006
@@ -54,28 +54,36 @@
     InstructionDisassembler* disasm;
     VMBreakPoint*            next;
     NativeCodePtr            addr;
-    jlocation                location;
     jmethodID                method;
+    jlocation                location;
     jbyte                    saved_byte;
-    bool                     is_interp;
-    bool                     is_processed;
 };
 
 // Breakpoint reference
 struct VMBreakPointRef
 {
-    VMBreakPoint*    brpt;
+    VMBreakPoint*    bp;
     void*            data;
     VMBreakPointRef* next;
 };
 
+struct VMLocalBreak
+{
+    VMBreakPoint *bp;
+    VMBreakPoint *bp_next;
+    VMBreakInterface *intf;
+    VMLocalBreak* next;
+    unsigned priority;
+};
+
 // Pointer to interface callback function
-typedef bool (*BPInterfaceCallBack)(VMBreakInterface* intf, VMBreakPointRef* bp_ref);
+typedef bool (*BPInterfaceCallBack)(TIEnv *env, VMBreakPoint* bp, void *data);
+typedef bool (*BPInterfaceProcedure) (VMBreakPoint *bp);
 
 class VMBreakPoints
 {
 public:
-    VMBreakPoints() : m_break(NULL)
+    VMBreakPoints() : m_break(NULL), m_last(NULL), m_local(NULL)
     {
         for(unsigned index = 0; index < PRIORITY_NUMBER; index++ ) {
             m_intf[index] = NULL;
@@ -84,34 +92,36 @@
 
     ~VMBreakPoints();
 
+    // Class lock interface
     void lock() {m_lock._lock();}
     void unlock() {m_lock._unlock();}
     // Is used for LMAutoUnlock
     Lock_Manager* get_lock() {return &m_lock;}
 
     // Returns interface for breakpoint handling
-    VMBreakInterface* new_intf(BPInterfaceCallBack callback,
+    VMBreakInterface* new_intf(TIEnv *env, BPInterfaceCallBack callback,
         unsigned priority, bool is_interp);
     // Destroys interface and deletes all its breakpoints
     void release_intf(VMBreakInterface* intf);
 
-    // Checks breakpoint before inserting
-    bool check_insert_breakpoint(VMBreakPoint* bp);
     // Inserts breakpoint into global list and performs instrumentation
-    bool insert_breakpoint(VMBreakPoint* brpt);
+    bool insert_native_breakpoint(VMBreakPoint* bp);
+    bool insert_interpreter_breakpoint(VMBreakPoint* bp);
     // Removes breakpoint from global list and restores instrumented area
-    bool remove_breakpoint(VMBreakPoint* brpt);
+    bool remove_native_breakpoint(VMBreakPoint* bp);
+    bool remove_interpreter_breakpoint(VMBreakPoint* bp);
 
-    // Search operations
+    // Search breakpoints operations
     VMBreakPoint* find_breakpoint(jmethodID method, jlocation location);
     VMBreakPoint* find_breakpoint(NativeCodePtr addr);
     VMBreakPoint* find_other_breakpoint_with_same_addr(VMBreakPoint* bp);
     VMBreakPoint* find_next_breakpoint(VMBreakPoint* prev, NativeCodePtr addr);
+    VMBreakPoint* find_next_breakpoint(VMBreakPoint* prev, jmethodID method,
+        jlocation location);
 
     // Search breakpoints for given method
-    bool has_breakpoint(jmethodID method);
-    VMBreakPoint* find_first(jmethodID method);
-    VMBreakPoint* find_next(VMBreakPoint* prev, jmethodID method);
+    VMBreakPoint* find_method_breakpoint(jmethodID method);
+    VMBreakPoint* find_next_method_breakpoint(VMBreakPoint* prev, jmethodID method);
 
     // Checks if given breakpoint is set by other interfaces
     VMBreakPointRef* find_other_reference(VMBreakInterface* intf,
@@ -119,31 +129,32 @@
     VMBreakPointRef* find_other_reference(VMBreakInterface* intf,
         NativeCodePtr addr);
     VMBreakPointRef* find_other_reference(VMBreakInterface* intf,
-        VMBreakPoint* brpt);
+        VMBreakPoint* bp);
+
+    // Interfaces iterator
+    VMBreakInterface* get_first_intf(unsigned priority) { return m_intf[priority]; }
+    VMBreakInterface* get_next_intf(VMBreakInterface *intf);
 
     // General callback functions
     void  process_native_breakpoint();
     jbyte process_interpreter_breakpoint(jmethodID method, jlocation location);
 
-protected:
-    void clear_breakpoints_processed_flags();
-    VMBreakPoint* get_none_processed_breakpoint(NativeCodePtr addr);
-    void set_breakpoint_processed( VMBreakPoint *bp, bool flag )
-    {
-        bp->is_processed = flag;
-    }
-    bool breakpoint_is_processed( VMBreakPoint *bp )
-    {
-        return bp->is_processed == true;
-    }
-
-    void clear_intfs_processed_flags();
-    VMBreakInterface* get_none_processed_intf(unsigned priority);
+private:
+    // Checks breakpoint before inserting
+    inline bool check_insert_breakpoint(VMBreakPoint* bp);
+    void insert_breakpoint(VMBreakPoint* bp);
+    void remove_breakpoint(VMBreakPoint* bp);
+
+    // Set/remove thread processing breakpoints interfaces
+    void set_thread_local_break(VMLocalBreak *local);
+    void remove_thread_local_break(VMLocalBreak *local);
 
 private:
     VMBreakInterface* m_intf[PRIORITY_NUMBER];
     VMBreakPoint*     m_break;
-    Lock_Manager m_lock;
+    VMBreakPoint*     m_last;
+    VMLocalBreak*     m_local;
+    Lock_Manager      m_lock;
 };
 
 class VMBreakInterface
@@ -151,54 +162,60 @@
     friend class VMBreakPoints;
 
 public:
-    void lock()     {VM_Global_State::loader_env->TI->vm_brpt->lock();}
-    void unlock()   {VM_Global_State::loader_env->TI->vm_brpt->unlock();}
-    Lock_Manager* get_lock()
-                    {return VM_Global_State::loader_env->TI->vm_brpt->get_lock();}
-
     int get_priority() const { return m_priority; }
 
     // Iteration
-    VMBreakPointRef* get_first() { return m_list; }
-    VMBreakPointRef* get_next(VMBreakPointRef* prev)
+    VMBreakPointRef* get_reference() { return m_list; }
+    VMBreakPointRef* get_next_reference(VMBreakPointRef* ref)
     {
-        assert(prev);
-        return prev->next;
+        assert(ref);
+        return ref->next;
     }
 
     // Basic operations
 
     // 'data' must be allocated with JVMTI Allocate (or internal _allocate)
     // Users must not deallocate 'data', it will be deallocated by 'remove'
-    VMBreakPointRef* add(jmethodID method, jlocation location, void* data);
+    VMBreakPointRef* add_reference(jmethodID method, jlocation location, void* data);
     // To specify address explicitly
-    VMBreakPointRef* add(jmethodID method, jlocation location,
+    VMBreakPointRef* add_reference(jmethodID method, jlocation location,
                     NativeCodePtr addr, void* data);
-    VMBreakPointRef* add(NativeCodePtr addr, void* data);
+    VMBreakPointRef* add_reference(NativeCodePtr addr, void* data);
 
-    void remove_all();
-    bool remove(VMBreakPointRef* ref);
+    bool remove_reference(VMBreakPointRef* ref);
+    void remove_all_reference()
+    {
+        while (m_list) {
+            remove_reference(m_list);
+        }
+    }
 
-    VMBreakPointRef* find(jmethodID method, jlocation location);
-    VMBreakPointRef* find(NativeCodePtr addr);
-    VMBreakPointRef* find(VMBreakPoint* brpt);
+    VMBreakPointRef* find_reference(jmethodID method, jlocation location);
+    VMBreakPointRef* find_reference(NativeCodePtr addr);
+    VMBreakPointRef* find_reference(VMBreakPoint* bp);
 
 protected:
-    VMBreakInterface(BPInterfaceCallBack callback, unsigned priority, bool is_interp)
-        : m_list(NULL), m_callback(callback), m_priority(priority),
-          m_next(NULL), m_processed(false), m_is_interp(is_interp) {}
-    ~VMBreakInterface() { remove_all(); }
+    VMBreakInterface(TIEnv *env,
+                     BPInterfaceCallBack callback,
+                     unsigned priority,
+                     bool is_interp);
+    ~VMBreakInterface() { remove_all_reference(); }
+    TIEnv* get_env() { return m_env; }
 
-    void set_processed(bool processed) { m_processed = processed; }
-    bool is_processed() const { return (m_processed == true); }
+private:
+    inline VMBreakPointRef* add_reference_internal(VMBreakPoint *bp, void *data);
+
+protected:
     VMBreakInterface*   m_next;
 
 private:
-    VMBreakPointRef*    m_list;
-    BPInterfaceCallBack m_callback;
-    bool                m_is_interp;
-    unsigned            m_priority;
-    bool                m_processed;
+    BPInterfaceCallBack  breakpoint_event_callback;
+    BPInterfaceProcedure breakpoint_insert;
+    BPInterfaceProcedure breakpoint_remove;
+    VMBreakPointRef*     m_list;
+    TIEnv               *m_env;
+    unsigned             m_priority;
+    Lock_Manager         m_lock;
 };
 
 // Callback function for native breakpoint processing

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=450053&r1=450052&r2=450053
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h Tue Sep 26 07:10:00 2006
@@ -74,19 +74,11 @@
     jvmti_frame_pop_listener *next;
 };
 
-/*
- * Type which will be attached to each JVMTI breakpoint
- */
-struct TIBrptData
-{
-    TIEnv *env;
-};
-
 struct jvmti_StepLocation
 {
     struct Method* method;
-    unsigned location;
     NativeCodePtr native_location;
+    unsigned location;
     bool no_event;
 };
 
@@ -147,7 +139,7 @@
 
 typedef struct Class Class;
 class VMBreakPoints;
-struct VMBreakPointRef;
+struct VMBreakPoint;
 
 /*
  * JVMTI state of the VM
@@ -367,6 +359,6 @@
     unsigned location, jvmti_StepLocation **next_step, unsigned *count);
 
 // Callback function for JVMTI breakpoint processing
-bool jvmti_process_breakpoint_event(VMBreakInterface* intf, VMBreakPointRef* bp_ref);
+bool jvmti_process_breakpoint_event(TIEnv *env, VMBreakPoint* bp, void* data);
 
 #endif /* _JVMTI_INTERNAL_H_ */

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/version_svn_tag.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/version_svn_tag.h?view=diff&rev=450053&r1=450052&r2=450053
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/version_svn_tag.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/version_svn_tag.h Tue Sep 26 07:10:00 2006
@@ -17,6 +17,6 @@
 #ifndef _VERSION_SVN_TAG_
 #define _VERSION_SVN_TAG_
 
-#define VERSION_SVN_TAG  "449396"
+#define VERSION_SVN_TAG  "450012"
 
 #endif // _VERSION_SVN_TAG_

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=450053&r1=450052&r2=450053
==============================================================================
--- 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 Sep 26 07:10:00 2006
@@ -278,7 +278,7 @@
                             jit->get_bc_location_for_native(method, ip, &bc);
                         assert(EXE_ERROR_NONE == result);
 
-                        jvmti_StepLocation method_start = {(Method *)method, bc, ip};
+                        jvmti_StepLocation method_start = {(Method *)method, ip, bc, false};
 
                         jvmti_set_single_step_breakpoints(ti, vm_thread,
                                 &method_start, 1);

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp?view=diff&rev=450053&r1=450052&r2=450053
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp Tue Sep 26 07:10:00 2006
@@ -266,7 +266,8 @@
 
     // Acquire interface for breakpoint handling
     newenv->brpt_intf =
-        vm->vm_env->TI->vm_brpt->new_intf(jvmti_process_breakpoint_event,
+        vm->vm_env->TI->vm_brpt->new_intf(newenv,
+                                          jvmti_process_breakpoint_event,
                                           PRIORITY_SIMPLE_BREAKPOINT,
                                           interpreter_enabled());
 

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=450053&r1=450052&r2=450053
==============================================================================
--- 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 Tue Sep 26 07:10:00 2006
@@ -37,16 +37,17 @@
 
 
 // Callback function for JVMTI breakpoint processing
-bool jvmti_process_breakpoint_event(VMBreakInterface* intf, VMBreakPointRef* bp_ref)
+bool jvmti_process_breakpoint_event(TIEnv *env, VMBreakPoint* bp, void* UNREF data)
 {
-    VMBreakPoint* bp = bp_ref->brpt;
     assert(bp);
 
     TRACE2("jvmti.break", "Process 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->addr);
+            << (bp->method
+                ? class_get_name(method_get_class((Method*)bp->method)) : "(nil)")
+            << "."
+            << (bp->method ? method_get_name((Method*)bp->method) : "(nil)")
+            << (bp->method ? method_get_descriptor((Method*)bp->method) : "")
+            << " :" << bp->location << " :" << bp->addr );
 
     DebugUtilsTI *ti = VM_Global_State::loader_env->TI;
     if (!ti->isEnabled() || ti->getPhase() != JVMTI_PHASE_LIVE)
@@ -54,8 +55,7 @@
 
     jlocation location = bp->location;
     jmethodID method = bp->method;
-    TIBrptData* data = (TIBrptData*)bp_ref->data;
-    TIEnv *env = data->env;
+    NativeCodePtr addr = bp->addr;
     
     hythread_t h_thread = hythread_self();
     jthread j_thread = jthread_get_java_thread(h_thread);
@@ -76,17 +76,15 @@
                 << class_get_name(method_get_class((Method*)method)) << "."
                 << method_get_name((Method*)method)
                 << method_get_descriptor((Method*)method)
-                << " :" << location);
+                << " :" << location << " :" << addr);
 
-            intf->unlock();
             func((jvmtiEnv*)env, jni_env, (jthread)hThread, method, location);
-            intf->lock();
 
             TRACE2("jvmti.break", "Finished global breakpoint callback: "
                 << class_get_name(method_get_class((Method*)method)) << "."
                 << method_get_name((Method*)method)
                 << method_get_descriptor((Method*)method)
-                << " :" << location);
+                << " :" << location << " :" << addr);
         }
         else
         {
@@ -104,17 +102,15 @@
                         << class_get_name(method_get_class((Method*)method)) << "."
                         << method_get_name((Method*)method)
                         << method_get_descriptor((Method*)method)
-                        << " :" << location);
+                        << " :" << location << " :" << addr);
 
-                    intf->unlock();
                     func((jvmtiEnv*)env, jni_env, (jthread)hThread, method, location);
-                    intf->lock();
 
                     TRACE2("jvmti.break", "Finished local breakpoint callback: "
                         << class_get_name(method_get_class((Method*)method)) << "."
                         << method_get_name((Method*)method)
                         << method_get_descriptor((Method*)method)
-                        << " :" << location);
+                        << " :" << location << " :" << addr);
                 }
             }
         }
@@ -190,25 +186,16 @@
 
     TIEnv *p_env = (TIEnv *)env;
     VMBreakInterface* brpt_intf = p_env->brpt_intf;
-    LMAutoUnlock lock(brpt_intf->get_lock());
+    VMBreakPoints *vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+    LMAutoUnlock lock(vm_breaks->get_lock());
 
-    VMBreakPointRef* bp = brpt_intf->find(method, location);
+    VMBreakPointRef* bp = brpt_intf->find_reference(method, location);
 
     if (NULL != bp)
         return JVMTI_ERROR_DUPLICATE;
 
-    TIBrptData* data;
-    errorCode = _allocate(sizeof(TIBrptData), (unsigned char**)&data);
-    if (JVMTI_ERROR_NONE != errorCode)
-        return errorCode;
-
-    data->env = p_env;
-
-    if (!brpt_intf->add(method, location, data))
-    {
-        _deallocate((unsigned char*)data);
+    if (!brpt_intf->add_reference(method, location, NULL))
         return JVMTI_ERROR_INTERNAL;
-    }
 
     TRACE2("jvmti.break", "SetBreakpoint is successfull");
     return JVMTI_ERROR_NONE;
@@ -278,14 +265,15 @@
 
     TIEnv *p_env = (TIEnv *)env;
     VMBreakInterface* brpt_intf = p_env->brpt_intf;
-    LMAutoUnlock lock(brpt_intf->get_lock());
+    VMBreakPoints *vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+    LMAutoUnlock lock(vm_breaks->get_lock());
 
-    VMBreakPointRef* bp = brpt_intf->find(method, location);
+    VMBreakPointRef* bp_ref = brpt_intf->find_reference(method, location);
 
-    if (NULL == bp)
+    if (NULL == bp_ref)
         return JVMTI_ERROR_NOT_FOUND;
 
-    if (!brpt_intf->remove(bp))
+    if (!brpt_intf->remove_reference(bp_ref))
         return JVMTI_ERROR_INTERNAL;
 
     TRACE2("jvmti.break", "ClearBreakpoint is successfull");

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp?view=diff&rev=450053&r1=450052&r2=450053
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp Tue Sep 26 07:10:00 2006
@@ -25,20 +25,21 @@
 #include "cxxlog.h"
 #include "environment.h"
 #include "encoder.h"
+#include "interpreter.h"
 #include "interpreter_exports.h"
 #include "jit_intf_cpp.h"
 #include "method_lookup.h"
 #include "exceptions.h"
 #include "m2n.h"
 #include "stack_iterator.h"
-
+#include "open/bytecodes.h"
 #include "jvmti_break_intf.h"
 
 
 // Forvard declarations
 static ConditionCode
 get_condition_code(InstructionDisassembler::CondJumpType jump_type);
-static bool set_jit_mode_breakpoint(VMBreakPoints* vm_brpt, VMBreakPoint* bp);
+static bool set_jit_mode_breakpoint(VMBreakPoint* bp);
 static bool set_native_breakpoint(VMBreakPoint* bp);
 static bool clear_native_breakpoint(VMBreakPoint* bp);
 
@@ -60,18 +61,39 @@
 }
 
 VMBreakInterface*
-VMBreakPoints::new_intf(BPInterfaceCallBack callback,
+VMBreakPoints::new_intf(TIEnv *env,
+                        BPInterfaceCallBack callback,
                         unsigned priority,
                         bool is_interp)
 {
     assert(callback);
     assert(priority < PRIORITY_NUMBER);
-    VMBreakInterface* intf = new VMBreakInterface(callback, priority, is_interp);
+    VMBreakInterface* intf = new VMBreakInterface(env, callback, priority, is_interp);
     assert(intf);
 
     lock();
-    intf->m_next = m_intf[priority];
-    m_intf[priority] = intf;
+
+    TRACE2("jvmti.break", "Create breakpoint interface: " << intf );
+
+    // add interface to the end of list
+    if( NULL == m_intf[priority] ) {
+        m_intf[priority] = intf;
+    } else {
+        VMBreakInterface *last = m_intf[priority];
+        for( ; last->m_next; last = last->m_next )
+            ;
+        last->m_next = intf;
+    }
+
+    // correct thread processing breakpoints
+    for(VMLocalBreak *local = m_local; local; local = local->next) {
+        if( local->priority == priority && NULL == local->intf ) {
+            TRACE2("jvmti.break", "Set local thread interface: "
+                << local << ", intf: " << intf );
+            local->intf = intf;
+        }
+    }
+
     unlock();
 
     return intf;
@@ -84,8 +106,21 @@
     assert(intf->get_priority() < PRIORITY_NUMBER);
     LMAutoUnlock lock(get_lock());
 
+    TRACE2("jvmti.break", "Release breakpoint interface: " << intf );
+
+    // correct thread processing breakpoints
+    for(VMLocalBreak *local = m_local; local; local = local->next) {
+        if( local->intf == intf ) {
+            TRACE2("jvmti.break", "Set local thread interface: "
+                << local << ", intf: " << intf->m_next );
+            local->intf = intf->m_next;
+        }
+    }
+
+    // release interface
     for (VMBreakInterface** cur_ptr = &m_intf[intf->get_priority()];
-         *cur_ptr; cur_ptr = &((*cur_ptr)->m_next))
+         *cur_ptr;
+         cur_ptr = &((*cur_ptr)->m_next))
     {
         if (*cur_ptr == intf)
         {
@@ -98,6 +133,12 @@
     DIE2("jvmti.break", "VMBreakPoints::release_intf: try to release unknown interface");
 }
 
+VMBreakInterface*
+VMBreakPoints::get_next_intf(VMBreakInterface *intf)
+{
+    return intf->m_next;
+}
+
 inline bool
 VMBreakPoints::check_insert_breakpoint(VMBreakPoint* bp)
 {
@@ -121,7 +162,7 @@
                 ? class_get_name(method_get_class((Method*)another->method)): "(nil)")
             << "."
             << (another->method ? method_get_name((Method*)another->method) : "(nil)")
-            << (another->method ? method_get_descriptor((Method*)another->method) : "(nil)")
+            << (another->method ? method_get_descriptor((Method*)another->method) : "")
             << " :" << another->location << " :" << another->addr);
 
         if( bp->addr == another->addr) {
@@ -141,7 +182,7 @@
                 ? class_get_name(method_get_class((Method*)another->method)) :"(nil)")
             << "."
             << (another->method ? method_get_name((Method*)another->method) :"(nil)")
-            << (another->method ? method_get_descriptor((Method*)another->method) :"(nil)")
+            << (another->method ? method_get_descriptor((Method*)another->method) :"")
             << " :" << another->location << " :" << another->addr);
 
         if(another->method) {
@@ -154,100 +195,190 @@
     return true;
 }
 
-bool
-VMBreakPoints::insert_breakpoint(VMBreakPoint* brpt)
+inline void
+VMBreakPoints::insert_breakpoint(VMBreakPoint* bp)
 {
-    check_insert_breakpoint(brpt);
-    if (brpt->is_interp)
-    {
-        assert(interpreter_enabled());
-        brpt->saved_byte = (POINTER_SIZE_INT)
-            interpreter.interpreter_ti_set_breakpoint(brpt->method, brpt->location);
+    TRACE2("jvmti.break", "Insert breakpoint: "
+        << (bp->method
+            ? class_get_name(method_get_class((Method*)bp->method)) : "(nil)")
+        << "."
+        << (bp->method ? method_get_name((Method*)bp->method) : "(nil)")
+        << (bp->method ? method_get_descriptor((Method*)bp->method) : "")
+        << " :" << bp->location << " :" << bp->addr);
+
+    // add breakpoint to the end of list
+    if(m_last) {
+        m_last->next = bp;
+    } else {
+        m_break = bp;
     }
-    else
-    {
-        if (brpt->method != NULL)
-        { // JIT breakpoint
-            Method *m = (Method *)brpt->method;
+    m_last = bp;
+    bp->next = NULL;
 
-            if (m->get_state() == Method::ST_Compiled)
-            {
-                if (!set_jit_mode_breakpoint(this, brpt))
-                    return false;
-            }
-            else
-            {
-                assert(brpt->addr == NULL);
-                TRACE2("jvmti.break.intf", "Skipping setting breakpoing in method "
-                    << class_get_name(method_get_class(m)) << "."
-                    << method_get_name(m)
-                    << method_get_descriptor(m)
-                    << " because it is not compiled yet");
-                m->insert_pending_breakpoint();
-            }
+    // correct thread processing breakpoints
+    for(VMLocalBreak *local = m_local; local; local = local->next) {
+        if( !local->bp_next ) {
+            TRACE2("jvmti.break", "Set local thread next breakpoint: "
+                << local << ", next: "
+                << (bp->method
+                    ? class_get_name(method_get_class((Method*)bp->method)) : "(nil)")
+                << "."
+                << (bp->method ? method_get_name((Method*)bp->method) : "(nil)")
+                << (bp->method ? method_get_descriptor((Method*)bp->method) : "")
+                << " :" << bp->location << " :" << bp->addr);
+            local->bp_next = bp;
         }
-        else
+    }
+    return;
+}
+
+bool
+VMBreakPoints::insert_native_breakpoint(VMBreakPoint* bp)
+{
+    LMAutoUnlock lock(get_lock());
+
+    assert(!interpreter_enabled());
+    bool UNREF check = check_insert_breakpoint(bp);
+    assert(check);
+    if (bp->method != NULL)
+    { // JIT breakpoint
+        Method *m = (Method *)bp->method;
+
+        if (m->get_state() == Method::ST_Compiled)
         {
-            if (!set_native_breakpoint(brpt))
+            if (!set_jit_mode_breakpoint(bp))
                 return false;
         }
+        else
+        {
+            assert(bp->addr == NULL);
+            TRACE2("jvmti.break.intf", "Skipping setting breakpoing in method "
+                << class_get_name(method_get_class(m)) << "."
+                << method_get_name(m)
+                << method_get_descriptor(m)
+                << " because it is not compiled yet");
+            m->insert_pending_breakpoint();
+        }
     }
-    TRACE2("jvmti.break.intf", "Insert breakpoint: "
-        << class_get_name(method_get_class((Method*)brpt->method)) << "."
-        << method_get_name((Method*)brpt->method)
-        << method_get_descriptor((Method*)brpt->method)
-        << " :" << brpt->location << " :" << brpt->addr);
-
-    brpt->next = m_break;
-    m_break = brpt;
-
+    else
+    {
+        if (!set_native_breakpoint(bp))
+            return false;
+    }
+    insert_breakpoint(bp);
     return true;
 }
 
 bool
-VMBreakPoints::remove_breakpoint(VMBreakPoint* brpt)
+VMBreakPoints::insert_interpreter_breakpoint(VMBreakPoint* bp)
 {
-    assert(brpt);
-    assert(!brpt->method || find_breakpoint(brpt->method, brpt->location));
-    assert(brpt->method || find_breakpoint(brpt->addr));
+    LMAutoUnlock lock(get_lock());
 
+    assert(interpreter_enabled());
+    bool UNREF check = check_insert_breakpoint(bp);
+    assert(check);
+    bp->saved_byte = (POINTER_SIZE_INT)
+        interpreter.interpreter_ti_set_breakpoint(bp->method, bp->location);
+
+    insert_breakpoint(bp);
+    return true;
+}
+
+inline void
+VMBreakPoints::remove_breakpoint(VMBreakPoint* bp)
+{
     TRACE2("jvmti.break.intf", "Remove breakpoint: "
-        << class_get_name(method_get_class((Method*)brpt->method)) << "."
-        << method_get_name((Method*)brpt->method)
-        << method_get_descriptor((Method*)brpt->method)
-        << " :" << brpt->location << " :" << brpt->addr);
+        << (bp->method ? class_get_name(method_get_class((Method*)bp->method)) : "(nil)" )
+        << "."
+        << (bp->method ? method_get_name((Method*)bp->method) : "(nil)" )
+        << (bp->method ? method_get_descriptor((Method*)bp->method) : "" )
+        << " :" << bp->location << " :" << bp->addr);
 
-    for (VMBreakPoint** cur_ptr = &m_break;
-         *cur_ptr; cur_ptr = &(*cur_ptr)->next)
-    {
-        if (*cur_ptr == brpt)
-        {
-            *cur_ptr = (*cur_ptr)->next;
+    // remove breakpoint from list
+    VMBreakPoint *last = NULL;
+    for( VMBreakPoint *index = m_break;
+         index;
+         last = index, index = index->next )
+    {
+        if(index == bp) {
+            if(m_last == bp) {
+                m_last = last;
+            }
+            if(last) {
+                last->next = index->next;
+            } else {
+                m_break = index->next;
+            }
             break;
         }
     }
 
-    if (brpt->is_interp)
+    // correct thread processing breakpoints
+    for(VMLocalBreak *local = m_local; local; local = local->next) {
+        if( local->bp == bp ) {
+            // processed breakpoint was removed
+            TRACE2("jvmti.break", "Remove local thread breakpoint: "
+                << local << ", bp: "
+                << (bp->method
+                    ? class_get_name(method_get_class((Method*)bp->method)) : "(nil)")
+                << "."
+                << (bp->method ? method_get_name((Method*)bp->method) : "(nil)")
+                << (bp->method ? method_get_descriptor((Method*)bp->method) : "")
+                << " :" << bp->location << " :" << bp->addr);
+
+            local->bp = NULL;
+        } else if( local->bp_next == bp ) {
+            // set new next breakpoint
+            TRACE2("jvmti.break", "Set local thread next breakpoint: "
+                << local << ", next: "
+                << (bp->method
+                    ? class_get_name(method_get_class((Method*)bp->method)) : "(nil)")
+                << "."
+                << (bp->method ? method_get_name((Method*)bp->method) : "(nil)")
+                << (bp->method ? method_get_descriptor((Method*)bp->method) : "")
+                << " :" << bp->location << " :" << bp->addr);
+            local->bp_next = bp->next;
+        }
+    }
+    return;
+}
+
+bool
+VMBreakPoints::remove_native_breakpoint(VMBreakPoint* bp)
+{
+    assert(bp);
+    assert(!bp->method || find_breakpoint(bp->method, bp->location));
+    assert(bp->method || find_breakpoint(bp->addr));
+    assert(!interpreter_enabled());
+
+    LMAutoUnlock lock(get_lock());
+    remove_breakpoint(bp);
+    if (bp->addr)
     {
-        assert(interpreter_enabled());
-        interpreter.interpreter_ti_clear_breakpoint(brpt->method,
-                                    brpt->location, brpt->saved_byte);
+        assert(!bp->method || (((Method*)bp->method)->get_state() == Method::ST_Compiled));
+        return clear_native_breakpoint(bp);
     }
     else
     {
-        if (brpt->addr)
-        {
-            assert(!brpt->method || (((Method*)brpt->method)->get_state() == Method::ST_Compiled));
-            return clear_native_breakpoint(brpt);
-        }
-        else
-        {
-            assert(brpt->method && (((Method*)brpt->method)->get_state() != Method::ST_Compiled));
-            Method *m = (Method *)brpt->method;
-            m->remove_pending_breakpoint();
-        }
+        assert(bp->method && (((Method*)bp->method)->get_state() != Method::ST_Compiled));
+        Method *m = (Method *)bp->method;
+        m->remove_pending_breakpoint();
     }
+    return true;
+}
 
+bool
+VMBreakPoints::remove_interpreter_breakpoint(VMBreakPoint* bp)
+{
+    assert(bp);
+    assert(bp->method);
+    assert(find_breakpoint(bp->method, bp->location));
+    assert(interpreter_enabled());
+
+    LMAutoUnlock lock(get_lock());
+    remove_breakpoint(bp);
+    interpreter.interpreter_ti_clear_breakpoint(bp->method,
+        bp->location, bp->saved_byte);
     return true;
 }
 
@@ -307,14 +438,25 @@
     return NULL;
 }
 
-bool
-VMBreakPoints::has_breakpoint(jmethodID method)
+VMBreakPoint*
+VMBreakPoints::find_next_breakpoint(VMBreakPoint* prev,
+                                    jmethodID method,
+                                    jlocation location)
 {
-    return (find_first(method) != NULL);
+    assert(prev);
+    assert(method);
+
+    for (VMBreakPoint* bp = prev->next; bp; bp = bp->next) {
+        if (bp->method == method && bp->location == location) {
+            return bp;
+        }
+    }
+
+    return NULL;
 }
 
 VMBreakPoint*
-VMBreakPoints::find_first(jmethodID method)
+VMBreakPoints::find_method_breakpoint(jmethodID method)
 {
     assert(method);
 
@@ -329,7 +471,7 @@
 }
 
 VMBreakPoint*
-VMBreakPoints::find_next(VMBreakPoint* prev, jmethodID method)
+VMBreakPoints::find_next_method_breakpoint(VMBreakPoint* prev, jmethodID method)
 {
     assert(prev);
 
@@ -354,7 +496,7 @@
             if (cur == intf)
                 continue;
 
-            VMBreakPointRef* ref = cur->find(method, location);
+            VMBreakPointRef* ref = cur->find_reference(method, location);
 
             if (ref)
                 return ref;
@@ -375,7 +517,7 @@
             if (cur == intf)
                 continue;
 
-            VMBreakPointRef* ref = cur->find(addr);
+            VMBreakPointRef* ref = cur->find_reference(addr);
 
             if (ref)
                 return ref;
@@ -396,7 +538,7 @@
             if (cur == intf)
                 continue;
 
-            VMBreakPointRef* ref = cur->find(brpt);
+            VMBreakPointRef* ref = cur->find_reference(brpt);
 
             if (ref)
                 return ref;
@@ -407,6 +549,35 @@
 }
 
 void
+VMBreakPoints::set_thread_local_break(VMLocalBreak *local)
+{
+    local->next = m_local;
+    m_local = local;
+    TRACE2( "jvmti.break", "Set local thread structure: " << local);
+}
+
+void
+VMBreakPoints::remove_thread_local_break(VMLocalBreak *local)
+{
+    TRACE2( "jvmti.break", "Remove local thread structure: " << local);
+    VMLocalBreak *last = NULL;
+    for( VMLocalBreak *index = m_local;
+         index;
+         last = index, index = index->next )
+    {
+        if(index == local) {
+            if(last) {
+                last->next = index->next;
+            } else {
+                m_local = index->next;
+            }
+            return;
+        }
+    }
+    assert(false);
+}
+
+void
 VMBreakPoints::process_native_breakpoint()
 {
     // When we get here we know already that breakpoint occurred in JITted code,
@@ -420,20 +591,32 @@
 #endif //_IA32_ && PLATFORM_POSIX && INSTRUMENTATION_BYTE == INSTRUMENTATION_BYTE_INT3
     NativeCodePtr addr = (NativeCodePtr)regs.get_ip();
 
-    TRACE2("jvmti.break.intf", "Native breakpoint occured: " << addr);
+    TRACE2("jvmti.break", "Native breakpoint occured: " << addr);
 
+    lock();
     VMBreakPoint* bp = find_breakpoint(addr);
-    assert(bp);
+    if (NULL == bp) {
+        // breakpoint could be deleted by another thread
+        unlock();
+        return;
+    }
+    assert(bp->addr == addr);
+    TRACE2("jvmti.break", "Process native breakpoint: "
+        << (bp->method
+            ? class_get_name(method_get_class((Method*)bp->method)) : "(nil)")
+        << "."
+        << (bp->method ? method_get_name((Method*)bp->method) : "(nil)")
+        << (bp->method ? method_get_descriptor((Method*)bp->method) : "")
+        << " :" << bp->location << " :" << bp->addr);
 
     bool push_frame = (vm_identify_eip(addr) == VM_TYPE_JAVA);
     M2nFrame* m2nf;
 
-    if (push_frame)
-    {
+    if (push_frame) {
         m2nf = m2n_push_suspended_frame(&regs);
-    }
-    else
+    } else {
         m2nf = m2n_get_last_frame();
+    }
 
     jbyte *instruction_buffer;
     BEGIN_RAISE_AREA;
@@ -450,37 +633,75 @@
 
     for (unsigned priority = 0; priority < PRIORITY_NUMBER; priority++)
     {
-        while( bp = get_none_processed_breakpoint(addr) ) {
-            set_breakpoint_processed(bp, true);
+        bp = find_breakpoint(addr);
+        assert(!bp || bp->addr == addr);
+        VMLocalBreak local;
+        local.priority = priority;
+        while( bp )
+        {
+            assert(bp->addr == addr);
+            // copy breakpoint to local thread variable
+            local.bp = bp;
+            local.bp_next = find_next_breakpoint(bp, addr);
 
-            VMBreakInterface* intf;
-            while( intf = get_none_processed_intf(priority) )
+            VMBreakInterface *intf = get_first_intf(priority);
+            while( intf )
             {
-                intf->set_processed(true);
-                VMBreakPointRef* ref = intf->find(bp);
+                VMBreakPointRef* ref = intf->find_reference(bp);
+                assert(!ref || ref->bp->addr == addr);
 
-                if (ref && bp->addr != addr)
-                    break; // It's another breakpoint now...
-
-                if (ref && intf->m_callback != NULL)
+                if (ref && intf->breakpoint_event_callback != NULL)
                 {
-                    TRACE2("jvmti.break.intf",
+                    local.intf = intf->m_next;
+                    VMBreakPoint local_bp = *bp;
+                    void *data = ref->data;
+
+                    Method *method = (Method*)bp->method;
+                    jlocation location = bp->location;
+                    NativeCodePtr addr = bp->addr;
+                    TRACE2("jvmti.break",
                         "Calling native breakpoint callback function: "
-                        << class_get_name(method_get_class((Method*)bp->method)) << "."
-                        << method_get_name((Method*)bp->method)
-                        << method_get_descriptor((Method*)bp->method)
-                        << " :" << bp->location << " :" << bp->addr );
-
-                    intf->m_callback(intf, ref);
-
-                    TRACE2("jvmti.break.intf",
-                        "Finished native breakpoint callback function: " << addr );
+                        << (method
+                            ? class_get_name(method_get_class(method)) : "(nil)")
+                        << "."
+                        << (method ? method_get_name(method) : "(nil)")
+                        << (method ? method_get_descriptor(method) : "")
+                        << " :" << location << " :" << addr);
+
+                    set_thread_local_break(&local);
+                    unlock();
+
+                    // call event breakpoint callback
+                    intf->breakpoint_event_callback(intf->get_env(), &local_bp, data);
+
+                    lock();
+                    remove_thread_local_break(&local);
+
+                    TRACE2("jvmti.break",
+                        "Finished native breakpoint callback function: "
+                        << (method
+                            ? class_get_name(method_get_class(method)) : "(nil)")
+                        << "."
+                        << (method ? method_get_name(method) : "(nil)")
+                        << (method ? method_get_descriptor(method) : "")
+                        << " :" << location << " :" << addr);
+
+                    if( !local.bp ) {
+                        // breakpoint was removed, no need report it anymore
+                        break;
+                    }
+                    intf = local.intf;
+                } else {
+                    intf = intf->m_next;
                 }
             }
-            clear_intfs_processed_flags();
+            bp = local.bp_next;
+            if( bp && bp->addr != addr ) {
+                bp = find_next_breakpoint(bp, addr);
+            }
         }
-        clear_breakpoints_processed_flags();
     }
+    unlock();
 
     // Now we need to return back to normal code execution, it is
     // necessary to execute the original instruction The idea is to
@@ -581,8 +802,6 @@
     }
     }
 
-    unlock();
-
     END_RAISE_AREA;
 
     // This function does not return. It restores register context and
@@ -615,163 +834,208 @@
 
     lock();
     VMBreakPoint* bp = find_breakpoint(method, location);
-    assert(bp);
+    if(NULL == bp) {
+        // breakpoint could be deleted by another thread
+        unlock();
+        return (jbyte)OPCODE_COUNT;
+    }
+    assert(bp->method == method);
+    assert(bp->location == location);
+    TRACE2("jvmti.break", "Process interpreter breakpoint: "
+        << class_get_name(method_get_class((Method*)method)) << "."
+        << method_get_name((Method*)method)
+        << method_get_descriptor((Method*)method)
+        << " :" << location );
 
     jbyte orig_byte = bp->saved_byte;
     for (unsigned priority = 0; priority < PRIORITY_NUMBER; priority++)
     {
-        VMBreakInterface* intf;
-
-        while (intf = get_none_processed_intf(priority) )
+        bp = find_breakpoint(method, location);;
+        assert(bp->method == method);
+        assert(bp->location == location);
+        VMLocalBreak local;
+        local.priority = priority;
+        while( bp )
         {
-            intf->set_processed(true);
-            VMBreakPointRef* ref = intf->find(bp);
-
-            if (ref &&
-                  ( bp->method != method ||
-                    bp->location != location ))
-                break; // It's another breakpoint now...
+            assert(bp->method == method);
+            assert(bp->location == location);
+            // copy breakpoint to local thread variable
+            local.bp = bp;
+            local.bp_next = find_next_breakpoint(bp, method, location);
 
-            if (ref && intf->m_callback != NULL)
+            VMBreakInterface *intf = get_first_intf(priority);
+            while( intf )
             {
-                JNIEnv *jni_env = (JNIEnv *)jni_native_intf;
-                TRACE2("jvmti.break.intf",
-                    "Calling interpreter breakpoint callback function: "
-                    << class_get_name(method_get_class((Method*)method)) << "."
-                    << method_get_name((Method*)method)
-                    << method_get_descriptor((Method*)method)
-                    << " :" << location );
-
-                intf->m_callback(intf, ref);
-
-                TRACE2("jvmti.break.intf",
-                    "Finished interpreter breakpoint callback function: "
-                    << class_get_name(method_get_class((Method*)method)) << "."
-                    << method_get_name((Method*)method)
-                    << method_get_descriptor((Method*)method)
-                    << " :" << location );
+                VMBreakPointRef* ref = intf->find_reference(bp);
+                assert(!ref || ref->bp->method == method);
+                assert(!ref || ref->bp->location == location);
+
+                if (ref && intf->breakpoint_event_callback != NULL)
+                {
+                    local.intf = intf->m_next;
+                    VMBreakPoint local_bp = *bp;
+                    void *data = ref->data;
+
+                    TRACE2("jvmti.break.intf",
+                        "Calling interpreter breakpoint callback function: "
+                        << class_get_name(method_get_class((Method*)method)) << "."
+                        << method_get_name((Method*)method)
+                        << method_get_descriptor((Method*)method)
+                        << " :" << location );
+
+                    set_thread_local_break(&local);
+                    unlock();
+
+                    // call event breakpoint callback
+                    intf->breakpoint_event_callback(intf->get_env(), &local_bp, data);
+
+                    lock();
+                    remove_thread_local_break(&local);
+
+                    TRACE2("jvmti.break",
+                        "Finished interpreter breakpoint callback function: "
+                        << class_get_name(method_get_class((Method*)method)) << "."
+                        << method_get_name((Method*)method)
+                        << method_get_descriptor((Method*)method)
+                        << " :" << location );
+
+                    if( !local.bp ) {
+                        // breakpoint was removed, no need report it anymore
+                        break;
+                    }
+                    intf = local.intf;
+                } else {
+                    intf = intf->m_next;
+                }
+            }
+            bp = local.bp_next;
+            if( bp && !(bp->method == method && bp->location == location) ) {
+                bp = find_next_breakpoint(bp, method, location);
             }
         }
     }
-
-    clear_intfs_processed_flags();
     unlock();
 
     return orig_byte;
 }
 
-void
-VMBreakPoints::clear_breakpoints_processed_flags()
-{
-    LMAutoUnlock lock(get_lock());
+//////////////////////////////////////////////////////////////////////////////
+// VMBreakInterface implementation
 
-    for(VMBreakPoint *bp = m_break; bp; bp = bp->next ) {
-        set_breakpoint_processed( bp, false );
-    }
+static bool insert_native_breakpoint(VMBreakPoint *bp)
+{
+    return VM_Global_State::loader_env->
+        TI->vm_brpt->insert_native_breakpoint(bp);
 }
 
-VMBreakPoint*
-VMBreakPoints::get_none_processed_breakpoint(NativeCodePtr addr)
+static bool insert_interpreter_breakpoint(VMBreakPoint *bp)
 {
-    LMAutoUnlock lock(get_lock());
-
-    for(VMBreakPoint *bp = find_breakpoint(addr);
-        bp;
-        bp = find_next_breakpoint(bp, addr) )
-    {
-        if(!breakpoint_is_processed(bp)) {
-            return bp;
-        }
-    }
+    return VM_Global_State::loader_env->
+        TI->vm_brpt->insert_interpreter_breakpoint(bp);
+}
 
-    return NULL;
+static bool remove_native_breakpoint(VMBreakPoint *bp)
+{
+    return VM_Global_State::loader_env->
+        TI->vm_brpt->remove_native_breakpoint(bp);
 }
 
-void
-VMBreakPoints::clear_intfs_processed_flags()
+static bool remove_interpreter_breakpoint(VMBreakPoint *bp)
 {
-    LMAutoUnlock lock(get_lock());
+    return VM_Global_State::loader_env->
+        TI->vm_brpt->remove_interpreter_breakpoint(bp);
+}
 
-    for(unsigned index = 0; index < PRIORITY_NUMBER; index++ ) {
-        for (VMBreakInterface* intf = m_intf[index]; intf; intf = intf->m_next) {
-            intf->set_processed(false);
-        }
+VMBreakInterface::VMBreakInterface(TIEnv *env,
+                 BPInterfaceCallBack callback,
+                 unsigned priority,
+                 bool is_interp)
+    : m_next(NULL), breakpoint_event_callback(callback), m_list(NULL),
+      m_env(env), m_priority(priority)
+{
+    if(is_interp) {
+        breakpoint_insert = &insert_interpreter_breakpoint;
+        breakpoint_remove = &remove_interpreter_breakpoint;
+    } else {
+        breakpoint_insert = &insert_native_breakpoint;
+        breakpoint_remove = &remove_native_breakpoint;
     }
 }
 
-VMBreakInterface*
-VMBreakPoints::get_none_processed_intf(unsigned priority)
+inline VMBreakPointRef*
+VMBreakInterface::add_reference_internal(VMBreakPoint *bp, void *data)
 {
-    LMAutoUnlock lock(get_lock());
-
-    for (VMBreakInterface* intf = m_intf[priority]; intf; intf = intf->m_next) {
-        if (!intf->is_processed()) {
-            assert(intf->get_priority() == priority);
-            return intf;
-        }
-    }
+    VMBreakPointRef* bp_ref =
+        (VMBreakPointRef*)STD_MALLOC(sizeof(VMBreakPointRef));
+    assert(bp_ref);
 
-    return NULL;
-}
+    bp_ref->bp = bp;
+    bp_ref->data = data;
+    bp_ref->next = m_list;
+    m_list = bp_ref;
 
+    TRACE2("jvmti.break.intf", "Added ref on breakpoint: "
+        << (bp->method
+            ? class_get_name(method_get_class((Method*)bp->method)) : "(nil)" )
+        << "."
+        << (bp->method ? method_get_name((Method*)bp->method) : "(nil)")
+        << (bp->method ? method_get_descriptor((Method*)bp->method) : "")
+        << " :" << bp->location << " :" << bp->addr << ", data: " << data);
 
-//////////////////////////////////////////////////////////////////////////////
-// VMBreakInterface implementation
+    return bp_ref;
+}
 
-VMBreakPointRef* VMBreakInterface::add(jmethodID method, jlocation location, void* data)
+VMBreakPointRef*
+VMBreakInterface::add_reference(jmethodID method, jlocation location, void* data)
 {
     assert(method);
-    assert(!this->find(method, location));
 
     VMBreakPoints* vm_brpt = VM_Global_State::loader_env->TI->vm_brpt;
-    VMBreakPoint* brpt = vm_brpt->find_breakpoint(method, location);
+    LMAutoUnlock lock(vm_brpt->get_lock());
+
+    // find existing reference
+    VMBreakPointRef *ref = find_reference(method, location);
+    if( ref && ref->data == data ) {
+        return ref;
+    }
 
+    VMBreakPoint* brpt = vm_brpt->find_breakpoint(method, location);
     if (!brpt)
     {
         brpt = (VMBreakPoint*)STD_MALLOC(sizeof(VMBreakPoint));
         assert(brpt);
 
-        brpt->is_interp = m_is_interp;
         brpt->addr = NULL;
         brpt->method = method;
         brpt->location = location;
         brpt->saved_byte = 0;
         brpt->disasm = NULL;
-        brpt->is_processed = false;
 
         // Insert breakpoint, possibly to the same native address
-        if (!vm_brpt->insert_breakpoint(brpt))
+        if (!breakpoint_insert(brpt))
         {
             STD_FREE(brpt);
             return false;
         }
     }
-
-    VMBreakPointRef* brpt_ref =
-        (VMBreakPointRef*)STD_MALLOC(sizeof(VMBreakPointRef));
-    assert(brpt_ref);
-
-    brpt_ref->brpt = brpt;
-    brpt_ref->data = data;
-    brpt_ref->next = m_list;
-    m_list = brpt_ref;
-
-    TRACE2("jvmti.break.intf", "Added ref on breakpoint: "
-        << class_get_name(method_get_class((Method*)brpt_ref->brpt->method)) << "."
-        << method_get_name((Method*)brpt_ref->brpt->method)
-        << method_get_descriptor((Method*)brpt_ref->brpt->method)
-        << " :" << brpt_ref->brpt->location << " :" << brpt_ref->brpt->addr);
-
-    return brpt_ref;
+    return add_reference_internal( brpt, data );
 }
 
-VMBreakPointRef* VMBreakInterface::add(jmethodID method, jlocation location,
-                            NativeCodePtr addr, void* data)
+VMBreakPointRef*
+VMBreakInterface::add_reference(jmethodID method, jlocation location,
+                                NativeCodePtr addr, void* data)
 {
     assert(method);
-    assert(!this->find(method, location));
 
     VMBreakPoints* vm_brpt = VM_Global_State::loader_env->TI->vm_brpt;
+    LMAutoUnlock lock(vm_brpt->get_lock());
+
+    // find existing reference
+    VMBreakPointRef *ref = find_reference(method, location);
+    if( ref && (!addr || addr == ref->bp->addr) && data == ref->data ) {
+        return ref;
+    }
+
     VMBreakPoint* brpt = vm_brpt->find_breakpoint(method, location);
 
     // If breakpoint with the same method location is not found or
@@ -783,104 +1047,81 @@
         brpt = (VMBreakPoint*)STD_MALLOC(sizeof(VMBreakPoint));
         assert(brpt);
 
-        brpt->is_interp = m_is_interp;
         brpt->addr = addr;
         brpt->method = method;
         brpt->location = location;
         brpt->saved_byte = 0;
         brpt->disasm = NULL;
-        brpt->is_processed = false;
 
-        if (!vm_brpt->insert_breakpoint(brpt))
+        if (!breakpoint_insert(brpt))
         {
             STD_FREE(brpt);
             return false;
         }
     }
-
-    VMBreakPointRef* brpt_ref =
-        (VMBreakPointRef*)STD_MALLOC(sizeof(VMBreakPointRef));
-    assert(brpt_ref);
-
-    brpt_ref->brpt = brpt;
-    brpt_ref->data = data;
-    brpt_ref->next = m_list;
-    m_list = brpt_ref;
-
-    TRACE2("jvmti.break.intf", "Added ref on breakpoint: "
-        << class_get_name(method_get_class((Method*)brpt_ref->brpt->method)) << "."
-        << method_get_name((Method*)brpt_ref->brpt->method)
-        << method_get_descriptor((Method*)brpt_ref->brpt->method)
-        << " :" << brpt_ref->brpt->location << " :" << brpt_ref->brpt->addr);
-
-    return brpt_ref;
+    return add_reference_internal( brpt, data );
 }
 
-VMBreakPointRef* VMBreakInterface::add(NativeCodePtr addr, void* data)
+VMBreakPointRef*
+VMBreakInterface::add_reference(NativeCodePtr addr, void* data)
 {
     assert(addr);
-    assert(!this->m_is_interp);
-    assert(!this->find(addr));
+    assert(!interpreter_enabled());
 
     VMBreakPoints* vm_brpt = VM_Global_State::loader_env->TI->vm_brpt;
-    VMBreakPoint* brpt = vm_brpt->find_breakpoint(addr);
+    LMAutoUnlock lock(vm_brpt->get_lock());
 
+    // find existing reference
+    VMBreakPointRef *ref = find_reference(addr);
+    if( ref && ref->data == data ) {
+        return ref;
+    }
+
+    VMBreakPoint* brpt = vm_brpt->find_breakpoint(addr);
     if (!brpt)
     {
         brpt = (VMBreakPoint*)STD_MALLOC(sizeof(VMBreakPoint));
         assert(brpt);
 
-        brpt->is_interp = m_is_interp; // false
         brpt->addr = addr;
         brpt->method = NULL;
         brpt->location = 0;
         brpt->saved_byte = 0;
         brpt->disasm = NULL;
-        brpt->is_processed = false;
 
         // Insert breakpoint, possibly duplicating breakpoint with method != NULL
-        if (!vm_brpt->insert_breakpoint(brpt))
+        if (!breakpoint_insert(brpt))
         {
             STD_FREE(brpt);
             return false;
         }
     }
-
-    VMBreakPointRef* brpt_ref =
-        (VMBreakPointRef*)STD_MALLOC(sizeof(VMBreakPointRef));
-    assert(brpt_ref);
-
-    brpt_ref->brpt = brpt;
-    brpt_ref->data = data;
-    brpt_ref->next = m_list;
-    m_list = brpt_ref;
-
-    TRACE2("jvmti.break.intf", "Added ref on breakpoint: "
-        << class_get_name(method_get_class((Method*)brpt_ref->brpt->method)) << "."
-        << method_get_name((Method*)brpt_ref->brpt->method)
-        << method_get_descriptor((Method*)brpt_ref->brpt->method)
-        << " :" << brpt_ref->brpt->location << " :" << brpt_ref->brpt->addr);
-
-    return brpt_ref;
+    return add_reference_internal( brpt, data );
 }
 
-bool VMBreakInterface::remove(VMBreakPointRef* ref)
+bool
+VMBreakInterface::remove_reference(VMBreakPointRef* bp_ref)
 {
-    assert(ref);
-
-    TRACE2("jvmti.break.intf", "Remove ref on breakpoint: "
-        << class_get_name(method_get_class((Method*)ref->brpt->method)) << "."
-        << method_get_name((Method*)ref->brpt->method)
-        << method_get_descriptor((Method*)ref->brpt->method)
-        << " :" << ref->brpt->location << " :" << ref->brpt->addr);
+    assert(bp_ref);
 
     VMBreakPoints* vm_brpt = VM_Global_State::loader_env->TI->vm_brpt;
+    LMAutoUnlock lock(vm_brpt->get_lock());
+
+    TRACE2("jvmti.break.intf", "Remove reference on breakpoint: "
+        << (bp_ref->bp->method
+            ? class_get_name(method_get_class((Method*)bp_ref->bp->method)) : "(nil)")
+        << "."
+        << (bp_ref->bp->method ? method_get_name((Method*)bp_ref->bp->method) : "(nil)")
+        << (bp_ref->bp->method ? method_get_descriptor((Method*)bp_ref->bp->method) : "")
+        << " :" << bp_ref->bp->location << " :" << bp_ref->bp->addr
+        << ", data: " << bp_ref->data );
+
     VMBreakPointRef* found = NULL;
 
     for (VMBreakPointRef** cur_ptr = &m_list;
          *cur_ptr; cur_ptr = &(*cur_ptr)->next)
     {
-        if (*cur_ptr == ref)
+        if (*cur_ptr == bp_ref)
         {
             found = *cur_ptr;
             *cur_ptr = (*cur_ptr)->next;
@@ -890,7 +1131,7 @@
 
     assert(found);
 
-    VMBreakPoint* brpt = found->brpt;
+    VMBreakPoint* brpt = found->bp;
     assert(brpt);
 
     if (found->data)
@@ -901,22 +1142,23 @@
     if (vm_brpt->find_other_reference(this, brpt))
         return true; // There are some other references to the same breakpoint
 
-    if (!vm_brpt->remove_breakpoint(brpt))
+    if (!breakpoint_remove(brpt))
         return false;
 
     STD_FREE(brpt);
     return true;
 }
 
-VMBreakPointRef* VMBreakInterface::find(jmethodID method, jlocation location)
+VMBreakPointRef*
+VMBreakInterface::find_reference(jmethodID method, jlocation location)
 {
     assert(method);
 
     for (VMBreakPointRef* ref = m_list; ref; ref = ref->next)
     {
-        if (ref->brpt->method &&
-            ref->brpt->method == method &&
-            ref->brpt->location == location)
+        if (ref->bp->method &&
+            ref->bp->method == method &&
+            ref->bp->location == location)
         {
             return ref;
         }
@@ -925,13 +1167,14 @@
     return NULL;
 }
 
-VMBreakPointRef* VMBreakInterface::find(NativeCodePtr addr)
+VMBreakPointRef*
+VMBreakInterface::find_reference(NativeCodePtr addr)
 {
     assert(addr);
 
     for (VMBreakPointRef* ref = m_list; ref; ref = ref->next)
     {
-        if (ref->brpt->addr == addr)
+        if (ref->bp->addr == addr)
         {
             return ref;
         }
@@ -940,13 +1183,14 @@
     return NULL;
 }
 
-VMBreakPointRef* VMBreakInterface::find(VMBreakPoint* brpt)
+VMBreakPointRef*
+VMBreakInterface::find_reference(VMBreakPoint* brpt)
 {
     assert(brpt);
 
     for (VMBreakPointRef* ref = m_list; ref; ref = ref->next)
     {
-        if (ref->brpt == brpt)
+        if (ref->bp == brpt)
         {
             return ref;
         }
@@ -955,12 +1199,6 @@
     return NULL;
 }
 
-void VMBreakInterface::remove_all()
-{
-    while (m_list)
-        remove(m_list);
-}
-
 //////////////////////////////////////////////////////////////////////////////
 // Helper functions
 
@@ -972,12 +1210,13 @@
     return (ConditionCode)jump_type;
 }
 
-static bool set_jit_mode_breakpoint(VMBreakPoints* vm_brpt, VMBreakPoint* bp)
+static bool set_jit_mode_breakpoint(VMBreakPoint* bp)
 {
     assert(bp);
 
     // Find native location in the method code
     Method *m = (Method *)bp->method;
+    assert(m);
     assert( m->get_state() == Method::ST_Compiled );
 
     NativeCodePtr np = bp->addr;
@@ -1004,6 +1243,7 @@
         << method_get_name((Method*)bp->method)
         << method_get_descriptor((Method*)bp->method)
         << " :" << bp->location << " :" << bp->addr);
+
     return set_native_breakpoint(bp);
 }
 
@@ -1013,9 +1253,9 @@
     assert(bp->addr);
 
     TRACE2("jvmti.break.intf", "Instrumenting native: "
-        << (bp->method ? class_get_name(method_get_class((Method*)bp->method)) : "" )
+        << (bp->method ? class_get_name(method_get_class((Method*)bp->method)) : "(nil)" )
         << "."
-        << (bp->method ? method_get_name((Method*)bp->method) : "" )
+        << (bp->method ? method_get_name((Method*)bp->method) : "(nil)" )
         << (bp->method ? method_get_descriptor((Method*)bp->method) : "" )
         << " :" << bp->location << " :" << bp->addr);
 
@@ -1088,6 +1328,7 @@
 #else
     NativeCodePtr native_location = (NativeCodePtr)regs->get_ip();
 #endif
+    ASSERT_NO_INTERPRETER;
 
     TRACE2("jvmti.break", "BREAKPOINT occured: " << native_location);
 
@@ -1095,20 +1336,8 @@
     if (!ti->isEnabled() || ti->getPhase() != JVMTI_PHASE_LIVE)
         return false;
 
-    VMBreakPoints* vm_brpt = ti->vm_brpt;
-    vm_brpt->lock();
-    VMBreakPoint* bp = vm_brpt->find_breakpoint(native_location);
-    if (NULL == bp)
-    {
-        vm_brpt->unlock();
-        return false;
-    }
-
-    assert(!interpreter_enabled());
-
     // Now it is necessary to set up a transition to
-    // process_native_breakpoint_event from the exception/signal
-    // handler
+    // process_native_breakpoint_event from the exception/signal handler
     VM_thread *vm_thread = p_TLS_vmthread;
     // Copy original registers to TLS
     vm_thread->jvmti_saved_exception_registers = *regs;
@@ -1117,9 +1346,6 @@
 #else
     regs->rip = (POINTER_SIZE_INT)process_native_breakpoint_event;
 #endif
-
-    // Breakpoints list lock is not released until it is unlocked
-    // inside of process_native_breakpoint_event
     return true;
 }
 
@@ -1139,7 +1365,7 @@
     if( !method->get_pending_breakpoints() )
         return;
 
-    VMBreakPoint* bp = vm_brpt->find_first((jmethodID)method);
+    VMBreakPoint* bp = vm_brpt->find_method_breakpoint((jmethodID)method);
     assert(bp);
 
     jlocation *locations = (jlocation *)STD_MALLOC(sizeof(jlocation) *
@@ -1155,11 +1381,11 @@
             if (bp->location == locations[iii])
                 continue;
 
-        set_jit_mode_breakpoint(vm_brpt, bp);
+        set_jit_mode_breakpoint(bp);
         locations[location_count++] = bp->location;
 
         method->remove_pending_breakpoint();
-        bp = vm_brpt->find_next(bp, (jmethodID)method);
+        bp = vm_brpt->find_next_method_breakpoint(bp, (jmethodID)method);
     }
     while (NULL != bp);
 

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_method.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_method.cpp?view=diff&rev=450053&r1=450052&r2=450053
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_method.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_method.cpp Tue Sep 26 07:10:00 2006
@@ -534,11 +534,8 @@
 
         LMAutoUnlock lock(vm_brpt->get_lock());
 
-        if (!vm_brpt->has_breakpoint(method))
-            return JVMTI_ERROR_NONE;
-
-        for (VMBreakPoint* bpt = vm_brpt->find_first(method); bpt;
-             bpt = vm_brpt->find_next(bpt, method))
+        for (VMBreakPoint* bpt = vm_brpt->find_method_breakpoint(method); bpt;
+             bpt = vm_brpt->find_next_method_breakpoint(bpt, method))
         {
             (*bytecodes_ptr)[bpt->location] =
                 (unsigned char)bpt->saved_byte;

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=450053&r1=450052&r2=450053
==============================================================================
--- 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 Sep 26 07:10:00 2006
@@ -342,7 +342,7 @@
                 jit->get_bc_location_for_native(method, ip, &bc);
             assert(EXE_ERROR_NONE == result);
 
-            jvmti_StepLocation locations = {method, bc, ip};
+            jvmti_StepLocation locations = {method, ip, bc, false};
             jvmti_set_single_step_breakpoints(ti, vm_thread, &locations, 1);
         }
     }

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=450053&r1=450052&r2=450053
==============================================================================
--- 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 Tue Sep 26 07:10:00 2006
@@ -429,8 +429,7 @@
 } // jvmti_SingleStepLocation
 
 static void
-jvmti_setup_jit_single_step(DebugUtilsTI *ti, VMBreakInterface* intf,
-                            Method* m, jlocation location)
+jvmti_setup_jit_single_step(DebugUtilsTI *ti, Method* m, jlocation location)
 {
     VM_thread* vm_thread = p_TLS_vmthread;
     jvmti_StepLocation *locations;
@@ -444,18 +443,18 @@
     jvmti_set_single_step_breakpoints(ti, vm_thread, locations, locations_count);
 }
 
-static void jvmti_start_single_step_in_virtual_method(DebugUtilsTI *ti, VMBreakInterface* intf,
-    VMBreakPointRef* bp_ref)
+static void jvmti_start_single_step_in_virtual_method(DebugUtilsTI *ti, VMBreakPoint* bp,
+                                                      void *data)
 {
     VM_thread *vm_thread = p_TLS_vmthread;
     Registers *regs = &vm_thread->jvmti_saved_exception_registers;
     // This is a virtual breakpoint set exactly on the call
     // instruction for the virtual method. In this place it is
     // possible to determine the target method in runtime
-    bool *virtual_flag = (bool *)bp_ref->data;
+    bool* UNREF virtual_flag = (bool *)data;
     assert(*virtual_flag == true);
 
-    InstructionDisassembler *disasm = bp_ref->brpt->disasm;
+    InstructionDisassembler *disasm = bp->disasm;
     const InstructionDisassembler::Opnd& op = disasm->get_opnd(0);
     Method *method;
     if (op.kind == InstructionDisassembler::Kind_Mem)
@@ -504,20 +503,20 @@
         }
     }
 
-    TRACE2("jvmti.break.ss", "Removing VIRTUAL single step breakpoint: " << bp_ref->brpt->addr);
+    TRACE2("jvmti.break.ss", "Removing VIRTUAL single step breakpoint: " << bp->addr);
     // The determined method is the one which is called by
     // invokevirtual or invokeinterface bytecodes. It should be
     // started to be single stepped from the beginning
-    intf->remove_all();
+    jvmti_remove_single_step_breakpoints(ti, vm_thread);
 
     jvmti_StepLocation method_start = {(Method *)method, 0};
     jvmti_set_single_step_breakpoints(ti, vm_thread, &method_start, 1);
 }
 
 // Callback function for JVMTI single step processing
-static bool jvmti_process_jit_single_step_event(VMBreakInterface* intf, VMBreakPointRef* bp_ref)
+static bool jvmti_process_jit_single_step_event(TIEnv* UNREF unused_env,
+                                                VMBreakPoint* bp, void *data)
 {
-    VMBreakPoint* bp = bp_ref->brpt;
     assert(bp);
 
     TRACE2("jvmti.break.ss", "SingleStep occured: "
@@ -541,9 +540,9 @@
     NativeCodePtr addr = bp->addr;
     assert(addr);
 
-    if (NULL != bp_ref->data)
+    if (NULL != data)
     {
-        jvmti_start_single_step_in_virtual_method(ti, intf, bp_ref);
+        jvmti_start_single_step_in_virtual_method(ti, bp, data);
         return true;
     }
 
@@ -574,10 +573,10 @@
                     << method_get_name((Method*)method)
                     << method_get_descriptor((Method*)method)
                     << " :" << location << " :" << addr);
+
                 // fire global event
-                intf->unlock();
                 func((jvmtiEnv*)env, jni_env, (jthread)hThread, method, location);
-                intf->lock();
+
                 TRACE2("jvmti.break.ss",
                     "Finished JIT global SingleStep breakpoint callback: "
                     << class_get_name(method_get_class((Method*)method)) << "."
@@ -606,10 +605,10 @@
                         << method_get_descriptor((Method*)method)
                         << " :" << location << " :" << addr);
                     found = true;
-                    intf->unlock();
+
                     func((jvmtiEnv*)env, jni_env,
                         (jthread)hThread, method, location);
-                    intf->lock();
+
                     TRACE2("jvmti.break.ss",
                         "Finished JIT local SingleStep breakpoint callback: "
                         << class_get_name(method_get_class((Method*)method)) << "."
@@ -625,7 +624,7 @@
 
     // Set breakpoints on bytecodes after the current one
     if (ti->is_single_step_enabled())
-        jvmti_setup_jit_single_step(ti, intf, m, location);
+        jvmti_setup_jit_single_step(ti, m, location);
 
     tmn_suspend_disable();
     oh_discard_local_handle(hThread);
@@ -646,7 +645,7 @@
         // Create SS breakpoints list
         // Single Step must be processed earlier then Breakpoints
         ss_state->predicted_breakpoints =
-            ti->vm_brpt->new_intf(jvmti_process_jit_single_step_event,
+            ti->vm_brpt->new_intf( NULL, jvmti_process_jit_single_step_event,
                 PRIORITY_SINGLE_STEP_BREAKPOINT, false);
         assert(ss_state->predicted_breakpoints);
     }
@@ -673,10 +672,11 @@
         }
 
         VMBreakPointRef* ref =
-            ss_state->predicted_breakpoints->add((jmethodID)locations[iii].method,
-                                                  locations[iii].location,
-                                                  locations[iii].native_location,
-                                                  data);
+            ss_state->predicted_breakpoints->add_reference(
+                (jmethodID)locations[iii].method,
+                locations[iii].location,
+                locations[iii].native_location,
+                data);
         assert(ref);
     }
 }
@@ -689,7 +689,7 @@
     TRACE2("jvmti.break.ss", "Remove single step breakpoints");
 
     if (ss_state && ss_state->predicted_breakpoints)
-        ss_state->predicted_breakpoints->remove_all();
+        ss_state->predicted_breakpoints->remove_all_reference();
 }
 
 jvmtiError jvmti_get_next_bytecodes_from_native(VM_thread *thread,



Mime
View raw message