[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-zero-dev
Subject:    Zero stack printer changes
From:       gbenson () redhat ! com (Gary Benson)
Date:       2009-09-09 9:00:56
Message-ID: 20090909090056.GA3281 () redhat ! com
[Download RAW message or body]

Hi all,

This patch rearranges the stack printer code in Zero so that it slots
in better with HotSpot's existing frame walker and therefore requires
less modification to vmError.cpp as requested by Tom Rodriguez.

Cheers,
Gary

-- 
http://gbenson.net/
-------------- next part --------------
diff -r 175266c8ad02 ChangeLog
--- a/ChangeLog	Tue Sep 08 11:47:14 2009 +0100
+++ b/ChangeLog	Wed Sep 09 04:44:36 2009 -0400
@@ -1,3 +1,50 @@
+2009-09-09  Gary Benson  <gbenson at redhat.com>
+
+	* ports/hotspot/src/cpu/zero/vm/stack_zero.hpp
+	(ZeroFrame::identify_word): New method.
+	(ZeroFrame::identify_vp_word): Likewise.
+	
+	* ports/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp
+	(EntryFrame::identify_word): New method.
+	* ports/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp
+	(InterpreterFrame::identify_word): New method.
+	* ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp
+	(SharkFrame::identify_word): New method.
+	* ports/hotspot/src/cpu/zero/vm/deoptimizerFrame_zero.hpp
+	(DeoptimizerFrame::identify_word): Likewise.
+
+	* ports/hotspot/src/cpu/zero/vm/frame_zero.hpp
+	(frame::frame): Added frame pointer argument.
+	(frame::_fp): New field.
+	(frame::fp): Return the above, instead of a dummy value.
+	(frame::zero_print_on_error): New method.
+	* ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
+	(frame::frame): Initialize frame pointer.
+	* ports/hotspot/src/cpu/zero/vm/frame_zero.cpp
+	(frame::sender_for_entry_frame): Pass frame pointer.
+	(frame::sender_for_interpreter_frame): Likewise.
+	(frame::sender_for_compiled_frame): Likewise.
+	(frame::sender_for_deoptimizer_frame): Likewise.
+	(frame::zero_print_on_error): New method.
+	(ZeroFrame::identify_word): Likewise.
+	(EntryFrame::identify_word): Likewise.
+	(InterpreterFrame::identify_word): Likewise.
+	(SharkFrame::identify_word): Likewise.
+	(ZeroFrame::identify_vp_word): Likewise.
+	(DeoptimizerFrame::identify_word): Likewise.
+
+	* ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp
+	(JavaThread::pd_last_frame): Pass frame pointer.
+
+	* ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
+	(os::current_frame): Implemented.
+	
+	* patches/icedtea-zero.patch
+	(VMError::report): Replace stack printer code.
+	(hotspot/src/share/vm/includeDB_core): Updated.
+
+	* ports/hotspot/src/cpu/zero/vm/stackPrinter_zero.hpp: Removed.
+	
 2009-09-08  Gary Benson  <gbenson at redhat.com>
 
 	* ports/hotspot/src/cpu/zero/vm/stack_zero.hpp: Whitespace changes.
diff -r 175266c8ad02 patches/icedtea-zero.patch
--- a/patches/icedtea-zero.patch	Tue Sep 08 11:47:14 2009 +0100
+++ b/patches/icedtea-zero.patch	Wed Sep 09 04:44:36 2009 -0400
@@ -144,43 +144,48 @@
  
 --- openjdk/hotspot/src/share/vm/utilities/vmError.cpp.orig	2008-07-27 08:37:02.000000000 +0000
 +++ openjdk/hotspot/src/share/vm/utilities/vmError.cpp	2008-07-27 08:38:13.000000000 +0000
-@@ -25,6 +25,10 @@
- # include "incls/_precompiled.incl"
- # include "incls/_vmError.cpp.incl"
- 
-+# ifdef ZERO
-+# include <stackPrinter_zero.hpp>
-+# endif // ZERO
-+
- // List of environment variables that should be reported in error log file.
- const char *env_list[] = {
-   // All platforms
-@@ -392,6 +397,7 @@
-        st->cr();
-      }
- 
-+#ifndef ZERO
-   STEP(110, "(printing stack bounds)" )
- 
-      if (_verbose) {
-@@ -449,11 +455,16 @@
-           st->cr();
-        }
-      }
-+#endif // !ZERO
- 
-   STEP(130, "(printing Java stack)" )
+@@ -462,6 +462,40 @@
  
       if (_verbose && _thread && _thread->is_Java_thread()) {
         JavaThread* jt = (JavaThread*)_thread;
 +#ifdef ZERO
-+       st->print_cr("Java stack:");
-+       ZeroStackPrinter(st, buf, sizeof(buf)).print(jt);
++       if (jt->zero_stack()->sp() && jt->top_zero_frame()) {
++         // StackFrameStream uses the frame anchor, which may not have
++         // been set up.  This can be done at any time in Zero, however,
++         // so if it hasn't been set up then we just set it up now and
++         // clear it again when we're done.
++         bool has_last_Java_frame = jt->has_last_Java_frame();
++         if (!has_last_Java_frame)
++           jt->set_last_Java_frame();
++         st->print("Java frames:");
++  
++         // If the top frame is a Shark frame and the frame anchor isn't
++         // set up then it's possible that the information in the frame
++         // is garbage: it could be from a previous decache, or it could
++         // simply have never been written.  So we print a warning...
++         StackFrameStream sfs(jt);
++         if (!has_last_Java_frame && !sfs.is_done()) {
++           if (sfs.current()->zeroframe()->is_shark_frame()) {
++             st->print(" (TOP FRAME MAY BE JUNK)");
++           }
++         }
++         st->cr();
++  
++         // Print the frames
++         for(int i = 0; !sfs.is_done(); sfs.next(), i++) {
++           sfs.current()->zero_print_on_error(i, st, buf, sizeof(buf));
++           st->cr();
++         }
++  
++         // Reset the frame anchor if necessary
++         if (!has_last_Java_frame)
++           jt->reset_last_Java_frame();
++       }
 +#else
         if (jt->has_last_Java_frame()) {
           st->print_cr("Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)");
           for(StackFrameStream sfs(jt); !sfs.is_done(); sfs.next()) {
-@@ -461,6 +472,7 @@
+@@ -469,6 +503,7 @@
             st->cr();
           }
         }
@@ -188,21 +193,7 @@
       }
  
    STEP(140, "(printing VM operation)" )
