You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2008/02/12 18:30:58 UTC

svn commit: r620872 - in /harmony/enhanced/drlvm/trunk/vm: port/src/encoder/ia32_em64t/ port/src/lil/ia32/pim/ vmcore/include/ vmcore/src/ncai/ vmcore/src/stack/ vmcore/src/util/ vmcore/src/util/em64t/base/ vmcore/src/util/ia32/base/ vmcore/src/util/ip...

Author: gshimansky
Date: Tue Feb 12 09:30:49 2008
New Revision: 620872

URL: http://svn.apache.org/viewvc?rev=620872&view=rev
Log:
Applied patch from HARMONY-5490
[drlvm][signals] New heuristics for crash handler


Added:
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp   (with props)
Modified:
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp Tue Feb 12 09:30:49 2008
@@ -74,7 +74,7 @@
 
     if (is_prefix(bytes)) {
         // More than 4 prefixes together ?
-        assert(false);
+//        assert(false);
         return 0;
     }
     
@@ -96,7 +96,7 @@
         }
     }
     if (!found) {
-        assert(false);
+//        assert(false);
         return 0;
     }
     tmp.size = (unsigned)(bytes-(const unsigned char*)addr);
@@ -167,7 +167,7 @@
         }
         return true;
     case OpcodeByteKind_cw:
-        assert(false); // not an error, but not expected in current env
+//        assert(false); // not an error, but not expected in current env
         break;
     case OpcodeByteKind_cd:
         {
@@ -231,11 +231,11 @@
             return true;
         }
     case OpcodeByteKind_ZeroOpcodeByte: // cant be here
-        assert(false);
+//        assert(false);
         break;
     default:
         // unknown kind ? how comes ?
-        assert(false);
+//        assert(false);
         break;
     }
     return false;

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp Tue Feb 12 09:30:49 2008
@@ -470,7 +470,7 @@
 BEGIN_OPCODES()
     {OpcodeInfo::all,     {0xE8, cd},        {rel32},     U },
     {OpcodeInfo::ia32,    {0xFF, _2},        {r_m32},     U },
-    {OpcodeInfo::em64t,   {REX_W, 0xFF, _2}, {r_m64},     U },
+    {OpcodeInfo::em64t,   {0xFF, _2},        {r_m64},     U },
 END_OPCODES()
 END_MNEMONIC()
 

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp Tue Feb 12 09:30:49 2008
@@ -115,7 +115,6 @@
         si->c.p_esi = &m2nfl->esi;
         si->c.p_ebx = &m2nfl->ebx;
         si->c.p_ebp = &m2nfl->ebp;
-        si->c.p_eip = &m2nfl->eip;
     }
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h Tue Feb 12 09:30:49 2008
@@ -38,26 +38,33 @@
     void*   stack;
 } native_frame_t;
 
+typedef struct WalkContext {
+    native_module_t*    modules;
+    bool                clean_modules;
+    native_segment_t    stack;
+} WalkContext;
+
 
 // If frame_array is NULL, only returns real frame count
-int walk_native_stack_registers(Registers* pregs,
+int walk_native_stack_registers(WalkContext* context, Registers* pregs,
     VM_thread* pthread, int max_depth, native_frame_t* frame_array);
 
+bool native_init_walk_context(WalkContext* context, native_module_t* modules, Registers* regs);
+void native_clean_walk_context(WalkContext* context);
+
 //////////////////////////////////////////////////////////////////////////////
 // Interchange between platform-dependent and general functions
-void native_get_frame_info(Registers* regs, void** ip, void** bp, void** sp);
-bool native_unwind_bp_based_frame(void* frame, void** ip, void** bp, void** sp);
-void native_get_ip_bp_from_si_jit_context(StackIterator* si, void** ip, void** bp);
-void native_get_sp_from_si_jit_context(StackIterator* si, void** sp);
-bool native_is_out_of_stack(void* value);
-bool native_is_frame_valid(native_module_t* modules, void* bp, void* sp);
-int native_test_unwind_special(native_module_t* modules, void* sp);
-bool native_unwind_special(native_module_t* modules,
-                void* stack, void** ip, void** sp, void** bp, bool is_last);
-void native_unwind_interrupted_frame(jvmti_thread_t thread, void** p_ip, void** p_bp, void** p_sp);
-bool native_is_ip_in_modules(native_module_t* modules, void* ip);
+
+bool native_unwind_stack_frame(WalkContext* context, Registers* regs);
+void native_get_regs_from_jit_context(JitFrameContext* jfc, Registers* regs);
+bool native_get_stack_range(WalkContext* context, Registers* regs, native_segment_t* seg);
+bool native_is_frame_exists(WalkContext* context, Registers* regs);
+bool native_unwind_special(WalkContext* context, Registers* regs);
+bool native_is_in_code(WalkContext* context, void* ip);
+bool native_is_in_stack(WalkContext* context, void* sp);
 bool native_is_ip_stub(void* ip);
 char* native_get_stub_name(void* ip, char* buf, size_t buflen);
+void native_fill_frame_info(Registers* regs, native_frame_t* frame, jint jdepth);
 
 
 #ifdef __cplusplus

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h Tue Feb 12 09:30:49 2008
@@ -28,9 +28,6 @@
 extern NcaiRegisterTableItem g_ncai_reg_table[];
 
 
-int walk_native_stack(hythread_t thread,
-    VM_thread* pthread, int max_depth, ncaiFrameInfo* frame_info);
-
 void clean_all_modules(ncaiModule* pmodules);
 void ncai_library_load_callback(const char* name);
 void ncai_library_unload_callback(const char* name);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h Tue Feb 12 09:30:49 2008
@@ -69,9 +69,11 @@
     uint64 *bsp;
     uint64 ip;
 
-    void reset_ip() { ip = 0; }
+    void  reset_ip() { ip = 0; }
     void* get_ip() { return (void*)ip; }
-    void set_ip(void* src_ip) { ip = (uint64)src_ip; }
+    void  set_ip(void* src_ip) { ip = (uint64)src_ip; }
+    void* get_sp() { return (void*)bsp; }
+    void  set_sp(void* src_sp) { }
 }; //Registers
 
 #else  // !_IPF_
@@ -101,9 +103,11 @@
 
     uint32 eflags;
 
-    void reset_ip() { rip = 0; }
+    void  reset_ip() { rip = 0; }
     void* get_ip() { return (void*)rip; }
-    void set_ip(void* src_ip) { rip = (uint64)src_ip; }
+    void  set_ip(void* src_ip) { rip = (uint64)src_ip; }
+    void* get_sp() { return (void*)rsp; }
+    void  set_sp(void* src_sp) { rsp = (uint64)src_sp; }
 }; //Registers
 
 #else // ! _EM64T_
@@ -120,9 +124,11 @@
     uint32 eip;
     uint32 eflags;
 
-    void reset_ip() { eip = 0; }
+    void  reset_ip() { eip = 0; }
     void* get_ip() { return (void*)eip; }
