harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gshiman...@apache.org
Subject svn commit: r540622 - in /harmony/enhanced/drlvm/trunk: src/test/regression/H3698/ src/test/regression/excludes/ vm/vmcore/include/ vm/vmcore/src/jvmti/
Date Tue, 22 May 2007 15:58:55 GMT
Author: gshimansky
Date: Tue May 22 08:58:54 2007
New Revision: 540622

URL: http://svn.apache.org/viewvc?view=rev&rev=540622
Log:
Applied HARMONY-3698 [drlvm][jvmti] location of EXCEPTION event differs from location of top
stack frame


Added:
    harmony/enhanced/drlvm/trunk/src/test/regression/H3698/
    harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.cpp   (with props)
    harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.java   (with
props)
    harmony/enhanced/drlvm/trunk/src/test/regression/H3698/run.test.xml   (with props)
Modified:
    harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64
    harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.cpp?view=auto&rev=540622
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.cpp (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.cpp Tue May 22
08:58:54 2007
@@ -0,0 +1,188 @@
+/**
+ * Test case for Exception event location parameter.
+ * Checks that location parameter for Exception is the same as location in
+ * topmost stack frame.
+*/
+
+#include <iostream>
+#include <jvmti.h>
+
+using namespace std;
+
+#define PACKAGE "org/apache/harmony/drlvm/tests/regression/h3698/"
+
+static const char* EXCEPTION_CLASS = "L" PACKAGE "InvokeAgentException;";
+
+static void set_passed_state(JNIEnv* jni)
+{
+    cerr << endl << "TEST PASSED" << endl << endl;
+
+    jclass cl = jni->FindClass(PACKAGE "Status");
+    if (NULL == cl) {
+        cerr << "unable to find 'Status' class" << endl;
+        return;
+    }
+
+    jfieldID fid = jni->GetStaticFieldID(cl, "status", "Z");
+    if (NULL == fid) {
+        cerr << "unable to find 'status' field" << endl;
+        return;
+    }
+
+    jni->SetStaticBooleanField(cl, fid, JNI_TRUE);
+}
+
+static jvmtiError turn_event(jvmtiEnv* jvmti, jvmtiEvent event, bool state,
+        const char* event_name)
+{
+    jvmtiError err;
+    err = jvmti->SetEventNotificationMode(state ? JVMTI_ENABLE : JVMTI_DISABLE,
+            event, NULL);
+    if (JVMTI_ERROR_NONE != err) {
+        cerr << "[JvmtiAgent] ERROR: unable to " << (state ? "en" : "dis")
+                << "able " << event_name
+                << endl;
+    }
+
+    return err;
+}
+
+#define TURN_EVENT(event, state) { \
+    jvmtiError err = turn_event(jvmti, event, state, #event); \
+    if (JVMTI_ERROR_NONE != err) return; \
+}
+
+#define CHECK_RESULT(func) \
+    if (JVMTI_ERROR_NONE != err) { \
+        cerr << "[JvmtiAgent] ERROR: " << #func << " failed with error:
" << err << endl;  \
+        return; \
+    }
+
+#define CHECK_JNI(result, func) \
+    if (NULL == (result)) { \
+        cerr << "[JvmtiAgent] ERROR: " << #func << " failed." <<
endl;  \
+        return; \
+    }
+
+
+static void JNICALL VMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread)
+{
+    cerr << endl << "==> VM Init callback" << endl;
+
+    TURN_EVENT(JVMTI_EVENT_EXCEPTION, true);
+}
+
+static void JNICALL
+Exception(jvmtiEnv *jvmti,
+            JNIEnv* jni,
+            jthread thread,
+            jmethodID method,
+            jlocation location,
+            jobject exception,
+            jmethodID catch_method,
+            jlocation catch_location)
+{
+    jvmtiError err;
+
+    jclass exn_class = jni->GetObjectClass(exception);
+    CHECK_JNI(exn_class, GetObjectClass);
+
+    char* class_name = NULL;
+    err = jvmti->GetClassSignature(exn_class, &class_name, NULL);
+    CHECK_RESULT(GetClassSignature);
+
+    if (0 != strcmp(EXCEPTION_CLASS, class_name))
+        return;
+
+    cerr << endl << "==> Exception callback" << endl;
+    cerr << "    for class: " << class_name << endl;
+
+    TURN_EVENT(JVMTI_EVENT_EXCEPTION, false);
+
+    char* method_name = NULL;
+    char* method_sig = NULL;
+    err = jvmti->GetMethodName(method, &method_name, &method_sig, NULL);
+    CHECK_RESULT(GetMethodName);
+
+    cerr << "Exception location:\t" << method_name << method_sig
+            << "\t: " << location << endl;;
+
+    char* catch_method_name = NULL;
+    char* catch_method_sig = NULL;
+    err = jvmti->GetMethodName(catch_method, &catch_method_name, &catch_method_sig,
NULL);
+    CHECK_RESULT(GetMethodName);
+
+    cerr << "Catch clause location:\t" << catch_method_name << catch_method_sig
+            << "\t: " << catch_location << endl;;
+
+
+    jint frame_count = 0;
+    const jint max_frame_count = 1;
+    jvmtiFrameInfo frames[max_frame_count];
+
+    err = jvmti->GetStackTrace(NULL, 0, max_frame_count, frames, &frame_count);
+    CHECK_RESULT(GetStackTrace);
+
+    char *frame_method_name = NULL;
+    char *frame_method_sig = NULL;
+    err = jvmti->GetMethodName(frames[0].method, &frame_method_name, &frame_method_sig,
NULL);
+    CHECK_RESULT(GetMethodName);
+    cerr << "Top frame location:\t" << frame_method_name << frame_method_sig
+            << "\t: " << frames[0].location << endl;
+
+    if (0 == strcmp(method_name, frame_method_name) &&
+        0 == strcmp(method_sig, frame_method_sig) &&
+        location == frames[0].location) {
+        set_passed_state(jni);
+    } else {
+        cerr << endl << "Exception location doesn't match top frame location"
<< endl;
+    }
+}
+
+JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+{
+    jvmtiEnv *jvmti = NULL;
+    jvmtiError err;
+
+    // Get JVMTI interface pointer
+    jint iRes = vm->GetEnv((void**)&jvmti, JVMTI_VERSION);
+    if (JNI_OK != iRes) {
+        cerr << "[JvmtiAgent] ERROR: unable to get JVMTI environment" << endl;
+        return -1;
+    }
+
+    // Set events callbacks
+    jvmtiEventCallbacks callbacks;
+    memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
+
+    callbacks.VMInit = VMInit;
+    callbacks.Exception = Exception;
+
+    err = jvmti->SetEventCallbacks(&callbacks, sizeof(jvmtiEventCallbacks));
+    if (JVMTI_ERROR_NONE != err) {
+        cerr << "[JvmtiAgent] ERROR: unable to register event callbacks" << endl;
+        return -1;
+    }
+
+    err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
+            JVMTI_EVENT_VM_INIT, NULL);
+    if (JVMTI_ERROR_NONE != err) {
+        cerr << "[JvmtiAgent] ERROR: unable to enable VMInit event"
+                << endl;
+        return -1;
+    }
+
+    // Set capabilities
+    jvmtiCapabilities capabilities;
+    memset(&capabilities, 0, sizeof(jvmtiCapabilities));
+    capabilities.can_generate_exception_events = 1;
+
+    err = jvmti->AddCapabilities(&capabilities);
+    if (JVMTI_ERROR_NONE != err) {
+        cerr << "[JvmtiAgent] ERROR: unable to possess capabilities" << endl;
+        return -1;
+    }
+
+    // Agent initialized successfully
+    return 0;
+}

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.java?view=auto&rev=540622
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.java Tue May
22 08:58:54 2007
@@ -0,0 +1,32 @@
+package org.apache.harmony.drlvm.tests.regression.h3698;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for Exception event location parameter.
+ */
+public class ExceptionLocation extends TestCase {
+
+    public static void main(String args[]) {
+        (new ExceptionLocation()).test();
+    }
+
+    public void test() {
+        try {
+            System.out.println("[Java]: Throwing an exception");
+            throw new InvokeAgentException();
+        } catch (Exception e) {
+            System.out.println("[Java]: Exception caught");
+        }
+
+        System.out.println("[Java]: test done");
+        assertTrue(Status.status);
+    }
+}
+
+class InvokeAgentException extends Exception {}
+
+class Status {
+    /** the field should be modified by jvmti agent to determine test result. */
+    public static boolean status = false;
+}

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3698/ExceptionLocation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3698/run.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3698/run.test.xml?view=auto&rev=540622
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3698/run.test.xml (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3698/run.test.xml Tue May 22 08:58:54
2007
@@ -0,0 +1,9 @@
+<project name="RUN HARMONY-3698 Regression Test">
+    <target name="run-test">
+        <!-- use special launcher for JVMTI tests -->
+        <run-jvmti-test
+            test="org.apache.harmony.drlvm.tests.regression.h3698.ExceptionLocation"
+            agent="ExceptionLocation"/>
+    </target>
+</project>
+

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3698/run.test.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64?view=diff&rev=540622&r1=540621&r2=540622
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64 (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64 Tue May
22 08:58:54 2007
@@ -5,4 +5,6 @@
 H3228
 # Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
 H3730
+# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
+H3698
 

Modified: harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64?view=diff&rev=540622&r1=540621&r2=540622
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64 (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64 Tue May
22 08:58:54 2007
@@ -2,5 +2,6 @@
 H3027
 # Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
 H3730
-
+# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
+H3698
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h?view=diff&rev=540622&r1=540621&r2=540622
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h Tue May 22 08:58:54 2007
@@ -91,7 +91,7 @@
 };
 
 jint JNICALL create_jvmti_environment(JavaVM *vm, void **env, jint version);
-jint get_thread_stack_depth(VM_thread *thread, jint* pskip = NULL);
+jint get_thread_stack_depth(VM_thread *thread);
 void jvmti_get_compilation_flags(OpenMethodExecutionParams *flags);
 
 // Marks topmost frame of the specified thead to be popped

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp?view=diff&rev=540622&r1=540621&r2=540622
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp Tue May 22 08:58:54 2007
@@ -873,8 +873,7 @@
 
     // processing PopFrame event
     VM_thread *curr_thread = p_TLS_vmthread;
-    jint UNREF skip;
-    jint depth = get_thread_stack_depth(curr_thread, &skip);
+    jint depth = get_thread_stack_depth(curr_thread);
 
 #ifndef NDEBUG
     if( curr_thread->frame_pop_listener ) {

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp?view=diff&rev=540622&r1=540621&r2=540622
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp Tue May 22 08:58:54 2007
@@ -14,14 +14,16 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-/** 
+/**
  * @author Gregory Shimansky, Pavel Afremov
  * @version $Revision: 1.1.2.2.4.5 $
- */  
+ */
 /*
  * JVMTI stack frame API
  */
 
+#define LOG_DOMAIN "jvmti.stack"
+
 #include "jvmti_direct.h"
 #include "jvmti_utils.h"
 #include "interpreter_exports.h"
@@ -40,6 +42,137 @@
 
 #define jvmti_test_jenv (p_TLS_vmthread->jni_env)
 
+class JavaStackIterator
+{
+    StackIterator* si;
+
+    /** index of current java stack frame */
+    jint depth;
+
+    /** number of inlines in current si frame */
+    uint32 inlined_num;
+
+    /** index of inlined frame in current si frame */
+    int inlined_depth;
+
+    bool past_end;
+
+    void update() {
+        Method_Handle method = NULL;
+
+        // skip non java frames
+        while (! si_is_past_end(si) && NULL == (method = si_get_method(si)))
+            si_goto_previous(si);
+
+        // end of stack
+        if (NULL == method) {
+            past_end = true;
+            return;
+        }
+
+        // hide vm specific stack tail
+        if (0 == strcmp("runImpl", method_get_name(method))) {
+            const char* class_name = class_get_name(method_get_class(method));
+
+            if (0 == strcmp("java/lang/VMStart$MainThread", class_name) ||
+                0 == strcmp("java/lang/Thread", class_name)) {
+                    past_end = true;
+                    return;
+            }
+        }
+
+        inlined_num = si_get_inline_depth(si);
+        inlined_depth = inlined_num;
+    }
+
+public:
+    ~JavaStackIterator() {
+        si_free(si);
+    }
+
+    JavaStackIterator(VM_thread *thread) {
+        si = si_create_from_native(thread);
+        depth = 0;
+        past_end = false;
+        update();
+    }
+
+    StackIterator* get_si() {
+        return si;
+    }
+
+    jint get_depth() {
+        return depth;
+    }
+
+    bool is_inlined() {
+        return 0 != inlined_depth;
+    }
+
+    bool is_jni() {
+        return si_is_native(si);
+    }
+
+    operator bool () {
+        return ! past_end;
+    }
+
+    void operator ++ (int) {
+        assert(! past_end);
+
+        depth++;
+
+        if (inlined_depth > 0) {
+            inlined_depth--;
+        } else {
+            si_goto_previous(si);
+            update();
+        }
+    }
+
+    void operator += (int frames_num) {
+        for (; frames_num > 0 && *this; frames_num--, (*this)++);
+    }
+
+    void get_location(jmethodID* p_method, jlocation* p_location) {
+        Method* method = si_get_method(si);
+
+        // jni method frame
+        if (si_is_native(si)) {
+            *p_method = (jmethodID) method;
+            *p_location = -1;
+            return;
+        }
+
+        // java frame
+        NativeCodePtr ip = si_get_ip(si);
+
+        // if ip points to next instruction
+        if (si_get_jit_context(si)->is_ip_past) {
+            ip = (NativeCodePtr) ((char*) ip - 1);
+        }
+
+        CodeChunkInfo *cci = si_get_code_chunk_info(si);
+        JIT *jit = cci->get_jit();
+
+        // inlined method frame
+        if (0 != inlined_depth) {
+            uint32 offset = (uint32) ((char*) ip -
+                (char*) cci->get_code_block_addr());
+            method = jit->get_inlined_method(
+                cci->get_inline_info(), offset, inlined_num - inlined_depth);
+        }
+
+        uint16 bc;
+        OpenExeJpdaError UNREF result = jit->get_bc_location_for_native(
+                method, ip, &bc);
+        assert(result == EXE_ERROR_NONE);
+
+        *p_method = (jmethodID) method;
+        *p_location = (jlocation) bc;
+    }
+};
+
 jthread getCurrentThread() {
     jthread current_thread = jthread_self();
     assert(current_thread);
@@ -47,45 +180,49 @@
     return oh_copy_to_local_handle(current_thread);
 }
 
-jint get_thread_stack_depth(VM_thread *thread, jint* pskip)
-{
-    StackIterator* si = si_create_from_native(thread);
-    jint depth = 0;
-    Method_Handle method = NULL;
 
-    jint skip = 0;
+jint get_thread_stack_depth(VM_thread *thread)
+{
+    JavaStackIterator jsi(thread);
 
-    while (!si_is_past_end(si))
-    {
-        method = si_get_method(si);
+    while (jsi)
+        jsi++;
 
-        if (method)
-        {
-            depth += 1 + si_get_inline_depth(si);
+    return jsi.get_depth();
+} // get_thread_stack_depth
 
-            Class *clss = method_get_class(method);
-            assert(clss);
+static jvmtiError get_stack_trace_jit(
+        VM_thread* vm_thread,
+        jint start_depth,
+        jint max_frame_count,
+        jvmtiFrameInfo* frame_buffer,
+        jint* count_ptr)
+{
+    jint start = start_depth;
 
-            if (!strcmp(method_get_name(method), "runImpl")) {
-                if(!strcmp(class_get_name(clss), "java/lang/VMStart$MainThread")) {
-                    skip = 3;
-                } else if(!strcmp(class_get_name(clss), "java/lang/Thread")) {
-                    skip = 1;
-                }
-            }
-        }
+    if (start < 0) {
+        start = start + get_thread_stack_depth(vm_thread);
 
-        si_goto_previous(si);
+        if (start < 0)
+            return JVMTI_ERROR_ILLEGAL_ARGUMENT;
     }
 
-    depth -= skip;
+    JavaStackIterator jsi(vm_thread);
 
-    if (pskip)
-        *pskip = skip;
+    jsi += start;
 
-    si_free(si);
-    return depth;
-}
+    if (! jsi)
+        return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+
+    jint i = 0;
+    for (; i < max_frame_count && jsi; i++, jsi++) {
+        jsi.get_location(& frame_buffer[i].method, & frame_buffer[i].location);
+    }
+
+    *count_ptr = i;
+
+    return JVMTI_ERROR_NONE;
+} // get_stack_trace_jit
 
 /*
  * Get Stack Trace
@@ -107,9 +244,8 @@
                    jvmtiFrameInfo* frame_buffer,
                    jint* count_ptr)
 {
-    TRACE2("jvmti.stack", "GetStackTrace called");
+    TRACE("GetStackTrace called");
     SuspendEnabledChecker sec;
-    jint state;
     jvmtiError err;
 
     /*
@@ -120,6 +256,7 @@
     CHECK_EVERYTHING();
 
     // check error condition: JVMTI_ERROR_INVALID_THREAD
+    jint state;
     err = jvmtiGetThreadState(env, thread, &state);
 
     if (err != JVMTI_ERROR_NONE) {
@@ -162,125 +299,17 @@
     else
         vm_thread = p_TLS_vmthread;
 
-    jvmtiError errStack;
     if (interpreter_enabled())
-        // check error condition: JVMTI_ERROR_ILLEGAL_ARGUMENT
-        errStack = interpreter.interpreter_ti_getStackTrace(env,
+        err = interpreter.interpreter_ti_getStackTrace(env,
             vm_thread, start_depth, max_frame_count, frame_buffer, count_ptr);
     else
-    {
-        jint start, skip = 0;
-        jint depth = get_thread_stack_depth(vm_thread, &skip);
-
-        if (start_depth < 0)
-        {
-            start = depth + start_depth;
-            if (start < 0)
-            {
-                if (thread_suspended)
-                    jthread_resume(thread);
-                return JVMTI_ERROR_ILLEGAL_ARGUMENT;
-            }
-        }
-        else
-            start = start_depth;
-
-        StackIterator *si = si_create_from_native(vm_thread);
-        jint count = 0;
-        jint stack_depth = 0;
-        jint max_depth = depth;
-        while (!si_is_past_end(si) && count < max_frame_count &&
-               count < max_depth)
-        {
-            jint inlined_depth = si_get_inline_depth(si);
-            if (stack_depth + inlined_depth >= start)
-            {
-                Method *method = si_get_method(si);
-                if (NULL != method)
-                {
-                    CodeChunkInfo *cci = si_get_code_chunk_info(si);
-                    if (NULL != cci)
-                    {
-                        NativeCodePtr ip = si_get_ip(si);
-                        // FIXME64: missing support for methods
-                        // with compiled code greater than 2GB
-                        uint32 offset = (uint32)((POINTER_SIZE_INT)ip -
-                            (POINTER_SIZE_INT)cci->get_code_block_addr());
-                        JIT *jit = cci->get_jit();
-
-                        uint16 bc;
-                        for (jint iii = 0;
-                             iii < inlined_depth && count < max_frame_count
&&
-                             count < max_depth; iii++)
-                        {
-                            if (stack_depth >= start)
-                            {
-                                Method *inlined_method = jit->get_inlined_method(
-                                    cci->get_inline_info(), offset, iii);
-
-                                OpenExeJpdaError UNREF result =
-                                    jit->get_bc_location_for_native(
-                                        inlined_method, ip, &bc);
-                                assert(result == EXE_ERROR_NONE);
-
-                                if (0 < stack_depth - iii) {
-                                    bc--;
-                                }
-                                frame_buffer[count].location = bc;
-                                frame_buffer[count].method =
-                                    reinterpret_cast<jmethodID>(method);
-                                count++;
-                            }
-                            stack_depth++;
-                        }
-
-                        // With all inlines we could've moved past the user limit
-                        if (count < max_frame_count && count < max_depth)
-                        {
-                            OpenExeJpdaError UNREF result =
-                                jit->get_bc_location_for_native(
-                                    method, ip, &bc);
-                            assert(result == EXE_ERROR_NONE);
-
-                            if (0 < stack_depth - inlined_depth) {
-                                bc--;
-                            }
-                            frame_buffer[count].location = bc;
-                        }
-                    }
-                    else
-                    {
-                        assert(si_is_native(si));
-                        frame_buffer[count].location = -1;
-                    }
-
-                    // With all inlines we could've moved past the user limit
-                    if (count < max_frame_count)
-                    {
-                        frame_buffer[count].method =
-                            reinterpret_cast<jmethodID>(method);
-                        count++;
-                    }
-
-                    stack_depth++;
-                }
-            }
-            si_goto_previous(si);
-        }
-
-        *count_ptr = count;
-        if (si_is_past_end(si) && count == 0)
-            errStack = JVMTI_ERROR_ILLEGAL_ARGUMENT;
-        else
-            errStack = JVMTI_ERROR_NONE;
-        si_free(si);
-    }
+        err = get_stack_trace_jit(vm_thread, start_depth, max_frame_count, frame_buffer,
count_ptr);
 
     if (thread_suspended)
         jthread_resume(thread);
 
-    return errStack;
-}
+    return err;
+} // jvmtiGetStackTrace
 
 /*
  * Get All Stack Traces
@@ -299,7 +328,7 @@
                        jvmtiStackInfo** stack_info_ptr,
                        jint* thread_count_ptr)
 {
-    TRACE2("jvmti.stack", "GetAllStackTraces called");
+    TRACE("GetAllStackTraces called");
     SuspendEnabledChecker sec;
     jint count;
     jthread *threads;
@@ -345,11 +374,12 @@
     }
 
     // getting thread states
-    for(int i = 0; i < count; i++) {
+    for (int i = 0; i < count; i++) {
         info[i].thread = threads[i];
         res = jvmtiGetThreadState(env, threads[i], &info[i].state);
 
         if (JVMTI_ERROR_NONE != res) {
+            _deallocate((unsigned char *) info);
             hythread_resume_all(NULL);
             return res;
         }
@@ -362,6 +392,7 @@
             info[i].frame_buffer, &info[i].frame_count);
 
         if (JVMTI_ERROR_NONE != res) {
+            _deallocate((unsigned char *) info);
             hythread_resume_all(NULL);
             return res;
         }
@@ -372,7 +403,7 @@
     *thread_count_ptr = count;
     *stack_info_ptr = info;
     return JVMTI_ERROR_NONE;
-}
+} // jvmtiGetAllStackTraces
 
 /*
  * Get Thread List Stack Traces
@@ -392,7 +423,7 @@
                               jint max_frame_count,
                               jvmtiStackInfo** stack_info_ptr)
 {
-    TRACE2("jvmti.stack", "GetThreadListStackTraces called");
+    TRACE("GetThreadListStackTraces called");
     SuspendEnabledChecker sec;
     jint count = thread_count;
     const jthread *threads = thread_list;
@@ -435,8 +466,10 @@
         info[i].thread = threads[i];
         res = jvmtiGetThreadState(env, threads[i], &info[i].state);
 
-        if (JVMTI_ERROR_NONE != res)
+        if (JVMTI_ERROR_NONE != res) {
+            _deallocate((unsigned char *) info);
             return res;
+        }
 
         // FIXME: suspended thread might be resumed in other jvmti thread?
         if (info[i].state != JVMTI_THREAD_STATE_SUSPENDED) {
@@ -473,7 +506,7 @@
 
     *stack_info_ptr = info;
     return JVMTI_ERROR_NONE;
-}
+} // jvmtiGetThreadListStackTraces
 
 /*
  * Get Frame Count
@@ -488,7 +521,7 @@
                    jthread thread,
                    jint* count_ptr)
 {
-    TRACE2("jvmti.stack", "GetFrameCount called");
+    TRACE("GetFrameCount called");
     SuspendEnabledChecker sec;
     jint state;
     jvmtiError err;
@@ -552,7 +585,7 @@
         jthread_resume(thread);
 
     return errStack;
-}
+} // jvmtiGetFrameCount
 
 /*
  * Pop Frame
@@ -566,7 +599,7 @@
 jvmtiPopFrame(jvmtiEnv* env,
               jthread thread)
 {
-    TRACE2("jvmti.stack", "PopFrame called");
+    TRACE("PopFrame called");
     SuspendEnabledChecker sec;
     jint state;
     jvmtiError err;
@@ -586,7 +619,7 @@
     JNIEnv *jni_env = p_TLS_vmthread->jni_env;
 
     jthread curr_thread = getCurrentThread();
-    if (jni_env->IsSameObject(thread,curr_thread) ) {
+    if (jni_env->IsSameObject(thread, curr_thread) ) {
         // cannot pop frame yourself
         return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
     }
@@ -630,7 +663,7 @@
     } else {
         return jvmti_jit_pop_frame(thread);
     }
-}
+} // jvmtiPopFrame
 
 /*
  * Get Frame Location
@@ -647,7 +680,7 @@
                       jmethodID* method_ptr,
                       jlocation* location_ptr)
 {
-    TRACE2("jvmti.stack", "GetFrameLocation called");
+    TRACE("GetFrameLocation called");
     SuspendEnabledChecker sec;
     jint state;
     jvmtiError err;
@@ -715,89 +748,22 @@
             depth, method_ptr, location_ptr);
     else
     {
-        StackIterator* si = si_create_from_native(vm_thread);
-
-        jint stack_depth = 0;
-        bool frame_found = false;
-        while (!si_is_past_end(si))
-        {
-            jint inlined_depth = si_get_inline_depth(si);
-            if (stack_depth + inlined_depth >= depth)
-            {
-                Method *method = si_get_method(si);
-                if (NULL != method)
-                {
-                    CodeChunkInfo *cci = si_get_code_chunk_info(si);
-                    if (NULL != cci)
-                    {
-                        NativeCodePtr ip = si_get_ip(si);
-                        // FIXME64: no support for methods
-                        // with compiled code greated than 4GB
-                        uint32 offset = (uint32)((POINTER_SIZE_INT)ip -
-                            (POINTER_SIZE_INT)cci->get_code_block_addr());
-                        JIT *jit = cci->get_jit();
-
-                        uint16 bc;
-                        if (stack_depth + inlined_depth > depth)
-                        {
-                            // Target frame is inlined
-                            jint inline_depth_method = inlined_depth - depth;
-                            Method *inlined_method = jit->get_inlined_method(
-                                cci->get_inline_info(), offset,
-                                inline_depth_method);
-
-                                OpenExeJpdaError UNREF result =
-                                    jit->get_bc_location_for_native(
-                                        inlined_method, ip, &bc);
-                                assert(result == EXE_ERROR_NONE);
-                                *location_ptr = bc;
-                                *method_ptr = reinterpret_cast<jmethodID>(method);
-                                frame_found = true;
-                                break;
-                        }
-                        else
-                        {
-                            // Target frame is not inlined
-                            OpenExeJpdaError UNREF result =
-                                jit->get_bc_location_for_native(
-                                    method, ip, &bc);
-                            assert(result == EXE_ERROR_NONE);
-                            *location_ptr = bc;
-                            *method_ptr = reinterpret_cast<jmethodID>(method);
-                            frame_found = true;
-                            break;
-                        }
-                        stack_depth += inlined_depth;
-                    }
-                    else
-                    {
-                        assert(si_is_native(si));
-                        *location_ptr = -1;
-                        *method_ptr = reinterpret_cast<jmethodID>(method);
-                        frame_found = true;
-                        break;
-                    }
-
-                    stack_depth++;
-                }
-            }
-
-            si_goto_previous(si);
-        }
+        JavaStackIterator jsi(vm_thread);
+        jsi += depth;
 
-        if (!frame_found)
-            errStack = JVMTI_ERROR_NO_MORE_FRAMES;
-        else
+        if (jsi) {
+            jsi.get_location(method_ptr, location_ptr);
             errStack = JVMTI_ERROR_NONE;
-
-        si_free(si);
+        } else {
+            errStack = JVMTI_ERROR_NO_MORE_FRAMES;
+        }
     }
 
     if (thread_suspended)
         jthread_resume(thread);
 
     return errStack;
-}
+} // jvmtiGetFrameLocation
 
 /*
  * Notify Frame Pop
@@ -814,7 +780,7 @@
                     jthread thread,
                     jint depth)
 {
-    TRACE2("jvmti.stack", "NotifyFramePop called: thread: "
+    TRACE("NotifyFramePop called: thread: "
         << thread << ", depth: " << depth);
     SuspendEnabledChecker sec;
     jint state;
@@ -866,48 +832,38 @@
             vm_thread, depth);
     else
     {
-        StackIterator* si = si_create_from_native(vm_thread);
-        if (!si_get_method(si)) {
-            // skip VM native
-            si_goto_previous(si);
-        }
-        jint current_depth = 0;
-        while (!si_is_past_end(si) && current_depth < depth)
-        {
-            if (si_get_method(si))
-                current_depth += 1 + si_get_inline_depth(si);
+        JavaStackIterator jsi(vm_thread);
 
-            si_goto_previous(si);
-        }
-        if ((current_depth == depth && si_is_native(si)) || // native method
-            current_depth > depth) // Inlined frame
-        {
-            si_free(si);
-            return JVMTI_ERROR_OPAQUE_FRAME;
-        }
-        Method* UNREF method = si_get_method(si);
-        si_free(si);
+        jsi += depth;
 
-        jint UNREF skip;
-        current_depth = get_thread_stack_depth(vm_thread, &skip);
-        if (current_depth < depth)
+        if (! jsi)
             return JVMTI_ERROR_NO_MORE_FRAMES;
 
+        if (jsi.is_jni() || jsi.is_inlined())
+            return JVMTI_ERROR_OPAQUE_FRAME;
+
+
+        // get method for TRACE message
+        Method* UNREF method = si_get_method(jsi.get_si());
+
+        // fast forward to teh end of stack
+        for (; jsi; jsi++);
+
         jvmti_frame_pop_listener *new_listener =
             (jvmti_frame_pop_listener *)STD_MALLOC(
                 sizeof(jvmti_frame_pop_listener));
         assert(new_listener);
 
-        new_listener->depth = current_depth - depth;
+        new_listener->depth = jsi.get_depth() - depth;
         new_listener->env = reinterpret_cast<TIEnv *>(env);
         new_listener->next = vm_thread->frame_pop_listener;
         vm_thread->frame_pop_listener = new_listener;
-        TRACE2("jvmti.stack", "Pop listener is created: thread: "
+
+        TRACE("Pop listener is created: thread: "
             << vm_thread << ", listener: " << new_listener
             << ", env: " << new_listener->env << ", depth: " <<
new_listener->depth
-            << " -> " << class_get_name(method_get_class(method)) <<
"."
-            << method_get_name(method) << method_get_descriptor(method));
+            << " -> " << method);
 
         return JVMTI_ERROR_NONE;
     }
-}
+} // jvmtiNotifyFramePop



Mime
View raw message