changeset 476:7b75310e57e2

Merge
author kvn
date Thu, 11 Dec 2008 17:20:10 -0800
parents 3ad2b8576c4a (diff) 284d0af00d53 (current diff)
children 06d2c3204df4 dd70dd4c91de
files src/share/vm/runtime/globals.hpp
diffstat 20 files changed, 173 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Dec 09 12:41:26 2008 -0800
+++ b/.hgtags	Thu Dec 11 17:20:10 2008 -0800
@@ -15,3 +15,4 @@
 d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
 49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
 81a0cbe3b28460ce836109934ece03db7afaf9cc jdk7-b40
+f9d938ede1960d18cb7cf23c645b026519c1a678 jdk7-b41
--- a/make/hotspot_version	Tue Dec 09 12:41:26 2008 -0800
+++ b/make/hotspot_version	Thu Dec 11 17:20:10 2008 -0800
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=14
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=08
+HS_BUILD_NUMBER=09
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/src/os/linux/vm/os_linux.cpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/os/linux/vm/os_linux.cpp	Thu Dec 11 17:20:10 2008 -0800
@@ -2272,7 +2272,9 @@
   uncommit_memory(addr, bytes);
 }
 
-void os::numa_make_global(char *addr, size_t bytes)    { }
+void os::numa_make_global(char *addr, size_t bytes) {
+  Linux::numa_interleave_memory(addr, bytes);
+}
 
 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
   Linux::numa_tonode_memory(addr, bytes, lgrp_hint);
@@ -2314,7 +2316,7 @@
 extern "C" void numa_warn(int number, char *where, ...) { }
 extern "C" void numa_error(char *where) { }
 
-void os::Linux::libnuma_init() {
+bool os::Linux::libnuma_init() {
   // sched_getcpu() should be in libc.
   set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
                                   dlsym(RTLD_DEFAULT, "sched_getcpu")));
@@ -2330,31 +2332,51 @@
                                         dlsym(handle, "numa_available")));
       set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t,
                                             dlsym(handle, "numa_tonode_memory")));
+      set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t,
+                                            dlsym(handle, "numa_interleave_memory")));
+
+
       if (numa_available() != -1) {
+        set_numa_all_nodes((unsigned long*)dlsym(handle, "numa_all_nodes"));
         // Create a cpu -> node mapping
         _cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true);
         rebuild_cpu_to_node_map();
+        return true;
       }
     }
   }
+  return false;
 }
 
 // rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id.
 // The table is later used in get_node_by_cpu().
 void os::Linux::rebuild_cpu_to_node_map() {
-  int cpu_num = os::active_processor_count();
+  const size_t NCPUS = 32768; // Since the buffer size computation is very obscure
+                              // in libnuma (possible values are starting from 16,
+                              // and continuing up with every other power of 2, but less
+                              // than the maximum number of CPUs supported by kernel), and
+                              // is a subject to change (in libnuma version 2 the requirements
+                              // are more reasonable) we'll just hardcode the number they use
+                              // in the library.
+  const size_t BitsPerCLong = sizeof(long) * CHAR_BIT;
+
+  size_t cpu_num = os::active_processor_count();
+  size_t cpu_map_size = NCPUS / BitsPerCLong;
+  size_t cpu_map_valid_size =
+    MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size);
+
   cpu_to_node()->clear();
   cpu_to_node()->at_grow(cpu_num - 1);
-  int node_num = numa_get_groups_num();
-  int cpu_map_size = (cpu_num + BitsPerLong - 1) / BitsPerLong;
+  size_t node_num = numa_get_groups_num();
+
   unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size);
