changeset 3502:f08a3a0e60c3 jdk7u6-b12

Merge
author amurillo
date Fri, 25 May 2012 13:52:17 -0700
parents 897d453d26ac (current diff) 365d216f0666 (diff)
children 36f64ab3c9ca
files .hgtags make/hotspot_version src/os/windows/vm/os_windows.cpp
diffstat 34 files changed, 640 insertions(+), 434 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu May 24 15:27:13 2012 -0700
+++ b/.hgtags	Fri May 25 13:52:17 2012 -0700
@@ -290,3 +290,4 @@
 702b62a5e1a546ba5eea17619f9056a86fec03f1 jdk7u6-b10
 b7ae1ee1d2e49bbfbcf35587cb51c04abf2710a2 hs23.2-b02
 5921bdc6ce5cd9e3511a4177f9995becb2c2981d jdk7u6-b11
+e974e15945658e574e6c344c4a7ba225f5708c10 hs23.2-b03
--- a/make/hotspot_version	Thu May 24 15:27:13 2012 -0700
+++ b/make/hotspot_version	Fri May 25 13:52:17 2012 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=23
 HS_MINOR_VER=2
-HS_BUILD_NUMBER=02
+HS_BUILD_NUMBER=03
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/make/jprt.properties	Thu May 24 15:27:13 2012 -0700
+++ b/make/jprt.properties	Fri May 25 13:52:17 2012 -0700
@@ -133,7 +133,8 @@
     ${jprt.my.linux.x64}-{product|fastdebug}, \
     ${jprt.my.macosx.x64}-{product|fastdebug|debug}, \
     ${jprt.my.windows.i586}-{product|fastdebug|debug}, \