-@@ -472,6 +484,14 @@ void VMError::report(outputStream* st) {
-           op->print_on_error(st);
-           st->cr();
-           st->cr();
-+#ifdef ZERO
-+          if (op->calling_thread()->is_Java_thread()) {
-+            st->print_cr("Calling thread's Java stack:");
-+            ZeroStackPrinter(st, buf, sizeof(buf)).print(
-+              (JavaThread *) op->calling_thread());
-+            st->cr();
-+          }
-+#endif // ZERO
-         }
-      }
- 
+
 Index: openjdk/hotspot/src/share/vm/runtime/jniHandles.cpp
 ===================================================================
 --- openjdk/hotspot/src/share/vm/runtime/jniHandles.cpp.orig	2009-06-10 11:30:46.000000000 +0200
@@ -219,3 +210,20 @@
  }
  
  
+--- openjdk/hotspot/src/share/vm/includeDB_core	2009-09-08 13:22:25.000000000 +0100
++++ openjdk/hotspot/src/share/vm/includeDB_core	2009-09-08 13:41:57.000000000 +0100
+@@ -1655,12 +1655,14 @@
+ frame_<arch>.cpp                        frame.inline.hpp
+ frame_<arch>.cpp                        handles.inline.hpp
+ frame_<arch>.cpp                        interpreter.hpp
++frame_<arch>.cpp                        interpreterRuntime.hpp
+ frame_<arch>.cpp                        javaCalls.hpp
+ frame_<arch>.cpp                        markOop.hpp
+ frame_<arch>.cpp                        methodOop.hpp
+ frame_<arch>.cpp                        monitorChunk.hpp
+ frame_<arch>.cpp                        oop.inline.hpp
+ frame_<arch>.cpp                        resourceArea.hpp
++frame_<arch>.cpp                        scopeDesc.hpp
+ frame_<arch>.cpp                        signature.hpp
+ frame_<arch>.cpp                        stubCodeGenerator.hpp
+ frame_<arch>.cpp                        stubRoutines.hpp
diff -r 175266c8ad02 ports/hotspot/src/cpu/zero/vm/deoptimizerFrame_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/deoptimizerFrame_zero.hpp	Tue Sep 08 11:47:14 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/deoptimizerFrame_zero.hpp	Wed Sep 09 04:44:36 2009 -0400
@@ -45,4 +45,11 @@
 
  public:
   static DeoptimizerFrame *build(ZeroStack* stack);
+
+ public:
+  void identify_word(int   frame_index,
+                     int   offset,
+                     char* fieldbuf,
+                     char* valuebuf,
+                     int   buflen) const;
 };
diff -r 175266c8ad02 ports/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp	Tue Sep 08 11:47:14 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp	Wed Sep 09 04:44:36 2009 -0400
@@ -57,4 +57,11 @@
   JavaCallWrapper *call_wrapper() const {
     return (JavaCallWrapper *) value_of_word(call_wrapper_off);
   }
+
+ public:
+  void identify_word(int   frame_index,
+                     int   offset,
+                     char* fieldbuf,
+                     char* valuebuf,
+                     int   buflen) const;
 };
diff -r 175266c8ad02 ports/hotspot/src/cpu/zero/vm/frame_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.cpp	Tue Sep 08 11:47:14 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.cpp	Wed Sep 09 04:44:36 2009 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
- * Copyright 2007, 2008 Red Hat, Inc.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,19 +47,19 @@
          "sender should be next Java frame");
   map->clear();
   assert(map->include_argument_oops(), "should be set by clear");
-  return frame(sender_sp());
+  return frame(sender_sp(), sp() + 1);
 }
 
 frame frame::sender_for_interpreter_frame(RegisterMap *map) const {
-  return frame(sender_sp());
+  return frame(sender_sp(), sp() + 1);
 }
 
 frame frame::sender_for_compiled_frame(RegisterMap *map) const {
-  return frame(sender_sp());
+  return frame(sender_sp(), sp() + 1);
 }
 
 frame frame::sender_for_deoptimizer_frame(RegisterMap *map) const {
-  return frame(sender_sp());
+  return frame(sender_sp(), sp() + 1);
 }
 
 frame frame::sender(RegisterMap* map) const {
@@ -180,3 +180,243 @@
   int index = (Interpreter::expr_offset_in_bytes(offset) / wordSize);
   return &interpreter_frame_tos_address()[index];
 }
+
+void frame::zero_print_on_error(int           frame_index,
+                                outputStream* st,
+                                char*         buf,
+                                int           buflen) const {
+  // Divide the buffer between the field and the value
+  buflen >>= 1;
+  char *fieldbuf = buf;
+  char *valuebuf = buf + buflen;
+
+  // Print each word of the frame
+  for (intptr_t *addr = fp(); addr <= sp(); addr++) {
+    int offset = sp() - addr;
+
+    // Fill in default values, then try and improve them
+    snprintf(fieldbuf, buflen, "word[%d]", offset);
+    snprintf(valuebuf, buflen, PTR_FORMAT, *addr);
+    zeroframe()->identify_word(frame_index, offset, fieldbuf, valuebuf, buflen);
+    fieldbuf[buflen - 1] = '\0';
+    valuebuf[buflen - 1] = '\0';
+
+    // Print the result
+    st->print_cr(" " PTR_FORMAT ": %-21s = %s", addr, fieldbuf, valuebuf);
+  }
+}
+
+void ZeroFrame::identify_word(int   frame_index,
+                              int   offset,
+                              char* fieldbuf,
+                              char* valuebuf,
+                              int   buflen) const {
+  switch (offset) {
+  case next_frame_off:
+    strncpy(fieldbuf, "next_frame", buflen);
+    break;
+
+  case frame_type_off:
+    strncpy(fieldbuf, "frame_type", buflen);
+    if (is_entry_frame())
+      strncpy(valuebuf, "ENTRY_FRAME", buflen);
+    else if (is_interpreter_frame())
+      strncpy(valuebuf, "INTERPRETER_FRAME", buflen);
+    else if (is_shark_frame())
+      strncpy(valuebuf, "SHARK_FRAME", buflen);
+    else if (is_deoptimizer_frame())
+      strncpy(valuebuf, "DEOPTIMIZER_FRAME", buflen);
+    break;
+
+  default:
+    if (is_entry_frame()) {
+      as_entry_frame()->identify_word(
+        frame_index, offset, fieldbuf, valuebuf, buflen);
+    }
+    else if (is_interpreter_frame()) {
+      as_interpreter_frame()->identify_word(
+        frame_index, offset, fieldbuf, valuebuf, buflen);
+    }
+    else if (is_shark_frame()) {
+      as_shark_frame()->identify_word(
+        frame_index, offset, fieldbuf, valuebuf, buflen);
+    }
+    else if (is_deoptimizer_frame()) {
+      as_deoptimizer_frame()->identify_word(
+        frame_index, offset, fieldbuf, valuebuf, buflen);
+    }
+  }
+}
+
+void EntryFrame::identify_word(int   frame_index,
+                               int   offset,
+                               char* fieldbuf,
+                               char* valuebuf,
+                               int   buflen) const {
+  switch (offset) {
+  case call_wrapper_off:
+    strncpy(fieldbuf, "call_wrapper", buflen);
+    break;
+
+  default:
+    snprintf(fieldbuf, buflen, "local[%d]", offset - 3);
+  }
+}
+
+void InterpreterFrame::identify_word(int   frame_index,
+                                     int   offset,
+                                     char* fieldbuf,
+                                     char* valuebuf,
+                                     int   buflen) const {
+  interpreterState istate = interpreter_state();
+  bool is_valid = istate->self_link() == istate;
+  intptr_t *addr = addr_of_word(offset);
+
+  // Fixed part
+  if (addr >= (intptr_t *) istate) {
+    const char *field = istate->name_of_field_at_address((address) addr);
+    if (field) {
+      if (is_valid && !strcmp(field, "_method")) {
+        istate->method()->name_and_sig_as_C_string(valuebuf, buflen);
+      }
+      else if (is_valid && !strcmp(field, "_bcp") && istate->bcp()) {
+        snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
+                 istate->bcp(), istate->method()->bci_from(istate->bcp()));
+      }
+      snprintf(fieldbuf, buflen, "%sistate->%s",
+               field[strlen(field) - 1] == ')' ? "(": "", field);
+    }
+    else if (addr == (intptr_t *) istate) {
+      strncpy(fieldbuf, "(vtable for istate)", buflen);
+    }
+    return;
+  }
+
+  // Variable part
+  if (!is_valid)
+    return;
+
+  // JNI stuff
+  if (istate->method()->is_native() && addr < istate->stack_base()) {
+    address hA = istate->method()->signature_handler();
+    if (hA != NULL) {
+      if (hA != (address) InterpreterRuntime::slow_signature_handler) {
+        InterpreterRuntime::SignatureHandler *handler =
+          InterpreterRuntime::SignatureHandler::from_handlerAddr(hA);
+
+        intptr_t *params = istate->stack_base() - handler->argument_count();
+        if (addr >= params) {
+          int param = addr - params;
+          const char *desc = "";
+          if (param == 0)
+            desc = " (JNIEnv)";
+          else if (param == 1) {
+            if (istate->method()->is_static())
+              desc = " (mirror)";
+            else
+              desc = " (this)";
+          }
+          snprintf(fieldbuf, buflen, "parameter[%d]%s", param, desc);
+          return;
+        }
+
+        for (int i = 0; i < handler->argument_count(); i++) {
+          if (params[i] == (intptr_t) addr) {
+            snprintf(fieldbuf, buflen, "unboxed parameter[%d]", i);
+            return;
+          }
+        }
+      }
+    }
+    return;
+  }
+
+  // Monitors and stack
+  identify_vp_word(frame_index, addr,
+                   (intptr_t *) istate->monitor_base(),
+                   istate->stack_base(),
+                   fieldbuf, buflen);
+}
+
+void SharkFrame::identify_word(int   frame_index,
+                               int   offset,
+                               char* fieldbuf,
+                               char* valuebuf,
+                               int   buflen) const {
+  // Fixed part
+  switch (offset) {
+  case pc_off:
+    strncpy(fieldbuf, "pc", buflen);
+    if (method()->is_oop()) {
+      nmethod *code = method()->code();
+      if (code && code->pc_desc_at(pc())) {
+        SimpleScopeDesc ssd(code, pc());
+        snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)", pc(), ssd.bci());
+      }
+    }
+    return;
+
+  case unextended_sp_off:
+    strncpy(fieldbuf, "unextended_sp", buflen);
+    return;
+
+  case method_off:
+    strncpy(fieldbuf, "method", buflen);
+    if (method()->is_oop()) {
+      method()->name_and_sig_as_C_string(valuebuf, buflen);
+    }
+    return;
+
+  case oop_tmp_off:
+    strncpy(fieldbuf, "oop_tmp", buflen);
+    return;
+  }
+
+  // Variable part
+  if (method()->is_oop()) {
+    identify_vp_word(frame_index, addr_of_word(offset),
+                     addr_of_word(header_words + 1),
+                     unextended_sp() + method()->max_stack(),
+                     fieldbuf, buflen);
+  }
+}
+
+void ZeroFrame::identify_vp_word(int       frame_index,
+                                 intptr_t* addr,
+                                 intptr_t* monitor_base,
+                                 intptr_t* stack_base,
+                                 char*     fieldbuf,
+                                 int       buflen) const {
+  // Monitors
+  if (addr >= stack_base && addr < monitor_base) {
+    int monitor_size = frame::interpreter_frame_monitor_size();
+    int last_index = (monitor_base - stack_base) / monitor_size - 1;
+    int index = last_index - (addr - stack_base) / monitor_size;
+    intptr_t monitor = (intptr_t) (
+      (BasicObjectLock *) monitor_base - 1 - index);
+    intptr_t offset = (intptr_t) addr - monitor;
+    
+    if (offset == BasicObjectLock::obj_offset_in_bytes())
+      snprintf(fieldbuf, buflen, "monitor[%d]->_obj", index);
+    else if (offset ==  BasicObjectLock::lock_offset_in_bytes())
+      snprintf(fieldbuf, buflen, "monitor[%d]->_lock", index);
+
+    return;
+  }
+
+  // Expression stack
+  if (addr < stack_base) {
+    snprintf(fieldbuf, buflen, "%s[%d]",
+             frame_index == 0 ? "stack_word" : "local",
+             (int) (stack_base - addr - 1));
+    return;
+  }
+}
+
+void DeoptimizerFrame::identify_word(int   frame_index,
+                                     int   offset,
+                                     char* fieldbuf,
+                                     char* valuebuf,
+                                     int   buflen) const {
+  // Deoptimizer frames have no extra words to identify
+}
diff -r 175266c8ad02 ports/hotspot/src/cpu/zero/vm/frame_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.hpp	Tue Sep 08 11:47:14 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.hpp	Wed Sep 09 04:44:36 2009 -0400
@@ -23,24 +23,26 @@
  *
  */
 
-// A frame represents a physical stack frame (an activation).  Frames
-// can be C or Java frames, and the Java frames can be interpreted or
-// compiled.  In contrast, vframes represent source-level activations,
-// so that one physical frame can correspond to multiple source level
-// frames because of inlining.  A frame is comprised of {pc, sp}
+// A frame represents a physical stack frame on the Zero stack.
 
  public:
   enum {
     pc_return_offset = 0
   };
 
+  // Constructor
  public:
-  // Constructors
-  frame(intptr_t* sp);
+  frame(intptr_t* sp, intptr_t* fp);
 
-  // accessors for the instance variables
+  // The sp of a Zero frame is the address of the highest word in
+  // that frame.  We keep track of the lowest address too, so the
+  // boundaries of the frame are available for debug printing.
+ private:
+  intptr_t* _fp;
+
+ public:
   intptr_t* fp() const {
-    return (intptr_t *) -1;
+    return _fp;
   }
 
 #ifdef CC_INTERP
@@ -67,3 +69,9 @@
 
  public:
   frame sender_for_deoptimizer_frame(RegisterMap* map) const;  
+
+ public:
+  void zero_print_on_error(int           index,
+                           outputStream* st,
+                           char*         buf,
+                           int           buflen) const;
diff -r 175266c8ad02 ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Tue Sep 08 11:47:14 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Wed Sep 09 04:44:36 2009 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
- * Copyright 2007, 2008 Red Hat, Inc.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,13 +32,15 @@
 
 inline frame::frame() {
   _sp = NULL;
+  _fp = NULL;
   _pc = NULL;
   _cb = NULL;
   _deopt_state = unknown;
 }
 