-  for (int i = 0; i < node_num; i++) {
+  for (size_t i = 0; i < node_num; i++) {
     if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) {
-      for (int j = 0; j < cpu_map_size; j++) {
+      for (size_t j = 0; j < cpu_map_valid_size; j++) {
         if (cpu_map[j] != 0) {
-          for (int k = 0; k < BitsPerLong; k++) {
+          for (size_t k = 0; k < BitsPerCLong; k++) {
             if (cpu_map[j] & (1UL << k)) {
-              cpu_to_node()->at_put(j * BitsPerLong + k, i);
+              cpu_to_node()->at_put(j * BitsPerCLong + k, i);
             }
           }
         }
@@ -2377,7 +2399,8 @@
 os::Linux::numa_max_node_func_t os::Linux::_numa_max_node;
 os::Linux::numa_available_func_t os::Linux::_numa_available;
 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory;
-
+os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory;
+unsigned long* os::Linux::_numa_all_nodes;
 
 bool os::uncommit_memory(char* addr, size_t size) {
   return ::mmap(addr, size,
@@ -3695,7 +3718,17 @@
   }
 
   if (UseNUMA) {
-    Linux::libnuma_init();
+    if (!Linux::libnuma_init()) {
+      UseNUMA = false;
+    } else {
+      if ((Linux::numa_max_node() < 1)) {
+        // There's only one node(they start from 0), disable NUMA.
+        UseNUMA = false;
+      }
+    }
+    if (!UseNUMA && ForceNUMA) {
+      UseNUMA = true;
+    }
   }
 
   if (MaxFDLimit) {
--- a/src/os/linux/vm/os_linux.hpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/os/linux/vm/os_linux.hpp	Thu Dec 11 17:20:10 2008 -0800
@@ -146,7 +146,7 @@
   static bool is_floating_stack()             { return _is_floating_stack; }
 
   static void libpthread_init();
-  static void libnuma_init();
+  static bool libnuma_init();
 
   // Minimum stack size a thread can be created with (allowing
   // the VM to completely create the thread and enter user code)
@@ -240,20 +240,23 @@
   typedef int (*numa_max_node_func_t)(void);
   typedef int (*numa_available_func_t)(void);
   typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node);
-
+  typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask);
 
   static sched_getcpu_func_t _sched_getcpu;
   static numa_node_to_cpus_func_t _numa_node_to_cpus;
   static numa_max_node_func_t _numa_max_node;
   static numa_available_func_t _numa_available;
   static numa_tonode_memory_func_t _numa_tonode_memory;
+  static numa_interleave_memory_func_t _numa_interleave_memory;
+  static unsigned long* _numa_all_nodes;
 
   static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; }
   static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; }
   static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; }
   static void set_numa_available(numa_available_func_t func) { _numa_available = func; }
   static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; }
-
+  static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; }
+  static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; }
 public:
   static int sched_getcpu()  { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
   static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {
@@ -264,6 +267,11 @@
   static int numa_tonode_memory(void *start, size_t size, int node) {
     return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1;
   }
+  static void numa_interleave_memory(void *start, size_t size) {
+    if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) {
+      _numa_interleave_memory(start, size, _numa_all_nodes);
+    }
+  }
   static int get_node_by_cpu(int cpu_id);
 };
 
--- a/src/os/solaris/vm/os_solaris.cpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/os/solaris/vm/os_solaris.cpp	Thu Dec 11 17:20:10 2008 -0800
@@ -4638,7 +4638,7 @@
   }
 }
 
-void os::Solaris::liblgrp_init() {
+bool os::Solaris::liblgrp_init() {
   void *handle = dlopen("liblgrp.so.1", RTLD_LAZY);
   if (handle != NULL) {
     os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home")));
@@ -4653,9 +4653,9 @@
 
     lgrp_cookie_t c = lgrp_init(LGRP_VIEW_CALLER);
     set_lgrp_cookie(c);
-  } else {
-    warning("your OS does not support NUMA");
-  }
+    return true;
+  }
+  return false;
 }
 
 void os::Solaris::misc_sym_init() {
@@ -4824,9 +4824,25 @@
         vm_page_size()));
 
   Solaris::libthread_init();
+
   if (UseNUMA) {
-    Solaris::liblgrp_init();
-  }
+    if (!Solaris::liblgrp_init()) {
+      UseNUMA = false;
+    } else {
+      size_t lgrp_limit = os::numa_get_groups_num();
+      int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit);
+      size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit);
+      FREE_C_HEAP_ARRAY(int, lgrp_ids);
+      if (lgrp_num < 2) {
+        // There's only one locality group, disable NUMA.
+        UseNUMA = false;
+      }
+    }
+    if (!UseNUMA && ForceNUMA) {
+      UseNUMA = true;
+    }
+  }
+
   Solaris::misc_sym_init();
   Solaris::signal_sets_init();
   Solaris::init_signal_mem();
--- a/src/os/solaris/vm/os_solaris.hpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/os/solaris/vm/os_solaris.hpp	Thu Dec 11 17:20:10 2008 -0800
@@ -176,7 +176,7 @@
  public:
   static void libthread_init();
   static void synchronization_init();
-  static void liblgrp_init();
+  static bool liblgrp_init();
   // Load miscellaneous symbols.
   static void misc_sym_init();
   // This boolean allows users to forward their own non-matching signals
--- a/src/os/windows/vm/os_windows.cpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/os/windows/vm/os_windows.cpp	Thu Dec 11 17:20:10 2008 -0800
@@ -2217,15 +2217,10 @@
                 // We only expect null pointers in the stubs (vtable)
                 // the rest are checked explicitly now.
                 //
-                CodeBlob* cb = CodeCache::find_blob(pc);
-                if (cb != NULL) {
-                  if (VtableStubs::stub_containing(pc) != NULL) {
-                    if (((uintptr_t)addr) < os::vm_page_size() ) {
-                      // an access to the first page of VM--assume it is a null pointer
-                      return Handle_Exception(exceptionInfo,
-                        SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL));
-                    }
-                  }
+                if (((uintptr_t)addr) < os::vm_page_size() ) {
+                  // an access to the first page of VM--assume it is a null pointer
+                  address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
+                  if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
                 }
               }
             } // in_java
@@ -2241,9 +2236,8 @@
             // Windows 98 reports faulting addresses incorrectly
             if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
                 !os::win32::is_nt()) {
-
-              return Handle_Exception(exceptionInfo,
-                  SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL));
+              address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
+              if (stub != NULL) return Handle_Exception(exceptionInfo, stub);
             }
             report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
                          exceptionInfo->ContextRecord);
@@ -3353,6 +3347,10 @@
   // initialize thread priority policy
   prio_init();
 
+  if (UseNUMA && !ForceNUMA) {
+    UseNUMA = false; // Currently unsupported.
+  }
+
   return JNI_OK;
 }
 
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Dec 11 17:20:10 2008 -0800
@@ -203,10 +203,10 @@
   return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
 }
 
-extern "C" intptr_t *_get_previous_fp();  // in .il file.
+extern "C" intptr_t *_get_current_fp();  // in .il file
 
 frame os::current_frame() {
-  intptr_t* fp = _get_previous_fp();
+  intptr_t* fp = _get_current_fp();  // it's inlined so want current fp
   frame myframe((intptr_t*)os::current_stack_pointer(),
                 (intptr_t*)fp,
                 CAST_FROM_FN_PTR(address, os::current_frame));
--- a/src/os_cpu/solaris_x86/vm/solaris_x86_32.il	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/os_cpu/solaris_x86/vm/solaris_x86_32.il	Thu Dec 11 17:20:10 2008 -0800
@@ -37,10 +37,10 @@
       movl     %gs:0, %eax 
       .end
 
-  // Get callers fp
-      .inline _get_previous_fp,0
+  // Get current fp
+      .inline _get_current_fp,0
+      .volatile
       movl     %ebp, %eax 
-      movl     %eax, %eax
       .end
 
   // Support for jint Atomic::add(jint inc, volatile jint* dest)
--- a/src/os_cpu/solaris_x86/vm/solaris_x86_64.il	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/os_cpu/solaris_x86/vm/solaris_x86_64.il	Thu Dec 11 17:20:10 2008 -0800
@@ -30,10 +30,10 @@
       movq     %fs:0, %rax 
       .end
 
-  // Get the frame pointer from previous frame.
-      .inline _get_previous_fp,0
+  // Get the frame pointer from current frame.
+      .inline _get_current_fp,0
+      .volatile
       movq     %rbp, %rax 
-      movq     %rax, %rax 
       .end
 
   // Support for jint Atomic::add(jint add_value, volatile jint* dest)
--- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Thu Dec 11 17:20:10 2008 -0800
@@ -414,9 +414,20 @@
   if (limit > 0) {
     limit = round_down(limit, page_size());
     if (chunk_size > current_chunk_size(i)) {
-      chunk_size = MIN2((off_t)chunk_size, (off_t)current_chunk_size(i) + (off_t)limit);
+      size_t upper_bound = pages_available * page_size();
+      if (upper_bound > limit &&
+          current_chunk_size(i) < upper_bound - limit) {
+        // The resulting upper bound should not exceed the available
+        // amount of memory (pages_available * page_size()).
+        upper_bound = current_chunk_size(i) + limit;
+      }
+      chunk_size = MIN2(chunk_size, upper_bound);
     } else {
-      chunk_size = MAX2((off_t)chunk_size, (off_t)current_chunk_size(i) - (off_t)limit);
+      size_t lower_bound = page_size();
+      if (current_chunk_size(i) > limit) { // lower_bound shouldn't underflow.
+        lower_bound = current_chunk_size(i) - limit;
+      }
+      chunk_size = MAX2(chunk_size, lower_bound);
     }
   }
   assert(chunk_size <= pages_available * page_size(), "Chunk size out of range");
--- a/src/share/vm/includeDB_core	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/share/vm/includeDB_core	Thu Dec 11 17:20:10 2008 -0800
@@ -2303,6 +2303,7 @@
 javaCalls.cpp                           interfaceSupport.hpp
 javaCalls.cpp                           interpreter.hpp
 javaCalls.cpp                           javaCalls.hpp
+javaCalls.cpp                           jniCheck.hpp
 javaCalls.cpp                           linkResolver.hpp
 javaCalls.cpp                           mutexLocker.hpp
 javaCalls.cpp                           nmethod.hpp
--- a/src/share/vm/includeDB_features	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/share/vm/includeDB_features	Thu Dec 11 17:20:10 2008 -0800
@@ -115,6 +115,8 @@
 heapInspection.cpp                      os.hpp
 heapInspection.cpp                      resourceArea.hpp
 
+javaCalls.cpp                           jniCheck.hpp
+
 jniCheck.cpp                            fieldDescriptor.hpp
 jniCheck.cpp                            handles.hpp
 jniCheck.cpp                            instanceKlass.hpp
--- a/src/share/vm/prims/jniCheck.cpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/share/vm/prims/jniCheck.cpp	Thu Dec 11 17:20:10 2008 -0800
@@ -112,18 +112,6 @@
 static const char * fatal_non_string = "JNI string operation received a non-string";
 
 
-
-// Report a JNI failure caught by -Xcheck:jni.  Perform a core dump.
-// Note: two variations -- one to be called when in VM state (e.g. when
-// within IN_VM macro), one to be called when in NATIVE state.
-
-// When in VM state:
-static void ReportJNIFatalError(JavaThread* thr, const char *msg) {
-  tty->print_cr("FATAL ERROR in native method: %s", msg);
-  thr->print_stack();
-  os::abort(true);
-}
-
 // When in VM state:
 static void ReportJNIWarning(JavaThread* thr, const char *msg) {
   tty->print_cr("WARNING in native method: %s", msg);
--- a/src/share/vm/prims/jniCheck.hpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/share/vm/prims/jniCheck.hpp	Thu Dec 11 17:20:10 2008 -0800
@@ -22,6 +22,19 @@
  *
  */
 
+extern "C" {
+  // Report a JNI failure caught by -Xcheck:jni.  Perform a core dump.
+  // Note: two variations -- one to be called when in VM state (e.g. when
+  // within IN_VM macro), one to be called when in NATIVE state.
+
+  // When in VM state:
+  static void ReportJNIFatalError(JavaThread* thr, const char *msg) {
+    tty->print_cr("FATAL ERROR in native method: %s", msg);
+    thr->print_stack();
+    os::abort(true);
+  }
+}
+
 //
 // Checked JNI routines that are useful for outside of checked JNI
 //
--- a/src/share/vm/runtime/globals.hpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/share/vm/runtime/globals.hpp	Thu Dec 11 17:20:10 2008 -0800
@@ -342,6 +342,9 @@
   product(bool, UseNUMA, false,                                             \
           "Use NUMA if available")                                          \
                                                                             \
+  product(bool, ForceNUMA, false,                                           \
+          "Force NUMA optimizations on single-node/UMA systems")            \
+                                                                            \
   product(intx, NUMAChunkResizeWeight, 20,                                  \
           "Percentage (0-100) used to weight the current sample when "      \
           "computing exponentially decaying average for "                   \
--- a/src/share/vm/runtime/javaCalls.cpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/share/vm/runtime/javaCalls.cpp	Thu Dec 11 17:20:10 2008 -0800
@@ -309,8 +309,12 @@
 
   CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 
-  // Make sure that the arguments have the right type
-  debug_only(args->verify(method, result->get_type(), thread));
+  // Verify the arguments
+
+  if (CheckJNICalls)  {
+    args->verify(method, result->get_type(), thread);
+  }
+  else debug_only(args->verify(method, result->get_type(), thread));
 
   // Ignore call if method is empty
   if (method->is_empty_method()) {
@@ -431,24 +435,26 @@
   return TaggedStackInterpreter ? _parameters : _value;
 }
 
-//--------------------------------------------------------------------------------------
-// Non-Product code
-#ifndef PRODUCT
 
 class SignatureChekker : public SignatureIterator {
  private:
    bool *_is_oop;
    int   _pos;
    BasicType _return_type;
+   intptr_t*   _value;
+   Thread* _thread;
 
  public:
   bool _is_return;
 
-  SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop) : SignatureIterator(signature) {
+  SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) {
     _is_oop = is_oop;
     _is_return = false;
     _return_type = return_type;
     _pos = 0;
+    _value = value;
+    _thread = thread;
+
     if (!is_static) {
       check_value(true); // Receiver must be an oop
     }
@@ -489,6 +495,24 @@
       check_return_type(t);
       return;
     }
+
+    // verify handle and the oop pointed to by handle
+    int p = _pos;
+    bool bad = false;
+    // If argument is oop
+    if (_is_oop[p]) {
+      intptr_t v = _value[p];
+      if (v != 0 ) {
+        size_t t = (size_t)v;
+        bad = (t < (size_t)os::vm_page_size() ) || !(*(oop*)v)->is_oop_or_null(true);
+        if (CheckJNICalls && bad) {
+          ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument");
+        }
+      }
+      // for the regular debug case.
+      assert(!bad, "Bad JNI oop argument");
+    }
+
     check_value(true);
   }
 
@@ -505,6 +529,7 @@
   void do_array(int begin, int end)    { check_obj(T_OBJECT);        }
 };
 
+
 void JavaCallArguments::verify(methodHandle method, BasicType return_type,
   Thread *thread) {
   guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
@@ -515,10 +540,9 @@
   // Check that oop information is correct
   symbolHandle signature (thread,  method->signature());
 
-  SignatureChekker sc(signature, return_type, method->is_static(),_is_oop);
+  SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread);
   sc.iterate_parameters();
   sc.check_doing_return(true);
   sc.iterate_returntype();
 }
 
-#endif // PRODUCT
--- a/src/share/vm/runtime/javaCalls.hpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/share/vm/runtime/javaCalls.hpp	Thu Dec 11 17:20:10 2008 -0800
@@ -150,7 +150,7 @@
   int   size_of_parameters() const { return _size; }
 
   // Verify that pushed arguments fits a given method
-  void verify(methodHandle method, BasicType return_type, Thread *thread) PRODUCT_RETURN;
+  void verify(methodHandle method, BasicType return_type, Thread *thread);
 };
 
 // All calls to Java have to go via JavaCalls. Sets up the stack frame
--- a/src/share/vm/runtime/sharedRuntime.cpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Thu Dec 11 17:20:10 2008 -0800
@@ -556,7 +556,10 @@
           // the caller was at a call site, it's safe to destroy all
           // caller-saved registers, as these entry points do.
           VtableStub* vt_stub = VtableStubs::stub_containing(pc);
-          guarantee(vt_stub != NULL, "unable to find SEGVing vtable stub");
+
+          // If vt_stub is NULL, then return NULL to signal handler to report the SEGV error.
+          if (vt_stub == NULL) return NULL;
+
           if (vt_stub->is_abstract_method_error(pc)) {
             assert(!vt_stub->is_vtable_stub(), "should never see AbstractMethodErrors from vtable-type VtableStubs");
             return StubRoutines::throw_AbstractMethodError_entry();
@@ -565,7 +568,9 @@
           }
         } else {
           CodeBlob* cb = CodeCache::find_blob(pc);
-          guarantee(cb != NULL, "exception happened outside interpreter, nmethods and vtable stubs (1)");
+
+          // If code blob is NULL, then return NULL to signal handler to report the SEGV error.
+          if (cb == NULL) return NULL;
 
           // Exception happened in CodeCache. Must be either:
           // 1. Inline-cache check in C2I handler blob,
@@ -574,7 +579,7 @@
 
           if (!cb->is_nmethod()) {
             guarantee(cb->is_adapter_blob(),
-                      "exception happened outside interpreter, nmethods and vtable stubs (2)");
+                      "exception happened outside interpreter, nmethods and vtable stubs (1)");
             // There is no handler here, so we will simply unwind.
             return StubRoutines::throw_NullPointerException_at_call_entry();
           }
--- a/src/share/vm/utilities/vmError.cpp	Tue Dec 09 12:41:26 2008 -0800
+++ b/src/share/vm/utilities/vmError.cpp	Thu Dec 11 17:20:10 2008 -0800
@@ -332,6 +332,8 @@
 
      // VM version
      st->print_cr("#");
+     JDK_Version::current().to_string(buf, sizeof(buf));
+     st->print_cr("# JRE version: %s", buf);
      st->print_cr("# Java VM: %s (%s %s %s %s)",
                    Abstract_VM_Version::vm_name(),
                    Abstract_VM_Version::vm_release(),