-    ${jprt.my.windows.x64}-{product|fastdebug|debug}
+    ${jprt.my.windows.x64}-{product|fastdebug|debug}, \
+    ${jprt.my.linux.armvfp}-{product|fastdebug}
 
 jprt.build.targets.open= \
     ${jprt.my.solaris.i586}-{productOpen}, \
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Fri May 25 13:52:17 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -238,9 +238,12 @@
 
   Register result = dst->as_register();
   {
-    // Get a pointer to the first character of string0 in tmp0 and get string0.count in str0
-    // Get a pointer to the first character of string1 in tmp1 and get string1.count in str1
-    // Also, get string0.count-string1.count in o7 and get the condition code set
+    // Get a pointer to the first character of string0 in tmp0
+    //   and get string0.length() in str0
+    // Get a pointer to the first character of string1 in tmp1
+    //   and get string1.length() in str1
+    // Also, get string0.length()-string1.length() in
+    //   o7 and get the condition code set
     // Note: some instructions have been hoisted for better instruction scheduling
 
     Register tmp0 = L0;
@@ -248,27 +251,40 @@
     Register tmp2 = L2;
 
     int  value_offset = java_lang_String:: value_offset_in_bytes(); // char array
-    int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
-    int  count_offset = java_lang_String:: count_offset_in_bytes();
-
-    __ load_heap_oop(str0, value_offset, tmp0);
-    __ ld(str0, offset_offset, tmp2);
-    __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
-    __ ld(str0, count_offset, str0);
-    __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
+    if (java_lang_String::has_offset_field()) {
+      int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
+      int  count_offset = java_lang_String:: count_offset_in_bytes();
+      __ load_heap_oop(str0, value_offset, tmp0);
+      __ ld(str0, offset_offset, tmp2);
+      __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
+      __ ld(str0, count_offset, str0);
+      __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
+    } else {
+      __ load_heap_oop(str0, value_offset, tmp1);
+      __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
+      __ ld(tmp1, arrayOopDesc::length_offset_in_bytes(), str0);
+    }
 
     // str1 may be null
     add_debug_info_for_null_check_here(info);
 
-    __ load_heap_oop(str1, value_offset, tmp1);
-    __ add(tmp0, tmp2, tmp0);
-
-    __ ld(str1, offset_offset, tmp2);
-    __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
-    __ ld(str1, count_offset, str1);
-    __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
+    if (java_lang_String::has_offset_field()) {
+      int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
+      int  count_offset = java_lang_String:: count_offset_in_bytes();
+      __ load_heap_oop(str1, value_offset, tmp1);
+      __ add(tmp0, tmp2, tmp0);
+
+      __ ld(str1, offset_offset, tmp2);
+      __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
+      __ ld(str1, count_offset, str1);
+      __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
+      __ add(tmp1, tmp2, tmp1);
+    } else {
+      __ load_heap_oop(str1, value_offset, tmp2);
+      __ add(tmp2, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
+      __ ld(tmp2, arrayOopDesc::length_offset_in_bytes(), str1);
+    }
     __ subcc(str0, str1, O7);
-    __ add(tmp1, tmp2, tmp1);
   }
 
   {
@@ -302,7 +318,7 @@
     // Shift base0 and base1 to the end of the arrays, negate limit
     __ add(base0, limit, base0);
     __ add(base1, limit, base1);
-    __ neg(limit);  // limit = -min{string0.count, strin1.count}
+    __ neg(limit);  // limit = -min{string0.length(), string1.length()}
 
     __ lduh(base0, limit, chr0);
     __ bind(Lloop);
--- a/src/cpu/x86/vm/assembler_x86.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Fri May 25 13:52:17 2012 -0700
@@ -528,10 +528,12 @@
     if (which == end_pc_operand)  return ip + (is_64bit ? 8 : 4);
     // these asserts are somewhat nonsensical
 #ifndef _LP64
-    assert(which == imm_operand || which == disp32_operand, "");
+    assert(which == imm_operand || which == disp32_operand,
+           err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, ip));
 #else
     assert((which == call32_operand || which == imm_operand) && is_64bit ||
-           which == narrow_oop_operand && !is_64bit, "");
+           which == narrow_oop_operand && !is_64bit,
+           err_msg("which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, ip));
 #endif // _LP64
     return ip;
 
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri May 25 13:52:17 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -505,19 +505,28 @@
 
   // Get addresses of first characters from both Strings
   __ load_heap_oop(rsi, Address(rax, java_lang_String::value_offset_in_bytes()));
-  __ movptr       (rcx, Address(rax, java_lang_String::offset_offset_in_bytes()));
-  __ lea          (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
-
+  if (java_lang_String::has_offset_field()) {
+    __ movptr     (rcx, Address(rax, java_lang_String::offset_offset_in_bytes()));
+    __ movl       (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
+    __ lea        (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+  } else {
+    __ movl       (rax, Address(rsi, arrayOopDesc::length_offset_in_bytes()));
+    __ lea        (rsi, Address(rsi, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+  }
 
   // rbx, may be NULL
   add_debug_info_for_null_check_here(info);
   __ load_heap_oop(rdi, Address(rbx, java_lang_String::value_offset_in_bytes()));
-  __ movptr       (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes()));
-  __ lea          (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+  if (java_lang_String::has_offset_field()) {
+    __ movptr     (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes()));
+    __ movl       (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
+    __ lea        (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+  } else {
+    __ movl       (rbx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));
+    __ lea        (rdi, Address(rdi, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+  }
 
   // compute minimum length (in rax) and difference of lengths (on top of stack)
-  __ movl  (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
-  __ movl  (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
   __ mov   (rcx, rbx);
   __ subptr(rbx, rax); // subtract lengths
   __ push  (rbx);      // result
@@ -1462,7 +1471,11 @@
       break;
 
     case Bytecodes::_l2i:
+#ifdef _LP64
+      __ movl(dest->as_register(), src->as_register_lo());
+#else
       move_regs(src->as_register_lo(), dest->as_register());
+#endif
       break;
 
     case Bytecodes::_i2b:
--- a/src/cpu/x86/vm/x86_64.ad	Thu May 24 15:27:13 2012 -0700
+++ b/src/cpu/x86/vm/x86_64.ad	Fri May 25 13:52:17 2012 -0700
@@ -3361,15 +3361,6 @@
   interface(CONST_INTER);
 %}
 
-operand immP_poll() %{
-  predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
-  match(ConP);
-
-  // formats are generated automatically for constants and base registers
-  format %{ %}
-  interface(CONST_INTER);
-%}
-
 // Pointer Immediate
 operand immN() %{
   match(ConN);
@@ -5718,16 +5709,6 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct loadConP_poll(rRegP dst, immP_poll src) %{
-  match(Set dst src);
-  format %{ "movq    $dst, $src\t!ptr" %}
-  ins_encode %{
-    AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
-    __ lea($dst$$Register, polling_page);
-  %}
-  ins_pipe(ialu_reg_fat);
-%}
-
 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
 %{
   match(Set dst src);
--- a/src/os/bsd/vm/os_bsd.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/os/bsd/vm/os_bsd.cpp	Fri May 25 13:52:17 2012 -0700
@@ -2340,93 +2340,21 @@
 #endif
 }
 
+void os::print_os_info_brief(outputStream* st) {
+  st->print("Bsd");
+
+  os::Posix::print_uname_info(st);
+}
 
 void os::print_os_info(outputStream* st) {
   st->print("OS:");
-
-  // Try to identify popular distros.
-  // Most Bsd distributions have /etc/XXX-release file, which contains
-  // the OS version string. Some have more than one /etc/XXX-release file
-  // (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.),
-  // so the order is important.
-  if (!_print_ascii_file("/etc/mandrake-release", st) &&
-      !_print_ascii_file("/etc/sun-release", st) &&
-      !_print_ascii_file("/etc/redhat-release", st) &&
-      !_print_ascii_file("/etc/SuSE-release", st) &&
-      !_print_ascii_file("/etc/turbobsd-release", st) &&
-      !_print_ascii_file("/etc/gentoo-release", st) &&
-      !_print_ascii_file("/etc/debian_version", st) &&
-      !_print_ascii_file("/etc/ltib-release", st) &&
-      !_print_ascii_file("/etc/angstrom-version", st)) {
-      st->print("Bsd");
-  }
-  st->cr();
-
-  // kernel
-  st->print("uname:");
-  struct utsname name;
-  uname(&name);
-  st->print(name.sysname); st->print(" ");
-  st->print(name.release); st->print(" ");
-  st->print(name.version); st->print(" ");
-  st->print(name.machine);
-  st->cr();
-
-#ifndef _ALLBSD_SOURCE
-  // Print warning if unsafe chroot environment detected
-  if (unsafe_chroot_detected) {
-    st->print("WARNING!! ");
-    st->print_cr(unstable_chroot_error);
-  }
-
-  // libc, pthread
-  st->print("libc:");
-  st->print(os::Bsd::glibc_version()); st->print(" ");
-  st->print(os::Bsd::libpthread_version()); st->print(" ");
-  if (os::Bsd::is_BsdThreads()) {
-     st->print("(%s stack)", os::Bsd::is_floating_stack() ? "floating" : "fixed");
-  }
-  st->cr();
-#endif
-
-  // rlimit
-  st->print("rlimit:");
-  struct rlimit rlim;
-
-  st->print(" STACK ");
-  getrlimit(RLIMIT_STACK, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
-
-  st->print(", CORE ");
-  getrlimit(RLIMIT_CORE, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
-
-  st->print(", NPROC ");
-  getrlimit(RLIMIT_NPROC, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%d", rlim.rlim_cur);
-
-  st->print(", NOFILE ");
-  getrlimit(RLIMIT_NOFILE, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%d", rlim.rlim_cur);
-
-#ifndef _ALLBSD_SOURCE
-  st->print(", AS ");
-  getrlimit(RLIMIT_AS, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
-  st->cr();
-
-  // load average
-  st->print("load average:");
-  double loadavg[3];
-  os::loadavg(loadavg, 3);
-  st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
-  st->cr();
-#endif
+  st->print("Bsd");
+
+  os::Posix::print_uname_info(st);
+
+  os::Posix::print_rlimit_info(st);
+
+  os::Posix::print_load_average(st);
 }
 
 void os::pd_print_cpu_info(outputStream* st) {
--- a/src/os/linux/vm/os_linux.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/os/linux/vm/os_linux.cpp	Fri May 25 13:52:17 2012 -0700
@@ -2020,15 +2020,43 @@
    }
 }
 
+void os::print_os_info_brief(outputStream* st) {
+  os::Linux::print_distro_info(st);
+
+  os::Posix::print_uname_info(st);
+
+  os::Linux::print_libversion_info(st);
+
+}
 
 void os::print_os_info(outputStream* st) {
   st->print("OS:");
 
-  // Try to identify popular distros.
-  // Most Linux distributions have /etc/XXX-release file, which contains
-  // the OS version string. Some have more than one /etc/XXX-release file
-  // (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.),
-  // so the order is important.
+  os::Linux::print_distro_info(st);
+
+  os::Posix::print_uname_info(st);
+
+  // Print warning if unsafe chroot environment detected
+  if (unsafe_chroot_detected) {
+    st->print("WARNING!! ");
+    st->print_cr(unstable_chroot_error);
+  }
+
+  os::Linux::print_libversion_info(st);
+
+  os::Posix::print_rlimit_info(st);
+
+  os::Posix::print_load_average(st);
+
+  os::Linux::print_full_memory_info(st);
+}
+
+// Try to identify popular distros.
+// Most Linux distributions have /etc/XXX-release file, which contains
+// the OS version string. Some have more than one /etc/XXX-release file
+// (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.),
+// so the order is important.
+void os::Linux::print_distro_info(outputStream* st) {
   if (!_print_ascii_file("/etc/mandrake-release", st) &&
       !_print_ascii_file("/etc/sun-release", st) &&
       !_print_ascii_file("/etc/redhat-release", st) &&
@@ -2041,23 +2069,9 @@
       st->print("Linux");
   }
   st->cr();
-
-  // kernel
-  st->print("uname:");
-  struct utsname name;
-  uname(&name);
-  st->print(name.sysname); st->print(" ");
-  st->print(name.release); st->print(" ");
-  st->print(name.version); st->print(" ");
-  st->print(name.machine);
-  st->cr();
-
-  // Print warning if unsafe chroot environment detected
-  if (unsafe_chroot_detected) {
-    st->print("WARNING!! ");
-    st->print_cr(unstable_chroot_error);
-  }
-
+}
+
+void os::Linux::print_libversion_info(outputStream* st) {
   // libc, pthread
   st->print("libc:");
   st->print(os::Linux::glibc_version()); st->print(" ");
@@ -2066,56 +2080,12 @@
      st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed");
   }
   st->cr();
-
-  // rlimit
-  st->print("rlimit:");
-  struct rlimit rlim;
-
-  st->print(" STACK ");
-  getrlimit(RLIMIT_STACK, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
-
-  st->print(", CORE ");
-  getrlimit(RLIMIT_CORE, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
-
-  st->print(", NPROC ");
-  getrlimit(RLIMIT_NPROC, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%d", rlim.rlim_cur);
-
-  st->print(", NOFILE ");
-  getrlimit(RLIMIT_NOFILE, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%d", rlim.rlim_cur);
-
-  st->print(", AS ");
-  getrlimit(RLIMIT_AS, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
-  st->cr();
-
-  // load average
-  st->print("load average:");
-  double loadavg[3];
-  os::loadavg(loadavg, 3);
-  st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
-  st->cr();
-
-  // meminfo
-  st->print("\n/proc/meminfo:\n");
-  _print_ascii_file("/proc/meminfo", st);
-  st->cr();
-}
-
-void os::pd_print_cpu_info(outputStream* st) {
-  st->print("\n/proc/cpuinfo:\n");
-  if (!_print_ascii_file("/proc/cpuinfo", st)) {
-    st->print("  <Not Available>");
-  }
-  st->cr();
+}
+
+void os::Linux::print_full_memory_info(outputStream* st) {
+   st->print("\n/proc/meminfo:\n");
+   _print_ascii_file("/proc/meminfo", st);
+   st->cr();
 }
 
 void os::print_memory_info(outputStream* st) {
@@ -2138,6 +2108,14 @@
   st->cr();
 }
 
+void os::pd_print_cpu_info(outputStream* st) {
+  st->print("\n/proc/cpuinfo:\n");
+  if (!_print_ascii_file("/proc/cpuinfo", st)) {
+    st->print("  <Not Available>");
+  }
+  st->cr();
+}
+
 // Taken from /usr/include/bits/siginfo.h  Supposed to be architecture specific
 // but they're the same for all the linux arch that we support
 // and they're the same for solaris but there's no common place to put this.
--- a/src/os/linux/vm/os_linux.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/os/linux/vm/os_linux.hpp	Fri May 25 13:52:17 2012 -0700
@@ -89,6 +89,10 @@
 
   static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
 
+  static void print_full_memory_info(outputStream* st);
+  static void print_distro_info(outputStream* st);
+  static void print_libversion_info(outputStream* st);
+
  public:
   static void init_thread_fpu_state();
   static int  get_fpu_control_word();
--- a/src/os/posix/vm/os_posix.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/os/posix/vm/os_posix.cpp	Fri May 25 13:52:17 2012 -0700
@@ -28,6 +28,8 @@
 
 #include <unistd.h>
 #include <sys/resource.h>
+#include <sys/utsname.h>
+
 
 // Check core dump limit and report possible place where core can be found
 void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) {
@@ -72,3 +74,59 @@
   // don't do anything on posix platforms
   return;
 }
+
+void os::Posix::print_load_average(outputStream* st) {
+  st->print("load average:");
+  double loadavg[3];
+  os::loadavg(loadavg, 3);
+  st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
+  st->cr();
+}
+
+void os::Posix::print_rlimit_info(outputStream* st) {
+  st->print("rlimit:");
+  struct rlimit rlim;
+
+  st->print(" STACK ");
+  getrlimit(RLIMIT_STACK, &rlim);
+  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
+  else st->print("%uk", rlim.rlim_cur >> 10);
+
+  st->print(", CORE ");
+  getrlimit(RLIMIT_CORE, &rlim);
+  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
+  else st->print("%uk", rlim.rlim_cur >> 10);
+
+  //Isn't there on solaris
+#ifndef TARGET_OS_FAMILY_solaris
+  st->print(", NPROC ");
+  getrlimit(RLIMIT_NPROC, &rlim);
+  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
+  else st->print("%d", rlim.rlim_cur);
+#endif
+
+  st->print(", NOFILE ");
+  getrlimit(RLIMIT_NOFILE, &rlim);
+  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
+  else st->print("%d", rlim.rlim_cur);
+
+  st->print(", AS ");
+  getrlimit(RLIMIT_AS, &rlim);
+  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
+  else st->print("%uk", rlim.rlim_cur >> 10);
+  st->cr();
+}
+
+void os::Posix::print_uname_info(outputStream* st) {
+  // kernel
+  st->print("uname:");
+  struct utsname name;
+  uname(&name);
+  st->print(name.sysname); st->print(" ");
+  st->print(name.release); st->print(" ");
+  st->print(name.version); st->print(" ");
+  st->print(name.machine);
+  st->cr();
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/posix/vm/os_posix.hpp	Fri May 25 13:52:17 2012 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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
+ * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef OS_POSIX_VM_OS_POSIX_HPP
+#define OS_POSIX_VM_OS_POSIX_HPP
+class Posix {
+  friend class os;
+
+protected:
+  static void print_distro_info(outputStream* st);
+  static void print_rlimit_info(outputStream* st);
+  static void print_uname_info(outputStream* st);
+  static void print_libversion_info(outputStream* st);
+  static void print_load_average(outputStream* st);
+
+
+};
+
+
+#endif
--- a/src/os/solaris/vm/os_solaris.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/os/solaris/vm/os_solaris.cpp	Fri May 25 13:52:17 2012 -0700
@@ -2251,61 +2251,44 @@
   return true;
 }
 
+void os::print_os_info_brief(outputStream* st) {
+  os::Solaris::print_distro_info(st);
+
+  os::Posix::print_uname_info(st);
+
+  os::Solaris::print_libversion_info(st);
+}
+
 void os::print_os_info(outputStream* st) {
   st->print("OS:");
 
+  os::Solaris::print_distro_info(st);
+
+  os::Posix::print_uname_info(st);
+
+  os::Solaris::print_libversion_info(st);
+
+  os::Posix::print_rlimit_info(st);
+
+  os::Posix::print_load_average(st);
+}
+
+void os::Solaris::print_distro_info(outputStream* st) {
   if (!_print_ascii_file("/etc/release", st)) {
-    st->print("Solaris");
+      st->print("Solaris");
+    }
+    st->cr();
+}
+
+void os::Solaris::print_libversion_info(outputStream* st) {
+  if (os::Solaris::T2_libthread()) {
+    st->print("  (T2 libthread)");
+  }
+  else {
+    st->print("  (T1 libthread)");
   }
   st->cr();
-
-  // kernel
-  st->print("uname:");
-  struct utsname name;
-  uname(&name);
-  st->print(name.sysname); st->print(" ");
-  st->print(name.release); st->print(" ");
-  st->print(name.version); st->print(" ");
-  st->print(name.machine);
-
-  // libthread
-  if (os::Solaris::T2_libthread()) st->print("  (T2 libthread)");
-  else st->print("  (T1 libthread)");
-  st->cr();
-
-  // rlimit
-  st->print("rlimit:");
-  struct rlimit rlim;
-
-  st->print(" STACK ");
-  getrlimit(RLIMIT_STACK, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
-
-  st->print(", CORE ");
-  getrlimit(RLIMIT_CORE, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
-
-  st->print(", NOFILE ");
-  getrlimit(RLIMIT_NOFILE, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%d", rlim.rlim_cur);
-
-  st->print(", AS ");
-  getrlimit(RLIMIT_AS, &rlim);
-  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
-  else st->print("%uk", rlim.rlim_cur >> 10);
-  st->cr();
-
-  // load average
-  st->print("load average:");
-  double loadavg[3];
-  os::loadavg(loadavg, 3);
-  st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
-  st->cr();
-}
-
+}
 
 static bool check_addr0(outputStream* st) {
   jboolean status = false;
--- a/src/os/solaris/vm/os_solaris.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/os/solaris/vm/os_solaris.hpp	Fri May 25 13:52:17 2012 -0700
@@ -180,6 +180,9 @@
   // proc_t structure (note that this is a system struct).
   static address _main_stack_base;
 
+  static void print_distro_info(outputStream* st);
+  static void print_libversion_info(outputStream* st);
+
  public:
   static void libthread_init();
   static void synchronization_init();
--- a/src/os/windows/vm/os_windows.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/os/windows/vm/os_windows.cpp	Fri May 25 13:52:17 2012 -0700
@@ -1572,9 +1572,17 @@
    enumerate_modules(pid, _print_module, (void *)st);
 }
 
+void os::print_os_info_brief(outputStream* st) {
+  os::print_os_info(st);
+}
+
 void os::print_os_info(outputStream* st) {
   st->print("OS:");
 
+  os::win32::print_windows_version(st);
+}
+
+void os::win32::print_windows_version(outputStream* st) {
   OSVERSIONINFOEX osvi;
   ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
--- a/src/os/windows/vm/os_windows.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/os/windows/vm/os_windows.hpp	Fri May 25 13:52:17 2012 -0700
@@ -27,6 +27,7 @@
 // Win32_OS defines the interface to windows operating systems
 
 class win32 {
+  friend class os;
 
  protected:
   static int    _vm_page_size;
@@ -39,6 +40,8 @@
   static bool   _is_windows_2003;
   static bool   _is_windows_server;
 
+  static void print_windows_version(outputStream* st);
+
  public:
   // Windows-specific interface:
   static void   initialize_system_info();
--- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Fri May 25 13:52:17 2012 -0700
@@ -522,11 +522,12 @@
 
       if ((sig == SIGSEGV || sig == SIGBUS) && os::is_poll_address((address)info->si_addr)) {
         stub = SharedRuntime::get_poll_stub(pc);
-#if defined(__APPLE__) && !defined(AMD64)
+#if defined(__APPLE__)
       // 32-bit Darwin reports a SIGBUS for nearly all memory access exceptions.
+      // 64-bit Darwin may also use a SIGBUS (seen with compressed oops).
       // Catching SIGBUS here prevents the implicit SIGBUS NULL check below from
       // being called, so only do so if the implicit NULL check is not necessary.
-      } else if (sig == SIGBUS && MacroAssembler::needs_explicit_null_check((int)info->si_addr)) {
+      } else if (sig == SIGBUS && MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) {
 #else
       } else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) {
 #endif
--- a/src/share/vm/classfile/javaClasses.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/classfile/javaClasses.cpp	Fri May 25 13:52:17 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -143,7 +143,27 @@
 }
 
 
+int java_lang_String::value_offset  = 0;
+int java_lang_String::offset_offset = 0;
+int java_lang_String::count_offset  = 0;
+int java_lang_String::hash_offset   = 0;
+
+bool java_lang_String::initialized  = false;
+
+void java_lang_String::compute_offsets() {
+  assert(!initialized, "offsets should be initialized only once");
+
+  klassOop k = SystemDictionary::String_klass();
+  compute_offset(value_offset,           k, vmSymbols::value_name(),  vmSymbols::char_array_signature());
+  compute_optional_offset(offset_offset, k, vmSymbols::offset_name(), vmSymbols::int_signature());
+  compute_optional_offset(count_offset,  k, vmSymbols::count_name(),  vmSymbols::int_signature());
+  compute_optional_offset(hash_offset,   k, vmSymbols::hash_name(),   vmSymbols::int_signature());
+
+  initialized = true;
+}
+
 Handle java_lang_String::basic_create(int length, bool tenured, TRAPS) {
+  assert(initialized, "Must be initialized");
   // Create the String object first, so there's a chance that the String
   // and the char array it points to end up in the same cache line.
   oop obj;
@@ -2837,10 +2857,6 @@
 
 
 
-int java_lang_String::value_offset;
-int java_lang_String::offset_offset;
-int java_lang_String::count_offset;
-int java_lang_String::hash_offset;
 int java_lang_Class::_klass_offset;
 int java_lang_Class::_array_klass_offset;
 int java_lang_Class::_resolved_constructor_offset;
@@ -3000,12 +3016,6 @@
   const int x = heapOopSize;
   const int header = instanceOopDesc::base_offset_in_bytes();
 
-  // Do the String Class
-  java_lang_String::value_offset  = java_lang_String::hc_value_offset  * x + header;
-  java_lang_String::offset_offset = java_lang_String::hc_offset_offset * x + header;
-  java_lang_String::count_offset  = java_lang_String::offset_offset + sizeof (jint);
-  java_lang_String::hash_offset   = java_lang_String::count_offset + sizeof (jint);
-
   // Throwable Class
   java_lang_Throwable::backtrace_offset  = java_lang_Throwable::hc_backtrace_offset  * x + header;
   java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header;
@@ -3200,9 +3210,13 @@
   // java.lang.String
 
   CHECK_OFFSET("java/lang/String", java_lang_String, value, "[C");
-  CHECK_OFFSET("java/lang/String", java_lang_String, offset, "I");
-  CHECK_OFFSET("java/lang/String", java_lang_String, count, "I");
-  CHECK_OFFSET("java/lang/String", java_lang_String, hash, "I");
+  if (java_lang_String::has_offset_field()) {
+    CHECK_OFFSET("java/lang/String", java_lang_String, offset, "I");
+    CHECK_OFFSET("java/lang/String", java_lang_String, count, "I");
+  }
+  if (java_lang_String::has_hash_field()) {
+    CHECK_OFFSET("java/lang/String", java_lang_String, hash, "I");
+  }
 
   // java.lang.Class
 
--- a/src/share/vm/classfile/javaClasses.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/classfile/javaClasses.hpp	Fri May 25 13:52:17 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -52,26 +52,36 @@
 
 class java_lang_String : AllStatic {
  private:
-  enum {
-    hc_value_offset  = 0,
-    hc_offset_offset = 1
-    //hc_count_offset = 2  -- not a word-scaled offset
-    //hc_hash_offset  = 3  -- not a word-scaled offset
-  };
-
   static int value_offset;
   static int offset_offset;
   static int count_offset;
   static int hash_offset;
 
+  static bool initialized;
+
   static Handle basic_create(int length, bool tenured, TRAPS);
   static Handle basic_create_from_unicode(jchar* unicode, int length, bool tenured, TRAPS);
 
-  static void set_value( oop string, typeArrayOop buffer) { string->obj_field_put(value_offset,  (oop)buffer); }
-  static void set_offset(oop string, int offset)          { string->int_field_put(offset_offset, offset); }
-  static void set_count( oop string, int count)           { string->int_field_put(count_offset,  count);  }
+  static void set_value( oop string, typeArrayOop buffer) {
+    assert(initialized, "Must be initialized");
+    string->obj_field_put(value_offset,  (oop)buffer);
+  }
+  static void set_offset(oop string, int offset) {
+    assert(initialized, "Must be initialized");
+    if (offset_offset > 0) {
+      string->int_field_put(offset_offset, offset);
+    }
+  }
+  static void set_count( oop string, int count) {
+    assert(initialized, "Must be initialized");
+    if (count_offset > 0) {
+      string->int_field_put(count_offset,  count);
+    }
+  }
 
  public:
+  static void compute_offsets();
+
   // Instance creation
   static Handle create_from_unicode(jchar* unicode, int len, TRAPS);
   static Handle create_tenured_from_unicode(jchar* unicode, int len, TRAPS);
@@ -82,23 +92,61 @@
   static Handle create_from_platform_dependent_str(const char* str, TRAPS);
   static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS);
 
-  static int value_offset_in_bytes()  { return value_offset;  }
-  static int count_offset_in_bytes()  { return count_offset;  }
-  static int offset_offset_in_bytes() { return offset_offset; }
-  static int hash_offset_in_bytes()   { return hash_offset;   }
+  static bool has_offset_field()  {
+    assert(initialized, "Must be initialized");
+    return (offset_offset > 0);
+  }
+
+  static bool has_count_field()  {
+    assert(initialized, "Must be initialized");
+    return (count_offset > 0);
+  }
+
+  static bool has_hash_field()  {
+    assert(initialized, "Must be initialized");
+    return (hash_offset > 0);
+  }
+
+  static int value_offset_in_bytes()  {
+    assert(initialized && (value_offset > 0), "Must be initialized");
+    return value_offset;
+  }
+  static int count_offset_in_bytes()  {
+    assert(initialized && (count_offset > 0), "Must be initialized");
+    return count_offset;
+  }
+  static int offset_offset_in_bytes() {
+    assert(initialized && (offset_offset > 0), "Must be initialized");
+    return offset_offset;
+  }
+  static int hash_offset_in_bytes()   {
+    assert(initialized && (hash_offset > 0), "Must be initialized");
+    return hash_offset;
+  }
 
   // Accessors
   static typeArrayOop value(oop java_string) {
+    assert(initialized && (value_offset > 0), "Must be initialized");
     assert(is_instance(java_string), "must be java_string");
     return (typeArrayOop) java_string->obj_field(value_offset);
   }
   static int offset(oop java_string) {
+    assert(initialized, "Must be initialized");
     assert(is_instance(java_string), "must be java_string");
-    return java_string->int_field(offset_offset);
+    if (offset_offset > 0) {
+      return java_string->int_field(offset_offset);
+    } else {
+      return 0;
+    }
   }
   static int length(oop java_string) {
+    assert(initialized, "Must be initialized");
     assert(is_instance(java_string), "must be java_string");
-    return java_string->int_field(count_offset);
+    if (count_offset > 0) {
+      return java_string->int_field(count_offset);
+    } else {
+      return ((typeArrayOop)java_string->obj_field(value_offset))->length();
+    }
   }
   static int utf8_length(oop java_string);
 
--- a/src/share/vm/classfile/systemDictionary.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/classfile/systemDictionary.cpp	Fri May 25 13:52:17 2012 -0700
@@ -1971,6 +1971,9 @@
   // first do Object, String, Class
   initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK);
 
+  // Calculate offsets for String and Class classes since they are loaded and
+  // can be used after this point.
+  java_lang_String::compute_offsets();
   java_lang_Class::compute_offsets();
 
   // Fixup mirrors for classes loaded before java.lang.Class.
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri May 25 13:52:17 2012 -0700
@@ -339,6 +339,9 @@
   template(park_event_name,                           "nativeParkEventPointer")                   \
   template(cache_field_name,                          "cache")                                    \
   template(value_name,                                "value")                                    \
+  template(offset_name,                               "offset")                                   \
+  template(count_name,                                "count")                                    \
+  template(hash_name,                                 "hash")                                     \
   template(frontCacheEnabled_name,                    "frontCacheEnabled")                        \
   template(stringCacheEnabled_name,                   "stringCacheEnabled")                       \
   template(numberOfLeadingZeros_name,                 "numberOfLeadingZeros")                     \
--- a/src/share/vm/gc_implementation/shared/gcUtil.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/gc_implementation/shared/gcUtil.cpp	Fri May 25 13:52:17 2012 -0700
@@ -31,9 +31,15 @@
                                                         float average) {
   // We smooth the samples by not using weight() directly until we've
   // had enough data to make it meaningful. We'd like the first weight
-  // used to be 1, the second to be 1/2, etc until we have 100/weight
-  // samples.
-  unsigned count_weight = 100/count();
+  // used to be 1, the second to be 1/2, etc until we have
+  // OLD_THRESHOLD/weight samples.
+  unsigned count_weight = 0;
+
+  // Avoid division by zero if the counter wraps (7158457)
+  if (!is_old()) {
+    count_weight = OLD_THRESHOLD/count();
+  }
+
   unsigned adaptive_weight = (MAX2(weight(), count_weight));
 
   float new_avg = exp_avg(average, new_sample, adaptive_weight);
@@ -43,8 +49,6 @@
 
 void AdaptiveWeightedAverage::sample(float new_sample) {
   increment_count();
-  assert(count() != 0,
-         "Wraparound -- history would be incorrectly discarded");
 
   // Compute the new weighted average
   float new_avg = compute_adaptive_average(new_sample, average());
--- a/src/share/vm/gc_implementation/shared/gcUtil.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/gc_implementation/shared/gcUtil.hpp	Fri May 25 13:52:17 2012 -0700
@@ -50,11 +50,20 @@
   unsigned         _weight;         // The weight used to smooth the averages
                                     //   A higher weight favors the most
                                     //   recent data.
+  bool             _is_old;         // Has enough historical data
+
+  const static unsigned OLD_THRESHOLD = 100;
 
  protected:
   float            _last_sample;    // The last value sampled.
 
-  void  increment_count()       { _sample_count++;       }
+  void  increment_count() {
+    _sample_count++;
+    if (!_is_old && _sample_count > OLD_THRESHOLD) {
+      _is_old = true;
+    }
+  }
+
   void  set_average(float avg)  { _average = avg;        }
 
   // Helper function, computes an adaptive weighted average
@@ -64,13 +73,15 @@
  public:
   // Input weight must be between 0 and 100
   AdaptiveWeightedAverage(unsigned weight, float avg = 0.0) :
-    _average(avg), _sample_count(0), _weight(weight), _last_sample(0.0) {
+    _average(avg), _sample_count(0), _weight(weight), _last_sample(0.0),
+    _is_old(false) {
   }
 
   void clear() {
     _average = 0;
     _sample_count = 0;
     _last_sample = 0;
+    _is_old = false;
   }
 
   // Useful for modifying static structures after startup.
@@ -84,7 +95,8 @@
   float    average() const       { return _average;       }
   unsigned weight()  const       { return _weight;        }
   unsigned count()   const       { return _sample_count;  }
-  float    last_sample() const   { return _last_sample; }
+  float    last_sample() const   { return _last_sample;   }
+  bool     is_old()  const       { return _is_old;        }
 
   // Update data with a new sample.
   void sample(float new_sample);
--- a/src/share/vm/memory/barrierSet.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/memory/barrierSet.hpp	Fri May 25 13:52:17 2012 -0700
@@ -181,6 +181,8 @@
   // within the heap, this function tells whether they are met.
   virtual bool is_aligned(HeapWord* addr) = 0;
 
+  // Print a description of the memory for the barrier set
+  virtual void print_on(outputStream* st) const = 0;
 };
 
 #endif // SHARE_VM_MEMORY_BARRIERSET_HPP
--- a/src/share/vm/memory/cardTableModRefBS.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/memory/cardTableModRefBS.cpp	Fri May 25 13:52:17 2012 -0700
@@ -711,6 +711,11 @@
 }
 #endif
 
+void CardTableModRefBS::print_on(outputStream* st) const {
+  st->print_cr("Card table byte_map: [" INTPTR_FORMAT "," INTPTR_FORMAT "] byte_map_base: " INTPTR_FORMAT,
+               _byte_map, _byte_map + _byte_map_size, byte_map_base);
+}
+
 bool CardTableModRefBSForCTRS::card_will_be_scanned(jbyte cv) {
   return
     CardTableModRefBS::card_will_be_scanned(cv) ||
--- a/src/share/vm/memory/cardTableModRefBS.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/memory/cardTableModRefBS.hpp	Fri May 25 13:52:17 2012 -0700
@@ -469,6 +469,9 @@
     return _byte_map + card_index;
   }
 
+  // Print a description of the memory for the barrier set
+  virtual void print_on(outputStream* st) const;
+
   void verify();
   void verify_guard();
 
--- a/src/share/vm/memory/dump.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/memory/dump.cpp	Fri May 25 13:52:17 2012 -0700
@@ -78,8 +78,8 @@
   void do_oop(oop* p) {
     if (p != NULL) {
       oop obj = *p;
-      if (obj->klass() == SystemDictionary::String_klass()) {
-
+      if (obj->klass() == SystemDictionary::String_klass() &&
+          java_lang_String::has_hash_field()) {
         int hash = java_lang_String::hash_string(obj);
         obj->int_field_put(hash_offset, hash);
       }
--- a/src/share/vm/opto/graphKit.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/opto/graphKit.cpp	Fri May 25 13:52:17 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -3748,3 +3748,81 @@
   final_sync(ideal);
 }
 #undef __
+
+
+
+Node* GraphKit::load_String_offset(Node* ctrl, Node* str) {
+  if (java_lang_String::has_offset_field()) {
+    int offset_offset = java_lang_String::offset_offset_in_bytes();
+    const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
+                                                       false, NULL, 0);
+    const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
+    int offset_field_idx = C->get_alias_index(offset_field_type);
+    return make_load(ctrl,
+                     basic_plus_adr(str, str, offset_offset),
+                     TypeInt::INT, T_INT, offset_field_idx);
+  } else {
+    return intcon(0);
+  }
+}
+
+Node* GraphKit::load_String_length(Node* ctrl, Node* str) {
+  if (java_lang_String::has_count_field()) {
+    int count_offset = java_lang_String::count_offset_in_bytes();
+    const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
+                                                       false, NULL, 0);
+    const TypePtr* count_field_type = string_type->add_offset(count_offset);
+    int count_field_idx = C->get_alias_index(count_field_type);
+    return make_load(ctrl,
+                     basic_plus_adr(str, str, count_offset),
+                     TypeInt::INT, T_INT, count_field_idx);
+  } else {
+    return load_array_length(load_String_value(ctrl, str));
+  }
+}
+
+Node* GraphKit::load_String_value(Node* ctrl, Node* str) {
+  int value_offset = java_lang_String::value_offset_in_bytes();
+  const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
+                                                     false, NULL, 0);
+  const TypePtr* value_field_type = string_type->add_offset(value_offset);
+  const TypeAryPtr*  value_type = TypeAryPtr::make(TypePtr::NotNull,
+                                                   TypeAry::make(TypeInt::CHAR,TypeInt::POS),
+                                                   ciTypeArrayKlass::make(T_CHAR), true, 0);
+  int value_field_idx = C->get_alias_index(value_field_type);
+  return make_load(ctrl, basic_plus_adr(str, str, value_offset),
+                   value_type, T_OBJECT, value_field_idx);
+}
+
+void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) {
+  int offset_offset = java_lang_String::offset_offset_in_bytes();
+  const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
+                                                     false, NULL, 0);
+  const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
+  int offset_field_idx = C->get_alias_index(offset_field_type);
+  store_to_memory(ctrl, basic_plus_adr(str, offset_offset),
+                  value, T_INT, offset_field_idx);
+}
+
+void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) {
+  int value_offset = java_lang_String::value_offset_in_bytes();
+  const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
+                                                     false, NULL, 0);
+  const TypePtr* value_field_type = string_type->add_offset(value_offset);
+  const TypeAryPtr*  value_type = TypeAryPtr::make(TypePtr::NotNull,
+                                                   TypeAry::make(TypeInt::CHAR,TypeInt::POS),
+                                                   ciTypeArrayKlass::make(T_CHAR), true, 0);
+  int value_field_idx = C->get_alias_index(value_field_type);
+  store_to_memory(ctrl, basic_plus_adr(str, value_offset),
+                  value, T_OBJECT, value_field_idx);
+}
+
+void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) {
+  int count_offset = java_lang_String::count_offset_in_bytes();
+  const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
+                                                     false, NULL, 0);
+  const TypePtr* count_field_type = string_type->add_offset(count_offset);
+  int count_field_idx = C->get_alias_index(count_field_type);
+  store_to_memory(ctrl, basic_plus_adr(str, count_offset),
+                  value, T_INT, count_field_idx);
+}
--- a/src/share/vm/opto/graphKit.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/opto/graphKit.hpp	Fri May 25 13:52:17 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -781,6 +781,14 @@
   Node* new_array(Node* klass_node, Node* count_val, int nargs,
                   Node* *return_size_val = NULL);
 
+  // java.lang.String helpers
+  Node* load_String_offset(Node* ctrl, Node* str);
+  Node* load_String_length(Node* ctrl, Node* str);
+  Node* load_String_value(Node* ctrl, Node* str);
+  void store_String_offset(Node* ctrl, Node* str, Node* value);
+  void store_String_length(Node* ctrl, Node* str, Node* value);
+  void store_String_value(Node* ctrl, Node* str, Node* value);
+
   // Handy for making control flow
   IfNode* create_and_map_if(Node* ctrl, Node* tst, float prob, float cnt) {
     IfNode* iff = new (C, 2) IfNode(ctrl, tst, prob, cnt);// New IfNode's
--- a/src/share/vm/opto/library_call.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/opto/library_call.cpp	Fri May 25 13:52:17 2012 -0700
@@ -147,7 +147,8 @@
     return generate_method_call(method_id, true, false);
   }
 
-  Node* make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2);
+  Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2);
+  Node* make_string_method_node(int opcode, Node* str1, Node* str2);
   bool inline_string_compareTo();
   bool inline_string_indexOf();
   Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
@@ -844,48 +845,76 @@
 
 
 //------------------------------make_string_method_node------------------------
-// Helper method for String intrinsic finctions.
-Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2) {
-  const int value_offset  = java_lang_String::value_offset_in_bytes();
-  const int count_offset  = java_lang_String::count_offset_in_bytes();
-  const int offset_offset = java_lang_String::offset_offset_in_bytes();
-
+// Helper method for String intrinsic functions. This version is called
+// with str1 and str2 pointing to String object nodes.
+//
+Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* str2) {
   Node* no_ctrl = NULL;
 
-  ciInstanceKlass* klass = env()->String_klass();
-  const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
-
-  const TypeAryPtr* value_type =
-        TypeAryPtr::make(TypePtr::NotNull,
-                         TypeAry::make(TypeInt::CHAR,TypeInt::POS),
-                         ciTypeArrayKlass::make(T_CHAR), true, 0);
-
-  // Get start addr of string and substring
-  Node* str1_valuea  = basic_plus_adr(str1, str1, value_offset);
-  Node* str1_value   = make_load(no_ctrl, str1_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset));
-  Node* str1_offseta = basic_plus_adr(str1, str1, offset_offset);
-  Node* str1_offset  = make_load(no_ctrl, str1_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
+  // Get start addr of string
+  Node* str1_value   = load_String_value(no_ctrl, str1);
+  Node* str1_offset  = load_String_offset(no_ctrl, str1);
   Node* str1_start   = array_element_address(str1_value, str1_offset, T_CHAR);
 
-  Node* str2_valuea  = basic_plus_adr(str2, str2, value_offset);
-  Node* str2_value   = make_load(no_ctrl, str2_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset));
-  Node* str2_offseta = basic_plus_adr(str2, str2, offset_offset);
-  Node* str2_offset  = make_load(no_ctrl, str2_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
+  // Get length of string 1
+  Node* str1_len  = load_String_length(no_ctrl, str1);
+
+  Node* str2_value   = load_String_value(no_ctrl, str2);
+  Node* str2_offset  = load_String_offset(no_ctrl, str2);
   Node* str2_start   = array_element_address(str2_value, str2_offset, T_CHAR);
 
+  Node* str2_len = NULL;
+  Node* result = NULL;
+
+  switch (opcode) {
+  case Op_StrIndexOf:
+    // Get length of string 2
+    str2_len = load_String_length(no_ctrl, str2);
+
+    result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
+                                 str1_start, str1_len, str2_start, str2_len);
+    break;
+  case Op_StrComp:
+    // Get length of string 2
+    str2_len = load_String_length(no_ctrl, str2);
+
+    result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS),
+                                 str1_start, str1_len, str2_start, str2_len);
+    break;
+  case Op_StrEquals:
+    result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
+                               str1_start, str2_start, str1_len);
+    break;
+  default:
+    ShouldNotReachHere();
+    return NULL;
+  }
+
+  // All these intrinsics have checks.
+  C->set_has_split_ifs(true); // Has chance for split-if optimization
+
+  return _gvn.transform(result);
+}
+
+// Helper method for String intrinsic functions. This version is called
+// with str1 and str2 pointing to char[] nodes, with cnt1 and cnt2 pointing
+// to Int nodes containing the lenghts of str1 and str2.
+//
+Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2) {
+
   Node* result = NULL;
   switch (opcode) {
   case Op_StrIndexOf:
     result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
-                                       str1_start, cnt1, str2_start, cnt2);
+                                 str1_start, cnt1, str2_start, cnt2);
     break;
   case Op_StrComp:
     result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS),
-                                    str1_start, cnt1, str2_start, cnt2);
+                                 str1_start, cnt1, str2_start, cnt2);
     break;
   case Op_StrEquals:
     result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
-                                      str1_start, str2_start, cnt1);
+                                 str1_start, str2_start, cnt1);
     break;
   default:
     ShouldNotReachHere();
@@ -903,10 +932,6 @@
 
   if (!Matcher::has_match_rule(Op_StrComp)) return false;
 
-  const int value_offset = java_lang_String::value_offset_in_bytes();
-  const int count_offset = java_lang_String::count_offset_in_bytes();
-  const int offset_offset = java_lang_String::offset_offset_in_bytes();
-
   _sp += 2;
   Node *argument = pop();  // pop non-receiver first:  it was pushed second
   Node *receiver = pop();
@@ -923,18 +948,7 @@
     return true;
   }
 