-inline frame::frame(intptr_t* sp) {
+inline frame::frame(intptr_t* sp, intptr_t* fp) {
   _sp = sp;
+  _fp = fp;
   switch (zeroframe()->type()) {
   case ZeroFrame::ENTRY_FRAME:
     _pc = StubRoutines::call_stub_return_pc();
diff -r 175266c8ad02 ports/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp	Tue Sep 08 11:47:14 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp	Wed Sep 09 04:44:36 2009 -0400
@@ -65,5 +65,12 @@
   interpreterState interpreter_state() const {
     return (interpreterState) addr_of_word(istate_off);
   }
+
+ public:
+  void identify_word(int   frame_index,
+                     int   offset,
+                     char* fieldbuf,
+                     char* valuebuf,
+                     int   buflen) const;
 };
 #endif // CC_INTERP
diff -r 175266c8ad02 ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp	Tue Sep 08 11:47:14 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp	Wed Sep 09 04:44:36 2009 -0400
@@ -70,4 +70,11 @@
   methodOop method() const {
     return (methodOop) value_of_word(method_off);
   }
+
+ public:
+  void identify_word(int   frame_index,
+                     int   offset,
+                     char* fieldbuf,
+                     char* valuebuf,
+                     int   buflen) const;
 };
diff -r 175266c8ad02 ports/hotspot/src/cpu/zero/vm/stackPrinter_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/stackPrinter_zero.hpp	Tue Sep 08 11:47:14 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-/*
- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- */
-
-#include <interpreterRuntime.hpp>
-#include <scopeDesc.hpp>
-
-class ZeroStackPrinter {
- private:
-  outputStream* _st;
-  char*         _buf;
-  int           _buflen;
-
- public:
-  ZeroStackPrinter(outputStream *st, char *buf, int buflen)
-    : _st(st), _buf(buf), _buflen(buflen) {}
-
-  void print(JavaThread *thread) {
-    intptr_t *lo_addr = thread->zero_stack()->sp();
-    if (!lo_addr) {
-      _st->print_cr(" stack not set up");
-      return;
-    }
-
-    intptr_t *hi_addr = (intptr_t *) thread->top_zero_frame();
-    if (!hi_addr) {
-      _st->print_cr("no frames pushed"); 
-      return;
-    }
-    assert(hi_addr >= lo_addr, "corrupted stack");
-
-    bool top_frame = true;
-    while (hi_addr) {
-      if (!top_frame)
-        _st->cr();      
-      ZeroFrame *frame = (ZeroFrame *) hi_addr;
-      for (intptr_t *addr = lo_addr; addr <= hi_addr; addr++)
-        print_word(frame, addr, top_frame);
-      lo_addr = hi_addr + 1;
-      hi_addr = *(intptr_t **) hi_addr;
-      top_frame = false;
-    }
-  }
-
- private:
-  void print_word(ZeroFrame *frame, intptr_t *addr, bool top_frame) {
-    const char *field = NULL;
-    const char *value = NULL;
-
-    int word = (intptr_t *) frame - addr;
-    switch (word) {
-    case ZeroFrame::next_frame_off:
-      field = "next_frame";
-      break;
-    case ZeroFrame::frame_type_off:
-      field = "frame_type";
-      switch (*addr) {
-      case ZeroFrame::ENTRY_FRAME:
-        value = "ENTRY_FRAME";
-        break;
-      case ZeroFrame::INTERPRETER_FRAME:
-        value = "INTERPRETER_FRAME";
-        break;
-      case ZeroFrame::SHARK_FRAME:
-        value = "SHARK_FRAME";
-        break;
-      case ZeroFrame::DEOPTIMIZER_FRAME:
-        value = "DEOPTIMIZER_FRAME";
-        break;
-      }
-      break;
-    }
-
-    if (!field) {
-      if (frame->is_entry_frame()) {
-        if (word == EntryFrame::call_wrapper_off) {
-          field = "call_wrapper";
-        }
-        else {
-          snprintf(_buf, _buflen, "local[%d]", word - 3);
-          field = _buf;
-        }
-      }
-      if (frame->is_interpreter_frame()) {
-        interpreterState istate =
-          ((InterpreterFrame *) frame)->interpreter_state();
-        bool is_valid = istate->self_link() == istate;
-        
-        if (addr >= (intptr_t *) istate) {
-          field = istate->name_of_field_at_address((address) addr);
-          if (field) {
-            if (is_valid && !strcmp(field, "_method")) {
-              value = istate->method()->name_and_sig_as_C_string(_buf,_buflen);
-              field = "istate->_method";
-            }
-            else if (is_valid && !strcmp(field, "_bcp") && istate->bcp()) {
-              snprintf(_buf, _buflen, PTR_FORMAT " (bci %d)", istate->bcp(),
-                       istate->method()->bci_from(istate->bcp()));
-              value = _buf;
-              field = "istate->_bcp";
-            }
-            else {
-              snprintf(_buf, _buflen, "%sistate->%s",
-                       field[strlen(field) - 1] == ')' ? "(": "", field);
-              field = _buf;
-            }
-          }
-          else if (addr == (intptr_t *) istate) {
-            field = "(vtable for istate)";
-          }
-        }
-        else if (is_valid) {
-          intptr_t *monitor_base = (intptr_t *) istate->monitor_base();
-          if (addr >= istate->stack_base() && addr < monitor_base) {
-            int monitor_size = frame::interpreter_frame_monitor_size();
-            int last_index =
-              (monitor_base - istate->stack_base()) / monitor_size - 1;
-            int index =
-              last_index - (addr - istate->stack_base()) / monitor_size;
-            intptr_t monitor = (intptr_t) (istate->monitor_base() - 1 - index);
-            intptr_t offset = (intptr_t) addr - monitor;
-            
-            if (offset == BasicObjectLock::obj_offset_in_bytes()) {
-              snprintf(_buf, _buflen, "monitor[%d]->_obj", index);
-              field = _buf;
-            }
-            else if (offset ==  BasicObjectLock::lock_offset_in_bytes()) {
-              snprintf(_buf, _buflen, "monitor[%d]->_lock", index);
-              field = _buf;
-            }
-          }
-          else if (addr < istate->stack_base()) {
-            if (istate->method()->is_native()) {
-              address hA = istate->method()->signature_handler();
-              if (hA != NULL) {
-                if (hA != (address)InterpreterRuntime::slow_signature_handler){
-                  InterpreterRuntime::SignatureHandler *handler =
-                    InterpreterRuntime::SignatureHandler::from_handlerAddr(hA);
-  
-                  intptr_t *params =
-                    istate->stack_base() - handler->argument_count();
-  
-                  if (addr >= params) {
-                    int param = addr - params;
-                    const char *desc = "";
-                    if (param == 0)
-                      desc = " (JNIEnv)";
-                    else if (param == 1) {
-                      if (istate->method()->is_static())
-                        desc = " (mirror)";
-                      else
-                        desc = " (this)";
-                    }
-                    snprintf(_buf, _buflen, "parameter[%d]%s", param, desc);
-                    field = _buf;
-                  }
-                  else {
-                    for (int i = 0; i < handler->argument_count(); i++) {
-                      if (params[i] == (intptr_t) addr) {
-                        snprintf(_buf, _buflen, "unboxed parameter[%d]", i);
-                        field = _buf;
-                        break;
-                      }
-                    } 
-                  }
-                }
-              }
-            }
-            else {
-              snprintf(_buf, _buflen, "%s[" INTPTR_FORMAT "]",
-                       top_frame ? "stack_word" : "local",
-                       istate->stack_base() - addr - 1);
-              field = _buf;
-            }
-          }
-        }
-      }
-      if (frame->is_shark_frame()) {
-        SharkFrame *sf = frame->as_shark_frame();
-        methodOop method = sf->method();
-          
-        if (word == SharkFrame::pc_off) {
-          field = "pc";
-          if (method->is_oop()) {
-            nmethod *code = method->code();
-            address pc = sf->pc();
-            if (code->pc_desc_at(pc)) {
-              SimpleScopeDesc ssd(code, pc);
-              snprintf(_buf, _buflen, PTR_FORMAT " (bci %d)", pc, ssd.bci());
-              value = _buf;
-            }
-          }
-        }
-        else if (word == SharkFrame::unextended_sp_off) {
-          field = "unextended_sp";
-        }
-        else if (word == SharkFrame::method_off) {
-          field = "method";
-          if (method->is_oop())
-            value = method->name_and_sig_as_C_string(_buf, _buflen);
-        }
-        else if (word == SharkFrame::oop_tmp_off) {
-          field = "oop_tmp";
-        }
-        else {
-          SharkFrame *sf = (SharkFrame *) frame;
-          intptr_t *monitor_base =
-            (intptr_t *) frame - SharkFrame::header_words + 1;
-          intptr_t *stack_base =
-            sf->unextended_sp() + sf->method()->max_stack();
-
-          if (addr >= stack_base && addr < monitor_base) {
-            int monitor_size = frame::interpreter_frame_monitor_size();
-            int last_index = (monitor_base - stack_base) / monitor_size - 1;
-            int index = last_index - (addr - stack_base) / monitor_size;
-            intptr_t monitor =
-              (intptr_t) ((BasicObjectLock *) monitor_base - 1 - index);
-            intptr_t offset = (intptr_t) addr - monitor;
-
-            if (offset == BasicObjectLock::obj_offset_in_bytes()) {
-              snprintf(_buf, _buflen, "monitor[%d]->_obj", index);
-              field = _buf;
-            }
-            else if (offset ==  BasicObjectLock::lock_offset_in_bytes()) {
-              snprintf(_buf, _buflen, "monitor[%d]->_lock", index);
-              field = _buf;
-            }
-          }
-          else {
-            snprintf(_buf, _buflen, "%s[" INTPTR_FORMAT "]",
-                     top_frame ? "stack_word" : "local",
-                     stack_base - addr - 1);
-            field = _buf;
-          }
-        }
-      }
-    }
-      
-    if (!field) {
-      snprintf(_buf, _buflen, "word[%d]", word);
-      field = _buf;
-    }
-    _st->print(" %p: %-21s = ", addr, field);
-    if (value)
-      _st->print_cr("%s", value);
-    else
-      _st->print_cr(PTR_FORMAT, *addr);    
-  }
-};
-
-#ifndef PRODUCT
-extern "C" {
-  void print_zero_threads() {
-    char buf[O_BUFLEN];
-    ZeroStackPrinter zsp(tty, buf, sizeof(buf));
-
-    for (JavaThread *t = Threads::first(); t; t = t->next()) {
-      tty->print(PTR_FORMAT, t);
-      tty->print(" ");
-      t->print_on_error(tty, buf, sizeof(buf));
-      tty->cr();
-      tty->cr();
-
-      zsp.print(t);
-      if (t->next())
-        tty->cr();
-    }
-  }
-}
-#endif // !PRODUCT
diff -r 175266c8ad02 ports/hotspot/src/cpu/zero/vm/stack_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp	Tue Sep 08 11:47:14 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp	Wed Sep 09 04:44:36 2009 -0400
@@ -179,4 +179,19 @@
     assert(is_deoptimizer_frame(), "should be");
     return (DeoptimizerFrame *) this;
   }
+
+ public:
+  void identify_word(int   frame_index,
+                     int   offset,
+                     char* fieldbuf,
+                     char* valuebuf,
+                     int   buflen) const;
+
+ protected:
+  void identify_vp_word(int       frame_index,
+                        intptr_t* addr,
+                        intptr_t* monitor_base,
+                        intptr_t* stack_base,
+                        char*     fieldbuf,
+                        int       buflen) const;
 };
diff -r 175266c8ad02 ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
--- a/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Tue Sep 08 11:47:14 2009 +0100
+++ b/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Wed Sep 09 04:44:36 2009 -0400
@@ -36,7 +36,18 @@
 }
 
 frame os::current_frame() {
-  Unimplemented();
+  // The only thing that calls this is the stack printing code in
+  // VMError::report:
+  //   - Step 110 (printing stack bounds) uses the sp in the frame
+  //     to determine the amount of free space on the stack.  We
+  //     set the sp to a close approximation of the real value in
+  //     order to allow this step to complete.
+  //   - Step 120 (printing native stack) tries to walk the stack.
+  //     The frame we create has a NULL pc, which is ignored as an
+  //     invalid frame.
+  frame dummy = frame();
+  dummy.set_sp((intptr_t *) current_stack_pointer());
+  return dummy;
 }
 
 char* os::non_memory_address_word() {
diff -r 175266c8ad02 ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp
--- a/ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp	Tue Sep 08 11:47:14 2009 +0100
+++ b/ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp	Wed Sep 09 04:44:36 2009 -0400
@@ -79,7 +79,7 @@
  private:
   frame pd_last_frame() {
     assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
-    return frame(last_Java_sp());
+    return frame(last_Java_sp(), zero_stack()->sp());
   }
 
  public:

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic