changeset 1832:1e9a9d2e6509

6970683: improvements to hs_err output Reviewed-by: kvn, jrose, dholmes, coleenp
author never
date Thu, 21 Oct 2010 11:55:10 -0700
parents f8aaf8522a6b
children f195c4737aca
files src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp src/os_cpu/linux_x86/vm/os_linux_x86.cpp src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp src/os_cpu/windows_x86/vm/os_windows_x86.cpp src/share/vm/code/codeCache.cpp src/share/vm/code/codeCache.hpp src/share/vm/gc_implementation/includeDB_gc_parallelScavenge src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp src/share/vm/memory/heap.hpp src/share/vm/runtime/os.cpp src/share/vm/runtime/os.hpp src/share/vm/utilities/vmError.cpp
diffstat 13 files changed, 383 insertions(+), 389 deletions(-) [+]
line wrap: on
line diff
--- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Thu Oct 21 11:55:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -200,6 +200,18 @@
   sigcontext* sc = (sigcontext*)context;
   st->print_cr("Registers:");
 
+  st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT
+               " G3=" INTPTR_FORMAT " G4=" INTPTR_FORMAT,
+               SIG_REGS(sc).u_regs[CON_G1],
+               SIG_REGS(sc).u_regs[CON_G2],
+               SIG_REGS(sc).u_regs[CON_G3],
+               SIG_REGS(sc).u_regs[CON_G4]);
+  st->print_cr(" G5=" INTPTR_FORMAT " G6=" INTPTR_FORMAT
+               " G7=" INTPTR_FORMAT " Y=" INTPTR_FORMAT,
+               SIG_REGS(sc).u_regs[CON_G5],
+               SIG_REGS(sc).u_regs[CON_G6],
+               SIG_REGS(sc).u_regs[CON_G7],
+               SIG_REGS(sc).y);
   st->print_cr(" O0=" INTPTR_FORMAT " O1=" INTPTR_FORMAT
                " O2=" INTPTR_FORMAT " O3=" INTPTR_FORMAT,
                SIG_REGS(sc).u_regs[CON_O0],
@@ -213,18 +225,32 @@
                SIG_REGS(sc).u_regs[CON_O6],
                SIG_REGS(sc).u_regs[CON_O7]);
 
-  st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT
-               " G3=" INTPTR_FORMAT " G4=" INTPTR_FORMAT,
-               SIG_REGS(sc).u_regs[CON_G1],
-               SIG_REGS(sc).u_regs[CON_G2],
-               SIG_REGS(sc).u_regs[CON_G3],
-               SIG_REGS(sc).u_regs[CON_G4]);
-  st->print_cr(" G5=" INTPTR_FORMAT " G6=" INTPTR_FORMAT
-               " G7=" INTPTR_FORMAT " Y=" INTPTR_FORMAT,
-               SIG_REGS(sc).u_regs[CON_G5],
-               SIG_REGS(sc).u_regs[CON_G6],
-               SIG_REGS(sc).u_regs[CON_G7],
-               SIG_REGS(sc).y);
+
+  intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
+  st->print_cr(" L0=" INTPTR_FORMAT " L1=" INTPTR_FORMAT
+               " L2=" INTPTR_FORMAT " L3=" INTPTR_FORMAT,
+               sp[L0->sp_offset_in_saved_window()],
+               sp[L1->sp_offset_in_saved_window()],
+               sp[L2->sp_offset_in_saved_window()],
+               sp[L3->sp_offset_in_saved_window()]);
+  st->print_cr(" L4=" INTPTR_FORMAT " L5=" INTPTR_FORMAT
+               " L6=" INTPTR_FORMAT " L7=" INTPTR_FORMAT,
+               sp[L4->sp_offset_in_saved_window()],
+               sp[L5->sp_offset_in_saved_window()],
+               sp[L6->sp_offset_in_saved_window()],
+               sp[L7->sp_offset_in_saved_window()]);
+  st->print_cr(" I0=" INTPTR_FORMAT " I1=" INTPTR_FORMAT
+               " I2=" INTPTR_FORMAT " I3=" INTPTR_FORMAT,
+               sp[I0->sp_offset_in_saved_window()],
+               sp[I1->sp_offset_in_saved_window()],
+               sp[I2->sp_offset_in_saved_window()],
+               sp[I3->sp_offset_in_saved_window()]);
+  st->print_cr(" I4=" INTPTR_FORMAT " I5=" INTPTR_FORMAT
+               " I6=" INTPTR_FORMAT " I7=" INTPTR_FORMAT,
+               sp[I4->sp_offset_in_saved_window()],
+               sp[I5->sp_offset_in_saved_window()],
+               sp[I6->sp_offset_in_saved_window()],
+               sp[I7->sp_offset_in_saved_window()]);
 
   st->print_cr(" PC=" INTPTR_FORMAT " nPC=" INTPTR_FORMAT,
                SIG_PC(sc),
@@ -232,7 +258,6 @@
   st->cr();
   st->cr();
 
-  intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
   st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
   print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t));
   st->cr();
@@ -242,7 +267,58 @@
   // this at the end, and hope for the best.
   address pc = os::Linux::ucontext_get_pc(uc);
   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
-  print_hex_dump(st, pc - 16, pc + 16, sizeof(char));
+  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+}
+
+
+void os::print_register_info(outputStream *st, void *context) {
+  if (context == NULL) return;
+
+  ucontext_t *uc = (ucontext_t*)context;
+  intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is only for the "general purpose" registers
+  st->print("G1="); print_location(st, SIG_REGS(sc).u_regs[CON__G1]);
+  st->print("G2="); print_location(st, SIG_REGS(sc).u_regs[CON__G2]);
+  st->print("G3="); print_location(st, SIG_REGS(sc).u_regs[CON__G3]);
+  st->print("G4="); print_location(st, SIG_REGS(sc).u_regs[CON__G4]);
+  st->print("G5="); print_location(st, SIG_REGS(sc).u_regs[CON__G5]);
+  st->print("G6="); print_location(st, SIG_REGS(sc).u_regs[CON__G6]);
+  st->print("G7="); print_location(st, SIG_REGS(sc).u_regs[CON__G7]);
+  st->cr();
+
+  st->print("O0="); print_location(st, SIG_REGS(sc).u_regs[CON__O0]);
+  st->print("O1="); print_location(st, SIG_REGS(sc).u_regs[CON__O1]);
+  st->print("O2="); print_location(st, SIG_REGS(sc).u_regs[CON__O2]);
+  st->print("O3="); print_location(st, SIG_REGS(sc).u_regs[CON__O3]);
+  st->print("O4="); print_location(st, SIG_REGS(sc).u_regs[CON__O4]);
+  st->print("O5="); print_location(st, SIG_REGS(sc).u_regs[CON__O5]);
+  st->print("O6="); print_location(st, SIG_REGS(sc).u_regs[CON__O6]);
+  st->print("O7="); print_location(st, SIG_REGS(sc).u_regs[CON__O7]);
+  st->cr();
+
+  st->print("L0="); print_location(st, sp[L0->sp_offset_in_saved_window()]);
+  st->print("L1="); print_location(st, sp[L1->sp_offset_in_saved_window()]);
+  st->print("L2="); print_location(st, sp[L2->sp_offset_in_saved_window()]);
+  st->print("L3="); print_location(st, sp[L3->sp_offset_in_saved_window()]);
+  st->print("L4="); print_location(st, sp[L4->sp_offset_in_saved_window()]);
+  st->print("L5="); print_location(st, sp[L5->sp_offset_in_saved_window()]);
+  st->print("L6="); print_location(st, sp[L6->sp_offset_in_saved_window()]);
+  st->print("L7="); print_location(st, sp[L7->sp_offset_in_saved_window()]);
+  st->cr();
+
+  st->print("I0="); print_location(st, sp[I0->sp_offset_in_saved_window()]);
+  st->print("I1="); print_location(st, sp[I1->sp_offset_in_saved_window()]);
+  st->print("I2="); print_location(st, sp[I2->sp_offset_in_saved_window()]);
+  st->print("I3="); print_location(st, sp[I3->sp_offset_in_saved_window()]);
+  st->print("I4="); print_location(st, sp[I4->sp_offset_in_saved_window()]);
+  st->print("I5="); print_location(st, sp[I5->sp_offset_in_saved_window()]);
+  st->print("I6="); print_location(st, sp[I6->sp_offset_in_saved_window()]);
+  st->print("I7="); print_location(st, sp[I7->sp_offset_in_saved_window()]);
+  st->cr();
 }
 
 
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Oct 21 11:55:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -718,11 +718,6 @@
 
   ucontext_t *uc = (ucontext_t*)context;
   st->print_cr("Registers:");
-
-  // this is horrendously verbose but the layout of the registers in the
-  // context does not match how we defined our abstract Register set, so
-  // we can't just iterate through the gregs area
-
 #ifdef AMD64
   st->print(  "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
   st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
@@ -745,68 +740,11 @@
   st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]);
   st->cr();
   st->print(  "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]);
-  st->print(", EFL=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
+  st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
   st->print(", CSGSFS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_CSGSFS]);
   st->print(", ERR=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ERR]);
   st->cr();
   st->print("  TRAPNO=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_TRAPNO]);
-
-  st->cr();
-  st->cr();
-
-  st->print_cr("Register to memory mapping:");
-  st->cr();
-
-  // this is only for the "general purpose" registers
-
-  st->print_cr("RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RAX]);
-  st->cr();
-  st->print_cr("RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RBX]);
-  st->cr();
-  st->print_cr("RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RCX]);
-  st->cr();
-  st->print_cr("RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RDX]);
-  st->cr();
-  st->print_cr("RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
-  st->cr();
-  st->print_cr("RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RBP]);
-  st->cr();
-  st->print_cr("RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RSI]);
-  st->cr();
-  st->print_cr("RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RDI]);
-  st->cr();
-  st->print_cr("R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R8]);
-  st->cr();
-  st->print_cr("R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R9]);
-  st->cr();
-  st->print_cr("R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R10]);
-  st->cr();
-  st->print_cr("R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R11]);
-  st->cr();
-  st->print_cr("R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R12]);
-  st->cr();
-  st->print_cr("R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R13]);
-  st->cr();
-  st->print_cr("R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R14]);
-  st->cr();
-  st->print_cr("R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R15]);
-
 #else
   st->print(  "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]);
   st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]);
@@ -819,41 +757,8 @@
   st->print(", EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDI]);
   st->cr();
   st->print(  "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EIP]);
+  st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
   st->print(", CR2=" INTPTR_FORMAT, uc->uc_mcontext.cr2);
-  st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
-
-  st->cr();
-  st->cr();
-
-  st->print_cr("Register to memory mapping:");
-  st->cr();
-
-  // this is only for the "general purpose" registers
-
-  st->print_cr("EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_EAX]);
-  st->cr();
-  st->print_cr("EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_EBX]);
-  st->cr();
-  st->print_cr("ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ECX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_ECX]);
-  st->cr();
-  st->print_cr("EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_EDX]);
-  st->cr();
-  st->print_cr("ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ESP]);
-  print_location(st, uc->uc_mcontext.gregs[REG_ESP]);
-  st->cr();
-  st->print_cr("EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBP]);
-  print_location(st, uc->uc_mcontext.gregs[REG_EBP]);
-  st->cr();
-  st->print_cr("ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ESI]);
-  print_location(st, uc->uc_mcontext.gregs[REG_ESI]);
-  st->cr();
-  st->print_cr("EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDI]);
-  print_location(st, uc->uc_mcontext.gregs[REG_EDI]);
-
 #endif // AMD64
   st->cr();
   st->cr();
@@ -868,7 +773,52 @@
   // this at the end, and hope for the best.
   address pc = os::Linux::ucontext_get_pc(uc);
   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
-  print_hex_dump(st, pc - 16, pc + 16, sizeof(char));
+  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+}
+
+void os::print_register_info(outputStream *st, void *context) {
+  if (context == NULL) return;
+
+  ucontext_t *uc = (ucontext_t*)context;
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is horrendously verbose but the layout of the registers in the
+  // context does not match how we defined our abstract Register set, so
+  // we can't just iterate through the gregs area
+
+  // this is only for the "general purpose" registers
+
+#ifdef AMD64
+  st->print("RAX="); print_location(st, uc->uc_mcontext.gregs[REG_RAX]);
+  st->print("RBX="); print_location(st, uc->uc_mcontext.gregs[REG_RBX]);
+  st->print("RCX="); print_location(st, uc->uc_mcontext.gregs[REG_RCX]);
+  st->print("RDX="); print_location(st, uc->uc_mcontext.gregs[REG_RDX]);
+  st->print("RSP="); print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
+  st->print("RBP="); print_location(st, uc->uc_mcontext.gregs[REG_RBP]);
+  st->print("RSI="); print_location(st, uc->uc_mcontext.gregs[REG_RSI]);
+  st->print("RDI="); print_location(st, uc->uc_mcontext.gregs[REG_RDI]);
+  st->print("R8 ="); print_location(st, uc->uc_mcontext.gregs[REG_R8]);
+  st->print("R9 ="); print_location(st, uc->uc_mcontext.gregs[REG_R9]);
+  st->print("R10="); print_location(st, uc->uc_mcontext.gregs[REG_R10]);
+  st->print("R11="); print_location(st, uc->uc_mcontext.gregs[REG_R11]);
+  st->print("R12="); print_location(st, uc->uc_mcontext.gregs[REG_R12]);
+  st->print("R13="); print_location(st, uc->uc_mcontext.gregs[REG_R13]);
+  st->print("R14="); print_location(st, uc->uc_mcontext.gregs[REG_R14]);
+  st->print("R15="); print_location(st, uc->uc_mcontext.gregs[REG_R15]);
+#else
+  st->print("EAX="); print_location(st, uc->uc_mcontext.gregs[REG_EAX]);
+  st->print("EBX="); print_location(st, uc->uc_mcontext.gregs[REG_EBX]);
+  st->print("ECX="); print_location(st, uc->uc_mcontext.gregs[REG_ECX]);
+  st->print("EDX="); print_location(st, uc->uc_mcontext.gregs[REG_EDX]);
+  st->print("ESP="); print_location(st, uc->uc_mcontext.gregs[REG_ESP]);
+  st->print("EBP="); print_location(st, uc->uc_mcontext.gregs[REG_EBP]);
+  st->print("ESI="); print_location(st, uc->uc_mcontext.gregs[REG_ESI]);
+  st->print("EDI="); print_location(st, uc->uc_mcontext.gregs[REG_EDI]);
+#endif // AMD64
+
+  st->cr();
 }
 
 void os::setup_fpu() {
--- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Oct 21 11:55:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -540,6 +540,11 @@
     pc = (address) uc->uc_mcontext.gregs[REG_PC];
   }
 
+  // Sometimes the register windows are not properly flushed.
+  if(uc->uc_mcontext.gwins != NULL) {
+    ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
+  }
+
   // unmask current signal
   sigset_t newset;
   sigemptyset(&newset);
@@ -558,6 +563,18 @@
   ucontext_t *uc = (ucontext_t*)context;
   st->print_cr("Registers:");
 
+  st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT
+               " G3=" INTPTR_FORMAT " G4=" INTPTR_FORMAT,
+            uc->uc_mcontext.gregs[REG_G1],
+            uc->uc_mcontext.gregs[REG_G2],
+            uc->uc_mcontext.gregs[REG_G3],
+            uc->uc_mcontext.gregs[REG_G4]);
+  st->print_cr(" G5=" INTPTR_FORMAT " G6=" INTPTR_FORMAT
+               " G7=" INTPTR_FORMAT " Y=" INTPTR_FORMAT,
+            uc->uc_mcontext.gregs[REG_G5],
+            uc->uc_mcontext.gregs[REG_G6],
+            uc->uc_mcontext.gregs[REG_G7],
+            uc->uc_mcontext.gregs[REG_Y]);
   st->print_cr(" O0=" INTPTR_FORMAT " O1=" INTPTR_FORMAT
                " O2=" INTPTR_FORMAT " O3=" INTPTR_FORMAT,
                  uc->uc_mcontext.gregs[REG_O0],
@@ -571,81 +588,39 @@
             uc->uc_mcontext.gregs[REG_O6],
             uc->uc_mcontext.gregs[REG_O7]);
 
-  st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT
-               " G3=" INTPTR_FORMAT " G4=" INTPTR_FORMAT,
-            uc->uc_mcontext.gregs[REG_G1],
-            uc->uc_mcontext.gregs[REG_G2],
-            uc->uc_mcontext.gregs[REG_G3],
-            uc->uc_mcontext.gregs[REG_G4]);
-  st->print_cr(" G5=" INTPTR_FORMAT " G6=" INTPTR_FORMAT
-               " G7=" INTPTR_FORMAT " Y=" INTPTR_FORMAT,
-            uc->uc_mcontext.gregs[REG_G5],
-            uc->uc_mcontext.gregs[REG_G6],
-            uc->uc_mcontext.gregs[REG_G7],
-            uc->uc_mcontext.gregs[REG_Y]);
+
+  intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc);
+  st->print_cr(" L0=" INTPTR_FORMAT " L1=" INTPTR_FORMAT
+               " L2=" INTPTR_FORMAT " L3=" INTPTR_FORMAT,
+               sp[L0->sp_offset_in_saved_window()],
+               sp[L1->sp_offset_in_saved_window()],
+               sp[L2->sp_offset_in_saved_window()],
+               sp[L3->sp_offset_in_saved_window()]);
+  st->print_cr(" L4=" INTPTR_FORMAT " L5=" INTPTR_FORMAT
+               " L6=" INTPTR_FORMAT " L7=" INTPTR_FORMAT,
+               sp[L4->sp_offset_in_saved_window()],
+               sp[L5->sp_offset_in_saved_window()],
+               sp[L6->sp_offset_in_saved_window()],
+               sp[L7->sp_offset_in_saved_window()]);
+  st->print_cr(" I0=" INTPTR_FORMAT " I1=" INTPTR_FORMAT
+               " I2=" INTPTR_FORMAT " I3=" INTPTR_FORMAT,
+               sp[I0->sp_offset_in_saved_window()],
+               sp[I1->sp_offset_in_saved_window()],
+               sp[I2->sp_offset_in_saved_window()],
+               sp[I3->sp_offset_in_saved_window()]);
+  st->print_cr(" I4=" INTPTR_FORMAT " I5=" INTPTR_FORMAT
+               " I6=" INTPTR_FORMAT " I7=" INTPTR_FORMAT,
+               sp[I4->sp_offset_in_saved_window()],
+               sp[I5->sp_offset_in_saved_window()],
+               sp[I6->sp_offset_in_saved_window()],
+               sp[I7->sp_offset_in_saved_window()]);
 
   st->print_cr(" PC=" INTPTR_FORMAT " nPC=" INTPTR_FORMAT,
             uc->uc_mcontext.gregs[REG_PC],
             uc->uc_mcontext.gregs[REG_nPC]);
-
   st->cr();
   st->cr();
 
-  st->print_cr("Register to memory mapping:");
-  st->cr();
-
-  // this is only for the "general purpose" registers
-
-  st->print_cr("O0=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O0]);
-  print_location(st, uc->uc_mcontext.gregs[REG_O0]);
-  st->cr();
-  st->print_cr("O1=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O1]);
-  print_location(st, uc->uc_mcontext.gregs[REG_O1]);
-  st->cr();
-  st->print_cr("O2=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O2]);
-  print_location(st, uc->uc_mcontext.gregs[REG_O2]);
-  st->cr();
-  st->print_cr("O3=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O3]);
-  print_location(st, uc->uc_mcontext.gregs[REG_O3]);
-  st->cr();
-  st->print_cr("O4=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O4]);
-  print_location(st, uc->uc_mcontext.gregs[REG_O4]);
-  st->cr();
-  st->print_cr("O5=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O5]);
-  print_location(st, uc->uc_mcontext.gregs[REG_O5]);
-  st->cr();
-  st->print_cr("O6=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O6]);
-  print_location(st, uc->uc_mcontext.gregs[REG_O6]);
-  st->cr();
-  st->print_cr("O7=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O7]);
-  print_location(st, uc->uc_mcontext.gregs[REG_O7]);
-  st->cr();
-
-  st->print_cr("G1=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G1]);
-  print_location(st, uc->uc_mcontext.gregs[REG_G1]);
-  st->cr();
-  st->print_cr("G2=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G2]);
-  print_location(st, uc->uc_mcontext.gregs[REG_G2]);
-  st->cr();
-  st->print_cr("G3=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G3]);
-  print_location(st, uc->uc_mcontext.gregs[REG_G3]);
-  st->cr();
-  st->print_cr("G4=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G4]);
-  print_location(st, uc->uc_mcontext.gregs[REG_G4]);
-  st->cr();
-  st->print_cr("G5=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G5]);
-  print_location(st, uc->uc_mcontext.gregs[REG_G5]);
-  st->cr();
-  st->print_cr("G6=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G6]);
-  print_location(st, uc->uc_mcontext.gregs[REG_G6]);
-  st->cr();
-  st->print_cr("G7=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G7]);
-  print_location(st, uc->uc_mcontext.gregs[REG_G7]);
-
-  st->cr();
-  st->cr();
-
-  intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc);
   st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
   print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t));
   st->cr();
@@ -656,7 +631,57 @@
   ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc);
   address pc = epc.pc();
   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
-  print_hex_dump(st, pc - 16, pc + 16, sizeof(char));
+  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+}
+
+void os::print_register_info(outputStream *st, void *context) {
+  if (context == NULL) return;
+
+  ucontext_t *uc = (ucontext_t*)context;
+  intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc);
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is only for the "general purpose" registers
+  st->print("G1="); print_location(st, uc->uc_mcontext.gregs[REG_G1]);
+  st->print("G2="); print_location(st, uc->uc_mcontext.gregs[REG_G2]);
+  st->print("G3="); print_location(st, uc->uc_mcontext.gregs[REG_G3]);
+  st->print("G4="); print_location(st, uc->uc_mcontext.gregs[REG_G4]);
+  st->print("G5="); print_location(st, uc->uc_mcontext.gregs[REG_G5]);
+  st->print("G6="); print_location(st, uc->uc_mcontext.gregs[REG_G6]);
+  st->print("G7="); print_location(st, uc->uc_mcontext.gregs[REG_G7]);
+  st->cr();
+
+  st->print("O0="); print_location(st, uc->uc_mcontext.gregs[REG_O0]);
+  st->print("O1="); print_location(st, uc->uc_mcontext.gregs[REG_O1]);
+  st->print("O2="); print_location(st, uc->uc_mcontext.gregs[REG_O2]);
+  st->print("O3="); print_location(st, uc->uc_mcontext.gregs[REG_O3]);
+  st->print("O4="); print_location(st, uc->uc_mcontext.gregs[REG_O4]);
+  st->print("O5="); print_location(st, uc->uc_mcontext.gregs[REG_O5]);
+  st->print("O6="); print_location(st, uc->uc_mcontext.gregs[REG_O6]);
+  st->print("O7="); print_location(st, uc->uc_mcontext.gregs[REG_O7]);
+  st->cr();
+
+  st->print("L0="); print_location(st, sp[L0->sp_offset_in_saved_window()]);
+  st->print("L1="); print_location(st, sp[L1->sp_offset_in_saved_window()]);
+  st->print("L2="); print_location(st, sp[L2->sp_offset_in_saved_window()]);
+  st->print("L3="); print_location(st, sp[L3->sp_offset_in_saved_window()]);
+  st->print("L4="); print_location(st, sp[L4->sp_offset_in_saved_window()]);
+  st->print("L5="); print_location(st, sp[L5->sp_offset_in_saved_window()]);
+  st->print("L6="); print_location(st, sp[L6->sp_offset_in_saved_window()]);
+  st->print("L7="); print_location(st, sp[L7->sp_offset_in_saved_window()]);
+  st->cr();
+
+  st->print("I0="); print_location(st, sp[I0->sp_offset_in_saved_window()]);
+  st->print("I1="); print_location(st, sp[I1->sp_offset_in_saved_window()]);
+  st->print("I2="); print_location(st, sp[I2->sp_offset_in_saved_window()]);
+  st->print("I3="); print_location(st, sp[I3->sp_offset_in_saved_window()]);
+  st->print("I4="); print_location(st, sp[I4->sp_offset_in_saved_window()]);
+  st->print("I5="); print_location(st, sp[I5->sp_offset_in_saved_window()]);
+  st->print("I6="); print_location(st, sp[I6->sp_offset_in_saved_window()]);
+  st->print("I7="); print_location(st, sp[I7->sp_offset_in_saved_window()]);
+  st->cr();
 }
 
 void os::Solaris::init_thread_fpu_state(void) {
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Oct 21 11:55:10 2010 -0700
@@ -719,11 +719,6 @@
 
   ucontext_t *uc = (ucontext_t*)context;
   st->print_cr("Registers:");
-
-  // this is horrendously verbose but the layout of the registers in the
-  // context does not match how we defined our abstract Register set, so
-  // we can't just iterate through the gregs area
-
 #ifdef AMD64
   st->print(  "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
   st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
@@ -735,8 +730,8 @@
   st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]);
   st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]);
   st->cr();
-  st->print(  "R8=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
-  st->print(", R9=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
+  st->print(  "R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
+  st->print(", R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
   st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]);
   st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]);
   st->cr();
@@ -747,63 +742,6 @@
   st->cr();
   st->print(  "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]);
   st->print(", RFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RFL]);
-
-  st->cr();
-  st->cr();
-
-  st->print_cr("Register to memory mapping:");
-  st->cr();
-
-  // this is only for the "general purpose" registers
-
-  st->print_cr("RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RAX]);
-  st->cr();
-  st->print_cr("RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RBX]);
-  st->cr();
-  st->print_cr("RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RCX]);
-  st->cr();
-  st->print_cr("RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RDX]);
-  st->cr();
-  st->print_cr("RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
-  st->cr();
-  st->print_cr("RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
-  st->cr();
-  st->print_cr("RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RSI]);
-  st->cr();
-  st->print_cr("RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]);
-  print_location(st, uc->uc_mcontext.gregs[REG_RDI]);
-  st->cr();
-  st->print_cr("R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R8]);
-  st->cr();
-  st->print_cr("R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R9]);
-  st->cr();
-  st->print_cr("R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R10]);
-  st->cr();
-  st->print_cr("R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R11]);
-  st->cr();
-  st->print_cr("R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R12]);
-  st->cr();
-  st->print_cr("R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R13]);
-  st->cr();
-  st->print_cr("R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R14]);
-  st->cr();
-  st->print_cr("R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]);
-  print_location(st, uc->uc_mcontext.gregs[REG_R15]);
-
 #else
   st->print(  "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EAX]);
   st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBX]);
@@ -817,39 +755,6 @@
   st->cr();
   st->print(  "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EIP]);
   st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EFL]);
-
-  st->cr();
-  st->cr();
-
-  st->print_cr("Register to memory mapping:");
-  st->cr();
-
-  // this is only for the "general purpose" registers
-
-  st->print_cr("EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EAX]);
-  print_location(st, uc->uc_mcontext.gregs[EAX]);
-  st->cr();
-  st->print_cr("EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBX]);
-  print_location(st, uc->uc_mcontext.gregs[EBX]);
-  st->cr();
-  st->print_cr("ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ECX]);
-  print_location(st, uc->uc_mcontext.gregs[ECX]);
-  st->cr();
-  st->print_cr("EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDX]);
-  print_location(st, uc->uc_mcontext.gregs[EDX]);
-  st->cr();
-  st->print_cr("ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[UESP]);
-  print_location(st, uc->uc_mcontext.gregs[UESP]);
-  st->cr();
-  st->print_cr("EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBP]);
-  print_location(st, uc->uc_mcontext.gregs[EBP]);
-  st->cr();
-  st->print_cr("ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ESI]);
-  print_location(st, uc->uc_mcontext.gregs[ESI]);
-  st->cr();
-  st->print_cr("EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDI]);
-  print_location(st, uc->uc_mcontext.gregs[EDI]);
-
 #endif // AMD64
   st->cr();
   st->cr();
@@ -865,7 +770,52 @@
   ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc);
   address pc = epc.pc();
   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
-  print_hex_dump(st, pc - 16, pc + 16, sizeof(char));
+  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+}
+
+void os::print_register_info(outputStream *st, void *context) {
+  if (context == NULL) return;
+
+  ucontext_t *uc = (ucontext_t*)context;
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is horrendously verbose but the layout of the registers in the
+  // context does not match how we defined our abstract Register set, so
+  // we can't just iterate through the gregs area
+
+  // this is only for the "general purpose" registers
+
+#ifdef AMD64
+  st->print("RAX="); print_location(st, uc->uc_mcontext.gregs[REG_RAX]);
+  st->print("RBX="); print_location(st, uc->uc_mcontext.gregs[REG_RBX]);
+  st->print("RCX="); print_location(st, uc->uc_mcontext.gregs[REG_RCX]);
+  st->print("RDX="); print_location(st, uc->uc_mcontext.gregs[REG_RDX]);
+  st->print("RSP="); print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
+  st->print("RBP="); print_location(st, uc->uc_mcontext.gregs[REG_RBP]);
+  st->print("RSI="); print_location(st, uc->uc_mcontext.gregs[REG_RSI]);
+  st->print("RDI="); print_location(st, uc->uc_mcontext.gregs[REG_RDI]);
+  st->print("R8 ="); print_location(st, uc->uc_mcontext.gregs[REG_R8]);
+  st->print("R9 ="); print_location(st, uc->uc_mcontext.gregs[REG_R9]);
+  st->print("R10="); print_location(st, uc->uc_mcontext.gregs[REG_R10]);
+  st->print("R11="); print_location(st, uc->uc_mcontext.gregs[REG_R11]);
+  st->print("R12="); print_location(st, uc->uc_mcontext.gregs[REG_R12]);
+  st->print("R13="); print_location(st, uc->uc_mcontext.gregs[REG_R13]);
+  st->print("R14="); print_location(st, uc->uc_mcontext.gregs[REG_R14]);
+  st->print("R15="); print_location(st, uc->uc_mcontext.gregs[REG_R15]);
+#else
+  st->print("EAX="); print_location(st, uc->uc_mcontext.gregs[EAX]);
+  st->print("EBX="); print_location(st, uc->uc_mcontext.gregs[EBX]);
+  st->print("ECX="); print_location(st, uc->uc_mcontext.gregs[ECX]);
+  st->print("EDX="); print_location(st, uc->uc_mcontext.gregs[EDX]);
+  st->print("ESP="); print_location(st, uc->uc_mcontext.gregs[UESP]);
+  st->print("EBP="); print_location(st, uc->uc_mcontext.gregs[EBP]);
+  st->print("ESI="); print_location(st, uc->uc_mcontext.gregs[ESI]);
+  st->print("EDI="); print_location(st, uc->uc_mcontext.gregs[EDI]);
+#endif
+
+  st->cr();
 }
 
 
--- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Thu Oct 21 11:55:10 2010 -0700
@@ -387,8 +387,8 @@
   st->print(", RSI=" INTPTR_FORMAT, uc->Rsi);
   st->print(", RDI=" INTPTR_FORMAT, uc->Rdi);
   st->cr();
-  st->print(  "R8=" INTPTR_FORMAT,  uc->R8);
-  st->print(", R9=" INTPTR_FORMAT,  uc->R9);
+  st->print(  "R8 =" INTPTR_FORMAT, uc->R8);
+  st->print(", R9 =" INTPTR_FORMAT, uc->R9);
   st->print(", R10=" INTPTR_FORMAT, uc->R10);
   st->print(", R11=" INTPTR_FORMAT, uc->R11);
   st->cr();
@@ -399,62 +399,6 @@
   st->cr();
   st->print(  "RIP=" INTPTR_FORMAT, uc->Rip);
   st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags);
-
-  st->cr();
-  st->cr();
-
-  st->print_cr("Register to memory mapping:");
-  st->cr();
-
-  // this is only for the "general purpose" registers
-
-  st->print_cr("RAX=" INTPTR_FORMAT, uc->Rax);
-  print_location(st, uc->Rax);
-  st->cr();
-  st->print_cr("RBX=" INTPTR_FORMAT, uc->Rbx);
-  print_location(st, uc->Rbx);
-  st->cr();
-  st->print_cr("RCX=" INTPTR_FORMAT, uc->Rcx);
-  print_location(st, uc->Rcx);
-  st->cr();
-  st->print_cr("RDX=" INTPTR_FORMAT, uc->Rdx);
-  print_location(st, uc->Rdx);
-  st->cr();
-  st->print_cr("RSP=" INTPTR_FORMAT, uc->Rsp);
-  print_location(st, uc->Rsp);
-  st->cr();
-  st->print_cr("RBP=" INTPTR_FORMAT, uc->Rbp);
-  print_location(st, uc->Rbp);
-  st->cr();
-  st->print_cr("RSI=" INTPTR_FORMAT, uc->Rsi);
-  print_location(st, uc->Rsi);
-  st->cr();
-  st->print_cr("RDI=" INTPTR_FORMAT, uc->Rdi);
-  print_location(st, uc->Rdi);
-  st->cr();
-  st->print_cr("R8 =" INTPTR_FORMAT, uc->R8);
-  print_location(st, uc->R8);
-  st->cr();
-  st->print_cr("R9 =" INTPTR_FORMAT, uc->R9);
-  print_location(st, uc->R9);
-  st->cr();
-  st->print_cr("R10=" INTPTR_FORMAT, uc->R10);
-  print_location(st, uc->R10);
-  st->cr();
-  st->print_cr("R11=" INTPTR_FORMAT, uc->R11);
-  print_location(st, uc->R11);
-  st->cr();
-  st->print_cr("R12=" INTPTR_FORMAT, uc->R12);
-  print_location(st, uc->R12);
-  st->cr();
-  st->print_cr("R13=" INTPTR_FORMAT, uc->R13);
-  print_location(st, uc->R13);
-  st->cr();
-  st->print_cr("R14=" INTPTR_FORMAT, uc->R14);
-  print_location(st, uc->R14);
-  st->cr();
-  st->print_cr("R15=" INTPTR_FORMAT, uc->R15);
-  print_location(st, uc->R15);
 #else
   st->print(  "EAX=" INTPTR_FORMAT, uc->Eax);
   st->print(", EBX=" INTPTR_FORMAT, uc->Ebx);
@@ -468,38 +412,6 @@
   st->cr();
   st->print(  "EIP=" INTPTR_FORMAT, uc->Eip);
   st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags);
-
-  st->cr();
-  st->cr();
-
-  st->print_cr("Register to memory mapping:");
-  st->cr();
-
-  // this is only for the "general purpose" registers
-
-  st->print_cr("EAX=" INTPTR_FORMAT, uc->Eax);
-  print_location(st, uc->Eax);
-  st->cr();
-  st->print_cr("EBX=" INTPTR_FORMAT, uc->Ebx);
-  print_location(st, uc->Ebx);
-  st->cr();
-  st->print_cr("ECX=" INTPTR_FORMAT, uc->Ecx);
-  print_location(st, uc->Ecx);
-  st->cr();
-  st->print_cr("EDX=" INTPTR_FORMAT, uc->Edx);
-  print_location(st, uc->Edx);
-  st->cr();
-  st->print_cr("ESP=" INTPTR_FORMAT, uc->Esp);
-  print_location(st, uc->Esp);
-  st->cr();
-  st->print_cr("EBP=" INTPTR_FORMAT, uc->Ebp);
-  print_location(st, uc->Ebp);
-  st->cr();
-  st->print_cr("ESI=" INTPTR_FORMAT, uc->Esi);
-  print_location(st, uc->Esi);
-  st->cr();
-  st->print_cr("EDI=" INTPTR_FORMAT, uc->Edi);
-  print_location(st, uc->Edi);
 #endif // AMD64
   st->cr();
   st->cr();
@@ -514,7 +426,49 @@
   // this at the end, and hope for the best.
   address pc = (address)uc->REG_PC;
   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
-  print_hex_dump(st, pc - 16, pc + 16, sizeof(char));
+  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+  st->cr();
+}
+
+
+void os::print_register_info(outputStream *st, void *context) {
+  if (context == NULL) return;
+
+  CONTEXT* uc = (CONTEXT*)context;
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  // this is only for the "general purpose" registers
+
+#ifdef AMD64
+  st->print("RAX="); print_location(st, uc->Rax);
+  st->print("RBX="); print_location(st, uc->Rbx);
+  st->print("RCX="); print_location(st, uc->Rcx);
+  st->print("RDX="); print_location(st, uc->Rdx);
+  st->print("RSP="); print_location(st, uc->Rsp);
+  st->print("RBP="); print_location(st, uc->Rbp);
+  st->print("RSI="); print_location(st, uc->Rsi);
+  st->print("RDI="); print_location(st, uc->Rdi);
+  st->print("R8 ="); print_location(st, uc->R8);
+  st->print("R9 ="); print_location(st, uc->R9);
+  st->print("R10="); print_location(st, uc->R10);
+  st->print("R11="); print_location(st, uc->R11);
+  st->print("R12="); print_location(st, uc->R12);
+  st->print("R13="); print_location(st, uc->R13);
+  st->print("R14="); print_location(st, uc->R14);
+  st->print("R15="); print_location(st, uc->R15);
+#else
+  st->print("EAX="); print_location(st, uc->Eax);
+  st->print("EBX="); print_location(st, uc->Ebx);
+  st->print("ECX="); print_location(st, uc->Ecx);
+  st->print("EDX="); print_location(st, uc->Edx);
+  st->print("ESP="); print_location(st, uc->Esp);
+  st->print("EBP="); print_location(st, uc->Ebp);
+  st->print("ESI="); print_location(st, uc->Esi);
+  st->print("EDI="); print_location(st, uc->Edi);
+#endif
+
   st->cr();
 }
 
--- a/src/share/vm/code/codeCache.cpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/share/vm/code/codeCache.cpp	Thu Oct 21 11:55:10 2010 -0700
@@ -914,3 +914,14 @@
 }
 
 #endif // PRODUCT
+
+void CodeCache::print_bounds(outputStream* st) {
+  st->print_cr("Code Cache  [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
+               _heap->low_boundary(),
+               _heap->high(),
+               _heap->high_boundary());
+  st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
+               " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT,
+               CodeCache::nof_blobs(), CodeCache::nof_nmethods(),
+               CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
+}
--- a/src/share/vm/code/codeCache.hpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/share/vm/code/codeCache.hpp	Thu Oct 21 11:55:10 2010 -0700
@@ -137,6 +137,7 @@
   static void print_internals();
   static void verify();                          // verifies the code cache
   static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
+  static void print_bounds(outputStream* st);    // Prints a summary of the bounds of the code cache
 
   // The full limits of the codeCache
   static address  low_bound()                    { return (address) _heap->low_boundary(); }
--- a/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge	Thu Oct 21 11:55:10 2010 -0700
@@ -133,6 +133,7 @@
 parallelScavengeHeap.cpp                psParallelCompact.hpp
 parallelScavengeHeap.cpp                psPromotionManager.hpp
 parallelScavengeHeap.cpp                psScavenge.hpp
+parallelScavengeHeap.cpp                vmError.hpp
 parallelScavengeHeap.cpp                vmThread.hpp
 parallelScavengeHeap.cpp                vmPSOperations.hpp
 
--- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Thu Oct 21 11:55:10 2010 -0700
@@ -805,7 +805,8 @@
   if (young_gen()->is_in_reserved(addr)) {
     assert(young_gen()->is_in(addr),
            "addr should be in allocated part of young gen");
-    if (Debugging)  return NULL;  // called from find() in debug.cpp
+    // called from os::print_location by find or VMError
+    if (Debugging || VMError::fatal_error_in_progress())  return NULL;
     Unimplemented();
   } else if (old_gen()->is_in_reserved(addr)) {
     assert(old_gen()->is_in(addr),
--- a/src/share/vm/memory/heap.hpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/share/vm/memory/heap.hpp	Thu Oct 21 11:55:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -140,6 +140,7 @@
 
   // Returns reserved area high and low addresses
   char *low_boundary() const                     { return _memory.low_boundary (); }
+  char *high() const                             { return _memory.high(); }
   char *high_boundary() const                    { return _memory.high_boundary(); }
 
   // Iteration
--- a/src/share/vm/runtime/os.cpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/share/vm/runtime/os.cpp	Thu Oct 21 11:55:10 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -736,8 +736,8 @@
 }
 
 // moved from debug.cpp (used to be find()) but still called from there
-// The print_pc parameter is only set by the debug code in one case
-void os::print_location(outputStream* st, intptr_t x, bool print_pc) {
+// The verbose parameter is only set by the debug code in one case
+void os::print_location(outputStream* st, intptr_t x, bool verbose) {
   address addr = (address)x;
   CodeBlob* b = CodeCache::find_blob_unsafe(addr);
   if (b != NULL) {
@@ -745,6 +745,7 @@
       // the interpreter is generated into a buffer blob
       InterpreterCodelet* i = Interpreter::codelet_containing(addr);
       if (i != NULL) {
+        st->print_cr(INTPTR_FORMAT " is an Interpreter codelet", addr);
         i->print_on(st);
         return;
       }
@@ -755,14 +756,14 @@
       }
       //
       if (AdapterHandlerLibrary::contains(b)) {
-        st->print_cr("Printing AdapterHandler");
+        st->print_cr(INTPTR_FORMAT " is an AdapterHandler", addr);
         AdapterHandlerLibrary::print_handler_on(st, b);
       }
       // the stubroutines are generated into a buffer blob
       StubCodeDesc* d = StubCodeDesc::desc_for(addr);
       if (d != NULL) {
         d->print_on(st);
-        if (print_pc) st->cr();
+        if (verbose) st->cr();
         return;
       }
       if (StubRoutines::contains(addr)) {
@@ -781,7 +782,7 @@
         return;
       }
     }
-    if (print_pc && b->is_nmethod()) {
+    if (verbose && b->is_nmethod()) {
       ResourceMark rm;
       st->print("%#p: Compiled ", addr);
       ((nmethod*)b)->method()->print_value_on(st);
@@ -789,11 +790,12 @@
       st->cr();
       return;
     }
+    st->print(INTPTR_FORMAT " ", b);
     if ( b->is_nmethod()) {
       if (b->is_zombie()) {
-        st->print_cr(INTPTR_FORMAT " is zombie nmethod", b);
+        st->print_cr("is zombie nmethod");
       } else if (b->is_not_entrant()) {
-        st->print_cr(INTPTR_FORMAT " is non-entrant nmethod", b);
+        st->print_cr("is non-entrant nmethod");
       }
     }
     b->print_on(st);
@@ -812,6 +814,7 @@
       print = true;
     }
     if (print) {
+      st->print_cr(INTPTR_FORMAT " is an oop", addr);
       oop(p)->print_on(st);
       if (p != (HeapWord*)x && oop(p)->is_constMethod() &&
           constMethodOop(p)->contains(addr)) {
@@ -855,12 +858,16 @@
         thread->privileged_stack_top()->contains(addr)) {
       st->print_cr(INTPTR_FORMAT " is pointing into the privilege stack "
                    "for thread: " INTPTR_FORMAT, addr, thread);
-      thread->print_on(st);
+      if (verbose) thread->print_on(st);
       return;
     }
     // If the addr is a java thread print information about that.
     if (addr == (address)thread) {
-      thread->print_on(st);
+      if (verbose) {
+        thread->print_on(st);
+      } else {
+        st->print_cr(INTPTR_FORMAT " is a thread", addr);
+      }
       return;
     }
     // If the addr is in the stack region for this thread then report that
@@ -869,7 +876,7 @@
         addr > (thread->stack_base() - thread->stack_size())) {
       st->print_cr(INTPTR_FORMAT " is pointing into the stack for thread: "
                    INTPTR_FORMAT, addr, thread);
-      thread->print_on(st);
+      if (verbose) thread->print_on(st);
       return;
     }
 
@@ -879,7 +886,7 @@
     return;
   }
 
-  st->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr);
+  st->print_cr(INTPTR_FORMAT " is an unknown value", addr);
 }
 
 // Looks like all platforms except IA64 can use the same function to check
--- a/src/share/vm/runtime/os.hpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/share/vm/runtime/os.hpp	Thu Oct 21 11:55:10 2010 -0700
@@ -450,11 +450,12 @@
   static void print_dll_info(outputStream* st);
   static void print_environment_variables(outputStream* st, const char** env_list, char* buffer, int len);
   static void print_context(outputStream* st, void* context);
+  static void print_register_info(outputStream* st, void* context);
   static void print_siginfo(outputStream* st, void* siginfo);
   static void print_signal_handlers(outputStream* st, char* buf, size_t buflen);
   static void print_date_and_time(outputStream* st);
 
-  static void print_location(outputStream* st, intptr_t x, bool print_pc = false);
+  static void print_location(outputStream* st, intptr_t x, bool verbose = false);
 
   // The following two functions are used by fatal error handler to trace
   // native (C) frames. They are not part of frame.hpp/frame.cpp because
--- a/src/share/vm/utilities/vmError.cpp	Wed Oct 20 13:18:17 2010 -0700
+++ b/src/share/vm/utilities/vmError.cpp	Thu Oct 21 11:55:10 2010 -0700
@@ -455,6 +455,14 @@
        st->cr();
      }
 
+  STEP(105, "(printing register info)")
+
+     // decode register contents if possible
+     if (_verbose && _context && Universe::is_fully_initialized()) {
+       os::print_register_info(st, _context);
+       st->cr();
+     }
+
   STEP(110, "(printing stack bounds)" )
 
      if (_verbose) {
@@ -522,7 +530,7 @@
   STEP(135, "(printing target Java thread stack)" )
 
      // printing Java thread stack trace if it is involved in GC crash
-     if (_verbose && (_thread->is_Named_thread())) {
+     if (_verbose && _thread && (_thread->is_Named_thread())) {
        JavaThread*  jt = ((NamedThread *)_thread)->processed_thread();
        if (jt != NULL) {
          st->print_cr("JavaThread " PTR_FORMAT " (nid = " UINTX_FORMAT ") was being processed", jt, jt->osthread()->thread_id());
@@ -608,6 +616,14 @@
        st->cr();
      }
 
+  STEP(195, "(printing code cache information)" )
+
+     if (_verbose && Universe::is_fully_initialized()) {
+       // print code cache information before vm abort
+       CodeCache::print_bounds(st);
+       st->cr();
+     }
+
   STEP(200, "(printing dynamic libraries)" )
 
      if (_verbose) {