-  ciInstanceKlass* klass = env()->String_klass();
-  const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
-  Node* no_ctrl = NULL;
-
-  // Get counts for string and argument
-  Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset);
-  Node* receiver_cnt  = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
-
-  Node* argument_cnta = basic_plus_adr(argument, argument, count_offset);
-  Node* argument_cnt  = make_load(no_ctrl, argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
-
-  Node* compare = make_string_method_node(Op_StrComp, receiver, receiver_cnt, argument, argument_cnt);
+  Node* compare = make_string_method_node(Op_StrComp, receiver, argument);
   push(compare);
   return true;
 }
@@ -944,10 +958,6 @@
 
   if (!Matcher::has_match_rule(Op_StrEquals)) return false;
 
-  const int value_offset = java_lang_String::value_offset_in_bytes();
-  const int count_offset = java_lang_String::count_offset_in_bytes();
-  const int offset_offset = java_lang_String::offset_offset_in_bytes();
-
   int nargs = 2;
   _sp += nargs;
   Node* argument = pop();  // pop non-receiver first:  it was pushed second
@@ -1001,24 +1011,31 @@
     }
   }
 
-  const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
-
-  Node* no_ctrl = NULL;
-  Node* receiver_cnt;
-  Node* argument_cnt;
-
   if (!stopped()) {
+    const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
+
     // Properly cast the argument to String
     argument = _gvn.transform(new (C, 2) CheckCastPPNode(control(), argument, string_type));
     // This path is taken only when argument's type is String:NotNull.
     argument = cast_not_null(argument, false);
 
-    // Get counts for string and argument
-    Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset);
-    receiver_cnt  = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
-
-    Node* argument_cnta = basic_plus_adr(argument, argument, count_offset);
-    argument_cnt  = make_load(no_ctrl, argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
+    Node* no_ctrl = NULL;
+
+    // Get start addr of receiver
+    Node* receiver_val    = load_String_value(no_ctrl, receiver);
+    Node* receiver_offset = load_String_offset(no_ctrl, receiver);
+    Node* receiver_start = array_element_address(receiver_val, receiver_offset, T_CHAR);
+
+    // Get length of receiver
+    Node* receiver_cnt  = load_String_length(no_ctrl, receiver);
+
+    // Get start addr of argument
+    Node* argument_val   = load_String_value(no_ctrl, argument);
+    Node* argument_offset = load_String_offset(no_ctrl, argument);
+    Node* argument_start = array_element_address(argument_val, argument_offset, T_CHAR);
+
+    // Get length of argument
+    Node* argument_cnt  = load_String_length(no_ctrl, argument);
 
     // Check for receiver count != argument count
     Node* cmp = _gvn.transform( new(C, 3) CmpINode(receiver_cnt, argument_cnt) );
@@ -1028,14 +1045,14 @@
       phi->init_req(4, intcon(0));
       region->init_req(4, if_ne);
     }
-  }
-
-  // Check for count == 0 is done by mach node StrEquals.
-
-  if (!stopped()) {
-    Node* equals = make_string_method_node(Op_StrEquals, receiver, receiver_cnt, argument, argument_cnt);
-    phi->init_req(1, equals);
-    region->init_req(1, control());
+
+    // Check for count == 0 is done by assembler code for StrEquals.
+
+    if (!stopped()) {
+      Node* equals = make_string_method_node(Op_StrEquals, receiver_start, receiver_cnt, argument_start, argument_cnt);
+      phi->init_req(1, equals);
+      region->init_req(1, control());
+    }
   }
 
   // post merge
@@ -1133,20 +1150,9 @@
 
   const int nargs = 2; // number of arguments to push back for uncommon trap in predicate
 
-  const int value_offset  = java_lang_String::value_offset_in_bytes();
-  const int count_offset  = java_lang_String::count_offset_in_bytes();
-  const int offset_offset = java_lang_String::offset_offset_in_bytes();
-
-  ciInstanceKlass* klass = env()->String_klass();
-  const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
-  const TypeAryPtr*  source_type = TypeAryPtr::make(TypePtr::NotNull, TypeAry::make(TypeInt::CHAR,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, 0);
-
-  Node* sourceOffseta = basic_plus_adr(string_object, string_object, offset_offset);
-  Node* sourceOffset  = make_load(no_ctrl, sourceOffseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
-  Node* sourceCounta  = basic_plus_adr(string_object, string_object, count_offset);
-  Node* sourceCount   = make_load(no_ctrl, sourceCounta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
-  Node* sourcea       = basic_plus_adr(string_object, string_object, value_offset);
-  Node* source        = make_load(no_ctrl, sourcea, source_type, T_OBJECT, string_type->add_offset(value_offset));
+  Node* source        = load_String_value(no_ctrl, string_object);
+  Node* sourceOffset  = load_String_offset(no_ctrl, string_object);
+  Node* sourceCount   = load_String_length(no_ctrl, string_object);
 
   Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)) );
   jint target_length = target_array->length();
@@ -1214,10 +1220,6 @@
 //------------------------------inline_string_indexOf------------------------
 bool LibraryCallKit::inline_string_indexOf() {
 
-  const int value_offset  = java_lang_String::value_offset_in_bytes();
-  const int count_offset  = java_lang_String::count_offset_in_bytes();
-  const int offset_offset = java_lang_String::offset_offset_in_bytes();
-
   _sp += 2;
   Node *argument = pop();  // pop non-receiver first:  it was pushed second
   Node *receiver = pop();
@@ -1251,12 +1253,21 @@
     Node*       result_phi = new (C, 4) PhiNode(result_rgn, TypeInt::INT);
     Node* no_ctrl  = NULL;
 
-    // Get counts for string and substr
-    Node* source_cnta = basic_plus_adr(receiver, receiver, count_offset);
-    Node* source_cnt  = make_load(no_ctrl, source_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
-
-    Node* substr_cnta = basic_plus_adr(argument, argument, count_offset);
-    Node* substr_cnt  = make_load(no_ctrl, substr_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
+    // Get start addr of source string
+    Node* source = load_String_value(no_ctrl, receiver);
+    Node* source_offset = load_String_offset(no_ctrl, receiver);
+    Node* source_start = array_element_address(source, source_offset, T_CHAR);
+
+    // Get length of source string
+    Node* source_cnt  = load_String_length(no_ctrl, receiver);
+
+    // Get start addr of substring
+    Node* substr = load_String_value(no_ctrl, argument);
+    Node* substr_offset = load_String_offset(no_ctrl, argument);
+    Node* substr_start = array_element_address(substr, substr_offset, T_CHAR);
+
+    // Get length of source string
+    Node* substr_cnt  = load_String_length(no_ctrl, argument);
 
     // Check for substr count > string count
     Node* cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, source_cnt) );
@@ -1279,7 +1290,7 @@
     }
 
     if (!stopped()) {
-      result = make_string_method_node(Op_StrIndexOf, receiver, source_cnt, argument, substr_cnt);
+      result = make_string_method_node(Op_StrIndexOf, source_start, source_cnt, substr_start, substr_cnt);
       result_phi->init_req(1, result);
       result_rgn->init_req(1, control());
     }
@@ -1304,11 +1315,19 @@
     ciInstance* str = str_const->as_instance();
     assert(str != NULL, "must be instance");
 
-    ciObject* v = str->field_value_by_offset(value_offset).as_object();
-    int       o = str->field_value_by_offset(offset_offset).as_int();
-    int       c = str->field_value_by_offset(count_offset).as_int();
+    ciObject* v = str->field_value_by_offset(java_lang_String::value_offset_in_bytes()).as_object();
     ciTypeArray* pat = v->as_type_array(); // pattern (argument) character array
 
+    int o;
+    int c;
+    if (java_lang_String::has_offset_field()) {
+      o = str->field_value_by_offset(java_lang_String::offset_offset_in_bytes()).as_int();
+      c = str->field_value_by_offset(java_lang_String::count_offset_in_bytes()).as_int();
+    } else {
+      o = 0;
+      c = pat->length();
+    }
+
     // constant strings have no offset and count == length which
     // simplifies the resulting code somewhat so lets optimize for that.
     if (o != 0 || c != pat->length()) {
--- a/src/share/vm/opto/stringopts.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/opto/stringopts.cpp	Fri May 25 13:52:17 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, 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
@@ -528,16 +528,6 @@
   }
 
   // Collect the types needed to talk about the various slices of memory
-  const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
-                                                     false, NULL, 0);
-
-  const TypePtr* value_field_type = string_type->add_offset(java_lang_String::value_offset_in_bytes());
-  const TypePtr* offset_field_type = string_type->add_offset(java_lang_String::offset_offset_in_bytes());
-  const TypePtr* count_field_type = string_type->add_offset(java_lang_String::count_offset_in_bytes());
-
-  value_field_idx = C->get_alias_index(value_field_type);
-  count_field_idx = C->get_alias_index(count_field_type);
-  offset_field_idx = C->get_alias_index(offset_field_type);
   char_adr_idx = C->get_alias_index(TypeAryPtr::CHARS);
 
   // For each locally allocated StringBuffer see if the usages can be
@@ -1173,18 +1163,9 @@
 
 Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start) {
   Node* string = str;
-  Node* offset = kit.make_load(kit.control(),
-                               kit.basic_plus_adr(string, string, java_lang_String::offset_offset_in_bytes()),
-                               TypeInt::INT, T_INT, offset_field_idx);
-  Node* count = kit.make_load(kit.control(),
-                              kit.basic_plus_adr(string, string, java_lang_String::count_offset_in_bytes()),
-                              TypeInt::INT, T_INT, count_field_idx);
-  const TypeAryPtr*  value_type = TypeAryPtr::make(TypePtr::NotNull,
-                                                   TypeAry::make(TypeInt::CHAR,TypeInt::POS),
-                                                   ciTypeArrayKlass::make(T_CHAR), true, 0);
-  Node* value = kit.make_load(kit.control(),
-                              kit.basic_plus_adr(string, string, java_lang_String::value_offset_in_bytes()),
-                              value_type, T_OBJECT, value_field_idx);
+  Node* offset = kit.load_String_offset(kit.control(), string);
+  Node* count  = kit.load_String_length(kit.control(), string);
+  Node* value  = kit.load_String_value (kit.control(), string);
 
   // copy the contents
   if (offset->is_Con() && count->is_Con() && value->is_Con() && count->get_int() < unroll_string_copy_length) {
@@ -1341,10 +1322,9 @@
           arg = phi;
           sc->set_argument(argi, arg);
         }
-        //         Node* offset = kit.make_load(NULL, kit.basic_plus_adr(arg, arg, offset_offset),
-        //                                      TypeInt::INT, T_INT, offset_field_idx);
-        Node* count = kit.make_load(kit.control(), kit.basic_plus_adr(arg, arg, java_lang_String::count_offset_in_bytes()),
-                                    TypeInt::INT, T_INT, count_field_idx);
+
+        Node* count = kit.load_String_length(kit.control(), arg);
+
         length = __ AddI(length, count);
         string_sizes->init_req(argi, NULL);
         break;
@@ -1435,12 +1415,11 @@
   }
 
   // Intialize the string
-  kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::offset_offset_in_bytes()),
-                      __ intcon(0), T_INT, offset_field_idx);
-  kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::count_offset_in_bytes()),
-                      length, T_INT, count_field_idx);
-  kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::value_offset_in_bytes()),
-                      char_array, T_OBJECT, value_field_idx);
+  if (java_lang_String::has_offset_field()) {
+    kit.store_String_offset(kit.control(), result, __ intcon(0));
+    kit.store_String_length(kit.control(), result, length);
+  }
+  kit.store_String_value(kit.control(), result, char_array);
 
   // hook up the outgoing control and result
   kit.replace_call(sc->end(), result);
--- a/src/share/vm/opto/stringopts.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/opto/stringopts.hpp	Fri May 25 13:52:17 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, 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
@@ -41,9 +41,6 @@
 
   // Memory slices needed for code gen
   int char_adr_idx;
-  int value_field_idx;
-  int count_field_idx;
-  int offset_field_idx;
 
   // Integer.sizeTable - used for int to String conversion
   ciField* size_table_field;
--- a/src/share/vm/runtime/os.hpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/runtime/os.hpp	Fri May 25 13:52:17 2012 -0700
@@ -490,6 +490,7 @@
   // Print out system information; they are called by fatal error handler.
   // Output format may be different on different platforms.
   static void print_os_info(outputStream* st);
+  static void print_os_info_brief(outputStream* st);
   static void print_cpu_info(outputStream* st);
   static void pd_print_cpu_info(outputStream* st);
   static void print_memory_info(outputStream* st);
@@ -683,14 +684,17 @@
   // Platform dependent stuff
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.hpp"
+# include "os_posix.hpp"
 #endif
 #ifdef TARGET_OS_FAMILY_solaris
 # include "os_solaris.hpp"
+# include "os_posix.hpp"
 #endif
 #ifdef TARGET_OS_FAMILY_windows
 # include "os_windows.hpp"
 #endif
 #ifdef TARGET_OS_FAMILY_bsd
+# include "os_posix.hpp"
 # include "os_bsd.hpp"
 #endif
 #ifdef TARGET_OS_ARCH_linux_x86
--- a/src/share/vm/utilities/vmError.cpp	Thu May 24 15:27:13 2012 -0700
+++ b/src/share/vm/utilities/vmError.cpp	Fri May 25 13:52:17 2012 -0700
@@ -684,6 +684,12 @@
        // extended (i.e., more detailed) version.
        Universe::print_on(st, true /* extended */);
        st->cr();
+
+       Universe::heap()->barrier_set()->print_on(st);
+       st->cr();
+
+       st->print_cr("Polling page: " INTPTR_FORMAT, os::get_polling_page());
+       st->cr();
      }
 
   STEP(195, "(printing code cache information)" )