-    void set_ip(void* src_ip) { eip = (uint32)src_ip; }
+    void  set_ip(void* src_ip) { eip = (uint32)src_ip; }
+    void* get_sp() { return (void*)esp; }
+    void  set_sp(void* src_sp) { esp = (uint32)src_sp; }
 }; //Registers
 
 #endif // _EM64T_

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp Tue Feb 12 09:30:49 2008
@@ -153,8 +153,14 @@
         vm_thread = jthread_get_vm_thread(thread);
     }
 
-    *pcount = walk_native_stack_registers(&regs,
+    WalkContext context;
+    if (!native_init_walk_context(&context, NULL, &regs))
+        return NCAI_ERROR_INTERNAL;
+
+    *pcount = walk_native_stack_registers(&context, &regs,
                     vm_thread, max_depth, frame_array);
+
+    native_clean_walk_context(&context);
 
     return NCAI_ERROR_NONE;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp Tue Feb 12 09:30:49 2008
@@ -474,26 +474,31 @@
     // walk_native_stack_registers cannot unwind frames in release build),
     // we will use JIT/interpreter stack iterator to complete stack trace.
 
-    jint num_frames =
-        walk_native_stack_registers(regs, thread, -1, NULL);
+    WalkContext context;
+    
+    if (native_init_walk_context(&context, g_modules, regs))
+    {
+        jint num_frames =
+            walk_native_stack_registers(&context, regs, thread, -1, NULL);
 
-    if (num_frames)
-        frames = (native_frame_t*)STD_ALLOCA(sizeof(native_frame_t)*num_frames);
+        if (num_frames)
+            frames = (native_frame_t*)STD_ALLOCA(sizeof(native_frame_t)*num_frames);
 
-    if (num_frames && frames)
-        walk_native_stack_registers(regs, thread, num_frames, frames);
-    else
-        num_frames = 0; // Consider native stack trace empty
+        if (num_frames && frames)
+            walk_native_stack_registers(&context, regs, thread, num_frames, frames);
+        else
+            num_frames = 0; // Consider native stack trace empty
 
-    fprintf(stderr, "\nStack trace:\n");
+        fprintf(stderr, "\nStack trace:\n");
 
-    if(interpreter_enabled() && thread)
-        sd_print_stack_interpreter(thread, frames, num_frames);
-    else // It should be used also for threads without VM_thread structure
-        sd_print_stack_jit(thread, frames, num_frames);
+        if (interpreter_enabled() && thread)
+            sd_print_stack_interpreter(thread, frames, num_frames);
+        else // It should be used also for threads without VM_thread structure
+            sd_print_stack_jit(thread, frames, num_frames);
 
-    fprintf(stderr, "<end of stack trace>\n");
-    fflush(stderr);
+        fprintf(stderr, "<end of stack trace>\n");
+        fflush(stderr);
+    }
 
     if (thread)
         set_unwindable(unwindable);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp Tue Feb 12 09:30:49 2008
@@ -20,175 +20,141 @@
  */
 
 #include "method_lookup.h"
+#include "dec_base.h"
+#include "native_modules.h"
 #include "native_stack.h"
 
-void native_get_frame_info(Registers* regs, void** ip, void** bp, void** sp)
+
+bool native_is_frame_exists(WalkContext* context, Registers* regs)
 {
-    *ip = (void*)regs->rip;
-    *bp = (void*)regs->rbp;
-    *sp = (void*)regs->rsp;
+    // Check for frame layout and stack values
+    if ((regs->rbp < regs->rsp) || !native_is_in_stack(context, (void*)regs->rbp))
+        return false; // Invalid frame
+
+    void** frame_ptr = (void**)regs->rbp;
+    void* rip = frame_ptr[1]; // Return address
+
+    // Check return address for meaning
+    return (native_is_in_code(context, rip) || native_is_ip_stub(rip));
 }
 
-bool native_unwind_bp_based_frame(void* frame, void** ip, void** bp, void** sp)
+bool native_unwind_stack_frame(WalkContext* context, Registers* regs)
 {
-    void** frame_ptr = (void**)frame;
+    void** frame = (void**)regs->rbp;
 
-    *ip = frame_ptr[1];
-    *bp = frame_ptr[0];
+    void* rbp = frame[0];
+    void* rip = frame[1];
+//    void* rsp = (void*)(frame + 2);
+    void* rsp = &frame[2];
 
-    *sp = (void*)((POINTER_SIZE_INT)frame + 2*sizeof(void*));
 
-    return (*bp != NULL && *ip != NULL);
-}
+    if (native_is_in_stack(context, rsp) &&
+        (native_is_in_code(context, rip) || native_is_ip_stub(rip)))
+    {
+        regs->rbp = (uint64)rbp;
+        regs->rsp = (uint64)rsp;
+        regs->rip = (uint64)rip;
+        return true;
+    }
 
-void native_get_ip_bp_from_si_jit_context(StackIterator* si, void** ip, void** bp)
-{
-    JitFrameContext* jfc = si_get_jit_context(si);
-    *ip = (void*)*jfc->p_rip;
-    *bp = (void*)*jfc->p_rbp;
+    return false;
 }
 
-void native_get_sp_from_si_jit_context(StackIterator* si, void** sp)
+void native_get_regs_from_jit_context(JitFrameContext* jfc, Registers* regs)
 {
-    *sp = (void*)si_get_jit_context(si)->rsp;
+    regs->rip = *jfc->p_rip;
+    regs->rbp = *jfc->p_rbp;
+    regs->rsp = jfc->rsp;
 }
 
-bool native_is_out_of_stack(void* value)
+static bool fill_regs_from_sp(WalkContext* context, Registers* regs, void** sp)
 {
-    // FIXME: Invalid criterion
-    return (value < (void*)0x10000) || (value > (void*)0x800000000000);
+    regs->rsp = (uint64)(sp + 1);
+    regs->rip = (uint64)*sp;
+    regs->rbp = native_is_in_stack(context, sp[-1]) ? (uint64)sp[-1] : regs->rsp;
+    return true;
 }
 
-bool native_is_frame_valid(native_module_t* modules, void* bp, void* sp)
+static unsigned native_dec_instr(WalkContext* context, void* addr, void** target)
 {
-    // Check for frame layout and stack values
-    if ((bp < sp) || native_is_out_of_stack(bp))
-        return false; // Invalid frame
-
-    void** dw_ptr = (void**)bp;
-    void* ret_ip = *(dw_ptr + 1); // Return address for frame
-
-    // Check return address for meaning
-    if (!native_is_ip_in_modules(modules, ret_ip) && !native_is_ip_stub(ret_ip))
-        return false;
+    Inst inst;
 
-    return true;
-}
+    if (!native_is_in_code(context, addr))
+        return 0;
 
-// Searches for correct return address in the stack
-// Returns stack address pointing to return address
-static void** native_search_special_frame(native_module_t* modules, void* sp)
-{
-// Max search depth for return address
-#define MAX_SPECIAL_DEPTH 0x100
+    unsigned len = DecoderBase::decode(addr, &inst);
 
-    POINTER_SIZE_INT sp_begin = (POINTER_SIZE_INT)sp;
-    for (POINTER_SIZE_INT sp_int = sp_begin;
-         sp_int < sp_begin + MAX_SPECIAL_DEPTH;
-         sp_int += 8) // 8 is granularity of stack
-    {
-        void** sp_pointer = (void**)sp_int;
+    if (len == 0 ||
+        inst.mn != Mnemonic_CALL ||
+        inst.argc != 1)
+        return 0;
 
-        if (native_is_ip_in_modules(modules, *sp_pointer))
-            return sp_pointer;
-    }
+    if (target && inst.operands[0].is_imm())
+        *target = (void*)((uint64)addr + (uint64)len + inst.operands[0].imm());
 
-    return NULL;
+    return len;
 }
 
-// Tests if stack contains non-BP-based frames on top
-int native_test_unwind_special(native_module_t* modules, void* sp)
+static bool native_check_caller(WalkContext* context, Registers* regs, void** sp)
 {
-#define MAX_SPECIAL_COUNT 16
-
-#if (!defined PLATFORM_POSIX)
-    return -1; // Because we cannot identify executable code on Windows
-#endif
-
-    if (modules == NULL)
-        return false;
-
-    int count = 0;
-    void** sp_pointer = (void**)sp;
-
-    do
+    void* target = NULL;
+    char* ptr = (char*)*sp;
+    
+    if (native_dec_instr(context, ptr - 2, &target) == 2 || // CALL r/m64 w/o SIB w/o disp
+        native_dec_instr(context, ptr - 3, &target) == 3 || // CALL r/m64 w/ SIB w/o disp
+        native_dec_instr(context, ptr - 4, &target) == 4 || // CALL r/m64 w/ SIB w/ disp8
+        native_dec_instr(context, ptr - 5, &target) == 5 || // CALL rel32
+        native_dec_instr(context, ptr - 6, &target) == 6 || // CALL r/m64 w/o SIB w/ disp32
+        native_dec_instr(context, ptr - 7, &target) == 7 || // CALL r/m64 w/ SIB w/ disp32
+        native_dec_instr(context, ptr - 8, &target) == 8)   // CALL r/m64 w/ SIB w/ disp32 + Seg prefix
     {
-        if (native_is_ip_stub(sp_pointer[-1]))
-            break; // We've found JNI stub
-
-        // We've reached Java without native stub
-        if (vm_identify_eip(sp_pointer[-1]) == VM_TYPE_JAVA)
-            break;
-
-        void** next_sp = native_search_special_frame(modules, sp_pointer);
-
-        if (next_sp == NULL)
-            break; // We cannot unwind anymore
+        if (!target)
+            return true;
 
-        if (count > 0 &&                     // Check BP-frame for upper frames
-            sp_pointer[-2] >= sp_pointer &&  // Correct frame layout
-            sp_pointer[-2] == next_sp - 1 && // is RBP saved correctly
-            next_sp[-1] >= next_sp + 1)      // Correct next frame layout
-        {
-            break;
-        }
+        native_module_t* cur_module =
+            find_native_module(context->modules, regs->get_ip());
+        native_module_t* found_module =
+            find_native_module(context->modules, target);
 
-        sp_pointer = next_sp + 1;
-
-    } while (++count <= MAX_SPECIAL_COUNT);
+        return (cur_module == found_module);
+    }
 
-    return count;
+    return false;
 }
 
-bool native_unwind_special(native_module_t* modules,
-                void* stack, void** ip, void** sp, void** bp, bool is_last)
-{
-    if (modules == NULL)
-    {
-        *ip = NULL;
-        return false;
-    }
 
-    void** found = NULL;
+// Max search depth for return address
+#define MAX_SPECIAL_DEPTH 0x900
+#define NATIVE_STRICT_UNWINDING 1
 
-    POINTER_SIZE_INT sp_begin = (POINTER_SIZE_INT)stack;
-    for (POINTER_SIZE_INT sp_int = sp_begin;
-         sp_int < sp_begin + MAX_SPECIAL_DEPTH;
-         sp_int += 8) // 8 is granularity of stack
+bool native_unwind_special(WalkContext* context, Registers* regs)
+{
+    for (void** cur_sp = (void**)regs->rsp;
+         (char*)cur_sp < ((char*)regs->rsp + MAX_SPECIAL_DEPTH) && native_is_in_stack(context, cur_sp);
+         ++cur_sp)
     {
-        void** sp_pointer = (void**)sp_int;
-
-        if (native_is_ip_in_modules(modules, *sp_pointer))
-        {
-            found = sp_pointer;
-            break;
-        }
-    }
+        if (!native_is_in_code(context, *cur_sp))
+            continue;
 
-    if (!found)
-    {
-        *ip = NULL;
-        return false;
+#if (!NATIVE_STRICT_UNWINDING)
+        return fill_regs_from_sp(context, regs, cur_sp);
+#else
+        if (native_check_caller(context, regs, cur_sp))
+            return fill_regs_from_sp(context, regs, cur_sp);
+#endif
     }
 
-    *ip = *found;
-    *sp = found + 1;
-
-    if (is_last && !native_is_ip_stub(*ip))
-        *bp = found[-1];
-    else
-        *bp = *sp;
-
-    return true;
+    return false;
 }
 
-void native_unwind_interrupted_frame(jvmti_thread_t thread, void** p_ip, void** p_bp, void** p_sp)
+void native_fill_frame_info(Registers* regs, native_frame_t* frame, jint jdepth)
 {
-    if (!thread) {
+    frame->java_depth = jdepth;
+
+    if (!regs)
         return;
-    }
-    Registers* pregs = (Registers*)(thread->jvmti_saved_exception_registers);
-    *p_ip = (void*)pregs->rip;
-    *p_bp = (void*)pregs->rbp;
-    *p_sp = (void*)pregs->rsp;
+
+    frame->ip = (void*)regs->rip;
+    frame->frame = (void*)regs->rbp;
+    frame->stack = (void*)regs->rsp;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp Tue Feb 12 09:30:49 2008
@@ -20,176 +20,141 @@
  */
 
 #include "method_lookup.h"
+#include "dec_base.h"
+#include "native_modules.h"
 #include "native_stack.h"
 
-void native_get_frame_info(Registers* regs, void** ip, void** bp, void** sp)
-{
-    *ip = (void*)regs->eip;
-    *bp = (void*)regs->ebp;
-    *sp = (void*)regs->esp;
-}
-
-bool native_unwind_bp_based_frame(void* frame, void** ip, void** bp, void** sp)
-{
-    void** frame_ptr = (void**)frame;
-
-    *ip = frame_ptr[1];
-    *bp = frame_ptr[0];
-    // FIXME - wrong value, we cannot get sp anyhow
-    *sp = (void*)((POINTER_SIZE_INT)frame + 2*sizeof(void*));
-
-    return (*bp != NULL && *ip != NULL);
-}
-
-void native_get_ip_bp_from_si_jit_context(StackIterator* si, void** ip, void** bp)
-{
-    JitFrameContext* jfc = si_get_jit_context(si);
-    *ip = (void*)*jfc->p_eip;
-    *bp = (void*)*jfc->p_ebp;
-}
-
-void native_get_sp_from_si_jit_context(StackIterator* si, void** sp)
-{
-    *sp = (void*)si_get_jit_context(si)->esp;
-}
 
-bool native_is_out_of_stack(void* value)
-{
-    // FIXME: Invalid criterion
-    return (value < (void*)0x10000) || (value > (void*)0xC0000000);
-}
-
-bool native_is_frame_valid(native_module_t* modules, void* bp, void* sp)
+bool native_is_frame_exists(WalkContext* context, Registers* regs)
 {
     // Check for frame layout and stack values
-    if ((bp < sp) || native_is_out_of_stack(bp))
+    if ((regs->ebp < regs->esp) || !native_is_in_stack(context, (void*)regs->ebp))
         return false; // Invalid frame
 
-    void** dw_ptr = (void**)bp;
-    void* ret_ip = *(dw_ptr + 1); // Return address for frame
+    void** frame_ptr = (void**)regs->ebp;
+    void* eip = frame_ptr[1]; // Return address
 
     // Check return address for meaning
-    if (!native_is_ip_in_modules(modules, ret_ip) && !native_is_ip_stub(ret_ip))
-        return false;
-
-    return true;
+    return (native_is_in_code(context, eip) || native_is_ip_stub(eip));
 }
 
-// Searches for correct return address in the stack
-// Returns stack address pointing to return address
-static void** native_search_special_frame(native_module_t* modules, void* sp)
+bool native_unwind_stack_frame(WalkContext* context, Registers* regs)
 {
-// Max search depth for return address
-#define MAX_SPECIAL_DEPTH 0x40
+    void** frame = (void**)regs->ebp;
+
+    void* ebp = frame[0];
+    void* eip = frame[1];
+//    void* esp = (void*)(frame + 2);
+    void* esp = &frame[2];
 
-    POINTER_SIZE_INT sp_begin = (POINTER_SIZE_INT)sp;
-    for (POINTER_SIZE_INT sp_int = sp_begin;
-         sp_int < sp_begin + MAX_SPECIAL_DEPTH;
-         sp_int +=2) // 2 is minimum stack item for ia32
-    {
-        void** sp_pointer = (void**)sp_int;
 
-        if (native_is_ip_in_modules(modules, *sp_pointer))
-            return sp_pointer;
+    if (native_is_in_stack(context, esp) &&
+        (native_is_in_code(context, eip) || native_is_ip_stub(eip)))
+    {
+        regs->ebp = (uint32)ebp;
+        regs->esp = (uint32)esp;
+        regs->eip = (uint32)eip;
+        return true;
     }
 
-    return NULL;
+    return false;
 }
 
-// Tests if stack contains non-BP-based frames on top
-int native_test_unwind_special(native_module_t* modules, void* sp)
+void native_get_regs_from_jit_context(JitFrameContext* jfc, Registers* regs)
 {
-#define MAX_SPECIAL_COUNT 16
-
-#if (!defined PLATFORM_POSIX)
-    return -1; // Because we cannot identify executable code on Windows
-#endif
-
-    if (modules == NULL)
-        return false;
-
-    int count = 0;
-    void** sp_pointer = (void**)sp;
-
-    do
-    {
-        if (native_is_ip_stub(sp_pointer[-1]))
-            break; // We've found JNI stub
+    regs->eip = *jfc->p_eip;
+    regs->ebp = *jfc->p_ebp;
+    regs->esp = jfc->esp;
+}
 
-        // We've reached Java without native stub
-        if (vm_identify_eip(sp_pointer[-1]) == VM_TYPE_JAVA)
-            break;
+static bool fill_regs_from_sp(WalkContext* context, Registers* regs, void** sp)
+{
+    regs->esp = (uint32)(sp + 1);
+    regs->eip = (uint32)*sp;
+    regs->ebp = native_is_in_stack(context, sp[-1]) ? (uint32)sp[-1] : regs->esp;
+    return true;
+}
 
-        void** next_sp = native_search_special_frame(modules, sp_pointer);
+static unsigned native_dec_instr(WalkContext* context, void* addr, void** target)
+{
+    Inst inst;
 
-        if (next_sp == NULL)
-            break; // We cannot unwind anymore
+    if (!native_is_in_code(context, addr))
+        return 0;
 
-        if (count > 0 &&                     // Check BP-frame for upper frames
-            sp_pointer[-2] >= sp_pointer &&  // Correct frame layout
-            sp_pointer[-2] == next_sp - 1 && // is BP saved correctly
-            next_sp[-1] >= next_sp + 1)      // Correct next frame layout
-        {
-            break;
-        }
+    uint32 len = DecoderBase::decode(addr, &inst);
 
-        sp_pointer = next_sp + 1;
+    if (len == 0 ||
+        inst.mn != Mnemonic_CALL ||
+        inst.argc != 1)
+        return 0;
 
-    } while (++count <= MAX_SPECIAL_COUNT);
+    if (target && inst.operands[0].is_imm())
+        *target = (void*)((uint32)addr + len + inst.operands[0].imm());
 
-    return count;
+    return len;
 }
 
-// Tries to unwind non-BP-based frame
-bool native_unwind_special(native_module_t* modules,
-    void* stack, void** ip, void** sp, void** bp, bool is_last)
+static bool native_check_caller(WalkContext* context, Registers* regs, void** sp)
 {
-    if (modules == NULL)
+    void* target = NULL;
+    char* ptr = (char*)*sp;
+    
+    if (native_dec_instr(context, ptr - 2, &target) == 2 || // CALL r/m32 w/o SIB w/o disp
+        native_dec_instr(context, ptr - 3, &target) == 3 || // CALL r/m32 w/ SIB w/o disp
+        native_dec_instr(context, ptr - 4, &target) == 4 || // CALL r/m32 w/ SIB w/ disp8
+        native_dec_instr(context, ptr - 5, &target) == 5 || // CALL rel32
+        native_dec_instr(context, ptr - 6, &target) == 6 || // CALL r/m32 w/o SIB w/ disp32
+        native_dec_instr(context, ptr - 7, &target) == 7 || // CALL r/m32 w/ SIB w/ disp32
+        native_dec_instr(context, ptr - 8, &target) == 8)   // CALL r/m32 w/ SIB w/ disp32 + Seg prefix
     {
-        *ip = NULL;
-        return false;
+        if (!target)
+            return true;
+
+        native_module_t* cur_module =
+            find_native_module(context->modules, regs->get_ip());
+        native_module_t* found_module =
+            find_native_module(context->modules, target);
+
+        return (cur_module == found_module);
     }
 
-    void** found = NULL;
+    return false;
+}
 
-    POINTER_SIZE_INT sp_begin = (POINTER_SIZE_INT)stack;
-    for (POINTER_SIZE_INT sp_int = sp_begin;
-         sp_int < sp_begin + MAX_SPECIAL_DEPTH;
-         sp_int +=2) // 2 is minimum stack item for ia32
-    {
-        void** sp_pointer = (void**)sp_int;
 
-        if (native_is_ip_in_modules(modules, *sp_pointer))
-        {
-            found = sp_pointer;
-            break;
-        }
-    }
+// Max search depth for return address
+#define MAX_SPECIAL_DEPTH 0x400
+#define NATIVE_STRICT_UNWINDING 1
 
-    if (!found)
+bool native_unwind_special(WalkContext* context, Registers* regs)
+{
+    for (void** cur_sp = (void**)regs->esp;
+         (char*)cur_sp < ((char*)regs->esp + MAX_SPECIAL_DEPTH) && native_is_in_stack(context, cur_sp);
+         ++cur_sp)
     {
-        *ip = NULL;
-        return false;
-    }
+        if (!native_is_in_code(context, *cur_sp))
+            continue;
 
-    *ip = *found;
-    *sp = found + 1;
-    
-    if (is_last && !native_is_ip_stub(*ip))
-        *bp = found[-1];
-    else
-        *bp = *sp;
+#if (!NATIVE_STRICT_UNWINDING)
+        return fill_regs_from_sp(context, regs, cur_sp);
+#else
+        if (native_check_caller(context, regs, cur_sp))
+            return fill_regs_from_sp(context, regs, cur_sp);
+#endif
+    }
 
-    return true;
+    return false;
 }
 
-void native_unwind_interrupted_frame(jvmti_thread_t thread, void** p_ip, void** p_bp, void** p_sp)
+void native_fill_frame_info(Registers* regs, native_frame_t* frame, jint jdepth)
 {
-    if (!thread) {
+    frame->java_depth = jdepth;
+
+    if (!regs)
         return;
-    }
-    Registers* pregs = (Registers*)(thread->jvmti_saved_exception_registers);
-    *p_ip = (void*)pregs->eip;
-    *p_bp = (void*)pregs->ebp;
-    *p_sp = (void*)pregs->esp;
+
+    frame->ip = (void*)regs->eip;
+    frame->frame = (void*)regs->ebp;
+    frame->stack = (void*)regs->esp;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp Tue Feb 12 09:30:49 2008
@@ -21,55 +21,26 @@
 
 #include "native_stack.h"
 
-void native_get_frame_info(Registers* regs, void** ip, void** bp, void** sp)
-{
-    // FIXME: not implemented
-}
 
-bool native_unwind_bp_based_frame(void* frame, void** ip, void** bp, void** sp)
+bool native_is_frame_exists(WalkContext* UNREF context, Registers* UNREF regs)
 {
-    return false; // Not implemented
-}
-
-void native_get_ip_bp_from_si_jit_context(StackIterator* si, void** ip, void** bp)
-{ // Not implemented
-}
-
-void native_get_sp_from_si_jit_context(StackIterator* si, void** sp)
-{ // Not implemented
+    return false;
 }
 
-bool native_is_out_of_stack(void* value)
+bool native_unwind_stack_frame(WalkContext* UNREF context, Registers* UNREF regs)
 {
-    return true; // Not implemented
+    return false;
 }
 
-bool native_is_frame_valid(native_module_t* modules, void* bp, void* sp)
+void native_get_regs_from_jit_context(JitFrameContext* UNREF jfc, Registers* UNREF regs)
 {
-    return false; // Not implemented
 }
 
-int native_test_unwind_special(native_module_t* modules, void* sp)
+bool native_unwind_special(WalkContext* UNREF context, Registers* UNREF regs)
 {
-    return false; // Not implemented
+    return false;
 }
 
-bool native_unwind_special(native_module_t* modules,
-                void* stack, void** ip, void** sp, void** bp, bool is_last)
+void native_fill_frame_info(Registers* UNREF regs, native_frame_t* UNREF frame, jint UNREF jdepth)
 {
-    return false; // Not implemented
 }
-
-void native_unwind_interrupted_frame(jvmti_thread_t thread, void** p_ip, void** p_bp, void** p_sp)
-{ // Not implemented yet
-    *p_ip = NULL;
-    *p_bp = NULL;
-    *p_sp = NULL;
-}
-
-void si_set_callbak(StackIterator* si, NativeCodePtr* callback) {
-    // FIXME: not implemented
-    assert(0);
-    abort();
-}
-

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp?rev=620872&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp Tue Feb 12 09:30:49 2008
@@ -0,0 +1,87 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+#include <pthread.h>
+#include "native_modules.h"
+#include "native_stack.h"
+
+
+bool native_is_in_code(WalkContext* context, void* ip)
+{
+    if (!ip)
+        return false;
+
+    for (native_module_t* module = context->modules; module; module = module->next)
+    {
+        for (size_t i = 0; i < module->seg_count; i++)
+        {
+            char* base = (char*)module->segments[i].base;
+
+            if (ip >= base &&
+                ip < (base + module->segments[i].size))
+                return true;
+        }
+    }
+
+    return false;
+}
+
+bool native_get_stack_range(WalkContext* context, Registers* regs, native_segment_t* seg)
+{
+    int err;
+    pthread_attr_t pthread_attr;
+
+    pthread_t thread = pthread_self();
+    void* sp = regs->get_sp();
+
+    if (pthread_attr_init(&pthread_attr) != 0)
+        return false;
+
+#if defined(FREEBSD)
+    err = pthread_attr_get_np(thread, &pthread_attr);
+#else
+    err = pthread_getattr_np(thread, &pthread_attr);
+#endif
+
+    if (err != 0)
+        return false;
+
+    if (pthread_attr_getstack(&pthread_attr, &seg->base, &seg->size))
+        return false;
+
+    pthread_attr_destroy(&pthread_attr);
+    return true;
+
+/*    for (native_module_t* module = context->modules; module; module = module->next)
+    {
+        for (size_t i = 0; i < module->seg_count; i++)
+        {
+            char* base = (char*)module->segments[i].base;
+
+            if (sp >= base &&
+                sp < (base + module->segments[i].size))
+            {
+                *seg = module->segments[i];
+                return true;
+            }
+        }
+    }
+
+    return false;
+*/
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp?rev=620872&r1=620871&r2=620872&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp Tue Feb 12 09:30:49 2008
@@ -33,52 +33,9 @@
 #include "native_stack.h"
 
 
-
-// Global lock used for locking module list access
-static Lock_Manager g_list_lock;
-
-
 //////////////////////////////////////////////////////////////////////////////
 /// Helper functions
 
-static bool get_modules(native_module_t** pmodules)
-{
-    assert(pmodules);
-
-    if (*pmodules != NULL)
-        return true;
-
-    int mod_count;
-    native_module_t* mod_list = NULL;
-
-    LMAutoUnlock aulock(&g_list_lock);
-
-    bool result = get_all_native_modules(&mod_list, &mod_count);
-
-    if (!result)
-        return false;
-
-    *pmodules = mod_list;
-    return true;
-}
-
-bool native_is_ip_in_modules(native_module_t* modules, void* ip)
-{
-    for (native_module_t* module = modules; module; module = module->next)
-    {
-        for (size_t i = 0; i < module->seg_count; i++)
-        {
-            char* base = (char*)module->segments[i].base;
-
-            if (ip >= base &&
-                ip < (base + module->segments[i].size))
-                return true;
-        }
-    }
-
-    return false;
-}
-
 static DynamicCode* native_find_stub(void* ip)
 {
     for (DynamicCode *dcList = compile_get_dynamic_code_list();
@@ -111,6 +68,12 @@
     return buf;
 }
 
+bool native_is_in_stack(WalkContext* context, void* sp)
+{
+    return (sp >= context->stack.base &&
+            sp < (char*)context->stack.base + context->stack.size);
+}
+
 bool native_is_ip_stub(void* ip)
 {
     // Synchronizing access to dynamic code list
@@ -131,54 +94,108 @@
 //////////////////////////////////////////////////////////////////////////////
 //
 
-static int walk_native_stack_jit(Registers* pregs, VM_thread* pthread,
+bool native_init_walk_context(WalkContext* context, native_module_t* modules, Registers* regs)
+{
+    if (!context)
+        return false;
+
+    if (!modules)
+    {
+        int mod_count;
+        native_module_t* mod_list = NULL;
+
+        if (!get_all_native_modules(&mod_list, &mod_count))
+            return false;
+
+        context->clean_modules = true;
+        context->modules = mod_list;
+    }
+    else
+    {
+        context->clean_modules = false;
+        context->modules = modules;
+    }
+
+    if (!native_get_stack_range(context, regs, &context->stack))
+    {
+        if (context->clean_modules)
+            clear_native_modules(&context->modules);
+        return false;
+    }
+
+    return true;
+}
+
+void native_clean_walk_context(WalkContext* context)
+{
+    if (!context)
+        return;
+
+    if (context->modules && context->clean_modules)
+    {
+        clear_native_modules(&context->modules);
+    }
+
+    context->modules = NULL;
+}
+
+
+static int walk_native_stack_jit(
+    WalkContext* context,
+    Registers* pregs, VM_thread* pthread,
     int max_depth, native_frame_t* frame_array);
-static int walk_native_stack_pure(Registers* pregs,
+static int walk_native_stack_pure(
+    WalkContext* context, Registers* pregs,
     int max_depth, native_frame_t* frame_array);
-static int walk_native_stack_interpreter(Registers* pregs, VM_thread* pthread,
+static int walk_native_stack_interpreter(
+    WalkContext* context,
+    Registers* pregs, VM_thread* pthread,
     int max_depth, native_frame_t* frame_array);
 
-int walk_native_stack_registers(Registers* pregs,
+int walk_native_stack_registers(WalkContext* context, Registers* pregs,
     VM_thread* pthread, int max_depth, native_frame_t* frame_array)
 {
     if (pthread == NULL) // Pure native thread
-        return walk_native_stack_pure(pregs, max_depth, frame_array);
+        return walk_native_stack_pure(context, pregs, max_depth, frame_array);
 
     if (interpreter_enabled())
-        return walk_native_stack_interpreter(pregs, pthread, max_depth, frame_array);
+        return walk_native_stack_interpreter(context, pregs,
+                                            pthread, max_depth, frame_array);
 
-    return walk_native_stack_jit(pregs, pthread, max_depth, frame_array);
+    return walk_native_stack_jit(context, pregs, pthread, max_depth, frame_array);
+    return 0;
 }
 
 
-static int walk_native_stack_jit(Registers* pregs, VM_thread* pthread,
+static int walk_native_stack_jit(
+    WalkContext* context,
+    Registers* pregs, VM_thread* pthread,
     int max_depth, native_frame_t* frame_array)
 {
-    // These vars store current frame context for each iteration
-    void *ip, *bp, *sp;
-    // To translate platform-dependant info; we will use ip from here
-    native_get_frame_info(pregs, &ip, &bp, &sp);
+    // Register context for current frame
+    Registers regs = *pregs;
 
     int frame_count = 0;
     
     // Search for method containing corresponding address
-    VM_Code_Type code_type = vm_identify_eip(ip);
+    VM_Code_Type code_type = vm_identify_eip(regs.get_ip());
     bool flag_dummy_frame = false;
     jint java_depth = 0;
     StackIterator* si = NULL;
     bool is_java = false;
-    native_module_t* modules = NULL;
 
     if (code_type == VM_TYPE_JAVA)
     { // We must add dummy M2N frame to start SI iteration
-        assert(pthread);
+        if (!pthread)
+            return 0;
+
         is_java = true;
 
         M2nFrame* lm2n = m2n_get_last_frame(pthread);
 
-        if (!m2n_is_suspended_frame(lm2n) || m2n_get_ip(lm2n) != ip)
+        if (!m2n_is_suspended_frame(lm2n) || m2n_get_ip(lm2n) != regs.get_ip())
         { // We should not push frame if it was pushed by breakpoint handler
-            m2n_push_suspended_frame(pthread, pregs);
+            m2n_push_suspended_frame(pthread, &regs);
             flag_dummy_frame = true;
         }
     }
@@ -206,12 +223,8 @@
 
         if (frame_array)
         { // If frames requested, store current frame
-            frame_array[frame_count].java_depth =
-                is_java ? java_depth : -1;
-
-            frame_array[frame_count].ip = ip;
-            frame_array[frame_count].frame = bp;
-            frame_array[frame_count].stack = sp;
+            native_fill_frame_info(&regs, &frame_array[frame_count],
+                is_java ? java_depth : -1);
         }
 
         ++frame_count;
@@ -221,7 +234,8 @@
         if (is_java) //code_type == VM_TYPE_JAVA
         { // Go to previous frame using StackIterator
             cci = si_get_code_chunk_info(si);
-            assert(cci); // Java method should contain cci
+            if (!cci) // Java method should contain cci
+                break;
 
             // if (inline_index < 0) we have new si
             // (inline_index < inline_count) we must process inline
@@ -246,22 +260,22 @@
                 inline_index = -1;
                 // Go to previous stack frame from StackIterator
                 si_goto_previous(si);
-                native_get_ip_bp_from_si_jit_context(si, &ip, &bp);//???
-                native_get_sp_from_si_jit_context(si, &sp);
+                native_get_regs_from_jit_context(si_get_jit_context(si), &regs);
             }
 
-            code_type = vm_identify_eip(ip);
+            code_type = vm_identify_eip(regs.get_ip());
             is_java = (code_type == VM_TYPE_JAVA);
             continue;
         }
 // ^^ Java ^^
 /////////////////////////
 // vv Native vv
-        is_stub = native_is_ip_stub(ip);
+        is_stub = native_is_ip_stub(regs.get_ip());
 
         if (is_stub)
         { // Native stub, previous frame is Java frame
-            assert(si_is_native(si));
+            if (!si_is_native(si))
+                break;
 
             if (si_get_method(si)) // Frame represents JNI frame
             {
@@ -278,60 +292,38 @@
             // Ge to previous stack frame from StackIterator
             si_goto_previous(si);
             // Let's get context from si
-            native_get_ip_bp_from_si_jit_context(si, &ip, &bp);
-            native_get_sp_from_si_jit_context(si, &sp);
+            native_get_regs_from_jit_context(si_get_jit_context(si), &regs);
         }
         else
         {
-            if (!modules && !get_modules(&modules))
-                break;
-
-            if (native_is_frame_valid(modules, bp, sp))
-            { // Simply bp-based frame, let's unwind it
-                void *tmp_ip, *tmp_bp, *tmp_sp;
-                native_unwind_bp_based_frame(bp, &tmp_ip, &tmp_bp, &tmp_sp);
-
-                VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
-                vm_breaks->lock();
-
-                if (native_is_ip_in_breakpoint_handler(tmp_ip))
-                {
-                    native_unwind_interrupted_frame(&pthread->jvmti_thread, &ip, &bp, &sp);
-                    flag_breakpoint = true;
-                }
-                else
-                {
-                    ip = tmp_ip;
-                    bp = tmp_bp;
-                    sp = tmp_sp;
-                }
+            Registers tmp_regs = regs;
 
-                vm_breaks->unlock();
+            if (native_is_frame_exists(context, &tmp_regs))
+            { // Stack frame (x86)
+                if (!native_unwind_stack_frame(context, &tmp_regs))
+                    break;
             }
             else
-            { // Is not bp-based frame
-                if (frame_count == 1)
-                { // For first frame, test special unwinding possibility
-                    special_count = native_test_unwind_special(modules, sp);
-                    if (special_count <= 0)
-                        ip = NULL;
-                }
-
-                if (frame_count <= special_count)
-                { // Specially unwind first native frames
-                    bool res = native_unwind_special(modules,
-                                        sp, &ip, &sp, &bp,
-                                        frame_count == special_count);
-
-                    if (!res)
-                        break; // Unwinding failed
-                }
-                else
-                    break; // There is another invalid frame in the stack
+            { // Stack frame does not exist, try using heuristics
+                if (!native_unwind_special(context, &tmp_regs))
+                    break;
             }
+
+            VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+            vm_breaks->lock();
+
+            if (native_is_ip_in_breakpoint_handler(tmp_regs.get_ip()))
+            {
+                regs = *pthread->jvmti_thread.jvmti_saved_exception_registers;
+                flag_breakpoint = true;
+            }
+            else
+                regs = tmp_regs;
+
+            vm_breaks->unlock();
         }
             
-        code_type = vm_identify_eip(ip);
+        code_type = vm_identify_eip(regs.get_ip());
         is_java = (code_type == VM_TYPE_JAVA);
 
         // If we've reached Java without native stub (or breakpoint handler frame)
@@ -355,18 +347,16 @@
 }
 
 
-static int walk_native_stack_pure(Registers* pregs,
+static int walk_native_stack_pure(
+    WalkContext* context, Registers* pregs,
     int max_depth, native_frame_t* frame_array)
 {
-    // These vars store current frame context for each iteration
-    void *ip, *bp, *sp;
-    // To translate platform-dependant info; we will use ip from here
-    native_get_frame_info(pregs, &ip, &bp, &sp);
-    assert(vm_identify_eip(ip) != VM_TYPE_JAVA);
+    // Register context for current frame
+    Registers regs = *pregs;
+    if (vm_identify_eip(regs.get_ip()) == VM_TYPE_JAVA)
+        return 0;
 
     int frame_count = 0;
-    int special_count = 0;
-    native_module_t* modules = NULL;
 
     while (1)
     {
@@ -375,40 +365,22 @@
 
         if (frame_array)
         { // If frames requested, store current frame
-            frame_array[frame_count].java_depth = -1;
-            frame_array[frame_count].ip = ip;
-            frame_array[frame_count].frame = bp;
-            frame_array[frame_count].stack = sp;
+            native_fill_frame_info(&regs, &frame_array[frame_count], -1);
         }
 
         ++frame_count;
 
-        if (!modules && !get_modules(&modules))
-            break;
-
-        // Simply bp-based frame, let's unwind it
-        if (native_is_frame_valid(modules, bp, sp))
-        {
+        if (native_is_frame_exists(context, &regs))
+        { // Stack frame (x86)
             // Here must be special processing for breakpoint handler frames
             // But it requires VM_thread structure attached to thread
             // TODO: Investigate possibility
-            native_unwind_bp_based_frame(bp, &ip, &bp, &sp);
+            if (!native_unwind_stack_frame(context, &regs))
+                break;
         }
         else
-        { // Wrong frame
-            if (frame_count == 1)
-            { // For first frame, test special unwinding possibility
-                special_count = native_test_unwind_special(modules, sp);
-                if (special_count <= 0)
-                    break;
-            }
-
-            if (frame_count <= special_count)
-            { // Specially unwind first native frames
-                native_unwind_special(modules, sp, &ip, &sp, &bp,
-                                    frame_count == special_count);
-            }
-            else // There is another invalid frame in the stack
+        { // Stack frame does not exist, try using heuristics
+            if (!native_unwind_special(context, &regs))
                 break;
         }
     }
@@ -417,13 +389,13 @@
 }
 
 
-static int walk_native_stack_interpreter(Registers* pregs, VM_thread* pthread,
+static int walk_native_stack_interpreter(
+    WalkContext* context,
+    Registers* pregs, VM_thread* pthread,
     int max_depth, native_frame_t* frame_array)
 {
-    // These vars store current frame context for each iteration
-    void *ip, *bp, *sp;
-    // To translate platform-dependant info; we will use ip from here
-    native_get_frame_info(pregs, &ip, &bp, &sp);
+    // Register context for current frame
+    Registers regs = *pregs;
 
     assert(pthread);
     FrameHandle* last_frame = interpreter.interpreter_get_last_frame(pthread);
@@ -431,8 +403,6 @@
 
     int frame_count = 0;
     jint java_depth = 0;
-    int special_count = 0;
-    native_module_t* modules = NULL;
 
     while (1)
     {
@@ -441,60 +411,37 @@
 
         if (frame_array)
         { // If frames requested, store current frame
-            frame_array[frame_count].java_depth = -1;
-            frame_array[frame_count].ip = ip;
-            frame_array[frame_count].frame = bp;
-            frame_array[frame_count].stack = sp;
+            native_fill_frame_info(&regs, &frame_array[frame_count], -1);
         }
 
         ++frame_count;
 
         // Store previous value to identify frame range later
-        void* prev_sp = sp;
+        void* prev_sp = regs.get_sp();
+        Registers tmp_regs = regs;
 
-        if (!modules && !get_modules(&modules))
-            break;
-
-        if (native_is_frame_valid(modules, bp, sp))
-        { // Simply bp-based frame, let's unwind it
-            void *tmp_ip, *tmp_bp, *tmp_sp;
-            native_unwind_bp_based_frame(bp, &tmp_ip, &tmp_bp, &tmp_sp);
+        if (native_is_frame_exists(context, &tmp_regs))
+        { // Stack frame (x86)
+            if (!native_unwind_stack_frame(context, &tmp_regs))
+                break;
+        }
+        else
+        { // Stack frame does not exist, try using heuristics
+            if (!native_unwind_special(context, &tmp_regs))
+                break;
+        }
 
-            VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
-            vm_breaks->lock();
+        VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+        vm_breaks->lock();
 
-            if (native_is_ip_in_breakpoint_handler(tmp_ip))
-            {
-                native_unwind_interrupted_frame(&pthread->jvmti_thread, &ip, &bp, &sp);
-            }
-            else
-            {
-                ip = tmp_ip;
-                bp = tmp_bp;
-                sp = tmp_sp;
-            }
-
-            vm_breaks->unlock();
-        }
+        if (native_is_ip_in_breakpoint_handler(tmp_regs.get_ip()))
+            regs = *pthread->jvmti_thread.jvmti_saved_exception_registers;
         else
-        { // Is not bp-based frame
-            if (frame_count == 1)
-            { // For first frame, test special unwinding possibility
-                special_count = native_test_unwind_special(modules, sp);
-                if (special_count <= 0)
-                    break;
-            }
+            regs = tmp_regs;
 
-            if (frame_count <= special_count)
-            { // Specially unwind first native frames
-                native_unwind_special(modules, sp, &ip, &sp, &bp,
-                                    frame_count == special_count);
-            }
-            else
-                break; // There is another invalid frame in the stack
-        }
+        vm_breaks->unlock();
 
-        bool is_java = interpreter.is_frame_in_native_frame(frame, prev_sp, sp);
+        bool is_java = interpreter.is_frame_in_native_frame(frame, prev_sp, regs.get_sp());
 
         if (is_java)
         {

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp?rev=620872&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp Tue Feb 12 09:30:49 2008
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+#include "native_modules.h"
+#include "native_stack.h"
+
+
+bool native_is_in_code(WalkContext* context, void* ip)
+{
+    if (!ip)
+        return false;
+
+    MEMORY_BASIC_INFORMATION mem_info;
+
+    if (VirtualQuery(ip, &mem_info, sizeof(mem_info)) == 0)
+        return false;
+
+    if (mem_info.State != MEM_COMMIT)
+        return false;
+
+    return ((mem_info.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
+                    PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0);
+}
+
+bool native_get_stack_range(WalkContext* context, Registers* regs, native_segment_t* seg)
+{
+    MEMORY_BASIC_INFORMATION mem_info;
+
+    if (VirtualQuery(regs->get_sp(), &mem_info, sizeof(mem_info)) == 0)
+        return false;
+
+    if (mem_info.State != MEM_COMMIT)
+        return false;
+
+    seg->base = mem_info.BaseAddress;
+    seg->size = mem_info.RegionSize;
+    return true;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp
------------------------------------------------------------------------------
    svn:eol-style = native



Re: [drlvm][signals] New heuristics for crash handler

Posted by Ilya Berezhniuk <il...@gmail.com>.
Tim,

As an author of the patch, I confirm that these changes affect the
code working in case of crash.

The only change affecting general VM code is the following one-line change:
-    {OpcodeInfo::em64t,   {REX_W, 0xFF, _2}, {r_m64},     U },
+    {OpcodeInfo::em64t,   {0xFF, _2},        {r_m64},     U },

Both Intel and AMD specs say that REX prefix is not required here - so
I hope this change is harmless too.

Thanks,
Ilya.


2008/2/12, Tim Ellison <t....@gmail.com>:
> Gregory Shimansky wrote:
> > Tim Ellison said the following on 12.02.2008 22:32:
> >> Gregory,
> >>
> >> Is this appropriate during feature freeze?  Looks like significant new
> >> functionality.
> >
> > Oh. I didn't realize the _feature_ freeze started up already! I only
> > remembered the date 15th of February from your email. I must have not
> > read it carefully enough. The good thing is that this is not a _feature_
> > per say since crash handler had problems printing good stack traces on
> > x86_64, so it could be called a bug to some extent. On the other hand,
> > if I was aware about the freeze, I'd hold on committing such big change.
> >
> >> Do you guarantee all this code going to work perfectly ?! <g>
> >
> > Well, the code in question is targeted to work only in case of a crash
> > which shouldn't happen in the first place. So I hope it is not critical
> > for general stability. If any regression is noticed, I'll revert this
> > commit.
>
> np -- at least you know there is a feature freeze on now.  Sorry for not
> making it clear.
>
> Regards,
> Tim
>

Re: [drlvm][signals] New heuristics for crash handler

Posted by Tim Ellison <t....@gmail.com>.
Gregory Shimansky wrote:
> Tim Ellison said the following on 12.02.2008 22:32:
>> Gregory,
>>
>> Is this appropriate during feature freeze?  Looks like significant new 
>> functionality.
> 
> Oh. I didn't realize the _feature_ freeze started up already! I only 
> remembered the date 15th of February from your email. I must have not 
> read it carefully enough. The good thing is that this is not a _feature_ 
> per say since crash handler had problems printing good stack traces on 
> x86_64, so it could be called a bug to some extent. On the other hand, 
> if I was aware about the freeze, I'd hold on committing such big change.
> 
>> Do you guarantee all this code going to work perfectly ?! <g>
> 
> Well, the code in question is targeted to work only in case of a crash 
> which shouldn't happen in the first place. So I hope it is not critical 
> for general stability. If any regression is noticed, I'll revert this 
> commit.

np -- at least you know there is a feature freeze on now.  Sorry for not 
making it clear.

Regards,
Tim

Re: [drlvm][signals] New heuristics for crash handler

Posted by Gregory Shimansky <gs...@apache.org>.
Tim Ellison said the following on 12.02.2008 22:32:
> Gregory,
> 
> Is this appropriate during feature freeze?  Looks like significant new 
> functionality.

Oh. I didn't realize the _feature_ freeze started up already! I only 
remembered the date 15th of February from your email. I must have not 
read it carefully enough. The good thing is that this is not a _feature_ 
per say since crash handler had problems printing good stack traces on 
x86_64, so it could be called a bug to some extent. On the other hand, 
if I was aware about the freeze, I'd hold on committing such big change.

> Do you guarantee all this code going to work perfectly ?! <g>

Well, the code in question is targeted to work only in case of a crash 
which shouldn't happen in the first place. So I hope it is not critical 
for general stability. If any regression is noticed, I'll revert this 
commit.

> gshimansky@apache.org wrote:
>> Author: gshimansky
>> Date: Tue Feb 12 09:30:49 2008
>> New Revision: 620872
>>
>> URL: http://svn.apache.org/viewvc?rev=620872&view=rev
>> Log:
>> Applied patch from HARMONY-5490
>> [drlvm][signals] New heuristics for crash handler
>>
>>
>> Added:
>>     
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp   
>> (with props)
>>     
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp   
>> (with props)
>> Modified:
>>     
>> harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp
>>     
>> harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
>>     
>> harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp 
>>
>>     harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h
>>     harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h
>>     harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h
>>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp
>>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
>>     
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp 
>>
>>     
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp 
>>
>>     
>> harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp 
>>
>>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp


[drlvm][signals] New heuristics for crash handler

Posted by Tim Ellison <t....@gmail.com>.
Gregory,

Is this appropriate during feature freeze?  Looks like significant new 
functionality.

Do you guarantee all this code going to work perfectly ?! <g>

Regards,
Tim

gshimansky@apache.org wrote:
> Author: gshimansky
> Date: Tue Feb 12 09:30:49 2008
> New Revision: 620872
> 
> URL: http://svn.apache.org/viewvc?rev=620872&view=rev
> Log:
> Applied patch from HARMONY-5490
> [drlvm][signals] New heuristics for crash handler
> 
> 
> Added:
>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/native_stack_os.cpp   (with props)
>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/native_stack_os.cpp   (with props)
> Modified:
>     harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp
>     harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
>     harmony/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
>     harmony/enhanced/drlvm/trunk/vm/vmcore/include/native_stack.h
>     harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h
>     harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h
>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_stack.cpp
>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp
>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp
>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/ipf/base/native_stack_ipf.cpp
>     harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp