changeset 1040:c46e727121a8

2008-09-12 Matthias Klose <doko@ubuntu.com> * Makefile.am, HACKING: Update for b12 zero patch. * patches/icedtea-hotspot-6b11-7b24.patch: Remove. * patches/icedtea-hotspot-6b12-7b24.patch: New.
author doko@ubuntu.com
date Sat, 13 Sep 2008 09:32:12 +0200
parents f2a1e7f88c53
children 02fc4b7ada3d
files ChangeLog HACKING Makefile.am patches/icedtea-hotspot-6b12-7b24.patch
diffstat 4 files changed, 56987 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Sep 12 23:30:45 2008 +0100
+++ b/ChangeLog	Sat Sep 13 09:32:12 2008 +0200
@@ -1,3 +1,9 @@
+2008-09-12  Matthias Klose  <doko@ubuntu.com>
+
+	* Makefile.am, HACKING: Update for b12 zero patch.
+	* patches/icedtea-hotspot-6b11-7b24.patch: Remove.
+	* patches/icedtea-hotspot-6b12-7b24.patch: New.
+
 2008-09-12  Andrew John Hughes  <gnu_andrew@member.fsf.org>
 
 	* Makefile.am:
--- a/HACKING	Fri Sep 12 23:30:45 2008 +0100
+++ b/HACKING	Sat Sep 13 09:32:12 2008 +0200
@@ -83,7 +83,7 @@
 * icedtea-bytecodeInterpreter.patch: Replace fast opcodes with opc_default.
 * icedtea-bytecodeInterpreterWithChecks.patch: Same as icedtea-xslfix.patch (OpenJDK6 only, S6707485).
 * icedtea-eclipse-hotspot-6614100-7b24.patch: Fix Eclipse crash (S6614100). Fixed in OpenJDK7 b29/hs13.
-* icedtea-hotspot-6b11-7b24.patch: Upgrade to HotSpot from OpenJDK b24 (OpenJDK6 only).
+* icedtea-hotspot-6b12-7b24.patch: Upgrade to HotSpot from OpenJDK b24 (OpenJDK6 only).
    - Never edit this patch.  It should be regenerated by unzipping the
      openjdk6 build you're using into openjdk6, and the openjdk7 build
      you want to use into openjdk, then running:
--- a/Makefile.am	Fri Sep 12 23:30:45 2008 +0100
+++ b/Makefile.am	Sat Sep 13 09:32:12 2008 +0200
@@ -415,7 +415,7 @@
 # If ZERO_BUILD is set then we are building zero and need
 # to patch up to OpenJDK 7 HotSpot for the C++ interpreter.
 ZERO_PATCHES = \
-	patches/icedtea-hotspot-6b11-7b24.patch \
+	patches/icedtea-hotspot-6b12-7b24.patch \
 	patches/icedtea-hotspot7-build-fixes.patch \
 	patches/icedtea-bytecodeInterpreter.patch \
 	patches/icedtea-bytecodeInterpreterWithChecks.patch \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-hotspot-6b12-7b24.patch	Sat Sep 13 09:32:12 2008 +0200
@@ -0,0 +1,56979 @@
+diff -ruNb openjdk6/hotspot/src/share/tools/MakeDeps/BuildConfig.java openjdk/hotspot/src/share/tools/MakeDeps/BuildConfig.java
+--- openjdk6/hotspot/src/share/tools/MakeDeps/BuildConfig.java	2008-08-28 10:23:06.000000000 +0200
++++ openjdk/hotspot/src/share/tools/MakeDeps/BuildConfig.java	2007-12-14 08:57:02.000000000 +0100
+@@ -704,6 +704,3 @@
+ 	receiver.add(attr); receiver.add(value); 
+     }
+ }
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/tools/MakeDeps/Macro.java openjdk/hotspot/src/share/tools/MakeDeps/Macro.java
+--- openjdk6/hotspot/src/share/tools/MakeDeps/Macro.java	2008-08-28 10:23:06.000000000 +0200
++++ openjdk/hotspot/src/share/tools/MakeDeps/Macro.java	2007-12-14 08:57:02.000000000 +0100
+@@ -26,4 +26,3 @@
+     public String name;
+     public String contents;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/tools/MakeDeps/Platform.java openjdk/hotspot/src/share/tools/MakeDeps/Platform.java
+--- openjdk6/hotspot/src/share/tools/MakeDeps/Platform.java	2008-08-28 10:23:06.000000000 +0200
++++ openjdk/hotspot/src/share/tools/MakeDeps/Platform.java	2007-12-14 08:57:02.000000000 +0100
+@@ -169,7 +169,7 @@
+ 
+     /** max is 31 on mac, so warn */
+     public int fileNameLengthLimit() {
+-	return 40;
++        return 45;
+     }
+ 
+     public int defaultGrandIncludeThreshold() {
+diff -ruNb openjdk6/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC6.java openjdk/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC6.java
+--- openjdk6/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC6.java	2008-08-28 10:23:06.000000000 +0200
++++ openjdk/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC6.java	2007-12-14 08:57:02.000000000 +0100
+@@ -236,7 +236,7 @@
+ 	       "                /nologo /base:\"0x8000000\" /subsystem:windows /dll" +
+ 	       "                /export:JNI_GetDefaultJavaVMInitArgs /export:JNI_CreateJavaVM /export:JNI_GetCreatedJavaVMs "+ 
+ 	       "                /export:jio_snprintf /export:jio_printf /export:jio_fprintf /export:jio_vfprintf "+
+-	       "                /export:jio_vsnprintf /export:JVM_EnqueueOperation ");
++               "                /export:jio_vsnprintf ");
+ 	rv.add("SUBTRACT LINK32 /pdb:none /map");
+ 
+ 	return rv;
+diff -ruNb openjdk6/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC7.java openjdk/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC7.java
+--- openjdk6/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC7.java	2008-08-28 10:23:06.000000000 +0200
++++ openjdk/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC7.java	2007-12-14 08:57:02.000000000 +0100
+@@ -262,6 +262,8 @@
+ 
+ 	rv.add(new SpecificNameFilter("JVMTI Generated", new String[] {"^jvmti.+"}));
+ 	
++        rv.add(new SpecificNameFilter("C++ Interpreter Generated", new String[] {"^bytecodeInterpreterWithChecks.+"}));
++
+ 	rv.add(new SpecificNameFilter("Include DBs", new String[] {"^includeDB_.+"}));
+ 
+ 	// this one is to catch files not caught by other filters
+@@ -574,8 +576,7 @@
+ 		"/export:JNI_GetCreatedJavaVMs "+
+ 		"/export:jio_snprintf /export:jio_printf "+
+ 		"/export:jio_fprintf /export:jio_vfprintf "+
+-		"/export:jio_vsnprintf "+
+-		"/export:JVM_EnqueueOperation ");	
++                "/export:jio_vsnprintf ");
+ 	addAttr(rv, "AdditionalDependencies", "Wsock32.lib winmm.lib");
+ 	addAttr(rv, "OutputFile", outDll);
+         addAttr(rv, "LinkIncremental", "1");
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/adlc.hpp openjdk/hotspot/src/share/vm/adlc/adlc.hpp
+--- openjdk6/hotspot/src/share/vm/adlc/adlc.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/adlc.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)adlc.hpp	1.28 07/05/05 17:04:59 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/adlparse.cpp openjdk/hotspot/src/share/vm/adlc/adlparse.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/adlparse.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/adlparse.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)adlparse.cpp	1.205 07/05/05 17:05:00 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/adlparse.hpp openjdk/hotspot/src/share/vm/adlc/adlparse.hpp
+--- openjdk6/hotspot/src/share/vm/adlc/adlparse.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/adlparse.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)adlparse.hpp	1.79 07/05/05 17:05:00 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -273,5 +270,3 @@
+   static bool is_int_token(const char* token, int& intval);
+   static void trim(char* &token);  // trim leading & trailing spaces
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/archDesc.cpp openjdk/hotspot/src/share/vm/adlc/archDesc.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/archDesc.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/archDesc.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -22,6 +22,7 @@
+ //  
+ //
+ 
++
+ // archDesc.cpp - Internal format for architecture definition
+ #include "adlc.hpp"
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/arena.cpp openjdk/hotspot/src/share/vm/adlc/arena.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/arena.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/arena.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)arena.cpp	1.16 07/05/05 17:05:00 JVM"
+-#endif
+ /*
+  * Copyright 1998-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -173,4 +170,3 @@
+ void CHeapObj::operator delete(void* p){
+  free(p);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/arena.hpp openjdk/hotspot/src/share/vm/adlc/arena.hpp
+--- openjdk6/hotspot/src/share/vm/adlc/arena.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/arena.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)arena.hpp	1.17 07/05/05 17:05:00 JVM"
+-#endif
+ /*
+  * Copyright 1998-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -158,4 +155,3 @@
+   size_t size_in_bytes() const         {  return _size_in_bytes; }
+   void   set_size_in_bytes(size_t size)  { _size_in_bytes = size;   }
+ }; 
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/dfa.cpp openjdk/hotspot/src/share/vm/adlc/dfa.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/dfa.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/dfa.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)dfa.cpp	1.83 07/05/05 17:04:59 JVM"
+-#endif
+ /*
+  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1022,4 +1019,3 @@
+ void ProductionState::print() {
+   _production.print(print_key, print_production);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/dict2.cpp openjdk/hotspot/src/share/vm/adlc/dict2.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/dict2.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/dict2.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)dict2.cpp	1.19 07/05/05 17:04:59 JVM"
+-#endif
+ /*
+  * Copyright 1998-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -354,5 +351,3 @@
+   }
+   _key = _value = NULL;
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/dict2.hpp openjdk/hotspot/src/share/vm/adlc/dict2.hpp
+--- openjdk6/hotspot/src/share/vm/adlc/dict2.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/dict2.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)dict2.hpp	1.16 07/05/05 17:05:01 JVM"
+-#endif
+ /*
+  * Copyright 1998-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -121,5 +118,3 @@
+ };
+ 
+ #endif // _DICT_
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/filebuff.cpp openjdk/hotspot/src/share/vm/adlc/filebuff.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/filebuff.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/filebuff.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)filebuff.cpp	1.30 07/05/05 17:05:01 JVM"
+-#endif
+ /*
+  * Copyright 1997-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -297,4 +294,3 @@
+   va_end(args);
+   _AD._no_output = 1;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/filebuff.hpp openjdk/hotspot/src/share/vm/adlc/filebuff.hpp
+--- openjdk6/hotspot/src/share/vm/adlc/filebuff.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/filebuff.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)filebuff.hpp	1.27 07/05/05 17:05:01 JVM"
+-#endif
+ /*
+  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/forms.cpp openjdk/hotspot/src/share/vm/adlc/forms.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/forms.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/forms.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)forms.cpp	1.161 07/05/05 17:04:59 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -386,4 +383,3 @@
+ void SourceForm::output(FILE *fp) {
+   fprintf(fp,"\n//%s\n%s\n",classname(),(_code?_code:"")); 
+ } 
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/forms.hpp openjdk/hotspot/src/share/vm/adlc/forms.hpp
+--- openjdk6/hotspot/src/share/vm/adlc/forms.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/forms.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)forms.hpp	1.150 07/05/05 17:05:00 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -587,6 +584,3 @@
+   void print_asserts(FILE *fp);
+   void dump();
+ };
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/formsopt.cpp openjdk/hotspot/src/share/vm/adlc/formsopt.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/formsopt.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/formsopt.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)formsopt.cpp	1.53 07/05/05 17:05:01 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -725,4 +722,3 @@
+ void PeepReplace::output(FILE *fp) {      // Write info to output files
+   fprintf(fp,"PeepReplace:\n");
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/formsopt.hpp openjdk/hotspot/src/share/vm/adlc/formsopt.hpp
+--- openjdk6/hotspot/src/share/vm/adlc/formsopt.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/formsopt.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)formsopt.hpp	1.54 07/05/05 17:05:01 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -549,4 +546,3 @@
+   void dump();
+   void output(FILE *fp);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/formssel.cpp openjdk/hotspot/src/share/vm/adlc/formssel.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/formssel.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/formssel.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)formssel.cpp	1.183 07/09/06 15:24:29 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -236,23 +233,58 @@
+   return _matrule ? _matrule->is_ideal_copy() : 0;
+ }
+ 
+-// Return 'true' if this instruction matches an ideal 'CosD' node
++// Return 'true' if this instruction is too complex to rematerialize.
+ int InstructForm::is_expensive() const {
+-  if (_matrule == NULL)  return 0;
+   // We can prove it is cheap if it has an empty encoding.
+   // This helps with platform-specific nops like ThreadLocal and RoundFloat.
++  if (is_empty_encoding())
++    return 0;
++
++  if (is_tls_instruction())
++    return 1;
++
++  if (_matrule == NULL)  return 0;
++
++  return _matrule->is_expensive();
++}
++
++// Has an empty encoding if _size is a constant zero or there
++// are no ins_encode tokens.
++int InstructForm::is_empty_encoding() const {
+   if (_insencode != NULL) {
+     _insencode->reset();
+     if (_insencode->encode_class_iter() == NULL) {
+-      return 0;
++      return 1;
+     }
+   }
+   if (_size != NULL && strcmp(_size, "0") == 0) {
++    return 1;
++  }
+     return 0;
++}
++
++int InstructForm::is_tls_instruction() const {
++  if (_ident != NULL &&
++      ( ! strcmp( _ident,"tlsLoadP") ||
++        ! strncmp(_ident,"tlsLoadP_",9)) ) {
++    return 1;
+   }
+-  return _matrule->is_expensive();
++
++  if (_matrule != NULL && _insencode != NULL) {
++    const char* opType = _matrule->_opType;
++    if (strcmp(opType, "Set")==0)
++      opType = _matrule->_rChild->_opType;
++    if (strcmp(opType,"ThreadLocal")==0) {
++      fprintf(stderr, "Warning: ThreadLocal instruction %s should be named 'tlsLoadP_*'\n",
++              (_ident == NULL ? "NULL" : _ident));
++      return 1;
++    }
++  }
++
++  return 0;
+ }
+ 
++
+ // Return 'true' if this instruction matches an ideal 'Copy*' node
+ bool InstructForm::is_ideal_unlock() const {
+   return _matrule ? _matrule->is_ideal_unlock() : false;
+@@ -492,6 +524,10 @@
+   if( _components.count() == 1 && _components[0]->is(Component::USE_DEF) ) 
+     rematerialize = true;
+ 
++  // Pseudo-constants (values easily available to the runtime)
++  if (is_empty_encoding() && is_tls_instruction())
++    rematerialize = true;
++
+   // 1-input, 1-output, such as copies or increments.
+   if( _components.count() == 2 && 
+       _components[0]->is(Component::DEF) && 
+@@ -1171,9 +1207,9 @@
+     // Output the format call for this operand
+     fprintf(fp,"opnd_array(%d)->",idx);
+     if (idx == 0) 
+-      fprintf(fp,"int_format(ra, this); // %s\n", rep_var);
++      fprintf(fp,"int_format(ra, this, st); // %s\n", rep_var);
+     else
+-      fprintf(fp,"ext_format(ra, this,idx%d); // %s\n", idx, rep_var );
++      fprintf(fp,"ext_format(ra, this,idx%d, st); // %s\n", idx, rep_var );
+   }
+ }
+ 
+@@ -2329,11 +2365,11 @@
+ 
+ void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) {
+   switch(const_type) {
+-  case Form::idealI: fprintf(fp,"tty->print(\"#%%d\", _c%d);\n", const_index); break;
+-  case Form::idealP: fprintf(fp,"_c%d->dump();\n",               const_index); break;
+-  case Form::idealL: fprintf(fp,"tty->print(\"#%%lld\", _c%d);\n", const_index); break;
+-  case Form::idealF: fprintf(fp,"tty->print(\"#%%f\", _c%d);\n", const_index); break;
+-  case Form::idealD: fprintf(fp,"tty->print(\"#%%f\", _c%d);\n", const_index); break;
++  case Form::idealI: fprintf(fp,"st->print(\"#%%d\", _c%d);\n", const_index); break;
++  case Form::idealP: fprintf(fp,"_c%d->dump_on(st);\n",         const_index); break;
++  case Form::idealL: fprintf(fp,"st->print(\"#%%lld\", _c%d);\n", const_index); break;
++  case Form::idealF: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break;
++  case Form::idealD: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break;
+   default:
+     assert( false, "ShouldNotReachHere()");
+   }
+@@ -3725,6 +3761,17 @@
+ int MatchRule::is_ideal_copy() const {
+   if( _rChild ) {
+     const char  *opType = _rChild->_opType;
++    if( strcmp(opType,"CastII")==0 )
++      return 1;
++    // Do not treat *CastPP this way, because it
++    // may transfer a raw pointer to an oop.
++    // If the register allocator were to coalesce this
++    // into a single LRG, the GC maps would be incorrect.
++    //if( strcmp(opType,"CastPP")==0 )
++    //  return 1;
++    //if( strcmp(opType,"CheckCastPP")==0 )
++    //  return 1;
++    //
+     // Do not treat CastX2P or CastP2X this way, because
+     // raw pointers and int types are treated differently
+     // when saving local & stack info for safepoints in 
+@@ -3773,7 +3820,6 @@
+         strcmp(opType,"ConvL2I")==0 ||
+         strcmp(opType,"RoundDouble")==0 ||
+         strcmp(opType,"RoundFloat")==0 ||
+-        strcmp(opType,"ThreadLocal")==0 ||
+         strcmp(opType,"ReverseBytesI")==0 ||
+         strcmp(opType,"ReverseBytesL")==0 ||
+         strcmp(opType,"Replicate16B")==0 ||
+@@ -3951,4 +3997,3 @@
+   fprintf(fp,"\nFormat Rule: \n%s", (_temp?_temp:""));
+   fprintf(fp,"\n");
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/formssel.hpp openjdk/hotspot/src/share/vm/adlc/formssel.hpp
+--- openjdk6/hotspot/src/share/vm/adlc/formssel.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/formssel.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)formssel.hpp	1.76 07/05/17 15:49:19 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -139,6 +136,8 @@
+   // ideal opcode enumeration
+   virtual const char *ideal_Opcode(FormDict &globals)  const; 
+   virtual int         is_expensive() const;     // node matches ideal 'CosD'
++  virtual int         is_empty_encoding() const; // _size=0 and/or _insencode empty
++  virtual int         is_tls_instruction() const; // tlsLoadP rule or ideal ThreadLocal
+   virtual int         is_ideal_copy() const;    // node matches ideal 'Copy*'
+   virtual bool        is_ideal_unlock() const;  // node matches ideal 'Unlock'
+   virtual bool        is_ideal_call_leaf() const; // node matches ideal 'CallLeaf'
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/output_c.cpp openjdk/hotspot/src/share/vm/adlc/output_c.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/output_c.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/output_c.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)output_c.cpp	1.184 07/05/17 15:49:23 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -2199,7 +2196,7 @@
+   const char* reg_conversion(const char* rep_var) {
+     if (strcmp(rep_var,"$Register") == 0)      return "as_Register";
+     if (strcmp(rep_var,"$FloatRegister") == 0) return "as_FloatRegister";
+-#if defined(IA32)
++#if defined(IA32) || defined(AMD64)
+     if (strcmp(rep_var,"$XMMRegister") == 0)   return "as_XMMRegister";
+ #endif
+     return NULL;
+diff -ruNb openjdk6/hotspot/src/share/vm/adlc/output_h.cpp openjdk/hotspot/src/share/vm/adlc/output_h.cpp
+--- openjdk6/hotspot/src/share/vm/adlc/output_h.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/adlc/output_h.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)output_h.cpp	1.178 07/05/05 17:05:03 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -345,34 +342,34 @@
+ 
+ // Generate the format rule for condition codes
+ static void defineCCodeDump(FILE *fp, int i) {
+-  fprintf(fp, "         if( _c%d == BoolTest::eq ) tty->print(\"eq\");\n",i);
+-  fprintf(fp, "    else if( _c%d == BoolTest::ne ) tty->print(\"ne\");\n",i);
+-  fprintf(fp, "    else if( _c%d == BoolTest::le ) tty->print(\"le\");\n",i);
+-  fprintf(fp, "    else if( _c%d == BoolTest::ge ) tty->print(\"ge\");\n",i);
+-  fprintf(fp, "    else if( _c%d == BoolTest::lt ) tty->print(\"lt\");\n",i);
+-  fprintf(fp, "    else if( _c%d == BoolTest::gt ) tty->print(\"gt\");\n",i);
++  fprintf(fp, "         if( _c%d == BoolTest::eq ) st->print(\"eq\");\n",i);
++  fprintf(fp, "    else if( _c%d == BoolTest::ne ) st->print(\"ne\");\n",i);
++  fprintf(fp, "    else if( _c%d == BoolTest::le ) st->print(\"le\");\n",i);
++  fprintf(fp, "    else if( _c%d == BoolTest::ge ) st->print(\"ge\");\n",i);
++  fprintf(fp, "    else if( _c%d == BoolTest::lt ) st->print(\"lt\");\n",i);
++  fprintf(fp, "    else if( _c%d == BoolTest::gt ) st->print(\"gt\");\n",i);
+ }
+ 
+ // Output code that dumps constant values, increment "i" if type is constant
+ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
+   if (!strcmp(ideal_type, "ConI")) {
+-    fprintf(fp,"   tty->print(\"#%%d\", _c%d);\n", i);
++    fprintf(fp,"   st->print(\"#%%d\", _c%d);\n", i);
+     ++i;
+   }
+   else if (!strcmp(ideal_type, "ConP")) {
+-    fprintf(fp,"    _c%d->dump();\n", i);
++    fprintf(fp,"    _c%d->dump_on(st);\n", i);
+     ++i;
+   }
+   else if (!strcmp(ideal_type, "ConL")) {
+-    fprintf(fp,"    tty->print(\"#\" INT64_FORMAT, _c%d);\n", i);
++    fprintf(fp,"    st->print(\"#\" INT64_FORMAT, _c%d);\n", i);
+     ++i;
+   }
+   else if (!strcmp(ideal_type, "ConF")) {
+-    fprintf(fp,"    tty->print(\"#%%f\", _c%d);\n", i);
++    fprintf(fp,"    st->print(\"#%%f\", _c%d);\n", i);
+     ++i;
+   }
+   else if (!strcmp(ideal_type, "ConD")) {
+-    fprintf(fp,"    tty->print(\"#%%f\", _c%d);\n", i);
++    fprintf(fp,"    st->print(\"#%%f\", _c%d);\n", i);
+     ++i;
+   }
+   else if (!strcmp(ideal_type, "Bool")) {
+@@ -388,8 +385,8 @@
+   if (!for_c_file) {
+     // invoked after output #ifndef PRODUCT to ad_<arch>.hpp 
+     // compile the bodies separately, to cut down on recompilations
+-    fprintf(fp,"  virtual void           int_format(PhaseRegAlloc *ra, const MachNode *node) const;\n");
+-    fprintf(fp,"  virtual void           ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx) const;\n");
++    fprintf(fp,"  virtual void           int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const;\n");
++    fprintf(fp,"  virtual void           ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const;\n");
+     return;
+   }
+ 
+@@ -398,7 +395,7 @@
+ 
+   // Generate internal format function, used when stored locally
+   fprintf(fp, "\n#ifndef PRODUCT\n");
+-  fprintf(fp,"void %sOper::int_format(PhaseRegAlloc *ra, const MachNode *node) const {\n", oper._ident);
++  fprintf(fp,"void %sOper::int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const {\n", oper._ident);
+   // Generate the user-defined portion of the format
+   if (oper._format) {
+     if ( oper._format->_strings.count() != 0 ) {
+@@ -414,8 +411,8 @@
+         // Check if this is a standard string or a replacement variable
+         if ( string != NameList::_signal ) {
+           // Normal string
+-          // Pass through to tty->print
+-          fprintf(fp,"tty->print(\"%s\");\n", string);
++          // Pass through to st->print
++          fprintf(fp,"st->print(\"%s\");\n", string);
+         } else {
+           // Replacement variable
+           const char *rep_var = oper._format->_rep_vars.iter();
+@@ -450,7 +447,7 @@
+   } else { // oper._format == NULL
+     // Provide a few special case formats where the AD writer cannot.
+     if ( strcmp(oper._ident,"Universe")==0 ) {
+-      fprintf(fp, "  tty->print(\"$$univ\");\n");
++      fprintf(fp, "  st->print(\"$$univ\");\n");
+     }
+     // labelOper::int_format is defined in ad_<...>.cpp
+   }
+@@ -461,7 +458,7 @@
+   fprintf(fp,"}\n");
+ 
+   // Generate external format function, when data is stored externally
+-  fprintf(fp,"void %sOper::ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx) const {\n", oper._ident);
++  fprintf(fp,"void %sOper::ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const {\n", oper._ident);
+   // Generate the user-defined portion of the format
+   if (oper._format) {
+     if ( oper._format->_strings.count() != 0 ) {
+@@ -481,8 +478,8 @@
+         // Check if this is a standard string or a replacement variable
+         if ( string != NameList::_signal ) {
+           // Normal string
+-          // Pass through to tty->print
+-          fprintf(fp,"tty->print(\"%s\");\n", string);
++          // Pass through to st->print
++          fprintf(fp,"st->print(\"%s\");\n", string);
+         } else {
+           // Replacement variable
+           const char *rep_var = oper._format->_rep_vars.iter();
+@@ -518,7 +515,7 @@
+   } else { // oper._format == NULL
+     // Provide a few special case formats where the AD writer cannot.
+     if ( strcmp(oper._ident,"Universe")==0 ) {
+-      fprintf(fp, "  tty->print(\"$$univ\");\n");
++      fprintf(fp, "  st->print(\"$$univ\");\n");
+     }
+     // labelOper::ext_format is defined in ad_<...>.cpp
+   }
+@@ -536,13 +533,13 @@
+   if (!for_c_file) {
+     // compile the bodies separately, to cut down on recompilations
+     // #ifndef PRODUCT region generated by caller 
+-    fprintf(fp,"  virtual void           format(PhaseRegAlloc *ra) const;\n");
++    fprintf(fp,"  virtual void           format(PhaseRegAlloc *ra, outputStream *st) const;\n");
+     return;
+   }
+ 
+   // Define the format function
+   fprintf(fp, "#ifndef PRODUCT\n");
+-  fprintf(fp, "void %sNode::format(PhaseRegAlloc *ra) const {\n", inst._ident);
++  fprintf(fp, "void %sNode::format(PhaseRegAlloc *ra, outputStream *st) const {\n", inst._ident);
+ 
+   // Generate the user-defined portion of the format
+   if( inst._format ) {
+@@ -559,7 +556,7 @@
+       fprintf(fp,"    ");
+       // Check if this is a standard string or a replacement variable
+       if( string != NameList::_signal )  // Normal string.  Pass through.
+-        fprintf(fp,"tty->print(\"%s\");\n", string);
++        fprintf(fp,"st->print(\"%s\");\n", string);
+       else			// Replacement variable
+ 	inst.rep_var_format( fp, inst._format->_rep_vars.iter() );
+     } // Done with all format strings
+@@ -573,8 +570,8 @@
+       fprintf(fp,"    _method->print_short_name();\n");
+       break;
+     case Form::JAVA_STATIC:
+-      fprintf(fp,"    if( _method ) _method->print_short_name(); else tty->print(\" wrapper for: %%s\", _name);\n");
+-      fprintf(fp,"    if( !_method ) dump_trap_args();\n");
++      fprintf(fp,"    if( _method ) _method->print_short_name(st); else st->print(\" wrapper for: %%s\", _name);\n");
++      fprintf(fp,"    if( !_method ) dump_trap_args(st);\n");
+       break;
+     case Form::JAVA_COMPILED:
+     case Form::JAVA_INTERP:
+@@ -582,38 +579,38 @@
+     case Form::JAVA_RUNTIME:
+     case Form::JAVA_LEAF:
+     case Form::JAVA_NATIVE:
+-      fprintf(fp,"    tty->print(\" %%s\", _name);");
++      fprintf(fp,"    st->print(\" %%s\", _name);");
+       break;
+     default: 
+       assert(0,"ShouldNotReacHere");
+     }
+-    fprintf(fp,  "    tty->print_cr(\"\");\n" );
+-    fprintf(fp,  "    if (_jvms) _jvms->format(ra, this); else tty->print_cr(\"        No JVM State Info\");\n" );
+-    fprintf(fp,  "    tty->print(\"        # \");\n" );
+-    fprintf(fp,  "    if( _jvms ) _oop_map->print();\n");
++    fprintf(fp,  "    st->print_cr(\"\");\n" );
++    fprintf(fp,  "    if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\"        No JVM State Info\");\n" );
++    fprintf(fp,  "    st->print(\"        # \");\n" );
++    fprintf(fp,  "    if( _jvms ) _oop_map->print_on(st);\n");
+   }
+   else if(inst.is_ideal_safepoint()) {
+-    fprintf(fp,  "    tty->print(\"\");\n" );
+-    fprintf(fp,  "    if (_jvms) _jvms->format(ra, this); else tty->print_cr(\"        No JVM State Info\");\n" );
+-    fprintf(fp,  "    tty->print(\"        # \");\n" );
+-    fprintf(fp,  "    if( _jvms ) _oop_map->print();\n");
++    fprintf(fp,  "    st->print(\"\");\n" );
++    fprintf(fp,  "    if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\"        No JVM State Info\");\n" );
++    fprintf(fp,  "    st->print(\"        # \");\n" );
++    fprintf(fp,  "    if( _jvms ) _oop_map->print_on(st);\n");
+   }
+   else if( inst.is_ideal_if() ) {
+-    fprintf(fp,  "    tty->print(\"  P=%%f C=%%f\",_prob,_fcnt);\n" );
++    fprintf(fp,  "    st->print(\"  P=%%f C=%%f\",_prob,_fcnt);\n" );
+   }
+   else if( inst.is_ideal_mem() ) {
+     // Print out the field name if available to improve readability
+     fprintf(fp,  "    if (ra->C->alias_type(adr_type())->field() != NULL) {\n");
+-    fprintf(fp,  "      tty->print(\" ! Field \");\n");
++    fprintf(fp,  "      st->print(\" ! Field \");\n");
+     fprintf(fp,  "      if( ra->C->alias_type(adr_type())->is_volatile() )\n");
+-    fprintf(fp,  "        tty->print(\" Volatile\");\n");
+-    fprintf(fp,  "      ra->C->alias_type(adr_type())->field()->holder()->name()->print_symbol_on(tty);\n");
+-    fprintf(fp,  "      tty->print(\".\");\n");
+-    fprintf(fp,  "      ra->C->alias_type(adr_type())->field()->name()->print_symbol_on(tty);\n");
++    fprintf(fp,  "        st->print(\" Volatile\");\n");
++    fprintf(fp,  "      ra->C->alias_type(adr_type())->field()->holder()->name()->print_symbol_on(st);\n");
++    fprintf(fp,  "      st->print(\".\");\n");
++    fprintf(fp,  "      ra->C->alias_type(adr_type())->field()->name()->print_symbol_on(st);\n");
+     fprintf(fp,  "    } else\n");
+     // Make sure 'Volatile' gets printed out
+     fprintf(fp,  "    if( ra->C->alias_type(adr_type())->is_volatile() )\n");
+-    fprintf(fp,  "      tty->print(\" Volatile!\");\n");
++    fprintf(fp,  "      st->print(\" Volatile!\");\n");
+   }
+ 
+   // Complete the definition of the format function
+@@ -1353,15 +1350,15 @@
+     // IF we have constants, create a dump_spec function for the derived class
+     //
+     // (1)  virtual void           dump_spec() const { 
+-    // (2)    tty->print("#%d", _c#);        // Constant != ConP
+-    //  OR    _c#->dump();                   // Type ConP
++    // (2)    st->print("#%d", _c#);        // Constant != ConP
++    //  OR    _c#->dump_on(st);             // Type ConP
+     //  ...
+     // (3)  }
+     uint num_consts = oper->num_consts(_globalNames);
+     if( num_consts > 0 ) {
+       // line (1)
+-      fprintf(fp, "  virtual void           dump_spec() const {\n");
+-      // generate format string for tty->print
++      fprintf(fp, "  virtual void           dump_spec(outputStream *st) const {\n");
++      // generate format string for st->print
+       // Iterate over the component list & spit out the right thing
+       uint i = 0;
+       const char *type = oper->ideal_type(_globalNames);
+@@ -1817,9 +1814,7 @@
+       // legal base-pointer input.  Otherwise it is NOT an oop.
+       fprintf(fp,"  const Type *bottom_type() const { return AddPNode::mach_bottom_type(this); } // AddP\n");
+     }
+-    else if ( instr->_ident && ( ! strcmp(instr->_ident,"tlsLoadP")
+-				 || ! strncmp(instr->_ident,"tlsLoadP_",9)) ) {
+-      // !!!!! 
++    else if (instr->is_tls_instruction()) {
+       // Special hack for tlsLoadP 
+       fprintf(fp,"  const Type            *bottom_type() const { return TypeRawPtr::BOTTOM; } // tlsLoadP\n");
+     }
+diff -ruNb openjdk6/hotspot/src/share/vm/asm/assembler.cpp openjdk/hotspot/src/share/vm/asm/assembler.cpp
+--- openjdk6/hotspot/src/share/vm/asm/assembler.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/asm/assembler.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)assembler.cpp	1.41 07/05/05 17:05:03 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/asm/assembler.hpp openjdk/hotspot/src/share/vm/asm/assembler.hpp
+--- openjdk6/hotspot/src/share/vm/asm/assembler.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/asm/assembler.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)assembler.hpp	1.52 07/05/05 17:05:03 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/asm/assembler.inline.hpp openjdk/hotspot/src/share/vm/asm/assembler.inline.hpp
+--- openjdk6/hotspot/src/share/vm/asm/assembler.inline.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/asm/assembler.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)assembler.inline.hpp	1.27 07/05/05 17:05:03 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/asm/codeBuffer.cpp openjdk/hotspot/src/share/vm/asm/codeBuffer.cpp
+--- openjdk6/hotspot/src/share/vm/asm/codeBuffer.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/asm/codeBuffer.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)codeBuffer.cpp	1.100 07/05/05 17:05:03 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/asm/codeBuffer.hpp openjdk/hotspot/src/share/vm/asm/codeBuffer.hpp
+--- openjdk6/hotspot/src/share/vm/asm/codeBuffer.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/asm/codeBuffer.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)codeBuffer.hpp	1.63 07/05/17 15:49:26 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -543,4 +540,3 @@
+   if (remaining() < amount) { _outer->expand(this, amount); return true; }
+   return false;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/asm/register.cpp openjdk/hotspot/src/share/vm/asm/register.cpp
+--- openjdk6/hotspot/src/share/vm/asm/register.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/asm/register.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)register.cpp	1.11 07/05/05 17:05:04 JVM"
+-#endif
+ /*
+  * Copyright 2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/asm/register.hpp openjdk/hotspot/src/share/vm/asm/register.hpp
+--- openjdk6/hotspot/src/share/vm/asm/register.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/asm/register.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)register.hpp	1.13 07/05/05 17:05:03 JVM"
+-#endif
+ /*
+  * Copyright 2000-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp openjdk/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_Canonicalizer.cpp	1.57 07/05/05 17:05:05 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp openjdk/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_Canonicalizer.hpp	1.29 07/05/05 17:05:05 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -97,4 +94,3 @@
+   virtual void do_ProfileCall    (ProfileCall*     x);
+   virtual void do_ProfileCounter (ProfileCounter*  x);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp openjdk/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_CFGPrinter.cpp	1.8 07/05/05 17:05:04 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp openjdk/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_CFGPrinter.hpp	1.7 07/05/05 17:05:05 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -47,4 +44,3 @@
+ };
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_CodeStubs.hpp openjdk/hotspot/src/share/vm/c1/c1_CodeStubs.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_CodeStubs.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_CodeStubs.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_CodeStubs.hpp	1.86 07/05/05 17:05:06 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -485,4 +482,3 @@
+   virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); }
+ #endif // PRODUCT
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Compilation.cpp openjdk/hotspot/src/share/vm/c1/c1_Compilation.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Compilation.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Compilation.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_Compilation.cpp	1.159 07/05/17 15:49:28 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -290,13 +287,16 @@
+ }
+ 
+ void Compilation::install_code(int frame_size) {
++  // frame_size is in 32-bit words so adjust it intptr_t words
++  assert(frame_size == frame_map()->framesize(), "must match");
++  assert(in_bytes(frame_map()->framesize_in_bytes()) % sizeof(intptr_t) == 0, "must be at least pointer aligned");
+   _env->register_method(
+     method(),
+     osr_bci(),
+     &_offsets,
+     in_bytes(_frame_map->sp_offset_for_orig_pc()),
+     code(),
+-    frame_size,
++    in_bytes(frame_map()->framesize_in_bytes()) / sizeof(intptr_t),
+     debug_info_recorder()->_oopmaps,
+     exception_handler_table(),
+     implicit_exception_table(),
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Compilation.hpp openjdk/hotspot/src/share/vm/c1/c1_Compilation.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Compilation.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Compilation.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_Compilation.hpp	1.88 07/05/17 15:49:31 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Compiler.cpp openjdk/hotspot/src/share/vm/c1/c1_Compiler.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Compiler.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Compiler.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_Compiler.cpp	1.105 07/05/05 17:05:06 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -89,5 +86,3 @@
+ void Compiler::print_timers() {
+   Compilation::print_timers();
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Compiler.hpp openjdk/hotspot/src/share/vm/c1/c1_Compiler.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Compiler.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Compiler.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_Compiler.hpp	1.49 07/05/05 17:05:06 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -68,4 +65,3 @@
+   // Print compilation timers and statistics
+   virtual void print_timers();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Defs.cpp openjdk/hotspot/src/share/vm/c1/c1_Defs.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Defs.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Defs.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_Defs.cpp	1.10 07/05/05 17:05:06 JVM"
+-#endif
+ /*
+  * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -27,4 +24,3 @@
+ 
+ #include "incls/_precompiled.incl"
+ #include "incls/_c1_Defs.cpp.incl"
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Defs.hpp openjdk/hotspot/src/share/vm/c1/c1_Defs.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Defs.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Defs.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_Defs.hpp	1.22 07/05/05 17:05:05 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_FpuStackSim.hpp openjdk/hotspot/src/share/vm/c1/c1_FpuStackSim.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_FpuStackSim.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_FpuStackSim.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_FpuStackSim.hpp	1.7 07/05/05 17:05:06 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -30,4 +27,3 @@
+ class FpuStackSim;
+ 
+ # include "incls/_c1_FpuStackSim_pd.hpp.incl"  // platform dependent declarations
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_FrameMap.cpp openjdk/hotspot/src/share/vm/c1/c1_FrameMap.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_FrameMap.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_FrameMap.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_FrameMap.cpp	1.37 07/05/05 17:05:06 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -83,7 +80,8 @@
+     args->append(opr);
+     if (opr->is_address()) {
+       LIR_Address* addr = opr->as_address_ptr();
+-      out_preserve = MAX2(out_preserve, addr->disp() / 4);
++      assert(addr->disp() == (int)addr->disp(), "out of range value");
++      out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4);
+     }
+     i += type2size[t];
+   }
+@@ -128,10 +126,13 @@
+     // C calls are always outgoing
+     bool outgoing = true;
+     LIR_Opr opr = map_to_opr(t, regs + i, outgoing);
++    // they might be of different types if for instance floating point
++    // values are passed in cpu registers, but the sizes must match.
++    assert(type2size[opr->type()] == type2size[t], "type mismatch");
+     args->append(opr);
+     if (opr->is_address()) {
+       LIR_Address* addr = opr->as_address_ptr();
+-      out_preserve = MAX2(out_preserve, addr->disp() / 4);
++      out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4);
+     }
+     i += type2size[t];
+   }
+@@ -172,7 +173,7 @@
+     LIR_Opr opr = _incoming_arguments->at(i);
+     if (opr->is_address()) {
+       LIR_Address* address = opr->as_address_ptr();
+-      _argument_locations->at_put(java_index, address->disp());
++      _argument_locations->at_put(java_index, address->disp() - STACK_BIAS);
+       _incoming_arguments->args()->at_put(i, LIR_OprFact::stack(java_index, as_BasicType(as_ValueType(address->type()))));
+     }
+     java_index += type2size[opr->type()];
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_FrameMap.hpp openjdk/hotspot/src/share/vm/c1/c1_FrameMap.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_FrameMap.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_FrameMap.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_FrameMap.hpp	1.59 07/05/05 17:05:07 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_globals.cpp openjdk/hotspot/src/share/vm/c1/c1_globals.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_globals.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_globals.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_globals.cpp	1.11 07/05/05 17:05:09 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_globals.hpp openjdk/hotspot/src/share/vm/c1/c1_globals.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_globals.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_globals.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_globals.hpp	1.104 07/05/05 17:05:10 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -333,4 +330,3 @@
+ // #include "incls/_c1_globals_pd.hpp.incl"
+ 
+ C1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_NOTPRODUCT_FLAG)
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp openjdk/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_GraphBuilder.cpp	1.255 07/05/17 15:49:34 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -88,8 +85,8 @@
+  , _blocks(16)
+  , _bci2block(new BlockList(scope->method()->code_size(), NULL))
+  , _next_block_number(0)
+- , _active(NULL, 0)         // size not known yet
+- , _visited(NULL, 0)        // size not known yet
++ , _active()         // size not known yet
++ , _visited()        // size not known yet
+  , _next_loop_index(0)
+  , _loop_map() // size not known yet
+ {
+@@ -413,7 +410,7 @@
+ 
+   if (block->is_set(BlockBegin::parser_loop_header_flag)) {
+     int header_loop_state = _loop_map.at(block_id);
+-    assert(is_power_of_2(header_loop_state), "exactly one bit must be set");
++    assert(is_power_of_2((unsigned)header_loop_state), "exactly one bit must be set");
+ 
+     // If the highest bit is set (i.e. when integer value is negative), the method 
+     // has 32 or more loops. This bit is never cleared because it is used for multiple loops
+@@ -3666,12 +3663,14 @@
+   _scope_data = scope_data()->parent();
+ }
+ 
+-
+ bool GraphBuilder::append_unsafe_get_obj(ciMethod* callee, BasicType t, bool is_volatile) {
+   if (InlineUnsafeOps) {
+     Values* args = state()->pop_arguments(callee->arg_size());
+     null_check(args->at(0));
+-    Instruction* offset = append(new Convert(Bytecodes::_l2i, args->at(2), as_ValueType(T_INT)));
++    Instruction* offset = args->at(2);
++#ifndef _LP64
++    offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
++#endif
+     Instruction* op = append(new UnsafeGetObject(t, args->at(1), offset, is_volatile));
+     push(op->type(), op);
+     compilation()->set_has_unsafe_access(true);
+@@ -3684,7 +3683,10 @@
+   if (InlineUnsafeOps) {
+     Values* args = state()->pop_arguments(callee->arg_size());
+     null_check(args->at(0));
+-    Instruction* offset = append(new Convert(Bytecodes::_l2i, args->at(2), as_ValueType(T_INT)));
++    Instruction* offset = args->at(2);
++#ifndef _LP64
++    offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
++#endif
+     Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile));
+     compilation()->set_has_unsafe_access(true);
+     kill_all();
+@@ -3725,7 +3727,10 @@
+     } else {
+       null_check(args->at(0));
+     }
+-    Instruction* offset = append(new Convert(Bytecodes::_l2i, args->at(obj_arg_index + 1), as_ValueType(T_INT)));
++    Instruction* offset = args->at(obj_arg_index + 1);
++#ifndef _LP64
++    offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
++#endif
+     Instruction* op = is_store ? append(new UnsafePrefetchWrite(args->at(obj_arg_index), offset))
+                                : append(new UnsafePrefetchRead (args->at(obj_arg_index), offset));
+     compilation()->set_has_unsafe_access(true);
+@@ -3742,7 +3747,7 @@
+   // Pop off some args to speically handle, then push back
+   Value newval = args->pop();
+   Value cmpval = args->pop();
+-  Value long_offset = args->pop();
++  Value offset = args->pop();
+   Value src = args->pop();
+   Value unsafe_obj = args->pop();
+ 
+@@ -3750,7 +3755,9 @@
+   // generation, but must be null checked
+   null_check(unsafe_obj);
+ 
+-  Instruction* offset = append(new Convert(Bytecodes::_l2i, long_offset, as_ValueType(T_INT)));
++#ifndef _LP64
++  offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
++#endif
+ 
+   args->push(src);
+   args->push(offset);
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp openjdk/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_GraphBuilder.hpp	1.75 07/05/17 15:49:37 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -391,4 +388,3 @@
+ 
+   BlockBegin* start() const                      { return _start; }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Instruction.cpp openjdk/hotspot/src/share/vm/c1/c1_Instruction.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Instruction.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Instruction.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_Instruction.cpp	1.90 07/05/05 17:05:05 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Instruction.hpp openjdk/hotspot/src/share/vm/c1/c1_Instruction.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Instruction.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Instruction.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_Instruction.hpp	1.195 07/05/05 17:05:07 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1528,16 +1525,16 @@
+   , _exception_handler_pco(-1)
+   , _lir(NULL)
+   , _loop_index(-1)
+-  , _live_in(NULL, 0)
+-  , _live_out(NULL, 0)
+-  , _live_gen(NULL, 0)
+-  , _live_kill(NULL, 0)
+-  , _fpu_register_usage(NULL, 0)
++  , _live_in()
++  , _live_out()
++  , _live_gen()
++  , _live_kill()
++  , _fpu_register_usage()
+   , _fpu_stack_state(NULL)
+   , _first_lir_instruction_id(-1)
+   , _last_lir_instruction_id(-1)
+   , _total_preds(0)
+-  , _stores_to_locals(NULL, 0)
++  , _stores_to_locals()
+   {
+     set_bci(bci);
+   }
+@@ -1962,7 +1959,11 @@
+ LEAF(OsrEntry, Instruction)
+  public:
+   // creation
++#ifdef _LP64
++  OsrEntry() : Instruction(longType, false) { pin(); }
++#else
+   OsrEntry() : Instruction(intType, false) { pin(); }
++#endif
+ 
+   // generic
+   virtual void input_values_do(void f(Value*))   { }
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp openjdk/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_InstructionPrinter.cpp	1.125 07/05/17 15:49:39 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -269,6 +266,8 @@
+ void InstructionPrinter::print_unsafe_object_op(UnsafeObjectOp* op, const char* name) {
+   print_unsafe_op(op, name);
+   print_value(op->object());
++  output()->print(", ");
++  print_value(op->offset());
+ }
+ 
+ 
+@@ -849,4 +848,3 @@
+ 
+ 
+ #endif // PRODUCT
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp openjdk/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_InstructionPrinter.hpp	1.65 07/05/05 17:05:07 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_IR.cpp openjdk/hotspot/src/share/vm/c1/c1_IR.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_IR.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_IR.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_IR.cpp	1.160 07/05/05 17:05:04 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_IR.hpp openjdk/hotspot/src/share/vm/c1/c1_IR.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_IR.hpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_IR.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_IR.hpp	1.100 07/05/05 17:05:04 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LinearScan.cpp openjdk/hotspot/src/share/vm/c1/c1_LinearScan.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_LinearScan.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_LinearScan.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_LinearScan.cpp	1.12 07/05/05 17:05:10 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -2547,8 +2544,8 @@
+   } else {
+     // double-size operands
+ 
+-    LocationValue* first;
+-    LocationValue* second;
++    ScopeValue* first;
++    ScopeValue* second;
+ 
+     if (opr->is_double_stack()) {
+       Location loc1, loc2;
+@@ -2559,6 +2556,11 @@
+       second = new LocationValue(loc2);
+ 
+     } else if (opr->is_double_cpu()) {
++#ifdef _LP64
++      VMReg rname_first = opr->as_register_lo()->as_VMReg();
++      first = new LocationValue(Location::new_reg_loc(Location::lng, rname_first));
++      second = &_int_0_scope_value;
++#else
+       VMReg rname_first = opr->as_register_lo()->as_VMReg();
+       VMReg rname_second = opr->as_register_hi()->as_VMReg();
+ 
+@@ -2571,6 +2573,7 @@
+ 
+       first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first));
+       second = new LocationValue(Location::new_reg_loc(Location::normal, rname_second));
++#endif
+ 
+ #ifdef IA32
+     } else if (opr->is_double_xmm()) {
+@@ -2862,15 +2865,21 @@
+     op->verify();
+ #endif
+ 
++#ifndef _LP64
+     // remove useless moves
+     if (op->code() == lir_move) {
+       assert(op->as_Op1() != NULL, "move must be LIR_Op1");
+       LIR_Op1* move = (LIR_Op1*)op;
+-      if (!move->result_opr()->is_pointer() && !move->in_opr()->is_pointer() && move->in_opr()->is_equivalent(move->result_opr()->with_type_of(move->in_opr()))) {
++      LIR_Opr src = move->in_opr();
++      LIR_Opr dst = move->result_opr();
++      if (dst == src ||
++          !dst->is_pointer() && !src->is_pointer() &&
++          src->is_same_register(dst)) {
+         instructions->at_put(j, NULL);
+         has_dead = true;
+       }
+     }
++#endif
+   }
+ 
+   if (has_dead) {
+@@ -6187,6 +6196,7 @@
+     case counter_move_reg_reg:    return "register->register";
+     case counter_move_reg_stack:  return "register->stack";
+     case counter_move_stack_reg:  return "stack->register";
++    case counter_move_stack_stack:return "stack->stack";
+     case counter_move_reg_mem:    return "register->memory";
+     case counter_move_mem_reg:    return "memory->register";
+     case counter_move_const_any:  return "constant->any";
+@@ -6333,8 +6343,11 @@
+               ShouldNotReachHere();
+             }
+           } else if (in->is_stack()) {
+-            assert(res->is_register(), "must be");
++            if (res->is_register()) {
+             inc_counter(counter_move_stack_reg);
++            } else {
++              inc_counter(counter_move_stack_stack);
++            }
+           } else if (in->is_address()) {
+             assert(res->is_register(), "must be");
+             inc_counter(counter_move_mem_reg);
+@@ -6379,7 +6392,6 @@
+         case lir_logic_or:
+         case lir_logic_xor:
+         case lir_shl:
+-        case lir_shlx:
+         case lir_shr:
+         case lir_ushr:            inc_counter(counter_alu); break;
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LinearScan.hpp openjdk/hotspot/src/share/vm/c1/c1_LinearScan.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_LinearScan.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_LinearScan.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_LinearScan.hpp	1.12 07/05/05 17:05:09 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -890,6 +887,7 @@
+     counter_move_reg_reg,
+     counter_move_reg_stack,
+     counter_move_stack_reg,
++    counter_move_stack_stack,
+     counter_move_reg_mem,
+     counter_move_mem_reg,
+     counter_move_const_any,
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp openjdk/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_LIRAssembler.cpp	1.133 07/05/05 17:05:08 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -218,7 +215,7 @@
+ #endif /* PRODUCT */
+ 
+   assert(block->lir() != NULL, "must have LIR");
+-  IA32_ONLY(assert(_masm->esp_offset() == 0, "frame size should be fixed"));
++  IA32_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed"));
+ 
+ #ifndef PRODUCT
+   if (CommentedAssembly) {
+@@ -230,7 +227,7 @@
+ 
+   emit_lir_list(block->lir());
+ 
+-  IA32_ONLY(assert(_masm->esp_offset() == 0, "frame size should be fixed"));
++  IA32_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed"));
+ }
+ 
+ 
+@@ -649,7 +646,6 @@
+       break;
+ 
+     case lir_shl:
+-    case lir_shlx:
+     case lir_shr:
+     case lir_ushr:
+       if (op->in_opr2()->is_constant()) {
+@@ -787,7 +783,7 @@
+           _masm->verify_oop(r->as_Register());
+ #endif
+         } else {
+-          _masm->verify_stack_oop(r->reg2stack() * wordSize);
++          _masm->verify_stack_oop(r->reg2stack() * VMRegImpl::stack_slot_size);
+         }
+       }
+       s.next();
+@@ -796,6 +792,3 @@
+   }
+ #endif
+ }
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp openjdk/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_LIRAssembler.hpp	1.116 07/05/05 17:05:08 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIR.cpp openjdk/hotspot/src/share/vm/c1/c1_LIR.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_LIR.cpp	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_LIR.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_LIR.cpp	1.118 07/05/05 17:05:04 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -126,10 +123,17 @@
+   assert(scale() == times_1, "Scaled addressing mode not available on SPARC and should not be used");
+   assert(disp() == 0 || index()->is_illegal(), "can't have both");
+ #endif
++#ifdef _LP64
++  assert(base()->is_cpu_register(), "wrong base operand");
++  assert(index()->is_illegal() || index()->is_double_cpu(), "wrong index operand");
++  assert(base()->type() == T_OBJECT || base()->type() == T_LONG,
++         "wrong type for addresses");
++#else
+   assert(base()->is_single_cpu(), "wrong base operand");
+   assert(index()->is_illegal() || index()->is_single_cpu(), "wrong index operand");
+   assert(base()->type() == T_OBJECT || base()->type() == T_INT,
+          "wrong type for addresses");
++#endif
+ }
+ #endif
+ 
+@@ -183,7 +187,6 @@
+     case T_INT:
+     case T_OBJECT:
+     case T_ARRAY:
+-    case T_ADDRESS:
+       assert((kind_field() == cpu_register || kind_field() == stack_value) && size_field() == single_size, "must match");
+       break;
+ 
+@@ -216,6 +219,15 @@
+ 
+ void LIR_Op2::verify() const {
+ #ifdef ASSERT
++  switch (code()) {
++    case lir_cmove:
++      break;
++
++    default:
++      assert(!result_opr()->is_register() || !result_opr()->is_oop_register(),
++             "can't produce oops from arith");
++  }
++
+   if (TwoOperandLIRForm) {
+     switch (code()) {
+     case lir_add:
+@@ -229,7 +241,6 @@
+     case lir_logic_or:
+     case lir_logic_xor:
+     case lir_shl:
+-    case lir_shlx:
+     case lir_shr:
+       assert(in_opr1() == result_opr(), "opr1 and result must match");
+       assert(in_opr1()->is_valid() && in_opr2()->is_valid(), "must be valid");
+@@ -561,7 +572,6 @@
+     case lir_logic_or:
+     case lir_logic_xor:
+     case lir_shl:
+-    case lir_shlx:
+     case lir_shr:
+     case lir_ushr:
+     {
+@@ -1567,7 +1577,6 @@
+      case lir_logic_or:              s = "logic_or";      break;
+      case lir_logic_xor:             s = "logic_xor";     break;
+      case lir_shl:                   s = "shift_left";    break;
+-     case lir_shlx:                  s = "shift_left_long";break;
+      case lir_shr:                   s = "shift_right";   break;
+      case lir_ushr:                  s = "ushift_right";  break;
+      case lir_alloc_array:           s = "alloc_array";   break;
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp openjdk/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_LIRGenerator.cpp	1.22 07/05/17 15:49:41 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -810,9 +807,10 @@
+ 
+ 
+ LIR_Opr LIRGenerator::force_to_spill(LIR_Opr value, BasicType t) {
++  assert(type2size[t] == type2size[value->type()], "size mismatch");
+   if (!value->is_register()) {
+     // force into a register
+-    LIR_Opr r = new_register(t);
++    LIR_Opr r = new_register(value->type());
+     __ move(value, r);
+     value = r;
+   }
+@@ -991,34 +989,6 @@
+ }
+ 
+ 
+-void LIRGenerator::write_barrier(LIR_Opr addr) {
+-  if (addr->is_address()) {
+-    LIR_Address* address = (LIR_Address*)addr;
+-    LIR_Opr ptr = new_register(T_OBJECT);
+-    if (!address->index()->is_valid() && address->disp() == 0) {
+-      __ move(address->base(), ptr);
+-    } else {
+-      __ leal(addr, ptr);
+-    }
+-    addr = ptr;
+-  }
+-  assert(addr->is_register(), "must be a register at this point");
+-
+-  LIR_Opr tmp = new_register(T_OBJECT);
+-  if (TwoOperandLIRForm) {
+-    __ move(addr, tmp);
+-    __ unsigned_shift_right(tmp, CardTableModRefBS::card_shift, tmp);
+-  } else {
+-    __ unsigned_shift_right(addr, CardTableModRefBS::card_shift, tmp);
+-  }
+-  if (can_inline_as_constant(card_table_base())) {
+-    __ move(LIR_OprFact::intConst(0), new LIR_Address(tmp, card_table_base()->as_jint(), T_BYTE));
+-  } else {
+-    __ move(LIR_OprFact::intConst(0), new LIR_Address(tmp, load_constant(card_table_base()), T_BYTE));
+-  }
+-}
+-
+-
+ void LIRGenerator::do_ExceptionObject(ExceptionObject* x) {
+   assert(block()->is_set(BlockBegin::exception_entry_flag), "ExceptionObject only allowed in exception handler block");
+   assert(block()->next() == x, "ExceptionObject must be first instruction of block");
+@@ -1267,6 +1237,58 @@
+   return result;
+ }
+ 
++// Various barriers
++
++void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
++  switch (Universe::heap()->barrier_set()->kind()) {
++    case BarrierSet::CardTableModRef:
++    case BarrierSet::CardTableExtension:
++      CardTableModRef_post_barrier(addr,  new_val);
++      break;
++    case BarrierSet::ModRef:
++    case BarrierSet::Other:
++      // No post barriers
++      break;
++    default      :
++      ShouldNotReachHere();
++    }
++}
++
++void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
++
++  BarrierSet* bs = Universe::heap()->barrier_set();
++  assert(sizeof(*((CardTableModRefBS*)bs)->byte_map_base) == sizeof(jbyte), "adjust this code");
++  LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)bs)->byte_map_base);
++  if (addr->is_address()) {
++    LIR_Address* address = addr->as_address_ptr();
++    LIR_Opr ptr = new_register(T_OBJECT);
++    if (!address->index()->is_valid() && address->disp() == 0) {
++      __ move(address->base(), ptr);
++    } else {
++      assert(address->disp() != max_jint, "lea doesn't support patched addresses!");
++      __ leal(addr, ptr);
++    }
++    addr = ptr;
++  }
++  assert(addr->is_register(), "must be a register at this point");
++
++  LIR_Opr tmp = new_pointer_register();
++  if (TwoOperandLIRForm) {
++    __ move(addr, tmp);
++    __ unsigned_shift_right(tmp, CardTableModRefBS::card_shift, tmp);
++  } else {
++    __ unsigned_shift_right(addr, CardTableModRefBS::card_shift, tmp);
++  }
++  if (can_inline_as_constant(card_table_base)) {
++    __ move(LIR_OprFact::intConst(0),
++              new LIR_Address(tmp, card_table_base->as_jint(), T_BYTE));
++  } else {
++    __ move(LIR_OprFact::intConst(0),
++              new LIR_Address(tmp, load_constant(card_table_base),
++                              T_BYTE));
++  }
++}
++
+ 
+ //------------------------field access--------------------------------------
+ 
+@@ -1302,6 +1324,7 @@
+   bool needs_patching = x->needs_patching();
+   bool is_volatile = x->field()->is_volatile();
+   BasicType field_type = x->field_type();
++  bool is_oop = (field_type == T_ARRAY || field_type == T_OBJECT);
+ 
+   CodeEmitInfo* info = NULL;
+   if (needs_patching) {
+@@ -1374,8 +1397,8 @@
+     __ store(value.result(), address, info, patch_code);
+   }
+ 
+-  if (field_type == T_ARRAY || field_type == T_OBJECT) {
+-    write_barrier(object.result());
++  if (is_oop) {
++    post_barrier(object.result(), value.result());
+   }
+ 
+   if (is_volatile && os::is_MP()) {
+@@ -1677,12 +1700,14 @@
+   assert(!x->has_index() || idx.value() == x->index(), "should match");
+ 
+   LIR_Opr base_op = base.result();
++#ifndef _LP64
+   if (x->base()->type()->tag() == longTag) {
+     base_op = new_register(T_INT);
+     __ convert(Bytecodes::_l2i, base.result(), base_op);
+   } else {
+     assert(x->base()->type()->tag() == intTag, "must be");
+   }
++#endif
+ 
+   BasicType dst_type = x->basic_type();
+   LIR_Opr index_op = idx.result();
+@@ -1740,8 +1765,15 @@
+ 
+   set_no_result(x);
+ 
+-  LIR_Opr intBase = new_register(T_INT);
+-  __ convert(Bytecodes::_l2i, base.result(), intBase);
++  LIR_Opr base_op = base.result();
++#ifndef _LP64
++  if (x->base()->type()->tag() == longTag) {
++    base_op = new_register(T_INT);
++    __ convert(Bytecodes::_l2i, base.result(), base_op);
++  } else {
++    assert(x->base()->type()->tag() == intTag, "must be");
++  }
++#endif
+ 
+   LIR_Opr index_op = idx.result();
+   if (log2_scale != 0) {
+@@ -1751,7 +1783,7 @@
+     __ shift_left(index_op, log2_scale, index_op);
+   }
+ 
+-  LIR_Address* addr = new LIR_Address(intBase, index_op, x->basic_type());
++  LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
+   __ move(value.result(), addr);
+ }
+ 
+@@ -2182,7 +2214,7 @@
+ 
+   // emit invoke code
+   bool optimized = x->target_is_loaded() && x->target_is_final();
+-  assert(receiver->is_illegal() || receiver->is_equivalent(LIR_Assembler::receiverOpr()), "must match");
++  assert(receiver->is_illegal() || receiver->is_equal(LIR_Assembler::receiverOpr()), "must match");
+ 
+   switch (x->code()) {
+     case Bytecodes::_invokestatic:
+@@ -2500,5 +2532,3 @@
+   }
+ #endif
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp openjdk/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_LIRGenerator.hpp	1.13 07/05/05 17:05:07 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -252,6 +249,19 @@
+   LIR_Opr call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info);
+   LIR_Opr call_runtime(Value arg1, Value arg2, address entry, ValueType* result_type, CodeEmitInfo* info);
+ 
++  // GC Barriers
++
++  // generic interface
++
++  void post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val);
++
++  // specific implementations
++
++  // post barriers
++
++  void CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val);
++
++
+   static LIR_Opr result_register_for(ValueType* type, bool callee = false);
+ 
+   ciObject* get_jobject_constant(Value value);
+@@ -325,8 +335,6 @@
+   }
+   LIR_Address* emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type, bool needs_card_mark);
+ 
+-  void write_barrier(LIR_Opr addr);
+-
+   // machine preferences and characteristics
+   bool can_inline_as_constant(Value i) const;
+   bool can_inline_as_constant(LIR_Const* c) const;
+@@ -360,6 +368,15 @@
+   LIR_Opr new_register(Value value)              { return new_register(as_BasicType(value->type())); }
+   LIR_Opr new_register(ValueType* type)          { return new_register(as_BasicType(type)); }
+ 
++  // returns a register suitable for doing pointer math
++  LIR_Opr new_pointer_register() {
++#ifdef _LP64
++    return new_register(T_LONG);
++#else
++    return new_register(T_INT);
++#endif
++  }
++
+   static LIR_Condition lir_cond(If::Condition cond) {
+     LIR_Condition l;
+     switch (cond) {
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIR.hpp openjdk/hotspot/src/share/vm/c1/c1_LIR.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_LIR.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_LIR.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_LIR.hpp	1.133 07/05/05 17:05:05 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -95,6 +92,15 @@
+   LIR_Const(jfloat f)                            { _value.set_type(T_FLOAT);   _value.set_jfloat(f); }
+   LIR_Const(jdouble d)                           { _value.set_type(T_DOUBLE);  _value.set_jdouble(d); }
+   LIR_Const(jobject o)                           { _value.set_type(T_OBJECT);  _value.set_jobject(o); }
++  LIR_Const(void* p) {
++#ifdef _LP64
++    assert(sizeof(jlong) >= sizeof(p), "too small");;
++    _value.set_type(T_LONG);    _value.set_jlong((jlong)p);
++#else
++    assert(sizeof(jint) >= sizeof(p), "too small");;
++    _value.set_type(T_INT);     _value.set_jint((jint)p);
++#endif
++  }
+                                        
+   virtual BasicType type()       const { return _value.get_type(); }
+   virtual LIR_Const* as_constant()     { return this; }
+@@ -107,6 +113,13 @@
+   jint      as_jint_lo() const         { type_check(T_LONG  ); return low(_value.get_jlong()); }
+   jint      as_jint_hi() const         { type_check(T_LONG  ); return high(_value.get_jlong()); }
+ 
++#ifdef _LP64
++  address   as_pointer() const         { type_check(T_LONG  ); return (address)_value.get_jlong(); }
++#else
++  address   as_pointer() const         { type_check(T_INT   ); return (address)_value.get_jint(); }
++#endif
++
++
+   jint      as_jint_bits() const       { type_check(T_FLOAT, T_INT); return _value.get_jint(); }
+   jint      as_jint_lo_bits() const    {
+     if (type() == T_DOUBLE) {
+@@ -244,8 +257,6 @@
+   OprKind kind_field() const                     { return (OprKind)(value() & kind_mask); }
+   OprSize size_field() const                     { return (OprSize)(value() & size_mask); }
+ 
+-  intptr_t value_without_type() const            { return is_illegal() ? value() : value() & no_type_mask; }
+-
+   static char type_char(BasicType t);
+ 
+  public:
+@@ -286,7 +297,6 @@
+       case T_INT:
+       case T_OBJECT:
+       case T_ARRAY:
+-      case T_ADDRESS:
+         return single_size;
+         break;
+         
+@@ -296,12 +306,6 @@
+   }
+ 
+ 
+-  // returns a new LIR_Opr with the OprType of from and all other information the current LIR_Opr
+-  LIR_Opr with_type_of(LIR_Opr from) {
+-    assert(!is_pointer() && !from->is_pointer(), "only simple LIR_Oprs");
+-    return (LIR_Opr)(from->type_field() | value_without_type());
+-  }
+-
+   void validate_type() const PRODUCT_RETURN;
+ 
+   BasicType type() const {
+@@ -316,23 +320,17 @@
+ 
+   char type_char() const                         { return type_char((is_pointer()) ? pointer()->type() : type()); }
+ 
+-  bool is_same(LIR_Opr opr) const                { return this == opr; }
+-  // checks whether types are same or one type is unknown
+-  bool is_type_compatible(LIR_Opr opr) const     {
+-    return type_field() == unknown_type ||
+-      opr->type_field() == unknown_type ||
+-      type_field() == opr->type_field();
+-  }
+-
+-  // is_type_compatible and equal
+-  bool is_equivalent(LIR_Opr opr) const {
+-    if (!is_pointer()) {
+-      if (is_type_compatible(opr) && data() == opr->data() && kind_field() == opr->kind_field() && is_xmm_register() == opr->is_xmm_register()) {
+-        return true;
+-      }
+-    }
+-    // could also do checks for other pointers types
+-    return is_same(opr);
++  bool is_equal(LIR_Opr opr) const         { return this == opr; }
++  // checks whether types are same
++  bool is_same_type(LIR_Opr opr) const     {
++    assert(type_field() != unknown_type &&
++           opr->type_field() != unknown_type, "shouldn't see unknown_type");
++    return type_field() == opr->type_field();
++  }
++  bool is_same_register(LIR_Opr opr) {
++    return (is_register() && opr->is_register() &&
++            kind_field() == opr->kind_field() &&
++            (value() & no_type_mask) == (opr->value() & no_type_mask));
+   }
+ 
+   bool is_pointer() const      { return check_value_mask(pointer_mask, pointer_value); }
+@@ -409,6 +407,16 @@
+   Register as_register_lo() const;
+   Register as_register_hi() const;
+ 
++  Register as_pointer_register() {
++#ifdef _LP64
++    if (is_double_cpu()) {
++      assert(as_register_lo() == as_register_hi(), "should be a single register");
++      return as_register_lo();
++    }
++#endif
++    return as_register();
++  }
++
+ #ifdef IA32
+   XMMRegister as_xmm_float_reg() const;
+   XMMRegister as_xmm_double_reg() const;
+@@ -606,6 +614,8 @@
+   static LIR_Opr doubleConst(jdouble d)          { return (LIR_Opr)(new LIR_Const(d)); }
+   static LIR_Opr oopConst(jobject o)             { return (LIR_Opr)(new LIR_Const(o)); }
+   static LIR_Opr address(LIR_Address* a)         { return (LIR_Opr)a; }
++  static LIR_Opr intptrConst(void* p)            { return (LIR_Opr)(new LIR_Const(p)); }
++  static LIR_Opr intptrConst(intptr_t v)         { return (LIR_Opr)(new LIR_Const((void*)v)); }
+   static LIR_Opr illegal()                       { return (LIR_Opr)-1; }
+ 
+   static LIR_Opr value_type(ValueType* type);
+@@ -713,7 +723,6 @@
+       , lir_logic_or
+       , lir_logic_xor
+       , lir_shl
+-      , lir_shlx
+       , lir_shr
+       , lir_ushr
+       , lir_alloc_array
+@@ -1534,7 +1543,6 @@
+   virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
+ };
+ 
+-
+ // LIR_OpProfileCall
+ class LIR_OpProfileCall : public LIR_Op {
+  friend class LIR_OpVisitState;
+@@ -1573,7 +1581,6 @@
+ 
+ class LIR_InsertionBuffer;
+ 
+-
+ //--------------------------------LIR_List---------------------------------------------------
+ // Maintains a list of LIR instructions (one instance of LIR_List per basic block)
+ // The LIR instructions are appended by the LIR_List class itself; 
+@@ -2025,4 +2032,3 @@
+ 
+ 
+ inline LIR_Opr LIR_OprDesc::illegalOpr()   { return LIR_OprFact::illegalOpr; };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp openjdk/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_MacroAssembler.hpp	1.23 07/05/05 17:05:08 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -83,5 +80,3 @@
+   int call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2);
+   int call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2, Register arg3);
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Optimizer.cpp openjdk/hotspot/src/share/vm/c1/c1_Optimizer.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Optimizer.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Optimizer.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_Optimizer.cpp	1.71 07/05/05 17:05:09 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Optimizer.hpp openjdk/hotspot/src/share/vm/c1/c1_Optimizer.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Optimizer.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Optimizer.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_Optimizer.hpp	1.16 07/05/05 17:05:09 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -38,4 +35,3 @@
+   void eliminate_blocks();
+   void eliminate_null_checks();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Runtime1.cpp openjdk/hotspot/src/share/vm/c1/c1_Runtime1.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Runtime1.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Runtime1.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_Runtime1.cpp	1.244 07/06/01 13:28:38 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Runtime1.hpp openjdk/hotspot/src/share/vm/c1/c1_Runtime1.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_Runtime1.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_Runtime1.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_Runtime1.hpp	1.140 07/05/17 15:49:48 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueMap.cpp openjdk/hotspot/src/share/vm/c1/c1_ValueMap.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_ValueMap.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_ValueMap.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_ValueMap.cpp	1.29 07/05/05 17:05:08 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueMap.hpp openjdk/hotspot/src/share/vm/c1/c1_ValueMap.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_ValueMap.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_ValueMap.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_ValueMap.hpp	1.22 07/05/05 17:05:07 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueSet.cpp openjdk/hotspot/src/share/vm/c1/c1_ValueSet.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_ValueSet.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_ValueSet.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_ValueSet.cpp	1.12 07/05/05 17:05:09 JVM"
+-#endif
+ /*
+  * Copyright 2001-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueSet.hpp openjdk/hotspot/src/share/vm/c1/c1_ValueSet.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_ValueSet.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_ValueSet.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_ValueSet.hpp	1.15 07/05/05 17:05:09 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueStack.cpp openjdk/hotspot/src/share/vm/c1/c1_ValueStack.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_ValueStack.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_ValueStack.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_ValueStack.cpp	1.65 07/05/05 17:05:09 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -286,4 +283,3 @@
+   Unimplemented();
+ }
+ #endif // PRODUCT
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueStack.hpp openjdk/hotspot/src/share/vm/c1/c1_ValueStack.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_ValueStack.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_ValueStack.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_ValueStack.hpp	1.51 07/05/05 17:05:10 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueType.cpp openjdk/hotspot/src/share/vm/c1/c1_ValueType.cpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_ValueType.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_ValueType.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c1_ValueType.cpp	1.22 07/05/05 17:05:10 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueType.hpp openjdk/hotspot/src/share/vm/c1/c1_ValueType.hpp
+--- openjdk6/hotspot/src/share/vm/c1/c1_ValueType.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/c1/c1_ValueType.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_ValueType.hpp	1.35 07/05/05 17:05:10 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp openjdk/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp
+--- openjdk6/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)bcEscapeAnalyzer.cpp	1.7 07/05/17 15:49:50 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1322,4 +1319,3 @@
+     deps->assert_unique_concrete_method(k, m);
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp openjdk/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp
+--- openjdk6/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)bcEscapeAnalyzer.hpp	1.6 07/05/05 17:05:11 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciArray.cpp openjdk/hotspot/src/share/vm/ci/ciArray.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciArray.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciArray.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciArray.cpp	1.12 07/05/05 17:05:11 JVM"
+-#endif
+ /*
+  * Copyright 1999-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -37,7 +34,7 @@
+ // ciArray::print_impl
+ //
+ // Implementation of the print method.
+-void ciArray::print_impl() {
+-  tty->print(" length=%d type=", length());
+-  klass()->print();
++void ciArray::print_impl(outputStream* st) {
++  st->print(" length=%d type=", length());
++  klass()->print(st);
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciArray.hpp openjdk/hotspot/src/share/vm/ci/ciArray.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciArray.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciArray.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciArray.hpp	1.12 07/05/05 17:05:11 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -44,7 +41,7 @@
+ 
+   const char* type_string() { return "ciArray"; }
+ 
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+ public:
+   int length() { return _length; }
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciArrayKlass.cpp openjdk/hotspot/src/share/vm/ci/ciArrayKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciArrayKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciArrayKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciArrayKlass.cpp	1.14 07/05/05 17:05:12 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciArrayKlass.hpp openjdk/hotspot/src/share/vm/ci/ciArrayKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciArrayKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciArrayKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciArrayKlass.hpp	1.15 07/05/05 17:05:12 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciArrayKlassKlass.hpp openjdk/hotspot/src/share/vm/ci/ciArrayKlassKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciArrayKlassKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciArrayKlassKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciArrayKlassKlass.hpp	1.12 07/05/05 17:05:12 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciCallProfile.hpp openjdk/hotspot/src/share/vm/ci/ciCallProfile.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciCallProfile.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciCallProfile.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciCallProfile.hpp	1.17 07/05/05 17:05:12 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciClassList.hpp openjdk/hotspot/src/share/vm/ci/ciClassList.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciClassList.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciClassList.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciClassList.hpp	1.21 07/05/05 17:05:11 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciConstant.cpp openjdk/hotspot/src/share/vm/ci/ciConstant.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciConstant.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciConstant.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciConstant.cpp	1.13 07/05/05 17:05:12 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciConstant.hpp openjdk/hotspot/src/share/vm/ci/ciConstant.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciConstant.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciConstant.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciConstant.hpp	1.17 07/05/05 17:05:12 JVM"
+-#endif
+ /*
+  * Copyright 1999-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -44,7 +41,7 @@
+   } _value;
+ 
+   // Implementation of the print method.
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+ public:
+ 
+@@ -113,4 +110,3 @@
+   // Debugging output
+   void print();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciConstantPoolCache.cpp openjdk/hotspot/src/share/vm/ci/ciConstantPoolCache.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciConstantPoolCache.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciConstantPoolCache.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciConstantPoolCache.cpp	1.12 07/05/05 17:05:12 JVM"
+-#endif
+ /*
+  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciConstantPoolCache.hpp openjdk/hotspot/src/share/vm/ci/ciConstantPoolCache.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciConstantPoolCache.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciConstantPoolCache.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciConstantPoolCache.hpp	1.11 07/05/05 17:05:11 JVM"
+-#endif
+ /*
+  * Copyright 1999-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -48,4 +45,3 @@
+ 
+   void print();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciEnv.cpp openjdk/hotspot/src/share/vm/ci/ciEnv.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciEnv.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciEnv.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciEnv.cpp	1.128 07/05/17 15:49:53 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciEnv.hpp openjdk/hotspot/src/share/vm/ci/ciEnv.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciEnv.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciEnv.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciEnv.hpp	1.70 07/05/05 17:05:11 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -360,5 +357,3 @@
+   void record_method_not_compilable(const char* reason, bool all_tiers = true);
+   void record_out_of_memory_failure();
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciExceptionHandler.cpp openjdk/hotspot/src/share/vm/ci/ciExceptionHandler.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciExceptionHandler.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciExceptionHandler.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciExceptionHandler.cpp	1.12 07/05/05 17:05:13 JVM"
+-#endif
+ /*
+  * Copyright 1999-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciExceptionHandler.hpp openjdk/hotspot/src/share/vm/ci/ciExceptionHandler.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciExceptionHandler.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciExceptionHandler.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciExceptionHandler.hpp	1.12 07/05/05 17:05:13 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -76,4 +73,3 @@
+ 
+   void      print();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciField.cpp openjdk/hotspot/src/share/vm/ci/ciField.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciField.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciField.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciField.cpp	1.33 07/05/05 17:05:13 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -143,12 +140,9 @@
+   _cp_index = -1;
+ 
+   // Get the field's name, signature, and type.
+-  symbolOop name = fd->name();
+-  symbolOop signature = fd->signature();
+-
+   ciEnv* env = CURRENT_ENV;
+-  _name = env->get_object(name)->as_symbol();
+-  _signature = env->get_object(signature)->as_symbol();
++  _name = env->get_object(fd->name())->as_symbol();
++  _signature = env->get_object(fd->signature())->as_symbol();
+ 
+   BasicType field_type = fd->field_type();
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciField.hpp openjdk/hotspot/src/share/vm/ci/ciField.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciField.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciField.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciField.hpp	1.21 07/05/05 17:05:12 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -34,6 +31,7 @@
+   CI_PACKAGE_ACCESS
+   friend class ciEnv;
+   friend class ciInstanceKlass;
++  friend class NonStaticFieldFiller;
+ 
+ private:
+   ciFlags          _flags;
+@@ -59,7 +57,7 @@
+   void initialize_from(fieldDescriptor* fd);
+ 
+   // The implementation of the print method.
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+ public:
+   ciFlags flags() { return _flags; }
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciFlags.cpp openjdk/hotspot/src/share/vm/ci/ciFlags.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciFlags.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciFlags.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciFlags.cpp	1.11 07/05/05 17:05:13 JVM"
+-#endif
+ /*
+  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -34,69 +31,69 @@
+ 
+ // ------------------------------------------------------------------
+ // ciFlags::print_klass_flags
+-void ciFlags::print_klass_flags() {
++void ciFlags::print_klass_flags(outputStream* st) {
+   if (is_public()) {
+-    tty->print("public");
++    st->print("public");
+   } else {
+-    tty->print("DEFAULT_ACCESS");
++    st->print("DEFAULT_ACCESS");
+   }
+ 
+   if (is_final()) {
+-    tty->print(",final");
++    st->print(",final");
+   }
+   if (is_super()) {
+-    tty->print(",super");
++    st->print(",super");
+   }
+   if (is_interface()) {
+-    tty->print(",interface");
++    st->print(",interface");
+   }
+   if (is_abstract()) {
+-    tty->print(",abstract");
++    st->print(",abstract");
+   }
+ }
+ 
+ // ------------------------------------------------------------------
+ // ciFlags::print_member_flags
+-void ciFlags::print_member_flags() {
++void ciFlags::print_member_flags(outputStream* st) {
+   if (is_public()) {
+-    tty->print("public");
++    st->print("public");
+   } else if (is_private()) {
+-    tty->print("private");
++    st->print("private");
+   } else if (is_protected()) {
+-    tty->print("protected");
++    st->print("protected");
+   } else {
+-    tty->print("DEFAULT_ACCESS");
++    st->print("DEFAULT_ACCESS");
+   }
+ 
+   if (is_static()) {
+-    tty->print(",static");
++    st->print(",static");
+   }
+   if (is_final()) {
+-    tty->print(",final");
++    st->print(",final");
+   }
+   if (is_synchronized()) {
+-    tty->print(",synchronized");
++    st->print(",synchronized");
+   }
+   if (is_volatile()) {
+-    tty->print(",volatile");
++    st->print(",volatile");
+   }
+   if (is_transient()) {
+-    tty->print(",transient");
++    st->print(",transient");
+   }
+   if (is_native()) {
+-    tty->print(",native");
++    st->print(",native");
+   }
+   if (is_abstract()) {
+-    tty->print(",abstract");
++    st->print(",abstract");
+   }
+   if (is_strict()) {
+-    tty->print(",strict");
++    st->print(",strict");
+   }
+     
+ }
+ 
+ // ------------------------------------------------------------------
+ // ciFlags::print
+-void ciFlags::print() {
+-  tty->print(" flags=%x", _flags);
++void ciFlags::print(outputStream* st) {
++  st->print(" flags=%x", _flags);
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciFlags.hpp openjdk/hotspot/src/share/vm/ci/ciFlags.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciFlags.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciFlags.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciFlags.hpp	1.14 07/05/05 17:05:13 JVM"
+-#endif
+ /*
+  * Copyright 1999-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -58,7 +55,7 @@
+   // Conversion
+   jint   as_int()                      { return _flags; }
+ 
+-  void print_klass_flags();
+-  void print_member_flags();
+-  void print();
++  void print_klass_flags(outputStream* st = tty);
++  void print_member_flags(outputStream* st = tty);
++  void print(outputStream* st = tty);
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstance.cpp openjdk/hotspot/src/share/vm/ci/ciInstance.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciInstance.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciInstance.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciInstance.cpp	1.16 07/05/05 17:05:13 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -131,7 +128,7 @@
+ // ciInstance::print_impl
+ //
+ // Implementation of the print method.
+-void ciInstance::print_impl() {
+-  tty->print(" type=");
+-  klass()->print();
++void ciInstance::print_impl(outputStream* st) {
++  st->print(" type=");
++  klass()->print(st);
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstance.hpp openjdk/hotspot/src/share/vm/ci/ciInstance.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciInstance.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciInstance.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciInstance.hpp	1.14 07/05/05 17:05:13 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -44,7 +41,7 @@
+ 
+   const char* type_string() { return "ciInstance"; }
+ 
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+ public:
+   // If this object is a java mirror, return the corresponding type.
+@@ -62,4 +59,3 @@
+   // Constant value of a field at the specified offset.
+   ciConstant field_value_by_offset(int field_offset);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstanceKlass.cpp openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciInstanceKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciInstanceKlass.cpp	1.44 07/05/17 15:49:55 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -238,11 +235,11 @@
+ // ciInstanceKlass::print_impl
+ //
+ // Implementation of the print method.
+-void ciInstanceKlass::print_impl() {
+-  ciKlass::print_impl();
+-  GUARDED_VM_ENTRY(tty->print(" loader=0x%x", (address)loader());)
++void ciInstanceKlass::print_impl(outputStream* st) {
++  ciKlass::print_impl(st);
++  GUARDED_VM_ENTRY(st->print(" loader=0x%x", (address)loader());)
+   if (is_loaded()) {
+-    tty->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=",
++    st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=",
+                bool_to_str(is_initialized()),
+                bool_to_str(has_finalizer()),
+                bool_to_str(has_subklass()),
+@@ -251,14 +248,14 @@
+     _flags.print_klass_flags();
+ 
+     if (_super) {
+-      tty->print(" super=");
++      st->print(" super=");
+       _super->print_name();
+     }
+     if (_java_mirror) {
+-      tty->print(" mirror=PRESENT");
++      st->print(" mirror=PRESENT");
+     }
+   } else {
+-    tty->print(" loaded=false");
++    st->print(" loaded=false");
+   }
+ }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstanceKlass.hpp openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciInstanceKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciInstanceKlass.hpp	1.35 07/05/05 17:05:13 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -77,7 +74,7 @@
+ 
+   const char* type_string() { return "ciInstanceKlass"; }
+ 
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+   ciConstantPoolCache* field_cache();
+ 
+@@ -190,4 +187,3 @@
+   bool is_instance_klass() { return true; }
+   bool is_java_klass()     { return true; }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstanceKlassKlass.cpp openjdk/hotspot/src/share/vm/ci/ciInstanceKlassKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciInstanceKlassKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciInstanceKlassKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciInstanceKlassKlass.cpp	1.10 07/05/05 17:05:14 JVM"
+-#endif
+ /*
+  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstanceKlassKlass.hpp openjdk/hotspot/src/share/vm/ci/ciInstanceKlassKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciInstanceKlassKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciInstanceKlassKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciInstanceKlassKlass.hpp	1.12 07/05/05 17:05:14 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciKlass.cpp openjdk/hotspot/src/share/vm/ci/ciKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciKlass.cpp	1.30 07/05/05 17:05:11 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -224,9 +221,9 @@
+ // ciKlass::print_impl
+ //
+ // Implementation of the print method
+-void ciKlass::print_impl() {
+-  tty->print(" name=");
+-  print_name();
++void ciKlass::print_impl(outputStream* st) {
++  st->print(" name=");
++  print_name_on(st);
+ }
+ 
+ // ------------------------------------------------------------------
+@@ -236,4 +233,3 @@
+ void ciKlass::print_name_on(outputStream* st) {
+   name()->print_symbol_on(st);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciKlass.hpp openjdk/hotspot/src/share/vm/ci/ciKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciKlass.hpp	1.26 07/05/05 17:05:11 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -66,7 +63,7 @@
+ 
+   const char* type_string() { return "ciKlass"; }
+ 
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+ public:
+   ciKlass(KlassHandle k_h);
+@@ -119,8 +116,4 @@
+   bool is_klass() { return true; }
+ 
+   void print_name_on(outputStream* st);
+-  void print_name() {
+-    print_name_on(tty);
+-  }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciKlassKlass.cpp openjdk/hotspot/src/share/vm/ci/ciKlassKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciKlassKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciKlassKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciKlassKlass.cpp	1.10 07/05/05 17:05:14 JVM"
+-#endif
+ /*
+  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciKlassKlass.hpp openjdk/hotspot/src/share/vm/ci/ciKlassKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciKlassKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciKlassKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciKlassKlass.hpp	1.13 07/05/05 17:05:14 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -52,4 +49,3 @@
+   // Return the distinguished ciKlassKlass instance.
+   static ciKlassKlass* make();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodBlocks.cpp openjdk/hotspot/src/share/vm/ci/ciMethodBlocks.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciMethodBlocks.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciMethodBlocks.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciMethodBlocks.cpp	1.5 07/05/05 17:05:13 JVM"
+-#endif
+ /*
+  * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -357,7 +354,7 @@
+   }
+ 
+   if (Verbose || WizardMode) {
+-    method()->print_codes(start_bci(), limit_bci());
++    method()->print_codes_on(start_bci(), limit_bci(), st);
+   }
+ }
+ #endif
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodBlocks.hpp openjdk/hotspot/src/share/vm/ci/ciMethodBlocks.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciMethodBlocks.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciMethodBlocks.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciMethodBlocks.hpp	1.5 07/05/05 17:05:14 JVM"
+-#endif
+ /*
+  * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethod.cpp openjdk/hotspot/src/share/vm/ci/ciMethod.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciMethod.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciMethod.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciMethod.cpp	1.104 07/05/05 17:05:15 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -255,7 +252,7 @@
+   check_is_loaded();
+   VM_ENTRY_MARK;
+   methodHandle mh(THREAD, get_methodOop());
+-  return AbstractInterpreter::entry_for_method(mh);
++  return Interpreter::entry_for_method(mh);
+ }
+ 
+ 
+@@ -408,7 +405,6 @@
+     if (data != NULL && data->is_CounterData()) {
+       // Every profiled call site has a counter.
+       int count = data->as_CounterData()->count();
+-      result._count = count;
+ 
+       if (!data->is_ReceiverTypeData()) {
+         result._receiver_count[0] = 0;  // that's a definite zero
+@@ -421,8 +417,6 @@
+           ciKlass* receiver = call->receiver(i);
+           if (receiver == NULL)  continue;
+           morphism += 1;
+-          // we don't support array klasses this way
+-          if (!receiver->is_instance_klass()) continue;
+           int rcount = call->receiver_count(i);
+           if (rcount == 0) rcount = 1; // Should be valid value
+           receivers_count_total += rcount;
+@@ -444,8 +438,18 @@
+              result._morphism = morphism;
+            }
+         }
++        // Make the count consistent if this is a call profile. If count is
++        // zero or less, presume that this is a typecheck profile and
++        // do nothing.  Otherwise, increase count to be the sum of all
++        // receiver's counts.
++        if (count > 0) {
++          if (count < receivers_count_total) {
++            count = receivers_count_total;
++          }
+       }
+     }
++      result._count = count;
++    }
+   }
+   return result;
+ }
+@@ -526,60 +530,6 @@
+   }
+ 
+ #ifndef PRODUCT
+-  if (VerifyDependencies || TraceDependencies) {
+-    // The CHA module is going to be honorably retired.
+-    // This is the only place where it is used.
+-    // For a while, test equivalence between old and new methods.
+-    KlassHandle caller_klass (THREAD, caller->get_klassOop());
+-    KlassHandle callee_klass (THREAD, callee_holder->get_klassOop());
+-    KlassHandle h_recv       (THREAD, actual_recv->get_klassOop());
+-    symbolHandle h_name      (THREAD, name()->get_symbolOop());
+-    symbolHandle h_signature (THREAD, signature()->get_symbolOop());
+-    methodHandle cha_target;
+-    CHAResult* result =
+-      CHA::analyze_call(caller_klass, callee_klass, h_recv, h_name, h_signature);
+-    if (TraceTypeProfile && Verbose) {
+-      result->print();
+-    }
+-    if (result->is_monomorphic()) {
+-      cha_target = result->monomorphic_target();
+-    }
+-
+-    if (target() != NULL && cha_target() == NULL) {
+-      ResourceMark rm;
+-      ttyLocker ttyl;
+-      if (xtty != NULL) {
+-        xtty->begin_elem("missed_by_CHA");
+-        xtty->method(target());
+-        xtty->klass(actual_recv->get_klassOop());
+-        xtty->end_elem("");
+-      }
+-      if (TraceDependencies) {
+-        tty->print_cr("found unique method missed by CHA:");
+-        tty->print_cr("  context = %s", instanceKlass::cast(actual_recv->get_klassOop())->external_name());
+-        tty->print("  method  = ");
+-        target->print_short_name(tty);
+-        tty->cr();
+-      }
+-    }
+-    if (cha_target() != NULL && target() == NULL) {
+-      ResourceMark rm;
+-      ttyLocker ttyl;
+-      if (xtty != NULL) {
+-        xtty->begin_elem("missed_by_deps_found_by_CHA");
+-        xtty->method(cha_target());
+-        xtty->klass(actual_recv->get_klassOop());
+-        xtty->end_elem("");
+-      }
+-      if (TraceDependencies) {
+-        tty->print_cr("missed unique method found by CHA:");
+-        tty->print_cr("  context = %s", instanceKlass::cast(actual_recv->get_klassOop())->external_name());
+-        tty->print("  method  = ");
+-        cha_target->print_short_name(tty);
+-        tty->cr();
+-      }
+-    }
+-  }
+   if (TraceDependencies && target() != NULL && target() != root_m->get_methodOop()) {
+     tty->print("found a non-root unique target method");
+     tty->print_cr("  context = %s", instanceKlass::cast(actual_recv->get_klassOop())->external_name());
+@@ -627,7 +577,9 @@
+    methodHandle m;
+    // Only do exact lookup if receiver klass has been linked.  Otherwise,
+    // the vtable has not been setup, and the LinkResolver will fail.
+-   if (instanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) {
++   if (h_recv->oop_is_javaArray()
++        ||
++       instanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) {
+      if (holder()->is_interface()) {
+        m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass);
+      } else {
+@@ -760,7 +712,6 @@
+   if (_method_data != NULL) {
+     return _method_data;
+   }
+-  if (ProfileInterpreter || Tier1UpdateMethodData) {
+     VM_ENTRY_MARK;
+     ciEnv* env = CURRENT_ENV;
+     Thread* my_thread = JavaThread::current();
+@@ -777,9 +728,7 @@
+       _method_data = CURRENT_ENV->get_empty_methodData();
+     }
+     return _method_data;
+-  }
+                      
+-  return NULL;
+ }
+ 
+ 
+@@ -949,7 +898,7 @@
+ bool ciMethod::is_not_reached(int bci) {
+   check_is_loaded();
+   VM_ENTRY_MARK;
+-  return AbstractInterpreter::is_not_reached(
++  return Interpreter::is_not_reached(
+                methodHandle(THREAD, get_methodOop()), bci);
+ }
+ 
+@@ -1008,9 +957,9 @@
+ // ciMethod::print_codes
+ //
+ // Print the bytecodes for this method.
+-void ciMethod::print_codes() {
++void ciMethod::print_codes_on(outputStream* st) {
+   check_is_loaded();
+-  GUARDED_VM_ENTRY(get_methodOop()->print_codes();)
++  GUARDED_VM_ENTRY(get_methodOop()->print_codes_on(st);)
+ }
+ 
+ 
+@@ -1049,9 +998,9 @@
+ // ciMethod::print_codes
+ //
+ // Print a range of the bytecodes for this method.
+-void ciMethod::print_codes(int from, int to) {
++void ciMethod::print_codes_on(int from, int to, outputStream* st) {
+   check_is_loaded();
+-  GUARDED_VM_ENTRY(get_methodOop()->print_codes(from, to);)
++  GUARDED_VM_ENTRY(get_methodOop()->print_codes_on(from, to, st);)
+ }
+ 
+ // ------------------------------------------------------------------
+@@ -1076,20 +1025,18 @@
+ // ciMethod::print_impl
+ //
+ // Implementation of the print method.
+-void ciMethod::print_impl() {
+-  ciObject::print_impl();
+-  tty->print(" name=");
+-  name()->print_symbol();
+-  tty->print(" holder=");
+-  holder()->print_name();
+-  tty->print(" signature=");
+-  signature()->print_signature();
++void ciMethod::print_impl(outputStream* st) {
++  ciObject::print_impl(st);
++  st->print(" name=");
++  name()->print_symbol_on(st);
++  st->print(" holder=");
++  holder()->print_name_on(st);
++  st->print(" signature=");
++  signature()->as_symbol()->print_symbol_on(st);
+   if (is_loaded()) {
+-    tty->print(" loaded=true flags=");
+-    flags().print_member_flags();
++    st->print(" loaded=true flags=");
++    flags().print_member_flags(st);
+   } else {
+-    tty->print(" loaded=false");
++    st->print(" loaded=false");
+   }
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodData.cpp openjdk/hotspot/src/share/vm/ci/ciMethodData.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciMethodData.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciMethodData.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciMethodData.cpp	1.28 07/05/05 17:05:15 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -291,8 +288,8 @@
+ }
+ 
+ // Implementation of the print method.
+-void ciMethodData::print_impl() {
+-  ciObject::print_impl();
++void ciMethodData::print_impl(outputStream* st) {
++  ciObject::print_impl(st);
+ }
+ 
+ #ifndef PRODUCT
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodData.hpp openjdk/hotspot/src/share/vm/ci/ciMethodData.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciMethodData.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciMethodData.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciMethodData.hpp	1.27 07/05/05 17:05:14 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -179,7 +176,7 @@
+ 
+   const char* type_string()                      { return "ciMethodData"; }
+ 
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+   DataLayout* data_layout_at(int data_index) {
+     assert(data_index % sizeof(intptr_t) == 0, "unaligned");
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethod.hpp openjdk/hotspot/src/share/vm/ci/ciMethod.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciMethod.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciMethod.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciMethod.hpp	1.63 07/06/08 15:21:44 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -89,7 +86,7 @@
+ 
+   const char* type_string()                      { return "ciMethod"; }
+ 
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+   void load_code();
+ 
+@@ -237,11 +234,13 @@
+   bool can_be_statically_bound() const           { return _can_be_statically_bound; }
+ 
+   // Print the bytecodes of this method.
+-  void print_codes();
+-  void print_codes(int from, int to);
++  void print_codes_on(outputStream* st);
++  void print_codes() {
++    print_codes_on(tty);
++  }
++  void print_codes_on(int from, int to, outputStream* st);
+ 
+   // Print the name of this method in various incarnations.
+   void print_name(outputStream* st = tty);
+   void print_short_name(outputStream* st = tty);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodKlass.cpp openjdk/hotspot/src/share/vm/ci/ciMethodKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciMethodKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciMethodKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciMethodKlass.cpp	1.10 07/05/05 17:05:15 JVM"
+-#endif
+ /*
+  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodKlass.hpp openjdk/hotspot/src/share/vm/ci/ciMethodKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciMethodKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciMethodKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciMethodKlass.hpp	1.13 07/05/05 17:05:15 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -49,4 +46,3 @@
+   // Return the distinguished ciMethodKlass instance.
+   static ciMethodKlass* make();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciNullObject.cpp openjdk/hotspot/src/share/vm/ci/ciNullObject.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciNullObject.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciNullObject.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciNullObject.cpp	1.11 07/05/05 17:05:15 JVM"
+-#endif
+ /*
+  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -37,9 +34,9 @@
+ // ciNullObject::print_impl
+ //
+ // Implementation of the print method.
+-void ciNullObject::print_impl() {
+-  ciObject::print_impl();
+-  tty->print(" unique");
++void ciNullObject::print_impl(outputStream* st) {
++  ciObject::print_impl(st);
++  st->print(" unique");
+ }
+ 
+ // ------------------------------------------------------------------
+@@ -49,4 +46,3 @@
+ ciNullObject* ciNullObject::make() {
+   return CURRENT_ENV->_null_object_instance->as_null_object();
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciNullObject.hpp openjdk/hotspot/src/share/vm/ci/ciNullObject.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciNullObject.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciNullObject.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciNullObject.hpp	1.12 07/05/05 17:05:14 JVM"
+-#endif
+ /*
+  * Copyright 1999-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -36,7 +33,7 @@
+ 
+   const char* type_string() { return "ciNullObject"; }
+ 
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+ public:
+   // Is this ciObject a Java Language Object?  That is,
+@@ -50,5 +47,3 @@
+   // Get the distinguished instance of this klass.
+   static ciNullObject* make();
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjArray.hpp openjdk/hotspot/src/share/vm/ci/ciObjArray.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciObjArray.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciObjArray.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciObjArray.hpp	1.12 07/05/05 17:05:15 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp openjdk/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciObjArrayKlass.cpp	1.23 07/05/05 17:05:15 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp openjdk/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciObjArrayKlass.hpp	1.14 07/05/05 17:05:16 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -72,4 +69,3 @@
+ 
+   static ciObjArrayKlass* make(ciKlass* element_klass);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.cpp openjdk/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciObjArrayKlassKlass.cpp	1.10 07/05/05 17:05:15 JVM"
+-#endif
+ /*
+  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.hpp openjdk/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciObjArrayKlassKlass.hpp	1.12 07/05/05 17:05:16 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -51,4 +48,3 @@
+   // Return the distinguished ciObjArrayKlassKlass instance.
+   static ciObjArrayKlassKlass* make();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObject.cpp openjdk/hotspot/src/share/vm/ci/ciObject.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciObject.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciObject.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciObject.cpp	1.28 07/05/17 15:49:59 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -195,10 +192,10 @@
+ //
+ // Implementation note: dispatch to the virtual print_impl behavior
+ // for this ciObject.
+-void ciObject::print() {
+-  tty->print("<%s", type_string());
+-  GUARDED_VM_ENTRY(print_impl();)
+-  tty->print(" ident=%d %s address=0x%x>", ident(),
++void ciObject::print(outputStream* st) {
++  st->print("<%s", type_string());
++  GUARDED_VM_ENTRY(print_impl(st);)
++  st->print(" ident=%d %s address=0x%x>", ident(),
+         is_perm() ? "PERM" : "",
+         (address)this);
+ }
+@@ -207,13 +204,12 @@
+ // ciObject::print_oop
+ //
+ // Print debugging output about the oop this ciObject represents.
+-void ciObject::print_oop() {
++void ciObject::print_oop(outputStream* st) {
+   if (is_null_object()) {
+-    tty->print_cr("NULL");
++    st->print_cr("NULL");
+   } else if (!is_loaded()) {
+-    tty->print_cr("UNLOADED");
++    st->print_cr("UNLOADED");
+   } else {
+-    GUARDED_VM_ENTRY(get_oop()->print();)
++    GUARDED_VM_ENTRY(get_oop()->print_on(st);)
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjectFactory.cpp openjdk/hotspot/src/share/vm/ci/ciObjectFactory.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciObjectFactory.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciObjectFactory.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciObjectFactory.cpp	1.39 07/05/17 15:50:05 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -648,4 +645,3 @@
+              _ci_objects->length(), _unloaded_methods->length(),
+              _unloaded_klasses->length());
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjectFactory.hpp openjdk/hotspot/src/share/vm/ci/ciObjectFactory.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciObjectFactory.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciObjectFactory.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciObjectFactory.hpp	1.20 07/05/17 15:50:07 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -111,5 +108,3 @@
+   void print_contents();
+   void print();
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObject.hpp openjdk/hotspot/src/share/vm/ci/ciObject.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciObject.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciObject.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciObject.hpp	1.24 07/05/05 17:05:16 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -71,13 +68,12 @@
+     return JNIHandles::resolve_non_null(_handle);
+   }
+ 
+-  bool is_perm() { return (_ident & PERM_FLAG) != 0; }
+   void set_perm() {
+     _ident |=  PERM_FLAG;
+   }
+ 
+   // Virtual behavior of the print() method.
+-  virtual void print_impl() {}
++  virtual void print_impl(outputStream* st) {}
+ 
+   virtual const char* type_string() { return "ciObject"; }
+ 
+@@ -101,6 +97,11 @@
+   // See ciEnv::make_perm_array
+   bool has_encoding();
+ 
++  // Is this object guaranteed to be in the permanent part of the heap?
++  // If so, CollectedHeap::can_elide_permanent_oop_store_barriers is relevant.
++  // If the answer is false, no guarantees are made.
++  bool is_perm() { return (_ident & PERM_FLAG) != 0; }
++
+   // The address which the compiler should embed into the
+   // generated code to represent this oop.  This address
+   // is not the true address of the oop -- it will get patched
+@@ -252,9 +253,8 @@
+   }
+ 
+   // Print debugging output about this ciObject.
+-  void print();
++  void print(outputStream* st = tty);
+ 
+   // Print debugging output about the oop this ciObject represents.
+-  void print_oop();
++  void print_oop(outputStream* st = tty);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSignature.cpp openjdk/hotspot/src/share/vm/ci/ciSignature.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciSignature.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciSignature.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciSignature.cpp	1.21 07/05/05 17:05:16 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -111,4 +108,3 @@
+   _accessing_klass->print();
+   tty->print(" address=0x%x>", (address)this);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSignature.hpp openjdk/hotspot/src/share/vm/ci/ciSignature.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciSignature.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciSignature.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciSignature.hpp	1.16 07/05/05 17:05:14 JVM"
+-#endif
+ /*
+  * Copyright 1999-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -57,6 +54,3 @@
+   void print_signature();
+   void print();
+ };
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciStreams.cpp openjdk/hotspot/src/share/vm/ci/ciStreams.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciStreams.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciStreams.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciStreams.cpp	1.30 07/05/05 17:05:16 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -368,5 +365,3 @@
+   int name_and_type_index = cpool->name_and_type_ref_index_at(method_index);
+   return cpool->signature_ref_index_at(name_and_type_index);
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciStreams.hpp openjdk/hotspot/src/share/vm/ci/ciStreams.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciStreams.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciStreams.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciStreams.hpp	1.36 07/05/05 17:05:14 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -370,7 +367,3 @@
+     return _method->_exception_handlers[_pos];
+   }
+ };
+-
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSymbol.cpp openjdk/hotspot/src/share/vm/ci/ciSymbol.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciSymbol.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciSymbol.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciSymbol.cpp	1.22 07/05/05 17:05:16 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -72,9 +69,9 @@
+ // ciSymbol::print_impl
+ //
+ // Implementation of the print method
+-void ciSymbol::print_impl() {
+-  tty->print(" value=");
+-  print_symbol();
++void ciSymbol::print_impl(outputStream* st) {
++  st->print(" value=");
++  print_symbol_on(st);
+ }
+ 
+ // ------------------------------------------------------------------
+@@ -109,4 +106,3 @@
+ ciSymbol* ciSymbol::make(const char* s) {
+   GUARDED_VM_ENTRY(return make_impl(s);)
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSymbol.hpp openjdk/hotspot/src/share/vm/ci/ciSymbol.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciSymbol.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciSymbol.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciSymbol.hpp	1.15 07/05/17 15:50:09 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -45,7 +42,7 @@
+ 
+   const char* type_string() { return "ciSymbol"; }
+   
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+   int         byte_at(int i);
+   jbyte*      base();
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSymbolKlass.cpp openjdk/hotspot/src/share/vm/ci/ciSymbolKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciSymbolKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciSymbolKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciSymbolKlass.cpp	1.10 07/05/05 17:05:16 JVM"
+-#endif
+ /*
+  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSymbolKlass.hpp openjdk/hotspot/src/share/vm/ci/ciSymbolKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciSymbolKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciSymbolKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciSymbolKlass.hpp	1.13 07/05/05 17:05:17 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -53,4 +50,3 @@
+   // Return the distinguished ciSymbolKlass instance.
+   static ciSymbolKlass* make();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArray.cpp openjdk/hotspot/src/share/vm/ci/ciTypeArray.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciTypeArray.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciTypeArray.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciTypeArray.cpp	1.6 07/05/05 17:05:17 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArray.hpp openjdk/hotspot/src/share/vm/ci/ciTypeArray.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciTypeArray.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciTypeArray.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciTypeArray.hpp	1.13 07/05/05 17:05:17 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlass.cpp openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciTypeArrayKlass.cpp	1.14 07/05/05 17:05:17 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -56,4 +53,3 @@
+ ciTypeArrayKlass* ciTypeArrayKlass::make(BasicType t) {
+   GUARDED_VM_ENTRY(return make_impl(t);)
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciTypeArrayKlass.hpp	1.13 07/05/05 17:05:17 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.cpp openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciTypeArrayKlassKlass.cpp	1.10 07/05/05 17:05:17 JVM"
+-#endif
+ /*
+  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.hpp openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciTypeArrayKlassKlass.hpp	1.12 07/05/05 17:05:18 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciType.cpp openjdk/hotspot/src/share/vm/ci/ciType.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciType.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciType.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciType.cpp	1.16 07/05/05 17:05:16 JVM"
+-#endif
+ /*
+  * Copyright 2000-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -67,17 +64,17 @@
+ // ciType::print_impl
+ //
+ // Implementation of the print method.
+-void ciType::print_impl() {
+-  tty->print(" type=");
+-  print_name();
++void ciType::print_impl(outputStream* st) {
++  st->print(" type=");
++  print_name_on(st);
+ }
+ 
+ // ------------------------------------------------------------------
+ // ciType::print_name
+ //
+ // Print the name of this type
+-void ciType::print_name() {
+-  tty->print(type2name(basic_type()));
++void ciType::print_name_on(outputStream* st) {
++  st->print(type2name(basic_type()));
+ }
+ 
+ 
+@@ -87,7 +84,7 @@
+ //
+ ciInstance* ciType::java_mirror() {
+   VM_ENTRY_MARK;
+-  return CURRENT_THREAD_ENV->get_object(SystemDictionary::java_mirror(basic_type()))->as_instance();
++  return CURRENT_THREAD_ENV->get_object(Universe::java_mirror(basic_type()))->as_instance();
+ }
+ 
+ // ------------------------------------------------------------------
+@@ -136,8 +133,8 @@
+ // ciReturnAddress::print_impl
+ //
+ // Implementation of the print method.
+-void ciReturnAddress::print_impl() {
+-  tty->print(" bci=%d", _bci);
++void ciReturnAddress::print_impl(outputStream* st) {
++  st->print(" bci=%d", _bci);
+ }
+ 
+ // ------------------------------------------------------------------
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeFlow.cpp openjdk/hotspot/src/share/vm/ci/ciTypeFlow.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciTypeFlow.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciTypeFlow.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciTypeFlow.cpp	1.46 07/05/05 17:05:17 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1869,7 +1866,7 @@
+ // ciTypeFlow::Block::print_on
+ void ciTypeFlow::Block::print_on(outputStream* st) const {
+   if ((Verbose || WizardMode)) {
+-    outer()->method()->print_codes(start(), limit());
++    outer()->method()->print_codes_on(start(), limit(), st);
+   }
+   st->print_cr("  ====================================================  ");
+   st->print ("  ");
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeFlow.hpp openjdk/hotspot/src/share/vm/ci/ciTypeFlow.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciTypeFlow.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciTypeFlow.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciTypeFlow.hpp	1.25 08/08/26 13:38:43 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -130,7 +127,7 @@
+ 
+   // Used as a combined index for locals and temps
+   enum Cell {
+-    Cell_0, Cell_max = INT_MAX
++    Cell_0
+   };
+ 
+   // A StateVector summarizes the type information at some
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciType.hpp openjdk/hotspot/src/share/vm/ci/ciType.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciType.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciType.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciType.hpp	1.14 07/05/05 17:05:16 JVM"
+-#endif
+ /*
+  * Copyright 2000-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -43,7 +40,7 @@
+ 
+   const char* type_string() { return "ciType"; }
+ 
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+   // Distinguished instances of primitive ciTypes..
+   static ciType* _basic_types[T_CONFLICT+1];
+@@ -76,7 +73,10 @@
+   bool is_type()                            { return true; }
+   bool is_classless() const                 { return is_primitive_type(); }
+ 
+-  virtual void print_name();
++  virtual void print_name_on(outputStream* st);
++  void print_name() {
++    print_name_on(tty);
++  }
+ 
+   static ciType* make(BasicType t);
+ };
+@@ -97,7 +97,7 @@
+   
+   const char* type_string() { return "ciReturnAddress"; }
+ 
+-  void print_impl();
++  void print_impl(outputStream* st);
+ 
+ public:
+   bool is_return_address()  { return true; }
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciUtilities.cpp openjdk/hotspot/src/share/vm/ci/ciUtilities.cpp
+--- openjdk6/hotspot/src/share/vm/ci/ciUtilities.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciUtilities.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ciUtilities.cpp	1.11 07/05/05 17:05:18 JVM"
+-#endif
+ /*
+  * Copyright 1999-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciUtilities.hpp openjdk/hotspot/src/share/vm/ci/ciUtilities.hpp
+--- openjdk6/hotspot/src/share/vm/ci/ciUtilities.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/ciUtilities.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ciUtilities.hpp	1.20 07/05/05 17:05:18 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -107,4 +104,3 @@
+ 
+ const char* basictype_to_str(BasicType t);
+ const char  basictype_to_char(BasicType t);
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/ci/compilerInterface.hpp openjdk/hotspot/src/share/vm/ci/compilerInterface.hpp
+--- openjdk6/hotspot/src/share/vm/ci/compilerInterface.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/ci/compilerInterface.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compilerInterface.hpp	1.11 07/05/05 17:05:18 JVM"
+-#endif
+ /*
+  * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classFileError.cpp openjdk/hotspot/src/share/vm/classfile/classFileError.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/classFileError.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/classFileError.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)classFileError.cpp	1.12 07/05/05 17:06:44 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classFileParser.cpp openjdk/hotspot/src/share/vm/classfile/classFileParser.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/classFileParser.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/classFileParser.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)classFileParser.cpp	1.279 07/05/25 15:14:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -892,44 +889,38 @@
+   return exception_handlers;
+ }
+ 
+-u_char* ClassFileParser::parse_linenumber_table(u4 code_attribute_length, 
+-                                                u4 code_length,
+-                                                int* compressed_linenumber_table_size, 
+-                                                TRAPS) {
++void ClassFileParser::parse_linenumber_table(
++    u4 code_attribute_length, u4 code_length,
++    CompressedLineNumberWriteStream** write_stream, TRAPS) {
+   ClassFileStream* cfs = stream();
+-  cfs->guarantee_more(2, CHECK_NULL);  // linenumber_table_length
+-  unsigned int linenumber_table_length = cfs->get_u2_fast();
++  unsigned int num_entries = cfs->get_u2(CHECK);
++
++  // Each entry is a u2 start_pc, and a u2 line_number
++  unsigned int length_in_bytes = num_entries * (sizeof(u2) + sizeof(u2));
+ 
+   // Verify line number attribute and table length
+-  if (_need_verify) {
+-    guarantee_property(code_attribute_length ==
+-                       (sizeof(u2) /* linenumber table length */ +
+-                        linenumber_table_length*(sizeof(u2) /* start_pc */ +
+-                        sizeof(u2) /* line_number */)),
+-                       "LineNumberTable attribute has wrong length in class file %s", CHECK_NULL);
+-  }          
+-  
+-  u_char* compressed_linenumber_table = NULL;
+-  if (linenumber_table_length > 0) {
+-    // initial_size large enough
+-    int initial_size = linenumber_table_length * sizeof(u2) * 2;
+-    CompressedLineNumberWriteStream c_stream =
+-      (initial_size <= fixed_buffer_size) ? 
+-      CompressedLineNumberWriteStream(_fixed_buffer, fixed_buffer_size) :
+-      CompressedLineNumberWriteStream(initial_size);
+-    cfs->guarantee_more(4 * linenumber_table_length, CHECK_NULL);  // bci, line
+-    while (linenumber_table_length-- > 0) {
++  check_property(
++    code_attribute_length == sizeof(u2) + length_in_bytes,
++    "LineNumberTable attribute has wrong length in class file %s", CHECK);
++
++  cfs->guarantee_more(length_in_bytes, CHECK);
++
++  if ((*write_stream) == NULL) {
++    if (length_in_bytes > fixed_buffer_size) {
++      (*write_stream) = new CompressedLineNumberWriteStream(length_in_bytes);
++    } else {
++      (*write_stream) = new CompressedLineNumberWriteStream(
++        linenumbertable_buffer, fixed_buffer_size);
++    }
++  }
++
++  while (num_entries-- > 0) {
+       u2 bci  = cfs->get_u2_fast(); // start_pc
+       u2 line = cfs->get_u2_fast(); // line_number
+       guarantee_property(bci < code_length,
+-                         "Invalid pc in LineNumberTable in class file %s", CHECK_NULL);
+-      c_stream.write_pair(bci, line);
+-    }
+-    c_stream.write_terminator();
+-    *compressed_linenumber_table_size = c_stream.position();
+-    compressed_linenumber_table = c_stream.buffer();
++        "Invalid pc in LineNumberTable in class file %s", CHECK);
++    (*write_stream)->write_pair(bci, line);
+   }
+-  return compressed_linenumber_table;
+ }
+ 
+ 
+@@ -1278,8 +1269,8 @@
+   typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
+   u2 checked_exceptions_length = 0;
+   u2* checked_exceptions_start = NULL;
+-  int compressed_linenumber_table_size = 0;
+-  u_char* compressed_linenumber_table = NULL;
++  CompressedLineNumberWriteStream* linenumber_table = NULL;
++  int linenumber_table_length = 0;
+   int total_lvt_length = 0;
+   u2 lvt_cnt = 0;
+   u2 lvtt_cnt = 0;
+@@ -1394,10 +1385,8 @@
+         if (LoadLineNumberTables && 
+             cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_line_number_table()) {
+           // Parse and compress line number table
+-          compressed_linenumber_table = parse_linenumber_table(code_attribute_length, 
+-                                                               code_length,
+-                                                               &compressed_linenumber_table_size, 
+-                                                               CHECK_(nullHandle));
++          parse_linenumber_table(code_attribute_length, code_length,
++            &linenumber_table, CHECK_(nullHandle));
+                                          
+         } else if (LoadLocalVariableTables && 
+                    cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_table()) {
+@@ -1545,6 +1534,12 @@
+       cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
+     }      
+   }
++
++  if (linenumber_table != NULL) {
++    linenumber_table->write_terminator();
++    linenumber_table_length = linenumber_table->position();
++  }
++
+   // Make sure there's at least one Code attribute in non-native/non-abstract method
+   if (_need_verify) {
+     guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute,
+@@ -1552,11 +1547,9 @@
+   }
+ 
+   // All sizing information for a methodOop is finally available, now create it
+-  methodOop m_oop  = oopFactory::new_method(code_length, access_flags,
+-                               compressed_linenumber_table_size, 
+-                               total_lvt_length, 
+-                               checked_exceptions_length, 
+-                               CHECK_(nullHandle));
++  methodOop m_oop  = oopFactory::new_method(
++    code_length, access_flags, linenumber_table_length,
++    total_lvt_length, checked_exceptions_length, CHECK_(nullHandle));
+   methodHandle m (THREAD, m_oop);
+ 
+   ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize);
+@@ -1602,10 +1595,13 @@
+   if (code_length > 0) {
+     memcpy(m->code_base(), code_start, code_length);
+   }
++
+   // Copy line number table
+-  if (compressed_linenumber_table_size > 0) {
+-    memcpy(m->compressed_linenumber_table(), compressed_linenumber_table, compressed_linenumber_table_size);
++  if (linenumber_table != NULL) {
++    memcpy(m->compressed_linenumber_table(),
++           linenumber_table->buffer(), linenumber_table_length);
+   }
++
+   // Copy checked exceptions
+   if (checked_exceptions_length > 0) {
+     int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2);
+@@ -4016,4 +4012,3 @@
+   }
+   return NULL;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classFileParser.hpp openjdk/hotspot/src/share/vm/classfile/classFileParser.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/classFileParser.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/classFileParser.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)classFileParser.hpp	1.84 07/05/05 17:06:45 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -42,7 +39,7 @@
+   bool _has_vanilla_constructor;
+ 
+   enum { fixed_buffer_size = 128 };
+-  u_char _fixed_buffer[fixed_buffer_size];
++  u_char linenumbertable_buffer[fixed_buffer_size];
+ 
+   ClassFileStream* _stream;              // Actual input stream
+ 
+@@ -98,8 +95,9 @@
+                                 TRAPS);
+   typeArrayHandle parse_exception_table(u4 code_length, u4 exception_table_length, 
+                                         constantPoolHandle cp, TRAPS);
+-  u_char* parse_linenumber_table(u4 code_attribute_length, u4 code_length,
+-                                 int* compressed_linenumber_table_size, TRAPS);
++  void parse_linenumber_table(
++      u4 code_attribute_length, u4 code_length,
++      CompressedLineNumberWriteStream** write_stream, TRAPS);
+   u2* parse_localvariable_table(u4 code_length, u2 max_locals, u4 code_attribute_length,
+                                 constantPoolHandle cp, u2* localvariable_table_length,
+                                 bool isLVTT, TRAPS);
+@@ -169,6 +167,15 @@
+       assert_property(property, msg, CHECK);
+     }
+   }
++
++  inline void check_property(bool property, const char* msg, TRAPS) {
++    if (_need_verify) {
++      guarantee_property(property, msg, CHECK);
++    } else {
++      assert_property(property, msg, CHECK);
++    }
++  }
++
+   inline void guarantee_property(bool b, const char* msg, int index, TRAPS) {
+     if (!b) { classfile_parse_error(msg, index, CHECK); }
+   }
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classFileStream.cpp openjdk/hotspot/src/share/vm/classfile/classFileStream.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/classFileStream.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/classFileStream.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)classFileStream.cpp	1.41 07/05/31 14:29:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classFileStream.hpp openjdk/hotspot/src/share/vm/classfile/classFileStream.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/classFileStream.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/classFileStream.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)classFileStream.hpp	1.33 07/05/31 14:29:25 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classLoader.cpp openjdk/hotspot/src/share/vm/classfile/classLoader.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/classLoader.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/classLoader.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)classLoader.cpp	1.186 07/05/05 17:06:44 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -390,7 +387,7 @@
+     char* path = NEW_C_HEAP_ARRAY(char, end-start+1);
+     strncpy(path, &sys_class_path[start], end-start);
+     path[end-start] = '\0';
+-    update_class_path_entry_list(path);
++    update_class_path_entry_list(path, false);
+     FREE_C_HEAP_ARRAY(char, path);
+     while (sys_class_path[end] == os::path_separator()[0]) {
+       end++;
+@@ -505,15 +502,31 @@
+   }
+ }
+ 
+-void ClassLoader::update_class_path_entry_list(const char *path) {
++void ClassLoader::update_class_path_entry_list(const char *path,
++                                               bool check_for_duplicates) {
+   struct stat st;
+   if (os::stat((char *)path, &st) == 0) {
+     // File or directory found
+     ClassPathEntry* new_entry = NULL;
+     create_class_path_entry((char *)path, st, &new_entry, LazyBootClassLoader);
++    // The kernel VM adds dynamically to the end of the classloader path and
++    // doesn't reorder the bootclasspath which would break java.lang.Package
++    // (see PackageInfo).
+     // Add new entry to linked list 
++    if (!check_for_duplicates || !contains_entry(new_entry)) {
+     add_to_list(new_entry);
+   }
++  }
++}
++
++void ClassLoader::print_bootclasspath() {
++  ClassPathEntry* e = _first_entry;
++  tty->print("[bootclasspath= ");
++  while (e != NULL) {
++    tty->print("%s ;", e->name());
++    e = e->next();
++  }
++  tty->print_cr("]");
+ }
+ 
+ void ClassLoader::load_zip_library() {
+@@ -866,7 +879,8 @@
+ 
+ // Initialize the class loader's access to methods in libzip.  Parse and
+ // process the boot classpath into a list ClassPathEntry objects.  Once
+-// this list has been created, it must not change (see class PackageInfo).
++// this list has been created, it must not change order (see class PackageInfo)
++// it can be appended to and is by jvmti and the kernel vm.
+ 
+ void ClassLoader::initialize() {
+   assert(_package_hash_table == NULL, "should have been initialized by now.");
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classLoader.hpp openjdk/hotspot/src/share/vm/classfile/classLoader.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/classLoader.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/classLoader.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)classLoader.hpp	1.64 07/05/05 17:06:45 JVM"
+-#endif 
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -49,7 +46,10 @@
+  public:
+   // Next entry in class path
+   ClassPathEntry* next()              { return _next; }
+-  void set_next(ClassPathEntry* next) { _next = next; }
++  void set_next(ClassPathEntry* next) {
++    // may have unlocked readers, so write atomically.
++    OrderAccess::release_store_ptr(&_next, next);
++  }
+   virtual bool is_jar_file() = 0;
+   virtual const char* name() = 0;
+   virtual bool is_lazy();
+@@ -185,12 +185,16 @@
+   static void setup_bootstrap_search_path();
+   static void load_zip_library();
+   static void create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy);
+-  static void update_class_path_entry_list(const char *path);
+ 
+   // Canonicalizes path names, so strcmp will work properly. This is mainly
+   // to avoid confusing the zip library
+   static bool get_canonical_path(char* orig, char* out, int len);
+  public:
++  // Used by the kernel jvm.
++  static void update_class_path_entry_list(const char *path,
++                                           bool check_for_duplicates);
++  static void print_bootclasspath();
++
+   // Timing
+   static PerfCounter* perf_accumulated_time()  { return _perf_accumulated_time; }
+   static PerfCounter* perf_classes_inited()    { return _perf_classes_inited; }
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/dictionary.cpp openjdk/hotspot/src/share/vm/classfile/dictionary.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/dictionary.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/dictionary.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)dictionary.cpp	1.27 08/06/19 10:32:36 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -158,8 +155,8 @@
+         for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) {
+           // check the previous versions array for GC'ed weak refs
+           PreviousVersionNode * pv_node = ik->previous_versions()->at(i);
+-          jobject cp_ref = pv_node->prev_constant_pool();
+-          assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
++          jweak cp_ref = pv_node->prev_constant_pool();
++          assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+           if (cp_ref == NULL) {
+             delete pv_node;
+             ik->previous_versions()->remove_at(i);
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/dictionary.hpp openjdk/hotspot/src/share/vm/classfile/dictionary.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/dictionary.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/dictionary.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)dictionary.hpp	1.15 07/05/05 17:05:47 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -220,4 +217,3 @@
+     tty->print_cr("pd set = #%d", count);
+   }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/javaAssertions.cpp openjdk/hotspot/src/share/vm/classfile/javaAssertions.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/javaAssertions.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/javaAssertions.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)javaAssertions.cpp	1.14 07/05/05 17:06:50 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/javaAssertions.hpp openjdk/hotspot/src/share/vm/classfile/javaAssertions.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/javaAssertions.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/javaAssertions.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)javaAssertions.hpp	1.11 07/05/05 17:06:50 JVM"
+-#endif
+ /*
+  * Copyright 2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/javaClasses.cpp openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/javaClasses.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)javaClasses.cpp	1.247 07/05/17 15:50:20 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -308,7 +305,7 @@
+       Handle comp_mirror;
+       if (k->oop_is_typeArray()) {
+         BasicType type = typeArrayKlass::cast(k->as_klassOop())->element_type();
+-        comp_mirror = SystemDictionary::java_mirror(type);
++        comp_mirror = Universe::java_mirror(type);
+         assert(comp_mirror.not_null(), "must have primitive mirror");
+       } else if (k->oop_is_objArray()) {
+         klassOop element_klass = objArrayKlass::cast(k->as_klassOop())->element_klass();
+@@ -394,15 +391,15 @@
+     // Note: create_basic_type_mirror above initializes ak to a non-null value.
+     type = arrayKlass::cast(ak)->element_type();
+   } else {
+-    assert(java_class == SystemDictionary::void_mirror(), "only valid non-array primitive");
++    assert(java_class == Universe::void_mirror(), "only valid non-array primitive");
+   }
+-  assert(SystemDictionary::java_mirror(type) == java_class, "must be consistent");
++  assert(Universe::java_mirror(type) == java_class, "must be consistent");
+   return type;
+ }
+ 
+ 
+ oop java_lang_Class::primitive_mirror(BasicType t) {
+-  oop mirror = SystemDictionary::java_mirror(t);
++  oop mirror = Universe::java_mirror(t);
+   assert(mirror != NULL && mirror->is_a(SystemDictionary::class_klass()), "must be a Class");
+   assert(java_lang_Class::is_primitive(mirror), "must be primitive");
+   return mirror;
+@@ -1125,7 +1122,7 @@
+     } else {
+       if (fr.is_first_frame()) break;      
+       address pc = fr.pc();
+-      if (AbstractInterpreter::contains(pc)) {
++      if (fr.is_interpreted_frame()) {
+         intptr_t bcx = fr.interpreter_frame_bcx();
+         method = fr.interpreter_frame_method();
+         bci =  fr.is_bci(bcx) ? bcx : method->bci_from((address)bcx);
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/javaClasses.hpp openjdk/hotspot/src/share/vm/classfile/javaClasses.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/javaClasses.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/javaClasses.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)javaClasses.hpp	1.157 07/05/05 17:05:52 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/loaderConstraints.cpp openjdk/hotspot/src/share/vm/classfile/loaderConstraints.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/loaderConstraints.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/loaderConstraints.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)loaderConstraints.cpp	1.19 07/05/17 15:50:23 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/loaderConstraints.hpp openjdk/hotspot/src/share/vm/classfile/loaderConstraints.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/loaderConstraints.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/loaderConstraints.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)loaderConstraints.hpp	1.14 07/05/05 17:05:52 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/placeholders.cpp openjdk/hotspot/src/share/vm/classfile/placeholders.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/placeholders.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/placeholders.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)placeholders.cpp	1.20 07/05/17 15:50:29 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -270,5 +267,3 @@
+   }
+ }
+ #endif
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/placeholders.hpp openjdk/hotspot/src/share/vm/classfile/placeholders.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/placeholders.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/placeholders.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)placeholders.hpp	1.21 07/05/05 17:05:54 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -332,5 +329,3 @@
+   void print() const  PRODUCT_RETURN;
+   void verify() const;
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/resolutionErrors.cpp openjdk/hotspot/src/share/vm/classfile/resolutionErrors.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/resolutionErrors.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/resolutionErrors.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)resolutionErrors.cpp	1.6 07/05/05 17:05:54 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -120,5 +117,3 @@
+     }
+   }
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/resolutionErrors.hpp openjdk/hotspot/src/share/vm/classfile/resolutionErrors.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/resolutionErrors.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/resolutionErrors.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)resolutionErrors.hpp	1.6 07/05/05 17:05:54 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -100,4 +97,3 @@
+   // GC support
+   void oops_do(OopClosure* blk);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/stackMapFrame.cpp openjdk/hotspot/src/share/vm/classfile/stackMapFrame.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/stackMapFrame.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/stackMapFrame.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)stackMapFrame.cpp	1.24 07/05/05 17:06:57 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -304,4 +301,3 @@
+ }
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/stackMapFrame.hpp openjdk/hotspot/src/share/vm/classfile/stackMapFrame.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/stackMapFrame.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/stackMapFrame.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)stackMapFrame.hpp	1.20 07/05/05 17:06:57 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -227,4 +224,3 @@
+   // Debugging
+   void print() const PRODUCT_RETURN;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/stackMapTable.cpp openjdk/hotspot/src/share/vm/classfile/stackMapTable.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/stackMapTable.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/stackMapTable.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)stackMapTable.cpp	1.28 07/05/05 17:06:53 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -428,4 +425,3 @@
+     "reserved frame type", CHECK_VERIFY_(pre_frame->verifier(), NULL));
+   return NULL;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/stackMapTable.hpp openjdk/hotspot/src/share/vm/classfile/stackMapTable.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/stackMapTable.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/stackMapTable.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)stackMapTable.hpp	1.21 07/05/05 17:06:57 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/symbolTable.cpp openjdk/hotspot/src/share/vm/classfile/symbolTable.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/symbolTable.cpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/symbolTable.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)symbolTable.cpp	1.69 07/05/05 17:05:55 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/symbolTable.hpp openjdk/hotspot/src/share/vm/classfile/symbolTable.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/symbolTable.hpp	2008-08-28 10:23:08.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/symbolTable.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)symbolTable.hpp	1.48 07/05/05 17:05:56 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/systemDictionary.cpp openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/systemDictionary.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)systemDictionary.cpp	1.361 07/09/01 18:23:02 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -95,6 +92,7 @@
+ klassOop    SystemDictionary::_java_nio_Buffer_klass      =  NULL;
+ 
+ klassOop    SystemDictionary::_sun_misc_AtomicLongCSImpl_klass = NULL;
++klassOop    SystemDictionary::_sun_jkernel_DownloadManager_klass  = NULL;
+ 
+ klassOop    SystemDictionary::_boolean_klass              =  NULL;
+ klassOop    SystemDictionary::_char_klass                 =  NULL;
+@@ -106,17 +104,6 @@
+ klassOop    SystemDictionary::_long_klass                 =  NULL;
+ klassOop    SystemDictionary::_box_klasses[T_VOID+1]      =  { NULL /*, NULL...*/ };
+ 
+-oop         SystemDictionary::_int_mirror                 =  NULL;
+-oop         SystemDictionary::_float_mirror               =  NULL;
+-oop         SystemDictionary::_double_mirror              =  NULL;
+-oop         SystemDictionary::_byte_mirror                =  NULL;
+-oop         SystemDictionary::_bool_mirror                =  NULL;
+-oop         SystemDictionary::_char_mirror                =  NULL;
+-oop         SystemDictionary::_long_mirror                =  NULL;
+-oop         SystemDictionary::_short_mirror               =  NULL;
+-oop         SystemDictionary::_void_mirror                =  NULL;
+-oop         SystemDictionary::_mirrors[T_VOID+1]          =  { NULL /*, NULL...*/ };
+-
+ oop         SystemDictionary::_java_system_loader         =  NULL;
+ 
+ bool        SystemDictionary::_has_loadClassInternal      =  false;
+@@ -1215,6 +1202,63 @@
+   return ik;
+ }
+ 
++#ifdef KERNEL
++// Some classes on the bootstrap class path haven't been installed on the
++// system yet.  Call the DownloadManager method to make them appear in the
++// bootstrap class path and try again to load the named class.
++// Note that with delegation class loaders all classes in another loader will
++// first try to call this so it'd better be fast!!
++static instanceKlassHandle download_and_retry_class_load(
++                                                    symbolHandle class_name,
++                                                    TRAPS) {
++
++  klassOop dlm = SystemDictionary::sun_jkernel_DownloadManager_klass();
++  instanceKlassHandle nk;
++
++  // If download manager class isn't loaded just return.
++  if (dlm == NULL) return nk;
++
++  { HandleMark hm(THREAD);
++    ResourceMark rm(THREAD);
++    Handle s = java_lang_String::create_from_symbol(class_name, CHECK_(nk));
++    Handle class_string = java_lang_String::externalize_classname(s, CHECK_(nk));
++
++    // return value
++    JavaValue result(T_OBJECT);
++
++    // Call the DownloadManager.  We assume that it has a lock because
++    // multiple classes could be not found and downloaded at the same time.
++    // class sun.misc.DownloadManager;
++    // public static String getBootClassPathEntryForClass(String className);
++    JavaCalls::call_static(&result,
++                       KlassHandle(THREAD, dlm),
++                       vmSymbolHandles::getBootClassPathEntryForClass_name(),
++                       vmSymbolHandles::string_string_signature(),
++                       class_string,
++                       CHECK_(nk));
++
++    // Get result.string and add to bootclasspath
++    assert(result.get_type() == T_OBJECT, "just checking");
++    oop obj = (oop) result.get_jobject();
++    if (obj == NULL) { return nk; }
++
++    char* new_class_name = java_lang_String::as_utf8_string(obj);
++
++    // lock the loader
++    // we use this lock because JVMTI does.
++    Handle loader_lock(THREAD, SystemDictionary::system_loader_lock());
++
++    ObjectLocker ol(loader_lock, THREAD);
++    // add the file to the bootclasspath
++    ClassLoader::update_class_path_entry_list(new_class_name, true);
++  } // end HandleMark
++
++  if (TraceClassLoading) {
++    ClassLoader::print_bootclasspath();
++  }
++  return ClassLoader::load_classfile(class_name, CHECK_(nk));
++}
++#endif // KERNEL
+ 
+ 
+ instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_name, Handle class_loader, TRAPS) {
+@@ -1230,6 +1274,15 @@
+       k = ClassLoader::load_classfile(class_name, CHECK_(nh));
+     }
+ 
++#ifdef KERNEL
++    // If the VM class loader has failed to load the class, call the
++    // DownloadManager class to make it magically appear on the classpath
++    // and try again.  This is only configured with the Kernel VM.
++    if (k.is_null()) {
++      k = download_and_retry_class_load(class_name, CHECK_(nh));
++    }
++#endif // KERNEL
++
+     // find_or_define_instance_class may return a different k
+     if (!k.is_null()) {
+       k = find_or_define_instance_class(class_name, class_loader, k, CHECK_(nh));
+@@ -1605,7 +1658,7 @@
+ 
+ // The mirrors are scanned by shared_oops_do() which is
+ // not called by oops_do().  In order to process oops in
+-// a necessary order, shared_oops_do() is called by
++// a necessary order, shared_oops_do() is call by
+ // Universe::oops_do().
+ void SystemDictionary::oops_do(OopClosure* f) {
+   // Adjust preloaded classes and system loader object
+@@ -1684,6 +1737,7 @@
+   f->do_oop((oop*) &_java_nio_Buffer_klass);
+ 
+   f->do_oop((oop*) &_sun_misc_AtomicLongCSImpl_klass);
++  f->do_oop((oop*) &_sun_jkernel_DownloadManager_klass);
+ 
+   f->do_oop((oop*) &_boolean_klass);
+   f->do_oop((oop*) &_char_klass);
+@@ -1710,29 +1764,6 @@
+   FilteredFieldsMap::klasses_oops_do(f); 
+ }
+ 
+-// These *_mirror objects in the system dictionary need to be processed
+-// early on when class data sharing is enabled, and are therefore treated
+-// as part of Universe::oops_do()  rather than in SystemDictionary::oops_do()
+-// as one would normally expect.
+-void SystemDictionary::shared_oops_do(OopClosure* f) {
+-  f->do_oop((oop*) &_int_mirror);
+-  f->do_oop((oop*) &_float_mirror);
+-  f->do_oop((oop*) &_double_mirror);
+-  f->do_oop((oop*) &_byte_mirror);
+-  f->do_oop((oop*) &_bool_mirror);
+-  f->do_oop((oop*) &_char_mirror);
+-  f->do_oop((oop*) &_long_mirror);
+-  f->do_oop((oop*) &_short_mirror);
+-  f->do_oop((oop*) &_void_mirror);
+-
+-  // It's important to iterate over these guys even if they are null,
+-  // since that's how shared heaps are restored.
+-  for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
+-    f->do_oop((oop*) &_mirrors[i]);
+-  }
+-  assert(_mirrors[0] == NULL && _mirrors[T_BOOLEAN - 1] == NULL, "checking");
+-}
+-
+ void SystemDictionary::lazily_loaded_oops_do(OopClosure* f) {
+   f->do_oop((oop*) &_abstract_ownable_synchronizer_klass);
+ }
+@@ -1816,9 +1847,12 @@
+   _string_klass            = resolve_or_fail(vmSymbolHandles::java_lang_String(),                true, CHECK);  
+   _class_klass             = resolve_or_fail(vmSymbolHandles::java_lang_Class(),                 true, CHECK);
+   debug_only(instanceKlass::verify_class_klass_nonstatic_oop_maps(_class_klass));
+-
+-  // Fixup mirrors for classes loaded before java.lang.Class
+-  initialize_basic_type_mirrors(CHECK);
++  // Fixup mirrors for classes loaded before java.lang.Class.
++  // These calls iterate over the objects currently in the perm gen
++  // so calling them at this point is matters (not before when there
++  // are fewer objects and not later after there are more objects
++  // in the perm gen.
++  Universe::initialize_basic_type_mirrors(CHECK);
+   Universe::fixup_mirrors(CHECK);
+ 
+   _cloneable_klass         = resolve_or_fail(vmSymbolHandles::java_lang_Cloneable(),             true, CHECK);
+@@ -1887,6 +1921,12 @@
+ 
+   // If this class isn't present, it won't be referenced.
+   _sun_misc_AtomicLongCSImpl_klass = resolve_or_null(vmSymbolHandles::sun_misc_AtomicLongCSImpl(),     CHECK);
++#ifdef KERNEL
++  _sun_jkernel_DownloadManager_klass = resolve_or_null(vmSymbolHandles::sun_jkernel_DownloadManager(),     CHECK);
++  if (_sun_jkernel_DownloadManager_klass == NULL) {
++    warning("Cannot find sun/jkernel/DownloadManager");
++  }
++#endif // KERNEL
+ 
+   // Preload boxing klasses
+   _boolean_klass           = resolve_or_fail(vmSymbolHandles::java_lang_Boolean(),               true, CHECK);
+@@ -1920,39 +1960,6 @@
+   }
+ }
+ 
+-void SystemDictionary::initialize_basic_type_mirrors(TRAPS) { 
+-  if (UseSharedSpaces) {
+-    assert(_int_mirror != NULL, "already loaded");
+-    assert(_void_mirror == _mirrors[T_VOID], "consistently loaded");
+-    return;
+-  }
+-
+-  assert(_int_mirror==NULL, "basic type mirrors already initialized");
+-
+-  _int_mirror     = java_lang_Class::create_basic_type_mirror("int",    T_INT,     CHECK);
+-  _float_mirror   = java_lang_Class::create_basic_type_mirror("float",  T_FLOAT,   CHECK);
+-  _double_mirror  = java_lang_Class::create_basic_type_mirror("double", T_DOUBLE,  CHECK);
+-  _byte_mirror    = java_lang_Class::create_basic_type_mirror("byte",   T_BYTE,    CHECK);
+-  _bool_mirror    = java_lang_Class::create_basic_type_mirror("boolean",T_BOOLEAN, CHECK);
+-  _char_mirror    = java_lang_Class::create_basic_type_mirror("char",   T_CHAR,    CHECK);
+-  _long_mirror    = java_lang_Class::create_basic_type_mirror("long",   T_LONG,    CHECK);
+-  _short_mirror   = java_lang_Class::create_basic_type_mirror("short",  T_SHORT,   CHECK);
+-  _void_mirror    = java_lang_Class::create_basic_type_mirror("void",   T_VOID,    CHECK);
+-
+-  _mirrors[T_INT]     = _int_mirror;
+-  _mirrors[T_FLOAT]   = _float_mirror;
+-  _mirrors[T_DOUBLE]  = _double_mirror;
+-  _mirrors[T_BYTE]    = _byte_mirror;
+-  _mirrors[T_BOOLEAN] = _bool_mirror;
+-  _mirrors[T_CHAR]    = _char_mirror;
+-  _mirrors[T_LONG]    = _long_mirror;
+-  _mirrors[T_SHORT]   = _short_mirror;
+-  _mirrors[T_VOID]    = _void_mirror;
+-  //_mirrors[T_OBJECT]  = instanceKlass::cast(_object_klass)->java_mirror();
+-  //_mirrors[T_ARRAY]   = instanceKlass::cast(_object_klass)->java_mirror();
+-}
+-
+-
+ // Tells if a given klass is a box (wrapper class, such as java.lang.Integer).
+ // If so, returns the basic type it holds.  If not, returns T_OBJECT.
+ BasicType SystemDictionary::box_klass_type(klassOop k) {
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/systemDictionary.hpp openjdk/hotspot/src/share/vm/classfile/systemDictionary.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/systemDictionary.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/systemDictionary.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)systemDictionary.hpp	1.153 07/05/05 17:05:56 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -183,9 +180,6 @@
+   // Applies "f->do_oop" to all root oops in the system dictionary.
+   static void oops_do(OopClosure* f);
+ 
+-  // Applies "f->do_oop" to root oops that are loaded from a shared heap.
+-  static void shared_oops_do(OopClosure* f);
+-
+   // System loader lock
+   static oop system_loader_lock()	    { return _system_loader_lock_obj; }
+ 
+@@ -309,6 +303,9 @@
+ 
+   static klassOop sun_misc_AtomicLongCSImpl_klass() { return _sun_misc_AtomicLongCSImpl_klass; }
+ 
++  // To support incremental JRE downloads (KERNEL JRE). Null if not present.
++  static klassOop sun_jkernel_DownloadManager_klass() { return _sun_jkernel_DownloadManager_klass; }
++
+   static klassOop boolean_klass()           { return check_klass(_boolean_klass); }
+   static klassOop char_klass()              { return check_klass(_char_klass); }
+   static klassOop float_klass()             { return check_klass(_float_klass); }
+@@ -355,20 +352,6 @@
+   }
+ 
+ public:
+-  static oop int_mirror()                   { return check_mirror(_int_mirror); }
+-  static oop float_mirror()                 { return check_mirror(_float_mirror); }
+-  static oop double_mirror()                { return check_mirror(_double_mirror); }
+-  static oop byte_mirror()                  { return check_mirror(_byte_mirror); }
+-  static oop bool_mirror()                  { return check_mirror(_bool_mirror); }
+-  static oop char_mirror()                  { return check_mirror(_char_mirror); }
+-  static oop long_mirror()                  { return check_mirror(_long_mirror); }
+-  static oop short_mirror()                 { return check_mirror(_short_mirror); }
+-  static oop void_mirror()                  { return check_mirror(_void_mirror); }
+-
+-  static oop java_mirror(BasicType t) {
+-    assert((uint)t < T_VOID+1, "range check");
+-    return check_mirror(_mirrors[t]);
+-  }
+   // Note:  java_lang_Class::primitive_type is the inverse of java_mirror
+ 
+   // Check class loader constraints
+@@ -505,7 +488,6 @@
+   
+   // Initialization
+   static void initialize_preloaded_classes(TRAPS);
+-  static void initialize_basic_type_mirrors(TRAPS);
+     
+   // Class loader constraints
+   static void check_constraints(int index, unsigned int hash,
+@@ -573,6 +555,9 @@
+ 
+   static klassOop _sun_misc_AtomicLongCSImpl_klass;
+ 
++  // KERNEL JRE support.
++  static klassOop _sun_jkernel_DownloadManager_klass;
++
+   // Lazily loaded klasses
+   static volatile klassOop _abstract_ownable_synchronizer_klass;
+ 
+@@ -593,18 +578,4 @@
+ 
+   static bool _has_loadClassInternal;
+   static bool _has_checkPackageAccess;
+-
+-  // Primitive classes
+-  static oop _int_mirror;
+-  static oop _float_mirror;
+-  static oop _double_mirror;
+-  static oop _byte_mirror;
+-  static oop _bool_mirror;
+-  static oop _char_mirror;
+-  static oop _long_mirror;
+-  static oop _short_mirror;
+-  static oop _void_mirror;
+-
+-  // table of same
+-  static oop _mirrors[T_VOID+1];
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/verificationType.cpp openjdk/hotspot/src/share/vm/classfile/verificationType.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/verificationType.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/verificationType.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)verificationType.cpp	1.16 07/05/05 17:07:01 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/verificationType.hpp openjdk/hotspot/src/share/vm/classfile/verificationType.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/verificationType.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/verificationType.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)verificationType.hpp	1.17 07/05/05 17:07:01 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/verifier.cpp openjdk/hotspot/src/share/vm/classfile/verifier.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/verifier.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/verifier.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)verifier.cpp	1.113 07/05/23 10:53:19 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/verifier.hpp openjdk/hotspot/src/share/vm/classfile/verifier.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/verifier.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/verifier.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)verifier.hpp	1.41 07/05/05 17:07:02 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/vmSymbols.cpp openjdk/hotspot/src/share/vm/classfile/vmSymbols.cpp
+--- openjdk6/hotspot/src/share/vm/classfile/vmSymbols.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/vmSymbols.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vmSymbols.cpp	1.28 07/05/17 15:50:36 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -35,7 +32,8 @@
+ 
+ inline int compare_symbol(symbolOop a, symbolOop b) {
+   if (a == b)  return 0;
+-  return (intptr_t)a > (intptr_t)b ? +1 : -1;
++  // follow the natural address order:
++  return (address)a > (address)b ? +1 : -1;
+ }
+ 
+ static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT];
+diff -ruNb openjdk6/hotspot/src/share/vm/classfile/vmSymbols.hpp openjdk/hotspot/src/share/vm/classfile/vmSymbols.hpp
+--- openjdk6/hotspot/src/share/vm/classfile/vmSymbols.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/classfile/vmSymbols.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vmSymbols.hpp	1.162 07/05/17 15:50:40 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -97,6 +94,8 @@
+   template(java_lang_Compiler,                        "java/lang/Compiler")                       \
+   template(sun_misc_Signal,                           "sun/misc/Signal")                          \
+   template(java_lang_AssertionStatusDirectives,       "java/lang/AssertionStatusDirectives")      \
++  template(sun_jkernel_DownloadManager,               "sun/jkernel/DownloadManager")                 \
++  template(getBootClassPathEntryForClass_name,        "getBootClassPathEntryForClass")            \
+                                                                                                   \
+   /* class file format tags */                                                                    \
+   template(tag_source_file,                           "SourceFile")                               \
+diff -ruNb openjdk6/hotspot/src/share/vm/code/codeBlob.cpp openjdk/hotspot/src/share/vm/code/codeBlob.cpp
+--- openjdk6/hotspot/src/share/vm/code/codeBlob.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/codeBlob.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)codeBlob.cpp	1.128 07/05/05 17:05:19 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/codeBlob.hpp openjdk/hotspot/src/share/vm/code/codeBlob.hpp
+--- openjdk6/hotspot/src/share/vm/code/codeBlob.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/codeBlob.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)codeBlob.hpp	1.125 07/05/05 17:05:18 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/codeCache.cpp openjdk/hotspot/src/share/vm/code/codeCache.cpp
+--- openjdk6/hotspot/src/share/vm/code/codeCache.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/codeCache.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)codeCache.cpp	1.132 07/05/05 17:05:19 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -358,7 +355,7 @@
+ #endif // PRODUCT
+ 
+ 
+-int CodeCache::mark_for_deoptimization(klassOop dependee) {
++int CodeCache::mark_for_deoptimization(DepChange& changes) {
+   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+   
+ #ifndef PRODUCT
+@@ -369,26 +366,27 @@
+   int number_of_marked_CodeBlobs = 0;
+ 
+   // search the hierarchy looking for nmethods which are affected by the loading of this class
+-  for (klassOop d = dependee; d != NULL; d = instanceKlass::cast(d)->super()) {
+-    number_of_marked_CodeBlobs += instanceKlass::cast(d)->mark_dependent_nmethods(dependee);
+-  }
++
+   // then search the interfaces this class implements looking for nmethods
+   // which might be dependent of the fact that an interface only had one
+   // implementor.
+-  objArrayOop interfaces = instanceKlass::cast(dependee)->transitive_interfaces();
+-  int number_of_interfaces = interfaces->length();
+-  for (int interface_index = 0; interface_index < number_of_interfaces; interface_index += 1) {
+-    klassOop d = klassOop(interfaces->obj_at(interface_index));
+-    number_of_marked_CodeBlobs += instanceKlass::cast(d)->mark_dependent_nmethods(dependee);
++
++  { No_Safepoint_Verifier nsv;
++    for (DepChange::ContextStream str(changes, nsv); str.next(); ) {
++      klassOop d = str.klass();
++      number_of_marked_CodeBlobs += instanceKlass::cast(d)->mark_dependent_nmethods(changes);
++    }
+   }
+ 
+   if (VerifyDependencies) {
++    // Turn off dependency tracing while actually testing deps.
++    NOT_PRODUCT( FlagSetting fs(TraceDependencies, false) );
+     FOR_ALL_ALIVE_NMETHODS(nm) {
+       if (!nm->is_marked_for_deoptimization() &&
+-          nm->is_dependent_on(NULL)) {
++          nm->check_all_dependencies()) {
+         ResourceMark rm;
+         tty->print_cr("Should have been marked for deoptimization:");
+-        tty->print_cr("  dependee = %s", instanceKlass::cast(dependee)->external_name());
++        changes.print();
+         nm->print();
+         nm->print_dependencies();
+       }
+diff -ruNb openjdk6/hotspot/src/share/vm/code/codeCache.hpp openjdk/hotspot/src/share/vm/code/codeCache.hpp
+--- openjdk6/hotspot/src/share/vm/code/codeCache.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/codeCache.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)codeCache.hpp	1.67 07/05/05 17:05:18 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -35,6 +32,7 @@
+ //     locating a method given a addess of an instruction.
+ 
+ class OopClosure;
++class DepChange;
+ 
+ class CodeCache : AllStatic {
+   friend class VMStructs;
+@@ -116,7 +114,7 @@
+   static void clear_inline_caches();             // clear all inline caches
+ 
+   // Deoptimization
+-  static int  mark_for_deoptimization(klassOop dependee);
++  static int  mark_for_deoptimization(DepChange& changes);
+ #ifdef HOTSWAP
+   static int  mark_for_evol_deoptimization(instanceKlassHandle dependee);
+ #endif // HOTSWAP
+diff -ruNb openjdk6/hotspot/src/share/vm/code/compiledIC.cpp openjdk/hotspot/src/share/vm/code/compiledIC.cpp
+--- openjdk6/hotspot/src/share/vm/code/compiledIC.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/compiledIC.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compiledIC.cpp	1.157 07/05/05 17:05:18 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/compiledIC.hpp openjdk/hotspot/src/share/vm/code/compiledIC.hpp
+--- openjdk6/hotspot/src/share/vm/code/compiledIC.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/compiledIC.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compiledIC.hpp	1.52 07/05/05 17:05:19 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -242,5 +239,3 @@
+ inline CompiledStaticCall* compiledStaticCall_at(Relocation* call_site) {
+   return compiledStaticCall_at(call_site->addr());
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/compressedStream.cpp openjdk/hotspot/src/share/vm/code/compressedStream.cpp
+--- openjdk6/hotspot/src/share/vm/code/compressedStream.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/compressedStream.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compressedStream.cpp	1.27 07/05/05 17:05:20 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/compressedStream.hpp openjdk/hotspot/src/share/vm/code/compressedStream.hpp
+--- openjdk6/hotspot/src/share/vm/code/compressedStream.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/compressedStream.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compressedStream.hpp	1.27 07/05/05 17:05:20 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/debugInfo.cpp openjdk/hotspot/src/share/vm/code/debugInfo.cpp
+--- openjdk6/hotspot/src/share/vm/code/debugInfo.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/debugInfo.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)debugInfo.cpp	1.34 07/05/05 17:05:19 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -36,14 +33,43 @@
+ }
+ 
+ // Serializing oops
++
+ void DebugInfoWriteStream::write_handle(jobject h) {
+   write_int(recorder()->oop_recorder()->find_index(h));
+ }
+ 
++ScopeValue* DebugInfoReadStream::read_object_value() {
++  int id = read_int();
++#ifdef ASSERT
++  assert(_obj_pool != NULL, "object pool does not exist");
++  for (int i = _obj_pool->length() - 1; i >= 0; i--) {
++    assert(((ObjectValue*) _obj_pool->at(i))->id() != id, "should not be read twice");
++  }
++#endif
++  ObjectValue* result = new ObjectValue(id);
++  _obj_pool->append(result);
++  result->read_object(this);
++  return result;
++}
++
++ScopeValue* DebugInfoReadStream::get_cached_object() {
++  int id = read_int();
++  assert(_obj_pool != NULL, "object pool does not exist");
++  for (int i = _obj_pool->length() - 1; i >= 0; i--) {
++    ObjectValue* sv = (ObjectValue*) _obj_pool->at(i);
++    if (sv->id() == id) {
++      return sv;
++    }
++  }
++  ShouldNotReachHere();
++  return NULL;
++}
++
+ // Serializing scope values
+ 
+ enum { LOCATION_CODE = 0, CONSTANT_INT_CODE = 1,  CONSTANT_OOP_CODE = 2,
+-                          CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4 };
++                          CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4,
++                          OBJECT_CODE = 5,        OBJECT_ID_CODE = 6 };
+ 
+ ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) {
+   ScopeValue* result = NULL;
+@@ -53,6 +79,8 @@
+    case CONSTANT_OOP_CODE:    result = new ConstantOopReadValue(stream); break;
+    case CONSTANT_LONG_CODE:   result = new ConstantLongValue(stream);    break;
+    case CONSTANT_DOUBLE_CODE: result = new ConstantDoubleValue(stream);  break;
++   case OBJECT_CODE:          result = stream->read_object_value();      break;
++   case OBJECT_ID_CODE:       result = stream->get_cached_object();      break;
+    default: ShouldNotReachHere();            
+   }
+   return result;
+@@ -73,6 +101,51 @@
+   location().print_on(st);
+ }
+ 
++// ObjectValue
++
++void ObjectValue::read_object(DebugInfoReadStream* stream) {
++  _klass = read_from(stream);
++  assert(_klass->is_constant_oop(), "should be constant klass oop");
++  int length = stream->read_int();
++  for (int i = 0; i < length; i++) {
++    ScopeValue* val = read_from(stream);
++    _field_values.append(val);
++  }
++}
++
++void ObjectValue::write_on(DebugInfoWriteStream* stream) {
++  if (_visited) {
++    stream->write_int(OBJECT_ID_CODE);
++    stream->write_int(_id);
++  } else {
++    _visited = true;
++    stream->write_int(OBJECT_CODE);
++    stream->write_int(_id);
++    _klass->write_on(stream);
++    int length = _field_values.length();
++    stream->write_int(length);
++    for (int i = 0; i < length; i++) {
++      _field_values.at(i)->write_on(stream);
++    }
++  }
++}
++
++void ObjectValue::print_on(outputStream* st) const {
++  st->print("obj[%d]", _id);
++}
++
++void ObjectValue::print_fields_on(outputStream* st) const {
++#ifndef PRODUCT
++  if (_field_values.length() > 0) {
++    _field_values.at(0)->print_on(st);
++  }
++  for (int i = 1; i < _field_values.length(); i++) {
++    st->print(", ");
++    _field_values.at(i)->print_on(st);
++  }
++#endif
++}
++
+ // ConstantIntValue
+ 
+ ConstantIntValue::ConstantIntValue(DebugInfoReadStream* stream) {
+@@ -147,19 +220,22 @@
+ 
+ // MonitorValue
+ 
+-MonitorValue::MonitorValue(ScopeValue* owner, Location basic_lock) {
++MonitorValue::MonitorValue(ScopeValue* owner, Location basic_lock, bool eliminated) {
+   _owner       = owner;
+   _basic_lock  = basic_lock;
++  _eliminated  = eliminated;
+ }
+ 
+ MonitorValue::MonitorValue(DebugInfoReadStream* stream) {
+   _basic_lock  = Location(stream);
+   _owner       = ScopeValue::read_from(stream);
++  _eliminated  = (stream->read_bool() != 0);
+ }
+ 
+ void MonitorValue::write_on(DebugInfoWriteStream* stream) {
+   _basic_lock.write_on(stream);
+   _owner->write_on(stream);
++  stream->write_bool(_eliminated);
+ }
+ 
+ #ifndef PRODUCT
+@@ -169,6 +245,8 @@
+   st->print(",");
+   basic_lock().print_on(st);
+   st->print("}");
++  if (_eliminated) {
++    st->print(" (eliminated)");
++  }
+ }
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/debugInfo.hpp openjdk/hotspot/src/share/vm/code/debugInfo.hpp
+--- openjdk6/hotspot/src/share/vm/code/debugInfo.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/debugInfo.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)debugInfo.hpp	1.34 07/05/05 17:05:20 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -37,6 +34,7 @@
+  public:
+   // Testers
+   virtual bool is_location() const { return false; }
++  virtual bool is_object() const { return false; }
+   virtual bool is_constant_int() const { return false; }
+   virtual bool is_constant_double() const { return false; }
+   virtual bool is_constant_long() const { return false; }
+@@ -68,6 +66,57 @@
+   void print_on(outputStream* st) const;
+ };
+ 
++
++// An ObjectValue describes an object eliminated by escape analysis.
++
++class ObjectValue: public ScopeValue {
++ private:
++  int                        _id;
++  ScopeValue*                _klass;
++  GrowableArray<ScopeValue*> _field_values;
++  Handle                     _value;
++  bool                       _visited;
++
++ public:
++  ObjectValue(int id, ScopeValue* klass)
++     : _id(id)
++     , _klass(klass)
++     , _field_values()
++     , _value()
++     , _visited(false) {
++    assert(klass->is_constant_oop(), "should be constant klass oop");
++  }
++
++  ObjectValue(int id)
++     : _id(id)
++     , _klass(NULL)
++     , _field_values()
++     , _value()
++     , _visited(false) {}
++
++  // Accessors
++  bool                        is_object() const         { return true; }
++  int                         id() const                { return _id; }
++  ScopeValue*                 klass() const             { return _klass; }
++  GrowableArray<ScopeValue*>* field_values()            { return &_field_values; }
++  ScopeValue*                 field_at(int i) const     { return _field_values.at(i); }
++  int                         field_size()              { return _field_values.length(); }
++  Handle                      value() const             { return _value; }
++  bool                        is_visited() const        { return _visited; }
++
++  void                        set_value(oop value)      { _value = Handle(value); }
++  void                        set_visited(bool visited) { _visited = false; }
++
++  // Serialization of debugging information
++  void read_object(DebugInfoReadStream* stream);
++  void write_on(DebugInfoWriteStream* stream);
++
++  // Printing
++  void print_on(outputStream* st) const;
++  void print_fields_on(outputStream* st) const;
++};
++
++
+ // A ConstantIntValue describes a constant int; i.e., the corresponding logical entity
+ // is either a source constant or its computation has been constant-folded.
+ 
+@@ -166,13 +215,15 @@
+  private:
+   ScopeValue* _owner;
+   Location    _basic_lock;
++  bool        _eliminated;
+  public:
+   // Constructor
+-  MonitorValue(ScopeValue* owner, Location basic_lock);
++  MonitorValue(ScopeValue* owner, Location basic_lock, bool eliminated = false);
+ 
+   // Accessors
+   ScopeValue*  owner()      const { return _owner; }
+   Location     basic_lock() const { return _basic_lock;  }
++  bool         eliminated() const { return _eliminated; }
+ 
+   // Serialization of debugging information
+   MonitorValue(DebugInfoReadStream* stream);
+@@ -189,15 +240,20 @@
+  private:
+   const nmethod* _code;
+   const nmethod* code() const { return _code; }
++  GrowableArray<ScopeValue*>* _obj_pool;
+  public:
+-  DebugInfoReadStream(const nmethod* code, int offset) :
++  DebugInfoReadStream(const nmethod* code, int offset, GrowableArray<ScopeValue*>* obj_pool = NULL) :
+     CompressedReadStream(code->scopes_data_begin(), offset) { 
+     _code = code; 
++    _obj_pool = obj_pool;
++
+   } ;
+ 
+   oop read_oop() { 
+     return code()->oop_at(read_int()); 
+   } 
++  ScopeValue* read_object_value();
++  ScopeValue* get_cached_object();
+   // BCI encoding is mostly unsigned, but -1 is a distinguished value
+   int read_bci() { return read_int() + InvocationEntryBci; }
+ };
+@@ -214,4 +270,3 @@
+   void write_handle(jobject h);
+   void write_bci(int bci) { write_int(bci - InvocationEntryBci); }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/debugInfoRec.cpp openjdk/hotspot/src/share/vm/code/debugInfoRec.cpp
+--- openjdk6/hotspot/src/share/vm/code/debugInfoRec.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/debugInfoRec.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)debugInfoRec.cpp	1.54 07/05/05 17:05:20 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -168,7 +165,8 @@
+   }
+   assert(_pcs_size > _pcs_length, "There must be room for after expanding");
+ 
+-  _pcs[_pcs_length++] = PcDesc(pc_offset, DebugInformationRecorder::serialized_null);
++  _pcs[_pcs_length++] = PcDesc(pc_offset, DebugInformationRecorder::serialized_null,
++                               DebugInformationRecorder::serialized_null);
+ }
+ 
+ 
+@@ -324,6 +322,18 @@
+   }
+ }
+ 
++void DebugInformationRecorder::dump_object_pool(GrowableArray<ScopeValue*>* objects) {
++  guarantee( _pcs_length > 0, "safepoint must exist before describing scopes");
++  PcDesc* last_pd = &_pcs[_pcs_length-1];
++  if (objects != NULL) {
++    for (int i = objects->length() - 1; i >= 0; i--) {
++      ((ObjectValue*) objects->at(i))->set_visited(false);
++    }
++  }
++  int offset = serialize_scope_values(objects);
++  last_pd->set_obj_decode_offset(offset);
++}
++
+ void DebugInformationRecorder::end_scopes(int pc_offset, bool is_safepoint) {
+   assert(_recording_state == (is_safepoint? rs_safepoint: rs_non_safepoint),
+          "nesting of recording calls");
+diff -ruNb openjdk6/hotspot/src/share/vm/code/debugInfoRec.hpp openjdk/hotspot/src/share/vm/code/debugInfoRec.hpp
+--- openjdk6/hotspot/src/share/vm/code/debugInfoRec.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/debugInfoRec.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)debugInfoRec.hpp	1.37 07/05/05 17:05:20 JVM"
+-#endif
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -94,6 +91,9 @@
+                       DebugToken* expressions = NULL,
+                       DebugToken* monitors    = NULL);
+ 
++
++  void dump_object_pool(GrowableArray<ScopeValue*>* objects);
++
+   // This call must follow every add_safepoint,
+   // after any intervening describe_scope calls.
+   void end_safepoint(int pc_offset)      { end_scopes(pc_offset, true); }
+@@ -180,4 +180,3 @@
+  public:
+   enum { serialized_null = 0 };
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/dependencies.cpp openjdk/hotspot/src/share/vm/code/dependencies.cpp
+--- openjdk6/hotspot/src/share/vm/code/dependencies.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/dependencies.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)dependencies.cpp	1.16 07/05/05 17:05:20 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -791,53 +788,147 @@
+ 
+  private:
+   // the actual search method:
+-  klassOop find_witness(klassOop context_type,
+-                        bool search_under_participants,
+-                        bool test_context_type);
++  klassOop find_witness_anywhere(klassOop context_type,
++                                 bool participants_hide_witnesses,
++                                 bool top_level_call = true);
++  // the spot-checking version:
++  klassOop find_witness_in(DepChange& changes,
++                           klassOop context_type,
++                           bool participants_hide_witnesses);
+  public:
+-  klassOop find_witness_subtype(klassOop context_type) {
++  klassOop find_witness_subtype(klassOop context_type, DepChange* changes = NULL) {
+     assert(doing_subtype_search(), "must set up a subtype search");
+     // When looking for unexpected concrete types,
+     // do not look beneath expected ones.
++    const bool participants_hide_witnesses = true;
+     // CX > CC > C' is OK, even if C' is new.
+     // CX > { CC,  C' } is not OK if C' is new, and C' is the witness.
+-    return find_witness(context_type, false, true);
++    if (changes != NULL) {
++      return find_witness_in(*changes, context_type, participants_hide_witnesses);
++    } else {
++      return find_witness_anywhere(context_type, participants_hide_witnesses);
++    }
+   }
+-  klassOop find_witness_definer(klassOop context_type) {
++  klassOop find_witness_definer(klassOop context_type, DepChange* changes = NULL) {
+     assert(!doing_subtype_search(), "must set up a method definer search");
+     // When looking for unexpected concrete methods,
+     // look beneath expected ones, to see if there are overrides.
++    const bool participants_hide_witnesses = true;
+     // CX.m > CC.m > C'.m is not OK, if C'.m is new, and C' is the witness.
+-    return find_witness(context_type, true, true);
++    if (changes != NULL) {
++      return find_witness_in(*changes, context_type, !participants_hide_witnesses);
++    } else {
++      return find_witness_anywhere(context_type, !participants_hide_witnesses);
++    }
+   }
+ };
+ 
+-#ifdef ASSERT
++#ifndef PRODUCT
+ static int deps_find_witness_calls = 0;
+ static int deps_find_witness_steps = 0;
+ static int deps_find_witness_recursions = 0;
+-#endif //ASSERT
++static int deps_find_witness_singles = 0;
++static int deps_find_witness_print = 0; // set to -1 to force a final print
++static bool count_find_witness_calls() {
++  if (TraceDependencies || LogCompilation) {
++    int pcount = deps_find_witness_print + 1;
++    bool final_stats      = (pcount == 0);
++    bool initial_call     = (pcount == 1);
++    bool occasional_print = ((pcount & ((1<<10) - 1)) == 0);
++    if (pcount < 0)  pcount = 1; // crude overflow protection
++    deps_find_witness_print = pcount;
++    if (VerifyDependencies && initial_call) {
++      tty->print_cr("Warning:  TraceDependencies results may be inflated by VerifyDependencies");
++    }
++    if (occasional_print || final_stats) {
++      // Every now and then dump a little info about dependency searching.
++      if (xtty != NULL) {
++        xtty->elem("deps_find_witness calls='%d' steps='%d' recursions='%d' singles='%d'",
++                   deps_find_witness_calls,
++                   deps_find_witness_steps,
++                   deps_find_witness_recursions,
++                   deps_find_witness_singles);
++      }
++      if (final_stats || (TraceDependencies && WizardMode)) {
++        tty->print_cr("Dependency check (find_witness) "
++                      "calls=%d, steps=%d (avg=%.1f), recursions=%d, singles=%d",
++                      deps_find_witness_calls,
++                      deps_find_witness_steps,
++                      (double)deps_find_witness_steps / deps_find_witness_calls,
++                      deps_find_witness_recursions,
++                      deps_find_witness_singles);
++      }
++    }
++    return true;
++  }
++  return false;
++}
++#else
++#define count_find_witness_calls() (0)
++#endif //PRODUCT
++
++
++klassOop ClassHierarchyWalker::find_witness_in(DepChange& changes,
++                                               klassOop context_type,
++                                               bool participants_hide_witnesses) {
++  assert(changes.involves_context(context_type), "irrelevant dependency");
++  klassOop new_type = changes.new_type();
++
++  count_find_witness_calls();
++  NOT_PRODUCT(deps_find_witness_singles++);
++
++  // Current thread must be in VM (not native mode, as in CI):
++  assert(must_be_in_vm(), "raw oops here");
++  // Must not move the class hierarchy during this check:
++  assert_locked_or_safepoint(Compile_lock);
++
++  assert(!is_participant(new_type), "only old classes are participants");
++  if (participants_hide_witnesses) {
++    // If the new type is a subtype of a participant, we are done.
++    for (int i = 0; i < num_participants(); i++) {
++      klassOop part = participant(i);
++      if (part == NULL)  continue;
++      assert(changes.involves_context(part) == Klass::cast(new_type)->is_subtype_of(part),
++             "correct marking of participants, b/c new_type is unique");
++      if (changes.involves_context(part)) {
++        // new guy is protected from this check by previous participant
++        return NULL;
++      }
++    }
++  }
++
++  if (is_witness(new_type) &&
++      !ignore_witness(new_type)) {
++    return new_type;
++  }
++
++  return NULL;
++}
++
+ 
+ // Walk hierarchy under a context type, looking for unexpected types.
+ // Do not report participant types, and recursively walk beneath
+-// them only if search_under_participants is true.
+-// If test_context_type is false, skip testing the context type,
++// them only if participants_hide_witnesses is false.
++// If top_level_call is false, skip testing the context type,
+ // because the caller has already considered it.
+-klassOop ClassHierarchyWalker::find_witness(klassOop context_type,
+-                                            bool search_under_participants,
+-                                            bool test_context_type) {
+-  DEBUG_ONLY(deps_find_witness_calls++);
+-
++klassOop ClassHierarchyWalker::find_witness_anywhere(klassOop context_type,
++                                                     bool participants_hide_witnesses,
++                                                     bool top_level_call) {
+   // Current thread must be in VM (not native mode, as in CI):
+   assert(must_be_in_vm(), "raw oops here");
+   // Must not move the class hierarchy during this check:
+   assert_locked_or_safepoint(Compile_lock);
+ 
++  bool do_counts = count_find_witness_calls();
++
+   // Check the root of the sub-hierarchy first.
+-  if (test_context_type) {
+-    DEBUG_ONLY(deps_find_witness_steps++);
++  if (top_level_call) {
++    if (do_counts) {
++      NOT_PRODUCT(deps_find_witness_calls++);
++      NOT_PRODUCT(deps_find_witness_steps++);
++    }
+     if (is_participant(context_type)) {
+-      if (!search_under_participants)  return NULL;
++      if (participants_hide_witnesses)  return NULL;
+       // else fall through to search loop...
+     } else if (is_witness(context_type) && !ignore_witness(context_type)) {
+       // The context is an abstract class or interface, to start with.
+@@ -882,9 +973,10 @@
+       // implementors array overflowed => no exact info.
+       return context_type;  // report an inexact witness to this sad affair
+     }
+-    DEBUG_ONLY(deps_find_witness_steps++);
++    if (do_counts)
++      { NOT_PRODUCT(deps_find_witness_steps++); }
+     if (is_participant(impl)) {
+-      if (!search_under_participants)  continue;
++      if (participants_hide_witnesses)  continue;
+       // else fall through to process this guy's subclasses
+     } else if (is_witness(impl) && !ignore_witness(impl)) {
+       return impl;
+@@ -897,9 +989,9 @@
+     Klass* chain = chains[--chaini];
+     for (Klass* subk = chain; subk != NULL; subk = subk->next_sibling()) {
+       klassOop sub = subk->as_klassOop();
+-      DEBUG_ONLY(deps_find_witness_steps++);
++      if (do_counts) { NOT_PRODUCT(deps_find_witness_steps++); }
+       if (is_participant(sub)) {
+-        if (!search_under_participants)  continue;
++        if (participants_hide_witnesses)  continue;
+         // else fall through to process this guy's subclasses
+       } else if (is_witness(sub) && !ignore_witness(sub)) {
+         return sub;
+@@ -913,8 +1005,10 @@
+         // (Note that sub has already been tested, so that there is
+         // no need for the recursive call to re-test.  That's handy,
+         // since the recursive call sees sub as the context_type.)
+-        DEBUG_ONLY(deps_find_witness_recursions++);
+-        klassOop witness = find_witness(sub, search_under_participants, false);
++        if (do_counts) { NOT_PRODUCT(deps_find_witness_recursions++); }
++        klassOop witness = find_witness_anywhere(sub,
++                                                 participants_hide_witnesses,
++                                                 /*top_level_call=*/ false);
+         if (witness != NULL)  return witness;
+       }
+     }
+@@ -925,6 +1019,7 @@
+ #undef ADD_SUBCLASS_CHAIN
+ }
+ 
++
+ bool Dependencies::is_concrete_klass(klassOop k) {
+   if (Klass::cast(k)->is_abstract())  return false;
+   // %%% We could treat classes which are concrete but
+@@ -1023,27 +1118,30 @@
+ // This allows the compiler to narrow occurrences of ctxk by conck,
+ // when dealing with the types of actual instances.
+ klassOop Dependencies::check_abstract_with_unique_concrete_subtype(klassOop ctxk,
+-                                                                   klassOop conck) {
++                                                                   klassOop conck,
++                                                                   DepChange* changes) {
+   ClassHierarchyWalker wf(conck);
+-  return wf.find_witness_subtype(ctxk);
++  return wf.find_witness_subtype(ctxk, changes);
+ }
+ 
+ // If a non-concrete class has no concrete subtypes, it is not (yet)
+ // instantiatable.  This can allow the compiler to make some paths go
+ // dead, if they are gated by a test of the type.
+-klassOop Dependencies::check_abstract_with_no_concrete_subtype(klassOop ctxk) {
++klassOop Dependencies::check_abstract_with_no_concrete_subtype(klassOop ctxk,
++                                                               DepChange* changes) {
+   // Find any concrete subtype, with no participants:
+   ClassHierarchyWalker wf;
+-  return wf.find_witness_subtype(ctxk);
++  return wf.find_witness_subtype(ctxk, changes);
+ }
+ 
+ 
+ // If a concrete class has no concrete subtypes, it can always be
+ // exactly typed.  This allows the use of a cheaper type test.
+-klassOop Dependencies::check_concrete_with_no_concrete_subtype(klassOop ctxk) {
++klassOop Dependencies::check_concrete_with_no_concrete_subtype(klassOop ctxk,
++                                                               DepChange* changes) {
+   // Find any concrete subtype, with only the ctxk as participant:
+   ClassHierarchyWalker wf(ctxk);
+-  return wf.find_witness_subtype(ctxk);
++  return wf.find_witness_subtype(ctxk, changes);
+ }
+ 
+ 
+@@ -1062,6 +1160,8 @@
+ #ifndef PRODUCT
+     // Make sure the dependency mechanism will pass this discovery:
+     if (VerifyDependencies) {
++      // Turn off dependency tracing while actually testing deps.
++      FlagSetting fs(TraceDependencies, false);
+       if (!Dependencies::is_concrete_klass(ctxk)) {
+         guarantee(NULL ==
+                   (void *)check_abstract_with_no_concrete_subtype(ctxk),
+@@ -1078,6 +1178,8 @@
+ #ifndef PRODUCT
+     // Make sure the dependency mechanism will pass this discovery:
+     if (VerifyDependencies) {
++      // Turn off dependency tracing while actually testing deps.
++      FlagSetting fs(TraceDependencies, false);
+       if (!Dependencies::is_concrete_klass(ctxk)) {
+         guarantee(NULL == (void *)
+                   check_abstract_with_unique_concrete_subtype(ctxk, conck),
+@@ -1096,11 +1198,12 @@
+ klassOop Dependencies::check_abstract_with_exclusive_concrete_subtypes(
+                                                 klassOop ctxk,
+                                                 klassOop k1,
+-                                                klassOop k2) {
++                                                klassOop k2,
++                                                DepChange* changes) {
+   ClassHierarchyWalker wf;
+   wf.add_participant(k1);
+   wf.add_participant(k2);
+-  return wf.find_witness_subtype(ctxk);
++  return wf.find_witness_subtype(ctxk, changes);
+ }
+ 
+ // Search ctxk for concrete implementations.  If there are klen or fewer,
+@@ -1124,6 +1227,8 @@
+ #ifndef PRODUCT
+   // Make sure the dependency mechanism will pass this discovery:
+   if (VerifyDependencies) {
++    // Turn off dependency tracing while actually testing deps.
++    FlagSetting fs(TraceDependencies, false);
+     switch (Dependencies::is_concrete_klass(ctxk)? -1: num) {
+     case -1: // ctxk was itself concrete
+       guarantee(num == 1 && karray[0] == ctxk, "verify dep.");
+@@ -1154,13 +1259,14 @@
+ 
+ // If a class (or interface) has a unique concrete method uniqm, return NULL.
+ // Otherwise, return a class that contains an interfering method.
+-klassOop Dependencies::check_unique_concrete_method(klassOop ctxk, methodOop uniqm) {
++klassOop Dependencies::check_unique_concrete_method(klassOop ctxk, methodOop uniqm,
++                                                    DepChange* changes) {
+   // Here is a missing optimization:  If uniqm->is_final(),
+   // we don't really need to search beneath it for overrides.
+   // This is probably not important, since we don't use dependencies
+   // to track final methods.  (They can't be "definalized".)
+   ClassHierarchyWalker wf(uniqm->method_holder(), uniqm);
+-  return wf.find_witness_definer(ctxk);
++  return wf.find_witness_definer(ctxk, changes);
+ }
+ 
+ // Find the set of all non-abstract methods under ctxk that match m.
+@@ -1196,11 +1302,12 @@
+ 
+ klassOop Dependencies::check_exclusive_concrete_methods(klassOop ctxk,
+                                                         methodOop m1,
+-                                                        methodOop m2) {
++                                                        methodOop m2,
++                                                        DepChange* changes) {
+   ClassHierarchyWalker wf(m1);
+   wf.add_participant(m1->method_holder());
+   wf.add_participant(m2->method_holder());
+-  return wf.find_witness_definer(ctxk);
++  return wf.find_witness_definer(ctxk, changes);
+ }
+ 
+ // Find the set of all non-abstract methods under ctxk that match m[0].
+@@ -1216,6 +1323,7 @@
+   ClassHierarchyWalker wf(m0);
+   assert(wf.check_method_context(ctxk, m0), "proper context");
+   wf.record_witnesses(mlen);
++  bool participants_hide_witnesses = true;
+   klassOop wit = wf.find_witness_definer(ctxk);
+   if (wit != NULL)  return -1;  // Too many witnesses.
+   int num = wf.num_participants();
+@@ -1236,6 +1344,8 @@
+ #ifndef PRODUCT
+   // Make sure the dependency mechanism will pass this discovery:
+   if (VerifyDependencies) {
++    // Turn off dependency tracing while actually testing deps.
++    FlagSetting fs(TraceDependencies, false);
+     switch (mfill) {
+     case 1:
+       guarantee(NULL == (void *)check_unique_concrete_method(ctxk, marray[0]),
+@@ -1255,8 +1365,11 @@
+ }
+ 
+ 
+-klassOop Dependencies::check_has_no_finalizable_subclasses(klassOop ctxk) {
+-  Klass* result = find_finalizable_subclass(ctxk->klass_part());
++klassOop Dependencies::check_has_no_finalizable_subclasses(klassOop ctxk, DepChange* changes) {
++  Klass* search_at = ctxk->klass_part();
++  if (changes != NULL)
++    search_at = changes->new_type()->klass_part(); // just look at the new bit
++  Klass* result = find_finalizable_subclass(search_at);
+   if (result == NULL) {
+     return NULL;
+   }
+@@ -1264,7 +1377,7 @@
+ }
+ 
+ 
+-klassOop Dependencies::DepStream::check_dependency() {
++klassOop Dependencies::DepStream::check_dependency_impl(DepChange* changes) {
+   assert_locked_or_safepoint(Compile_lock);
+ 
+   klassOop witness = NULL;
+@@ -1277,30 +1390,37 @@
+     break;
+   case abstract_with_unique_concrete_subtype:
+     witness = check_abstract_with_unique_concrete_subtype(context_type(),
+-                                                          type_argument(1));
++                                                          type_argument(1),
++                                                          changes);
+     break;
+   case abstract_with_no_concrete_subtype:
+-    witness = check_abstract_with_no_concrete_subtype(context_type());
++    witness = check_abstract_with_no_concrete_subtype(context_type(),
++                                                      changes);
+     break;
+   case concrete_with_no_concrete_subtype:
+-    witness = check_concrete_with_no_concrete_subtype(context_type());
++    witness = check_concrete_with_no_concrete_subtype(context_type(),
++                                                      changes);
+     break;
+   case unique_concrete_method:
+     witness = check_unique_concrete_method(context_type(),
+-                                           method_argument(1));
++                                           method_argument(1),
++                                           changes);
+     break;
+   case abstract_with_exclusive_concrete_subtypes_2:
+     witness = check_abstract_with_exclusive_concrete_subtypes(context_type(),
+                                                               type_argument(1),
+-                                                              type_argument(2));
++                                                              type_argument(2),
++                                                              changes);
+     break;
+   case exclusive_concrete_methods_2:
+     witness = check_exclusive_concrete_methods(context_type(),
+                                                method_argument(1),
+-                                               method_argument(2));
++                                               method_argument(2),
++                                               changes);
+     break;
+   case no_finalizable_subclasses:
+-    witness = check_has_no_finalizable_subclasses(context_type());
++    witness = check_has_no_finalizable_subclasses(context_type(),
++                                                  changes);
+     break;
+ 	  default:
+     witness = NULL;
+@@ -1316,3 +1436,114 @@
+   }
+   return witness;
+ }
++
++
++klassOop Dependencies::DepStream::spot_check_dependency_at(DepChange& changes) {
++  if (!changes.involves_context(context_type()))
++    // irrelevant dependency; skip it
++    return NULL;
++
++  return check_dependency_impl(&changes);
++}
++
++
++void DepChange::initialize() {
++  // entire transaction must be under this lock:
++  assert_lock_strong(Compile_lock);
++
++  // Mark all dependee and all its superclasses
++  // Mark transitive interfaces
++  for (ContextStream str(*this); str.next(); ) {
++    klassOop d = str.klass();
++    assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking");
++    instanceKlass::cast(d)->set_is_marked_dependent(true);
++  }
++}
++
++DepChange::~DepChange() {
++  // Unmark all dependee and all its superclasses
++  // Unmark transitive interfaces
++  for (ContextStream str(*this); str.next(); ) {
++    klassOop d = str.klass();
++    instanceKlass::cast(d)->set_is_marked_dependent(false);
++  }
++}
++
++bool DepChange::involves_context(klassOop k) {
++  if (k == NULL || !Klass::cast(k)->oop_is_instance()) {
++    return false;
++  }
++  instanceKlass* ik = instanceKlass::cast(k);
++  bool is_contained = ik->is_marked_dependent();
++  assert(is_contained == Klass::cast(new_type())->is_subtype_of(k),
++         "correct marking of potential context types");
++  return is_contained;
++}
++
++bool DepChange::ContextStream::next() {
++  switch (_change_type) {
++  case Start_Klass:             // initial state; _klass is the new type
++    _ti_base = instanceKlass::cast(_klass)->transitive_interfaces();
++    _ti_index = 0;
++    _change_type = Change_new_type;
++    return true;
++  case Change_new_type:
++    // fall through:
++    _change_type = Change_new_sub;
++  case Change_new_sub:
++    _klass = instanceKlass::cast(_klass)->super();
++    if (_klass != NULL) {
++      return true;
++    }
++    // else set up _ti_limit and fall through:
++    _ti_limit = (_ti_base == NULL) ? 0 : _ti_base->length();
++    _change_type = Change_new_impl;
++  case Change_new_impl:
++    if (_ti_index < _ti_limit) {
++      _klass = klassOop( _ti_base->obj_at(_ti_index++) );
++      return true;
++    }
++    // fall through:
++    _change_type = NO_CHANGE;  // iterator is exhausted
++  case NO_CHANGE:
++    break;
++  default:
++    ShouldNotReachHere();
++  }
++  return false;
++}
++
++void DepChange::print() {
++  int nsup = 0, nint = 0;
++  for (ContextStream str(*this); str.next(); ) {
++    klassOop k = str.klass();
++    switch (str._change_type) {
++    case Change_new_type:
++      tty->print_cr("  dependee = %s", instanceKlass::cast(k)->external_name());
++      break;
++    case Change_new_sub:
++      if (!WizardMode)
++           ++nsup;
++      else tty->print_cr("  context super = %s", instanceKlass::cast(k)->external_name());
++      break;
++    case Change_new_impl:
++      if (!WizardMode)
++           ++nint;
++      else tty->print_cr("  context interface = %s", instanceKlass::cast(k)->external_name());
++      break;
++    }
++  }
++  if (nsup + nint != 0) {
++    tty->print_cr("  context supers = %d, interfaces = %d", nsup, nint);
++  }
++}
++
++#ifndef PRODUCT
++void Dependencies::print_statistics() {
++  if (deps_find_witness_print != 0) {
++    // Call one final time, to flush out the data.
++    deps_find_witness_print = -1;
++    count_find_witness_calls();
++  }
++}
++#endif
+diff -ruNb openjdk6/hotspot/src/share/vm/code/dependencies.hpp openjdk/hotspot/src/share/vm/code/dependencies.hpp
+--- openjdk6/hotspot/src/share/vm/code/dependencies.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/dependencies.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)dependencies.hpp	1.11 07/05/05 17:05:18 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -46,6 +43,8 @@
+ class OopRecorder;
+ class xmlStream;
+ class CompileLog;
++class DepChange;
++class No_Safepoint_Verifier;
+ 
+ class Dependencies: public ResourceObj {
+  public:
+@@ -288,13 +287,20 @@
+   // Checking old assertions at run-time (in the VM only):
+   static klassOop check_evol_method(methodOop m);
+   static klassOop check_leaf_type(klassOop ctxk);
+-  static klassOop check_abstract_with_unique_concrete_subtype(klassOop ctxk, klassOop conck);
+-  static klassOop check_abstract_with_no_concrete_subtype(klassOop ctxk);
+-  static klassOop check_concrete_with_no_concrete_subtype(klassOop ctxk);
+-  static klassOop check_unique_concrete_method(klassOop ctxk, methodOop uniqm);
+-  static klassOop check_abstract_with_exclusive_concrete_subtypes(klassOop ctxk, klassOop k1, klassOop k2);
+-  static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2);
+-  static klassOop check_has_no_finalizable_subclasses(klassOop ctxk);
++  static klassOop check_abstract_with_unique_concrete_subtype(klassOop ctxk, klassOop conck,
++                                                              DepChange* changes = NULL);
++  static klassOop check_abstract_with_no_concrete_subtype(klassOop ctxk,
++                                                          DepChange* changes = NULL);
++  static klassOop check_concrete_with_no_concrete_subtype(klassOop ctxk,
++                                                          DepChange* changes = NULL);
++  static klassOop check_unique_concrete_method(klassOop ctxk, methodOop uniqm,
++                                               DepChange* changes = NULL);
++  static klassOop check_abstract_with_exclusive_concrete_subtypes(klassOop ctxk, klassOop k1, klassOop k2,
++                                                                  DepChange* changes = NULL);
++  static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2,
++                                                   DepChange* changes = NULL);
++  static klassOop check_has_no_finalizable_subclasses(klassOop ctxk,
++                                                      DepChange* changes = NULL);
+   // A returned klassOop is NULL if the dependency assertion is still
+   // valid.  A non-NULL klassOop is a 'witness' to the assertion
+   // failure, a point in the class hierarchy where the assertion has
+@@ -305,6 +311,10 @@
+   // witnesses to the failure.  The value returned from the check_foo
+   // method is chosen arbitrarily.
+ 
++  // The 'changes' value, if non-null, requests a limited spot-check
++  // near the indicated recent changes in the class hierarchy.
++  // It is used by DepStream::spot_check_dependency_at.
++
+   // Detecting possible new assertions:
+   static klassOop  find_unique_concrete_subtype(klassOop ctxk);
+   static methodOop find_unique_concrete_method(klassOop ctxk, methodOop m);
+@@ -397,6 +407,8 @@
+     inline oop recorded_oop_at(int i);
+         // => _code? _code->oop_at(i): *_deps->_oop_recorder->handle_at(i)
+ 
++    klassOop check_dependency_impl(DepChange* changes);
++
+   public:
+     DepStream(Dependencies* deps)
+       : _deps(deps),
+@@ -434,7 +446,12 @@
+     }
+ 
+     // The point of the whole exercise:  Is this dep is still OK?
+-    klassOop check_dependency();
++    klassOop check_dependency() {
++      return check_dependency_impl(NULL);
++    }
++    // A lighter version:  Checks only around recent changes in a class
++    // hierarchy.  (See Universe::flush_dependents_on.)
++    klassOop spot_check_dependency_at(DepChange& changes);
+ 
+     // Log the current dependency to xtty or compilation log.
+     void log_dependency(klassOop witness = NULL);
+@@ -443,4 +460,91 @@
+     void print_dependency(klassOop witness = NULL, bool verbose = false);
+   };
+   friend class Dependencies::DepStream;
++
++  static void print_statistics() PRODUCT_RETURN;
++};
++
++// A class hierarchy change coming through the VM (under the Compile_lock).
++// The change is structured as a single new type with any number of supers
++// and implemented interface types.  Other than the new type, any of the
++// super types can be context types for a relevant dependency, which the
++// new type could invalidate.
++class DepChange : public StackObj {
++ private:
++  enum ChangeType {
++    NO_CHANGE = 0,              // an uninvolved klass
++    Change_new_type,            // a newly loaded type
++    Change_new_sub,             // a super with a new subtype
++    Change_new_impl,            // an interface with a new implementation
++    CHANGE_LIMIT,
++    Start_Klass = CHANGE_LIMIT  // internal indicator for ContextStream
++  };
++
++  // each change set is rooted in exactly one new type (at present):
++  KlassHandle _new_type;
++
++  void initialize();
++
++ public:
++  // notes the new type, marks it and all its super-types
++  DepChange(KlassHandle new_type)
++    : _new_type(new_type)
++  {
++    initialize();
++  }
++
++  // cleans up the marks
++  ~DepChange();
++
++  klassOop new_type()                   { return _new_type(); }
++
++  // involves_context(k) is true if k is new_type or any of the super types
++  bool involves_context(klassOop k);
++
++  // Usage:
++  // for (DepChange::ContextStream str(changes); str.next(); ) {
++  //   klassOop k = str.klass();
++  //   switch (str.change_type()) {
++  //     ...
++  //   }
++  // }
++  class ContextStream : public StackObj {
++   private:
++    DepChange&       _changes;
++    friend class DepChange;
++
++    // iteration variables:
++    ChangeType            _change_type;
++    klassOop              _klass;
++    objArrayOop           _ti_base;    // i.e., transitive_interfaces
++    int                   _ti_index;
++    int                   _ti_limit;
++
++    // start at the beginning:
++    void start() {
++      klassOop new_type = _changes.new_type();
++      _change_type = (new_type == NULL ? NO_CHANGE: Start_Klass);
++      _klass = new_type;
++      _ti_base = NULL;
++      _ti_index = 0;
++      _ti_limit = 0;
++    }
++
++    ContextStream(DepChange& changes)
++      : _changes(changes)
++    { start(); }
++
++   public:
++    ContextStream(DepChange& changes, No_Safepoint_Verifier& nsv)
++      : _changes(changes)
++      // the nsv argument makes it safe to hold oops like _klass
++    { start(); }
++
++    bool next();
++
++    klassOop   klass()           { return _klass; }
++  };
++  friend class DepChange::ContextStream;
++
++  void print();
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/code/exceptionHandlerTable.cpp openjdk/hotspot/src/share/vm/code/exceptionHandlerTable.cpp
+--- openjdk6/hotspot/src/share/vm/code/exceptionHandlerTable.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/exceptionHandlerTable.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)exceptionHandlerTable.cpp	1.33 07/05/05 17:05:20 JVM"
+-#endif
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/exceptionHandlerTable.hpp openjdk/hotspot/src/share/vm/code/exceptionHandlerTable.hpp
+--- openjdk6/hotspot/src/share/vm/code/exceptionHandlerTable.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/exceptionHandlerTable.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)exceptionHandlerTable.hpp	1.30 07/05/05 17:05:21 JVM"
+-#endif
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/icBuffer.cpp openjdk/hotspot/src/share/vm/code/icBuffer.cpp
+--- openjdk6/hotspot/src/share/vm/code/icBuffer.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/icBuffer.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)icBuffer.cpp	1.70 07/05/05 17:05:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -187,6 +184,3 @@
+   ICStub* stub = ICStub_from_destination_address(ic->stub_address());
+   return stub->cached_oop();  
+ }
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/icBuffer.hpp openjdk/hotspot/src/share/vm/code/icBuffer.hpp
+--- openjdk6/hotspot/src/share/vm/code/icBuffer.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/icBuffer.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)icBuffer.hpp	1.30 07/05/05 17:05:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/location.cpp openjdk/hotspot/src/share/vm/code/location.cpp
+--- openjdk6/hotspot/src/share/vm/code/location.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/location.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)location.cpp	1.40 07/05/05 17:05:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -70,4 +67,3 @@
+   if ((offset_in_bytes % BytesPerInt) != 0)  return false;
+   return (offset_in_bytes / BytesPerInt) < (OFFSET_MASK >> OFFSET_SHIFT);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/location.hpp openjdk/hotspot/src/share/vm/code/location.hpp
+--- openjdk6/hotspot/src/share/vm/code/location.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/location.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)location.hpp	1.47 07/05/05 17:05:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/nmethod.cpp openjdk/hotspot/src/share/vm/code/nmethod.cpp
+--- openjdk6/hotspot/src/share/vm/code/nmethod.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/nmethod.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)nmethod.cpp	1.366 07/06/08 15:21:44 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -316,6 +313,18 @@
+   // Note:  Do not update _last_pc_desc.  It fronts for the LRU cache.
+ }
+ 
++// adjust pcs_size so that it is a multiple of both oopSize and
++// sizeof(PcDesc) (assumes that if sizeof(PcDesc) is not a multiple
++// of oopSize, then 2*sizeof(PcDesc) is)
++static int  adjust_pcs_size(int pcs_size) {
++  int nsize = round_to(pcs_size,   oopSize);
++  if ((nsize % sizeof(PcDesc)) != 0) {
++    nsize = pcs_size + sizeof(PcDesc);
++  }
++  assert((nsize %  oopSize) == 0, "correct alignment");
++  return nsize;
++}
++
+ //-----------------------------------------------------------------------------
+ 
+ 
+@@ -473,7 +482,7 @@
+   { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+     int nmethod_size =
+       allocation_size(code_buffer, sizeof(nmethod))
+-      + round_to(debug_info->pcs_size()        , oopSize)
++      + adjust_pcs_size(debug_info->pcs_size())
+       + round_to(dependencies->size_in_bytes() , oopSize)
+       + round_to(handler_table->size_in_bytes(), oopSize)
+       + round_to(nul_chk_table->size_in_bytes(), oopSize)
+@@ -596,6 +605,9 @@
+       print_code();
+       oop_maps->print();
+     }
++    if (PrintRelocations) {
++      print_relocations();
++    }
+     if (xtty != NULL) {
+       xtty->tail("print_native_nmethod");
+     }
+@@ -654,7 +666,7 @@
+     _consts_offset           = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start());
+     _scopes_data_offset      = data_offset();
+     _scopes_pcs_offset       = _scopes_data_offset   + round_to(debug_info->data_size         (), oopSize);
+-    _dependencies_offset     = _scopes_pcs_offset    + round_to(debug_info->pcs_size          (), oopSize);
++    _dependencies_offset     = _scopes_pcs_offset    + adjust_pcs_size(debug_info->pcs_size());
+     _handler_table_offset    = _dependencies_offset  + round_to(dependencies->size_in_bytes (), oopSize);
+     _nul_chk_table_offset    = _handler_table_offset + round_to(handler_table->size_in_bytes(), oopSize);
+     _nmethod_end_offset      = _nul_chk_table_offset + round_to(nul_chk_table->size_in_bytes(), oopSize);
+@@ -830,7 +842,8 @@
+ ScopeDesc* nmethod::scope_desc_at(address pc) {
+   PcDesc* pd = pc_desc_at(pc);
+   guarantee(pd != NULL, "scope must be present");
+-  return new ScopeDesc(this, pd->scope_decode_offset());
++  return new ScopeDesc(this, pd->scope_decode_offset(),
++                       pd->obj_decode_offset());
+ }
+ 
+ 
+@@ -1605,9 +1618,8 @@
+ }
+ 
+ 
+-bool nmethod::is_dependent_on(klassOop dependee) {
++bool nmethod::check_all_dependencies() {
+   bool found_check = false;
+-  if (dependee == NULL) {
+     // wholesale check of all dependencies
+     for (Dependencies::DepStream deps(this); deps.next(); ) {
+       if (deps.check_dependency() != NULL) {
+@@ -1615,23 +1627,21 @@
+         NOT_DEBUG(break);
+       }
+     }
+-  } else {
++  return found_check;  // tell caller if we found anything
++}
++
++bool nmethod::check_dependency_on(DepChange& changes) {
+     // What has happened:
+     // 1) a new class dependee has been added
+     // 2) dependee and all its super classes have been marked
++  bool found_check = false;  // set true if we are upset
+     for (Dependencies::DepStream deps(this); deps.next(); ) {
+       // Evaluate only relevant dependencies.
+-      klassOop ctxk = deps.context_type();
+-      if (ctxk == NULL)  continue;  // e.g., evol_method
+-      bool ctxk_is_marked = instanceKlass::cast(ctxk)->is_marked_dependent();
+-      assert(ctxk_is_marked == Klass::cast(dependee)->is_subtype_of(ctxk),
+-             "correct marking of potential context types");
+-      if (ctxk_is_marked && deps.check_dependency() != NULL) {
++    if (deps.spot_check_dependency_at(changes) != NULL) {
+         found_check = true;
+         NOT_DEBUG(break);
+       }
+     }
+-  }
+   return found_check;
+ }
+ 
+@@ -1802,7 +1812,8 @@
+   }
+   PcDesc* pd = pc_desc_at(ic->end_of_call());
+   assert(pd != NULL, "PcDesc must exist");
+-  for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset());
++  for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(),
++                                     pd->obj_decode_offset());
+        !sd->is_top(); sd = sd->sender()) {
+     sd->verify();
+   }
+@@ -1867,14 +1878,16 @@
+   ttyLocker ttyl;   // keep the following output all in one block
+ 
+   tty->print("Compiled ");
+-#ifdef TIERED
+-  if (compiler()->is_c1()) {
++
++  if (is_compiled_by_c1()) {
+     tty->print("(c1) ");
+-  } else {
+-    assert(compiler()->is_c2(), "Who else?");
++  } else if (is_compiled_by_c2()) {
+     tty->print("(c2) ");
++  } else {
++    assert(is_native_method(), "Who else?");
++    tty->print("(nm) ");
+   }
+-#endif // TIERED
++
+   print_on(tty, "nmethod");
+   tty->cr();
+   if (WizardMode) {
+@@ -1954,6 +1967,13 @@
+   tty->print_cr("Dependencies:");
+   for (Dependencies::DepStream deps(this); deps.next(); ) {
+     deps.print_dependency();
++    klassOop ctxk = deps.context_type();
++    if (ctxk != NULL) {
++      Klass* k = Klass::cast(ctxk);
++      if (k->oop_is_instance() && ((instanceKlass*)k)->is_dependent_nmethod(this)) {
++        tty->print("   [nmethod<=klass]%s", k->external_name());
++      }
++    }
+     deps.log_dependency();  // put it into the xml log also
+   }
+ }
+@@ -2040,7 +2060,8 @@
+ ScopeDesc* nmethod::scope_desc_in(address begin, address end) {
+   PcDesc* p = pc_desc_near(begin+1);
+   if (p != NULL && p->real_pc(this) <= end) {
+-    return new ScopeDesc(this, p->scope_decode_offset());
++    return new ScopeDesc(this, p->scope_decode_offset(),
++                         p->obj_decode_offset());
+   }
+   return NULL;
+ }
+@@ -2188,6 +2209,7 @@
+   nmethod_stats.print_nmethod_stats();
+   DebugInformationRecorder::print_statistics();
+   nmethod_stats.print_pc_stats();
++  Dependencies::print_statistics();
+   if (xtty != NULL)  xtty->tail("statistics");
+ }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/code/nmethod.hpp openjdk/hotspot/src/share/vm/code/nmethod.hpp
+--- openjdk6/hotspot/src/share/vm/code/nmethod.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/nmethod.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)nmethod.hpp	1.170 07/05/17 15:50:48 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -523,8 +520,13 @@
+   // PrimitiveIC*   primitiveIC_at(char* p) const;
+   oop embeddedOop_at(address p);
+ 
+-  // tells if this compiled method is dependent on
+-  bool is_dependent_on(klassOop dependee);  
++  // tells if any of this method's dependencies have been invalidated
++  // (this is expensive!)
++  bool check_all_dependencies();
++
++  // tells if this compiled method is dependent on the given changes,
++  // and the changes have invalidated it
++  bool check_dependency_on(DepChange& changes);
+ 
+   // Evolution support. Tells if this compiled method is dependent on any of
+   // methods m() of class dependee, such that if m() in dependee is replaced,
+@@ -574,5 +576,3 @@
+     lock_nmethod(_nm);
+   }
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/oopRecorder.cpp openjdk/hotspot/src/share/vm/code/oopRecorder.cpp
+--- openjdk6/hotspot/src/share/vm/code/oopRecorder.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/oopRecorder.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)oopRecorder.cpp	1.22 07/05/05 17:05:22 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -157,5 +154,3 @@
+   }
+   return -1;
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/oopRecorder.hpp openjdk/hotspot/src/share/vm/code/oopRecorder.hpp
+--- openjdk6/hotspot/src/share/vm/code/oopRecorder.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/oopRecorder.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oopRecorder.hpp	1.22 07/05/05 17:05:21 JVM"
+-#endif
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/pcDesc.cpp openjdk/hotspot/src/share/vm/code/pcDesc.cpp
+--- openjdk6/hotspot/src/share/vm/code/pcDesc.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/pcDesc.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)pcDesc.cpp	1.30 07/05/05 17:05:18 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -28,9 +25,10 @@
+ # include "incls/_precompiled.incl"
+ # include "incls/_pcDesc.cpp.incl"
+ 
+-PcDesc::PcDesc(int pc_offset, int scope_decode_offset) {
++PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset) {
+   _pc_offset           = pc_offset;
+   _scope_decode_offset = scope_decode_offset;
++  _obj_decode_offset   = obj_decode_offset;
+ }
+ 
+ address PcDesc::real_pc(const nmethod* code) const {
+@@ -61,4 +59,3 @@
+   //Unimplemented();
+   return true;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/pcDesc.hpp openjdk/hotspot/src/share/vm/code/pcDesc.hpp
+--- openjdk6/hotspot/src/share/vm/code/pcDesc.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/pcDesc.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)pcDesc.hpp	1.36 07/05/05 17:05:20 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -35,17 +32,20 @@
+  private:
+   int _pc_offset;           // offset from start of nmethod
+   int _scope_decode_offset; // offset for scope in nmethod
++  int _obj_decode_offset;
+ 
+  public:
+   int pc_offset() const           { return _pc_offset;   }
+   int scope_decode_offset() const { return _scope_decode_offset; }
++  int obj_decode_offset() const   { return _obj_decode_offset; }
+ 
+   void set_pc_offset(int x)           { _pc_offset           = x; }
+   void set_scope_decode_offset(int x) { _scope_decode_offset = x; }
++  void set_obj_decode_offset(int x)   { _obj_decode_offset   = x; }
+ 
+   // Constructor (only used for static in nmethod.cpp)
+   // Also used by ScopeDesc::sender()]
+-  PcDesc(int pc_offset, int scope_decode_offset);
++  PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset);
+ 
+   enum {
+     // upper and lower exclusive limits real offsets:
+@@ -59,4 +59,3 @@
+   void print(nmethod* code);
+   bool verify(nmethod* code);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/relocInfo.cpp openjdk/hotspot/src/share/vm/code/relocInfo.cpp
+--- openjdk6/hotspot/src/share/vm/code/relocInfo.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/relocInfo.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)relocInfo.cpp	1.89 07/05/05 17:05:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/relocInfo.hpp openjdk/hotspot/src/share/vm/code/relocInfo.hpp
+--- openjdk6/hotspot/src/share/vm/code/relocInfo.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/relocInfo.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)relocInfo.hpp	1.86 07/05/05 17:05:22 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1201,10 +1198,12 @@
+ 
+ 
+ class poll_Relocation : public Relocation {
++  bool          is_data()                      { return true; }
+   relocInfo::relocType type() { return relocInfo::poll_type; }
+ };
+ 
+ class poll_return_Relocation : public Relocation {
++  bool          is_data()                      { return true; }
+   relocInfo::relocType type() { return relocInfo::poll_return_type; }
+ };
+ 
+@@ -1327,4 +1326,3 @@
+ 
+   ~PatchingRelocIterator()                           { postpass(); }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/scopeDesc.cpp openjdk/hotspot/src/share/vm/code/scopeDesc.cpp
+--- openjdk6/hotspot/src/share/vm/code/scopeDesc.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/scopeDesc.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)scopeDesc.cpp	1.57 07/05/05 17:05:22 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,24 +26,42 @@
+ # include "incls/_scopeDesc.cpp.incl"
+ 
+ 
++ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset) {
++  _code          = code;
++  _decode_offset = decode_offset;
++  _objects       = decode_object_values(obj_decode_offset);
++  decode_body();
++}
++
+ ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset) {
+   _code          = code;
+   _decode_offset = decode_offset;
++  _objects       = decode_object_values(DebugInformationRecorder::serialized_null);
++  decode_body();
++}
++
+ 
+-  if (decode_offset == DebugInformationRecorder::serialized_null) {
++ScopeDesc::ScopeDesc(const ScopeDesc* parent) {
++  _code          = parent->_code;
++  _decode_offset = parent->_sender_decode_offset;
++  _objects       = parent->_objects;
++  decode_body();
++}
++
++
++void ScopeDesc::decode_body() {
++  if (decode_offset() == DebugInformationRecorder::serialized_null) {
+     // This is a sentinel record, which is only relevant to
+     // approximate queries.  Decode a reasonable frame.
+     _sender_decode_offset = DebugInformationRecorder::serialized_null;
+-    _method = methodHandle(code->method());
++    _method = methodHandle(_code->method());
+     _bci = InvocationEntryBci;
+     _locals_decode_offset = DebugInformationRecorder::serialized_null;
+     _expressions_decode_offset = DebugInformationRecorder::serialized_null;
+     _monitors_decode_offset = DebugInformationRecorder::serialized_null;
+-    return;
+-  }
+-
++  } else {
+   // decode header
+-  DebugInfoReadStream* stream  = stream_at(_decode_offset);
++    DebugInfoReadStream* stream  = stream_at(decode_offset());
+ 
+   _sender_decode_offset = stream->read_int();
+   _method = methodHandle((methodOop) stream->read_oop());
+@@ -55,6 +70,7 @@
+   _locals_decode_offset      = stream->read_int();
+   _expressions_decode_offset = stream->read_int();
+   _monitors_decode_offset    = stream->read_int();
++  }
+ }
+ 
+ 
+@@ -69,6 +85,18 @@
+   return result;
+ }
+ 
++GrowableArray<ScopeValue*>* ScopeDesc::decode_object_values(int decode_offset) {
++  if (decode_offset == DebugInformationRecorder::serialized_null) return NULL;
++  GrowableArray<ScopeValue*>* result = new GrowableArray<ScopeValue*>();
++  DebugInfoReadStream* stream = new DebugInfoReadStream(_code, decode_offset, result);
++  int length = stream->read_int();
++  for (int index = 0; index < length; index++) {
++    result->push(ScopeValue::read_from(stream));
++  }
++  assert(result->length() == length, "inconsistent debug information");
++  return result;
++}
++
+ 
+ GrowableArray<MonitorValue*>* ScopeDesc::decode_monitor_values(int decode_offset) {
+   if (decode_offset == DebugInformationRecorder::serialized_null) return NULL;
+@@ -82,7 +110,7 @@
+ }
+ 
+ DebugInfoReadStream* ScopeDesc::stream_at(int decode_offset) const {
+-  return new DebugInfoReadStream(_code, decode_offset);
++  return new DebugInfoReadStream(_code, decode_offset, _objects);
+ }
+ 
+ GrowableArray<ScopeValue*>* ScopeDesc::locals() {
+@@ -97,13 +125,17 @@
+   return decode_monitor_values(_monitors_decode_offset);
+ }
+ 
++GrowableArray<ScopeValue*>* ScopeDesc::objects() {
++  return _objects;
++}
++
+ bool ScopeDesc::is_top() const {
+  return _sender_decode_offset == DebugInformationRecorder::serialized_null;
+ }
+ 
+ ScopeDesc* ScopeDesc::sender() const {
+   if (is_top()) return NULL;
+-  return new ScopeDesc(_code, _sender_decode_offset);
++  return new ScopeDesc(this);
+ }
+ 
+ 
+@@ -174,6 +206,18 @@
+       }
+     }
+   }
++
++#ifdef COMPILER2
++  if (DoEscapeAnalysis && is_top() && _objects != NULL) {
++    tty->print_cr("Objects");
++    for (int i = 0; i < _objects->length(); i++) {
++      ObjectValue* sv = (ObjectValue*) _objects->at(i);
++      tty->print(" - %d: ", sv->id());
++      sv->print_fields_on(tty);
++      tty->cr();
++    }
++  }
++#endif // COMPILER2
+ }
+ 
+ #endif
+diff -ruNb openjdk6/hotspot/src/share/vm/code/scopeDesc.hpp openjdk/hotspot/src/share/vm/code/scopeDesc.hpp
+--- openjdk6/hotspot/src/share/vm/code/scopeDesc.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/scopeDesc.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)scopeDesc.hpp	1.36 07/05/05 17:05:22 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -55,6 +52,11 @@
+ class ScopeDesc : public ResourceObj {
+  public:
+   // Constructor
++  ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset);
++
++  // Calls above, giving default value of "serialized_null" to the
++  // "obj_decode_offset" argument.  (We don't use a default argument to
++  // avoid a .hpp-.hpp dependency.)
+   ScopeDesc(const nmethod* code, int decode_offset);
+ 
+   // JVM state
+@@ -64,6 +66,7 @@
+   GrowableArray<ScopeValue*>*   locals();
+   GrowableArray<ScopeValue*>*   expressions();  
+   GrowableArray<MonitorValue*>* monitors();
++  GrowableArray<ScopeValue*>*   objects();
+ 
+   // Stack walking, returns NULL if this is the outer most scope.
+   ScopeDesc* sender() const;
+@@ -77,6 +80,9 @@
+   bool is_equal(ScopeDesc* sd) const;
+ 
+  private:
++  // Alternative constructor
++  ScopeDesc(const ScopeDesc* parent);
++
+   // JVM state
+   methodHandle  _method;
+   int           _bci;
+@@ -88,6 +94,9 @@
+   int _expressions_decode_offset;
+   int _monitors_decode_offset;
+ 
++  // Object pool
++  GrowableArray<ScopeValue*>* _objects;
++
+   // Nmethod information
+   const nmethod* _code;
+ 
+@@ -95,6 +104,7 @@
+   void decode_body();
+   GrowableArray<ScopeValue*>* decode_scope_values(int decode_offset);
+   GrowableArray<MonitorValue*>* decode_monitor_values(int decode_offset);
++  GrowableArray<ScopeValue*>* decode_object_values(int decode_offset);
+ 
+   DebugInfoReadStream* stream_at(int decode_offset) const;
+ 
+@@ -111,6 +121,3 @@
+   void print_value_on(outputStream* st) const;
+ #endif
+ };
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/stubs.cpp openjdk/hotspot/src/share/vm/code/stubs.cpp
+--- openjdk6/hotspot/src/share/vm/code/stubs.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/stubs.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)stubs.cpp	1.47 07/05/05 17:05:20 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/stubs.hpp openjdk/hotspot/src/share/vm/code/stubs.hpp
+--- openjdk6/hotspot/src/share/vm/code/stubs.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/stubs.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)stubs.hpp	1.34 07/05/05 17:05:22 JVM"
+-#endif
+ /*
+  * Copyright 1997-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -209,6 +206,3 @@
+   void  verify();                                // verifies the stub queue
+   void  print();                                 // prints information about the stub queue
+ };
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/vmreg.cpp openjdk/hotspot/src/share/vm/code/vmreg.cpp
+--- openjdk6/hotspot/src/share/vm/code/vmreg.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/vmreg.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vmreg.cpp	1.35 07/05/05 17:05:22 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/vmreg.hpp openjdk/hotspot/src/share/vm/code/vmreg.hpp
+--- openjdk6/hotspot/src/share/vm/code/vmreg.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/vmreg.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vmreg.hpp	1.37 07/05/05 17:05:22 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/code/vtableStubs.cpp openjdk/hotspot/src/share/vm/code/vtableStubs.cpp
+--- openjdk6/hotspot/src/share/vm/code/vtableStubs.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/vtableStubs.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vtableStubs.cpp	1.55 07/05/05 17:05:22 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -198,8 +195,3 @@
+ }
+ 
+ #endif // Product
+-
+-
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/code/vtableStubs.hpp openjdk/hotspot/src/share/vm/code/vtableStubs.hpp
+--- openjdk6/hotspot/src/share/vm/code/vtableStubs.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/code/vtableStubs.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vtableStubs.hpp	1.27 07/05/05 17:05:22 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/abstractCompiler.cpp openjdk/hotspot/src/share/vm/compiler/abstractCompiler.cpp
+--- openjdk6/hotspot/src/share/vm/compiler/abstractCompiler.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/abstractCompiler.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)abstractCompiler.cpp	1.4 07/05/05 17:05:23 JVM"
+-#endif
+ // 
+ // Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/abstractCompiler.hpp openjdk/hotspot/src/share/vm/compiler/abstractCompiler.hpp
+--- openjdk6/hotspot/src/share/vm/compiler/abstractCompiler.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/abstractCompiler.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)abstractCompiler.hpp	1.26 07/05/05 17:05:24 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/cha.cpp openjdk/hotspot/src/share/vm/compiler/cha.cpp
+--- openjdk6/hotspot/src/share/vm/compiler/cha.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/cha.cpp	1970-01-01 01:00:00.000000000 +0100
+@@ -1,213 +0,0 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cha.cpp	1.54 07/05/05 17:05:23 JVM"
+-#endif
+-/*
+- * Copyright 1997-2005 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+- * CA 95054 USA or visit www.sun.com if you need additional information or
+- * have any questions.
+- *  
+- */
+-
+-#include "incls/_precompiled.incl"
+-#include "incls/_cha.cpp.incl"
+-
+-bool CHA::_used = false;
+-int CHA::_max_result = 5;
+-
+-
+-CHAResult* CHA::analyze_call(KlassHandle calling_klass, KlassHandle static_receiver, KlassHandle actual_receiver, 
+-                             symbolHandle name, symbolHandle signature) {
+-  assert(static_receiver->oop_is_instance(), "must be instance klass");
+-  
+-  methodHandle m;
+-  // Only do exact lookup if receiver klass has been linked.  Otherwise,
+-  // the vtables has not been setup, and the LinkResolver will fail.
+-  if (instanceKlass::cast(static_receiver())->is_linked() && instanceKlass::cast(actual_receiver())->is_linked()) {    
+-    if (static_receiver->is_interface()) {
+-      // no point trying to resolve unless actual receiver is a klass
+-      if (!actual_receiver->is_interface()) {
+-        m = LinkResolver::resolve_interface_call_or_null(actual_receiver, static_receiver, name, signature, calling_klass);
+-      }
+-    } else {
+-      m = LinkResolver::resolve_virtual_call_or_null(actual_receiver, static_receiver, name, signature, calling_klass);
+-    }
+-
+-    if (m.is_null()) {
+-      // didn't find method (e.g., could be abstract method)
+-      return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false);
+-    } 
+-    if( m()->can_be_statically_bound() ||
+-        m()->is_private() || 
+-        actual_receiver->subklass() == NULL ) {
+-      // always optimize final methods, private methods or methods with no
+-      // subclasses.
+-      return new CHAResult(actual_receiver, name, signature, NULL, NULL, m);
+-    } 
+-    if (!UseCHA) {
+-      // don't optimize this call
+-      return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false);
+-    }
+-  }
+-
+-  // If the method is abstract then each non-abstract subclass must implement 
+-  // the method and inlining is not possible.  If there is exactly 1 subclass
+-  // then there can be only 1 implementation and we are OK.  
+-  // (This test weakens CHA slightly, for the sake of the old dependency mechanism.)
+-  if( !m.is_null() && m()->is_abstract() ) {// Method is abstract?
+-    Klass *sr = Klass::cast(static_receiver());
+-    if( sr == sr->up_cast_abstract() )
+-      return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false);
+-    // Fall into the next code; it will find the one implementation
+-    // and that implementation is correct.
+-  }
+-
+-  _used = true;
+-  GrowableArray<methodHandle>* methods  = new GrowableArray<methodHandle>(CHA::max_result());
+-  GrowableArray<KlassHandle>* receivers = new GrowableArray<KlassHandle>(CHA::max_result());
+-
+-  // Since 'm' is visible from the actual receiver we can call it if the
+-  // runtime receiver class does not override 'm'.  
+-  if( !m.is_null() && m()->method_holder() != actual_receiver() &&
+-      !m->is_abstract() ) {
+-    receivers->push(actual_receiver);
+-    methods->push(m);
+-  }
+-  if (static_receiver->is_interface()) {
+-    instanceKlassHandle sr = static_receiver();
+-    process_interface(sr, receivers, methods, name, signature);
+-  } else {
+-    process_class(static_receiver, receivers, methods, name, signature);
+-  }
+-
+-  methodHandle dummy;
+-  CHAResult* res = new CHAResult(actual_receiver, name, signature, receivers, methods, dummy);
+-
+-  //res->print();
+-  return res;
+-}
+-
+-void CHA::process_class(KlassHandle r, GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, symbolHandle name, symbolHandle signature) {    
+-  // recursively add non-abstract subclasses of r to receivers list
+-  assert(!r->is_interface(), "should call process_interface instead");
+-  for (Klass* s = r->subklass(); s != NULL && !methods->is_full(); s = s->next_sibling()) {
+-    // preorder traversal, so check subclasses first
+-    if (s->is_interface()) {
+-      // can only happen if r == Object
+-      assert(r->superklass() == NULL, "must be klass Object");
+-    } else {
+-      process_class(s, receivers, methods, name, signature);
+-    }
+-  }
+-  // now check r itself (after subclasses because of preorder)
+-  if (!methods->is_full()) {
+-    // don't add abstract classes to receivers list
+-    // (but still consider their methods -- they may be non-abstract)
+-    if (!receivers->is_full() && !r->is_abstract()) {
+-      // don't duplicate the actual receiver
+-      if (!receivers->contains(r)) receivers->push(r);
+-    }
+-    methodOop m = NULL;
+-    if (r->oop_is_instance()) m = instanceKlass::cast(r())->find_method(name(), signature()); 
+-    if (m != NULL && !m->is_abstract()) {
+-      if (!methods->contains(m)) methods->push(m);
+-    }
+-  }
+-}
+-
+-void CHA::process_interface(instanceKlassHandle r, GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, 
+-                            symbolHandle name, symbolHandle signature) {
+-  // recursively add non-abstract implementors of interface r to receivers list
+-  assert(r->is_interface(), "should call process_class instead");
+-  
+-  // We only store the implementors for an interface, if there is exactly one implementor  
+-  klassOop k = NULL;
+-  if (r->nof_implementors() == 1)  k = r->implementor(0);
+-  if (k == NULL)  methods->clear();  // no news is bad news
+-  if (k != NULL && !methods->is_full()) {   
+-    instanceKlass* kl = instanceKlass::cast(k);
+-    assert(kl->oop_is_instance(), "primitive klasses don't implement interfaces");
+-    assert(!kl->is_interface(), "must be a real klass");
+-    process_class(kl, receivers, methods, name, signature);
+-  }
+-
+-  // there are no links to subinterfaces
+-  assert(r->subklass() == NULL, "interfaces have no subclasses");
+-}
+-
+-
+-CHAResult::CHAResult(KlassHandle r, symbolHandle n, symbolHandle s,
+-                     GrowableArray<KlassHandle>* rs, GrowableArray<methodHandle>* ms, 
+-                     methodHandle target, bool v) :
+-  _receiver(r), _name(n), _signature(s), _receivers(rs), _target_methods(ms), _valid(v), _target(target) {}
+-
+-bool CHAResult::is_monomorphic() const {
+-  // note: check number of target methods, not number of receivers
+-  // (send can be monomorphic even with many receiver classes, if all inherit same method)
+-  return _valid && (_target_methods == NULL || _target_methods->length() == 1);
+-}
+-
+-methodHandle CHAResult::monomorphic_target() const {
+-  assert(is_monomorphic(), "not monomorphic");
+-  if (_target_methods != NULL) {
+-    assert(_target_methods->length() == 1, "expected single target");
+-    return _target_methods->first();
+-  } else {
+-    // final method
+-    //    assert(_target->is_final_method(), "expected final method");
+-    return _target;
+-  }
+-}
+-
+-KlassHandle CHAResult::monomorphic_receiver() const {
+-  assert(is_monomorphic(), "not monomorphic");
+-  if (_receivers != NULL) {
+-    // since all lookups will find the same method, it doesn't matter that much
+-    // which klass we return; for beauty's sake, return the target's method holder
+-    // (note: don't return _receiver -- its method may be abstract)
+-    return _target_methods->first()->method_holder();
+-  } else {
+-    // final method
+-    //    assert(_target->is_final_method(), "expected final method");
+-    return _receiver;
+-  }
+-}
+-
+-void CHAResult::print() {
+-  tty->print("(CHAResult*)%#x : ", this); 
+-  (instanceKlass::cast(_receiver()))->name()->print_value();
+-  tty->print("::");
+-  _name()->print_value();
+-  tty->print_cr(" %s", _valid ? "(Found)" : "(Not found)");
+-  if (_receivers != NULL) 
+-    tty->print("%d receiver klasses ", _receivers->length());
+-  if (_target_methods != NULL) 
+-    tty->print("%d target methods %s", _target_methods->length(), 
+-                _target_methods->is_full() ? "(FULL)" : "");
+-  if (is_monomorphic()) {
+-    methodHandle target = monomorphic_target();
+-    tty->print("monomorphic target method : ");
+-    target->print_short_name(tty);
+-    if (target->is_final())
+-      tty->print(" (final)");
+-    if (target->is_abstract())
+-      tty->print(" (abstract)");
+-  }
+-  tty->cr();
+-}
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/cha.hpp openjdk/hotspot/src/share/vm/compiler/cha.hpp
+--- openjdk6/hotspot/src/share/vm/compiler/cha.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/cha.hpp	1970-01-01 01:00:00.000000000 +0100
+@@ -1,88 +0,0 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cha.hpp	1.21 07/05/05 17:05:23 JVM"
+-#endif
+-/*
+- * Copyright 1997-1998 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+- * CA 95054 USA or visit www.sun.com if you need additional information or
+- * have any questions.
+- *  
+- */
+-
+-// Class Hierarchy Analysis 
+-// Computes the set of overriding methods for a particular call,
+-// using the subclass links in instanceKlass.
+-// Right now the CHA just traverses these links for every query;
+-// if this should become too slow we can put in a cache.
+-
+-// result of a CHA query
+-class CHAResult : public ResourceObj {
+-  friend class CHA;
+-  const KlassHandle  _receiver;                                 // copies of the lookup (for better debugging)
+-  const symbolHandle _name;
+-  const symbolHandle _signature;
+-  const methodHandle _target;                                   // target method (if final)
+-  const bool         _valid;
+-  const GrowableArray<methodHandle>* const _target_methods;     // list of possible targets (NULL for final methods or if !UseCHA)
+-  const GrowableArray<KlassHandle>* const  _receivers;          // list of possible receiver klasses (NULL for final methods or if !UseCHA)
+-
+-  CHAResult(KlassHandle receiver, symbolHandle name, symbolHandle signature,
+-            GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, 
+-            methodHandle target, bool valid = true);
+- public:
+-  KlassHandle  receiver() const                               { return _receiver; }
+-  symbolHandle name() const                                   { return _name; }
+-  symbolHandle signature() const                              { return _signature; }
+-  bool      is_accurate() const                               { return !_target_methods->is_full(); }
+-  bool      is_monomorphic() const;
+-  methodHandle monomorphic_target() const;                    // returns the single target (if is_monomorphic)
+-  KlassHandle  monomorphic_receiver() const;                  // receiver klass of monomorphic_target
+-  const GrowableArray<KlassHandle>*  receivers() const        { return _receivers; }
+-    // Returns the list of all subclasses that are possible receivers (empty array if none, capped at max_result).
+-    // The static receiver klass *is* included in the result (unless it is abstract).
+-    // The list is a class hierarchy preorder, i.e., subclasses precede their superclass.
+-    // All possible receiver classes are included, not just those that (re)define the method.
+-    // Abstract classes are suppressed.
+-  const GrowableArray<methodHandle>* target_methods() const   { return _target_methods; }
+-    // Returns the list of possible target methods, i.e., all methods potentially invoked
+-    // by this send (empty array if none, capped at max_result).
+-    // If the receiver klass (or one of its superclasses) defines the method, this definition 
+-    // is included in the result.  Abstract methods are suppressed.
+-  void print();
+-};
+-
+-
+-class CHA : AllStatic {
+-  static int _max_result;           // maximum result size (for efficiency)
+-  static bool _used;                // has CHA been used yet?  (will go away when deoptimization implemented)
+-
+-  static void process_class(KlassHandle r, GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, 
+-                            symbolHandle name, symbolHandle signature);
+-  static void process_interface(instanceKlassHandle r, GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, 
+-                            symbolHandle name, symbolHandle signature);
+- public:
+-  static bool has_been_used()       { return _used; }
+-  static int  max_result()          { return _max_result; }
+-  static void set_max_result(int n) { _max_result = n; }
+-
+-  static CHAResult* analyze_call(KlassHandle calling_klass, KlassHandle static_receiver, 
+-                                 KlassHandle actual_receiver, symbolHandle name, symbolHandle signature);
+-};
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compileBroker.cpp openjdk/hotspot/src/share/vm/compiler/compileBroker.cpp
+--- openjdk6/hotspot/src/share/vm/compiler/compileBroker.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/compileBroker.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compileBroker.cpp	1.147 07/05/17 15:50:51 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compileBroker.hpp openjdk/hotspot/src/share/vm/compiler/compileBroker.hpp
+--- openjdk6/hotspot/src/share/vm/compiler/compileBroker.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/compileBroker.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compileBroker.hpp	1.55 07/05/05 17:05:24 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compileLog.cpp openjdk/hotspot/src/share/vm/compiler/compileLog.cpp
+--- openjdk6/hotspot/src/share/vm/compiler/compileLog.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/compileLog.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compileLog.cpp	1.20 07/05/05 17:05:23 JVM"
+-#endif
+ /*
+  * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -295,4 +292,3 @@
+   char buf[4 * K];
+   finish_log_on_error(file, buf, sizeof(buf));
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compileLog.hpp openjdk/hotspot/src/share/vm/compiler/compileLog.hpp
+--- openjdk6/hotspot/src/share/vm/compiler/compileLog.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/compileLog.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compileLog.hpp	1.12 07/05/05 17:05:24 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compilerOracle.cpp openjdk/hotspot/src/share/vm/compiler/compilerOracle.cpp
+--- openjdk6/hotspot/src/share/vm/compiler/compilerOracle.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/compilerOracle.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compilerOracle.cpp	1.34 07/05/17 15:50:53 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -539,7 +536,7 @@
+ }
+ 
+ static const char* cc_file() {
+-  if (CompileCommandFile[0] == '\0')
++  if (CompileCommandFile == NULL)
+     return ".hotspot_compiler";
+   return CompileCommandFile;
+ }
+@@ -711,5 +708,3 @@
+     line = *line == '\0' ? line : line + 1;
+   }
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compilerOracle.hpp openjdk/hotspot/src/share/vm/compiler/compilerOracle.hpp
+--- openjdk6/hotspot/src/share/vm/compiler/compilerOracle.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/compilerOracle.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compilerOracle.hpp	1.21 07/05/05 17:05:23 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/disassemblerEnv.hpp openjdk/hotspot/src/share/vm/compiler/disassemblerEnv.hpp
+--- openjdk6/hotspot/src/share/vm/compiler/disassemblerEnv.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/disassemblerEnv.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)disassemblerEnv.hpp	1.18 07/05/05 17:05:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -36,4 +33,3 @@
+   virtual char* string_for_offset(intptr_t value) = 0;
+   virtual char* string_for_constant(unsigned char* pc, intptr_t value, int is_decimal) = 0;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/methodLiveness.cpp openjdk/hotspot/src/share/vm/compiler/methodLiveness.cpp
+--- openjdk6/hotspot/src/share/vm/compiler/methodLiveness.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/methodLiveness.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)methodLiveness.cpp	1.41 07/05/05 17:05:24 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1064,4 +1061,3 @@
+ }
+ 
+ #endif // PRODUCT
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/methodLiveness.hpp openjdk/hotspot/src/share/vm/compiler/methodLiveness.hpp
+--- openjdk6/hotspot/src/share/vm/compiler/methodLiveness.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/methodLiveness.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)methodLiveness.hpp	1.25 07/05/05 17:05:24 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/oopMap.cpp openjdk/hotspot/src/share/vm/compiler/oopMap.cpp
+--- openjdk6/hotspot/src/share/vm/compiler/oopMap.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/oopMap.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)oopMap.cpp	1.151 07/05/05 17:05:23 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -194,6 +191,10 @@
+   }
+ }
+ 
++void OopMap::set_stack_obj(VMReg reg) {
++  set_xxx(reg, OopMapValue::stack_obj, VMRegImpl::Bad());
++}
++
+ // OopMapSet
+ 
+ OopMapSet::OopMapSet() {
+@@ -401,7 +402,7 @@
+       if ( loc != NULL ) {
+         if ( omv.type() == OopMapValue::oop_value ) {
+ #ifdef ASSERT
+-          if (!Universe::heap()->is_in_or_null(*loc)) {
++          if (COMPILER2_PRESENT(!DoEscapeAnalysis &&) !Universe::heap()->is_in_or_null(*loc)) {
+             tty->print_cr("# Found non oop pointer.  Dumping state at failure");
+             // try to dump out some helpful debugging information
+             trace_codeblob_maps(fr, reg_map);
+@@ -420,6 +421,17 @@
+       }
+     }
+   }
++
++#ifdef COMPILER2
++  if (DoEscapeAnalysis) {
++    for (OopMapStream oms(map, OopMapValue::stack_obj); !oms.is_done(); oms.next()) {
++      omv = oms.current();
++      assert(omv.is_stack_loc(), "should refer to stack location");
++      oop loc = (oop) fr->oopmapreg_to_location(omv.reg(),reg_map);
++      oop_fn->do_oop(&loc);
++    }
++  }
++#endif // COMPILER2
+ }
+ 
+ 
+@@ -513,6 +525,9 @@
+     tty->print("Derived_oop_" );
+     optional->print();
+     break;
++  case OopMapValue::stack_obj:
++    tty->print("Stack");
++    break;
+   default:
+     ShouldNotReachHere();
+   }
+@@ -527,25 +542,25 @@
+ }
+ 
+ 
+-void OopMap::print() const {
++void OopMap::print_on(outputStream* st) const {
+   OopMapValue omv;
+   for(OopMapStream oms((OopMap*)this); !oms.is_done(); oms.next()) {
+     omv = oms.current();
+-    omv.print();
++    omv.print_on(st);
+   }
+ }
+ 
+ 
+-void OopMapSet::print() const {
++void OopMapSet::print_on(outputStream* st) const {
+   int i, len = om_count();
+ 
+-  tty->print_cr("OopMapSet contains %d OopMaps\n",len);
++  st->print_cr("OopMapSet contains %d OopMaps\n",len);
+   
+   for( i = 0; i < len; i++) {
+     OopMap* m = at(i);
+-    tty->print_cr("OopMap #%d offset:%p",i,m->offset());
+-    m->print();
+-    tty->print_cr("\n");
++    st->print_cr("OopMap #%d offset:%p",i,m->offset());
++    m->print_on(st);
++    st->print_cr("\n");
+   }
+ }
+ #endif // !PRODUCT
+diff -ruNb openjdk6/hotspot/src/share/vm/compiler/oopMap.hpp openjdk/hotspot/src/share/vm/compiler/oopMap.hpp
+--- openjdk6/hotspot/src/share/vm/compiler/oopMap.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/compiler/oopMap.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oopMap.hpp	1.79 07/05/05 17:05:24 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -49,7 +46,7 @@
+ 
+ public:
+   // Constants
+-  enum { type_bits                = 5,
++  enum { type_bits                = 6,
+          register_bits            = BitsPerShort - type_bits };
+  
+   enum { type_shift               = 0,
+@@ -66,7 +63,8 @@
+          value_value = 2,
+          dead_value = 4,
+          callee_saved_value = 8,
+-         derived_oop_value= 16 };
++         derived_oop_value= 16,
++         stack_obj = 32 };
+ 
+   // Constructors
+   OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
+@@ -95,12 +93,14 @@
+   bool is_dead()              { return mask_bits(value(), type_mask_in_place) == dead_value; } 
+   bool is_callee_saved()      { return mask_bits(value(), type_mask_in_place) == callee_saved_value; } 
+   bool is_derived_oop()       { return mask_bits(value(), type_mask_in_place) == derived_oop_value; } 
++  bool is_stack_obj()         { return mask_bits(value(), type_mask_in_place) == stack_obj; }
+ 
+   void set_oop()              { set_value((value() & register_mask_in_place) | oop_value); } 
+   void set_value()            { set_value((value() & register_mask_in_place) | value_value); } 
+   void set_dead()             { set_value((value() & register_mask_in_place) | dead_value); } 
+   void set_callee_saved()     { set_value((value() & register_mask_in_place) | callee_saved_value); } 
+   void set_derived_oop()      { set_value((value() & register_mask_in_place) | derived_oop_value); } 
++  void set_stack_obj()        { set_value((value() & register_mask_in_place) | stack_obj); }
+ 
+   VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
+   oop_types type() const      { return (oop_types)mask_bits(value(), type_mask_in_place); }
+@@ -178,6 +178,7 @@
+   void set_dead ( VMReg local);
+   void set_callee_saved( VMReg local, VMReg caller_machine_register );
+   void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
++  void set_stack_obj( VMReg local);
+   void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
+ 
+   int heap_size() const;
+@@ -191,7 +192,8 @@
+   }
+ 
+   // Printing
+-  void print() const PRODUCT_RETURN;
++  void print_on(outputStream* st) const PRODUCT_RETURN;
++  void print() const { print_on(tty); }
+ };
+ 
+ 
+@@ -245,7 +247,8 @@
+                      OopClosure* value_fn, OopClosure* dead_fn);
+ 
+   // Printing
+-  void print() const PRODUCT_RETURN;
++  void print_on(outputStream* st) const PRODUCT_RETURN;
++  void print() const { print_on(tty); }
+ };
+ 
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)binaryTreeDictionary.cpp	1.37 07/05/05 17:05:43 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)binaryTreeDictionary.hpp	1.26 07/05/05 17:05:41 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cmsAdaptiveSizePolicy.cpp	1.19 07/05/05 17:05:24 JVM"
+-#endif
+ /*
+  * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cmsAdaptiveSizePolicy.hpp	1.16 07/05/05 17:05:25 JVM"
+-#endif
+ /*
+  * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cmsCollectorPolicy.cpp	1.1 07/05/16 10:53:57 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cmsCollectorPolicy.hpp	1.1 07/05/16 10:53:57 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cmsGCAdaptivePolicyCounters.cpp	1.16 07/05/05 17:05:25 JVM"
+-#endif
+ /*
+  * Copyright 2004-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cmsGCAdaptivePolicyCounters.hpp	1.16 07/05/05 17:05:25 JVM"
+-#endif
+ /*
+  * Copyright 2004-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cmsLockVerifier.cpp	1.14 07/05/05 17:05:44 JVM"
+-#endif
+ /*
+  * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -96,4 +93,3 @@
+   }
+ }
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cmsLockVerifier.hpp	1.9 07/05/05 17:05:44 JVM"
+-#endif
+ /*
+  * Copyright 2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cmsOopClosures.hpp	1.2 07/05/16 16:53:01 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -32,8 +29,10 @@
+ class CMSBitMap;
+ class CMSMarkStack;
+ class CMSCollector;
+-class OopTaskQueue;
+-class OopTaskQueueSet;
++template<class E> class GenericTaskQueue;
++typedef GenericTaskQueue<oop> OopTaskQueue;
++template<class E> class GenericTaskQueueSet;
++typedef GenericTaskQueueSet<oop> OopTaskQueueSet;
+ class MarkFromRootsClosure;
+ class Par_MarkFromRootsClosure;
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cmsOopClosures.inline.hpp	1.1 07/05/16 10:52:51 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cmsPermGen.cpp	1.2 07/05/16 16:53:01 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cmsPermGen.hpp	1.1 07/05/02 16:12:51 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compactibleFreeListSpace.cpp	1.143 07/07/17 11:43:33 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -2846,4 +2843,3 @@
+   pst->set_par_threads(n_threads);
+   pst->set_n_tasks((int)n_tasks);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compactibleFreeListSpace.hpp	1.91 07/05/05 17:05:45 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp	2008-08-28 10:23:09.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -158,6 +158,8 @@
+ 
+   SurrogateLockerThread();
+ 
++  bool is_hidden_from_external_view() const     { return true; }
++
+   void loop(); // main method
+ 
+   void manipulatePLL(SLT_msg_type msg);
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)concurrentMarkSweepGeneration.cpp	1.290 07/07/17 11:49:58 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -4081,7 +4078,7 @@
+   while (_restart_addr != NULL) {
+     // XXX For now we do not make use of ABORTED state and have not
+     // yet implemented the right abort semantics (even in the original
+-    // single-threaded CMS case. That needs some more investigation
++    // single-threaded CMS case). That needs some more investigation
+     // and is deferred for now; see CR# TBF. 07252005YSR. XXX
+     assert(!CMSAbortSemantics || tsk.aborted(), "Inconsistency");
+     // If _restart_addr is non-NULL, a marking stack overflow
+@@ -4238,7 +4235,9 @@
+       // take a short break.
+       if (workdone < CMSAbortablePrecleanMinWorkPerIteration) {
+         // Sleep for some time, waiting for work to accumulate
++        stopTimer();
+         cmsThread()->wait_on_cms_lock(CMSAbortablePrecleanWaitMillis);
++        startTimer();
+         waited++;
+       }
+     }
+@@ -4323,8 +4322,10 @@
+     // the computed reachability of the referents, the
+     // only properties manipulated by the precleaning
+     // of these reference lists.
++    stopTimer();
+     CMSTokenSyncWithLocks x(true /* is cms thread */,
+                             bitMapLock());
++    startTimer();
+     sample_eden();
+     // The following will yield to allow foreground
+     // collection to proceed promptly. XXX YSR:
+@@ -4346,8 +4347,10 @@
+                              &_markBitMap, &_modUnionTable,
+                              &_markStack, &_revisitStack,
+                              true /* precleaning phase */);
++    stopTimer();
+     CMSTokenSyncWithLocks ts(true /* is cms thread */,
+                              bitMapLock());
++    startTimer();
+     unsigned int before_count =
+       GenCollectedHeap::heap()->total_collections();
+     SurvivorSpacePrecleanClosure
+@@ -4481,13 +4484,10 @@
+ 
+     MemRegion dirtyRegion;
+     {
++      stopTimer();
+       CMSTokenSync ts(true);
+-      sample_eden();
+-
+-      if (PrintGCDetails) {
+         startTimer();
+-      }
+-
++      sample_eden();
+       // Get dirty region starting at nextOffset (inclusive),
+       // simultaneously clearing it.
+       dirtyRegion = 
+@@ -4507,20 +4507,16 @@
+     // We'll scan the cards in the dirty region (with periodic
+     // yields for foreground GC as needed).
+     if (!dirtyRegion.is_empty()) {
+-      if (PrintGCDetails) {
+-        stopTimer();
+-      }
+       assert(numDirtyCards > 0, "consistency check");
+       HeapWord* stop_point = NULL;
+       {
++        stopTimer();
+         CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
+                                  bitMapLock());
++        startTimer();
+         verify_work_stacks_empty();
+         verify_overflow_empty();
+         sample_eden();
+-        if (PrintGCDetails) {
+-          startTimer();
+-        }
+         stop_point =
+           gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
+       }
+@@ -4535,7 +4531,9 @@
+                (_collectorState == AbortablePreclean && should_abort_preclean()),
+                "Unparsable objects should only be in perm gen.");
+ 
++        stopTimer();
+         CMSTokenSyncWithLocks ts(true, bitMapLock());
++        startTimer();
+         _modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end()));
+         if (should_abort_preclean()) {
+           break; // out of preclean loop
+@@ -4545,18 +4543,12 @@
+           lastAddr = next_card_start_after_block(stop_point);
+         }
+       }
+-      if (PrintGCDetails) {
+-        stopTimer();
+-      }
+     } else {
+       assert(lastAddr == endAddr, "consistency check");
+       assert(numDirtyCards == 0, "consistency check");
+       break;
+     }
+   }
+-  if (PrintGCDetails) {
+-    stopTimer();
+-  }
+   verify_work_stacks_empty();
+   verify_overflow_empty();
+   return cumNumDirtyCards;
+@@ -4592,13 +4584,10 @@
+       // See comments in "Precleaning notes" above on why we
+       // do this locking. XXX Could the locking overheads be
+       // too high when dirty cards are sparse? [I don't think so.]
++      stopTimer();
+       CMSTokenSync x(true); // is cms thread
+-      sample_eden();
+-
+-      if (PrintGCDetails) {
+         startTimer();
+-      }
+-
++      sample_eden();
+       // Get and clear dirty region from card table
+       dirtyRegion = _ct->ct_bs()->dirty_card_range_after_preclean(
+                                     MemRegion(nextAddr, endAddr));
+@@ -4610,16 +4599,12 @@
+       dirtyRegion.word_size()/CardTableModRefBS::card_size_in_words;
+ 
+     if (!dirtyRegion.is_empty()) {
+-      if (PrintGCDetails) {
+         stopTimer();
+-      }
+       CMSTokenSyncWithLocks ts(true, gen->freelistLock(), bitMapLock());
++      startTimer();
+       sample_eden();
+       verify_work_stacks_empty();
+       verify_overflow_empty();
+-      if (PrintGCDetails) {
+-        startTimer();
+-      }
+       HeapWord* stop_point =
+         gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
+       if (stop_point != NULL) {
+@@ -4638,16 +4623,10 @@
+           lastAddr = next_card_start_after_block(stop_point);
+         }
+       }
+-      if (PrintGCDetails) {
+-        stopTimer();
+-      }
+     } else {
+       break;
+     }
+   }
+-  if (PrintGCDetails) {
+-    stopTimer();
+-  }
+   verify_work_stacks_empty();
+   verify_overflow_empty();
+   return cumNumDirtyCards;
+@@ -8362,6 +8341,7 @@
+   for (oop next; i > 0 && cur != NULL; cur = next, i--) {
+     next = oop(cur->mark());
+     cur->set_mark(proto);   // until proven otherwise
++    assert(cur->is_oop(), "Should be an oop");
+     bool res = stack->push(cur);
+     assert(res, "Bit off more than can chew?");
+     NOT_PRODUCT(n++;)
+@@ -8416,6 +8396,7 @@
+   for (cur = prefix; cur != NULL; cur = next) {
+     next = oop(cur->mark());
+     cur->set_mark(proto);   // until proven otherwise
++    assert(cur->is_oop(), "Should be an oop");
+     bool res = work_q->push(cur);
+     assert(res, "Bit off more than we can chew?");
+     NOT_PRODUCT(n++;)
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)concurrentMarkSweepGeneration.hpp	1.161 07/07/17 11:44:43 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -918,10 +915,10 @@
+   CollectorCounters* counters()    { return _gc_counters; }
+ 
+   // timer stuff
+-  void    startTimer() { _timer.start();   }
+-  void    stopTimer()  { _timer.stop();    }
+-  void    resetTimer() { _timer.reset();   }
+-  double  timerValue() { return _timer.seconds(); }
++  void    startTimer() { assert(!_timer.is_active(), "Error"); _timer.start();   }
++  void    stopTimer()  { assert( _timer.is_active(), "Error"); _timer.stop();    }
++  void    resetTimer() { assert(!_timer.is_active(), "Error"); _timer.reset();   }
++  double  timerValue() { assert(!_timer.is_active(), "Error"); return _timer.seconds(); }
+ 
+   int  yields()          { return _numYields; }
+   void resetYields()     { _numYields = 0;    }
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)concurrentMarkSweepGeneration.inline.hpp	1.47 07/05/17 15:52:12 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)concurrentMarkSweepThread.cpp	1.48 07/05/05 17:06:45 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)concurrentMarkSweepThread.hpp	1.38 07/05/05 17:06:46 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)freeBlockDictionary.cpp	1.12 07/05/05 17:05:47 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)freeBlockDictionary.hpp	1.32 07/05/05 17:05:47 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)freeChunk.cpp	1.16 07/05/05 17:05:47 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)freeList.cpp	1.31 07/05/05 17:05:48 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)freeList.hpp	1.31 07/05/05 17:05:48 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vmCMSOperations.cpp	1.16 07/05/29 09:44:13 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -251,4 +248,3 @@
+   // Enable iCMS back.
+   CMSCollector::enable_icms();
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vmCMSOperations.hpp	1.13 07/05/29 09:44:13 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vmStructs_cms.hpp	1.2 07/05/01 19:01:30 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)adjoiningGenerations.cpp	1.16 07/05/05 17:05:26 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -279,4 +276,3 @@
+     }
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)adjoiningGenerations.hpp	1.14 07/05/05 17:05:25 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)adjoiningVirtualSpaces.cpp	1.14 07/05/05 17:05:26 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)adjoiningVirtualSpaces.hpp	1.11 07/05/05 17:05:25 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -109,4 +106,3 @@
+ 		  size_t init_low_byte_size,
+ 		  size_t init_high_byte_size);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)asPSOldGen.cpp	1.18 07/05/05 17:05:26 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -78,7 +75,10 @@
+   assert(virtual_space()->is_aligned(gen_size_limit()), "not aligned");
+   assert(gen_size_limit() >= virtual_space()->committed_size(), "bad gen size");
+ 
+-  return gen_size_limit() - virtual_space()->committed_size();
++  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
++  size_t result =  gen_size_limit() - virtual_space()->committed_size();
++  size_t result_aligned = align_size_down(result, heap->old_gen_alignment());
++  return result_aligned;
+ }
+ 
+ size_t ASPSOldGen::available_for_contraction() {
+@@ -87,12 +87,12 @@
+     return uncommitted_bytes;
+   }
+ 
+-  const size_t alignment = virtual_space()->alignment();
+   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); 
++  const size_t gen_alignment = heap->old_gen_alignment();
+   PSAdaptiveSizePolicy* policy = heap->size_policy();
+   const size_t working_size = 
+     used_in_bytes() + (size_t) policy->avg_promoted()->padded_average();
+-  const size_t working_aligned = align_size_up(working_size, alignment);
++  const size_t working_aligned = align_size_up(working_size, gen_alignment);
+   const size_t working_or_min = MAX2(working_aligned, min_gen_size());
+   if (working_or_min > reserved().byte_size()) {
+     // If the used or minimum gen size (aligned up) is greater
+@@ -109,9 +109,11 @@
+   // only reduce the footprint.
+ 
+   size_t result = policy->promo_increment_aligned_down(max_contraction);
++  // Also adjust for inter-generational alignment
++  size_t result_aligned = align_size_down(result, gen_alignment);
+   if (PrintAdaptiveSizePolicy && Verbose) {
+     gclog_or_tty->print_cr("\nASPSOldGen::available_for_contraction:"
+-      " %d K / 0x%x", result/K, result);
++      " %d K / 0x%x", result_aligned/K, result_aligned);
+     gclog_or_tty->print_cr(" reserved().byte_size() %d K / 0x%x ", 
+       reserved().byte_size()/K, reserved().byte_size());
+     size_t working_promoted = (size_t) policy->avg_promoted()->padded_average();
+@@ -126,8 +128,8 @@
+     gclog_or_tty->print_cr("	without alignment %d K / 0x%x", 
+       policy->promo_increment(max_contraction)/K, 
+       policy->promo_increment(max_contraction));
+-    gclog_or_tty->print_cr(" alignment 0x%x", alignment);
++    gclog_or_tty->print_cr(" alignment 0x%x", gen_alignment);
+   }
+-  assert(result <= max_contraction, "arithmetic is wrong");
+-  return result;
++  assert(result_aligned <= max_contraction, "arithmetic is wrong");
++  return result_aligned;
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)asPSOldGen.hpp	1.14 07/05/05 17:05:26 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)asPSYoungGen.cpp	1.22 07/05/05 17:05:27 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -69,7 +66,10 @@
+   size_t current_committed_size = virtual_space()->committed_size();
+   assert((gen_size_limit() >= current_committed_size),
+     "generation size limit is wrong");
+-  return gen_size_limit() - current_committed_size;
++  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
++  size_t result =  gen_size_limit() - current_committed_size;
++  size_t result_aligned = align_size_down(result, heap->young_gen_alignment());
++  return result_aligned;
+ }
+ 
+ // Return the number of bytes the young gen is willing give up.
+@@ -87,7 +87,7 @@
+     // Respect the minimum size for eden and for the young gen as a whole.
+     ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+     const size_t eden_alignment = heap->intra_generation_alignment();
+-    const size_t gen_alignment = heap->generation_alignment();
++    const size_t gen_alignment = heap->young_gen_alignment();
+ 
+     assert(eden_space()->capacity_in_bytes() >= eden_alignment,
+       "Alignment is wrong");
+@@ -104,14 +104,15 @@
+     // for reasons the "increment" fraction is used.
+     PSAdaptiveSizePolicy* policy = heap->size_policy();
+     size_t result = policy->eden_increment_aligned_down(max_contraction);
++    size_t result_aligned = align_size_down(result, gen_alignment);
+     if (PrintAdaptiveSizePolicy && Verbose) {
+       gclog_or_tty->print_cr("ASPSYoungGen::available_for_contraction: %d K",
+-	result/K);
++        result_aligned/K);
+       gclog_or_tty->print_cr("	max_contraction %d K", max_contraction/K);
+       gclog_or_tty->print_cr("	eden_avail %d K", eden_avail/K);
+       gclog_or_tty->print_cr("	gen_avail %d K", gen_avail/K);
+     }
+-    return result;
++    return result_aligned;
+ 
+   }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)asPSYoungGen.hpp	1.16 07/05/05 17:05:26 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cardTableExtension.cpp	1.34 07/05/17 15:52:46 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -191,15 +188,21 @@
+           *first_nonclean_card++ = clean_card;
+         }
+         // scan oops in objects
++        // hoisted the if (depth_first) check out of the loop
++        if (depth_first){
+         do {
+-	  if (depth_first) {
+ 	    oop(bottom_obj)->push_contents(pm);
++            bottom_obj += oop(bottom_obj)->size();
++            assert(bottom_obj <= sp_top, "just checking");
++          } while (bottom_obj < top);
++          pm->drain_stacks_cond_depth();
+ 	  } else {
++          do {
+ 	    oop(bottom_obj)->copy_contents(pm);
+-	  }
+           bottom_obj += oop(bottom_obj)->size();
+           assert(bottom_obj <= sp_top, "just checking");
+         } while (bottom_obj < top);
++        }
+         // remember top oop* scanned
+         prev_top = top;
+       }
+@@ -347,29 +350,44 @@
+ 	const int interval = PrefetchScanIntervalInBytes;
+ 	// scan all objects in the range
+ 	if (interval != 0) {
++          // hoisted the if (depth_first) check out of the loop
++          if (depth_first) {
+ 	  while (p < to) {
+ 	    Prefetch::write(p, interval);
+ 	    oop m = oop(p);
+ 	    assert(m->is_oop_or_null(), "check for header");
+-	    if (depth_first) {
+ 	      m->push_contents(pm); 
++              p += m->size();
++            }
++            pm->drain_stacks_cond_depth();
+ 	    } else {
++            while (p < to) {
++              Prefetch::write(p, interval);
++              oop m = oop(p);
++              assert(m->is_oop_or_null(), "check for header");
+ 	      m->copy_contents(pm); 
+-	    }
+             p += m->size();
+           }
++          }
+ 	} else {
++          // hoisted the if (depth_first) check out of the loop
++          if (depth_first) {
+ 	  while (p < to) {
+ 	    oop m = oop(p);
+ 	    assert(m->is_oop_or_null(), "check for header");
+-	    if (depth_first) {
+ 	      m->push_contents(pm);
++              p += m->size();
++            }
++            pm->drain_stacks_cond_depth();
+ 	    } else {
++            while (p < to) {
++              oop m = oop(p);
++              assert(m->is_oop_or_null(), "check for header");
+ 	      m->copy_contents(pm);
+-	    }
+             p += m->size();
+           }
+ 	}
++        }
+ 	last_scanned = p;
+       }
+       // "current_card" is still the "following_clean_card" or
+@@ -759,4 +777,3 @@
+   }
+   return min_start;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cardTableExtension.hpp	1.20 07/05/05 17:05:26 JVM"
+-#endif
+ /*
+  * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -109,4 +106,3 @@
+   
+ #endif // ASSERT
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gcTaskManager.cpp	1.34 07/05/05 17:05:27 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -333,7 +330,7 @@
+ // 
+ 
+ SynchronizedGCTaskQueue::SynchronizedGCTaskQueue(GCTaskQueue* queue_arg,
+-                                                 Mutex*       lock_arg) :
++                                                 Monitor *       lock_arg) :
+   _unsynchronized_queue(queue_arg),
+   _lock(lock_arg) {
+   assert(unsynchronized_queue() != NULL, "null queue");
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)gcTaskManager.hpp	1.28 07/05/05 17:05:26 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -209,10 +206,10 @@
+ private:
+   // Instance state.
+   GCTaskQueue* _unsynchronized_queue;   // Has-a unsynchronized queue.
+-  Mutex*       _lock;                   // Lock to control access.
++  Monitor *    _lock;                   // Lock to control access.
+ public:
+   // Factory create and destroy methods.
+-  static SynchronizedGCTaskQueue* create(GCTaskQueue* queue, Mutex* lock) {
++  static SynchronizedGCTaskQueue* create(GCTaskQueue* queue, Monitor * lock) {
+     return new SynchronizedGCTaskQueue(queue, lock);
+   }
+   static void destroy(SynchronizedGCTaskQueue* that) {
+@@ -224,7 +221,7 @@
+   GCTaskQueue* unsynchronized_queue() const {
+     return _unsynchronized_queue;
+   }
+-  Mutex* lock() const {
++  Monitor * lock() const {
+     return _lock;
+   }
+   // GCTaskQueue wrapper methods.
+@@ -260,7 +257,7 @@
+   }
+ protected:
+   // Constructor.  Clients use factory, but there might be subclasses.
+-  SynchronizedGCTaskQueue(GCTaskQueue* queue, Mutex* lock);
++  SynchronizedGCTaskQueue(GCTaskQueue* queue, Monitor * lock);
+   // Destructor.  Not virtual because no virtuals.
+   ~SynchronizedGCTaskQueue();
+ };
+@@ -325,7 +322,7 @@
+   Monitor* monitor() const {
+     return _monitor;
+   }
+-  Mutex* lock() const {
++  Monitor * lock() const {
+     return _monitor;
+   }
+   // Methods.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,7 +1,4 @@
+ 
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gcTaskThread.cpp	1.25 07/05/05 17:05:26 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -151,4 +148,3 @@
+     }
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)gcTaskThread.hpp	1.18 07/05/05 17:05:27 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)generationSizer.hpp	1.17 07/05/05 17:05:27 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -70,5 +67,3 @@
+   size_t perm_gen_size()      { return PermSize; }
+   size_t max_perm_gen_size()  { return MaxPermSize; }
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)objectStartArray.cpp	1.20 07/05/05 17:05:28 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)objectStartArray.hpp	1.21 07/05/05 17:05:28 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -163,4 +160,3 @@
+   // "start", the method will return true.
+   bool object_starts_in_range(HeapWord* start_addr, HeapWord* end_addr) const;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)parallelScavengeHeap.cpp	1.94 07/05/17 15:52:49 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -36,59 +33,100 @@
+ ParallelScavengeHeap* ParallelScavengeHeap::_psh = NULL;
+ GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL;
+ 
++static void trace_gen_sizes(const char* const str,
++                            size_t pg_min, size_t pg_max,
++                            size_t og_min, size_t og_max,
++                            size_t yg_min, size_t yg_max)
++{
++  if (TracePageSizes) {
++    tty->print_cr("%s:  " SIZE_FORMAT "," SIZE_FORMAT " "
++                  SIZE_FORMAT "," SIZE_FORMAT " "
++                  SIZE_FORMAT "," SIZE_FORMAT " "
++                  SIZE_FORMAT,
++                  str, pg_min / K, pg_max / K,
++                  og_min / K, og_max / K,
++                  yg_min / K, yg_max / K,
++                  (pg_max + og_max + yg_max) / K);
++  }
++}
++
+ jint ParallelScavengeHeap::initialize() {
+   // Cannot be initialized until after the flags are parsed
+   GenerationSizer flag_parser;
+ 
+-  size_t max_young_size = flag_parser.max_young_gen_size();
+-  size_t max_old_size = flag_parser.max_old_gen_size();
+-  if (UseLargePages && 
+-      (max_young_size + max_old_size) >= LargePageHeapSizeThreshold) {
+-    adjust_generation_alignment_for_page_size(os::large_page_size());
+-  }
+-  const size_t alignment = generation_alignment();
+-
+-  // Check alignments
+-// NEEDS_CLEANUP   The default TwoGenerationCollectorPolicy uses
+-//   NewRatio;  it should check UseAdaptiveSizePolicy. Changes from
+-//   generationSizer could move to the common code.
+-  size_t min_young_size = 
+-    align_size_up(flag_parser.min_young_gen_size(), alignment);
+-  size_t young_size = align_size_up(flag_parser.young_gen_size(), alignment);
+-  max_young_size = align_size_up(max_young_size, alignment);
+-
+-  size_t min_old_size = 
+-    align_size_up(flag_parser.min_old_gen_size(), alignment);
+-  size_t old_size = align_size_up(flag_parser.old_gen_size(), alignment);
+-  old_size = MAX2(old_size, min_old_size);
+-  max_old_size = align_size_up(max_old_size, alignment);
+-
+-  size_t perm_size = align_size_up(flag_parser.perm_gen_size(), alignment);
+-  size_t max_perm_size = align_size_up(flag_parser.max_perm_gen_size(), 
+-                                                                  alignment);
+-
+-  // Calculate the total size.
+-  size_t total_reserved = max_young_size + max_old_size + max_perm_size;
+-
+-  if (UseLargePages) {
+-    total_reserved = round_to(total_reserved, os::large_page_size());
+-  }
++  size_t yg_min_size = flag_parser.min_young_gen_size();
++  size_t yg_max_size = flag_parser.max_young_gen_size();
++  size_t og_min_size = flag_parser.min_old_gen_size();
++  size_t og_max_size = flag_parser.max_old_gen_size();
++  // Why isn't there a min_perm_gen_size()?
++  size_t pg_min_size = flag_parser.perm_gen_size();
++  size_t pg_max_size = flag_parser.max_perm_gen_size();
++
++  trace_gen_sizes("ps heap raw",
++                  pg_min_size, pg_max_size,
++                  og_min_size, og_max_size,
++                  yg_min_size, yg_max_size);
++
++  // The ReservedSpace ctor used below requires that the page size for the perm
++  // gen is <= the page size for the rest of the heap (young + old gens).
++  const size_t og_page_sz = os::page_size_for_region(yg_min_size + og_min_size,
++                                                     yg_max_size + og_max_size,
++                                                     8);
++  const size_t pg_page_sz = MIN2(os::page_size_for_region(pg_min_size,
++                                                          pg_max_size, 16),
++                                 og_page_sz);
++
++  const size_t pg_align = set_alignment(_perm_gen_alignment,  pg_page_sz);
++  const size_t og_align = set_alignment(_old_gen_alignment,   og_page_sz);
++  const size_t yg_align = set_alignment(_young_gen_alignment, og_page_sz);
+ 
+-  ReservedSpace heap_rs(total_reserved, alignment, UseLargePages);
++  // Update sizes to reflect the selected page size(s).
++  //
++  // NEEDS_CLEANUP.  The default TwoGenerationCollectorPolicy uses NewRatio; it
++  // should check UseAdaptiveSizePolicy.  Changes from generationSizer could
++  // move to the common code.
++  yg_min_size = align_size_up(yg_min_size, yg_align);
++  yg_max_size = align_size_up(yg_max_size, yg_align);
++  size_t yg_cur_size = align_size_up(flag_parser.young_gen_size(), yg_align);
++  yg_cur_size = MAX2(yg_cur_size, yg_min_size);
++
++  og_min_size = align_size_up(og_min_size, og_align);
++  og_max_size = align_size_up(og_max_size, og_align);
++  size_t og_cur_size = align_size_up(flag_parser.old_gen_size(), og_align);
++  og_cur_size = MAX2(og_cur_size, og_min_size);
++
++  pg_min_size = align_size_up(pg_min_size, pg_align);
++  pg_max_size = align_size_up(pg_max_size, pg_align);
++  size_t pg_cur_size = pg_min_size;
++
++  trace_gen_sizes("ps heap rnd",
++                  pg_min_size, pg_max_size,
++                  og_min_size, og_max_size,
++                  yg_min_size, yg_max_size);
++
++  // The main part of the heap (old gen + young gen) can often use a larger page
++  // size than is needed or wanted for the perm gen.  Use the "compound
++  // alignment" ReservedSpace ctor to avoid having to use the same page size for
++  // all gens.
++  ReservedSpace heap_rs(pg_max_size, pg_align, og_max_size + yg_max_size,
++                        og_align);
++  os::trace_page_sizes("ps perm", pg_min_size, pg_max_size, pg_page_sz,
++                       heap_rs.base(), pg_max_size);
++  os::trace_page_sizes("ps main", og_min_size + yg_min_size,
++                       og_max_size + yg_max_size, og_page_sz,
++                       heap_rs.base() + pg_max_size,
++                       heap_rs.size() - pg_max_size);
+   if (!heap_rs.is_reserved()) {
+     vm_shutdown_during_initialization(
+       "Could not reserve enough space for object heap");
+     return JNI_ENOMEM;
+   }
+ 
+-  _reserved_byte_size = heap_rs.size();
+   _reserved = MemRegion((HeapWord*)heap_rs.base(),
+ 			(HeapWord*)(heap_rs.base() + heap_rs.size()));
+ 
+-  HeapWord* boundary = (HeapWord*)(heap_rs.base() + max_young_size);
+-  CardTableExtension* card_table_barrier_set = new CardTableExtension(_reserved, 3);
+-  _barrier_set = card_table_barrier_set;
+-
++  CardTableExtension* const barrier_set = new CardTableExtension(_reserved, 3);
++  _barrier_set = barrier_set;
+   oopDesc::set_bs(_barrier_set);
+   if (_barrier_set == NULL) {
+     vm_shutdown_during_initialization(
+@@ -97,17 +135,15 @@
+   }
+ 
+   // Initial young gen size is 4 Mb
+-  size_t init_young_size = align_size_up(4 * M, alignment);
+-  init_young_size = MAX2(MIN2(init_young_size, max_young_size), young_size);
+-
+-  // Divide up the reserved space: perm, old, young
+-  ReservedSpace perm_rs  = heap_rs.first_part(max_perm_size);
+-  ReservedSpace old_young_rs                
+-			 = heap_rs.last_part(max_perm_size);
+-  ReservedSpace old_rs   = old_young_rs.first_part(max_old_size);
+-  heap_rs                = old_young_rs.last_part(max_old_size);
+-  ReservedSpace young_rs = heap_rs.first_part(max_young_size);
+-  assert(young_rs.size() == heap_rs.size(), "Didn't reserve all of the heap");
++  //
++  // XXX - what about flag_parser.young_gen_size()?
++  const size_t init_young_size = align_size_up(4 * M, yg_align);
++  yg_cur_size = MAX2(MIN2(init_young_size, yg_max_size), yg_cur_size);
++
++  // Split the reserved space into perm gen and the main heap (everything else).
++  // The main heap uses a different alignment.
++  ReservedSpace perm_rs = heap_rs.first_part(pg_max_size);
++  ReservedSpace main_rs = heap_rs.last_part(pg_max_size, og_align);
+ 
+   // Make up the generations
+   // Calculate the maximum size that a generation can grow.  This
+@@ -118,14 +154,14 @@
+   double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
+   double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
+ 
+-  _gens = new AdjoiningGenerations(old_young_rs,
+-  				   old_size,
+-		                   min_old_size,
+-		                   max_old_size,
+-		                   init_young_size,
+-		                   min_young_size,
+-		                   max_young_size,
+-				   alignment);
++  _gens = new AdjoiningGenerations(main_rs,
++                                   og_cur_size,
++                                   og_min_size,
++                                   og_max_size,
++                                   yg_cur_size,
++                                   yg_min_size,
++                                   yg_max_size,
++                                   yg_align);
+ 
+   _old_gen = _gens->old_gen();
+   _young_gen = _gens->young_gen();
+@@ -137,7 +173,6 @@
+     new PSAdaptiveSizePolicy(eden_capacity,
+ 			     initial_promo_size,
+ 			     young_gen()->to_space()->capacity_in_bytes(),
+-			     generation_alignment(),
+ 			     intra_generation_alignment(),
+ 			     max_gc_pause_sec,
+ 			     max_gc_minor_pause_sec,
+@@ -145,10 +180,10 @@
+ 			     );
+ 
+   _perm_gen = new PSPermGen(perm_rs,
+-			    alignment,
+-                            perm_size,
+-                            perm_size,
+-                            max_perm_size,
++                            pg_align,
++                            pg_cur_size,
++                            pg_cur_size,
++                            pg_max_size,
+                             "perm", 2);
+ 
+   assert(!UseAdaptiveGCBoundary ||
+@@ -170,22 +205,6 @@
+   return JNI_OK;
+ }
+ 
+-// Set the alignment of the generation so it would be aligned
+-// to both page_size and to intra_generation_alignment.
+-// This would require that we align to
+-// LCM(page_size, intra_generation_alignment), where LCM is
+-// "least common multiple". However, when page_size and
+-// intra_generation_alignment are both powers of 2, then
+-// round_to() below computes the same result; hence the
+-// assert below.
+-void ParallelScavengeHeap::adjust_generation_alignment_for_page_size(
+-  size_t page_size) {
+-  assert(is_power_of_2(page_size), 
+-    "Should not use round_to() if page size is not a power of 2");
+-  // round_to() checks that its second parameter is a power of 2
+-  set_generation_alignment(round_to(page_size, intra_generation_alignment()));
+-}
+-
+ void ParallelScavengeHeap::post_initialize() {
+   // Need to init the tenuring threshold
+   PSScavenge::initialize();
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)parallelScavengeHeap.hpp	1.61 07/05/17 15:52:51 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -42,14 +39,11 @@
+ 
+   static ParallelScavengeHeap* _psh;
+ 
+-  // Byte size of the reserved space for the heap
+-  size_t _reserved_byte_size;
++  size_t _perm_gen_alignment;
++  size_t _young_gen_alignment;
++  size_t _old_gen_alignment;
+ 
+-  size_t _generation_alignment;
+-  inline void set_generation_alignment(size_t val);
+-
+-  // Adjust alignment for page size (may be large page size)
+-  void adjust_generation_alignment_for_page_size(size_t page_size);
++  inline size_t set_alignment(size_t& var, size_t val);
+ 
+   // Collection of generations that are adjacent in the
+   // space reserved for the heap.
+@@ -57,9 +51,6 @@
+ 
+   static GCTaskManager*          _gc_task_manager;      // The task manager.
+ 
+-  // Private accessors
+-  size_t reserved_byte_size() const { return _reserved_byte_size; }
+-
+  protected:
+   static inline size_t total_invocations();
+   HeapWord* allocate_new_tlab(size_t size);
+@@ -67,7 +58,9 @@
+ 
+  public:
+   ParallelScavengeHeap() : CollectedHeap() {
+-    set_generation_alignment(intra_generation_alignment());
++    set_alignment(_perm_gen_alignment, intra_generation_alignment());
++    set_alignment(_young_gen_alignment, intra_generation_alignment());
++    set_alignment(_old_gen_alignment, intra_generation_alignment());
+   }
+ 
+   // For use by VM operations
+@@ -100,8 +93,10 @@
+   void post_initialize();
+   void update_counters();
+ 
+-  // The alignment used for generations.
+-  size_t generation_alignment() const { return _generation_alignment; }
++  // The alignment used for the various generations.
++  size_t perm_gen_alignment()  const { return _perm_gen_alignment; }
++  size_t young_gen_alignment() const { return _young_gen_alignment; }
++  size_t old_gen_alignment()  const { return _old_gen_alignment; }
+ 
+   // The alignment used for eden and survivors within the young gen.
+   size_t intra_generation_alignment() const { return 64 * K; }
+@@ -219,8 +214,9 @@
+   void resize_old_gen(size_t desired_free_space);
+ };
+ 
+-inline void ParallelScavengeHeap::set_generation_alignment(size_t val) {
+-  assert(align_size_up_(val, os::vm_page_size()) == val, "not aligned");
+-  assert(val >= intra_generation_alignment(), "alignment size is too small");
+-  _generation_alignment = val;
++inline size_t ParallelScavengeHeap::set_alignment(size_t& var, size_t val)
++{
++  assert(is_power_of_2((intptr_t)val), "must be a power of 2");
++  var = round_to(val, intra_generation_alignment());
++  return var;
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)parallelScavengeHeap.inline.hpp	1.5 07/05/05 17:05:28 JVM"
+-#endif
+ /*
+  * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)parMarkBitMap.cpp	1.30 07/05/05 17:05:27 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -31,17 +28,23 @@
+ bool
+ ParMarkBitMap::initialize(MemRegion covered_region)
+ {
+-  const size_t alloc_granularity = os::vm_allocation_granularity();
+   const idx_t bits = bits_required(covered_region);
+-  const idx_t words = bits / BitsPerWord;
+-  const idx_t bytes = align_size_up(words * sizeof(idx_t), alloc_granularity);
+-
+   // The bits will be divided evenly between two bitmaps; each of them should be
+   // an integral number of words.
+   assert(bits % (BitsPerWord * 2) == 0, "region size unaligned");
+ 
+-  ReservedSpace rs(bytes);
+-  _virtual_space = new PSVirtualSpace(rs, os::vm_page_size());
++  const size_t words = bits / BitsPerWord;
++  const size_t raw_bytes = words * sizeof(idx_t);
++  const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10);
++  const size_t granularity = os::vm_allocation_granularity();
++  const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity));
++
++  const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
++    MAX2(page_sz, granularity);
++  ReservedSpace rs(bytes, rs_align, false);
++  os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
++                       rs.base(), rs.size());
++  _virtual_space = new PSVirtualSpace(rs, page_sz);
+   if (_virtual_space != NULL && _virtual_space->expand_by(bytes)) {
+     _region_start = covered_region.start();
+     _region_size = covered_region.word_size();
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)parMarkBitMap.hpp	1.16 07/05/05 17:05:27 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)parMarkBitMap.inline.hpp	1.6 07/05/05 17:05:27 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)pcTasks.cpp	1.21 07/05/05 17:05:27 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -149,7 +146,7 @@
+ {
+   ParallelScavengeHeap* heap = PSParallelCompact::gc_heap();
+   uint parallel_gc_threads = heap->gc_task_manager()->workers();
+-  GenTaskQueueSet* qset = ParCompactionManager::chunk_array()->task_queue_set();
++  TaskQueueSetSuper* qset = ParCompactionManager::chunk_array();
+   ParallelTaskTerminator terminator(parallel_gc_threads, qset);
+   GCTaskQueue* q = GCTaskQueue::create();
+   for(uint i=0; i<parallel_gc_threads; i++) {
+@@ -284,4 +281,3 @@
+   // Process any chunks already in the compaction managers stacks.
+   cm->drain_chunk_stacks();
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)pcTasks.hpp	1.19 07/05/05 17:05:26 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/prefetchQueue.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/prefetchQueue.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/prefetchQueue.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/prefetchQueue.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)prefetchQueue.hpp	1.13 07/05/05 17:05:28 JVM"
+-#endif
+ /*
+  * Copyright 2002-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -68,6 +65,3 @@
+     return _prefetch_queue[_prefetch_index];
+   }
+ };
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psAdaptiveSizePolicy.cpp	1.81 07/05/05 17:05:29 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -33,7 +30,6 @@
+ PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
+ 					   size_t init_promo_size,
+ 					   size_t init_survivor_size,
+-					   size_t generation_alignment,
+ 					   size_t intra_generation_alignment,
+ 					   double gc_pause_goal_sec,
+ 					   double gc_minor_pause_goal_sec,
+@@ -45,18 +41,13 @@
+ 			gc_cost_ratio),
+      _collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin/
+        100.0),
+-     _generation_alignment(generation_alignment),
+      _intra_generation_alignment(intra_generation_alignment),
+      _live_at_last_full_gc(init_promo_size),
+      _gc_minor_pause_goal_sec(gc_minor_pause_goal_sec),
+      _latest_major_mutator_interval_seconds(0),
+      _young_gen_change_for_major_pause_count(0)
+ {
+-   assert(generation_alignment >= intra_generation_alignment,
+-     "generation alignment is too small")
+-
+   // Sizing policy statistics
+-    
+   _avg_major_pause    = 
+     new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding);
+   _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psAdaptiveSizePolicy.hpp	1.63 07/05/05 17:05:27 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -86,7 +83,6 @@
+   // for making ergonomic decisions.
+   double _latest_major_mutator_interval_seconds;
+ 
+-  const size_t _generation_alignment;       // alignment for generations
+   const size_t _intra_generation_alignment; // alignment for eden, survivors
+ 
+   const double _gc_minor_pause_goal_sec;    // goal for maximum minor gc pause
+@@ -222,7 +218,6 @@
+   PSAdaptiveSizePolicy(size_t init_eden_size, 
+ 		       size_t init_promo_size, 
+ 		       size_t init_survivor_size, 
+-		       size_t generation_alignment,
+ 		       size_t intra_generation_alignment,
+ 		       double gc_pause_goal_sec,
+ 		       double gc_minor_pause_goal_sec,
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psCompactionManager.cpp	1.21 07/05/05 17:05:28 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -97,7 +94,11 @@
+     _manager_array[i] = new ParCompactionManager();
+     guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager");
+     stack_array()->register_queue(i, _manager_array[i]->marking_stack());
++#ifdef USE_ChunkTaskQueueWithOverflow
++    chunk_array()->register_queue(i, _manager_array[i]->chunk_stack()->task_queue());
++#else
+     chunk_array()->register_queue(i, _manager_array[i]->chunk_stack());
++#endif
+   }
+ 
+   // The VMThread gets its own ParCompactionManager, which is not available
+@@ -175,13 +176,12 @@
+ }
+ 
+ bool ParCompactionManager::retrieve_for_processing(size_t& chunk_index) {
+-
+ #ifdef USE_ChunkTaskQueueWithOverflow
+   return chunk_stack()->retrieve(chunk_index);
+ #else
+   // Should not be used in the parallel case
+   ShouldNotReachHere();
+-  return NULL;
++  return false;
+ #endif
+ }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psCompactionManager.hpp	1.17 07/05/05 17:05:29 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psGCAdaptivePolicyCounters.cpp	1.23 07/05/05 17:05:31 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -200,4 +197,3 @@
+     update_counters_from_policy();
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psGCAdaptivePolicyCounters.hpp	1.21 07/05/05 17:05:29 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psGenerationCounters.cpp	1.7 07/05/05 17:05:29 JVM"
+-#endif
+ 
+ /*
+  * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psGenerationCounters.hpp	1.8 07/05/05 17:05:29 JVM"
+-#endif
+ 
+ /*
+  * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psMarkSweep.cpp	1.92 07/06/08 23:11:01 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psMarkSweepDecorator.cpp	1.26 07/05/17 15:52:53 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psMarkSweepDecorator.hpp	1.14 07/05/05 17:05:29 JVM"
+-#endif
+ /*
+  * Copyright 2001-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -74,7 +71,3 @@
+   void precompact();
+   void compact(bool mangle_free_space);
+ };
+-
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psMarkSweep.hpp	1.26 07/05/05 17:05:28 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -86,4 +83,3 @@
+   // Time since last full gc (in milliseconds)
+   static jlong millis_since_last_gc();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psOldGen.cpp	1.54 07/05/05 17:05:28 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psOldGen.hpp	1.37 07/05/05 17:05:30 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psParallelCompact.cpp	1.61 07/06/08 23:12:00 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -47,11 +44,23 @@
+ 
+ const size_t ParallelCompactData::BlocksPerChunk = ChunkSize / BlockSize;
+ 
+-// The values for Claimed and Completed were chosen simply to make decrementing
+-// them to another valid value 'unlikely.'
+-const size_t ParallelCompactData::ChunkData::Available = 0;
+-const size_t ParallelCompactData::ChunkData::Claimed   = 0x0ffff;
+-const size_t ParallelCompactData::ChunkData::Completed = 0xfffff;
++const ParallelCompactData::ChunkData::chunk_sz_t
++ParallelCompactData::ChunkData::dc_shift = 27;
++
++const ParallelCompactData::ChunkData::chunk_sz_t
++ParallelCompactData::ChunkData::dc_mask = ~0U << dc_shift;
++
++const ParallelCompactData::ChunkData::chunk_sz_t
++ParallelCompactData::ChunkData::dc_one = 0x1U << dc_shift;
++
++const ParallelCompactData::ChunkData::chunk_sz_t
++ParallelCompactData::ChunkData::los_mask = ~dc_mask;
++
++const ParallelCompactData::ChunkData::chunk_sz_t
++ParallelCompactData::ChunkData::dc_claimed = 0x8U << dc_shift;
++
++const ParallelCompactData::ChunkData::chunk_sz_t
++ParallelCompactData::ChunkData::dc_completed = 0xcU << dc_shift;
+ 
+ #ifdef ASSERT
+ short	ParallelCompactData::BlockData::_cur_phase = 0;
+@@ -397,11 +406,17 @@
+ PSVirtualSpace*
+ ParallelCompactData::create_vspace(size_t count, size_t element_size)
+ {
++  const size_t raw_bytes = count * element_size;
++  const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10);
+   const size_t granularity = os::vm_allocation_granularity();
+-  const size_t bytes = align_size_up(count * element_size, granularity);
++  const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity));
+ 
+-  ReservedSpace rs(bytes);
+-  PSVirtualSpace* vspace = new PSVirtualSpace(rs, os::vm_page_size());
++  const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
++    MAX2(page_sz, granularity);
++  ReservedSpace rs(bytes, rs_align, false);
++  os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(),
++                       rs.size());
++  PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz);
+   if (vspace != 0) {
+     if (vspace->expand_by(bytes)) {
+       return vspace;
+@@ -517,14 +532,13 @@
+   HeapWord* addr = beg;
+   while (cur_chunk < end_chunk) {
+     _chunk_data[cur_chunk].set_destination(addr);
+-    _chunk_data[cur_chunk].set_destination_count(ChunkData::Available);
++    _chunk_data[cur_chunk].set_destination_count(0);
+     _chunk_data[cur_chunk].set_source_chunk(cur_chunk);
+     _chunk_data[cur_chunk].set_data_location(addr);
+ 
+     // Update live_obj_size so the chunk appears completely full.
+     size_t live_size = ChunkSize - _chunk_data[cur_chunk].partial_obj_size();
+     _chunk_data[cur_chunk].set_live_obj_size(live_size);
+-    _chunk_data[cur_chunk].set_obj_not_updated(NULL);
+ 
+     ++cur_chunk;
+     addr += ChunkSize;
+@@ -590,7 +604,7 @@
+       // adjust the value below if necessary.  Under this assumption, if
+       // cur_chunk == dest_chunk_2, then cur_chunk will be compacted completely
+       // into itself.
+-      size_t destination_count = cur_chunk == dest_chunk_2 ? 0 : 1;
++      uint destination_count = cur_chunk == dest_chunk_2 ? 0 : 1;
+       if (dest_chunk_1 != dest_chunk_2) {
+ 	// Destination chunks differ; adjust destination_count.
+ 	destination_count += 1;
+@@ -606,7 +620,7 @@
+       // adjust the value below if necessary.  Under this assumption, if
+       // cur_chunk == dest_chunk2, then cur_chunk will be compacted partially
+       // into dest_chunk_1 and partially into itself.
+-      size_t destination_count = cur_chunk == dest_chunk_2 ? 1 : 2;
++      uint destination_count = cur_chunk == dest_chunk_2 ? 1 : 2;
+       if (dest_chunk_1 != dest_chunk_2) {
+ 	// Data from cur_chunk will be copied to the start of dest_chunk_2.
+ 	_chunk_data[dest_chunk_2].set_source_chunk(cur_chunk);
+@@ -633,11 +647,6 @@
+   return true;
+ }
+ 
+-void ParallelCompactData::set_obj_not_updated(HeapWord* moved_obj) {
+-  size_t chunk_index = addr_to_chunk_idx(moved_obj);
+-  chunk(chunk_index)->set_obj_not_updated(moved_obj);
+-}
+-
+ bool ParallelCompactData::partial_obj_ends_in_block(size_t block_index) {
+   HeapWord* block_addr = block_to_addr(block_index);
+   HeapWord* block_end_addr = block_addr + BlockSize;
+@@ -655,39 +664,6 @@
+   return false;
+ }
+ 
+-HeapWord*
+-ParallelCompactData::first_live_or_end_in_chunk_range(size_t chunk_index_start,
+-						      size_t chunk_index_end) {
+-  HeapWord* const end_addr = chunk_to_addr(chunk_index_end);
+-
+-  // A live object may entend into the chunk; skip over it.
+-  HeapWord* poe_addr = partial_obj_end(chunk_index_start);
+-  if (poe_addr >= end_addr) {
+-    return end_addr;
+-  }
+-
+-  // Search the bitmap for the next object.
+-  typedef ParMarkBitMap::idx_t idx_t;
+-  ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
+-  const idx_t beg_bit = bitmap->addr_to_bit(poe_addr);
+-  const idx_t end_bit = bitmap->addr_to_bit(end_addr);
+-  const idx_t res_bit = bitmap->find_obj_beg(beg_bit, end_bit);
+-  return res_bit < end_bit ? bitmap->bit_to_addr(res_bit) : end_addr;
+-}
+-
+-HeapWord* ParallelCompactData::first_live_or_end_in_chunk(size_t chunk_index) {
+-  // Has the first live for the chunk already been found once?
+-  HeapWord* result = NULL;
+-  HeapWord* first_addr = chunk_to_addr(chunk_index);
+-  if (chunk(chunk_index)->first_live_obj() >= first_addr) {
+-    result = chunk(chunk_index)->first_live_obj();
+-  } else {
+-    result = first_live_or_end_in_chunk_range(chunk_index, chunk_index + 1);
+-    chunk(chunk_index)->set_first_live_obj(result);
+-  }
+-  return result;
+-}
+-
+ HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
+   HeapWord* result = NULL;
+   if (UseParallelOldGCChunkPointerCalc) {
+@@ -2372,7 +2348,7 @@
+ 
+   ParallelScavengeHeap* heap = gc_heap();
+   uint parallel_gc_threads = heap->gc_task_manager()->workers();
+-  GenTaskQueueSet* qset = ParCompactionManager::chunk_array()->task_queue_set();
++  TaskQueueSetSuper* qset = ParCompactionManager::chunk_array();
+   ParallelTaskTerminator terminator(parallel_gc_threads, qset);
+ 
+   PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
+@@ -2677,7 +2653,7 @@
+   PSOldGen* old_gen = heap->old_gen();
+   old_gen->start_array()->reset();
+   uint parallel_gc_threads = heap->gc_task_manager()->workers();
+-  GenTaskQueueSet* qset = ParCompactionManager::chunk_array()->task_queue_set();
++  TaskQueueSetSuper* qset = ParCompactionManager::chunk_array();
+   ParallelTaskTerminator terminator(parallel_gc_threads, qset);
+ 
+   GCTaskQueue* q = GCTaskQueue::create();
+@@ -3045,8 +3021,10 @@
+   }
+ 
+   // Mark the chunks as filled.
+-  for (size_t done_chunk = beg_chunk; done_chunk < end_chunk; ++done_chunk) {
+-    sd.chunk(done_chunk)->set_completed();
++  ChunkData* const beg_cp = sd.chunk(beg_chunk);
++  ChunkData* const end_cp = sd.chunk(end_chunk);
++  for (ChunkData* cp = beg_cp; cp < end_cp; ++cp) {
++    cp->set_completed();
+   }
+ }
+ 
+@@ -3083,7 +3061,7 @@
+   const ChunkData* const end_chunk = sd.addr_to_chunk_ptr(end_addr);
+   const ChunkData* cur_chunk;
+   for (cur_chunk = beg_chunk; cur_chunk < end_chunk; ++cur_chunk) {
+-    HeapWord* const addr = cur_chunk->obj_not_updated();
++    HeapWord* const addr = cur_chunk->deferred_obj_addr();
+     if (addr != NULL) {
+       if (start_array != NULL) {
+ 	start_array->allocate_block(addr);
+@@ -3312,6 +3290,7 @@
+     closure.copy_partial_obj();
+     if (closure.is_full()) {
+       decrement_destination_counts(cm, src_chunk_idx, closure.source());
++      chunk_ptr->set_deferred_obj_addr(NULL);
+       chunk_ptr->set_completed();
+       return;
+     }
+@@ -3355,12 +3334,17 @@
+     if (status == ParMarkBitMap::would_overflow) {
+       // The last object did not fit.  Note that interior oop updates were
+       // deferred, then copy enough of the object to fill the chunk.
+-      chunk_ptr->set_obj_not_updated(closure.destination());
++      chunk_ptr->set_deferred_obj_addr(closure.destination());
+       status = closure.copy_until_full(); // copies from closure.source()
++
++      decrement_destination_counts(cm, src_chunk_idx, closure.source());
++      chunk_ptr->set_completed();
++      return;
+     }
+ 
+     if (status == ParMarkBitMap::full) {
+       decrement_destination_counts(cm, src_chunk_idx, closure.source());
++      chunk_ptr->set_deferred_obj_addr(NULL);
+       chunk_ptr->set_completed();
+       return;
+     }
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psParallelCompact.hpp	1.47 07/05/05 17:05:30 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -100,28 +97,33 @@
+   class ChunkData
+   {
+   public:
+-    static const size_t Available;
+-    static const size_t Claimed;
+-    static const size_t Completed;
++    // Destination address of the chunk.
++    HeapWord* destination() const { return _destination; }
+ 
+-  public:
+-    // Size of the partial object extending onto the chunk (words).
+-    size_t partial_obj_size() const { return _partial_obj_size; }
++    // The first chunk containing data destined for this chunk.
++    size_t source_chunk() const { return _source_chunk; }
++
++    // The object (if any) starting in this chunk and ending in a different
++    // chunk that could not be updated during the main (parallel) compaction
++    // phase.  This is different from _partial_obj_addr, which is an object that
++    // extends onto a source chunk.  However, the two uses do not overlap in
++    // time, so the same field is used to save space.
++    HeapWord* deferred_obj_addr() const { return _partial_obj_addr; }
+ 
+-    // The starting address of the partial object.
++    // The starting address of the partial object extending onto the chunk.
+     HeapWord* partial_obj_addr() const { return _partial_obj_addr; }
+ 
++    // Size of the partial object extending onto the chunk (words).
++    size_t partial_obj_size() const { return _partial_obj_size; }
++
+     // Size of live data that lies within this chunk due to objects that start
+     // in this chunk (words).  This does not include the partial object
+     // extending onto the chunk (if any), or the part of an object that extends
+     // onto the next chunk (if any).
+-    size_t live_obj_size() const { return _live_obj_size; }
++    size_t live_obj_size() const { return _dc_and_los & los_mask; }
+ 
+     // Total live data that lies within the chunk (words).
+-    size_t data_size() const { return _partial_obj_size + _live_obj_size; }
+-
+-    // Destination address of the chunk.
+-    HeapWord* destination() const { return _destination; }
++    size_t data_size() const { return partial_obj_size() + live_obj_size(); }
+ 
+     // The destination_count is the number of other chunks to which data from
+     // this chunk will be copied.  At the end of the summary phase, the valid
+@@ -138,90 +140,74 @@
+     // then filled.
+     // 
+     // A chunk is claimed for processing by atomically changing the
+-    // destination_count from Available to Claimed.  After a chunk has been
+-    // filled, the destination_count should be set to ChunkData::Completed.
+-    size_t destination_count() const { return _destination_count; }
+-
+-    // Cached address of the first live object starting in the chunk.  If the
+-    // value has not been cached yet, returns NULL.  If there is no live object
+-    // starting in the chunk, returns the address one past the end of the chunk.
+-    HeapWord* first_live_obj() { return _first_live_obj; }
+-
+-    // Object that crosses this chunk's right (upper) boundary and whose
+-    // starting address is in this chunk.  This is set during
+-    // compaction when an object extends over the right (upper) boundary of
+-    // a destination chunk.  This is different than _partial_obj_addr
+-    // which extends over the left (lower) boundary of a source chunk.
+-    // This object is unique to a chunk.
+-    HeapWord* obj_not_updated() const { return _obj_not_updated; }
+-
+-    // The first chunk containing data destined for this chunk.
+-    size_t source_chunk() const { return _source_chunk; }
++    // destination_count to the claimed value (dc_claimed).  After a chunk has
++    // been filled, the destination_count should be set to the completed value
++    // (dc_completed).
++    inline uint destination_count() const;
++    inline uint destination_count_raw() const;
+ 
+     // The location of the java heap data that corresponds to this chunk.
+-    HeapWord* data_location() const { return _data_location; }
++    inline HeapWord* data_location() const;
+ 
+     // The highest address referenced by objects in this chunk.
+-    HeapWord* highest_ref() const { return _highest_ref; }
++    inline HeapWord* highest_ref() const;
+ 
+     // Whether this chunk is available to be claimed, has been claimed, or has
+     // been completed.
+-    bool available() const { return _destination_count == Available; }
+-    bool claimed() const   { return _destination_count == Claimed; }
+-    bool completed() const { return _destination_count == Completed; }
++    //
++    // Minor subtlety:  claimed() returns true if the chunk is marked
++    // completed(), which is desirable since a chunk must be claimed before it
++    // can be completed.
++    bool available() const { return _dc_and_los < dc_one; }
++    bool claimed() const   { return _dc_and_los >= dc_claimed; }
++    bool completed() const { return _dc_and_los >= dc_completed; }
+ 
+     // These are not atomic.
+-    void set_partial_obj_size(size_t words)  { _partial_obj_size = words; }
+-    void set_partial_obj_addr(HeapWord* k)   { _partial_obj_addr = k; }
+-    void set_live_obj_size(size_t words)     { _live_obj_size = words; }
+     void set_destination(HeapWord* addr)     { _destination = addr; }
+-    void set_destination_count(size_t count) { _destination_count = count; }
+-    void set_first_live_obj(HeapWord* v)     { _first_live_obj = v; }
+-    void set_obj_not_updated(HeapWord* addr) { _obj_not_updated = addr; }
+     void set_source_chunk(size_t chunk)      { _source_chunk = chunk; }
+-    void set_data_location(HeapWord* addr)   { _data_location = addr; }
++    void set_deferred_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; }
++    void set_partial_obj_addr(HeapWord* addr)  { _partial_obj_addr = addr; }
++    void set_partial_obj_size(size_t words)    {
++      _partial_obj_size = (chunk_sz_t) words;
++    }
++
++    inline void set_destination_count(uint count);
++    inline void set_live_obj_size(size_t words);
++    inline void set_data_location(HeapWord* addr);
+     inline void set_completed();
+     inline bool claim_unsafe();
+ 
+     // These are atomic.
+-    void add_live_obj(size_t words)          { add_live_obj((intptr_t)words); }
+-
+-    void set_highest_ref(HeapWord* addr) {
+-      HeapWord* tmp = _highest_ref;
+-      while (addr > tmp) {
+-	tmp = (HeapWord*)Atomic::cmpxchg_ptr(addr, &_highest_ref, tmp);
+-      }
+-    }
+-
+-    void decrement_destination_count() {
+-      assert(_destination_count < Claimed, "Chunk already claimed");
+-      assert(_destination_count > 0, "count must not go negative");
+-      Atomic::add_ptr(-1, &_destination_count);
+-    }
+-
+-    bool claim() {
+-      size_t old_val = cmpxchg_size_t(Claimed, &_destination_count, Available);
+-      return old_val == Available;
+-    }
++    inline void add_live_obj(size_t words);
++    inline void set_highest_ref(HeapWord* addr);
++    inline void decrement_destination_count();
++    inline bool claim();
+ 
+   private:
+-    static size_t cmpxchg_size_t(size_t new_val, volatile size_t* addr,
+-				 size_t old_val) {
+-      return size_t(Atomic::cmpxchg_ptr((void*)new_val, addr, (void*)old_val));
+-    }
+-    void add_live_obj(intptr_t sz) { Atomic::add_ptr(sz, &_live_obj_size); }
++    // The type used to represent object sizes within a chunk.
++    typedef uint chunk_sz_t;
++
++    // Constants for manipulating the _dc_and_los field, which holds both the
++    // destination count and live obj size.  The live obj size lives at the
++    // least significant end so no masking is necessary when adding.
++    static const chunk_sz_t dc_shift;           // Shift amount.
++    static const chunk_sz_t dc_mask;            // Mask for destination count.
++    static const chunk_sz_t dc_one;             // 1, shifted appropriately.
++    static const chunk_sz_t dc_claimed;         // Chunk has been claimed.
++    static const chunk_sz_t dc_completed;       // Chunk has been completed.
++    static const chunk_sz_t los_mask;           // Mask for live obj size.
+ 
+-  private:
+-    size_t          _partial_obj_size;
+-    HeapWord*       _partial_obj_addr;
+-    volatile size_t _live_obj_size;
+     HeapWord*       _destination;
+-    HeapWord*       _first_live_obj;
+-    HeapWord*	    _obj_not_updated;
+     size_t          _source_chunk;
++    HeapWord*           _partial_obj_addr;
++    chunk_sz_t          _partial_obj_size;
++    chunk_sz_t volatile _dc_and_los;
++#ifdef ASSERT
++    // These enable optimizations that are only partially implemented.  Use
++    // debug builds to prevent the code fragments from breaking.
+     HeapWord*       _data_location;
+     HeapWord*       _highest_ref;
+-    volatile size_t _destination_count;
++#endif  // #ifdef ASSERT
+ 
+ #ifdef ASSERT
+    public:
+@@ -357,10 +343,6 @@
+   inline BlockData* addr_to_block_ptr(const HeapWord* addr) const;
+   inline HeapWord*  block_to_addr(size_t block) const;
+ 
+-  // The given object (new location) was not updated.
+-  // Set the _obj_not_updated field in the appropriate chunk.
+-  void set_obj_not_updated(HeapWord* moved_obj);
+-
+   // Return the address one past the end of the partial object.
+   HeapWord* partial_obj_end(size_t chunk_idx) const;
+ 
+@@ -386,16 +368,6 @@
+   // If there is no partial object, returns false.
+   bool partial_obj_ends_in_block(size_t block_index);
+ 
+-  // Returns the address of the first live object starting in the chunk.
+-  HeapWord* first_live_or_end_in_chunk(size_t chunk_index);
+-
+-  // Returns the address of the first live object starting in the chunk.
+-  HeapWord* first_live_or_end_in_chunk_range(size_t chunk_index_start,
+-					     size_t chunk_index_end);
+-
+-  // Returns the address of the first live object starting in the block.
+-  HeapWord* first_live_object_in_block(size_t block_index);
+-
+   // Returns the block index for the block
+   static size_t block_idx(BlockData* block);
+ 
+@@ -424,23 +396,97 @@
+   size_t          _block_count;
+ };
+ 
++inline uint
++ParallelCompactData::ChunkData::destination_count_raw() const
++{
++  return _dc_and_los & dc_mask;
++}
++
++inline uint
++ParallelCompactData::ChunkData::destination_count() const
++{
++  return destination_count_raw() >> dc_shift;
++}
++
++inline void
++ParallelCompactData::ChunkData::set_destination_count(uint count)
++{
++  assert(count <= (dc_completed >> dc_shift), "count too large");
++  const chunk_sz_t live_sz = (chunk_sz_t) live_obj_size();
++  _dc_and_los = (count << dc_shift) | live_sz;
++}
++
++inline void ParallelCompactData::ChunkData::set_live_obj_size(size_t words)
++{
++  assert(words <= los_mask, "would overflow");
++  _dc_and_los = destination_count_raw() | (chunk_sz_t)words;
++}
++
++inline void ParallelCompactData::ChunkData::decrement_destination_count()
++{
++  assert(_dc_and_los < dc_claimed, "already claimed");
++  assert(_dc_and_los >= dc_one, "count would go negative");
++  Atomic::add((int)dc_mask, (volatile int*)&_dc_and_los);
++}
++
++inline HeapWord* ParallelCompactData::ChunkData::data_location() const
++{
++  DEBUG_ONLY(return _data_location;)
++  NOT_DEBUG(return NULL;)
++}
++
++inline HeapWord* ParallelCompactData::ChunkData::highest_ref() const
++{
++  DEBUG_ONLY(return _highest_ref;)
++  NOT_DEBUG(return NULL;)
++}
++
++inline void ParallelCompactData::ChunkData::set_data_location(HeapWord* addr)
++{
++  DEBUG_ONLY(_data_location = addr;)
++}
++
+ inline void ParallelCompactData::ChunkData::set_completed()
+ {
+   assert(claimed(), "must be claimed first");
+-  set_destination_count(Completed);
++  _dc_and_los = dc_completed | (chunk_sz_t) live_obj_size();
+ }
+ 
+ // MT-unsafe claiming of a chunk.  Should only be used during single threaded
+ // execution.
+ inline bool ParallelCompactData::ChunkData::claim_unsafe()
+ {
+-  if (destination_count() == Available) {
+-    set_destination_count(Claimed);
++  if (available()) {
++    _dc_and_los |= dc_claimed;
+     return true;
+   }
+   return false;
+ }
+ 
++inline void ParallelCompactData::ChunkData::add_live_obj(size_t words)
++{
++  assert(words <= (size_t)los_mask - live_obj_size(), "overflow");
++  Atomic::add((int) words, (volatile int*) &_dc_and_los);
++}
++
++inline void ParallelCompactData::ChunkData::set_highest_ref(HeapWord* addr)
++{
++#ifdef ASSERT
++  HeapWord* tmp = _highest_ref;
++  while (addr > tmp) {
++    tmp = (HeapWord*)Atomic::cmpxchg_ptr(addr, &_highest_ref, tmp);
++  }
++#endif  // #ifdef ASSERT
++}
++
++inline bool ParallelCompactData::ChunkData::claim()
++{
++  const int los = (int) live_obj_size();
++  const int old = Atomic::cmpxchg(dc_claimed | los,
++                                  (volatile int*) &_dc_and_los, los);
++  return old == los;
++}
++
+ inline ParallelCompactData::ChunkData*
+ ParallelCompactData::chunk(size_t chunk_idx) const
+ {
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psPermGen.cpp	1.28 07/05/05 17:05:30 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psPermGen.hpp	1.18 07/05/05 17:05:30 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -54,4 +51,3 @@
+ 
+   virtual const char* name() const { return "PSPermGen"; }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psPromotionLAB.cpp	1.17 07/05/05 17:05:30 JVM"
+-#endif
+ /*
+  * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psPromotionLAB.hpp	1.13 07/05/05 17:05:30 JVM"
+-#endif
+ /*
+  * Copyright 2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -143,5 +140,3 @@
+ 
+   debug_only(virtual bool lab_is_valid(MemRegion lab));
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psPromotionManager.cpp	1.29 07/05/05 17:05:30 JVM"
+-#endif
+ /*
+  * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -68,7 +65,6 @@
+   // for work stealing. 
+   _manager_array[ParallelGCThreads] = new PSPromotionManager();
+   guarantee(_manager_array[ParallelGCThreads] != NULL, "Could not create PSPromotionManager");
+-
+ }
+ 
+ PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(int index) {
+@@ -94,6 +90,10 @@
+ }
+ 
+ void PSPromotionManager::post_scavenge() {
++#if PS_PM_STATS
++  print_stats();
++#endif // PS_PM_STATS
++
+   for(uint i=0; i<ParallelGCThreads+1; i++) {
+     PSPromotionManager* manager = manager_array(i);
+ 
+@@ -137,6 +137,38 @@
+   }
+ }
+ 
++#if PS_PM_STATS
++
++void
++PSPromotionManager::print_stats(uint i) {
++  tty->print_cr("---- GC Worker %2d Stats", i);
++  tty->print_cr("    total pushes            %8d", _total_pushes);
++  tty->print_cr("    masked pushes           %8d", _masked_pushes);
++  tty->print_cr("    overflow pushes         %8d", _overflow_pushes);
++  tty->print_cr("    max overflow length     %8d", _max_overflow_length);
++  tty->print_cr("");
++  tty->print_cr("    arrays chunked          %8d", _arrays_chunked);
++  tty->print_cr("    array chunks processed  %8d", _array_chunks_processed);
++  tty->print_cr("");
++  tty->print_cr("    total steals            %8d", _total_steals);
++  tty->print_cr("    masked steals           %8d", _masked_steals);
++  tty->print_cr("");
++}
++
++void
++PSPromotionManager::print_stats() {
++  tty->print_cr("== GC Tasks Stats (%s), GC %3d",
++                (UseDepthFirstScavengeOrder) ? "Depth-First" : "Breadth-First",
++                Universe::heap()->total_collections());
++
++  for (uint i = 0; i < ParallelGCThreads+1; ++i) {
++    PSPromotionManager* manager = manager_array(i);
++    manager->print_stats(i);
++  }
++}
++
++#endif // PS_PM_STATS
++
+ PSPromotionManager::PSPromotionManager() {
+   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+@@ -169,6 +201,10 @@
+                                      (uint) (queue_size / 4));
+   }
+ 
++  _array_chunk_size = ParGCArrayScanChunk;
++  // let's choose 1.5x the chunk size
++  _min_array_size_for_chunking = 3 * _array_chunk_size / 2;
++
+   reset();
+ }
+ 
+@@ -191,9 +227,21 @@
+   _old_gen_is_full = false;
+   
+   _prefetch_queue.clear();
++
++#if PS_PM_STATS
++  _total_pushes = 0;
++  _masked_pushes = 0;
++  _overflow_pushes = 0;
++  _max_overflow_length = 0;
++  _arrays_chunked = 0;
++  _array_chunks_processed = 0;
++  _total_steals = 0;
++  _masked_steals = 0;
++#endif // PS_PM_STATS
+ }
+ 
+ void PSPromotionManager::drain_stacks_depth(bool totally_drain) {
++  assert(depth_first(), "invariant");
+   assert(overflow_stack_depth() != NULL, "invariant");
+   totally_drain = totally_drain || _totally_drain;
+ 
+@@ -212,17 +260,17 @@
+     // claimed stack while we work.
+     while(!overflow_stack_depth()->is_empty()) {
+       p = overflow_stack_depth()->pop();
+-      PSScavenge::copy_and_push_safe_barrier(this, p);
++      process_popped_location_depth(p);
+     }
+ 
+     if (totally_drain) {
+       while (claimed_stack_depth()->pop_local(p)) {
+-	PSScavenge::copy_and_push_safe_barrier(this, p);
++        process_popped_location_depth(p);
+       }
+     } else {
+       while (claimed_stack_depth()->size() > _target_stack_size &&
+ 	     claimed_stack_depth()->pop_local(p)) {
+-	PSScavenge::copy_and_push_safe_barrier(this, p);
++        process_popped_location_depth(p);
+       }
+     }
+   } while( (totally_drain && claimed_stack_depth()->size() > 0) ||
+@@ -236,6 +284,7 @@
+ }
+ 
+ void PSPromotionManager::drain_stacks_breadth(bool totally_drain) {
++  assert(!depth_first(), "invariant");
+   assert(overflow_stack_breadth() != NULL, "invariant");
+   totally_drain = totally_drain || _totally_drain;
+ 
+@@ -420,13 +469,28 @@
+       }
+ 
+       if (depth_first) {
+-	new_obj->push_contents(this);
++        // Do the size comparison first with new_obj_size, which we
++        // already have. Hopefully, only a few objects are larger than
++        // _min_array_size_for_chunking, and most of them will be arrays.
++        // So, the is->objArray() test would be very infrequent.
++        if (new_obj_size > _min_array_size_for_chunking &&
++            new_obj->is_objArray() &&
++            PSChunkLargeArrays) {
++          // we'll chunk it
++#if PS_PM_STATS
++          ++_arrays_chunked;
++#endif // PS_PM_STATS
++          oop* const masked_o = mask_chunked_array_oop(o);
++          push_depth(masked_o);
++#if PS_PM_STATS
++          ++_masked_pushes;
++#endif // PS_PM_STATS
+       } else {
+-	// If we loop too many times, handle_stack_overflow will assert.
+-	// It may be worth adding loop count asserts anyway.
+-	if (!claimed_stack_breadth()->push(new_obj)) {
+-	  overflow_stack_breadth()->push(new_obj);
++          // we'll just push its contents
++          new_obj->push_contents(this);
+ 	}
++      } else {
++        push_breadth(new_obj);
+       }
+     }  else {
+       // We lost, someone else "owns" this object
+@@ -476,6 +540,47 @@
+   return new_obj;
+ }
+ 
++void PSPromotionManager::process_array_chunk(oop old) {
++  assert(PSChunkLargeArrays, "invariant");
++  assert(old->is_objArray(), "invariant");
++  assert(old->is_forwarded(), "invariant");
++
++#if PS_PM_STATS
++  ++_array_chunks_processed;
++#endif // PS_PM_STATS
++
++  oop const obj = old->forwardee();
++
++  int start;
++  int const end = arrayOop(old)->length();
++  if (end > (int) _min_array_size_for_chunking) {
++    // we'll chunk more
++    start = end - _array_chunk_size;
++    assert(start > 0, "invariant");
++    arrayOop(old)->set_length(start);
++    push_depth(mask_chunked_array_oop(old));
++#if PS_PM_STATS
++    ++_masked_pushes;
++#endif // PS_PM_STATS
++  } else {
++    // this is the final chunk for this array
++    start = 0;
++    int const actual_length = arrayOop(obj)->length();
++    arrayOop(old)->set_length(actual_length);
++  }
++
++  assert(start < end, "invariant");
++  oop* const base      = objArrayOop(obj)->base();
++  oop* p               = base + start;
++  oop* const chunk_end = base + end;
++  while (p < chunk_end) {
++    if (PSScavenge::should_scavenge(*p)) {
++      claim_or_forward_depth(p);
++    }
++    ++p;
++  }
++}
++
+ oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
+   assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
+ 
+@@ -493,9 +598,7 @@
+     } else {
+       // Don't bother incrementing the age, just push
+       // onto the claimed_stack..
+-      if(!claimed_stack_breadth()->push(obj)) {
+-	overflow_stack_breadth()->push(obj);
+-      }
++      push_breadth(obj);
+     }
+ 
+     // Save the mark if needed
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psPromotionManager.hpp	1.19 07/05/05 17:05:30 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -41,11 +38,14 @@
+ #define HAS_BEEN_MOVED 0x1501d01d
+ // End move to some global location
+ 
+-
+ class MutableSpace;
+ class PSOldGen;
+ class ParCompactionManager;
+ 
++#define PS_CHUNKED_ARRAY_OOP_MASK  1
++
++#define PS_PM_STATS         0
++
+ class PSPromotionManager : public CHeapObj {
+   friend class PSScavenge;
+   friend class PSRefProcTaskExecutor;
+@@ -56,6 +56,23 @@
+   static PSOldGen*             _old_gen;
+   static MutableSpace*         _young_space;
+   
++#if PS_PM_STATS
++  uint                                _total_pushes;
++  uint                                _masked_pushes;
++
++  uint                                _overflow_pushes;
++  uint                                _max_overflow_length;
++
++  uint                                _arrays_chunked;
++  uint                                _array_chunks_processed;
++
++  uint                                _total_steals;
++  uint                                _masked_steals;
++
++  void print_stats(uint i);
++  static void print_stats();
++#endif // PS_PM_STATS
++
+   PSYoungPromotionLAB          _young_lab;
+   PSOldPromotionLAB            _old_lab;
+   bool                         _young_gen_is_full;
+@@ -71,17 +88,92 @@
+   bool                         _totally_drain;
+   uint                         _target_stack_size;
+ 
++  uint                                _array_chunk_size;
++  uint                                _min_array_size_for_chunking;
++
+   // Accessors
+   static PSOldGen* old_gen()              { return _old_gen; }
+   static MutableSpace* young_space()      { return _young_space; }
+ 
+   inline static PSPromotionManager* manager_array(int index);
+-  inline void claim_or_forward_internal_depth(oop* p);
+-  inline void claim_or_forward_internal_breadth(oop* p);
+ 
+   GrowableArray<oop*>* overflow_stack_depth()  { return _overflow_stack_depth; }
+   GrowableArray<oop>* overflow_stack_breadth()   { return _overflow_stack_breadth; }
+ 
++  // On the task queues we push reference locations as well as
++  // partially-scanned arrays (in the latter case, we push an oop to
++  // the from-space image of the array and the length on the
++  // from-space image indicates how many entries on the array we still
++  // need to scan; this is basically how ParNew does partial array
++  // scanning too). To be able to distinguish between reference
++  // locations and partially-scanned array oops we simply mask the
++  // latter oops with 0x01. The next three methods do the masking,
++  // unmasking, and checking whether the oop is masked or not. Notice
++  // that the signature of the mask and unmask methods looks a bit
++  // strange, as they accept and return different types (oop and
++  // oop*). This is because of the difference in types between what
++  // the task queue holds (oop*) and oops to partially-scanned arrays
++  // (oop). We do all the necessary casting in the mask / unmask
++  // methods to avoid sprinkling the rest of the code with more casts.
++
++  bool is_oop_masked(oop* p) {
++    return ((intptr_t) p & PS_CHUNKED_ARRAY_OOP_MASK) == PS_CHUNKED_ARRAY_OOP_MASK;
++  }
++
++  oop* mask_chunked_array_oop(oop obj) {
++    assert(!is_oop_masked((oop*) obj), "invariant");
++    oop* ret = (oop*) ((intptr_t) obj  | PS_CHUNKED_ARRAY_OOP_MASK);
++    assert(is_oop_masked(ret), "invariant");
++    return ret;
++  }
++
++  oop unmask_chunked_array_oop(oop* p) {
++    assert(is_oop_masked(p), "invariant");
++    oop ret = oop((intptr_t) p & ~PS_CHUNKED_ARRAY_OOP_MASK);
++    assert(!is_oop_masked((oop*) ret), "invariant");
++    return ret;
++  }
++
++  void process_array_chunk(oop old);
++
++  void push_depth(oop* p) {
++    assert(depth_first(), "pre-condition");
++
++#if PS_PM_STATS
++    ++_total_pushes;
++#endif // PS_PM_STATS
++
++    if (!claimed_stack_depth()->push(p)) {
++      overflow_stack_depth()->push(p);
++#if PS_PM_STATS
++      ++_overflow_pushes;
++      uint stack_length = (uint) overflow_stack_depth()->length();
++      if (stack_length > _max_overflow_length) {
++        _max_overflow_length = stack_length;
++      }
++#endif // PS_PM_STATS
++    }
++  }
++
++  void push_breadth(oop o) {
++    assert(!depth_first(), "pre-condition");
++
++#if PS_PM_STATS
++    ++_total_pushes;
++#endif // PS_PM_STATS
++
++    if(!claimed_stack_breadth()->push(o)) {
++      overflow_stack_breadth()->push(o);
++#if PS_PM_STATS
++      ++_overflow_pushes;
++      uint stack_length = (uint) overflow_stack_breadth()->length();
++      if (stack_length > _max_overflow_length) {
++        _max_overflow_length = stack_length;
++      }
++#endif // PS_PM_STATS
++    }
++  }
++
+  protected:
+   static OopStarTaskQueueSet* stack_array_depth() { return _stack_array_depth; }
+   static OopTaskQueueSet*     stack_array_breadth() { return _stack_array_breadth; }
+@@ -124,7 +216,6 @@
+   // Promotion methods
+   oop copy_to_survivor_space(oop o, bool depth_first);
+   oop oop_promotion_failed(oop obj, markOop obj_mark);
+-  void handle_stack_overflow();
+ 
+   void reset();
+ 
+@@ -136,6 +227,11 @@
+       drain_stacks_breadth(totally_drain);
+     }
+   }
++  void drain_stacks_cond_depth() {
++    if (claimed_stack_depth()->size() > _target_stack_size) {
++      drain_stacks_depth(false);
++    }
++  }
+   void drain_stacks_depth(bool totally_drain);
+   void drain_stacks_breadth(bool totally_drain);
+ 
+@@ -160,7 +256,22 @@
+     return _depth_first;
+   }
+ 
++  inline void process_popped_location_depth(oop* p);
++
+   inline void flush_prefetch_queue();
++
+   inline void claim_or_forward_depth(oop* p);
++  inline void claim_or_forward_internal_depth(oop* p);
++
+   inline void claim_or_forward_breadth(oop* p);
++  inline void claim_or_forward_internal_breadth(oop* p);
++
++#if PS_PM_STATS
++  void increment_steals(oop* p = NULL) {
++    _total_steals += 1;
++    if (p != NULL && is_oop_masked(p)) {
++      _masked_steals += 1;
++    }
++  }
++#endif // PS_PM_STATS
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psPromotionManager.inline.hpp	1.18 07/05/05 17:05:30 JVM"
+-#endif
+ /*
+  * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -43,9 +40,7 @@
+       }
+       *p = o;
+     } else {
+-      if (!claimed_stack_depth()->push(p)) {
+-	overflow_stack_depth()->push(p);
+-      }
++      push_depth(p);
+     }
+   }
+ }
+@@ -110,3 +105,13 @@
+     claim_or_forward_internal_breadth(p);
+   }
+ }
++
++inline void PSPromotionManager::process_popped_location_depth(oop* p) {
++  if (is_oop_masked(p)) {
++    assert(PSChunkLargeArrays, "invariant");
++    oop const old = unmask_chunked_array_oop(p);
++    process_array_chunk(old);
++  } else {
++    PSScavenge::copy_and_push_safe_barrier(this, p);
++  }
++}
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psScavenge.cpp	1.98 07/06/08 23:12:37 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -778,7 +775,7 @@
+     mr,                         // span
+     true,                       // atomic_discovery
+     true,                       // mt_discovery
+-    &_is_alive_closure,
++    NULL,                       // is_alive_non_header
+     ParallelGCThreads,
+     ParallelRefProcEnabled);
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psScavenge.hpp	1.46 07/05/05 17:05:30 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psScavenge.inline.hpp	1.18 07/05/05 17:05:29 JVM"
+-#endif
+ /*
+  * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psTasks.cpp	1.28 07/05/05 17:05:27 JVM"
+-#endif
+ /*
+  * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -140,7 +137,10 @@
+     while(true) {
+       oop* p;
+       if (PSPromotionManager::steal_depth(which, &random_seed, p)) {
+-	PSScavenge::copy_and_push_safe_barrier(pm, p);
++#if PS_PM_STATS
++        pm->increment_steals(p);
++#endif // PS_PM_STATS
++        pm->process_popped_location_depth(p);
+ 	pm->drain_stacks_depth(true);
+       } else {
+ 	if (terminator()->offer_termination()) {
+@@ -152,6 +152,9 @@
+     while(true) {
+       oop obj;
+       if (PSPromotionManager::steal_breadth(which, &random_seed, obj)) {
++#if PS_PM_STATS
++        pm->increment_steals();
++#endif // PS_PM_STATS
+ 	obj->copy_contents(pm);
+ 	pm->drain_stacks_breadth(true);
+       } else {
+@@ -216,5 +219,3 @@
+     pm->drain_stacks(false);
+   }
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psTasks.hpp	1.21 07/05/05 17:05:29 JVM"
+-#endif
+ /*
+  * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -146,4 +143,3 @@
+ 
+   virtual void do_it(GCTaskManager* manager, uint which);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psVirtualspace.cpp	1.16 07/05/05 17:05:31 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psVirtualspace.hpp	1.15 07/05/05 17:05:31 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psYoungGen.cpp	1.67 07/05/05 17:05:31 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -712,7 +709,7 @@
+   size_t delta_in_survivor = 0;
+   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+   const size_t space_alignment = heap->intra_generation_alignment();
+-  const size_t gen_alignment = heap->generation_alignment();
++  const size_t gen_alignment = heap->young_gen_alignment();
+ 
+   MutableSpace* space_shrinking = NULL;
+   if (from_space()->end() > to_space()->end()) {
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psYoungGen.hpp	1.48 07/05/05 17:05:31 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vmPSOperations.cpp	1.1 07/05/14 11:57:11 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -102,4 +99,3 @@
+   }
+   notify_gc_end();
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vmPSOperations.hpp	1.2 07/05/16 16:53:01 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vmStructs_parallelgc.hpp	1.2 07/05/01 19:01:30 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)asParNewGeneration.cpp	1.11 07/05/05 17:05:25 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.hpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)asParNewGeneration.hpp	1.8 07/05/05 17:05:25 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)parCardTableModRefBS.cpp	1.1 07/05/16 19:06:21 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)parGCAllocBuffer.cpp	1.28 07/05/29 09:44:12 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)parGCAllocBuffer.hpp	1.30 07/05/29 09:44:13 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)parNewGeneration.cpp	1.101 07/05/22 17:23:45 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1193,7 +1190,7 @@
+         _reserved,                  // span
+         refs_discovery_is_atomic(), // atomic_discovery
+         refs_discovery_is_mt(),     // mt_discovery
+-        &_is_alive_closure,
++        NULL,                       // is_alive_non_header
+         ParallelGCThreads,
+         ParallelRefProcEnabled);
+   }
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)parNewGeneration.hpp	1.48 07/05/17 15:52:44 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)parOopClosures.hpp	1.1 07/05/16 10:51:44 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,7 +26,8 @@
+ 
+ class ParScanThreadState;
+ class ParNewGeneration;
+-typedef class OopTaskQueueSet ObjToScanQueueSet;
++template<class E> class GenericTaskQueueSet;
++typedef GenericTaskQueueSet<oop> ObjToScanQueueSet;
+ class ParallelTaskTerminator;
+ 
+ class ParScanClosure: public OopsInGenClosure {
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)parOopClosures.inline.hpp	1.1 07/05/16 10:51:44 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -100,4 +97,3 @@
+     }
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)adaptiveSizePolicy.cpp	1.13 07/05/05 17:05:33 JVM"
+-#endif
+ /*
+  * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)adaptiveSizePolicy.hpp	1.15 07/05/05 17:05:32 JVM"
+-#endif
+ /*
+  * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ageTable.cpp	1.36 07/05/05 17:05:33 JVM"
+-#endif
+ /*
+  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ageTable.hpp	1.29 07/05/05 17:05:32 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)collectorCounters.cpp	1.10 07/05/05 17:05:32 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)collectorCounters.hpp	1.10 07/05/05 17:05:33 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -81,4 +78,3 @@
+       if (UsePerfData) _c->last_exit_counter()->set_value(os::elapsed_counter());
+     }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cSpaceCounters.cpp	1.10 07/05/05 17:05:32 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cSpaceCounters.hpp	1.12 07/05/05 17:05:33 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -78,4 +75,3 @@
+       return _space->used();
+     }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gcAdaptivePolicyCounters.cpp	1.10 07/05/05 17:05:34 JVM"
+-#endif
+ /*
+  * Copyright 2004-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gcAdaptivePolicyCounters.hpp	1.11 07/05/05 17:05:34 JVM"
+-#endif
+ /*
+  * Copyright 2004-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gcPolicyCounters.cpp	1.13 07/05/05 17:05:34 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)gcPolicyCounters.hpp	1.18 07/05/05 17:05:33 JVM"
+-#endif
+ /*
+  * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcStats.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcStats.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcStats.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcStats.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gcStats.cpp	1.9 07/05/05 17:05:33 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)gcStats.hpp	1.10 07/05/05 17:05:34 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcUtil.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcUtil.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcUtil.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcUtil.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gcUtil.cpp	1.21 07/05/05 17:05:32 JVM"
+-#endif
+ /*
+  * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)gcUtil.hpp	1.19 07/05/05 17:05:32 JVM"
+-#endif
+ /*
+  * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -177,4 +174,3 @@
+     _timer->start();
+   }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)generationCounters.cpp	1.10 07/05/05 17:05:34 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)generationCounters.hpp	1.14 07/05/05 17:05:34 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gSpaceCounters.cpp	1.11 07/05/05 17:05:33 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)gSpaceCounters.hpp	1.14 07/05/05 17:05:33 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -103,4 +100,3 @@
+       return _gen->used();
+     }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)immutableSpace.cpp	1.13 07/05/05 17:05:34 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -80,4 +77,3 @@
+   }
+   guarantee(p == end(), "end of last object must match end of space");
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)immutableSpace.hpp	1.14 07/05/05 17:05:33 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)isGCActiveMark.hpp	1.9 07/05/05 17:05:34 JVM"
+-#endif
+ /*
+  * Copyright 2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/liveRange.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/liveRange.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/liveRange.hpp	2008-08-28 10:23:10.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/liveRange.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)liveRange.hpp	1.11 07/05/05 17:05:34 JVM"
+-#endif
+ /*
+  * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)markSweep.cpp	1.196 07/05/05 17:05:35 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -358,4 +355,3 @@
+ }
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)markSweep.hpp	1.67 07/05/17 15:52:55 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)markSweep.inline.hpp	1.17 07/05/29 09:44:12 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)mutableNUMASpace.cpp	1.8 07/05/05 17:05:35 JVM"
+-#endif
+ 
+ /*
+  * Copyright 2006-2007 Sun Microsystems, Inc.  All Rights Reserved.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)mutableNUMASpace.hpp	1.8 07/05/05 17:05:34 JVM"
+-#endif
+ /*
+  * Copyright 2006-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)mutableSpace.cpp	1.22 07/05/05 17:05:35 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)mutableSpace.hpp	1.22 07/05/05 17:05:35 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)spaceCounters.cpp	1.10 07/05/05 17:05:35 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)spaceCounters.hpp	1.11 07/05/05 17:05:35 JVM"
+-#endif
+ /*
+  * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vmGCOperations.cpp	1.21 07/05/29 09:44:12 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp
+--- openjdk6/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vmGCOperations.hpp	1.14 07/05/29 09:44:12 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.cpp openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
+--- openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)collectedHeap.cpp	1.23 07/05/05 17:05:40 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -132,6 +129,23 @@
+   return obj;
+ }
+ 
++oop CollectedHeap::new_store_barrier(oop new_obj) {
++  // %%% This needs refactoring.  (It was imported from the server compiler.)
++  guarantee(can_elide_tlab_store_barriers(), "store barrier elision not supported");
++  BarrierSet* bs = this->barrier_set();
++  assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
++  int new_size = new_obj->size();
++  bs->write_region(MemRegion((HeapWord*)new_obj, new_size));
++  return new_obj;
++}
++
++bool CollectedHeap::can_elide_permanent_oop_store_barriers() const {
++  // %%% This needs refactoring.  (It was gating logic from the server compiler.)
++  guarantee(kind() < CollectedHeap::G1CollectedHeap, "");
++  return !UseConcMarkSweepGC;
++}
++
++
+ HeapWord* CollectedHeap::allocate_new_tlab(size_t size) {
+   guarantee(false, "thread-local allocation buffers not supported");
+   return NULL;
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.hpp openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
+--- openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)collectedHeap.hpp	1.55 07/05/17 15:52:57 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -245,6 +242,11 @@
+     return p == NULL || is_in_permanent(p);
+   }
+ 
++  // Returns "TRUE" if "p" is a method oop in the
++  // current heap, with high probability. This predicate
++  // is not stable, in general.
++  bool is_valid_method(oop p) const;
++
+   void set_gc_cause(GCCause::Cause v) {
+      if (UsePerfData) {
+        _gc_lastcause = _gc_cause;
+@@ -363,6 +365,25 @@
+     guarantee(false, "thread-local allocation buffers not supported");
+     return 0;
+   }
++  // Can a compiler initialize a new object without store barriers?
++  // This permission only extends from the creation of a new object
++  // via a TLAB up to the first subsequent safepoint.
++  virtual bool can_elide_tlab_store_barriers() const {
++    guarantee(kind() < CollectedHeap::G1CollectedHeap, "else change or refactor this");
++    return true;
++  }
++  // If a compiler is eliding store barriers for TLAB-allocated objects,
++  // there is probably a corresponding slow path which can produce
++  // an object allocated anywhere.  The compiler's runtime support
++  // promises to call this function on such a slow-path-allocated
++  // object before performing initializations that have elided
++  // store barriers.  Returns new_obj, or maybe a safer copy thereof.
++  virtual oop new_store_barrier(oop new_obj);
++
++  // Can a compiler elide a store barrier when it writes
++  // a permanent oop into the heap?  Applies when the compiler
++  // is storing x to the heap, where x->is_perm() is true.
++  virtual bool can_elide_permanent_oop_store_barriers() const;
+   
+   // Does this heap support heap inspection (+PrintClassHistogram?)
+   virtual bool supports_heap_inspection() const {
+@@ -386,7 +407,7 @@
+   // Returns "true" iff there is a stop-world GC in progress.  (I assume
+   // that it should answer "false" for the concurrent part of a concurrent
+   // collector -- dld).
+-  bool is_gc_active() { return _is_gc_active; }
++  bool is_gc_active() const { return _is_gc_active; }
+ 
+   // Total number of GC collections (started)
+   unsigned int total_collections() const { return _total_collections; }
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
+--- openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)collectedHeap.inline.hpp	1.46 07/05/17 15:52:59 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -292,7 +289,45 @@
+   return (oop)obj;  
+ }
+ 
++// Returns "TRUE" if "p" is a method oop in the
++// current heap with high probability. NOTE: The main
++// current consumers of this interface are Forte::
++// and ThreadProfiler::. In these cases, the
++// interpreter frame from which "p" came, may be
++// under construction when sampled asynchronously, so
++// the clients want to check that it represents a
++// valid method before using it. Nonetheless since
++// the clients do not typically lock out GC, the
++// predicate is_valid_method() is not stable, so
++// it is possible that by the time "p" is used, it
++// is no longer valid.
++inline bool CollectedHeap::is_valid_method(oop p) const {
++  return
++    p != NULL &&
++
++    // Check whether it is aligned at a HeapWord boundary.
++    Space::is_aligned(p) &&
++
++    // Check whether "method" is in the allocated part of the
++    // permanent generation -- this needs to be checked before
++    // p->klass() below to avoid a SEGV (but see below
++    // for a potential window of vulnerability).
++    is_permanent((void*)p) &&
++
++    // See if GC is active; however, there is still an
++    // apparently unavoidable window after this call
++    // and before the client of this interface uses "p".
++    // If the client chooses not to lock out GC, then
++    // it's a risk the client must accept.
++    !is_gc_active() &&
++
++    // Check that p is a methodOop.
++    p->klass() == Universe::methodKlassObj();
++}
++
++
+ #ifndef	PRODUCT
++
+ inline bool
+ CollectedHeap::promotion_should_fail(volatile size_t* count) {
+   // Access to count is not atomic; the value does not have to be exact.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_interface/gcCause.cpp openjdk/hotspot/src/share/vm/gc_interface/gcCause.cpp
+--- openjdk6/hotspot/src/share/vm/gc_interface/gcCause.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_interface/gcCause.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gcCause.cpp	1.20 07/05/05 17:05:40 JVM"
+-#endif
+ /*
+  * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/gc_interface/gcCause.hpp openjdk/hotspot/src/share/vm/gc_interface/gcCause.hpp
+--- openjdk6/hotspot/src/share/vm/gc_interface/gcCause.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/gc_interface/gcCause.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)gcCause.hpp	1.24 07/05/05 17:05:40 JVM"
+-#endif
+ /*
+  * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_compiler1 openjdk/hotspot/src/share/vm/includeDB_compiler1
+--- openjdk6/hotspot/src/share/vm/includeDB_compiler1	2008-08-28 10:23:06.000000000 +0200
++++ openjdk/hotspot/src/share/vm/includeDB_compiler1	2007-12-14 08:57:02.000000000 +0100
+@@ -281,7 +281,7 @@
+ c1_LinearScan_<arch>.hpp                generate_platform_dependent_include
+ 
+ c1_MacroAssembler.hpp                   assembler.hpp
+-c1_MacroAssembler.hpp                   assembler_<arch>.inline.hpp
++c1_MacroAssembler.hpp                   assembler_<arch_model>.inline.hpp
+ 
+ c1_MacroAssembler_<arch>.cpp            arrayOop.hpp
+ c1_MacroAssembler_<arch>.cpp            biasedLocking.hpp
+@@ -326,7 +326,7 @@
+ c1_Runtime1.cpp                         disassembler_<arch>.hpp
+ c1_Runtime1.cpp                         events.hpp
+ c1_Runtime1.cpp                         interfaceSupport.hpp
+-c1_Runtime1.cpp                         interpreter_<arch>.hpp
++c1_Runtime1.cpp                         interpreter.hpp
+ c1_Runtime1.cpp                         javaCalls.hpp
+ c1_Runtime1.cpp                         objArrayKlass.hpp
+ c1_Runtime1.cpp                         oop.inline.hpp
+@@ -352,7 +352,7 @@
+ c1_Runtime1_<arch>.cpp                  c1_MacroAssembler.hpp
+ c1_Runtime1_<arch>.cpp                  c1_Runtime1.hpp
+ c1_Runtime1_<arch>.cpp                  compiledICHolderOop.hpp
+-c1_Runtime1_<arch>.cpp                  interpreter_<arch>.hpp
++c1_Runtime1_<arch>.cpp                  interpreter.hpp
+ c1_Runtime1_<arch>.cpp                  jvmtiExport.hpp
+ c1_Runtime1_<arch>.cpp                  nativeInst_<arch>.hpp
+ c1_Runtime1_<arch>.cpp                  oop.inline.hpp
+@@ -395,8 +395,6 @@
+ 
+ compileBroker.cpp                       c1_Compiler.hpp
+ 
+-fprofiler.cpp                           c1_Compiler.hpp
+-
+ frame.hpp                               c1_Defs.hpp
+ 
+ frame_<arch>.cpp                        c1_Runtime1.hpp
+@@ -408,7 +406,7 @@
+ 
+ instanceKlass.cpp                       c1_Compiler.hpp
+ 
+-interpreter_<arch>.cpp                  c1_Runtime1.hpp
++interpreter_<arch_model>.cpp            c1_Runtime1.hpp
+ 
+ java.cpp                                c1_Compiler.hpp
+ java.cpp                                c1_Runtime1.hpp
+@@ -419,7 +417,7 @@
+ 
+ os_<os_family>.cpp                      c1_Runtime1.hpp
+ 
+-os_<os_family>_<arch>.cpp               c1_Runtime1.hpp
++os_<os_arch>.cpp                        c1_Runtime1.hpp
+ 
+ registerMap.hpp                         c1_Defs.hpp
+ 
+@@ -427,12 +425,11 @@
+ 
+ sharedRuntime.cpp                       c1_Runtime1.hpp
+ 
+-sharedRuntime_<arch>.cpp                c1_Runtime1.hpp
++sharedRuntime_<arch_model>.cpp          c1_Runtime1.hpp
+ 
+ thread.cpp                              c1_Compiler.hpp
+ 
+ top.hpp                                 c1_globals.hpp
+ 
+-vmStructs.cpp                           c1_Defs.hpp
+-vmStructs.cpp                           c1_Runtime1.hpp
++vmStructs.hpp                           c1_Runtime1.hpp
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_compiler2 openjdk/hotspot/src/share/vm/includeDB_compiler2
+--- openjdk6/hotspot/src/share/vm/includeDB_compiler2	2008-08-28 10:23:06.000000000 +0200
++++ openjdk/hotspot/src/share/vm/includeDB_compiler2	2007-12-14 08:57:02.000000000 +0100
+@@ -22,55 +22,55 @@
+ //  
+ //
+ 
+-ad_<arch>.cpp                           adGlobals_<arch>.hpp
+-ad_<arch>.cpp                           ad_<arch>.hpp
+-ad_<arch>.cpp                           allocation.inline.hpp
+-ad_<arch>.cpp                           assembler.hpp
+-ad_<arch>.cpp                           assembler_<arch>.inline.hpp
+-ad_<arch>.cpp                           biasedLocking.hpp
+-ad_<arch>.cpp                           cfgnode.hpp
+-ad_<arch>.cpp                           collectedHeap.inline.hpp
+-ad_<arch>.cpp                           compiledICHolderOop.hpp
+-ad_<arch>.cpp                           growableArray.hpp
+-ad_<arch>.cpp                           locknode.hpp
+-ad_<arch>.cpp                           markOop.hpp
+-ad_<arch>.cpp                           methodOop.hpp
+-ad_<arch>.cpp                           nativeInst_<arch>.hpp
+-ad_<arch>.cpp                           oop.inline.hpp
+-ad_<arch>.cpp                           oop.inline2.hpp
+-ad_<arch>.cpp                           opcodes.hpp
+-ad_<arch>.cpp                           regalloc.hpp
+-ad_<arch>.cpp                           regmask.hpp
+-ad_<arch>.cpp                           runtime.hpp
+-ad_<arch>.cpp                           sharedRuntime.hpp
+-ad_<arch>.cpp                           stubRoutines.hpp
+-ad_<arch>.cpp                           vmreg.hpp
+-ad_<arch>.cpp                           vmreg_<arch>.inline.hpp
+-
+-ad_<arch>.hpp                           addnode.hpp
+-ad_<arch>.hpp                           machnode.hpp
+-ad_<arch>.hpp                           matcher.hpp
+-ad_<arch>.hpp                           opcodes.hpp
+-ad_<arch>.hpp                           regalloc.hpp
+-ad_<arch>.hpp                           resourceArea.hpp
+-ad_<arch>.hpp                           subnode.hpp
+-ad_<arch>.hpp                           vectornode.hpp
+-
+-ad_<arch>_clone.cpp                     ad_<arch>.hpp
+-
+-ad_<arch>_expand.cpp                    ad_<arch>.hpp
+-
+-ad_<arch>_format.cpp                    ad_<arch>.hpp
+-
+-ad_<arch>_gen.cpp                       ad_<arch>.hpp
+-ad_<arch>_gen.cpp                       cfgnode.hpp
+-ad_<arch>_gen.cpp                       locknode.hpp
++ad_<arch_model>.cpp                     adGlobals_<arch_model>.hpp
++ad_<arch_model>.cpp                     ad_<arch_model>.hpp
++ad_<arch_model>.cpp                     allocation.inline.hpp
++ad_<arch_model>.cpp                     assembler.hpp
++ad_<arch_model>.cpp                     assembler_<arch_model>.inline.hpp
++ad_<arch_model>.cpp                     biasedLocking.hpp
++ad_<arch_model>.cpp                     cfgnode.hpp
++ad_<arch_model>.cpp                     collectedHeap.inline.hpp
++ad_<arch_model>.cpp                     compiledICHolderOop.hpp
++ad_<arch_model>.cpp                     growableArray.hpp
++ad_<arch_model>.cpp                     locknode.hpp
++ad_<arch_model>.cpp                     markOop.hpp
++ad_<arch_model>.cpp                     methodOop.hpp
++ad_<arch_model>.cpp                     nativeInst_<arch>.hpp
++ad_<arch_model>.cpp                     oop.inline.hpp
++ad_<arch_model>.cpp                     oop.inline2.hpp
++ad_<arch_model>.cpp                     opcodes.hpp
++ad_<arch_model>.cpp                     regalloc.hpp
++ad_<arch_model>.cpp                     regmask.hpp
++ad_<arch_model>.cpp                     runtime.hpp
++ad_<arch_model>.cpp                     sharedRuntime.hpp
++ad_<arch_model>.cpp                     stubRoutines.hpp
++ad_<arch_model>.cpp                     vmreg.hpp
++ad_<arch_model>.cpp                     vmreg_<arch>.inline.hpp
++
++ad_<arch_model>.hpp                     addnode.hpp
++ad_<arch_model>.hpp                     machnode.hpp
++ad_<arch_model>.hpp                     matcher.hpp
++ad_<arch_model>.hpp                     opcodes.hpp
++ad_<arch_model>.hpp                     regalloc.hpp
++ad_<arch_model>.hpp                     resourceArea.hpp
++ad_<arch_model>.hpp                     subnode.hpp
++ad_<arch_model>.hpp                     vectornode.hpp
++
++ad_<arch_model>_clone.cpp               ad_<arch_model>.hpp
++
++ad_<arch_model>_expand.cpp              ad_<arch_model>.hpp
++
++ad_<arch_model>_format.cpp              ad_<arch_model>.hpp
++
++ad_<arch_model>_gen.cpp                 ad_<arch_model>.hpp
++ad_<arch_model>_gen.cpp                 cfgnode.hpp
++ad_<arch_model>_gen.cpp                 locknode.hpp
+ 
+-ad_<arch>_misc.cpp                      ad_<arch>.hpp
++ad_<arch_model>_misc.cpp                ad_<arch_model>.hpp
+ 
+-ad_<arch>_peephole.cpp                  ad_<arch>.hpp
++ad_<arch_model>_peephole.cpp            ad_<arch_model>.hpp
+ 
+-ad_<arch>_pipeline.cpp                  ad_<arch>.hpp
++ad_<arch_model>_pipeline.cpp            ad_<arch_model>.hpp
+ 
+ addnode.cpp                             addnode.hpp
+ addnode.cpp                             allocation.inline.hpp
+@@ -125,6 +125,8 @@
+ bytecodeInfo.cpp                        systemDictionary.hpp
+ bytecodeInfo.cpp                        vmSymbols.hpp
+ 
++bytecodeInterpreter.hpp                 methodDataOop.hpp
++
+ c2_globals.cpp                          c2_globals.hpp
+ 
+ c2_globals.hpp                          c2_globals_<arch>.hpp
+@@ -139,14 +141,12 @@
+ 
+ c2_init_<arch>.cpp                      compile.hpp
+ 
+-c2compiler.cpp                          ad_<arch>.hpp
++c2compiler.cpp                          ad_<arch_model>.hpp
+ c2compiler.cpp                          c2compiler.hpp
+ c2compiler.cpp                          runtime.hpp
+ 
+ c2compiler.hpp                          abstractCompiler.hpp
+ 
+-cInterpreter.hpp                        methodDataOop.hpp
+-
+ callGenerator.cpp                       addnode.hpp
+ callGenerator.cpp                       callGenerator.hpp
+ callGenerator.cpp                       callnode.hpp
+@@ -287,7 +287,7 @@
+ 
+ coalesce.hpp                            phase.hpp
+ 
+-compile.cpp                             ad_<arch>.hpp
++compile.cpp                             ad_<arch_model>.hpp
+ compile.cpp                             addnode.hpp
+ compile.cpp                             arguments.hpp
+ compile.cpp                             assembler.hpp
+@@ -333,6 +333,7 @@
+ compile.hpp                             deoptimization.hpp
+ compile.hpp                             dict.hpp
+ compile.hpp                             exceptionHandlerTable.hpp
++compile.hpp                             idealGraphPrinter.hpp
+ compile.hpp                             phase.hpp
+ compile.hpp                             port.hpp
+ compile.hpp                             regmask.hpp
+@@ -358,11 +359,11 @@
+ connode.hpp                             opcodes.hpp
+ connode.hpp                             type.hpp
+ 
+-deoptimization.cpp                      ad_<arch>.hpp
++deoptimization.cpp                      ad_<arch_model>.hpp
+ 
+-dfa_<arch>.cpp                          ad_<arch>.hpp
+-dfa_<arch>.cpp                          matcher.hpp
+-dfa_<arch>.cpp                          opcodes.hpp
++dfa_<arch_model>.cpp                    ad_<arch_model>.hpp
++dfa_<arch_model>.cpp                    matcher.hpp
++dfa_<arch_model>.cpp                    opcodes.hpp
+ 
+ dict.cpp                                allocation.inline.hpp
+ dict.cpp                                dict.hpp
+@@ -389,7 +390,6 @@
+ doCall.cpp                              addnode.hpp
+ doCall.cpp                              callGenerator.hpp
+ doCall.cpp                              cfgnode.hpp
+-doCall.cpp                              cha.hpp
+ doCall.cpp                              compileLog.hpp
+ doCall.cpp                              linkResolver.hpp
+ doCall.cpp                              mulnode.hpp
+@@ -422,9 +422,9 @@
+ escape.hpp                              growableArray.hpp
+ escape.hpp                              node.hpp
+ 
+-frame.hpp                               adGlobals_<arch>.hpp
++frame.hpp                               adGlobals_<arch_model>.hpp
+ 
+-gcm.cpp                                 ad_<arch>.hpp
++gcm.cpp                                 ad_<arch_model>.hpp
+ gcm.cpp                                 allocation.inline.hpp
+ gcm.cpp                                 block.hpp
+ gcm.cpp                                 c2compiler.hpp
+@@ -481,9 +481,11 @@
+ graphKit.hpp                            type.hpp
+ 
+ idealKit.cpp                            addnode.hpp
++idealKit.cpp                            callnode.hpp
+ idealKit.cpp                            cfgnode.hpp
+ idealKit.cpp                            idealKit.hpp
+ 
++idealKit.hpp                            connode.hpp
+ idealKit.hpp                            mulnode.hpp
+ idealKit.hpp                            phaseX.hpp
+ idealKit.hpp                            subnode.hpp
+@@ -530,7 +532,7 @@
+ java.cpp                                methodLiveness.hpp
+ java.cpp                                runtime.hpp
+ 
+-lcm.cpp                                 ad_<arch>.hpp
++lcm.cpp                                 ad_<arch_model>.hpp
+ lcm.cpp                                 allocation.inline.hpp
+ lcm.cpp                                 block.hpp
+ lcm.cpp                                 c2compiler.hpp
+@@ -572,7 +574,7 @@
+ locknode.cpp                            rootnode.hpp
+ locknode.cpp                            runtime.hpp
+ 
+-locknode.hpp                            ad_<arch>.hpp
++locknode.hpp                            ad_<arch_model>.hpp
+ locknode.hpp                            node.hpp
+ locknode.hpp                            opcodes.hpp
+ locknode.hpp                            subnode.hpp
+@@ -647,7 +649,7 @@
+ macro.cpp                               vectset.hpp
+ macro.hpp                               phase.hpp
+ 
+-matcher.cpp                             ad_<arch>.hpp
++matcher.cpp                             ad_<arch_model>.hpp
+ matcher.cpp                             addnode.hpp
+ matcher.cpp                             allocation.inline.hpp
+ matcher.cpp                             atomic.hpp
+@@ -762,7 +764,7 @@
+ output.cpp                              type.hpp
+ output.cpp                              xmlstream.hpp
+ 
+-output.hpp                              ad_<arch>.hpp
++output.hpp                              ad_<arch_model>.hpp
+ output.hpp                              block.hpp
+ output.hpp                              node.hpp
+ 
+@@ -881,11 +883,11 @@
+ regalloc.hpp                            phase.hpp
+ regalloc.hpp                            vmreg.hpp
+ 
+-regmask.cpp                             ad_<arch>.hpp
++regmask.cpp                             ad_<arch_model>.hpp
+ regmask.cpp                             compile.hpp
+ regmask.cpp                             regmask.hpp
+ 
+-regmask.hpp                             adGlobals_<arch>.hpp
++regmask.hpp                             adGlobals_<arch_model>.hpp
+ regmask.hpp                             optoreg.hpp
+ regmask.hpp                             port.hpp
+ regmask.hpp                             vmreg.hpp
+@@ -901,7 +903,7 @@
+ 
+ rootnode.hpp                            loopnode.hpp
+ 
+-runtime.cpp                             ad_<arch>.hpp
++runtime.cpp                             ad_<arch_model>.hpp
+ runtime.cpp                             addnode.hpp
+ runtime.cpp                             barrierSet.hpp
+ runtime.cpp                             bytecode.hpp
+@@ -953,21 +955,21 @@
+ runtime.hpp                             type.hpp
+ runtime.hpp                             vframe.hpp
+ 
+-runtime_<arch>.cpp                      adGlobals_<arch>.hpp
+-runtime_<arch>.cpp                      ad_<arch>.hpp
+-runtime_<arch>.cpp                      assembler.hpp
+-runtime_<arch>.cpp                      assembler_<arch>.inline.hpp
+-runtime_<arch>.cpp                      globalDefinitions.hpp
+-runtime_<arch>.cpp                      interfaceSupport.hpp
+-runtime_<arch>.cpp                      interpreter_<arch>.hpp
+-runtime_<arch>.cpp                      nativeInst_<arch>.hpp
+-runtime_<arch>.cpp                      runtime.hpp
+-runtime_<arch>.cpp                      sharedRuntime.hpp
+-runtime_<arch>.cpp                      stubRoutines.hpp
+-runtime_<arch>.cpp                      systemDictionary.hpp
+-runtime_<arch>.cpp                      vframeArray.hpp
+-runtime_<arch>.cpp                      vmreg.hpp
+-runtime_<arch>.cpp                      vmreg_<arch>.inline.hpp
++runtime_<arch_model>.cpp                adGlobals_<arch_model>.hpp
++runtime_<arch_model>.cpp                ad_<arch_model>.hpp
++runtime_<arch_model>.cpp                assembler.hpp
++runtime_<arch_model>.cpp                assembler_<arch_model>.inline.hpp
++runtime_<arch_model>.cpp                globalDefinitions.hpp
++runtime_<arch_model>.cpp                interfaceSupport.hpp
++runtime_<arch_model>.cpp                interpreter.hpp
++runtime_<arch_model>.cpp                nativeInst_<arch>.hpp
++runtime_<arch_model>.cpp                runtime.hpp
++runtime_<arch_model>.cpp                sharedRuntime.hpp
++runtime_<arch_model>.cpp                stubRoutines.hpp
++runtime_<arch_model>.cpp                systemDictionary.hpp
++runtime_<arch_model>.cpp                vframeArray.hpp
++runtime_<arch_model>.cpp                vmreg.hpp
++runtime_<arch_model>.cpp                vmreg_<arch>.inline.hpp
+ 
+ set.cpp                                 allocation.inline.hpp
+ set.cpp                                 set.hpp
+@@ -975,16 +977,14 @@
+ set.hpp                                 allocation.hpp
+ set.hpp                                 port.hpp
+ 
+-sharedRuntime_<arch>.cpp                runtime.hpp
++sharedRuntime_<arch_model>.cpp          runtime.hpp
+ 
+ split_if.cpp                            allocation.inline.hpp
+ split_if.cpp                            callnode.hpp
+ split_if.cpp                            connode.hpp
+ split_if.cpp                            loopnode.hpp
+ 
+-stackValue.cpp                          debugInfo.hpp
+-
+-stubGenerator_<arch>.cpp                runtime.hpp
++stubGenerator_<arch_model>.cpp          runtime.hpp
+ 
+ stubRoutines.cpp                        runtime.hpp
+ 
+@@ -1025,8 +1025,6 @@
+ superword.hpp                           phaseX.hpp
+ superword.hpp                           vectornode.hpp
+ 
+-systemDictionary.cpp                    cha.hpp
+-
+ thread.cpp                              c2compiler.hpp
+ 
+ top.hpp                                 c2_globals.hpp
+@@ -1070,15 +1068,34 @@
+ 
+ vframe_hp.cpp                           matcher.hpp
+ 
+-vmStructs.cpp                           adGlobals_<arch>.hpp
++vmStructs.cpp                           adGlobals_<arch_model>.hpp
+ vmStructs.cpp                           matcher.hpp
+ 
+-vmreg.hpp                               adGlobals_<arch>.hpp
++vmreg.hpp                               adGlobals_<arch_model>.hpp
+ vmreg.hpp                               adlcVMDeps.hpp
+ vmreg.hpp                               ostream.hpp
+ 
+ vtableStubs.cpp                         matcher.hpp
+ 
+-vtableStubs_<arch>.cpp                  ad_<arch>.hpp
+-vtableStubs_<arch>.cpp                  runtime.hpp
++vtableStubs_<arch_model>.cpp            ad_<arch_model>.hpp
++vtableStubs_<arch_model>.cpp            runtime.hpp
+ 
++idealGraphPrinter.hpp                   dict.hpp
++idealGraphPrinter.hpp                   vectset.hpp
++idealGraphPrinter.hpp                   growableArray.hpp
++idealGraphPrinter.hpp                   ostream.hpp
++
++idealGraphPrinter.cpp                   idealGraphPrinter.hpp
++idealGraphPrinter.cpp			chaitin.hpp
++idealGraphPrinter.cpp                   machnode.hpp
++idealGraphPrinter.cpp                   parse.hpp
++idealGraphPrinter.cpp                   threadCritical.hpp
++
++compile.cpp                             idealGraphPrinter.hpp
++thread.cpp                              idealGraphPrinter.hpp
++phaseX.cpp                              idealGraphPrinter.hpp
++parse2.cpp                              idealGraphPrinter.hpp
++parse1.cpp                              idealGraphPrinter.hpp
++matcher.cpp                             idealGraphPrinter.hpp
++loopnode.cpp                            idealGraphPrinter.hpp
++chaitin.cpp				idealGraphPrinter.hpp
+diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_core openjdk/hotspot/src/share/vm/includeDB_core
+--- openjdk6/hotspot/src/share/vm/includeDB_core	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/includeDB_core	2007-12-14 08:57:02.000000000 +0100
+@@ -47,7 +47,7 @@
+ // bodies for inline functions declared in H.hpp.
+ //
+ // NOTE: Files that use the token "generate_platform_dependent_include" 
+-// are expected to contain macro references like <os>, <arch>, ... and
++// are expected to contain macro references like <os>, <arch_model>, ... and
+ // makedeps has a dependency on these platform files looking like:
+ // foo_<macro>.trailing_string 
+ // (where "trailing_string" can be any legal filename strings but typically
+@@ -120,6 +120,13 @@
+ 
+ abstractCompiler.hpp                    compilerInterface.hpp
+ 
++abstractInterpreter.hpp                 bytecodes.hpp
++abstractInterpreter.hpp                 interp_masm_<arch_model>.hpp
++abstractInterpreter.hpp                 stubs.hpp
++abstractInterpreter.hpp                 thread_<os_family>.inline.hpp
++abstractInterpreter.hpp                 top.hpp
++abstractInterpreter.hpp                 vmThread.hpp
++
+ accessFlags.cpp                         accessFlags.hpp
+ accessFlags.cpp                         oop.inline.hpp
+ accessFlags.cpp                         os_<os_family>.inline.hpp
+@@ -175,7 +182,7 @@
+ arguments.cpp                           oop.inline.hpp
+ arguments.cpp                           os_<os_family>.inline.hpp
+ arguments.cpp                           universe.inline.hpp
+-arguments.cpp                           vm_version_<arch>.hpp
++arguments.cpp                           vm_version_<arch_model>.hpp
+ 
+ arguments.hpp                           perfData.hpp
+ arguments.hpp                           top.hpp
+@@ -226,7 +233,7 @@
+ 
+ assembler.cpp                           assembler.hpp
+ assembler.cpp                           assembler.inline.hpp
+-assembler.cpp                           assembler_<arch>.inline.hpp
++assembler.cpp                           assembler_<arch_model>.inline.hpp
+ assembler.cpp                           codeBuffer.hpp
+ assembler.cpp                           icache.hpp
+ assembler.cpp                           os.hpp
+@@ -239,36 +246,36 @@
+ assembler.hpp                           register_<arch>.hpp
+ assembler.hpp                           relocInfo.hpp
+ assembler.hpp                           top.hpp
+-assembler.hpp                           vm_version_<arch>.hpp
++assembler.hpp                           vm_version_<arch_model>.hpp
+ 
+ assembler.inline.hpp                    assembler.hpp
+ assembler.inline.hpp                    codeBuffer.hpp
+ assembler.inline.hpp                    disassembler_<arch>.hpp
+ assembler.inline.hpp                    threadLocalStorage.hpp
+ 
+-assembler_<arch>.cpp                    assembler_<arch>.inline.hpp
+-assembler_<arch>.cpp                    biasedLocking.hpp
+-assembler_<arch>.cpp                    cardTableModRefBS.hpp
+-assembler_<arch>.cpp                    collectedHeap.hpp
+-assembler_<arch>.cpp                    interfaceSupport.hpp
+-assembler_<arch>.cpp                    interpreter_<arch>.hpp
+-assembler_<arch>.cpp                    objectMonitor.hpp
+-assembler_<arch>.cpp                    os.hpp
+-assembler_<arch>.cpp                    resourceArea.hpp
+-assembler_<arch>.cpp                    sharedRuntime.hpp
+-assembler_<arch>.cpp                    stubRoutines.hpp
+-
+-assembler_<arch>.hpp                    generate_platform_dependent_include
+-
+-assembler_<arch>.inline.hpp             assembler.inline.hpp
+-assembler_<arch>.inline.hpp             codeBuffer.hpp
+-assembler_<arch>.inline.hpp             codeCache.hpp
+-assembler_<arch>.inline.hpp             handles.inline.hpp
+-
+-assembler_<os_arch>.cpp                 assembler.hpp
+-assembler_<os_arch>.cpp                 assembler_<arch>.inline.hpp
+-assembler_<os_arch>.cpp                 os.hpp
+-assembler_<os_arch>.cpp                 threadLocalStorage.hpp
++assembler_<arch_model>.cpp              assembler_<arch_model>.inline.hpp
++assembler_<arch_model>.cpp              biasedLocking.hpp
++assembler_<arch_model>.cpp              cardTableModRefBS.hpp
++assembler_<arch_model>.cpp              collectedHeap.hpp
++assembler_<arch_model>.cpp              interfaceSupport.hpp
++assembler_<arch_model>.cpp              interpreter.hpp
++assembler_<arch_model>.cpp              objectMonitor.hpp
++assembler_<arch_model>.cpp              os.hpp
++assembler_<arch_model>.cpp              resourceArea.hpp
++assembler_<arch_model>.cpp              sharedRuntime.hpp
++assembler_<arch_model>.cpp              stubRoutines.hpp
++
++assembler_<arch_model>.hpp              generate_platform_dependent_include
++
++assembler_<arch_model>.inline.hpp       assembler.inline.hpp
++assembler_<arch_model>.inline.hpp       codeBuffer.hpp
++assembler_<arch_model>.inline.hpp       codeCache.hpp
++assembler_<arch_model>.inline.hpp       handles.inline.hpp
++
++assembler_<os_arch_model>.cpp           assembler.hpp
++assembler_<os_arch_model>.cpp           assembler_<arch_model>.inline.hpp
++assembler_<os_arch_model>.cpp           os.hpp
++assembler_<os_arch_model>.cpp           threadLocalStorage.hpp
+ 
+ atomic.cpp                              atomic.hpp
+ atomic.cpp                              atomic_<os_arch>.inline.hpp
+@@ -278,30 +285,14 @@
+ 
+ atomic_<os_arch>.inline.hpp             atomic.hpp
+ atomic_<os_arch>.inline.hpp             os.hpp
+-atomic_<os_arch>.inline.hpp             vm_version_<arch>.hpp
++atomic_<os_arch>.inline.hpp             vm_version_<arch_model>.hpp
+ 
+-attachListener.cpp                      arguments.hpp
+-attachListener.cpp                      attachListener.hpp
+-attachListener.cpp                      globals.hpp
+-attachListener.cpp                      heapDumper.hpp
+-attachListener.cpp                      java.hpp
+-attachListener.cpp                      javaCalls.hpp
+-attachListener.cpp                      javaClasses.hpp
+-attachListener.cpp                      jvmtiExport.hpp
+-attachListener.cpp                      os.hpp
+-attachListener.cpp                      resourceArea.hpp
+-attachListener.cpp                      systemDictionary.hpp
+-attachListener.cpp                      vmGCOperations.hpp
++// attachListener is jck optional, put cpp deps in includeDB_features
+ 
+ attachListener.hpp                      allocation.hpp
+ attachListener.hpp                      debug.hpp
+ attachListener.hpp                      ostream.hpp
+ 
+-attachListener_<os_family>.cpp          attachListener.hpp
+-attachListener_<os_family>.cpp          dtraceAttacher.hpp
+-attachListener_<os_family>.cpp          interfaceSupport.hpp
+-attachListener_<os_family>.cpp          os.hpp
+-
+ barrierSet.hpp                          memRegion.hpp
+ barrierSet.hpp                          oopsHierarchy.hpp
+ 
+@@ -384,6 +375,64 @@
+ bytecodeHistogram.hpp                   allocation.hpp
+ bytecodeHistogram.hpp                   bytecodes.hpp
+ 
++bytecodeInterpreter.cpp                 no_precompiled_headers
++bytecodeInterpreter.cpp                 bytecodeHistogram.hpp
++bytecodeInterpreter.cpp                 bytecodeInterpreter.hpp
++bytecodeInterpreter.cpp                 bytecodeInterpreter.inline.hpp
++bytecodeInterpreter.cpp                 cardTableModRefBS.hpp
++bytecodeInterpreter.cpp                 collectedHeap.hpp
++bytecodeInterpreter.cpp                 exceptions.hpp
++bytecodeInterpreter.cpp                 frame.inline.hpp
++bytecodeInterpreter.cpp                 handles.inline.hpp
++bytecodeInterpreter.cpp                 interfaceSupport.hpp
++bytecodeInterpreter.cpp                 interpreterRuntime.hpp
++bytecodeInterpreter.cpp                 interpreter.hpp
++bytecodeInterpreter.cpp                 jvmtiExport.hpp
++bytecodeInterpreter.cpp                 objArrayKlass.hpp
++bytecodeInterpreter.cpp                 oop.inline.hpp
++bytecodeInterpreter.cpp                 orderAccess_<os_arch>.inline.hpp
++bytecodeInterpreter.cpp                 resourceArea.hpp
++bytecodeInterpreter.cpp                 sharedRuntime.hpp
++bytecodeInterpreter.cpp                 threadCritical.hpp
++bytecodeInterpreter.cpp                 vmSymbols.hpp
++
++bytecodeInterpreter_<arch>.cpp          assembler.hpp
++bytecodeInterpreter_<arch>.cpp          bytecodeInterpreter.hpp
++bytecodeInterpreter_<arch>.cpp          bytecodeInterpreter.inline.hpp
++bytecodeInterpreter_<arch>.cpp          debug.hpp
++bytecodeInterpreter_<arch>.cpp          deoptimization.hpp
++bytecodeInterpreter_<arch>.cpp          frame.inline.hpp
++bytecodeInterpreter_<arch>.cpp          interp_masm_<arch_model>.hpp
++bytecodeInterpreter_<arch>.cpp          interpreterRuntime.hpp
++bytecodeInterpreter_<arch>.cpp          interpreter.hpp
++bytecodeInterpreter_<arch>.cpp          jvmtiExport.hpp
++bytecodeInterpreter_<arch>.cpp          jvmtiThreadState.hpp
++bytecodeInterpreter_<arch>.cpp          methodDataOop.hpp
++bytecodeInterpreter_<arch>.cpp          methodOop.hpp
++bytecodeInterpreter_<arch>.cpp          oop.inline.hpp
++bytecodeInterpreter_<arch>.cpp          sharedRuntime.hpp
++bytecodeInterpreter_<arch>.cpp          stubRoutines.hpp
++bytecodeInterpreter_<arch>.cpp          synchronizer.hpp
++bytecodeInterpreter_<arch>.cpp          vframeArray.hpp
++
++bytecodeInterpreterWithChecks.cpp       bytecodeInterpreter.cpp
++
++bytecodeInterpreter.hpp                 allocation.hpp
++bytecodeInterpreter.hpp                 bytes_<arch>.hpp
++bytecodeInterpreter.hpp                 frame.hpp
++bytecodeInterpreter.hpp                 globalDefinitions.hpp
++bytecodeInterpreter.hpp                 globals.hpp
++bytecodeInterpreter.hpp                 methodDataOop.hpp
++bytecodeInterpreter.hpp                 methodOop.hpp
++bytecodeInterpreter.hpp                 synchronizer.hpp
++
++bytecodeInterpreter.inline.hpp          bytecodeInterpreter.hpp
++bytecodeInterpreter.inline.hpp          stubRoutines.hpp
++
++bytecodeInterpreter_<arch>.hpp          generate_platform_dependent_include
++
++bytecodeInterpreter_<arch>.inline.hpp   generate_platform_dependent_include
++
+ bytecodeStream.cpp                      bytecodeStream.hpp
+ bytecodeStream.cpp                      bytecodes.hpp
+ 
+@@ -421,45 +470,6 @@
+ 
+ bytes_<os_arch>.inline.hpp              generate_platform_dependent_include
+ 
+-cInterpretMethod.hpp                    interpreter_<arch>.hpp
+-cInterpretMethod.hpp                    threadLocalAllocBuffer.inline.hpp
+-
+-cInterpreter.cpp                        bytecodeHistogram.hpp
+-cInterpreter.cpp                        cInterpretMethod.hpp
+-cInterpreter.cpp                        cInterpreter.hpp
+-cInterpreter.cpp                        cInterpreter.inline.hpp
+-cInterpreter.cpp                        cardTableModRefBS.hpp
+-cInterpreter.cpp                        collectedHeap.hpp
+-cInterpreter.cpp                        exceptions.hpp
+-cInterpreter.cpp                        frame.inline.hpp
+-cInterpreter.cpp                        handles.inline.hpp
+-cInterpreter.cpp                        interfaceSupport.hpp
+-cInterpreter.cpp                        interpreterRuntime.hpp
+-cInterpreter.cpp                        interpreter_<arch>.hpp
+-cInterpreter.cpp                        jvmtiExport.hpp
+-cInterpreter.cpp                        objArrayKlass.hpp
+-cInterpreter.cpp                        oop.inline.hpp
+-cInterpreter.cpp                        orderAccess_<os_arch>.inline.hpp
+-cInterpreter.cpp                        resourceArea.hpp
+-cInterpreter.cpp                        sharedRuntime.hpp
+-cInterpreter.cpp                        threadCritical.hpp
+-cInterpreter.cpp                        vmSymbols.hpp
+-
+-cInterpreter.hpp                        allocation.hpp
+-cInterpreter.hpp                        bytes_<arch>.hpp
+-cInterpreter.hpp                        frame.hpp
+-cInterpreter.hpp                        globalDefinitions.hpp
+-cInterpreter.hpp                        globals.hpp
+-cInterpreter.hpp                        methodOop.hpp
+-cInterpreter.hpp                        synchronizer.hpp
+-
+-cInterpreter.inline.hpp                 cInterpreter.hpp
+-cInterpreter.inline.hpp                 stubRoutines.hpp
+-
+-cInterpreter_<arch>.hpp                 generate_platform_dependent_include
+-
+-cInterpreter_<arch>.inline.hpp          generate_platform_dependent_include
+-
+ cardTableModRefBS.cpp                   allocation.inline.hpp
+ cardTableModRefBS.cpp                   cardTableModRefBS.hpp
+ cardTableModRefBS.cpp                   cardTableRS.hpp
+@@ -487,19 +497,6 @@
+ cardTableRS.hpp                         genRemSet.hpp
+ cardTableRS.hpp                         memRegion.hpp
+ 
+-cha.cpp                                 cha.hpp
+-cha.cpp                                 instanceKlass.hpp
+-cha.cpp                                 linkResolver.hpp
+-cha.cpp                                 methodOop.hpp
+-cha.cpp                                 oop.inline.hpp
+-cha.cpp                                 systemDictionary.hpp
+-cha.cpp                                 universe.inline.hpp
+-
+-cha.hpp                                 growableArray.hpp
+-cha.hpp                                 handles.hpp
+-cha.hpp                                 handles.inline.hpp
+-cha.hpp                                 klassOop.hpp
+-
+ ciArray.cpp                             ciArray.hpp
+ ciArray.cpp                             ciKlass.hpp
+ ciArray.cpp                             ciUtilities.hpp
+@@ -654,7 +651,6 @@
+ ciMethod.cpp                            abstractCompiler.hpp
+ ciMethod.cpp                            allocation.inline.hpp
+ ciMethod.cpp                            bcEscapeAnalyzer.hpp
+-ciMethod.cpp                            cha.hpp
+ ciMethod.cpp                            ciCallProfile.hpp
+ ciMethod.cpp                            ciExceptionHandler.hpp
+ ciMethod.cpp                            ciInstanceKlass.hpp
+@@ -984,6 +980,8 @@
+ codeCache.cpp                           allocation.inline.hpp
+ codeCache.cpp                           codeBlob.hpp
+ codeCache.cpp                           codeCache.hpp
++codeCache.cpp                           dependencies.hpp
++codeCache.cpp                           gcLocker.hpp
+ codeCache.cpp                           icache.hpp
+ codeCache.cpp                           iterator.hpp
+ codeCache.cpp                           java.hpp
+@@ -1046,7 +1044,7 @@
+ compilationPolicy.cpp                   frame.hpp
+ compilationPolicy.cpp                   globalDefinitions.hpp
+ compilationPolicy.cpp                   handles.inline.hpp
+-compilationPolicy.cpp                   interpreter_<arch>.hpp
++compilationPolicy.cpp                   interpreter.hpp
+ compilationPolicy.cpp                   methodDataOop.hpp
+ compilationPolicy.cpp                   methodOop.hpp
+ compilationPolicy.cpp                   nativeLookup.hpp
+@@ -1104,7 +1102,7 @@
+ compiledIC.cpp                          events.hpp
+ compiledIC.cpp                          icBuffer.hpp
+ compiledIC.cpp                          icache.hpp
+-compiledIC.cpp                          interpreter_<arch>.hpp
++compiledIC.cpp                          interpreter.hpp
+ compiledIC.cpp                          linkResolver.hpp
+ compiledIC.cpp                          methodOop.hpp
+ compiledIC.cpp                          nmethod.hpp
+@@ -1275,7 +1273,7 @@
+ cpCacheOop.cpp                          cpCacheOop.hpp
+ cpCacheOop.cpp                          handles.inline.hpp
+ cpCacheOop.cpp                          interpreter.hpp
+-cpCacheOop.cpp                          jvmtiRedefineClasses.hpp
++cpCacheOop.cpp                          jvmtiRedefineClassesTrace.hpp
+ cpCacheOop.cpp                          markSweep.hpp
+ cpCacheOop.cpp                          markSweep.inline.hpp
+ cpCacheOop.cpp                          objArrayOop.hpp
+@@ -1287,6 +1285,39 @@
+ cpCacheOop.hpp                          arrayOop.hpp
+ cpCacheOop.hpp                          bytecodes.hpp
+ 
++cppInterpreter.cpp                      bytecodeInterpreter.hpp
++cppInterpreter.cpp                      interpreter.hpp
++cppInterpreter.cpp                      interpreterGenerator.hpp
++cppInterpreter.cpp                      interpreterRuntime.hpp
++
++cppInterpreter.hpp                      abstractInterpreter.hpp
++
++cppInterpreter_<arch>.cpp               arguments.hpp
++cppInterpreter_<arch>.cpp               arrayOop.hpp
++cppInterpreter_<arch>.cpp               assembler.hpp
++cppInterpreter_<arch>.cpp               bytecodeHistogram.hpp
++cppInterpreter_<arch>.cpp               debug.hpp
++cppInterpreter_<arch>.cpp               deoptimization.hpp
++cppInterpreter_<arch>.cpp               frame.inline.hpp
++cppInterpreter_<arch>.cpp               interpreterRuntime.hpp
++cppInterpreter_<arch>.cpp               interpreter.hpp
++cppInterpreter_<arch>.cpp               interpreterGenerator.hpp
++cppInterpreter_<arch>.cpp               jvmtiExport.hpp
++cppInterpreter_<arch>.cpp               jvmtiThreadState.hpp
++cppInterpreter_<arch>.cpp               methodDataOop.hpp
++cppInterpreter_<arch>.cpp               methodOop.hpp
++cppInterpreter_<arch>.cpp               oop.inline.hpp
++cppInterpreter_<arch>.cpp               sharedRuntime.hpp
++cppInterpreter_<arch>.cpp               stubRoutines.hpp
++cppInterpreter_<arch>.cpp               synchronizer.hpp
++cppInterpreter_<arch>.cpp               cppInterpreter.hpp
++cppInterpreter_<arch>.cpp               timer.hpp
++cppInterpreter_<arch>.cpp               vframeArray.hpp
++
++cppInterpreter_<arch>.hpp          generate_platform_dependent_include
++
++cppInterpreterGenerator_<arch>.hpp generate_platform_dependent_include
++
+ debug.cpp                               arguments.hpp
+ debug.cpp                               bytecodeHistogram.hpp
+ debug.cpp                               codeCache.hpp
+@@ -1298,7 +1329,7 @@
+ debug.cpp                               frame.hpp
+ debug.cpp                               heapDumper.hpp
+ debug.cpp                               icBuffer.hpp
+-debug.cpp                               interpreter_<arch>.hpp
++debug.cpp                               interpreter.hpp
+ debug.cpp                               java.hpp
+ debug.cpp                               markSweep.hpp
+ debug.cpp                               nmethod.hpp
+@@ -1433,7 +1464,7 @@
+ dictionary.cpp                          classLoadingService.hpp
+ dictionary.cpp                          dictionary.hpp
+ dictionary.cpp                          hashtable.inline.hpp
+-dictionary.cpp                          jvmtiRedefineClasses.hpp
++dictionary.cpp                          jvmtiRedefineClassesTrace.hpp
+ dictionary.cpp                          oop.inline.hpp
+ dictionary.cpp                          systemDictionary.hpp
+ 
+@@ -1465,24 +1496,7 @@
+ dtraceAttacher.cpp                      vmThread.hpp
+ dtraceAttacher.cpp                      vm_operations.hpp
+ 
+-dump.cpp                                classify.hpp
+-dump.cpp                                copy.hpp
+-dump.cpp                                filemap.hpp
+-dump.cpp                                javaCalls.hpp
+-dump.cpp                                javaClasses.hpp
+-dump.cpp                                loaderConstraints.hpp
+-dump.cpp                                methodDataOop.hpp
+-dump.cpp                                oop.hpp
+-dump.cpp                                oopFactory.hpp
+-dump.cpp                                resourceArea.hpp
+-dump.cpp                                signature.hpp
+-dump.cpp                                symbolTable.hpp
+-dump.cpp                                systemDictionary.hpp
+-dump.cpp                                vmThread.hpp
+-dump.cpp                                vm_operations.hpp
+-
+-dump_<arch>.cpp                         assembler_<arch>.inline.hpp
+-dump_<arch>.cpp                         compactingPermGenGen.hpp
++// dump is jck optional, put cpp deps in includeDB_features
+ 
+ events.cpp                              allocation.inline.hpp
+ events.cpp                              events.hpp
+@@ -1559,34 +1573,8 @@
+ filemap.hpp                             compactingPermGenGen.hpp
+ filemap.hpp                             space.hpp
+ 
+-forte.cpp                               collectedHeap.inline.hpp
+-forte.cpp                               debugInfoRec.hpp
+-forte.cpp                               forte.hpp
+-forte.cpp                               oop.inline.hpp
+-forte.cpp                               oop.inline2.hpp
+-forte.cpp                               pcDesc.hpp
+-forte.cpp                               space.hpp
+-forte.cpp                               thread.hpp
+-forte.cpp                               universe.inline.hpp
+-forte.cpp                               vframe.hpp
+-forte.cpp                               vframeArray.hpp
+-
+-fprofiler.cpp                           allocation.inline.hpp
+-fprofiler.cpp                           classLoader.hpp
+-fprofiler.cpp                           collectedHeap.inline.hpp
+-fprofiler.cpp                           deoptimization.hpp
+-fprofiler.cpp                           fprofiler.hpp
+-fprofiler.cpp                           interpreter_<arch>.hpp
+-fprofiler.cpp                           mutexLocker.hpp
+-fprofiler.cpp                           oop.inline.hpp
+-fprofiler.cpp                           oop.inline2.hpp
+-fprofiler.cpp                           stubCodeGenerator.hpp
+-fprofiler.cpp                           stubRoutines.hpp
+-fprofiler.cpp                           symbolOop.hpp
+-fprofiler.cpp                           task.hpp
+-fprofiler.cpp                           universe.inline.hpp
+-fprofiler.cpp                           vframe.hpp
+-fprofiler.cpp                           vtableStubs.hpp
++// forte is jck optional, put cpp deps in includeDB_features
++// fprofiler is jck optional, put cpp deps in includeDB_features
+ 
+ fprofiler.hpp                           thread_<os_family>.inline.hpp
+ fprofiler.hpp                           timer.hpp
+@@ -1594,8 +1582,7 @@
+ frame.cpp                               collectedHeap.inline.hpp
+ frame.cpp                               frame.inline.hpp
+ frame.cpp                               handles.inline.hpp
+-frame.cpp                               init.hpp
+-frame.cpp                               interpreter_<arch>.hpp
++frame.cpp                               interpreter.hpp
+ frame.cpp                               javaCalls.hpp
+ frame.cpp                               markOop.hpp
+ frame.cpp                               methodDataOop.hpp
+@@ -1620,8 +1607,8 @@
+ frame.hpp                               synchronizer.hpp
+ frame.hpp                               top.hpp
+ 
+-frame.inline.hpp                        cInterpreter.hpp
+-frame.inline.hpp                        cInterpreter.inline.hpp
++frame.inline.hpp                        bytecodeInterpreter.hpp
++frame.inline.hpp                        bytecodeInterpreter.inline.hpp
+ frame.inline.hpp                        frame.hpp
+ frame.inline.hpp                        interpreter.hpp
+ frame.inline.hpp                        jniTypes_<arch>.hpp
+@@ -1630,7 +1617,7 @@
+ 
+ frame_<arch>.cpp                        frame.inline.hpp
+ frame_<arch>.cpp                        handles.inline.hpp
+-frame_<arch>.cpp                        interpreter_<arch>.hpp
++frame_<arch>.cpp                        interpreter.hpp
+ frame_<arch>.cpp                        javaCalls.hpp
+ frame_<arch>.cpp                        markOop.hpp
+ frame_<arch>.cpp                        methodOop.hpp
+@@ -1871,33 +1858,14 @@
+ heap.hpp                                allocation.hpp
+ heap.hpp                                virtualspace.hpp
+ 
+-heapDumper.cpp                          genCollectedHeap.hpp
+-heapDumper.cpp                          heapDumper.hpp 
+-heapDumper.cpp                          javaCalls.hpp
+-heapDumper.cpp                          jniHandles.hpp
+-heapDumper.cpp                          objArrayKlass.hpp
+-heapDumper.cpp                          ostream.hpp
+-heapDumper.cpp                          reflectionUtils.hpp
+-heapDumper.cpp                          symbolTable.hpp
+-heapDumper.cpp                          systemDictionary.hpp
+-heapDumper.cpp                          universe.hpp
+-heapDumper.cpp                          vframe.hpp
+-heapDumper.cpp                          vmSymbols.hpp
+-heapDumper.cpp                          vmThread.hpp
+-heapDumper.cpp                          vm_operations.hpp
++// heapDumper is jck optional, put cpp deps in includeDB_features
+ 
+ heapDumper.hpp                          allocation.hpp
+ heapDumper.hpp                          klassOop.hpp
+ heapDumper.hpp                          oop.hpp
+ heapDumper.hpp                          os.hpp
+ 
+-heapInspection.cpp                      collectedHeap.hpp
+-heapInspection.cpp                      genCollectedHeap.hpp
+-heapInspection.cpp                      globalDefinitions.hpp
+-heapInspection.cpp                      heapInspection.hpp
+-heapInspection.cpp                      klassOop.hpp
+-heapInspection.cpp                      os.hpp
+-heapInspection.cpp                      resourceArea.hpp
++// heapInspection is jck optional, put cpp deps in includeDB_features
+ 
+ heapInspection.hpp                      allocation.inline.hpp
+ heapInspection.hpp                      oop.inline.hpp
+@@ -1924,11 +1892,11 @@
+ 
+ hpi_imported.h                          jni.h
+ 
+-icBuffer.cpp                            assembler_<arch>.inline.hpp
++icBuffer.cpp                            assembler_<arch_model>.inline.hpp
+ icBuffer.cpp                            collectedHeap.inline.hpp
+ icBuffer.cpp                            compiledIC.hpp
+ icBuffer.cpp                            icBuffer.hpp
+-icBuffer.cpp                            interpreter_<arch>.hpp
++icBuffer.cpp                            interpreter.hpp
+ icBuffer.cpp                            linkResolver.hpp
+ icBuffer.cpp                            methodOop.hpp
+ icBuffer.cpp                            mutexLocker.hpp
+@@ -1945,7 +1913,7 @@
+ icBuffer.hpp                            stubs.hpp
+ 
+ icBuffer_<arch>.cpp                     assembler.hpp
+-icBuffer_<arch>.cpp                     assembler_<arch>.inline.hpp
++icBuffer_<arch>.cpp                     assembler_<arch_model>.inline.hpp
+ icBuffer_<arch>.cpp                     bytecodes.hpp
+ icBuffer_<arch>.cpp                     collectedHeap.inline.hpp
+ icBuffer_<arch>.cpp                     icBuffer.hpp
+@@ -1960,13 +1928,14 @@
+ icache.hpp                              allocation.hpp
+ icache.hpp                              stubCodeGenerator.hpp
+ 
+-icache_<arch>.cpp                       assembler_<arch>.inline.hpp
++icache_<arch>.cpp                       assembler_<arch_model>.inline.hpp
+ icache_<arch>.cpp                       icache.hpp
+ 
+ icache_<arch>.hpp                       generate_platform_dependent_include
+ 
+ init.cpp                                bytecodes.hpp
+ init.cpp                                collectedHeap.hpp
++init.cpp				handles.inline.hpp
+ init.cpp                                icBuffer.hpp
+ init.cpp                                icache.hpp
+ init.cpp                                init.hpp
+@@ -1987,7 +1956,7 @@
+ instanceKlass.cpp                       javaClasses.hpp
+ instanceKlass.cpp                       jvmti.h
+ instanceKlass.cpp                       jvmtiExport.hpp
+-instanceKlass.cpp                       jvmtiRedefineClasses.hpp
++instanceKlass.cpp                       jvmtiRedefineClassesTrace.hpp
+ instanceKlass.cpp                       methodOop.hpp
+ instanceKlass.cpp                       mutexLocker.hpp
+ instanceKlass.cpp                       objArrayKlassKlass.hpp
+@@ -2076,33 +2045,33 @@
+ 
+ interfaceSupport_<os_family>.hpp        generate_platform_dependent_include
+ 
+-interp_masm_<arch>.cpp                  arrayOop.hpp
+-interp_masm_<arch>.cpp                  biasedLocking.hpp
+-interp_masm_<arch>.cpp                  interp_masm_<arch>.hpp
+-interp_masm_<arch>.cpp                  interpreterRuntime.hpp
+-interp_masm_<arch>.cpp                  interpreter_<arch>.hpp
+-interp_masm_<arch>.cpp                  jvmtiExport.hpp
+-interp_masm_<arch>.cpp                  jvmtiThreadState.hpp
+-interp_masm_<arch>.cpp                  markOop.hpp
+-interp_masm_<arch>.cpp                  methodDataOop.hpp
+-interp_masm_<arch>.cpp                  methodOop.hpp
+-interp_masm_<arch>.cpp                  sharedRuntime.hpp
+-interp_masm_<arch>.cpp                  synchronizer.hpp
+-interp_masm_<arch>.cpp                  thread_<os_family>.inline.hpp
++interp_masm_<arch_model>.cpp            arrayOop.hpp
++interp_masm_<arch_model>.cpp            biasedLocking.hpp
++interp_masm_<arch_model>.cpp            interp_masm_<arch_model>.hpp
++interp_masm_<arch_model>.cpp            interpreterRuntime.hpp
++interp_masm_<arch_model>.cpp            interpreter.hpp
++interp_masm_<arch_model>.cpp            jvmtiExport.hpp
++interp_masm_<arch_model>.cpp            jvmtiThreadState.hpp
++interp_masm_<arch_model>.cpp            markOop.hpp
++interp_masm_<arch_model>.cpp            methodDataOop.hpp
++interp_masm_<arch_model>.cpp            methodOop.hpp
++interp_masm_<arch_model>.cpp            sharedRuntime.hpp
++interp_masm_<arch_model>.cpp            synchronizer.hpp
++interp_masm_<arch_model>.cpp            thread_<os_family>.inline.hpp
+ 
+-interp_masm_<arch>.hpp                  assembler_<arch>.inline.hpp
+-interp_masm_<arch>.hpp                  invocationCounter.hpp
++interp_masm_<arch_model>.hpp            assembler_<arch_model>.inline.hpp
++interp_masm_<arch_model>.hpp            invocationCounter.hpp
+ 
+ interpreter.cpp                         allocation.inline.hpp
+ interpreter.cpp                         arrayOop.hpp
+ interpreter.cpp                         assembler.hpp
+ interpreter.cpp                         bytecodeHistogram.hpp
+-interpreter.cpp                         cInterpreter.hpp
++interpreter.cpp                         bytecodeInterpreter.hpp
+ interpreter.cpp                         forte.hpp
+ interpreter.cpp                         handles.inline.hpp
+ interpreter.cpp                         interpreter.hpp
+ interpreter.cpp                         interpreterRuntime.hpp
+-interpreter.cpp                         interpreter_<arch>.hpp
++interpreter.cpp                         interpreter.hpp
+ interpreter.cpp                         jvmtiExport.hpp
+ interpreter.cpp                         methodDataOop.hpp
+ interpreter.cpp                         methodOop.hpp
+@@ -2114,25 +2083,20 @@
+ interpreter.cpp                         timer.hpp
+ interpreter.cpp                         vtune.hpp
+ 
+-interpreter.hpp                         bytecodes.hpp
+-interpreter.hpp                         cInterpreter.hpp
+-interpreter.hpp                         interp_masm_<arch>.hpp
++interpreter.hpp                         cppInterpreter.hpp
+ interpreter.hpp                         stubs.hpp
+-interpreter.hpp                         templateTable.hpp
+-interpreter.hpp                         thread_<os_family>.inline.hpp
+-interpreter.hpp                         top.hpp
+-interpreter.hpp                         vmThread.hpp
+-
+-interpreterRT_<arch>.cpp                allocation.inline.hpp
+-interpreterRT_<arch>.cpp                handles.inline.hpp
+-interpreterRT_<arch>.cpp                icache.hpp
+-interpreterRT_<arch>.cpp                interfaceSupport.hpp
+-interpreterRT_<arch>.cpp                interpreterRuntime.hpp
+-interpreterRT_<arch>.cpp                interpreter_<arch>.hpp
+-interpreterRT_<arch>.cpp                methodOop.hpp
+-interpreterRT_<arch>.cpp                oop.inline.hpp
+-interpreterRT_<arch>.cpp                signature.hpp
+-interpreterRT_<arch>.cpp                universe.inline.hpp
++interpreter.hpp                         templateInterpreter.hpp
++
++interpreterRT_<arch_model>.cpp          allocation.inline.hpp
++interpreterRT_<arch_model>.cpp          handles.inline.hpp
++interpreterRT_<arch_model>.cpp          icache.hpp
++interpreterRT_<arch_model>.cpp          interfaceSupport.hpp
++interpreterRT_<arch_model>.cpp          interpreterRuntime.hpp
++interpreterRT_<arch_model>.cpp          interpreter.hpp
++interpreterRT_<arch_model>.cpp          methodOop.hpp
++interpreterRT_<arch_model>.cpp          oop.inline.hpp
++interpreterRT_<arch_model>.cpp          signature.hpp
++interpreterRT_<arch_model>.cpp          universe.inline.hpp
+ 
+ interpreterRT_<arch>.hpp                allocation.hpp
+ interpreterRT_<arch>.hpp                generate_platform_dependent_include
+@@ -2149,7 +2113,7 @@
+ interpreterRuntime.cpp                  instanceKlass.hpp
+ interpreterRuntime.cpp                  interfaceSupport.hpp
+ interpreterRuntime.cpp                  interpreterRuntime.hpp
+-interpreterRuntime.cpp                  interpreter_<arch>.hpp
++interpreterRuntime.cpp                  interpreter.hpp
+ interpreterRuntime.cpp                  java.hpp
+ interpreterRuntime.cpp                  jfieldIDWorkaround.hpp
+ interpreterRuntime.cpp                  jvmtiExport.hpp
+@@ -2169,7 +2133,7 @@
+ interpreterRuntime.cpp                  threadCritical.hpp
+ interpreterRuntime.cpp                  universe.inline.hpp
+ interpreterRuntime.cpp                  vmSymbols.hpp
+-interpreterRuntime.cpp                  vm_version_<arch>.hpp
++interpreterRuntime.cpp                  vm_version_<arch_model>.hpp
+ 
+ interpreterRuntime.hpp                  bytecode.hpp
+ interpreterRuntime.hpp                  frame.inline.hpp
+@@ -2180,29 +2144,36 @@
+ interpreterRuntime.hpp                  top.hpp
+ interpreterRuntime.hpp                  universe.hpp
+ 
+-interpreter_<arch>.cpp                  arguments.hpp
+-interpreter_<arch>.cpp                  arrayOop.hpp
+-interpreter_<arch>.cpp                  assembler.hpp
+-interpreter_<arch>.cpp                  bytecodeHistogram.hpp
+-interpreter_<arch>.cpp                  debug.hpp
+-interpreter_<arch>.cpp                  deoptimization.hpp
+-interpreter_<arch>.cpp                  frame.inline.hpp
+-interpreter_<arch>.cpp                  interpreterRuntime.hpp
+-interpreter_<arch>.cpp                  interpreter_<arch>.hpp
+-interpreter_<arch>.cpp                  jvmtiExport.hpp
+-interpreter_<arch>.cpp                  jvmtiThreadState.hpp
+-interpreter_<arch>.cpp                  methodDataOop.hpp
+-interpreter_<arch>.cpp                  methodOop.hpp
+-interpreter_<arch>.cpp                  oop.inline.hpp
+-interpreter_<arch>.cpp                  sharedRuntime.hpp
+-interpreter_<arch>.cpp                  stubRoutines.hpp
+-interpreter_<arch>.cpp                  synchronizer.hpp
+-interpreter_<arch>.cpp                  templateTable.hpp
+-interpreter_<arch>.cpp                  timer.hpp
+-interpreter_<arch>.cpp                  vframeArray.hpp
++interpreter_<arch_model>.cpp            arguments.hpp
++interpreter_<arch_model>.cpp            arrayOop.hpp
++interpreter_<arch_model>.cpp            assembler.hpp
++interpreter_<arch_model>.cpp            bytecodeHistogram.hpp
++interpreter_<arch_model>.cpp            debug.hpp
++interpreter_<arch_model>.cpp            deoptimization.hpp
++interpreter_<arch_model>.cpp            frame.inline.hpp
++interpreter_<arch_model>.cpp            interpreterRuntime.hpp
++interpreter_<arch_model>.cpp            interpreter.hpp
++interpreter_<arch_model>.cpp            interpreterGenerator.hpp
++interpreter_<arch_model>.cpp            jvmtiExport.hpp
++interpreter_<arch_model>.cpp            jvmtiThreadState.hpp
++interpreter_<arch_model>.cpp            methodDataOop.hpp
++interpreter_<arch_model>.cpp            methodOop.hpp
++interpreter_<arch_model>.cpp            oop.inline.hpp
++interpreter_<arch_model>.cpp            sharedRuntime.hpp
++interpreter_<arch_model>.cpp            stubRoutines.hpp
++interpreter_<arch_model>.cpp            synchronizer.hpp
++interpreter_<arch_model>.cpp            templateTable.hpp
++interpreter_<arch_model>.cpp            timer.hpp
++interpreter_<arch_model>.cpp            vframeArray.hpp
++
++interpreter_<arch>.hpp                  generate_platform_dependent_include
++
++interpreterGenerator.hpp                cppInterpreter.hpp
++interpreterGenerator.hpp                cppInterpreterGenerator.hpp
++interpreterGenerator.hpp                templateInterpreter.hpp
++interpreterGenerator.hpp                templateInterpreterGenerator.hpp
+ 
+-interpreter_<arch>.hpp                  frame.inline.hpp
+-interpreter_<arch>.hpp                  interpreter.hpp
++interpreterGenerator_<arch>.hpp         generate_platform_dependent_include
+ 
+ invocationCounter.cpp                   frame.hpp
+ invocationCounter.cpp                   handles.inline.hpp
+@@ -2260,7 +2231,7 @@
+ java.cpp                                universe.hpp
+ java.cpp                                vmError.hpp
+ java.cpp                                vm_operations.hpp
+-java.cpp                                vm_version_<arch>.hpp
++java.cpp                                vm_version_<arch_model>.hpp
+ java.cpp                                vtune.hpp
+ 
+ java.hpp                                os.hpp
+@@ -2283,7 +2254,7 @@
+ javaCalls.cpp                           compileBroker.hpp
+ javaCalls.cpp                           handles.inline.hpp
+ javaCalls.cpp                           interfaceSupport.hpp
+-javaCalls.cpp                           interpreter_<arch>.hpp
++javaCalls.cpp                           interpreter.hpp
+ javaCalls.cpp                           javaCalls.hpp
+ javaCalls.cpp                           linkResolver.hpp
+ javaCalls.cpp                           mutexLocker.hpp
+@@ -2388,31 +2359,18 @@
+ jni.cpp                                 vmSymbols.hpp
+ jni.cpp                                 vm_operations.hpp
+ 
+-jniCheck.cpp                            fieldDescriptor.hpp
+-jniCheck.cpp                            handles.hpp
+-jniCheck.cpp                            instanceKlass.hpp
+-jniCheck.cpp                            interfaceSupport.hpp
+-jniCheck.cpp                            jfieldIDWorkaround.hpp
+-jniCheck.cpp                            jni.h
+-jniCheck.cpp                            jniCheck.hpp
+-jniCheck.cpp                            jniTypes_<arch>.hpp
+-jniCheck.cpp                            jvm_misc.hpp
+-jniCheck.cpp                            oop.inline.hpp
+-jniCheck.cpp                            symbolOop.hpp
+-jniCheck.cpp                            systemDictionary.hpp
+-jniCheck.cpp                            thread.hpp
+-jniCheck.cpp                            vmSymbols.hpp
++// jniCheck is jck optional, put cpp deps in includeDB_features
+ 
+ jniFastGetField.cpp                     jniFastGetField.hpp
+ 
+ jniFastGetField.hpp                     allocation.hpp
+ jniFastGetField.hpp                     jvm_misc.hpp
+ 
+-jniFastGetField_<arch>.cpp              assembler_<arch>.inline.hpp
+-jniFastGetField_<arch>.cpp              jniFastGetField.hpp
+-jniFastGetField_<arch>.cpp              jvm_misc.hpp
+-jniFastGetField_<arch>.cpp              resourceArea.hpp
+-jniFastGetField_<arch>.cpp              safepoint.hpp
++jniFastGetField_<arch_model>.cpp        assembler_<arch_model>.inline.hpp
++jniFastGetField_<arch_model>.cpp        jniFastGetField.hpp
++jniFastGetField_<arch_model>.cpp        jvm_misc.hpp
++jniFastGetField_<arch_model>.cpp        resourceArea.hpp
++jniFastGetField_<arch_model>.cpp        safepoint.hpp
+ 
+ jniHandles.cpp                          jniHandles.hpp
+ jniHandles.cpp                          mutexLocker.hpp
+@@ -2487,181 +2445,6 @@
+ jvm_misc.hpp                            handles.hpp
+ jvm_misc.hpp                            jni.h
+ 
+-jvmtiAgentThread.hpp                    jvmtiEnv.hpp
+-
+-jvmtiClassFileReconstituter.cpp         bytecodeStream.hpp
+-jvmtiClassFileReconstituter.cpp         bytes_<arch>.hpp
+-jvmtiClassFileReconstituter.cpp         jvmtiClassFileReconstituter.hpp
+-jvmtiClassFileReconstituter.cpp         symbolTable.hpp
+-
+-jvmtiClassFileReconstituter.hpp         jvmtiEnv.hpp
+-
+-jvmtiCodeBlobEvents.cpp                 codeBlob.hpp
+-jvmtiCodeBlobEvents.cpp                 codeCache.hpp
+-jvmtiCodeBlobEvents.cpp                 handles.hpp
+-jvmtiCodeBlobEvents.cpp                 handles.inline.hpp
+-jvmtiCodeBlobEvents.cpp                 jvmtiCodeBlobEvents.hpp
+-jvmtiCodeBlobEvents.cpp                 jvmtiExport.hpp
+-jvmtiCodeBlobEvents.cpp                 oop.inline.hpp
+-jvmtiCodeBlobEvents.cpp                 resourceArea.hpp
+-jvmtiCodeBlobEvents.cpp                 scopeDesc.hpp
+-jvmtiCodeBlobEvents.cpp                 vmThread.hpp
+-
+-jvmtiCodeBlobEvents.hpp                 jvmti.h
+-
+-jvmtiEnter.cpp                          jvmtiEnter.hpp
+-
+-jvmtiEnter.hpp                          interfaceSupport.hpp
+-jvmtiEnter.hpp                          jvmtiEnv.hpp
+-jvmtiEnter.hpp                          jvmtiImpl.hpp
+-jvmtiEnter.hpp                          resourceArea.hpp
+-jvmtiEnter.hpp                          systemDictionary.hpp
+-
+-jvmtiEnterTrace.cpp                     jvmtiEnter.hpp
+-
+-jvmtiEnv.cpp                            arguments.hpp
+-jvmtiEnv.cpp                            bytecodeStream.hpp
+-jvmtiEnv.cpp                            cpCacheOop.hpp
+-jvmtiEnv.cpp                            deoptimization.hpp
+-jvmtiEnv.cpp                            exceptions.hpp
+-jvmtiEnv.cpp                            instanceKlass.hpp
+-jvmtiEnv.cpp                            interfaceSupport.hpp
+-jvmtiEnv.cpp                            interpreter.hpp
+-jvmtiEnv.cpp                            javaCalls.hpp
+-jvmtiEnv.cpp                            jfieldIDWorkaround.hpp
+-jvmtiEnv.cpp                            jniCheck.hpp
+-jvmtiEnv.cpp                            jvm_misc.hpp
+-jvmtiEnv.cpp                            jvmtiAgentThread.hpp
+-jvmtiEnv.cpp                            jvmtiClassFileReconstituter.hpp
+-jvmtiEnv.cpp                            jvmtiCodeBlobEvents.hpp
+-jvmtiEnv.cpp                            jvmtiEnv.hpp
+-jvmtiEnv.cpp                            jvmtiExtensions.hpp
+-jvmtiEnv.cpp                            jvmtiGetLoadedClasses.hpp
+-jvmtiEnv.cpp                            jvmtiImpl.hpp
+-jvmtiEnv.cpp                            jvmtiManageCapabilities.hpp
+-jvmtiEnv.cpp                            jvmtiRedefineClasses.hpp
+-jvmtiEnv.cpp                            jvmtiTagMap.hpp 
+-jvmtiEnv.cpp                            jvmtiThreadState.inline.hpp
+-jvmtiEnv.cpp                            objectMonitor.inline.hpp
+-jvmtiEnv.cpp                            osThread.hpp
+-jvmtiEnv.cpp                            preserveException.hpp
+-jvmtiEnv.cpp                            reflectionUtils.hpp
+-jvmtiEnv.cpp                            resourceArea.hpp
+-jvmtiEnv.cpp                            signature.hpp
+-jvmtiEnv.cpp                            systemDictionary.hpp
+-jvmtiEnv.cpp                            threadService.hpp
+-jvmtiEnv.cpp                            thread_<os_family>.inline.hpp
+-jvmtiEnv.cpp                            universe.inline.hpp
+-jvmtiEnv.cpp                            vframe.hpp
+-jvmtiEnv.cpp                            vmSymbols.hpp
+-jvmtiEnv.cpp                            vmThread.hpp
+-
+-jvmtiEnv.hpp                            jvmtiEnvBase.hpp
+-
+-jvmtiEnvBase.cpp                        biasedLocking.hpp
+-jvmtiEnvBase.cpp                        interfaceSupport.hpp
+-jvmtiEnvBase.cpp                        jfieldIDWorkaround.hpp
+-jvmtiEnvBase.cpp                        jvmtiEnv.hpp
+-jvmtiEnvBase.cpp                        jvmtiEnvBase.hpp
+-jvmtiEnvBase.cpp                        jvmtiEventController.inline.hpp
+-jvmtiEnvBase.cpp                        jvmtiExtensions.hpp
+-jvmtiEnvBase.cpp                        jvmtiImpl.hpp
+-jvmtiEnvBase.cpp                        jvmtiManageCapabilities.hpp
+-jvmtiEnvBase.cpp                        jvmtiTagMap.hpp
+-jvmtiEnvBase.cpp                        jvmtiThreadState.inline.hpp
+-jvmtiEnvBase.cpp                        objArrayKlass.hpp
+-jvmtiEnvBase.cpp                        objArrayOop.hpp
+-jvmtiEnvBase.cpp                        objectMonitor.hpp
+-jvmtiEnvBase.cpp                        objectMonitor.inline.hpp
+-jvmtiEnvBase.cpp                        signature.hpp
+-jvmtiEnvBase.cpp                        systemDictionary.hpp
+-jvmtiEnvBase.cpp                        vframe.hpp
+-jvmtiEnvBase.cpp                        vframe_hp.hpp
+-jvmtiEnvBase.cpp                        vmThread.hpp
+-jvmtiEnvBase.cpp                        vm_operations.hpp
+-
+-jvmtiEnvBase.hpp                        classLoader.hpp
+-jvmtiEnvBase.hpp                        fieldDescriptor.hpp
+-jvmtiEnvBase.hpp                        frame.hpp
+-jvmtiEnvBase.hpp                        growableArray.hpp
+-jvmtiEnvBase.hpp                        handles.inline.hpp
+-jvmtiEnvBase.hpp                        jvmtiEnvThreadState.hpp
+-jvmtiEnvBase.hpp                        jvmtiEventController.hpp
+-jvmtiEnvBase.hpp                        jvmtiThreadState.hpp
+-jvmtiEnvBase.hpp                        thread.hpp
+-jvmtiEnvBase.hpp                        vm_operations.hpp
+-
+-jvmtiEnvThreadState.cpp                 handles.hpp
+-jvmtiEnvThreadState.cpp                 handles.inline.hpp
+-jvmtiEnvThreadState.cpp                 interfaceSupport.hpp
+-jvmtiEnvThreadState.cpp                 interpreter.hpp
+-jvmtiEnvThreadState.cpp                 javaCalls.hpp
+-jvmtiEnvThreadState.cpp                 jvmtiEnv.hpp
+-jvmtiEnvThreadState.cpp                 jvmtiEnvThreadState.hpp
+-jvmtiEnvThreadState.cpp                 jvmtiEventController.inline.hpp
+-jvmtiEnvThreadState.cpp                 jvmtiImpl.hpp
+-jvmtiEnvThreadState.cpp                 resourceArea.hpp
+-jvmtiEnvThreadState.cpp                 signature.hpp
+-jvmtiEnvThreadState.cpp                 systemDictionary.hpp
+-jvmtiEnvThreadState.cpp                 vframe.hpp
+-jvmtiEnvThreadState.cpp                 vm_operations.hpp
+-
+-jvmtiEnvThreadState.hpp                 allocation.hpp
+-jvmtiEnvThreadState.hpp                 allocation.inline.hpp
+-jvmtiEnvThreadState.hpp                 globalDefinitions.hpp
+-jvmtiEnvThreadState.hpp                 growableArray.hpp
+-jvmtiEnvThreadState.hpp                 instanceKlass.hpp
+-jvmtiEnvThreadState.hpp                 jvmti.h
+-jvmtiEnvThreadState.hpp                 jvmtiEventController.hpp
+-
+-jvmtiEventController.cpp                frame.hpp
+-jvmtiEventController.cpp                interpreter.hpp
+-jvmtiEventController.cpp                jvmtiEnv.hpp
+-jvmtiEventController.cpp                jvmtiEventController.hpp
+-jvmtiEventController.cpp                jvmtiEventController.inline.hpp
+-jvmtiEventController.cpp                jvmtiExport.hpp
+-jvmtiEventController.cpp                jvmtiImpl.hpp
+-jvmtiEventController.cpp                jvmtiThreadState.inline.hpp
+-jvmtiEventController.cpp                resourceArea.hpp
+-jvmtiEventController.cpp                thread.hpp
+-jvmtiEventController.cpp                vframe.hpp
+-jvmtiEventController.cpp                vframe_hp.hpp
+-jvmtiEventController.cpp                vmThread.hpp
+-jvmtiEventController.cpp                vm_operations.hpp
+-
+-jvmtiEventController.hpp                allocation.hpp
+-jvmtiEventController.hpp                allocation.inline.hpp
+-jvmtiEventController.hpp                globalDefinitions.hpp
+-jvmtiEventController.hpp                jvmti.h
+-
+-jvmtiEventController.inline.hpp         jvmtiEventController.hpp
+-jvmtiEventController.inline.hpp         jvmtiImpl.hpp
+-
+-jvmtiExport.cpp                         arguments.hpp
+-jvmtiExport.cpp                         attachListener.hpp
+-jvmtiExport.cpp                         handles.hpp
+-jvmtiExport.cpp                         interfaceSupport.hpp
+-jvmtiExport.cpp                         interpreter.hpp
+-jvmtiExport.cpp                         jvmtiCodeBlobEvents.hpp
+-jvmtiExport.cpp                         jvmtiEventController.hpp
+-jvmtiExport.cpp                         jvmtiEventController.inline.hpp
+-jvmtiExport.cpp                         jvmtiExport.hpp
+-jvmtiExport.cpp                         jvmtiImpl.hpp
+-jvmtiExport.cpp                         jvmtiManageCapabilities.hpp
+-jvmtiExport.cpp                         jvmtiTagMap.hpp
+-jvmtiExport.cpp                         jvmtiThreadState.inline.hpp
+-jvmtiExport.cpp                         nmethod.hpp
+-jvmtiExport.cpp                         objArrayKlass.hpp
+-jvmtiExport.cpp                         objArrayOop.hpp
+-jvmtiExport.cpp                         objectMonitor.inline.hpp
+-jvmtiExport.cpp                         pcDesc.hpp
+-jvmtiExport.cpp                         resourceArea.hpp
+-jvmtiExport.cpp                         scopeDesc.hpp
+-jvmtiExport.cpp                         serviceUtil.hpp
+-jvmtiExport.cpp                         systemDictionary.hpp
+-jvmtiExport.cpp                         thread.hpp
+-jvmtiExport.cpp                         vframe.hpp
+-
+ jvmtiExport.hpp                         allocation.hpp
+ jvmtiExport.hpp                         globalDefinitions.hpp
+ jvmtiExport.hpp                         growableArray.hpp
+@@ -2671,113 +2454,6 @@
+ jvmtiExport.hpp                         oop.hpp
+ jvmtiExport.hpp                         oopsHierarchy.hpp
+ 
+-jvmtiExtensions.cpp                     jvmtiExport.hpp
+-jvmtiExtensions.cpp                     jvmtiExtensions.hpp
+-
+-jvmtiExtensions.hpp                     allocation.hpp
+-jvmtiExtensions.hpp                     jvmti.h
+-jvmtiExtensions.hpp                     jvmtiEnv.hpp
+-
+-jvmtiGetLoadedClasses.cpp               jvmtiGetLoadedClasses.hpp
+-jvmtiGetLoadedClasses.cpp               systemDictionary.hpp
+-jvmtiGetLoadedClasses.cpp               thread.hpp
+-jvmtiGetLoadedClasses.cpp               universe.inline.hpp
+-
+-jvmtiGetLoadedClasses.hpp               jvmtiEnv.hpp
+-
+-jvmtiImpl.cpp                           exceptions.hpp
+-jvmtiImpl.cpp                           handles.hpp
+-jvmtiImpl.cpp                           handles.inline.hpp
+-jvmtiImpl.cpp                           instanceKlass.hpp
+-jvmtiImpl.cpp                           interfaceSupport.hpp
+-jvmtiImpl.cpp                           interpreter.hpp
+-jvmtiImpl.cpp                           javaCalls.hpp
+-jvmtiImpl.cpp                           jvmtiAgentThread.hpp
+-jvmtiImpl.cpp                           jvmtiEnv.hpp
+-jvmtiImpl.cpp                           jvmtiEventController.inline.hpp
+-jvmtiImpl.cpp                           jvmtiImpl.hpp
+-jvmtiImpl.cpp                           jvmtiRedefineClasses.hpp
+-jvmtiImpl.cpp                           resourceArea.hpp
+-jvmtiImpl.cpp                           signature.hpp
+-jvmtiImpl.cpp                           systemDictionary.hpp
+-jvmtiImpl.cpp                           thread_<os_family>.inline.hpp
+-jvmtiImpl.cpp                           vframe.hpp
+-jvmtiImpl.cpp                           vframe_hp.hpp
+-jvmtiImpl.cpp                           vm_operations.hpp
+-
+-jvmtiImpl.hpp                           jvmti.h
+-jvmtiImpl.hpp                           jvmtiEnvThreadState.hpp
+-jvmtiImpl.hpp                           jvmtiEventController.hpp
+-jvmtiImpl.hpp                           objArrayOop.hpp
+-jvmtiImpl.hpp                           stackValueCollection.hpp
+-jvmtiImpl.hpp                           systemDictionary.hpp
+-jvmtiImpl.hpp                           vm_operations.hpp
+-
+-jvmtiManageCapabilities.cpp             jvmtiEnv.hpp
+-jvmtiManageCapabilities.cpp             jvmtiExport.hpp
+-jvmtiManageCapabilities.cpp             jvmtiManageCapabilities.hpp
+-
+-jvmtiManageCapabilities.hpp             allocation.hpp
+-jvmtiManageCapabilities.hpp             jvmti.h
+-
+-jvmtiRedefineClasses.cpp                codeCache.hpp
+-jvmtiRedefineClasses.cpp                deoptimization.hpp
+-jvmtiRedefineClasses.cpp                gcLocker.hpp
+-jvmtiRedefineClasses.cpp                jvmtiImpl.hpp
+-jvmtiRedefineClasses.cpp                jvmtiRedefineClasses.hpp
+-jvmtiRedefineClasses.cpp                klassVtable.hpp
+-jvmtiRedefineClasses.cpp                methodComparator.hpp
+-jvmtiRedefineClasses.cpp                oopMapCache.hpp
+-jvmtiRedefineClasses.cpp                relocator.hpp
+-jvmtiRedefineClasses.cpp                rewriter.hpp
+-jvmtiRedefineClasses.cpp                systemDictionary.hpp
+-jvmtiRedefineClasses.cpp                universe.inline.hpp
+-jvmtiRedefineClasses.cpp                verifier.hpp
+-
+-jvmtiRedefineClasses.hpp                jvmtiEnv.hpp
+-jvmtiRedefineClasses.hpp                objArrayKlass.hpp
+-jvmtiRedefineClasses.hpp                objArrayOop.hpp
+-jvmtiRedefineClasses.hpp                oopFactory.hpp
+-jvmtiRedefineClasses.hpp                resourceArea.hpp
+-jvmtiRedefineClasses.hpp                vm_operations.hpp
+-
+-jvmtiTagMap.cpp                         biasedLocking.hpp
+-jvmtiTagMap.cpp                         javaCalls.hpp
+-jvmtiTagMap.cpp                         jniHandles.hpp
+-jvmtiTagMap.cpp                         jvmtiEnv.hpp
+-jvmtiTagMap.cpp                         jvmtiEventController.hpp
+-jvmtiTagMap.cpp                         jvmtiEventController.inline.hpp
+-jvmtiTagMap.cpp                         jvmtiExport.hpp
+-jvmtiTagMap.cpp                         jvmtiImpl.hpp
+-jvmtiTagMap.cpp                         jvmtiTagMap.hpp
+-jvmtiTagMap.cpp                         mutex.hpp
+-jvmtiTagMap.cpp                         mutexLocker.hpp
+-jvmtiTagMap.cpp                         objArrayKlass.hpp
+-jvmtiTagMap.cpp                         oop.inline2.hpp
+-jvmtiTagMap.cpp                         reflectionUtils.hpp
+-jvmtiTagMap.cpp                         serviceUtil.hpp
+-jvmtiTagMap.cpp                         symbolTable.hpp
+-jvmtiTagMap.cpp                         systemDictionary.hpp
+-jvmtiTagMap.cpp                         vframe.hpp
+-jvmtiTagMap.cpp                         vmSymbols.hpp
+-jvmtiTagMap.cpp                         vmThread.hpp
+-jvmtiTagMap.cpp                         vm_operations.hpp
+-
+-jvmtiTagMap.hpp                         allocation.hpp
+-jvmtiTagMap.hpp                         collectedHeap.hpp
+-jvmtiTagMap.hpp                         genCollectedHeap.hpp
+-jvmtiTagMap.hpp                         jvmti.h
+-jvmtiTagMap.hpp                         jvmtiEnv.hpp
+-jvmtiTagMap.hpp                         universe.hpp
+-
+-jvmtiThreadState.cpp                    gcLocker.hpp
+-jvmtiThreadState.cpp                    jvmtiEnv.hpp
+-jvmtiThreadState.cpp                    jvmtiEventController.inline.hpp
+-jvmtiThreadState.cpp                    jvmtiImpl.hpp
+-jvmtiThreadState.cpp                    jvmtiThreadState.inline.hpp
+-jvmtiThreadState.cpp                    resourceArea.hpp
+-jvmtiThreadState.cpp                    vframe.hpp
+-
+ jvmtiThreadState.hpp                    allocation.hpp
+ jvmtiThreadState.hpp                    allocation.inline.hpp
+ jvmtiThreadState.hpp                    growableArray.hpp
+@@ -2785,9 +2461,6 @@
+ jvmtiThreadState.hpp                    jvmtiEventController.hpp
+ jvmtiThreadState.hpp                    thread.hpp
+ 
+-jvmtiThreadState.inline.hpp             jvmtiEnvThreadState.hpp
+-jvmtiThreadState.inline.hpp             jvmtiThreadState.hpp
+-
+ klass.cpp                               atomic.hpp
+ klass.cpp                               collectedHeap.inline.hpp
+ klass.cpp                               instanceKlass.hpp
+@@ -2844,7 +2517,7 @@
+ klassVtable.cpp                         gcLocker.hpp
+ klassVtable.cpp                         handles.inline.hpp
+ klassVtable.cpp                         instanceKlass.hpp
+-klassVtable.cpp                         jvmtiRedefineClasses.hpp
++klassVtable.cpp                         jvmtiRedefineClassesTrace.hpp
+ klassVtable.cpp                         klassOop.hpp
+ klassVtable.cpp                         klassVtable.hpp
+ klassVtable.cpp                         markSweep.hpp
+@@ -3046,7 +2719,7 @@
+ 
+ methodComparator.cpp                    globalDefinitions.hpp
+ methodComparator.cpp                    handles.inline.hpp
+-methodComparator.cpp                    jvmtiRedefineClasses.hpp
++methodComparator.cpp                    jvmtiRedefineClassesTrace.hpp
+ methodComparator.cpp                    methodComparator.hpp
+ methodComparator.cpp                    oop.inline.hpp
+ methodComparator.cpp                    symbolOop.hpp
+@@ -3193,7 +2866,7 @@
+ mutex_<os_family>.inline.hpp            os_<os_family>.inline.hpp
+ mutex_<os_family>.inline.hpp            thread_<os_family>.inline.hpp
+ 
+-nativeInst_<arch>.cpp                   assembler_<arch>.inline.hpp
++nativeInst_<arch>.cpp                   assembler_<arch_model>.inline.hpp
+ nativeInst_<arch>.cpp                   handles.hpp
+ nativeInst_<arch>.cpp                   nativeInst_<arch>.hpp
+ nativeInst_<arch>.cpp                   oop.hpp
+@@ -3240,7 +2913,7 @@
+ nmethod.cpp                             disassembler_<arch>.hpp
+ nmethod.cpp                             dtrace.hpp
+ nmethod.cpp                             events.hpp
+-nmethod.cpp                             jvmtiRedefineClasses.hpp
++nmethod.cpp                             jvmtiRedefineClassesTrace.hpp
+ nmethod.cpp                             methodDataOop.hpp
+ nmethod.cpp                             nmethod.hpp
+ nmethod.cpp                             scopeDesc.hpp
+@@ -3395,7 +3068,6 @@
+ 
+ oopMapCache.cpp                         allocation.inline.hpp
+ oopMapCache.cpp                         handles.inline.hpp
+-oopMapCache.cpp                         jvmtiRedefineClasses.hpp
+ oopMapCache.cpp                         oop.inline.hpp
+ oopMapCache.cpp                         oopMapCache.hpp
+ oopMapCache.cpp                         resourceArea.hpp
+@@ -3459,7 +3131,7 @@
+ 
+ os_<os_arch>.cpp                        allocation.inline.hpp
+ os_<os_arch>.cpp                        arguments.hpp
+-os_<os_arch>.cpp                        assembler_<arch>.inline.hpp
++os_<os_arch>.cpp                        assembler_<arch_model>.inline.hpp
+ os_<os_arch>.cpp                        classLoader.hpp
+ os_<os_arch>.cpp                        events.hpp
+ os_<os_arch>.cpp                        extendedPC.hpp
+@@ -3467,7 +3139,7 @@
+ os_<os_arch>.cpp                        hpi.hpp
+ os_<os_arch>.cpp                        icBuffer.hpp
+ os_<os_arch>.cpp                        interfaceSupport.hpp
+-os_<os_arch>.cpp                        interpreter_<arch>.hpp
++os_<os_arch>.cpp                        interpreter.hpp
+ os_<os_arch>.cpp                        java.hpp
+ os_<os_arch>.cpp                        javaCalls.hpp
+ os_<os_arch>.cpp                        jniFastGetField.hpp
+@@ -3493,7 +3165,7 @@
+ 
+ os_<os_family>.cpp                      allocation.inline.hpp
+ os_<os_family>.cpp                      arguments.hpp
+-os_<os_family>.cpp                      assembler_<arch>.inline.hpp
++os_<os_family>.cpp                      assembler_<arch_model>.inline.hpp
+ os_<os_family>.cpp                      attachListener.hpp
+ os_<os_family>.cpp                      classLoader.hpp
+ os_<os_family>.cpp                      compileBroker.hpp
+@@ -3505,7 +3177,7 @@
+ os_<os_family>.cpp                      hpi.hpp
+ os_<os_family>.cpp                      icBuffer.hpp
+ os_<os_family>.cpp                      interfaceSupport.hpp
+-os_<os_family>.cpp                      interpreter_<arch>.hpp
++os_<os_family>.cpp                      interpreter.hpp
+ os_<os_family>.cpp                      java.hpp
+ os_<os_family>.cpp                      javaCalls.hpp
+ os_<os_family>.cpp                      jniFastGetField.hpp
+@@ -3551,7 +3223,7 @@
+ osThread.hpp                            objectMonitor.hpp
+ osThread.hpp                            top.hpp
+ 
+-osThread_<os_family>.cpp                assembler_<arch>.inline.hpp
++osThread_<os_family>.cpp                assembler_<arch_model>.inline.hpp
+ osThread_<os_family>.cpp                atomic.hpp
+ osThread_<os_family>.cpp                handles.inline.hpp
+ osThread_<os_family>.cpp                mutexLocker.hpp
+@@ -3568,6 +3240,8 @@
+ ostream.cpp                             defaultStream.hpp
+ ostream.cpp                             oop.inline.hpp
+ ostream.cpp                             os_<os_family>.inline.hpp
++ostream.cpp                             hpi.hpp
++ostream.cpp                             hpi_<os_family>.hpp
+ ostream.cpp                             ostream.hpp
+ ostream.cpp                             top.hpp
+ ostream.cpp                             xmlstream.hpp
+@@ -3745,7 +3419,7 @@
+ register_<arch>.cpp                     register_<arch>.hpp
+ 
+ register_<arch>.hpp                     register.hpp
+-register_<arch>.hpp                     vm_version_<arch>.hpp
++register_<arch>.hpp                     vm_version_<arch_model>.hpp
+ 
+ registerMap.hpp                         globalDefinitions.hpp
+ registerMap.hpp                         register_<arch>.hpp
+@@ -3754,11 +3428,11 @@
+ registerMap_<arch>.hpp                  generate_platform_dependent_include
+ 
+ register_definitions_<arch>.cpp         assembler.hpp
+-register_definitions_<arch>.cpp         interp_masm_<arch>.hpp
++register_definitions_<arch>.cpp         interp_masm_<arch_model>.hpp
+ register_definitions_<arch>.cpp         register.hpp
+ register_definitions_<arch>.cpp         register_<arch>.hpp
+ 
+-relocInfo.cpp                           assembler_<arch>.inline.hpp
++relocInfo.cpp                           assembler_<arch_model>.inline.hpp
+ relocInfo.cpp                           compiledIC.hpp
+ relocInfo.cpp                           copy.hpp
+ relocInfo.cpp                           nativeInst_<arch>.hpp
+@@ -3771,7 +3445,7 @@
+ relocInfo.hpp                           top.hpp
+ 
+ relocInfo_<arch>.cpp                    assembler.inline.hpp
+-relocInfo_<arch>.cpp                    assembler_<arch>.inline.hpp
++relocInfo_<arch>.cpp                    assembler_<arch_model>.inline.hpp
+ relocInfo_<arch>.cpp                    nativeInst_<arch>.hpp
+ relocInfo_<arch>.cpp                    relocInfo.hpp
+ relocInfo_<arch>.cpp                    safepoint.hpp
+@@ -3806,11 +3480,7 @@
+ resourceArea.hpp                        allocation.hpp
+ resourceArea.hpp                        thread_<os_family>.inline.hpp
+ 
+-restore.cpp                             filemap.hpp
+-restore.cpp                             hashtable.inline.hpp
+-restore.cpp                             oop.inline.hpp
+-restore.cpp                             symbolTable.hpp
+-restore.cpp                             systemDictionary.hpp
++// restore is jck optional, put cpp deps in includeDB_features
+ 
+ rewriter.cpp                            bytecodes.hpp
+ rewriter.cpp                            gcLocker.hpp
+@@ -3827,7 +3497,7 @@
+ rewriter.hpp                            handles.inline.hpp
+ 
+ rframe.cpp                              frame.inline.hpp
+-rframe.cpp                              interpreter_<arch>.hpp
++rframe.cpp                              interpreter.hpp
+ rframe.cpp                              oop.inline.hpp
+ rframe.cpp                              rframe.hpp
+ rframe.cpp                              symbolOop.hpp
+@@ -3855,7 +3525,6 @@
+ safepoint.cpp                           icBuffer.hpp
+ safepoint.cpp                           interfaceSupport.hpp
+ safepoint.cpp                           interpreter.hpp
+-safepoint.cpp                           interpreter_<arch>.hpp
+ safepoint.cpp                           mutexLocker.hpp
+ safepoint.cpp                           nativeInst_<arch>.hpp
+ safepoint.cpp                           nmethod.hpp
+@@ -3896,15 +3565,7 @@
+ scopeDesc.hpp                           methodOop.hpp
+ scopeDesc.hpp                           pcDesc.hpp
+ 
+-serialize.cpp                           classify.hpp
+-serialize.cpp                           codeCache.hpp
+-serialize.cpp                           compactingPermGenGen.hpp
+-serialize.cpp                           compiledICHolderOop.hpp
+-serialize.cpp                           methodDataOop.hpp
+-serialize.cpp                           objArrayOop.hpp
+-serialize.cpp                           oop.hpp
+-serialize.cpp                           symbolTable.hpp
+-serialize.cpp                           systemDictionary.hpp
++// serialize is jck optional, put cpp deps in includeDB_features
+ 
+ serviceUtil.hpp                         objArrayOop.hpp
+ serviceUtil.hpp                         systemDictionary.hpp
+@@ -3939,7 +3600,7 @@
+ sharedRuntime.cpp                       init.hpp
+ sharedRuntime.cpp                       interfaceSupport.hpp
+ sharedRuntime.cpp                       interpreterRuntime.hpp
+-sharedRuntime.cpp                       interpreter_<arch>.hpp
++sharedRuntime.cpp                       interpreter.hpp
+ sharedRuntime.cpp                       javaCalls.hpp
+ sharedRuntime.cpp                       jvmtiExport.hpp
+ sharedRuntime.cpp                       nativeInst_<arch>.hpp
+@@ -3965,17 +3626,16 @@
+ sharedRuntime.hpp                       resourceArea.hpp
+ sharedRuntime.hpp                       threadLocalStorage.hpp
+ 
+-sharedRuntime_<arch>.cpp                assembler.hpp
+-sharedRuntime_<arch>.cpp                assembler_<arch>.inline.hpp
+-sharedRuntime_<arch>.cpp                compiledICHolderOop.hpp
+-sharedRuntime_<arch>.cpp                debugInfoRec.hpp
+-sharedRuntime_<arch>.cpp                icBuffer.hpp
+-sharedRuntime_<arch>.cpp                interpreter.hpp
+-sharedRuntime_<arch>.cpp                interpreter_<arch>.hpp
+-sharedRuntime_<arch>.cpp                sharedRuntime.hpp
+-sharedRuntime_<arch>.cpp                vframeArray.hpp
+-sharedRuntime_<arch>.cpp                vmreg_<arch>.inline.hpp
+-sharedRuntime_<arch>.cpp                vtableStubs.hpp
++sharedRuntime_<arch_model>.cpp          assembler.hpp
++sharedRuntime_<arch_model>.cpp          assembler_<arch_model>.inline.hpp
++sharedRuntime_<arch_model>.cpp          compiledICHolderOop.hpp
++sharedRuntime_<arch_model>.cpp          debugInfoRec.hpp
++sharedRuntime_<arch_model>.cpp          icBuffer.hpp
++sharedRuntime_<arch_model>.cpp          interpreter.hpp
++sharedRuntime_<arch_model>.cpp          sharedRuntime.hpp
++sharedRuntime_<arch_model>.cpp          vframeArray.hpp
++sharedRuntime_<arch_model>.cpp          vmreg_<arch>.inline.hpp
++sharedRuntime_<arch_model>.cpp          vtableStubs.hpp
+ 
+ sharedRuntimeTrans.cpp                  interfaceSupport.hpp
+ sharedRuntimeTrans.cpp                  jni.h
+@@ -4070,11 +3730,14 @@
+ stackMapTable.hpp                       methodOop.hpp
+ stackMapTable.hpp                       stackMapFrame.hpp
+ 
++stackValue.cpp                          debugInfo.hpp
++stackValue.cpp                          frame.inline.hpp
+ stackValue.cpp                          handles.inline.hpp
+ stackValue.cpp                          oop.hpp
+ stackValue.cpp                          stackValue.hpp
+ 
+ stackValue.hpp                          handles.hpp
++stackValue.hpp                          location.hpp
+ stackValue.hpp                          top.hpp
+ 
+ stackValueCollection.cpp                jniTypes_<arch>.hpp
+@@ -4094,12 +3757,12 @@
+ statSampler.cpp                         statSampler.hpp
+ statSampler.cpp                         systemDictionary.hpp
+ statSampler.cpp                         vmSymbols.hpp
+-statSampler.cpp                         vm_version_<arch>.hpp
++statSampler.cpp                         vm_version_<arch_model>.hpp
+ 
+ statSampler.hpp                         perfData.hpp
+ statSampler.hpp                         task.hpp
+ 
+-stubCodeGenerator.cpp                   assembler_<arch>.inline.hpp
++stubCodeGenerator.cpp                   assembler_<arch_model>.inline.hpp
+ stubCodeGenerator.cpp                   disassembler_<arch>.hpp
+ stubCodeGenerator.cpp                   forte.hpp
+ stubCodeGenerator.cpp                   oop.inline.hpp
+@@ -4109,20 +3772,21 @@
+ stubCodeGenerator.hpp                   allocation.hpp
+ stubCodeGenerator.hpp                   assembler.hpp
+ 
+-stubGenerator_<arch>.cpp                assembler.hpp
+-stubGenerator_<arch>.cpp                assembler_<arch>.inline.hpp
+-stubGenerator_<arch>.cpp                handles.inline.hpp
+-stubGenerator_<arch>.cpp                instanceOop.hpp
+-stubGenerator_<arch>.cpp                interpreter_<arch>.hpp
+-stubGenerator_<arch>.cpp                methodOop.hpp
+-stubGenerator_<arch>.cpp                nativeInst_<arch>.hpp
+-stubGenerator_<arch>.cpp                objArrayKlass.hpp
+-stubGenerator_<arch>.cpp                oop.inline.hpp
+-stubGenerator_<arch>.cpp                sharedRuntime.hpp
+-stubGenerator_<arch>.cpp                stubCodeGenerator.hpp
+-stubGenerator_<arch>.cpp                stubRoutines.hpp
+-stubGenerator_<arch>.cpp                thread_<os_family>.inline.hpp
+-stubGenerator_<arch>.cpp                top.hpp
++stubGenerator_<arch_model>.cpp          assembler.hpp
++stubGenerator_<arch_model>.cpp          assembler_<arch_model>.inline.hpp
++stubGenerator_<arch_model>.cpp          frame.inline.hpp
++stubGenerator_<arch_model>.cpp          handles.inline.hpp
++stubGenerator_<arch_model>.cpp          instanceOop.hpp
++stubGenerator_<arch_model>.cpp          interpreter.hpp
++stubGenerator_<arch_model>.cpp          methodOop.hpp
++stubGenerator_<arch_model>.cpp          nativeInst_<arch>.hpp
++stubGenerator_<arch_model>.cpp          objArrayKlass.hpp
++stubGenerator_<arch_model>.cpp          oop.inline.hpp
++stubGenerator_<arch_model>.cpp          sharedRuntime.hpp
++stubGenerator_<arch_model>.cpp          stubCodeGenerator.hpp
++stubGenerator_<arch_model>.cpp          stubRoutines.hpp
++stubGenerator_<arch_model>.cpp          thread_<os_family>.inline.hpp
++stubGenerator_<arch_model>.cpp          top.hpp
+ 
+ stubRoutines.cpp                        codeBuffer.hpp
+ stubRoutines.cpp                        copy.hpp
+@@ -4141,12 +3805,12 @@
+ stubRoutines.hpp                        stubCodeGenerator.hpp
+ stubRoutines.hpp                        top.hpp
+ 
+-stubRoutines_<arch>.cpp                 deoptimization.hpp
+-stubRoutines_<arch>.cpp                 frame.inline.hpp
+-stubRoutines_<arch>.cpp                 stubRoutines.hpp
+-stubRoutines_<arch>.cpp                 thread_<os_family>.inline.hpp
++stubRoutines_<arch_model>.cpp           deoptimization.hpp
++stubRoutines_<arch_model>.cpp           frame.inline.hpp
++stubRoutines_<arch_model>.cpp           stubRoutines.hpp
++stubRoutines_<arch_model>.cpp           thread_<os_family>.inline.hpp
+ 
+-stubRoutines_<arch>.hpp                 generate_platform_dependent_include
++stubRoutines_<arch_model>.hpp           generate_platform_dependent_include
+ 
+ stubRoutines_<os_family>.cpp            os.hpp
+ stubRoutines_<os_family>.cpp            stubRoutines.hpp
+@@ -4283,26 +3947,60 @@
+ taskqueue.hpp                           mutex.hpp
+ taskqueue.hpp                           orderAccess_<os_arch>.inline.hpp
+ 
++templateInterpreter.cpp                 interpreter.hpp
++templateInterpreter.cpp                 interpreterGenerator.hpp
++templateInterpreter.cpp                 interpreterRuntime.hpp
++templateInterpreter.cpp                 templateTable.hpp
++
++templateInterpreter.hpp                 abstractInterpreter.hpp
++templateInterpreter.hpp                 templateTable.hpp
++
++templateInterpreter_<arch_model>.cpp    arguments.hpp
++templateInterpreter_<arch_model>.cpp    arrayOop.hpp
++templateInterpreter_<arch_model>.cpp    assembler.hpp
++templateInterpreter_<arch_model>.cpp    bytecodeHistogram.hpp
++templateInterpreter_<arch_model>.cpp    debug.hpp
++templateInterpreter_<arch_model>.cpp    deoptimization.hpp
++templateInterpreter_<arch_model>.cpp    frame.inline.hpp
++templateInterpreter_<arch_model>.cpp    interpreterRuntime.hpp
++templateInterpreter_<arch_model>.cpp    interpreter.hpp
++templateInterpreter_<arch_model>.cpp    interpreterGenerator.hpp
++templateInterpreter_<arch_model>.cpp    jvmtiExport.hpp
++templateInterpreter_<arch_model>.cpp    jvmtiThreadState.hpp
++templateInterpreter_<arch_model>.cpp    methodDataOop.hpp
++templateInterpreter_<arch_model>.cpp    methodOop.hpp
++templateInterpreter_<arch_model>.cpp    oop.inline.hpp
++templateInterpreter_<arch_model>.cpp    sharedRuntime.hpp
++templateInterpreter_<arch_model>.cpp    stubRoutines.hpp
++templateInterpreter_<arch_model>.cpp    synchronizer.hpp
++templateInterpreter_<arch_model>.cpp    templateTable.hpp
++templateInterpreter_<arch_model>.cpp    timer.hpp
++templateInterpreter_<arch_model>.cpp    vframeArray.hpp
++
++templateInterpreter_<arch>.hpp          generate_platform_dependent_include
++
++templateInterpreterGenerator_<arch>.hpp generate_platform_dependent_include
++
+ templateTable.cpp                       templateTable.hpp
+ templateTable.cpp                       timer.hpp
+ 
+ templateTable.hpp                       allocation.hpp
+ templateTable.hpp                       bytecodes.hpp
+ templateTable.hpp                       frame.hpp
+-templateTable.hpp                       interp_masm_<arch>.hpp
++templateTable.hpp                       interp_masm_<arch_model>.hpp
+ 
+-templateTable_<arch>.cpp                interpreterRuntime.hpp
+-templateTable_<arch>.cpp                interpreter_<arch>.hpp
+-templateTable_<arch>.cpp                methodDataOop.hpp
+-templateTable_<arch>.cpp                objArrayKlass.hpp
+-templateTable_<arch>.cpp                oop.inline.hpp
+-templateTable_<arch>.cpp                sharedRuntime.hpp
+-templateTable_<arch>.cpp                stubRoutines.hpp
+-templateTable_<arch>.cpp                synchronizer.hpp
+-templateTable_<arch>.cpp                templateTable.hpp
+-templateTable_<arch>.cpp                universe.inline.hpp
++templateTable_<arch_model>.cpp          interpreterRuntime.hpp
++templateTable_<arch_model>.cpp          interpreter.hpp
++templateTable_<arch_model>.cpp          methodDataOop.hpp
++templateTable_<arch_model>.cpp          objArrayKlass.hpp
++templateTable_<arch_model>.cpp          oop.inline.hpp
++templateTable_<arch_model>.cpp          sharedRuntime.hpp
++templateTable_<arch_model>.cpp          stubRoutines.hpp
++templateTable_<arch_model>.cpp          synchronizer.hpp
++templateTable_<arch_model>.cpp          templateTable.hpp
++templateTable_<arch_model>.cpp          universe.inline.hpp
+ 
+-templateTable_<arch>.hpp                generate_platform_dependent_include
++templateTable_<arch_model>.hpp          generate_platform_dependent_include
+ 
+ tenuredGeneration.cpp                   allocation.inline.hpp
+ tenuredGeneration.cpp                   blockOffsetTable.inline.hpp
+@@ -4338,7 +4036,7 @@
+ thread.cpp                              instanceKlass.hpp
+ thread.cpp                              interfaceSupport.hpp
+ thread.cpp                              interpreter.hpp
+-thread.cpp                              interpreter_<arch>.hpp
++thread.cpp                              interpreter.hpp
+ thread.cpp                              java.hpp
+ thread.cpp                              javaCalls.hpp
+ thread.cpp                              javaClasses.hpp
+@@ -4541,6 +4239,7 @@
+ universe.cpp                            cpCacheKlass.hpp
+ universe.cpp                            cpCacheOop.hpp
+ universe.cpp                            deoptimization.hpp
++universe.cpp                            dependencies.hpp
+ universe.cpp                            events.hpp
+ universe.cpp                            filemap.hpp
+ universe.cpp                            fprofiler.hpp
+@@ -4553,11 +4252,11 @@
+ universe.cpp                            instanceKlass.hpp
+ universe.cpp                            instanceKlassKlass.hpp
+ universe.cpp                            instanceRefKlass.hpp
+-universe.cpp                            interpreter_<arch>.hpp
++universe.cpp                            interpreter.hpp
+ universe.cpp                            java.hpp
+ universe.cpp                            javaCalls.hpp
+ universe.cpp                            javaClasses.hpp
+-universe.cpp                            jvmtiRedefineClasses.hpp
++universe.cpp                            jvmtiRedefineClassesTrace.hpp
+ universe.cpp                            klassKlass.hpp
+ universe.cpp                            klassOop.hpp
+ universe.cpp                            memoryService.hpp
+@@ -4650,7 +4349,7 @@
+ vframe.cpp                              debugInfoRec.hpp
+ vframe.cpp                              handles.inline.hpp
+ vframe.cpp                              instanceKlass.hpp
+-vframe.cpp                              interpreter_<arch>.hpp
++vframe.cpp                              interpreter.hpp
+ vframe.cpp                              javaClasses.hpp
+ vframe.cpp                              nmethod.hpp
+ vframe.cpp                              objectMonitor.hpp
+@@ -4683,7 +4382,7 @@
+ vframeArray.cpp                         allocation.inline.hpp
+ vframeArray.cpp                         events.hpp
+ vframeArray.cpp                         handles.inline.hpp
+-vframeArray.cpp                         interpreter_<arch>.hpp
++vframeArray.cpp                         interpreter.hpp
+ vframeArray.cpp                         jvmtiThreadState.hpp
+ vframeArray.cpp                         methodDataOop.hpp
+ vframeArray.cpp                         monitorChunk.hpp
+@@ -4706,7 +4405,7 @@
+ vframe_hp.cpp                           debugInfoRec.hpp
+ vframe_hp.cpp                           handles.inline.hpp
+ vframe_hp.cpp                           instanceKlass.hpp
+-vframe_hp.cpp                           interpreter_<arch>.hpp
++vframe_hp.cpp                           interpreter.hpp
+ vframe_hp.cpp                           monitorChunk.hpp
+ vframe_hp.cpp                           nmethod.hpp
+ vframe_hp.cpp                           oop.inline.hpp
+@@ -4749,86 +4448,7 @@
+ vmError_<os_family>.cpp                 thread.hpp
+ vmError_<os_family>.cpp                 vmError.hpp
+ 
+-vmStructs.cpp                           arguments.hpp
+-vmStructs.cpp                           arrayKlass.hpp
+-vmStructs.cpp                           arrayKlassKlass.hpp
+-vmStructs.cpp                           arrayOop.hpp
+-vmStructs.cpp                           bytecodes.hpp
+-vmStructs.cpp                           cInterpreter.hpp
+-vmStructs.cpp                           cardTableRS.hpp
+-vmStructs.cpp                           codeBlob.hpp
+-vmStructs.cpp                           codeCache.hpp
+-vmStructs.cpp                           collectedHeap.hpp
+-vmStructs.cpp                           compactPermGen.hpp
+-vmStructs.cpp                           compiledICHolderKlass.hpp
+-vmStructs.cpp                           compiledICHolderOop.hpp
+-vmStructs.cpp                           compressedStream.hpp
+-vmStructs.cpp                           constMethodKlass.hpp
+-vmStructs.cpp                           constMethodOop.hpp
+-vmStructs.cpp                           constantPoolKlass.hpp
+-vmStructs.cpp                           constantPoolOop.hpp
+-vmStructs.cpp                           cpCacheKlass.hpp
+-vmStructs.cpp                           cpCacheOop.hpp
+-vmStructs.cpp                           defNewGeneration.hpp
+-vmStructs.cpp                           dictionary.hpp
+-vmStructs.cpp                           freeBlockDictionary.hpp
+-vmStructs.cpp                           genCollectedHeap.hpp
+-vmStructs.cpp                           generation.hpp
+-vmStructs.cpp                           generationSpec.hpp
+-vmStructs.cpp                           globalDefinitions.hpp
+-vmStructs.cpp                           globals.hpp
+-vmStructs.cpp                           hashtable.hpp
+-vmStructs.cpp                           heap.hpp
+-vmStructs.cpp                           immutableSpace.hpp
+-vmStructs.cpp                           instanceKlass.hpp
+-vmStructs.cpp                           instanceKlassKlass.hpp
+-vmStructs.cpp                           instanceOop.hpp
+-vmStructs.cpp                           interpreter.hpp
+-vmStructs.cpp                           java.hpp
+-vmStructs.cpp                           javaCalls.hpp
+-vmStructs.cpp                           javaClasses.hpp
+-vmStructs.cpp                           jvmtiAgentThread.hpp
+-vmStructs.cpp                           klass.hpp
+-vmStructs.cpp                           klassOop.hpp
+-vmStructs.cpp                           loaderConstraints.hpp
+-vmStructs.cpp                           location.hpp
+-vmStructs.cpp                           markOop.hpp
+-vmStructs.cpp                           markSweep.hpp
+-vmStructs.cpp                           methodDataKlass.hpp
+-vmStructs.cpp                           methodDataOop.hpp
+-vmStructs.cpp                           methodKlass.hpp
+-vmStructs.cpp                           methodOop.hpp
+-vmStructs.cpp                           mutableSpace.hpp
+-vmStructs.cpp                           nmethod.hpp
+-vmStructs.cpp                           objArrayKlass.hpp
+-vmStructs.cpp                           objArrayKlassKlass.hpp
+-vmStructs.cpp                           objArrayOop.hpp
+-vmStructs.cpp                           oop.hpp
+-vmStructs.cpp                           oopMap.hpp
+-vmStructs.cpp                           pcDesc.hpp
+-vmStructs.cpp                           perfMemory.hpp
+-vmStructs.cpp                           permGen.hpp
+-vmStructs.cpp                           placeholders.hpp
+-vmStructs.cpp                           sharedRuntime.hpp
+-vmStructs.cpp                           space.hpp
+-vmStructs.cpp                           stubRoutines.hpp
+-vmStructs.cpp                           stubs.hpp
+-vmStructs.cpp                           symbolKlass.hpp
+-vmStructs.cpp                           symbolOop.hpp
+-vmStructs.cpp                           symbolTable.hpp
+-vmStructs.cpp                           systemDictionary.hpp
+-vmStructs.cpp                           tenuredGeneration.hpp
+-vmStructs.cpp                           thread_<os_family>.inline.hpp
+-vmStructs.cpp                           typeArrayKlass.hpp
+-vmStructs.cpp                           typeArrayKlassKlass.hpp
+-vmStructs.cpp                           typeArrayOop.hpp
+-vmStructs.cpp                           universe.hpp
+-vmStructs.cpp                           virtualspace.hpp
+-vmStructs.cpp                           vmStructs.hpp
+-vmStructs.cpp                           vmStructs_<arch>.hpp
+-vmStructs.cpp                           vmStructs_<os_arch>.hpp
+-vmStructs.cpp                           vmreg.hpp
+-vmStructs.cpp                           watermark.hpp
++// vmStructs is jck optional, put cpp deps in includeDB_features
+ 
+ vmStructs.hpp                           debug.hpp
+ 
+@@ -4880,22 +4500,22 @@
+ vm_version.cpp                          arguments.hpp
+ vm_version.cpp                          oop.inline.hpp
+ vm_version.cpp                          universe.hpp
+-vm_version.cpp                          vm_version_<arch>.hpp
++vm_version.cpp                          vm_version_<arch_model>.hpp
+ 
+ vm_version.hpp                          allocation.hpp
+ vm_version.hpp                          ostream.hpp
+ 
+-vm_version_<arch>.cpp                   assembler_<arch>.inline.hpp
+-vm_version_<arch>.cpp                   java.hpp
+-vm_version_<arch>.cpp                   os_<os_family>.inline.hpp
+-vm_version_<arch>.cpp                   resourceArea.hpp
+-vm_version_<arch>.cpp                   stubCodeGenerator.hpp
+-vm_version_<arch>.cpp                   vm_version_<arch>.hpp
++vm_version_<arch_model>.cpp             assembler_<arch_model>.inline.hpp
++vm_version_<arch_model>.cpp             java.hpp
++vm_version_<arch_model>.cpp             os_<os_family>.inline.hpp
++vm_version_<arch_model>.cpp             resourceArea.hpp
++vm_version_<arch_model>.cpp             stubCodeGenerator.hpp
++vm_version_<arch_model>.cpp             vm_version_<arch_model>.hpp
+ 
+-vm_version_<arch>.hpp                   globals_extension.hpp
+-vm_version_<arch>.hpp                   vm_version.hpp
++vm_version_<arch_model>.hpp             globals_extension.hpp
++vm_version_<arch_model>.hpp             vm_version.hpp
+ 
+-vm_version_<os_arch>.cpp                vm_version_<arch>.hpp
++vm_version_<os_arch>.cpp                vm_version_<arch_model>.hpp
+ 
+ vmreg.cpp                               assembler.hpp
+ vmreg.cpp                               vmreg.hpp
+@@ -4924,19 +4544,19 @@
+ 
+ vtableStubs.hpp                         allocation.hpp
+ 
+-vtableStubs_<arch>.cpp                  assembler.hpp
+-vtableStubs_<arch>.cpp                  assembler_<arch>.inline.hpp
+-vtableStubs_<arch>.cpp                  instanceKlass.hpp
+-vtableStubs_<arch>.cpp                  interp_masm_<arch>.hpp
+-vtableStubs_<arch>.cpp                  klassVtable.hpp
+-vtableStubs_<arch>.cpp                  resourceArea.hpp
+-vtableStubs_<arch>.cpp                  sharedRuntime.hpp
+-vtableStubs_<arch>.cpp                  vmreg_<arch>.inline.hpp
+-vtableStubs_<arch>.cpp                  vtableStubs.hpp
++vtableStubs_<arch_model>.cpp            assembler.hpp
++vtableStubs_<arch_model>.cpp            assembler_<arch_model>.inline.hpp
++vtableStubs_<arch_model>.cpp            instanceKlass.hpp
++vtableStubs_<arch_model>.cpp            interp_masm_<arch_model>.hpp
++vtableStubs_<arch_model>.cpp            klassVtable.hpp
++vtableStubs_<arch_model>.cpp            resourceArea.hpp
++vtableStubs_<arch_model>.cpp            sharedRuntime.hpp
++vtableStubs_<arch_model>.cpp            vmreg_<arch>.inline.hpp
++vtableStubs_<arch_model>.cpp            vtableStubs.hpp
+ 
+ vtune.hpp                               allocation.hpp
+ 
+-vtune_<os_family>.cpp                   interpreter_<arch>.hpp
++vtune_<os_family>.cpp                   interpreter.hpp
+ vtune_<os_family>.cpp                   vtune.hpp
+ 
+ watermark.hpp                           allocation.hpp
+diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_coreonly openjdk/hotspot/src/share/vm/includeDB_coreonly
+--- openjdk6/hotspot/src/share/vm/includeDB_coreonly	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/includeDB_coreonly	1970-01-01 01:00:00.000000000 +0100
+@@ -1,26 +0,0 @@
+-//
+-// Copyright 2000-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+-// CA 95054 USA or visit www.sun.com if you need additional information or
+-// have any questions.
+-//  
+-//
+-
+-// NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps!
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_features openjdk/hotspot/src/share/vm/includeDB_features
+--- openjdk6/hotspot/src/share/vm/includeDB_features	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/includeDB_features	2007-12-14 08:57:02.000000000 +0100
+@@ -0,0 +1,319 @@
++//
++// Copyright 2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++// CA 95054 USA or visit www.sun.com if you need additional information or
++// have any questions.
++//  
++//
++
++attachListener.cpp                      arguments.hpp
++attachListener.cpp                      attachListener.hpp
++attachListener.cpp                      globals.hpp
++attachListener.cpp                      heapDumper.hpp
++attachListener.cpp                      java.hpp
++attachListener.cpp                      javaCalls.hpp
++attachListener.cpp                      javaClasses.hpp
++attachListener.cpp                      jvmtiExport.hpp
++attachListener.cpp                      os.hpp
++attachListener.cpp                      resourceArea.hpp
++attachListener.cpp                      systemDictionary.hpp
++attachListener.cpp                      vmGCOperations.hpp
++
++attachListener_<os_family>.cpp          attachListener.hpp
++attachListener_<os_family>.cpp          dtraceAttacher.hpp
++attachListener_<os_family>.cpp          interfaceSupport.hpp
++attachListener_<os_family>.cpp          os.hpp
++
++dump.cpp                                classify.hpp
++dump.cpp                                copy.hpp
++dump.cpp                                filemap.hpp
++dump.cpp                                javaCalls.hpp
++dump.cpp                                javaClasses.hpp
++dump.cpp                                loaderConstraints.hpp
++dump.cpp                                methodDataOop.hpp
++dump.cpp                                oop.hpp
++dump.cpp                                oopFactory.hpp
++dump.cpp                                resourceArea.hpp
++dump.cpp                                signature.hpp
++dump.cpp                                symbolTable.hpp
++dump.cpp                                systemDictionary.hpp
++dump.cpp                                vmThread.hpp
++dump.cpp                                vm_operations.hpp
++
++dump_<arch_model>.cpp                   assembler_<arch_model>.inline.hpp
++dump_<arch_model>.cpp                   compactingPermGenGen.hpp
++
++forte.cpp                               collectedHeap.inline.hpp
++forte.cpp                               debugInfoRec.hpp
++forte.cpp                               forte.hpp
++forte.cpp                               oop.inline.hpp
++forte.cpp                               oop.inline2.hpp
++forte.cpp                               pcDesc.hpp
++forte.cpp                               space.hpp
++forte.cpp                               thread.hpp
++forte.cpp                               universe.inline.hpp
++forte.cpp                               vframe.hpp
++forte.cpp                               vframeArray.hpp
++
++fprofiler.cpp                           allocation.inline.hpp
++fprofiler.cpp                           classLoader.hpp
++fprofiler.cpp                           collectedHeap.inline.hpp
++fprofiler.cpp                           deoptimization.hpp
++fprofiler.cpp                           fprofiler.hpp
++fprofiler.cpp                           interpreter.hpp
++fprofiler.cpp                           macros.hpp
++fprofiler.cpp                           mutexLocker.hpp
++fprofiler.cpp                           oop.inline.hpp
++fprofiler.cpp                           oop.inline2.hpp
++fprofiler.cpp                           stubCodeGenerator.hpp
++fprofiler.cpp                           stubRoutines.hpp
++fprofiler.cpp                           symbolOop.hpp
++fprofiler.cpp                           task.hpp
++fprofiler.cpp                           universe.inline.hpp
++fprofiler.cpp                           vframe.hpp
++fprofiler.cpp                           vtableStubs.hpp
++
++heapDumper.cpp                          genCollectedHeap.hpp
++heapDumper.cpp                          heapDumper.hpp 
++heapDumper.cpp                          javaCalls.hpp
++heapDumper.cpp                          jniHandles.hpp
++heapDumper.cpp                          objArrayKlass.hpp
++heapDumper.cpp                          ostream.hpp
++heapDumper.cpp                          reflectionUtils.hpp
++heapDumper.cpp                          symbolTable.hpp
++heapDumper.cpp                          systemDictionary.hpp
++heapDumper.cpp                          universe.hpp
++heapDumper.cpp                          vframe.hpp
++heapDumper.cpp                          vmGCOperations.hpp
++heapDumper.cpp                          vmSymbols.hpp
++heapDumper.cpp                          vmThread.hpp
++heapDumper.cpp                          vm_operations.hpp
++
++heapInspection.cpp                      collectedHeap.hpp
++heapInspection.cpp                      genCollectedHeap.hpp
++heapInspection.cpp                      globalDefinitions.hpp
++heapInspection.cpp                      heapInspection.hpp
++heapInspection.cpp                      klassOop.hpp
++heapInspection.cpp                      os.hpp
++heapInspection.cpp                      resourceArea.hpp
++
++jniCheck.cpp                            fieldDescriptor.hpp
++jniCheck.cpp                            handles.hpp
++jniCheck.cpp                            instanceKlass.hpp
++jniCheck.cpp                            interfaceSupport.hpp
++jniCheck.cpp                            jfieldIDWorkaround.hpp
++jniCheck.cpp                            jni.h
++jniCheck.cpp                            jniCheck.hpp
++jniCheck.cpp                            jniTypes_<arch>.hpp
++jniCheck.cpp                            jvm_misc.hpp
++jniCheck.cpp                            oop.inline.hpp
++jniCheck.cpp                            symbolOop.hpp
++jniCheck.cpp                            systemDictionary.hpp
++jniCheck.cpp                            thread.hpp
++jniCheck.cpp                            vmSymbols.hpp
++
++jvmtiCodeBlobEvents.cpp                 codeBlob.hpp
++jvmtiCodeBlobEvents.cpp                 codeCache.hpp
++jvmtiCodeBlobEvents.cpp                 handles.hpp
++jvmtiCodeBlobEvents.cpp                 handles.inline.hpp
++jvmtiCodeBlobEvents.cpp                 jvmtiCodeBlobEvents.hpp
++jvmtiCodeBlobEvents.cpp                 jvmtiExport.hpp
++jvmtiCodeBlobEvents.cpp                 oop.inline.hpp
++jvmtiCodeBlobEvents.cpp                 resourceArea.hpp
++jvmtiCodeBlobEvents.cpp                 scopeDesc.hpp
++jvmtiCodeBlobEvents.cpp                 vmThread.hpp
++
++jvmtiCodeBlobEvents.hpp                 jvmti.h
++
++jvmtiExtensions.cpp                     jvmtiExport.hpp
++jvmtiExtensions.cpp                     jvmtiExtensions.hpp
++
++jvmtiExtensions.hpp                     allocation.hpp
++jvmtiExtensions.hpp                     jvmti.h
++jvmtiExtensions.hpp                     jvmtiEnv.hpp
++
++jvmtiImpl.cpp                           exceptions.hpp
++jvmtiImpl.cpp                           handles.hpp
++jvmtiImpl.cpp                           handles.inline.hpp
++jvmtiImpl.cpp                           instanceKlass.hpp
++jvmtiImpl.cpp                           interfaceSupport.hpp
++jvmtiImpl.cpp                           interpreter.hpp
++jvmtiImpl.cpp                           javaCalls.hpp
++jvmtiImpl.cpp                           jvmtiAgentThread.hpp
++jvmtiImpl.cpp                           jvmtiEnv.hpp
++jvmtiImpl.cpp                           jvmtiEventController.inline.hpp
++jvmtiImpl.cpp                           jvmtiImpl.hpp
++jvmtiImpl.cpp                           jvmtiRedefineClasses.hpp
++jvmtiImpl.cpp                           resourceArea.hpp
++jvmtiImpl.cpp                           signature.hpp
++jvmtiImpl.cpp                           systemDictionary.hpp
++jvmtiImpl.cpp                           thread_<os_family>.inline.hpp
++jvmtiImpl.cpp                           vframe.hpp
++jvmtiImpl.cpp                           vframe_hp.hpp
++jvmtiImpl.cpp                           vm_operations.hpp
++
++jvmtiImpl.hpp                           jvmti.h
++jvmtiImpl.hpp                           jvmtiEnvThreadState.hpp
++jvmtiImpl.hpp                           jvmtiEventController.hpp
++jvmtiImpl.hpp                           jvmtiTrace.hpp
++jvmtiImpl.hpp                           jvmtiUtil.hpp
++jvmtiImpl.hpp                           objArrayOop.hpp
++jvmtiImpl.hpp                           stackValueCollection.hpp
++jvmtiImpl.hpp                           systemDictionary.hpp
++jvmtiImpl.hpp                           vm_operations.hpp
++
++jvmtiTagMap.cpp                         biasedLocking.hpp
++jvmtiTagMap.cpp                         javaCalls.hpp
++jvmtiTagMap.cpp                         jniHandles.hpp
++jvmtiTagMap.cpp                         jvmtiEnv.hpp
++jvmtiTagMap.cpp                         jvmtiEventController.hpp
++jvmtiTagMap.cpp                         jvmtiEventController.inline.hpp
++jvmtiTagMap.cpp                         jvmtiExport.hpp
++jvmtiTagMap.cpp                         jvmtiImpl.hpp
++jvmtiTagMap.cpp                         jvmtiTagMap.hpp
++jvmtiTagMap.cpp                         mutex.hpp
++jvmtiTagMap.cpp                         mutexLocker.hpp
++jvmtiTagMap.cpp                         objArrayKlass.hpp
++jvmtiTagMap.cpp                         oop.inline2.hpp
++jvmtiTagMap.cpp                         reflectionUtils.hpp
++jvmtiTagMap.cpp                         serviceUtil.hpp
++jvmtiTagMap.cpp                         symbolTable.hpp
++jvmtiTagMap.cpp                         systemDictionary.hpp
++jvmtiTagMap.cpp                         vframe.hpp
++jvmtiTagMap.cpp                         vmSymbols.hpp
++jvmtiTagMap.cpp                         vmThread.hpp
++jvmtiTagMap.cpp                         vm_operations.hpp
++
++jvmtiTagMap.hpp                         allocation.hpp
++jvmtiTagMap.hpp                         collectedHeap.hpp
++jvmtiTagMap.hpp                         genCollectedHeap.hpp
++jvmtiTagMap.hpp                         jvmti.h
++jvmtiTagMap.hpp                         jvmtiEnv.hpp
++jvmtiTagMap.hpp                         universe.hpp
++
++jvmtiTrace.cpp                          jvmtiEnv.hpp
++jvmtiTrace.cpp                          jvmtiTrace.hpp
++
++jvmtiTrace.hpp                          jvmti.h
++jvmtiTrace.hpp                          jvmtiEnvThreadState.hpp
++jvmtiTrace.hpp                          jvmtiEventController.hpp
++jvmtiTrace.hpp                          jvmtiUtil.hpp
++jvmtiTrace.hpp                          objArrayOop.hpp
++jvmtiTrace.hpp                          stackValueCollection.hpp
++jvmtiTrace.hpp                          systemDictionary.hpp
++jvmtiTrace.hpp                          vm_operations.hpp
++
++restore.cpp                             filemap.hpp
++restore.cpp                             hashtable.inline.hpp
++restore.cpp                             oop.inline.hpp
++restore.cpp                             symbolTable.hpp
++restore.cpp                             systemDictionary.hpp
++
++serialize.cpp                           classify.hpp
++serialize.cpp                           codeCache.hpp
++serialize.cpp                           compactingPermGenGen.hpp
++serialize.cpp                           compiledICHolderOop.hpp
++serialize.cpp                           methodDataOop.hpp
++serialize.cpp                           objArrayOop.hpp
++serialize.cpp                           oop.hpp
++serialize.cpp                           symbolTable.hpp
++serialize.cpp                           systemDictionary.hpp
++
++vmStructs.cpp                           arguments.hpp
++vmStructs.cpp                           arrayKlass.hpp
++vmStructs.cpp                           arrayKlassKlass.hpp
++vmStructs.cpp                           arrayOop.hpp
++vmStructs.cpp                           bytecodes.hpp
++vmStructs.cpp                           bytecodeInterpreter.hpp
++vmStructs.cpp                           cardTableRS.hpp
++vmStructs.cpp                           codeBlob.hpp
++vmStructs.cpp                           codeCache.hpp
++vmStructs.cpp                           collectedHeap.hpp
++vmStructs.cpp                           compactPermGen.hpp
++vmStructs.cpp                           compiledICHolderKlass.hpp
++vmStructs.cpp                           compiledICHolderOop.hpp
++vmStructs.cpp                           compressedStream.hpp
++vmStructs.cpp                           constMethodKlass.hpp
++vmStructs.cpp                           constMethodOop.hpp
++vmStructs.cpp                           constantPoolKlass.hpp
++vmStructs.cpp                           constantPoolOop.hpp
++vmStructs.cpp                           cpCacheKlass.hpp
++vmStructs.cpp                           cpCacheOop.hpp
++vmStructs.cpp                           defNewGeneration.hpp
++vmStructs.cpp                           dictionary.hpp
++vmStructs.cpp                           freeBlockDictionary.hpp
++vmStructs.cpp                           genCollectedHeap.hpp
++vmStructs.cpp                           generation.hpp
++vmStructs.cpp                           generationSpec.hpp
++vmStructs.cpp                           globalDefinitions.hpp
++vmStructs.cpp                           globals.hpp
++vmStructs.cpp                           hashtable.hpp
++vmStructs.cpp                           heap.hpp
++vmStructs.cpp                           immutableSpace.hpp
++vmStructs.cpp                           instanceKlass.hpp
++vmStructs.cpp                           instanceKlassKlass.hpp
++vmStructs.cpp                           instanceOop.hpp
++vmStructs.cpp                           interpreter.hpp
++vmStructs.cpp                           java.hpp
++vmStructs.cpp                           javaCalls.hpp
++vmStructs.cpp                           javaClasses.hpp
++vmStructs.cpp                           jvmtiAgentThread.hpp
++vmStructs.cpp                           klass.hpp
++vmStructs.cpp                           klassOop.hpp
++vmStructs.cpp                           loaderConstraints.hpp
++vmStructs.cpp                           location.hpp
++vmStructs.cpp                           markOop.hpp
++vmStructs.cpp                           markSweep.hpp
++vmStructs.cpp                           methodDataKlass.hpp
++vmStructs.cpp                           methodDataOop.hpp
++vmStructs.cpp                           methodKlass.hpp
++vmStructs.cpp                           methodOop.hpp
++vmStructs.cpp                           mutableSpace.hpp
++vmStructs.cpp                           nmethod.hpp
++vmStructs.cpp                           objArrayKlass.hpp
++vmStructs.cpp                           objArrayKlassKlass.hpp
++vmStructs.cpp                           objArrayOop.hpp
++vmStructs.cpp                           oop.hpp
++vmStructs.cpp                           oopMap.hpp
++vmStructs.cpp                           pcDesc.hpp
++vmStructs.cpp                           perfMemory.hpp
++vmStructs.cpp                           permGen.hpp
++vmStructs.cpp                           placeholders.hpp
++vmStructs.cpp                           sharedRuntime.hpp
++vmStructs.cpp                           space.hpp
++vmStructs.cpp                           stubRoutines.hpp
++vmStructs.cpp                           stubs.hpp
++vmStructs.cpp                           symbolKlass.hpp
++vmStructs.cpp                           symbolOop.hpp
++vmStructs.cpp                           symbolTable.hpp
++vmStructs.cpp                           systemDictionary.hpp
++vmStructs.cpp                           tenuredGeneration.hpp
++vmStructs.cpp                           thread_<os_family>.inline.hpp
++vmStructs.cpp                           typeArrayKlass.hpp
++vmStructs.cpp                           typeArrayKlassKlass.hpp
++vmStructs.cpp                           typeArrayOop.hpp
++vmStructs.cpp                           universe.hpp
++vmStructs.cpp                           virtualspace.hpp
++vmStructs.cpp                           vmStructs.hpp
++vmStructs.cpp                           vmStructs_<arch>.hpp
++vmStructs.cpp                           vmStructs_<os_arch>.hpp
++vmStructs.cpp                           vmreg.hpp
++vmStructs.cpp                           watermark.hpp
++
++vmStructs.hpp                           debug.hpp
+diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_gc_parallel openjdk/hotspot/src/share/vm/includeDB_gc_parallel
+--- openjdk6/hotspot/src/share/vm/includeDB_gc_parallel	2008-08-28 10:23:07.000000000 +0200
++++ openjdk/hotspot/src/share/vm/includeDB_gc_parallel	2007-12-14 08:57:02.000000000 +0100
+@@ -42,11 +42,14 @@
+ instanceKlass.cpp                       psScavenge.inline.hpp
+ instanceKlass.cpp                       parOopClosures.inline.hpp
+ 
++instanceKlassKlass.cpp                  cardTableRS.hpp
++instanceKlassKlass.cpp                  oop.pcgc.inline.hpp
+ instanceKlassKlass.cpp                  psPromotionManager.inline.hpp
+ instanceKlassKlass.cpp                  psScavenge.inline.hpp
++instanceKlassKlass.cpp                  parOopClosures.inline.hpp
+ 
+-instanceRefKlass.cpp                    psPromotionManager.inline.hpp
+ instanceRefKlass.cpp                    oop.pcgc.inline.hpp
++instanceRefKlass.cpp                    psPromotionManager.inline.hpp
+ instanceRefKlass.cpp                    psScavenge.inline.hpp
+ instanceRefKlass.cpp                    parOopClosures.inline.hpp
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_jvmti openjdk/hotspot/src/share/vm/includeDB_jvmti
+--- openjdk6/hotspot/src/share/vm/includeDB_jvmti	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/includeDB_jvmti	2007-12-14 08:57:02.000000000 +0100
+@@ -0,0 +1,257 @@
++//
++// Copyright 2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++// CA 95054 USA or visit www.sun.com if you need additional information or
++// have any questions.
++//  
++//
++
++jvmtiAgentThread.hpp                    jvmtiEnv.hpp
++
++jvmtiClassFileReconstituter.cpp         bytecodeStream.hpp
++jvmtiClassFileReconstituter.cpp         bytes_<arch>.hpp
++jvmtiClassFileReconstituter.cpp         jvmtiClassFileReconstituter.hpp
++jvmtiClassFileReconstituter.cpp         symbolTable.hpp
++
++jvmtiClassFileReconstituter.hpp         jvmtiEnv.hpp
++
++// jvmtiCodeBlobEvents is jck optional, please put deps in includeDB_features
++
++jvmtiEnter.cpp                          jvmtiEnter.hpp
++jvmtiEnter.cpp                          jvmtiUtil.hpp
++
++jvmtiEnter.hpp                          interfaceSupport.hpp
++jvmtiEnter.hpp                          jvmtiEnv.hpp
++jvmtiEnter.hpp                          jvmtiImpl.hpp
++jvmtiEnter.hpp                          resourceArea.hpp
++jvmtiEnter.hpp                          systemDictionary.hpp
++
++jvmtiEnterTrace.cpp                     jvmtiEnter.hpp
++jvmtiEnterTrace.cpp                     jvmtiUtil.hpp
++
++jvmtiEnv.cpp                            arguments.hpp
++jvmtiEnv.cpp                            bytecodeStream.hpp
++jvmtiEnv.cpp                            cpCacheOop.hpp
++jvmtiEnv.cpp                            deoptimization.hpp
++jvmtiEnv.cpp                            exceptions.hpp
++jvmtiEnv.cpp                            instanceKlass.hpp
++jvmtiEnv.cpp                            interfaceSupport.hpp
++jvmtiEnv.cpp                            interpreter.hpp
++jvmtiEnv.cpp                            javaCalls.hpp
++jvmtiEnv.cpp                            jfieldIDWorkaround.hpp
++jvmtiEnv.cpp                            jniCheck.hpp
++jvmtiEnv.cpp                            jvm_misc.hpp
++jvmtiEnv.cpp                            jvmtiAgentThread.hpp
++jvmtiEnv.cpp                            jvmtiClassFileReconstituter.hpp
++jvmtiEnv.cpp                            jvmtiCodeBlobEvents.hpp
++jvmtiEnv.cpp                            jvmtiEnv.hpp
++jvmtiEnv.cpp                            jvmtiExtensions.hpp
++jvmtiEnv.cpp                            jvmtiGetLoadedClasses.hpp
++jvmtiEnv.cpp                            jvmtiImpl.hpp
++jvmtiEnv.cpp                            jvmtiManageCapabilities.hpp
++jvmtiEnv.cpp                            jvmtiRedefineClasses.hpp
++jvmtiEnv.cpp                            jvmtiTagMap.hpp
++jvmtiEnv.cpp                            jvmtiThreadState.inline.hpp
++jvmtiEnv.cpp                            jvmtiUtil.hpp
++jvmtiEnv.cpp                            objectMonitor.inline.hpp
++jvmtiEnv.cpp                            osThread.hpp
++jvmtiEnv.cpp                            preserveException.hpp
++jvmtiEnv.cpp                            reflectionUtils.hpp
++jvmtiEnv.cpp                            resourceArea.hpp
++jvmtiEnv.cpp                            signature.hpp
++jvmtiEnv.cpp                            systemDictionary.hpp
++jvmtiEnv.cpp                            threadService.hpp
++jvmtiEnv.cpp                            thread_<os_family>.inline.hpp
++jvmtiEnv.cpp                            universe.inline.hpp
++jvmtiEnv.cpp                            vframe.hpp
++jvmtiEnv.cpp                            vmSymbols.hpp
++jvmtiEnv.cpp                            vmThread.hpp
++
++jvmtiEnv.hpp                            jvmtiEnvBase.hpp
++
++jvmtiEnvBase.cpp                        biasedLocking.hpp
++jvmtiEnvBase.cpp                        interfaceSupport.hpp
++jvmtiEnvBase.cpp                        jfieldIDWorkaround.hpp
++jvmtiEnvBase.cpp                        jvmtiEnv.hpp
++jvmtiEnvBase.cpp                        jvmtiEnvBase.hpp
++jvmtiEnvBase.cpp                        jvmtiEventController.inline.hpp
++jvmtiEnvBase.cpp                        jvmtiExtensions.hpp
++jvmtiEnvBase.cpp                        jvmtiImpl.hpp
++jvmtiEnvBase.cpp                        jvmtiManageCapabilities.hpp
++jvmtiEnvBase.cpp                        jvmtiTagMap.hpp
++jvmtiEnvBase.cpp                        jvmtiThreadState.inline.hpp
++jvmtiEnvBase.cpp                        objArrayKlass.hpp
++jvmtiEnvBase.cpp                        objArrayOop.hpp
++jvmtiEnvBase.cpp                        objectMonitor.hpp
++jvmtiEnvBase.cpp                        objectMonitor.inline.hpp
++jvmtiEnvBase.cpp                        signature.hpp
++jvmtiEnvBase.cpp                        systemDictionary.hpp
++jvmtiEnvBase.cpp                        vframe.hpp
++jvmtiEnvBase.cpp                        vframe_hp.hpp
++jvmtiEnvBase.cpp                        vmThread.hpp
++jvmtiEnvBase.cpp                        vm_operations.hpp
++
++jvmtiEnvBase.hpp                        classLoader.hpp
++jvmtiEnvBase.hpp                        fieldDescriptor.hpp
++jvmtiEnvBase.hpp                        frame.hpp
++jvmtiEnvBase.hpp                        growableArray.hpp
++jvmtiEnvBase.hpp                        handles.inline.hpp
++jvmtiEnvBase.hpp                        jvmtiEnvThreadState.hpp
++jvmtiEnvBase.hpp                        jvmtiEventController.hpp
++jvmtiEnvBase.hpp                        jvmtiThreadState.hpp
++jvmtiEnvBase.hpp                        thread.hpp
++jvmtiEnvBase.hpp                        vm_operations.hpp
++
++jvmtiEnvThreadState.cpp                 handles.hpp
++jvmtiEnvThreadState.cpp                 handles.inline.hpp
++jvmtiEnvThreadState.cpp                 interfaceSupport.hpp
++jvmtiEnvThreadState.cpp                 interpreter.hpp
++jvmtiEnvThreadState.cpp                 javaCalls.hpp
++jvmtiEnvThreadState.cpp                 jvmtiEnv.hpp
++jvmtiEnvThreadState.cpp                 jvmtiEnvThreadState.hpp
++jvmtiEnvThreadState.cpp                 jvmtiEventController.inline.hpp
++jvmtiEnvThreadState.cpp                 jvmtiImpl.hpp
++jvmtiEnvThreadState.cpp                 resourceArea.hpp
++jvmtiEnvThreadState.cpp                 signature.hpp
++jvmtiEnvThreadState.cpp                 systemDictionary.hpp
++jvmtiEnvThreadState.cpp                 vframe.hpp
++jvmtiEnvThreadState.cpp                 vm_operations.hpp
++
++jvmtiEnvThreadState.hpp                 allocation.hpp
++jvmtiEnvThreadState.hpp                 allocation.inline.hpp
++jvmtiEnvThreadState.hpp                 globalDefinitions.hpp
++jvmtiEnvThreadState.hpp                 growableArray.hpp
++jvmtiEnvThreadState.hpp                 instanceKlass.hpp
++jvmtiEnvThreadState.hpp                 jvmti.h
++jvmtiEnvThreadState.hpp                 jvmtiEventController.hpp
++
++jvmtiEventController.cpp                frame.hpp
++jvmtiEventController.cpp                interpreter.hpp
++jvmtiEventController.cpp                jvmtiEnv.hpp
++jvmtiEventController.cpp                jvmtiEventController.hpp
++jvmtiEventController.cpp                jvmtiEventController.inline.hpp
++jvmtiEventController.cpp                jvmtiExport.hpp
++jvmtiEventController.cpp                jvmtiImpl.hpp
++jvmtiEventController.cpp                jvmtiThreadState.inline.hpp
++jvmtiEventController.cpp                resourceArea.hpp
++jvmtiEventController.cpp                thread.hpp
++jvmtiEventController.cpp                vframe.hpp
++jvmtiEventController.cpp                vframe_hp.hpp
++jvmtiEventController.cpp                vmThread.hpp
++jvmtiEventController.cpp                vm_operations.hpp
++
++jvmtiEventController.hpp                allocation.hpp
++jvmtiEventController.hpp                allocation.inline.hpp
++jvmtiEventController.hpp                globalDefinitions.hpp
++jvmtiEventController.hpp                jvmti.h
++
++jvmtiEventController.inline.hpp         jvmtiEventController.hpp
++jvmtiEventController.inline.hpp         jvmtiImpl.hpp
++jvmtiEventController.inline.hpp         jvmtiUtil.hpp
++
++jvmtiExport.cpp                         arguments.hpp
++jvmtiExport.cpp                         attachListener.hpp
++jvmtiExport.cpp                         handles.hpp
++jvmtiExport.cpp                         interfaceSupport.hpp
++jvmtiExport.cpp                         interpreter.hpp
++jvmtiExport.cpp                         jvmtiCodeBlobEvents.hpp
++jvmtiExport.cpp                         jvmtiEnv.hpp
++jvmtiExport.cpp                         jvmtiEventController.hpp
++jvmtiExport.cpp                         jvmtiEventController.inline.hpp
++jvmtiExport.cpp                         jvmtiExport.hpp
++jvmtiExport.cpp                         jvmtiImpl.hpp
++jvmtiExport.cpp                         jvmtiManageCapabilities.hpp
++jvmtiExport.cpp                         jvmtiTagMap.hpp
++jvmtiExport.cpp                         jvmtiThreadState.inline.hpp
++jvmtiExport.cpp                         nmethod.hpp
++jvmtiExport.cpp                         objArrayKlass.hpp
++jvmtiExport.cpp                         objArrayOop.hpp
++jvmtiExport.cpp                         objectMonitor.inline.hpp
++jvmtiExport.cpp                         pcDesc.hpp
++jvmtiExport.cpp                         resourceArea.hpp
++jvmtiExport.cpp                         scopeDesc.hpp
++jvmtiExport.cpp                         serviceUtil.hpp
++jvmtiExport.cpp                         systemDictionary.hpp
++jvmtiExport.cpp                         thread.hpp
++jvmtiExport.cpp                         vframe.hpp
++
++// jvmtiExtensions is jck optional, please put deps in includeDB_features
++
++jvmtiGetLoadedClasses.cpp               jvmtiGetLoadedClasses.hpp
++jvmtiGetLoadedClasses.cpp               systemDictionary.hpp
++jvmtiGetLoadedClasses.cpp               thread.hpp
++jvmtiGetLoadedClasses.cpp               universe.inline.hpp
++
++jvmtiGetLoadedClasses.hpp               jvmtiEnv.hpp
++
++// jvmtiImpl is jck optional, please put deps in includeDB_features
++
++jvmtiManageCapabilities.cpp             jvmtiEnv.hpp
++jvmtiManageCapabilities.cpp             jvmtiExport.hpp
++jvmtiManageCapabilities.cpp             jvmtiManageCapabilities.hpp
++ 
++jvmtiManageCapabilities.hpp             allocation.hpp
++jvmtiManageCapabilities.hpp             jvmti.h
++
++jvmtiRedefineClasses.cpp                codeCache.hpp
++jvmtiRedefineClasses.cpp                deoptimization.hpp
++jvmtiRedefineClasses.cpp                gcLocker.hpp
++jvmtiRedefineClasses.cpp                jvmtiImpl.hpp
++jvmtiRedefineClasses.cpp                jvmtiRedefineClasses.hpp
++jvmtiRedefineClasses.cpp                klassVtable.hpp
++jvmtiRedefineClasses.cpp                methodComparator.hpp
++jvmtiRedefineClasses.cpp                oopMapCache.hpp
++jvmtiRedefineClasses.cpp                relocator.hpp
++jvmtiRedefineClasses.cpp                rewriter.hpp
++jvmtiRedefineClasses.cpp                systemDictionary.hpp
++jvmtiRedefineClasses.cpp                universe.inline.hpp
++jvmtiRedefineClasses.cpp                verifier.hpp
++
++jvmtiRedefineClasses.hpp                jvmtiEnv.hpp
++jvmtiRedefineClasses.hpp                jvmtiRedefineClassesTrace.hpp
++jvmtiRedefineClasses.hpp                objArrayKlass.hpp
++jvmtiRedefineClasses.hpp                objArrayOop.hpp
++jvmtiRedefineClasses.hpp                oopFactory.hpp
++jvmtiRedefineClasses.hpp                resourceArea.hpp
++jvmtiRedefineClasses.hpp                vm_operations.hpp
++
++// jvmtiTagMap is jck optional, please put deps in includeDB_features
++// jvmtiTrace is jck optional, please put deps in includeDB_features
++
++jvmtiThreadState.cpp                    gcLocker.hpp
++jvmtiThreadState.cpp                    jvmtiEnv.hpp
++jvmtiThreadState.cpp                    jvmtiEventController.inline.hpp
++jvmtiThreadState.cpp                    jvmtiImpl.hpp
++jvmtiThreadState.cpp                    jvmtiThreadState.inline.hpp
++jvmtiThreadState.cpp                    resourceArea.hpp
++jvmtiThreadState.cpp                    vframe.hpp
++
++jvmtiThreadState.inline.hpp             jvmtiEnvThreadState.hpp
++jvmtiThreadState.inline.hpp             jvmtiThreadState.hpp
++
++jvmtiUtil.cpp                           exceptions.hpp
++jvmtiUtil.cpp                           handles.hpp
++jvmtiUtil.cpp                           handles.inline.hpp
++jvmtiUtil.cpp                           interfaceSupport.hpp
++jvmtiUtil.cpp                           jvmtiUtil.hpp
++jvmtiUtil.cpp                           vm_operations.hpp
++
++jvmtiUtil.hpp                           jvmti.h
++jvmtiUtil.hpp                           jvmtiEventController.hpp
++jvmtiUtil.hpp                           resourceArea.hpp
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -0,0 +1,245 @@
++/*
++ * Copyright 1997-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++// This file contains the platform-independant parts
++// of the abstract interpreter and the abstract interpreter generator.
++
++// Organization of the interpreter(s). There exists two different interpreters in hotpot
++// an assembly language version (aka template interpreter) and a high level language version
++// (aka c++ interpreter). Th division of labor is as follows:
++
++// Template Interpreter          C++ Interpreter        Functionality
++//
++// templateTable*                bytecodeInterpreter*   actual interpretation of bytecodes
++//
++// templateInterpreter*          cppInterpreter*        generation of assembly code that creates
++//                                                      and manages interpreter runtime frames.
++//                                                      Also code for populating interpreter
++//                                                      frames created during deoptimization.
++//
++// For both template and c++ interpreter. There are common files for aspects of the interpreter
++// that are generic to both interpreters. This is the layout:
++//
++// abstractInterpreter.hpp: generic description of the interpreter.
++// interpreter*:            generic frame creation and handling.
++//
++
++//------------------------------------------------------------------------------------------------------------------------
++// The C++ interface to the bytecode interpreter(s).
++
++class AbstractInterpreter: AllStatic {
++  friend class VMStructs;
++  friend class Interpreter;
++  friend class CppInterpreterGenerator;
++ public:
++  enum MethodKind {
++    zerolocals,                                                 // method needs locals initialization
++    zerolocals_synchronized,                                    // method needs locals initialization & is synchronized
++    native,                                                     // native method
++    native_synchronized,                                        // native method & is synchronized
++    empty,                                                      // empty method (code: _return)
++    accessor,                                                   // accessor method (code: _aload_0, _getfield, _(a|i)return)
++    abstract,                                                   // abstract method (throws an AbstractMethodException)
++    java_lang_math_sin,                                         // implementation of java.lang.Math.sin   (x)
++    java_lang_math_cos,                                         // implementation of java.lang.Math.cos   (x)
++    java_lang_math_tan,                                         // implementation of java.lang.Math.tan   (x)
++    java_lang_math_abs,                                         // implementation of java.lang.Math.abs   (x)
++    java_lang_math_sqrt,                                        // implementation of java.lang.Math.sqrt  (x)
++    java_lang_math_log,                                         // implementation of java.lang.Math.log   (x)
++    java_lang_math_log10,                                       // implementation of java.lang.Math.log10 (x)
++    number_of_method_entries,
++    invalid = -1
++  };
++
++  enum SomeConstants {
++    number_of_result_handlers = 10                              // number of result handlers for native calls
++  };
++
++ protected:
++  static StubQueue* _code;                                      // the interpreter code (codelets)
++
++  static bool       _notice_safepoints;                         // true if safepoints are activated
++
++  static address    _native_entry_begin;                        // Region for native entry code
++  static address    _native_entry_end;
++
++  // method entry points
++  static address    _entry_table[number_of_method_entries];     // entry points for a given method
++  static address    _native_abi_to_tosca[number_of_result_handlers];  // for native method result handlers
++  static address    _slow_signature_handler;                              // the native method generic (slow) signature handler
++
++  static address    _rethrow_exception_entry;                   // rethrows an activation in previous frame
++
++
++
++  friend class      AbstractInterpreterGenerator;
++  friend class              InterpreterGenerator;
++  friend class      InterpreterMacroAssembler;
++
++ public:
++  // Initialization/debugging
++  static void       initialize();
++  static StubQueue* code()                                      { return _code; }
++
++
++  // Method activation
++  static MethodKind method_kind(methodHandle m);
++  static address    entry_for_kind(MethodKind k)                { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; }
++  static address    entry_for_method(methodHandle m)            { return _entry_table[method_kind(m)]; }
++
++  static void       print_method_kind(MethodKind kind)          PRODUCT_RETURN;
++
++  // Runtime support
++
++  // length = invoke bytecode length (to advance to next bytecode)
++  static address    deopt_entry   (TosState state, int length) { ShouldNotReachHere(); return NULL; }
++  static address    return_entry  (TosState state, int length) { ShouldNotReachHere(); return NULL; }
++
++  static address    rethrow_exception_entry()                   { return _rethrow_exception_entry; }
++
++  // Activation size in words for a method that is just being called.
++  // Parameters haven't been pushed so count them too.
++  static int        size_top_interpreter_activation(methodOop method);
++
++  // Deoptimization support
++  static address    continuation_for(methodOop method,
++                                     address bcp,
++                                     int callee_parameters,
++                                     bool is_top_frame,
++                                     bool& use_next_mdp);
++
++  // share implementation of size_activation and layout_activation:
++  static int        size_activation(methodOop method,
++                                    int temps,
++                                    int popframe_args,
++                                    int monitors,
++                                    int callee_params,
++                                    int callee_locals,
++                                    bool is_top_frame);
++
++  static int       layout_activation(methodOop method,
++                                      int temps,
++                                      int popframe_args,
++                                      int monitors,
++                                      int callee_params,
++                                      int callee_locals,
++                                      frame* caller,
++                                      frame* interpreter_frame,
++                                      bool is_top_frame);
++
++  // Runtime support
++  static bool       is_not_reached(                       methodHandle method, int bci);
++  // Safepoint support
++  static void       notice_safepoints()                         { ShouldNotReachHere(); } // stops the thread when reaching a safepoint
++  static void       ignore_safepoints()                         { ShouldNotReachHere(); } // ignores safepoints
++
++  // Support for native calls
++  static address    slow_signature_handler()                    { return _slow_signature_handler; }
++  static address    result_handler(BasicType type)              { return _native_abi_to_tosca[BasicType_as_index(type)]; }
++  static int        BasicType_as_index(BasicType type);         // computes index into result_handler_by_index table
++  static bool       in_native_entry(address pc)                 { return _native_entry_begin <= pc && pc < _native_entry_end; }
++  // Debugging/printing
++  static void       print();                                    // prints the interpreter code
++
++  // Support for Tagged Stacks
++  //
++  // Tags are stored on the Java Expression stack above the value:
++  //
++  //  tag
++  //  value
++  //
++  // For double values:
++  //
++  //  tag2
++  //  high word
++  //  tag1
++  //  low word
++
++ public:
++  static int stackElementWords()   { return TaggedStackInterpreter ? 2 : 1; }
++  static int stackElementSize()    { return stackElementWords()*wordSize; }
++  static int logStackElementSize() { return
++                 TaggedStackInterpreter? LogBytesPerWord+1 : LogBytesPerWord; }
++
++  // Tag is at pointer, value is one below for a stack growing down
++  // (or above for stack growing up)
++  static int  value_offset_in_bytes()  {
++    return TaggedStackInterpreter ?
++      frame::interpreter_frame_expression_stack_direction() * wordSize : 0;
++  }
++  static int  tag_offset_in_bytes()    {
++    assert(TaggedStackInterpreter, "should not call this");
++    return 0;
++  }
++
++  // Tagged Locals
++  // Locals are stored relative to Llocals:
++  //
++  // tag    <- Llocals[n]
++  // value
++  //
++  // Category 2 types are indexed as:
++  //
++  // tag    <- Llocals[-n]
++  // high word
++  // tag    <- Llocals[-n+1]
++  // low word
++  //
++
++  // Local values relative to locals[n]
++  static int  local_offset_in_bytes(int n) {
++    return ((frame::interpreter_frame_expression_stack_direction() * n) *
++            stackElementSize()) + value_offset_in_bytes();
++  }
++  static int  local_tag_offset_in_bytes(int n) {
++    assert(TaggedStackInterpreter, "should not call this");
++    return ((frame::interpreter_frame_expression_stack_direction() * n) *
++            stackElementSize()) + tag_offset_in_bytes();
++  }
++
++};
++
++//------------------------------------------------------------------------------------------------------------------------
++// The interpreter generator.
++
++class Template;
++class AbstractInterpreterGenerator: public StackObj {
++ protected:
++  InterpreterMacroAssembler* _masm;
++
++  // shared code sequences
++  // Converter for native abi result to tosca result
++  address generate_result_handler_for(BasicType type);
++  address generate_slow_signature_handler();
++
++  // entry point generator
++  address generate_method_entry(AbstractInterpreter::MethodKind kind);
++
++  void bang_stack_shadow_pages(bool native_call);
++
++  void generate_all();
++
++ public:
++  AbstractInterpreterGenerator(StubQueue* _code);
++};
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecode.cpp openjdk/hotspot/src/share/vm/interpreter/bytecode.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecode.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/bytecode.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)bytecode.cpp	1.69 07/05/05 17:05:36 JVM"
+-#endif
+ /*
+  * Copyright 1997-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -206,4 +203,3 @@
+ }
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeHistogram.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodeHistogram.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeHistogram.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeHistogram.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)bytecodeHistogram.cpp	1.29 07/05/05 17:05:36 JVM"
+-#endif
+ /*
+  * Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeHistogram.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodeHistogram.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeHistogram.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeHistogram.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)bytecodeHistogram.hpp	1.27 07/05/05 17:05:36 JVM"
+-#endif
+ /*
+  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -32,11 +29,8 @@
+   NOT_PRODUCT(static int   _counter_value;)
+   NOT_PRODUCT(static jlong _reset_time;)
+ 
+-  friend class AbstractInterpreterGenerator;
+-  friend class         InterpreterGenerator;
+-#ifdef CC_INTERP
+-  friend class         cInterpreter;
+-#endif
++  friend class TemplateInterpreterGenerator;
++  friend class         BytecodeInterpreter;
+ 
+  public:
+   // Initialization
+@@ -58,11 +52,9 @@
+  private:
+   NOT_PRODUCT(static int _counters[Bytecodes::number_of_codes];)   // a counter for each bytecode
+ 
+-  friend class AbstractInterpreterGenerator;
++  friend class TemplateInterpreterGenerator;
+   friend class         InterpreterGenerator;
+-#ifdef CC_INTERP
+-  friend class         cInterpreter;
+-#endif
++  friend class         BytecodeInterpreter;
+ 
+  public:
+   // Initialization
+@@ -88,7 +80,7 @@
+   NOT_PRODUCT(static int  _index;)                      // new bytecode is shifted in - used to index into _counters
+   NOT_PRODUCT(static int  _counters[number_of_pairs];)  // a counter for each pair
+ 
+-  friend class AbstractInterpreterGenerator;
++  friend class TemplateInterpreterGenerator;
+   friend class         InterpreterGenerator;
+ 
+  public:
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecode.hpp openjdk/hotspot/src/share/vm/interpreter/bytecode.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecode.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/bytecode.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)bytecode.hpp	1.67 07/05/05 17:05:36 JVM"
+-#endif
+ /*
+  * Copyright 1997-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -0,0 +1,3047 @@
++/*
++ * Copyright 2002-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++
++// no precompiled headers
++#include "incls/_bytecodeInterpreter.cpp.incl"
++
++#ifdef CC_INTERP
++
++/*
++ * USELABELS - If using GCC, then use labels for the opcode dispatching
++ * rather -then a switch statement. This improves performance because it
++ * gives us the oportunity to have the instructions that calculate the
++ * next opcode to jump to be intermixed with the rest of the instructions
++ * that implement the opcode (see UPDATE_PC_AND_TOS_AND_CONTINUE macro).
++ */
++#undef USELABELS
++#ifdef __GNUC__
++/*
++   ASSERT signifies debugging. It is much easier to step thru bytecodes if we
++   don't use the computed goto approach.
++*/
++#ifndef ASSERT
++#define USELABELS
++#endif
++#endif
++
++#undef CASE
++#ifdef USELABELS
++#define CASE(opcode) opc ## opcode
++#define DEFAULT opc_default
++#else
++#define CASE(opcode) case Bytecodes:: opcode
++#define DEFAULT default
++#endif
++
++/*
++ * PREFETCH_OPCCODE - Some compilers do better if you prefetch the next
++ * opcode before going back to the top of the while loop, rather then having
++ * the top of the while loop handle it. This provides a better opportunity
++ * for instruction scheduling. Some compilers just do this prefetch
++ * automatically. Some actually end up with worse performance if you
++ * force the prefetch. Solaris gcc seems to do better, but cc does worse.
++ */
++#undef PREFETCH_OPCCODE
++#define PREFETCH_OPCCODE
++
++/*
++  Interpreter safepoint: it is expected that the interpreter will have no live
++  handles of its own creation live at an interpreter safepoint. Therefore we
++  run a HandleMarkCleaner and trash all handles allocated in the call chain
++  since the JavaCalls::call_helper invocation that initiated the chain.
++  There really shouldn't be any handles remaining to trash but this is cheap
++  in relation to a safepoint.
++*/
++#define SAFEPOINT                                                                 \
++    if ( SafepointSynchronize::is_synchronizing()) {                              \
++        {                                                                         \
++          /* zap freed handles rather than GC'ing them */                         \
++          HandleMarkCleaner __hmc(THREAD);                                        \
++        }                                                                         \
++        CALL_VM(SafepointSynchronize::block(THREAD), handle_exception);           \
++    }
++
++/*
++ * VM_JAVA_ERROR - Macro for throwing a java exception from
++ * the interpreter loop. Should really be a CALL_VM but there
++ * is no entry point to do the transition to vm so we just
++ * do it by hand here.
++ */
++#define VM_JAVA_ERROR_NO_JUMP(name, msg)                                          \
++    DECACHE_STATE();                                                              \
++    SET_LAST_JAVA_FRAME();                                                        \
++    {                                                                             \
++       ThreadInVMfromJava trans(THREAD);                                          \
++       Exceptions::_throw_msg(THREAD, __FILE__, __LINE__, name, msg);             \
++    }                                                                             \
++    RESET_LAST_JAVA_FRAME();                                                      \
++    CACHE_STATE();
++
++// Normal throw of a java error
++#define VM_JAVA_ERROR(name, msg)                                                  \
++    VM_JAVA_ERROR_NO_JUMP(name, msg)                                              \
++    goto handle_exception;
++
++#ifdef PRODUCT
++#define DO_UPDATE_INSTRUCTION_COUNT(opcode)
++#else
++#define DO_UPDATE_INSTRUCTION_COUNT(opcode)                                                          \
++{                                                                                                    \
++    BytecodeCounter::_counter_value++;                                                               \
++    BytecodeHistogram::_counters[(Bytecodes::Code)opcode]++;                                         \
++    if (StopInterpreterAt && StopInterpreterAt == BytecodeCounter::_counter_value) os::breakpoint(); \
++    if (TraceBytecodes) {                                                                            \
++      CALL_VM((void)SharedRuntime::trace_bytecode(THREAD, 0,               \
++                                   topOfStack[Interpreter::expr_index_at(1)],   \
++                                   topOfStack[Interpreter::expr_index_at(2)]),  \
++                                   handle_exception);                      \
++    }                                                                      \
++}
++#endif
++
++#undef DEBUGGER_SINGLE_STEP_NOTIFY
++#ifdef VM_JVMTI
++/* NOTE: (kbr) This macro must be called AFTER the PC has been
++   incremented. JvmtiExport::at_single_stepping_point() may cause a
++   breakpoint opcode to get inserted at the current PC to allow the
++   debugger to coalesce single-step events.
++
++   As a result if we call at_single_stepping_point() we refetch opcode
++   to get the current opcode. This will override any other prefetching
++   that might have occurred.
++*/
++#define DEBUGGER_SINGLE_STEP_NOTIFY()                                            \
++{                                                                                \
++      if (_jvmti_interp_events) {                                                \
++        if (JvmtiExport::should_post_single_step()) {                            \
++          DECACHE_STATE();                                                       \
++          SET_LAST_JAVA_FRAME();                                                 \
++          ThreadInVMfromJava trans(THREAD);                                      \
++          JvmtiExport::at_single_stepping_point(THREAD,                          \
++                                          istate->method(),                      \
++                                          pc);                                   \
++          RESET_LAST_JAVA_FRAME();                                               \
++          CACHE_STATE();                                                         \
++          if (THREAD->pop_frame_pending() &&                                     \
++              !THREAD->pop_frame_in_process()) {                                 \
++            goto handle_Pop_Frame;                                               \
++          }                                                                      \
++          opcode = *pc;                                                          \
++        }                                                                        \
++      }                                                                          \
++}
++#else
++#define DEBUGGER_SINGLE_STEP_NOTIFY()
++#endif
++
++/*
++ * CONTINUE - Macro for executing the next opcode.
++ */
++#undef CONTINUE
++#ifdef USELABELS
++// Have to do this dispatch this way in C++ because otherwise gcc complains about crossing an
++// initialization (which is is the initialization of the table pointer...)
++#define DISPATCH(opcode) goto *dispatch_table[opcode]
++#define CONTINUE {                              \
++        opcode = *pc;                           \
++        DO_UPDATE_INSTRUCTION_COUNT(opcode);    \
++        DEBUGGER_SINGLE_STEP_NOTIFY();          \
++        DISPATCH(opcode);                       \
++    }
++#else
++#ifdef PREFETCH_OPCCODE
++#define CONTINUE {                              \
++        opcode = *pc;                           \
++        DO_UPDATE_INSTRUCTION_COUNT(opcode);    \
++        DEBUGGER_SINGLE_STEP_NOTIFY();          \
++        continue;                               \
++    }
++#else
++#define CONTINUE {                              \
++        DO_UPDATE_INSTRUCTION_COUNT(opcode);    \
++        DEBUGGER_SINGLE_STEP_NOTIFY();          \
++        continue;                               \
++    }
++#endif
++#endif
++
++// JavaStack Implementation
++#define MORE_STACK(count)  \
++    (topOfStack -= ((count) * Interpreter::stackElementWords()))
++
++
++#define UPDATE_PC(opsize) {pc += opsize; }
++/*
++ * UPDATE_PC_AND_TOS - Macro for updating the pc and topOfStack.
++ */
++#undef UPDATE_PC_AND_TOS
++#define UPDATE_PC_AND_TOS(opsize, stack) \
++    {pc += opsize; MORE_STACK(stack); }
++
++/*
++ * UPDATE_PC_AND_TOS_AND_CONTINUE - Macro for updating the pc and topOfStack,
++ * and executing the next opcode. It's somewhat similar to the combination
++ * of UPDATE_PC_AND_TOS and CONTINUE, but with some minor optimizations.
++ */
++#undef UPDATE_PC_AND_TOS_AND_CONTINUE
++#ifdef USELABELS
++#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) {         \
++        pc += opsize; opcode = *pc; MORE_STACK(stack);          \
++        DO_UPDATE_INSTRUCTION_COUNT(opcode);                    \
++        DEBUGGER_SINGLE_STEP_NOTIFY();                          \
++        DISPATCH(opcode);                                       \
++    }
++
++#define UPDATE_PC_AND_CONTINUE(opsize) {                        \
++        pc += opsize; opcode = *pc;                             \
++        DO_UPDATE_INSTRUCTION_COUNT(opcode);                    \
++        DEBUGGER_SINGLE_STEP_NOTIFY();                          \
++        DISPATCH(opcode);                                       \
++    }
++#else
++#ifdef PREFETCH_OPCCODE
++#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) {         \
++        pc += opsize; opcode = *pc; MORE_STACK(stack);          \
++        DO_UPDATE_INSTRUCTION_COUNT(opcode);                    \
++        DEBUGGER_SINGLE_STEP_NOTIFY();                          \
++        goto do_continue;                                       \
++    }
++
++#define UPDATE_PC_AND_CONTINUE(opsize) {                        \
++        pc += opsize; opcode = *pc;                             \
++        DO_UPDATE_INSTRUCTION_COUNT(opcode);                    \
++        DEBUGGER_SINGLE_STEP_NOTIFY();                          \
++        goto do_continue;                                       \
++    }
++#else
++#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \
++        pc += opsize; MORE_STACK(stack);                \
++        DO_UPDATE_INSTRUCTION_COUNT(opcode);            \
++        DEBUGGER_SINGLE_STEP_NOTIFY();                  \
++        goto do_continue;                               \
++    }
++
++#define UPDATE_PC_AND_CONTINUE(opsize) {                \
++        pc += opsize;                                   \
++        DO_UPDATE_INSTRUCTION_COUNT(opcode);            \
++        DEBUGGER_SINGLE_STEP_NOTIFY();                  \
++        goto do_continue;                               \
++    }
++#endif /* PREFETCH_OPCCODE */
++#endif /* USELABELS */
++
++// About to call a new method, update the save the adjusted pc and return to frame manager
++#define UPDATE_PC_AND_RETURN(opsize)  \
++   DECACHE_TOS();                     \
++   istate->set_bcp(pc+opsize);        \
++   return;
++
++
++#define METHOD istate->method()
++#define INVOCATION_COUNT METHOD->invocation_counter()
++#define BACKEDGE_COUNT METHOD->backedge_counter()
++
++
++#define INCR_INVOCATION_COUNT INVOCATION_COUNT->increment()
++#define OSR_REQUEST(res, branch_pc) \
++            CALL_VM(res=InterpreterRuntime::frequency_counter_overflow(THREAD, branch_pc), handle_exception);
++/*
++ * For those opcodes that need to have a GC point on a backwards branch
++ */
++
++// Backedge counting is kind of strange. The asm interpreter will increment
++// the backedge counter as a separate counter but it does it's comparisons
++// to the sum (scaled) of invocation counter and backedge count to make
++// a decision. Seems kind of odd to sum them together like that
++
++// skip is delta from current bcp/bci for target, branch_pc is pre-branch bcp
++
++
++#define DO_BACKEDGE_CHECKS(skip, branch_pc)                                                         \
++    if ((skip) <= 0) {                                                                              \
++      if (UseCompiler && UseLoopCounter) {                                                          \
++        bool do_OSR = UseOnStackReplacement;                                                        \
++        BACKEDGE_COUNT->increment();                                                                \
++        if (do_OSR) do_OSR = BACKEDGE_COUNT->reached_InvocationLimit();                             \
++        if (do_OSR) {                                                                               \
++          nmethod*  osr_nmethod;                                                                    \
++          OSR_REQUEST(osr_nmethod, branch_pc);                                                      \
++          if (osr_nmethod != NULL && osr_nmethod->osr_entry_bci() != InvalidOSREntryBci) {          \
++            intptr_t* buf;                                                                          \
++            CALL_VM(buf=SharedRuntime::OSR_migration_begin(THREAD), handle_exception);              \
++            istate->set_msg(do_osr);                                                                \
++            istate->set_osr_buf((address)buf);                                                      \
++            istate->set_osr_entry(osr_nmethod->osr_entry());                                        \
++            return;                                                                                 \
++          }                                                                                         \
++        } else {                                                                                    \
++          INCR_INVOCATION_COUNT;                                                                    \
++          SAFEPOINT;                                                                                \
++        }                                                                                           \
++      }  /* UseCompiler ... */                                                                      \
++      INCR_INVOCATION_COUNT;                                                                        \
++      SAFEPOINT;                                                                                    \
++    }
++
++/*
++ * For those opcodes that need to have a GC point on a backwards branch
++ */
++
++/*
++ * Macros for caching and flushing the interpreter state. Some local
++ * variables need to be flushed out to the frame before we do certain
++ * things (like pushing frames or becomming gc safe) and some need to
++ * be recached later (like after popping a frame). We could use one
++ * macro to cache or decache everything, but this would be less then
++ * optimal because we don't always need to cache or decache everything
++ * because some things we know are already cached or decached.
++ */
++#undef DECACHE_TOS
++#undef CACHE_TOS
++#undef CACHE_PREV_TOS
++#define DECACHE_TOS()    istate->set_stack(topOfStack);
++
++#define CACHE_TOS()      topOfStack = (intptr_t *)istate->stack();
++
++#undef DECACHE_PC
++#undef CACHE_PC
++#define DECACHE_PC()    istate->set_bcp(pc);
++#define CACHE_PC()      pc = istate->bcp();
++#define CACHE_CP()      cp = istate->constants();
++#define CACHE_LOCALS()  locals = istate->locals();
++#undef CACHE_FRAME
++#define CACHE_FRAME()
++
++/*
++ * CHECK_NULL - Macro for throwing a NullPointerException if the object
++ * passed is a null ref.
++ * On some architectures/platforms it should be possible to do this implicitly
++ */
++#undef CHECK_NULL
++#define CHECK_NULL(obj_)                                                 \
++    if ((obj_) == 0) {                                                   \
++        VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), "");  \
++    }
++
++#define VMdoubleConstZero() 0.0
++#define VMdoubleConstOne() 1.0
++#define VMlongConstZero() (max_jlong-max_jlong)
++#define VMlongConstOne() ((max_jlong-max_jlong)+1)
++
++/*
++ * Alignment
++ */
++#define VMalignWordUp(val)          (((uintptr_t)(val) + 3) & ~3)
++
++// Decache the interpreter state that interpreter modifies directly (i.e. GC is indirect mod)
++#define DECACHE_STATE() DECACHE_PC(); DECACHE_TOS();
++
++// Reload interpreter state after calling the VM or a possible GC
++#define CACHE_STATE()   \
++        CACHE_TOS();    \
++        CACHE_PC();     \
++        CACHE_CP();     \
++        CACHE_LOCALS();
++
++// Call the VM don't check for pending exceptions
++#define CALL_VM_NOCHECK(func)                                     \
++          DECACHE_STATE();                                        \
++          SET_LAST_JAVA_FRAME();                                  \
++          func;                                                   \
++          RESET_LAST_JAVA_FRAME();                                \
++          CACHE_STATE();                                          \
++          if (THREAD->pop_frame_pending() &&                      \
++              !THREAD->pop_frame_in_process()) {                  \
++            goto handle_Pop_Frame;                                \
++          }
++
++// Call the VM and check for pending exceptions
++#define CALL_VM(func, label) {                                    \
++          CALL_VM_NOCHECK(func);                                  \
++          if (THREAD->has_pending_exception()) goto label;        \
++        }
++
++/*
++ * BytecodeInterpreter::run(interpreterState istate)
++ * BytecodeInterpreter::runWithChecks(interpreterState istate)
++ *
++ * The real deal. This is where byte codes actually get interpreted.
++ * Basically it's a big while loop that iterates until we return from
++ * the method passed in.
++ *
++ * The runWithChecks is used if JVMTI is enabled.
++ *
++ */
++#if defined(VM_JVMTI)
++void
++BytecodeInterpreter::runWithChecks(interpreterState istate) {
++#else
++void
++BytecodeInterpreter::run(interpreterState istate) {
++#endif
++
++  // In order to simplify some tests based on switches set at runtime
++  // we invoke the interpreter a single time after switches are enabled
++  // and set simpler to to test variables rather than method calls or complex
++  // boolean expressions.
++
++  static int initialized = 0;
++  static int checkit = 0;
++  static intptr_t* c_addr = NULL;
++  static intptr_t  c_value;
++
++  if (checkit && *c_addr != c_value) {
++    os::breakpoint();
++  }
++#ifdef VM_JVMTI
++  static bool _jvmti_interp_events = 0;
++#endif
++
++  static int _compiling;  // (UseCompiler || CountCompiledCalls)
++
++#ifdef ASSERT
++  if (istate->_msg != initialize) {
++    assert(abs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit");
++  IA32_ONLY(assert(istate->_stack_limit == istate->_thread->last_Java_sp() + 1, "wrong"));
++  }
++  // Verify linkages.
++  interpreterState l = istate;
++  do {
++    assert(l == l->_self_link, "bad link");
++    l = l->_prev_link;
++  } while (l != NULL);
++  // Screwups with stack management usually cause us to overwrite istate
++  // save a copy so we can verify it.
++  interpreterState orig = istate;
++#endif
++
++  static volatile jbyte* _byte_map_base; // adjusted card table base for oop store barrier
++
++  register intptr_t*        topOfStack = (intptr_t *)istate->stack(); /* access with STACK macros */
++  register address          pc = istate->bcp();
++  register jubyte opcode;
++  register intptr_t*        locals = istate->locals();
++  register constantPoolCacheOop  cp = istate->constants(); // method()->constants()->cache()
++#ifdef LOTS_OF_REGS
++  register JavaThread*      THREAD = istate->thread();
++  register volatile jbyte*  BYTE_MAP_BASE = _byte_map_base;
++#else
++#undef THREAD
++#define THREAD istate->thread()
++#undef BYTE_MAP_BASE
++#define BYTE_MAP_BASE _byte_map_base
++#endif
++
++#ifdef USELABELS
++  const static void* const opclabels_data[256] = {
++/* 0x00 */ &&opc_nop,     &&opc_aconst_null,&&opc_iconst_m1,&&opc_iconst_0,
++/* 0x04 */ &&opc_iconst_1,&&opc_iconst_2,   &&opc_iconst_3, &&opc_iconst_4,
++/* 0x08 */ &&opc_iconst_5,&&opc_lconst_0,   &&opc_lconst_1, &&opc_fconst_0,
++/* 0x0C */ &&opc_fconst_1,&&opc_fconst_2,   &&opc_dconst_0, &&opc_dconst_1,
++
++/* 0x10 */ &&opc_bipush, &&opc_sipush, &&opc_ldc,    &&opc_ldc_w,
++/* 0x14 */ &&opc_ldc2_w, &&opc_iload,  &&opc_lload,  &&opc_fload,
++/* 0x18 */ &&opc_dload,  &&opc_aload,  &&opc_iload_0,&&opc_iload_1,
++/* 0x1C */ &&opc_iload_2,&&opc_iload_3,&&opc_lload_0,&&opc_lload_1,
++
++/* 0x20 */ &&opc_lload_2,&&opc_lload_3,&&opc_fload_0,&&opc_fload_1,
++/* 0x24 */ &&opc_fload_2,&&opc_fload_3,&&opc_dload_0,&&opc_dload_1,
++/* 0x28 */ &&opc_dload_2,&&opc_dload_3,&&opc_aload_0,&&opc_aload_1,
++/* 0x2C */ &&opc_aload_2,&&opc_aload_3,&&opc_iaload, &&opc_laload,
++
++/* 0x30 */ &&opc_faload,  &&opc_daload,  &&opc_aaload,  &&opc_baload,
++/* 0x34 */ &&opc_caload,  &&opc_saload,  &&opc_istore,  &&opc_lstore,
++/* 0x38 */ &&opc_fstore,  &&opc_dstore,  &&opc_astore,  &&opc_istore_0,
++/* 0x3C */ &&opc_istore_1,&&opc_istore_2,&&opc_istore_3,&&opc_lstore_0,
++
++/* 0x40 */ &&opc_lstore_1,&&opc_lstore_2,&&opc_lstore_3,&&opc_fstore_0,
++/* 0x44 */ &&opc_fstore_1,&&opc_fstore_2,&&opc_fstore_3,&&opc_dstore_0,
++/* 0x48 */ &&opc_dstore_1,&&opc_dstore_2,&&opc_dstore_3,&&opc_astore_0,
++/* 0x4C */ &&opc_astore_1,&&opc_astore_2,&&opc_astore_3,&&opc_iastore,
++
++/* 0x50 */ &&opc_lastore,&&opc_fastore,&&opc_dastore,&&opc_aastore,
++/* 0x54 */ &&opc_bastore,&&opc_castore,&&opc_sastore,&&opc_pop,
++/* 0x58 */ &&opc_pop2,   &&opc_dup,    &&opc_dup_x1, &&opc_dup_x2,
++/* 0x5C */ &&opc_dup2,   &&opc_dup2_x1,&&opc_dup2_x2,&&opc_swap,
++
++/* 0x60 */ &&opc_iadd,&&opc_ladd,&&opc_fadd,&&opc_dadd,
++/* 0x64 */ &&opc_isub,&&opc_lsub,&&opc_fsub,&&opc_dsub,
++/* 0x68 */ &&opc_imul,&&opc_lmul,&&opc_fmul,&&opc_dmul,
++/* 0x6C */ &&opc_idiv,&&opc_ldiv,&&opc_fdiv,&&opc_ddiv,
++
++/* 0x70 */ &&opc_irem, &&opc_lrem, &&opc_frem,&&opc_drem,
++/* 0x74 */ &&opc_ineg, &&opc_lneg, &&opc_fneg,&&opc_dneg,
++/* 0x78 */ &&opc_ishl, &&opc_lshl, &&opc_ishr,&&opc_lshr,
++/* 0x7C */ &&opc_iushr,&&opc_lushr,&&opc_iand,&&opc_land,
++
++/* 0x80 */ &&opc_ior, &&opc_lor,&&opc_ixor,&&opc_lxor,
++/* 0x84 */ &&opc_iinc,&&opc_i2l,&&opc_i2f, &&opc_i2d,
++/* 0x88 */ &&opc_l2i, &&opc_l2f,&&opc_l2d, &&opc_f2i,
++/* 0x8C */ &&opc_f2l, &&opc_f2d,&&opc_d2i, &&opc_d2l,
++
++/* 0x90 */ &&opc_d2f,  &&opc_i2b,  &&opc_i2c,  &&opc_i2s,
++/* 0x94 */ &&opc_lcmp, &&opc_fcmpl,&&opc_fcmpg,&&opc_dcmpl,
++/* 0x98 */ &&opc_dcmpg,&&opc_ifeq, &&opc_ifne, &&opc_iflt,
++/* 0x9C */ &&opc_ifge, &&opc_ifgt, &&opc_ifle, &&opc_if_icmpeq,
++
++/* 0xA0 */ &&opc_if_icmpne,&&opc_if_icmplt,&&opc_if_icmpge,  &&opc_if_icmpgt,
++/* 0xA4 */ &&opc_if_icmple,&&opc_if_acmpeq,&&opc_if_acmpne,  &&opc_goto,
++/* 0xA8 */ &&opc_jsr,      &&opc_ret,      &&opc_tableswitch,&&opc_lookupswitch,
++/* 0xAC */ &&opc_ireturn,  &&opc_lreturn,  &&opc_freturn,    &&opc_dreturn,
++
++/* 0xB0 */ &&opc_areturn,     &&opc_return,         &&opc_getstatic,    &&opc_putstatic,
++/* 0xB4 */ &&opc_getfield,    &&opc_putfield,       &&opc_invokevirtual,&&opc_invokespecial,
++/* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,NULL,               &&opc_new,
++/* 0xBC */ &&opc_newarray,    &&opc_anewarray,      &&opc_arraylength,  &&opc_athrow,
++
++/* 0xC0 */ &&opc_checkcast,   &&opc_instanceof,     &&opc_monitorenter, &&opc_monitorexit,
++/* 0xC4 */ &&opc_wide,        &&opc_multianewarray, &&opc_ifnull,       &&opc_ifnonnull,
++/* 0xC8 */ &&opc_goto_w,      &&opc_jsr_w,          &&opc_breakpoint,   &&opc_fast_igetfield,
++/* 0xCC */ &&opc_fastagetfield,&&opc_fast_aload_0,  &&opc_fast_iaccess_0, &&opc__fast_aaccess_0,
++
++/* 0xD0 */ &&opc_fast_linearswitch, &&opc_fast_binaryswitch, &&opc_return_register_finalizer,      &&opc_default,
++/* 0xD4 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
++/* 0xD8 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
++/* 0xDC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
++
++/* 0xE0 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
++/* 0xE4 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
++/* 0xE8 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
++/* 0xEC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
++
++/* 0xF0 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
++/* 0xF4 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
++/* 0xF8 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
++/* 0xFC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default
++  };
++  register uintptr_t *dispatch_table = (uintptr_t*)&opclabels_data[0];
++#endif /* USELABELS */
++
++#ifdef ASSERT
++  // this will trigger a VERIFY_OOP on entry
++  if (istate->msg() != initialize && ! METHOD->is_static()) {
++    oop rcvr = LOCALS_OBJECT(0);
++  }
++#endif
++// #define HACK
++#ifdef HACK
++  bool interesting = false;
++#endif // HACK
++
++  /* QQQ this should be a stack method so we don't know actual direction */
++  assert(istate->msg() == initialize ||
++         topOfStack >= istate->stack_limit() &&
++         topOfStack < istate->stack_base(),
++         "Stack top out of range");
++
++  switch (istate->msg()) {
++    case initialize: {
++      if (initialized++) ShouldNotReachHere(); // Only one initialize call
++      _compiling = (UseCompiler || CountCompiledCalls);
++#ifdef VM_JVMTI
++      _jvmti_interp_events = JvmtiExport::can_post_interpreter_events();
++#endif
++      BarrierSet* bs = Universe::heap()->barrier_set();
++      assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
++      _byte_map_base = (volatile jbyte*)(((CardTableModRefBS*)bs)->byte_map_base);
++      return;
++    }
++    break;
++    case method_entry: {
++      THREAD->set_do_not_unlock();
++      // count invocations
++      assert(initialized, "Interpreter not initialized");
++      if (_compiling) {
++        if (ProfileInterpreter) {
++          METHOD->increment_interpreter_invocation_count();
++        }
++        INCR_INVOCATION_COUNT;
++        if (INVOCATION_COUNT->reached_InvocationLimit()) {
++            CALL_VM((void)InterpreterRuntime::frequency_counter_overflow(THREAD, NULL), handle_exception);
++
++            // We no longer retry on a counter overflow
++
++            // istate->set_msg(retry_method);
++            // THREAD->clr_do_not_unlock();
++            // return;
++        }
++        SAFEPOINT;
++      }
++
++      if ((istate->_stack_base - istate->_stack_limit) != istate->method()->max_stack() + 1) {
++        // initialize
++        os::breakpoint();
++      }
++
++#ifdef HACK
++      {
++        ResourceMark rm;
++        char *method_name = istate->method()->name_and_sig_as_C_string();
++        if (strstr(method_name, "runThese$TestRunner.run()V") != NULL) {
++          tty->print_cr("entering: depth %d bci: %d",
++                         (istate->_stack_base - istate->_stack),
++                         istate->_bcp - istate->_method->code_base());
++          interesting = true;
++        }
++      }
++#endif // HACK
++
++
++      // lock method if synchronized
++      if (METHOD->is_synchronized()) {
++          // oop rcvr = locals[0].j.r;
++          oop rcvr;
++          if (METHOD->is_static()) {
++            rcvr = METHOD->constants()->pool_holder()->klass_part()->java_mirror();
++          } else {
++            rcvr = LOCALS_OBJECT(0);
++          }
++          // The initial monitor is ours for the taking
++          BasicObjectLock* mon = &istate->monitor_base()[-1];
++          oop monobj = mon->obj();
++          assert(mon->obj() == rcvr, "method monitor mis-initialized");
++
++          bool success = UseBiasedLocking;
++          if (UseBiasedLocking) {
++            markOop mark = rcvr->mark();
++            if (mark->has_bias_pattern()) {
++              // The bias pattern is present in the object's header. Need to check
++              // whether the bias owner and the epoch are both still current.
++              intptr_t xx = ((intptr_t) THREAD) ^ (intptr_t) mark;
++              xx = (intptr_t) rcvr->klass()->klass_part()->prototype_header() ^ xx;
++              intptr_t yy = (xx & ~((int) markOopDesc::age_mask_in_place));
++              if (yy != 0 ) {
++                // At this point we know that the header has the bias pattern and
++                // that we are not the bias owner in the current epoch. We need to
++                // figure out more details about the state of the header in order to
++                // know what operations can be legally performed on the object's
++                // header.
++
++                // If the low three bits in the xor result aren't clear, that means
++                // the prototype header is no longer biased and we have to revoke
++                // the bias on this object.
++
++                if (yy & markOopDesc::biased_lock_mask_in_place == 0 ) {
++                  // Biasing is still enabled for this data type. See whether the
++                  // epoch of the current bias is still valid, meaning that the epoch
++                  // bits of the mark word are equal to the epoch bits of the
++                  // prototype header. (Note that the prototype header's epoch bits
++                  // only change at a safepoint.) If not, attempt to rebias the object
++                  // toward the current thread. Note that we must be absolutely sure
++                  // that the current epoch is invalid in order to do this because
++                  // otherwise the manipulations it performs on the mark word are
++                  // illegal.
++                  if (yy & markOopDesc::epoch_mask_in_place == 0) {
++                    // The epoch of the current bias is still valid but we know nothing
++                    // about the owner; it might be set or it might be clear. Try to
++                    // acquire the bias of the object using an atomic operation. If this
++                    // fails we will go in to the runtime to revoke the object's bias.
++                    // Note that we first construct the presumed unbiased header so we
++                    // don't accidentally blow away another thread's valid bias.
++                    intptr_t unbiased = (intptr_t) mark & (markOopDesc::biased_lock_mask_in_place |
++                                                           markOopDesc::age_mask_in_place |
++                                                           markOopDesc::epoch_mask_in_place);
++                    if (Atomic::cmpxchg_ptr((intptr_t)THREAD | unbiased, (intptr_t*) rcvr->mark_addr(), unbiased) != unbiased) {
++                      CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
++                    }
++                  } else {
++                    try_rebias:
++                    // At this point we know the epoch has expired, meaning that the
++                    // current "bias owner", if any, is actually invalid. Under these
++                    // circumstances _only_, we are allowed to use the current header's
++                    // value as the comparison value when doing the cas to acquire the
++                    // bias in the current epoch. In other words, we allow transfer of
++                    // the bias from one thread to another directly in this situation.
++                    xx = (intptr_t) rcvr->klass()->klass_part()->prototype_header() | (intptr_t) THREAD;
++                    if (Atomic::cmpxchg_ptr((intptr_t)THREAD | (intptr_t) rcvr->klass()->klass_part()->prototype_header(),
++                                            (intptr_t*) rcvr->mark_addr(),
++                                            (intptr_t) mark) != (intptr_t) mark) {
++                      CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
++                    }
++                  }
++                } else {
++                  try_revoke_bias:
++                  // The prototype mark in the klass doesn't have the bias bit set any
++                  // more, indicating that objects of this data type are not supposed
++                  // to be biased any more. We are going to try to reset the mark of
++                  // this object to the prototype value and fall through to the
++                  // CAS-based locking scheme. Note that if our CAS fails, it means
++                  // that another thread raced us for the privilege of revoking the
++                  // bias of this particular object, so it's okay to continue in the
++                  // normal locking code.
++                  //
++                  xx = (intptr_t) rcvr->klass()->klass_part()->prototype_header() | (intptr_t) THREAD;
++                  if (Atomic::cmpxchg_ptr(rcvr->klass()->klass_part()->prototype_header(),
++                                          (intptr_t*) rcvr->mark_addr(),
++                                          mark) == mark) {
++                    // (*counters->revoked_lock_entry_count_addr())++;
++                  success = false;
++                  }
++                }
++              }
++            } else {
++              cas_label:
++              success = false;
++            }
++          }
++          if (!success) {
++            markOop displaced = rcvr->mark()->set_unlocked();
++            mon->lock()->set_displaced_header(displaced);
++            if (Atomic::cmpxchg_ptr(mon, rcvr->mark_addr(), displaced) != displaced) {
++              // Is it simple recursive case?
++              if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
++                mon->lock()->set_displaced_header(NULL);
++              } else {
++                CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
++              }
++            }
++          }
++      }
++      THREAD->clr_do_not_unlock();
++
++      // Notify jvmti
++#ifdef VM_JVMTI
++      if (_jvmti_interp_events) {
++        // Whenever JVMTI puts a thread in interp_only_mode, method
++        // entry/exit events are sent for that thread to track stack depth.
++        if (THREAD->is_interp_only_mode()) {
++          CALL_VM(InterpreterRuntime::post_method_entry(THREAD),
++                  handle_exception);
++        }
++      }
++#endif /* VM_JVMTI */
++
++      goto run;
++    }
++
++    case popping_frame: {
++      // returned from a java call to pop the frame, restart the call
++      // clear the message so we don't confuse ourselves later
++      assert(THREAD->pop_frame_in_process(), "wrong frame pop state");
++      istate->set_msg(no_request);
++      THREAD->clr_pop_frame_in_process();
++      goto run;
++    }
++
++    case method_resume: {
++      if ((istate->_stack_base - istate->_stack_limit) != istate->method()->max_stack() + 1) {
++        // resume
++        os::breakpoint();
++      }
++#ifdef HACK
++      {
++        ResourceMark rm;
++        char *method_name = istate->method()->name_and_sig_as_C_string();
++        if (strstr(method_name, "runThese$TestRunner.run()V") != NULL) {
++          tty->print_cr("resume: depth %d bci: %d",
++                         (istate->_stack_base - istate->_stack) ,
++                         istate->_bcp - istate->_method->code_base());
++          interesting = true;
++        }
++      }
++#endif // HACK
++      // returned from a java call, continue executing.
++      if (THREAD->pop_frame_pending() && !THREAD->pop_frame_in_process()) {
++        goto handle_Pop_Frame;
++      }
++
++      if (THREAD->has_pending_exception()) goto handle_exception;
++      // Update the pc by the saved amount of the invoke bytecode size
++      UPDATE_PC(istate->bcp_advance());
++      goto run;
++    }
++
++    case deopt_resume2: {
++      // Returned from an opcode that will reexecute. Deopt was
++      // a result of a PopFrame request.
++      //
++      goto run;
++    }
++
++    case deopt_resume: {
++      // Returned from an opcode that has completed. The stack has
++      // the result all we need to do is skip across the bytecode
++      // and continue (assuming there is no exception pending)
++      //
++      // compute continuation length
++      //
++      // Note: it is possible to deopt at a return_register_finalizer opcode
++      // because this requires entering the vm to do the registering. While the
++      // opcode is complete we can't advance because there are no more opcodes
++      // much like trying to deopt at a poll return. In that has we simply
++      // get out of here
++      //
++      if ( Bytecodes::code_at(pc, METHOD) == Bytecodes::_return_register_finalizer) {
++        // this will do the right thing even if an exception is pending.
++        goto handle_return;
++      }
++      UPDATE_PC(Bytecodes::length_at(pc));
++      if (THREAD->has_pending_exception()) goto handle_exception;
++      goto run;
++    }
++    case got_monitors: {
++      // continue locking now that we have a monitor to use
++      // we expect to find newly allocated monitor at the "top" of the monitor stack.
++      oop lockee = STACK_OBJECT(-1);
++      // derefing's lockee ought to provoke implicit null check
++      // find a free monitor
++      BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base();
++      assert(entry->obj() == NULL, "Frame manager didn't allocate the monitor");
++      entry->set_obj(lockee);
++
++      markOop displaced = lockee->mark()->set_unlocked();
++      entry->lock()->set_displaced_header(displaced);
++      if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) {
++        // Is it simple recursive case?
++        if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
++          entry->lock()->set_displaced_header(NULL);
++        } else {
++          CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
++        }
++      }
++      UPDATE_PC_AND_TOS(1, -1);
++      goto run;
++    }
++    default: {
++      fatal("Unexpected message from frame manager");
++    }
++  }
++
++run:
++
++  DO_UPDATE_INSTRUCTION_COUNT(*pc)
++  DEBUGGER_SINGLE_STEP_NOTIFY();
++#ifdef PREFETCH_OPCCODE
++  opcode = *pc;  /* prefetch first opcode */
++#endif
++
++#ifndef USELABELS
++  while (1)
++#endif
++  {
++#ifndef PREFETCH_OPCCODE
++      opcode = *pc;
++#endif
++      // Seems like this happens twice per opcode. At worst this is only
++      // need at entry to the loop.
++      // DEBUGGER_SINGLE_STEP_NOTIFY();
++      /* Using this labels avoids double breakpoints when quickening and
++       * when returing from transition frames.
++       */
++  opcode_switch:
++      assert(istate == orig, "Corrupted istate");
++      /* QQQ Hmm this has knowledge of direction, ought to be a stack method */
++      assert(topOfStack >= istate->stack_limit(), "Stack overrun");
++      assert(topOfStack < istate->stack_base(), "Stack underrun");
++
++#ifdef USELABELS
++      DISPATCH(opcode);
++#else
++      switch (opcode)
++#endif
++      {
++      CASE(_nop):
++          UPDATE_PC_AND_CONTINUE(1);
++
++          /* Push miscellaneous constants onto the stack. */
++
++      CASE(_aconst_null):
++          SET_STACK_OBJECT(NULL, 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++
++#undef  OPC_CONST_n
++#define OPC_CONST_n(opcode, const_type, value)                          \
++      CASE(opcode):                                                     \
++          SET_STACK_ ## const_type(value, 0);                           \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++
++          OPC_CONST_n(_iconst_m1,   INT,       -1);
++          OPC_CONST_n(_iconst_0,    INT,        0);
++          OPC_CONST_n(_iconst_1,    INT,        1);
++          OPC_CONST_n(_iconst_2,    INT,        2);
++          OPC_CONST_n(_iconst_3,    INT,        3);
++          OPC_CONST_n(_iconst_4,    INT,        4);
++          OPC_CONST_n(_iconst_5,    INT,        5);
++          OPC_CONST_n(_fconst_0,    FLOAT,      0.0);
++          OPC_CONST_n(_fconst_1,    FLOAT,      1.0);
++          OPC_CONST_n(_fconst_2,    FLOAT,      2.0);
++
++#undef  OPC_CONST2_n
++#define OPC_CONST2_n(opcname, value, key, kind)                         \
++      CASE(_##opcname):                                                 \
++      {                                                                 \
++          SET_STACK_ ## kind(VM##key##Const##value(), 1);               \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);                         \
++      }
++         OPC_CONST2_n(dconst_0, Zero, double, DOUBLE);
++         OPC_CONST2_n(dconst_1, One,  double, DOUBLE);
++         OPC_CONST2_n(lconst_0, Zero, long, LONG);
++         OPC_CONST2_n(lconst_1, One,  long, LONG);
++
++         /* Load constant from constant pool: */
++
++          /* Push a 1-byte signed integer value onto the stack. */
++      CASE(_bipush):
++          SET_STACK_INT((jbyte)(pc[1]), 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1);
++
++          /* Push a 2-byte signed integer constant onto the stack. */
++      CASE(_sipush):
++          SET_STACK_INT((int16_t)Bytes::get_Java_u2(pc + 1), 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);
++
++          /* load from local variable */
++
++      CASE(_aload):
++          SET_STACK_OBJECT(LOCALS_OBJECT(pc[1]), 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1);
++
++      CASE(_iload):
++      CASE(_fload):
++          SET_STACK_SLOT(LOCALS_SLOT(pc[1]), 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1);
++
++      CASE(_lload):
++          SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(pc[1]), 1);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(2, 2);
++
++      CASE(_dload):
++          SET_STACK_DOUBLE_FROM_ADDR(LOCALS_DOUBLE_AT(pc[1]), 1);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(2, 2);
++
++#undef  OPC_LOAD_n
++#define OPC_LOAD_n(num)                                                 \
++      CASE(_aload_##num):                                               \
++          SET_STACK_OBJECT(LOCALS_OBJECT(num), 0);                      \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);                         \
++                                                                        \
++      CASE(_iload_##num):                                               \
++      CASE(_fload_##num):                                               \
++          SET_STACK_SLOT(LOCALS_SLOT(num), 0);                          \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);                         \
++                                                                        \
++      CASE(_lload_##num):                                               \
++          SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(num), 1);             \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);                         \
++      CASE(_dload_##num):                                               \
++          SET_STACK_DOUBLE_FROM_ADDR(LOCALS_DOUBLE_AT(num), 1);         \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
++
++          OPC_LOAD_n(0);
++          OPC_LOAD_n(1);
++          OPC_LOAD_n(2);
++          OPC_LOAD_n(3);
++
++          /* store to a local variable */
++
++      CASE(_astore):
++          astore(topOfStack, -1, locals, pc[1]);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(2, -1);
++
++      CASE(_istore):
++      CASE(_fstore):
++          SET_LOCALS_SLOT(STACK_SLOT(-1), pc[1]);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(2, -1);
++
++      CASE(_lstore):
++          SET_LOCALS_LONG(STACK_LONG(-1), pc[1]);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(2, -2);
++
++      CASE(_dstore):
++          SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), pc[1]);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(2, -2);
++
++      CASE(_wide): {
++          uint16_t reg = Bytes::get_Java_u2(pc + 2);
++
++          opcode = pc[1];
++          switch(opcode) {
++              case Bytecodes::_aload:
++                  SET_STACK_OBJECT(LOCALS_OBJECT(reg), 0);
++                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1);
++
++              case Bytecodes::_iload:
++              case Bytecodes::_fload:
++                  SET_STACK_SLOT(LOCALS_SLOT(reg), 0);
++                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1);
++
++              case Bytecodes::_lload:
++                  SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(reg), 1);
++                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, 2);
++
++              case Bytecodes::_dload:
++                  SET_STACK_DOUBLE_FROM_ADDR(LOCALS_LONG_AT(reg), 1);
++                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, 2);
++
++              case Bytecodes::_astore:
++                  astore(topOfStack, -1, locals, reg);
++                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, -1);
++
++              case Bytecodes::_istore:
++              case Bytecodes::_fstore:
++                  SET_LOCALS_SLOT(STACK_SLOT(-1), reg);
++                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, -1);
++
++              case Bytecodes::_lstore:
++                  SET_LOCALS_LONG(STACK_LONG(-1), reg);
++                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, -2);
++
++              case Bytecodes::_dstore:
++                  SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), reg);
++                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, -2);
++
++              case Bytecodes::_iinc: {
++                  int16_t offset = (int16_t)Bytes::get_Java_u2(pc+4);
++                  // Be nice to see what this generates.... QQQ
++                  SET_LOCALS_INT(LOCALS_INT(reg) + offset, reg);
++                  UPDATE_PC_AND_CONTINUE(6);
++              }
++              case Bytecodes::_ret:
++                  pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(reg));
++                  UPDATE_PC_AND_CONTINUE(0);
++              default:
++                  VM_JAVA_ERROR(vmSymbols::java_lang_InternalError(), "undefined opcode");
++          }
++      }
++
++
++#undef  OPC_STORE_n
++#define OPC_STORE_n(num)                                                \
++      CASE(_astore_##num):                                              \
++          astore(topOfStack, -1, locals, num);                          \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                        \
++      CASE(_istore_##num):                                              \
++      CASE(_fstore_##num):                                              \
++          SET_LOCALS_SLOT(STACK_SLOT(-1), num);                         \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
++
++          OPC_STORE_n(0);
++          OPC_STORE_n(1);
++          OPC_STORE_n(2);
++          OPC_STORE_n(3);
++
++#undef  OPC_DSTORE_n
++#define OPC_DSTORE_n(num)                                               \
++      CASE(_dstore_##num):                                              \
++          SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), num);                     \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);                        \
++      CASE(_lstore_##num):                                              \
++          SET_LOCALS_LONG(STACK_LONG(-1), num);                         \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);
++
++          OPC_DSTORE_n(0);
++          OPC_DSTORE_n(1);
++          OPC_DSTORE_n(2);
++          OPC_DSTORE_n(3);
++
++          /* stack pop, dup, and insert opcodes */
++
++
++      CASE(_pop):                /* Discard the top item on the stack */
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
++
++
++      CASE(_pop2):               /* Discard the top 2 items on the stack */
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);
++
++
++      CASE(_dup):               /* Duplicate the top item on the stack */
++          dup(topOfStack);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++
++      CASE(_dup2):              /* Duplicate the top 2 items on the stack */
++          dup2(topOfStack);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
++
++      CASE(_dup_x1):    /* insert top word two down */
++          dup_x1(topOfStack);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++
++      CASE(_dup_x2):    /* insert top word three down  */
++          dup_x2(topOfStack);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++
++      CASE(_dup2_x1):   /* insert top 2 slots three down */
++          dup2_x1(topOfStack);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
++
++      CASE(_dup2_x2):   /* insert top 2 slots four down */
++          dup2_x2(topOfStack);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
++
++      CASE(_swap): {        /* swap top two elements on the stack */
++          swap(topOfStack);
++          UPDATE_PC_AND_CONTINUE(1);
++      }
++
++          /* Perform various binary integer operations */
++
++#undef  OPC_INT_BINARY
++#define OPC_INT_BINARY(opcname, opname, test)                           \
++      CASE(_i##opcname):                                                \
++          if (test && (STACK_INT(-1) == 0)) {                           \
++              VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \
++                            "/ by int zero");                           \
++          }                                                             \
++          SET_STACK_INT(VMint##opname(STACK_INT(-2),                    \
++                                      STACK_INT(-1)),                   \
++                                      -2);                              \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                        \
++      CASE(_l##opcname):                                                \
++      {                                                                 \
++          if (test) {                                                   \
++            jlong l1 = STACK_LONG(-1);                                  \
++            if (VMlongEqz(l1)) {                                        \
++              VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \
++                            "/ by long zero");                          \
++            }                                                           \
++          }                                                             \
++          /* First long at (-1,-2) next long at (-3,-4) */              \
++          SET_STACK_LONG(VMlong##opname(STACK_LONG(-3),                 \
++                                        STACK_LONG(-1)),                \
++                                        -3);                            \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);                        \
++      }
++
++      OPC_INT_BINARY(add, Add, 0);
++      OPC_INT_BINARY(sub, Sub, 0);
++      OPC_INT_BINARY(mul, Mul, 0);
++      OPC_INT_BINARY(and, And, 0);
++      OPC_INT_BINARY(or,  Or,  0);
++      OPC_INT_BINARY(xor, Xor, 0);
++      OPC_INT_BINARY(div, Div, 1);
++      OPC_INT_BINARY(rem, Rem, 1);
++
++
++      /* Perform various binary floating number operations */
++      /* On some machine/platforms/compilers div zero check can be implicit */
++
++#undef  OPC_FLOAT_BINARY
++#define OPC_FLOAT_BINARY(opcname, opname)                                  \
++      CASE(_d##opcname): {                                                 \
++          SET_STACK_DOUBLE(VMdouble##opname(STACK_DOUBLE(-3),              \
++                                            STACK_DOUBLE(-1)),             \
++                                            -3);                           \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);                           \
++      }                                                                    \
++      CASE(_f##opcname):                                                   \
++          SET_STACK_FLOAT(VMfloat##opname(STACK_FLOAT(-2),                 \
++                                          STACK_FLOAT(-1)),                \
++                                          -2);                             \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
++
++
++     OPC_FLOAT_BINARY(add, Add);
++     OPC_FLOAT_BINARY(sub, Sub);
++     OPC_FLOAT_BINARY(mul, Mul);
++     OPC_FLOAT_BINARY(div, Div);
++     OPC_FLOAT_BINARY(rem, Rem);
++
++      /* Shift operations
++       * Shift left int and long: ishl, lshl
++       * Logical shift right int and long w/zero extension: iushr, lushr
++       * Arithmetic shift right int and long w/sign extension: ishr, lshr
++       */
++
++#undef  OPC_SHIFT_BINARY
++#define OPC_SHIFT_BINARY(opcname, opname)                               \
++      CASE(_i##opcname):                                                \
++         SET_STACK_INT(VMint##opname(STACK_INT(-2),                     \
++                                     STACK_INT(-1)),                    \
++                                     -2);                               \
++         UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                         \
++      CASE(_l##opcname):                                                \
++      {                                                                 \
++         SET_STACK_LONG(VMlong##opname(STACK_LONG(-2),                  \
++                                       STACK_INT(-1)),                  \
++                                       -2);                             \
++         UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                         \
++      }
++
++      OPC_SHIFT_BINARY(shl, Shl);
++      OPC_SHIFT_BINARY(shr, Shr);
++      OPC_SHIFT_BINARY(ushr, Ushr);
++
++     /* Increment local variable by constant */
++      CASE(_iinc):
++      {
++          // locals[pc[1]].j.i += (jbyte)(pc[2]);
++          SET_LOCALS_INT(LOCALS_INT(pc[1]) + (jbyte)(pc[2]), pc[1]);
++          UPDATE_PC_AND_CONTINUE(3);
++      }
++
++     /* negate the value on the top of the stack */
++
++      CASE(_ineg):
++         SET_STACK_INT(VMintNeg(STACK_INT(-1)), -1);
++         UPDATE_PC_AND_CONTINUE(1);
++
++      CASE(_fneg):
++         SET_STACK_FLOAT(VMfloatNeg(STACK_FLOAT(-1)), -1);
++         UPDATE_PC_AND_CONTINUE(1);
++
++      CASE(_lneg):
++      {
++         SET_STACK_LONG(VMlongNeg(STACK_LONG(-1)), -1);
++         UPDATE_PC_AND_CONTINUE(1);
++      }
++
++      CASE(_dneg):
++      {
++         SET_STACK_DOUBLE(VMdoubleNeg(STACK_DOUBLE(-1)), -1);
++         UPDATE_PC_AND_CONTINUE(1);
++      }
++
++      /* Conversion operations */
++
++      CASE(_i2f):       /* convert top of stack int to float */
++         SET_STACK_FLOAT(VMint2Float(STACK_INT(-1)), -1);
++         UPDATE_PC_AND_CONTINUE(1);
++
++      CASE(_i2l):       /* convert top of stack int to long */
++      {
++          // this is ugly QQQ
++          jlong r = VMint2Long(STACK_INT(-1));
++          MORE_STACK(-1); // Pop
++          SET_STACK_LONG(r, 1);
++
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
++      }
++
++      CASE(_i2d):       /* convert top of stack int to double */
++      {
++          // this is ugly QQQ (why cast to jlong?? )
++          jdouble r = (jlong)STACK_INT(-1);
++          MORE_STACK(-1); // Pop
++          SET_STACK_DOUBLE(r, 1);
++
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
++      }
++
++      CASE(_l2i):       /* convert top of stack long to int */
++      {
++          jint r = VMlong2Int(STACK_LONG(-1));
++          MORE_STACK(-2); // Pop
++          SET_STACK_INT(r, 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++      }
++
++      CASE(_l2f):   /* convert top of stack long to float */
++      {
++          jlong r = STACK_LONG(-1);
++          MORE_STACK(-2); // Pop
++          SET_STACK_FLOAT(VMlong2Float(r), 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++      }
++
++      CASE(_l2d):       /* convert top of stack long to double */
++      {
++          jlong r = STACK_LONG(-1);
++          MORE_STACK(-2); // Pop
++          SET_STACK_DOUBLE(VMlong2Double(r), 1);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
++      }
++
++      CASE(_f2i):  /* Convert top of stack float to int */
++          SET_STACK_INT(SharedRuntime::f2i(STACK_FLOAT(-1)), -1);
++          UPDATE_PC_AND_CONTINUE(1);
++
++      CASE(_f2l):  /* convert top of stack float to long */
++      {
++          jlong r = SharedRuntime::f2l(STACK_FLOAT(-1));
++          MORE_STACK(-1); // POP
++          SET_STACK_LONG(r, 1);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
++      }
++
++      CASE(_f2d):  /* convert top of stack float to double */
++      {
++          jfloat f;
++          jdouble r;
++          f = STACK_FLOAT(-1);
++#ifdef IA64
++          // IA64 gcc bug
++          r = ( f == 0.0f ) ? (jdouble) f : (jdouble) f + ia64_double_zero;
++#else
++          r = (jdouble) f;
++#endif
++          MORE_STACK(-1); // POP
++          SET_STACK_DOUBLE(r, 1);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
++      }
++
++      CASE(_d2i): /* convert top of stack double to int */
++      {
++          jint r1 = SharedRuntime::d2i(STACK_DOUBLE(-1));
++          MORE_STACK(-2);
++          SET_STACK_INT(r1, 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++      }
++
++      CASE(_d2f): /* convert top of stack double to float */
++      {
++          jfloat r1 = VMdouble2Float(STACK_DOUBLE(-1));
++          MORE_STACK(-2);
++          SET_STACK_FLOAT(r1, 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++      }
++
++      CASE(_d2l): /* convert top of stack double to long */
++      {
++          jlong r1 = SharedRuntime::d2l(STACK_DOUBLE(-1));
++          MORE_STACK(-2);
++          SET_STACK_LONG(r1, 1);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
++      }
++
++      CASE(_i2b):
++          SET_STACK_INT(VMint2Byte(STACK_INT(-1)), -1);
++          UPDATE_PC_AND_CONTINUE(1);
++
++      CASE(_i2c):
++          SET_STACK_INT(VMint2Char(STACK_INT(-1)), -1);
++          UPDATE_PC_AND_CONTINUE(1);
++
++      CASE(_i2s):
++          SET_STACK_INT(VMint2Short(STACK_INT(-1)), -1);
++          UPDATE_PC_AND_CONTINUE(1);
++
++      /* comparison operators */
++
++
++#define COMPARISON_OP(name, comparison)                                      \
++      CASE(_if_icmp##name): {                                                \
++          int skip = (STACK_INT(-2) comparison STACK_INT(-1))                \
++                      ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;             \
++          address branch_pc = pc;                                            \
++          UPDATE_PC_AND_TOS(skip, -2);                                       \
++          DO_BACKEDGE_CHECKS(skip, branch_pc);                               \
++          CONTINUE;                                                          \
++      }                                                                      \
++      CASE(_if##name): {                                                     \
++          int skip = (STACK_INT(-1) comparison 0)                            \
++                      ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;             \
++          address branch_pc = pc;                                            \
++          UPDATE_PC_AND_TOS(skip, -1);                                       \
++          DO_BACKEDGE_CHECKS(skip, branch_pc);                               \
++          CONTINUE;                                                          \
++      }
++
++#define COMPARISON_OP2(name, comparison)                                     \
++      COMPARISON_OP(name, comparison)                                        \
++      CASE(_if_acmp##name): {                                                \
++          int skip = (STACK_OBJECT(-2) comparison STACK_OBJECT(-1))          \
++                       ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;            \
++          address branch_pc = pc;                                            \
++          UPDATE_PC_AND_TOS(skip, -2);                                       \
++          DO_BACKEDGE_CHECKS(skip, branch_pc);                               \
++          CONTINUE;                                                          \
++      }
++
++#define NULL_COMPARISON_NOT_OP(name)                                         \
++      CASE(_if##name): {                                                     \
++          int skip = (!(STACK_OBJECT(-1) == 0))                              \
++                      ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;             \
++          address branch_pc = pc;                                            \
++          UPDATE_PC_AND_TOS(skip, -1);                                       \
++          DO_BACKEDGE_CHECKS(skip, branch_pc);                               \
++          CONTINUE;                                                          \
++      }
++
++#define NULL_COMPARISON_OP(name)                                             \
++      CASE(_if##name): {                                                     \
++          int skip = ((STACK_OBJECT(-1) == 0))                               \
++                      ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;             \
++          address branch_pc = pc;                                            \
++          UPDATE_PC_AND_TOS(skip, -1);                                       \
++          DO_BACKEDGE_CHECKS(skip, branch_pc);                               \
++          CONTINUE;                                                          \
++      }
++      COMPARISON_OP(lt, <);
++      COMPARISON_OP(gt, >);
++      COMPARISON_OP(le, <=);
++      COMPARISON_OP(ge, >=);
++      COMPARISON_OP2(eq, ==);  /* include ref comparison */
++      COMPARISON_OP2(ne, !=);  /* include ref comparison */
++      NULL_COMPARISON_OP(null);
++      NULL_COMPARISON_NOT_OP(nonnull);
++
++      /* Goto pc at specified offset in switch table. */
++
++      CASE(_tableswitch): {
++          jint* lpc  = (jint*)VMalignWordUp(pc+1);
++          int32_t  key  = STACK_INT(-1);
++          int32_t  low  = Bytes::get_Java_u4((address)&lpc[1]);
++          int32_t  high = Bytes::get_Java_u4((address)&lpc[2]);
++          int32_t  skip;
++          key -= low;
++          skip = ((uint32_t) key > (uint32_t)(high - low))
++                      ? Bytes::get_Java_u4((address)&lpc[0])
++                      : Bytes::get_Java_u4((address)&lpc[key + 3]);
++          // Does this really need a full backedge check (osr?)
++          address branch_pc = pc;
++          UPDATE_PC_AND_TOS(skip, -1);
++          DO_BACKEDGE_CHECKS(skip, branch_pc);
++          CONTINUE;
++      }
++
++      /* Goto pc whose table entry matches specified key */
++
++      CASE(_lookupswitch): {
++          jint* lpc  = (jint*)VMalignWordUp(pc+1);
++          int32_t  key  = STACK_INT(-1);
++          int32_t  skip = Bytes::get_Java_u4((address) lpc); /* default amount */
++          int32_t  npairs = Bytes::get_Java_u4((address) &lpc[1]);
++          while (--npairs >= 0) {
++              lpc += 2;
++              if (key == (int32_t)Bytes::get_Java_u4((address)lpc)) {
++                  skip = Bytes::get_Java_u4((address)&lpc[1]);
++                  break;
++              }
++          }
++          address branch_pc = pc;
++          UPDATE_PC_AND_TOS(skip, -1);
++          DO_BACKEDGE_CHECKS(skip, branch_pc);
++          CONTINUE;
++      }
++
++      CASE(_fcmpl):
++      CASE(_fcmpg):
++      {
++          SET_STACK_INT(VMfloatCompare(STACK_FLOAT(-2),
++                                        STACK_FLOAT(-1),
++                                        (opcode == Bytecodes::_fcmpl ? -1 : 1)),
++                        -2);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
++      }
++
++      CASE(_dcmpl):
++      CASE(_dcmpg):
++      {
++          int r = VMdoubleCompare(STACK_DOUBLE(-3),
++                                  STACK_DOUBLE(-1),
++                                  (opcode == Bytecodes::_dcmpl ? -1 : 1));
++          MORE_STACK(-4); // Pop
++          SET_STACK_INT(r, 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++      }
++
++      CASE(_lcmp):
++      {
++          int r = VMlongCompare(STACK_LONG(-3), STACK_LONG(-1));
++          MORE_STACK(-4);
++          SET_STACK_INT(r, 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
++      }
++
++
++      /* Return from a method */
++
++      CASE(_areturn):
++      CASE(_ireturn):
++      CASE(_freturn):
++      {
++          // Allow a safepoint before returning to frame manager.
++          SAFEPOINT;
++
++          goto handle_return;
++      }
++
++      CASE(_lreturn):
++      CASE(_dreturn):
++      {
++          // Allow a safepoint before returning to frame manager.
++          SAFEPOINT;
++          goto handle_return;
++      }
++
++      CASE(_return_register_finalizer): {
++
++          oop rcvr = LOCALS_OBJECT(0);
++          if (rcvr->klass()->klass_part()->has_finalizer()) {
++            CALL_VM(InterpreterRuntime::register_finalizer(THREAD, rcvr), handle_exception);
++          }
++          goto handle_return;
++      }
++      CASE(_return): {
++
++          // Allow a safepoint before returning to frame manager.
++          SAFEPOINT;
++          goto handle_return;
++      }
++
++      /* Array access byte-codes */
++
++      /* Every array access byte-code starts out like this */
++//        arrayOopDesc* arrObj = (arrayOopDesc*)STACK_OBJECT(arrayOff);
++#define ARRAY_INTRO(arrayOff)                                                  \
++      arrayOop arrObj = (arrayOop)STACK_OBJECT(arrayOff);                      \
++      jint     index  = STACK_INT(arrayOff + 1);                               \
++      char message[jintAsStringSize];                                          \
++      CHECK_NULL(arrObj);                                                      \
++      if ((uint32_t)index >= (uint32_t)arrObj->length()) {                     \
++          sprintf(message, "%d", index);                                       \
++          VM_JAVA_ERROR(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), \
++                        message);                                              \
++      }
++
++      /* 32-bit loads. These handle conversion from < 32-bit types */
++#define ARRAY_LOADTO32(T, T2, format, stackRes, extra)                                \
++      {                                                                               \
++          ARRAY_INTRO(-2);                                                            \
++          extra;                                                                      \
++          SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), \
++                           -2);                                                       \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                                      \
++      }
++
++      /* 64-bit loads */
++#define ARRAY_LOADTO64(T,T2, stackRes, extra)                                              \
++      {                                                                                    \
++          ARRAY_INTRO(-2);                                                                 \
++          SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), -1); \
++          extra;                                                                           \
++          UPDATE_PC_AND_CONTINUE(1);                                            \
++      }
++
++      CASE(_iaload):
++          ARRAY_LOADTO32(T_INT, jint,   "%d",   STACK_INT, 0);
++      CASE(_faload):
++          ARRAY_LOADTO32(T_FLOAT, jfloat, "%f",   STACK_FLOAT, 0);
++      CASE(_aaload):
++          ARRAY_LOADTO32(T_OBJECT, oop,   INTPTR_FORMAT, STACK_OBJECT, 0);
++      CASE(_baload):
++          ARRAY_LOADTO32(T_BYTE, jbyte,  "%d",   STACK_INT, 0);
++      CASE(_caload):
++          ARRAY_LOADTO32(T_CHAR,  jchar, "%d",   STACK_INT, 0);
++      CASE(_saload):
++          ARRAY_LOADTO32(T_SHORT, jshort, "%d",   STACK_INT, 0);
++      CASE(_laload):
++          ARRAY_LOADTO64(T_LONG, jlong, STACK_LONG, 0);
++      CASE(_daload):
++          ARRAY_LOADTO64(T_DOUBLE, jdouble, STACK_DOUBLE, 0);
++
++      /* 32-bit stores. These handle conversion to < 32-bit types */
++#define ARRAY_STOREFROM32(T, T2, format, stackSrc, extra)                            \
++      {                                                                              \
++          ARRAY_INTRO(-3);                                                           \
++          extra;                                                                     \
++          *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3);                                     \
++      }
++
++      /* 64-bit stores */
++#define ARRAY_STOREFROM64(T, T2, stackSrc, extra)                                    \
++      {                                                                              \
++          ARRAY_INTRO(-4);                                                           \
++          extra;                                                                     \
++          *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -4);                                     \
++      }
++
++      CASE(_iastore):
++          ARRAY_STOREFROM32(T_INT, jint,   "%d",   STACK_INT, 0);
++      CASE(_fastore):
++          ARRAY_STOREFROM32(T_FLOAT, jfloat, "%f",   STACK_FLOAT, 0);
++      /*
++       * This one looks different because of the assignability check
++       */
++      CASE(_aastore): {
++          oop rhsObject = STACK_OBJECT(-1);
++          ARRAY_INTRO( -3);
++          // arrObj, index are set
++          if (rhsObject != NULL) {
++            /* Check assignability of rhsObject into arrObj */
++            klassOop rhsKlassOop = rhsObject->klass(); // EBX (subclass)
++            assert(arrObj->klass()->klass()->klass_part()->oop_is_objArrayKlass(), "Ack not an objArrayKlass");
++            klassOop elemKlassOop = ((objArrayKlass*) arrObj->klass()->klass_part())->element_klass(); // superklass EAX
++            //
++            // Check for compatibilty. This check must not GC!!
++            // Seems way more expensive now that we must dispatch
++            //
++            if (rhsKlassOop != elemKlassOop && !rhsKlassOop->klass_part()->is_subtype_of(elemKlassOop)) { // ebx->is...
++              VM_JAVA_ERROR(vmSymbols::java_lang_ArrayStoreException(), "");
++            }
++          }
++          oop* elem_loc = (oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop));
++          // *(oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop)) = rhsObject;
++          *elem_loc = rhsObject;
++          // Mark the card
++          OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)elem_loc >> CardTableModRefBS::card_shift], 0);
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3);
++      }
++      CASE(_bastore):
++          ARRAY_STOREFROM32(T_BYTE, jbyte,  "%d",   STACK_INT, 0);
++      CASE(_castore):
++          ARRAY_STOREFROM32(T_CHAR, jchar,  "%d",   STACK_INT, 0);
++      CASE(_sastore):
++          ARRAY_STOREFROM32(T_SHORT, jshort, "%d",   STACK_INT, 0);
++      CASE(_lastore):
++          ARRAY_STOREFROM64(T_LONG, jlong, STACK_LONG, 0);
++      CASE(_dastore):
++          ARRAY_STOREFROM64(T_DOUBLE, jdouble, STACK_DOUBLE, 0);
++
++      CASE(_arraylength):
++      {
++          arrayOop ary = (arrayOop) STACK_OBJECT(-1);
++          CHECK_NULL(ary);
++          SET_STACK_INT(ary->length(), -1);
++          UPDATE_PC_AND_CONTINUE(1);
++      }
++
++      /* monitorenter and monitorexit for locking/unlocking an object */
++
++      CASE(_monitorenter): {
++        oop lockee = STACK_OBJECT(-1);
++        // derefing's lockee ought to provoke implicit null check
++        CHECK_NULL(lockee);
++        // find a free monitor or one already allocated for this object
++        // if we find a matching object then we need a new monitor
++        // since this is recursive enter
++        BasicObjectLock* limit = istate->monitor_base();
++        BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base();
++        BasicObjectLock* entry = NULL;
++        while (most_recent != limit ) {
++          if (most_recent->obj() == NULL) entry = most_recent;
++          else if (most_recent->obj() == lockee) break;
++          most_recent++;
++        }
++        if (entry != NULL) {
++          entry->set_obj(lockee);
++          markOop displaced = lockee->mark()->set_unlocked();
++          entry->lock()->set_displaced_header(displaced);
++          if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) {
++            // Is it simple recursive case?
++            if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
++              entry->lock()->set_displaced_header(NULL);
++            } else {
++              CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
++            }
++          }
++          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
++        } else {
++          istate->set_msg(more_monitors);
++          UPDATE_PC_AND_RETURN(0); // Re-execute
++        }
++      }
++
++      CASE(_monitorexit): {
++        oop lockee = STACK_OBJECT(-1);
++        CHECK_NULL(lockee);
++        // derefing's lockee ought to provoke implicit null check
++        // find our monitor slot
++        BasicObjectLock* limit = istate->monitor_base();
++        BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base();
++        while (most_recent != limit ) {
++          if ((most_recent)->obj() == lockee) {
++            BasicLock* lock = most_recent->lock();
++            markOop header = lock->displaced_header();
++            most_recent->set_obj(NULL);
++            // If it isn't recursive we either must swap old header or call the runtime
++            if (header != NULL) {
++              if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) {
++                // restore object for the slow case
++                most_recent->set_obj(lockee);
++                CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception);
++              }
++            }
++            UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
++          }
++          most_recent++;
++        }
++        // Need to throw illegal monitor state exception
++        CALL_VM(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD), handle_exception);
++        // Should never reach here...
++        assert(false, "Should have thrown illegal monitor exception");
++      }
++
++      /* All of the non-quick opcodes. */
++
++      /* -Set clobbersCpIndex true if the quickened opcode clobbers the
++       *  constant pool index in the instruction.
++       */
++      CASE(_getfield):
++      CASE(_getstatic):
++        {
++          u2 index;
++          ConstantPoolCacheEntry* cache;
++          index = Bytes::get_native_u2(pc+1);
++
++          // QQQ Need to make this as inlined as possible. Probably need to
++          // split all the bytecode cases out so c++ compiler has a chance
++          // for constant prop to fold everything possible away.
++
++          cache = cp->entry_at(index);
++          if (!cache->is_resolved((Bytecodes::Code)opcode)) {
++            CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode),
++                    handle_exception);
++            cache = cp->entry_at(index);
++          }
++
++#ifdef VM_JVMTI
++          if (_jvmti_interp_events) {
++            int *count_addr;
++            oop obj;
++            // Check to see if a field modification watch has been set
++            // before we take the time to call into the VM.
++            count_addr = (int *)JvmtiExport::get_field_access_count_addr();
++            if ( *count_addr > 0 ) {
++              if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) {
++                obj = (oop)NULL;
++              } else {
++                obj = (oop) STACK_OBJECT(-1);
++              }
++              CALL_VM(InterpreterRuntime::post_field_access(THREAD,
++                                          obj,
++                                          cache),
++                                          handle_exception);
++            }
++          }
++#endif /* VM_JVMTI */
++
++          oop obj;
++          if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) {
++            obj = (oop) cache->f1();
++            MORE_STACK(1);  // Assume single slot push
++          } else {
++            obj = (oop) STACK_OBJECT(-1);
++            CHECK_NULL(obj);
++          }
++
++          //
++          // Now store the result on the stack
++          //
++          TosState tos_type = cache->flag_state();
++          int field_offset = cache->f2();
++          if (cache->is_volatile()) {
++            if (tos_type == atos) {
++              SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1);
++            } else if (tos_type == itos) {
++              SET_STACK_INT(obj->int_field_acquire(field_offset), -1);
++            } else if (tos_type == ltos) {
++              SET_STACK_LONG(obj->long_field_acquire(field_offset), 0);
++              MORE_STACK(1);
++            } else if (tos_type == btos) {
++              SET_STACK_INT(obj->byte_field_acquire(field_offset), -1);
++            } else if (tos_type == ctos) {
++              SET_STACK_INT(obj->char_field_acquire(field_offset), -1);
++            } else if (tos_type == stos) {
++              SET_STACK_INT(obj->short_field_acquire(field_offset), -1);
++            } else if (tos_type == ftos) {
++              SET_STACK_FLOAT(obj->float_field_acquire(field_offset), -1);
++            } else {
++              SET_STACK_DOUBLE(obj->double_field_acquire(field_offset), 0);
++              MORE_STACK(1);
++            }
++          } else {
++            if (tos_type == atos) {
++              SET_STACK_OBJECT(obj->obj_field(field_offset), -1);
++            } else if (tos_type == itos) {
++              SET_STACK_INT(obj->int_field(field_offset), -1);
++            } else if (tos_type == ltos) {
++              SET_STACK_LONG(obj->long_field(field_offset), 0);
++              MORE_STACK(1);
++            } else if (tos_type == btos) {
++              SET_STACK_INT(obj->byte_field(field_offset), -1);
++            } else if (tos_type == ctos) {
++              SET_STACK_INT(obj->char_field(field_offset), -1);
++            } else if (tos_type == stos) {
++              SET_STACK_INT(obj->short_field(field_offset), -1);
++            } else if (tos_type == ftos) {
++              SET_STACK_FLOAT(obj->float_field(field_offset), -1);
++            } else {
++              SET_STACK_DOUBLE(obj->double_field(field_offset), 0);
++              MORE_STACK(1);
++            }
++          }
++
++          UPDATE_PC_AND_CONTINUE(3);
++         }
++
++      CASE(_putfield):
++      CASE(_putstatic):
++        {
++          u2 index = Bytes::get_native_u2(pc+1);
++          ConstantPoolCacheEntry* cache = cp->entry_at(index);
++          if (!cache->is_resolved((Bytecodes::Code)opcode)) {
++            CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode),
++                    handle_exception);
++            cache = cp->entry_at(index);
++          }
++
++#ifdef VM_JVMTI
++          if (_jvmti_interp_events) {
++            int *count_addr;
++            oop obj;
++            // Check to see if a field modification watch has been set
++            // before we take the time to call into the VM.
++            count_addr = (int *)JvmtiExport::get_field_modification_count_addr();
++            if ( *count_addr > 0 ) {
++              if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) {
++                obj = (oop)NULL;
++              }
++              else {
++                if (cache->is_long() || cache->is_double()) {
++                  obj = (oop) STACK_OBJECT(-3);
++                } else {
++                  obj = (oop) STACK_OBJECT(-2);
++                }
++              }
++
++              CALL_VM(InterpreterRuntime::post_field_modification(THREAD,
++                                          obj,
++                                          cache,
++                                          (jvalue *)STACK_SLOT(-1)),
++                                          handle_exception);
++            }
++          }
++#endif /* VM_JVMTI */
++
++          // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases
++          // out so c++ compiler has a chance for constant prop to fold everything possible away.
++
++          oop obj;
++          int count;
++          TosState tos_type = cache->flag_state();
++
++          count = -1;
++          if (tos_type == ltos || tos_type == dtos) {
++            --count;
++          }
++          if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) {
++            obj = (oop) cache->f1();
++          } else {
++            --count;
++            obj = (oop) STACK_OBJECT(count);
++            CHECK_NULL(obj);
++          }
++
++          //
++          // Now store the result
++          //
++          int field_offset = cache->f2();
++          if (cache->is_volatile()) {
++            if (tos_type == itos) {
++              obj->release_int_field_put(field_offset, STACK_INT(-1));
++            } else if (tos_type == atos) {
++              obj->release_obj_field_put(field_offset, STACK_OBJECT(-1));
++              OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0);
++            } else if (tos_type == btos) {
++              obj->release_byte_field_put(field_offset, STACK_INT(-1));
++            } else if (tos_type == ltos) {
++              obj->release_long_field_put(field_offset, STACK_LONG(-1));
++            } else if (tos_type == ctos) {
++              obj->release_char_field_put(field_offset, STACK_INT(-1));
++            } else if (tos_type == stos) {
++              obj->release_short_field_put(field_offset, STACK_INT(-1));
++            } else if (tos_type == ftos) {
++              obj->release_float_field_put(field_offset, STACK_FLOAT(-1));
++            } else {
++              obj->release_double_field_put(field_offset, STACK_DOUBLE(-1));
++            }
++            OrderAccess::storeload();
++          } else {
++            if (tos_type == itos) {
++              obj->int_field_put(field_offset, STACK_INT(-1));
++            } else if (tos_type == atos) {
++              obj->obj_field_put(field_offset, STACK_OBJECT(-1));
++              OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0);
++            } else if (tos_type == btos) {
++              obj->byte_field_put(field_offset, STACK_INT(-1));
++            } else if (tos_type == ltos) {
++              obj->long_field_put(field_offset, STACK_LONG(-1));
++            } else if (tos_type == ctos) {
++              obj->char_field_put(field_offset, STACK_INT(-1));
++            } else if (tos_type == stos) {
++              obj->short_field_put(field_offset, STACK_INT(-1));
++            } else if (tos_type == ftos) {
++              obj->float_field_put(field_offset, STACK_FLOAT(-1));
++            } else {
++              obj->double_field_put(field_offset, STACK_DOUBLE(-1));
++            }
++          }
++
++          UPDATE_PC_AND_TOS_AND_CONTINUE(3, count);
++        }
++
++      CASE(_new): {
++        u2 index = Bytes::get_Java_u2(pc+1);
++        constantPoolOop constants = istate->method()->constants();
++        if (!constants->tag_at(index).is_unresolved_klass()) {
++          // Make sure klass is initialized and doesn't have a finalizer
++          oop entry = (klassOop) *constants->obj_at_addr(index);
++          assert(entry->is_klass(), "Should be resolved klass");
++          klassOop k_entry = (klassOop) entry;
++          assert(k_entry->klass_part()->oop_is_instance(), "Should be instanceKlass");
++          instanceKlass* ik = (instanceKlass*) k_entry->klass_part();
++          if ( ik->is_initialized() && ik->can_be_fastpath_allocated() ) {
++            size_t obj_size = ik->size_helper();
++            oop result = NULL;
++            // If the TLAB isn't pre-zeroed then we'll have to do it
++            bool need_zero = !ZeroTLAB;
++            if (UseTLAB) {
++              result = (oop) THREAD->tlab().allocate(obj_size);
++            }
++            if (result == NULL) {
++              need_zero = true;
++              // Try allocate in shared eden
++        retry:
++              HeapWord* compare_to = *Universe::heap()->top_addr();
++              HeapWord* new_top = compare_to + obj_size;
++              if (new_top <= *Universe::heap()->end_addr()) {
++                if (Atomic::cmpxchg_ptr(new_top, Universe::heap()->top_addr(), compare_to) != compare_to) {
++                  goto retry;
++                }
++                result = (oop) compare_to;
++              }
++            }
++            if (result != NULL) {
++              // Initialize object (if nonzero size and need) and then the header
++              if (need_zero ) {
++                HeapWord* to_zero = (HeapWord*) result + sizeof(oopDesc) / oopSize;
++                obj_size -= sizeof(oopDesc) / oopSize;
++                if (obj_size > 0 ) {
++                  memset(to_zero, 0, obj_size * HeapWordSize);
++                }
++              }
++              if (UseBiasedLocking) {
++                result->set_mark(ik->prototype_header());
++              } else {
++                result->set_mark(markOopDesc::prototype());
++              }
++              result->set_klass(k_entry);
++              SET_STACK_OBJECT(result, 0);
++              UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);
++            }
++          }
++        }
++        // Slow case allocation
++        CALL_VM(InterpreterRuntime::_new(THREAD, METHOD->constants(), index),
++                handle_exception);
++        SET_STACK_OBJECT(THREAD->vm_result(), 0);
++        THREAD->set_vm_result(NULL);
++        UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);
++      }
++      CASE(_anewarray): {
++        u2 index = Bytes::get_Java_u2(pc+1);
++        jint size = STACK_INT(-1);
++        CALL_VM(InterpreterRuntime::anewarray(THREAD, METHOD->constants(), index, size),
++                handle_exception);
++        SET_STACK_OBJECT(THREAD->vm_result(), -1);
++        THREAD->set_vm_result(NULL);
++        UPDATE_PC_AND_CONTINUE(3);
++      }
++      CASE(_multianewarray): {
++        jint dims = *(pc+3);
++        jint size = STACK_INT(-1);
++        // stack grows down, dimensions are up!
++        jint *dimarray =
++                   (jint*)&topOfStack[dims * Interpreter::stackElementWords()+
++                                      Interpreter::stackElementWords()-1];
++        //adjust pointer to start of stack element
++        CALL_VM(InterpreterRuntime::multianewarray(THREAD, dimarray),
++                handle_exception);
++        SET_STACK_OBJECT(THREAD->vm_result(), -dims);
++        THREAD->set_vm_result(NULL);
++        UPDATE_PC_AND_TOS_AND_CONTINUE(4, -(dims-1));
++      }
++      CASE(_checkcast):
++          if (STACK_OBJECT(-1) != NULL) {
++            u2 index = Bytes::get_Java_u2(pc+1);
++            if (ProfileInterpreter) {
++              // needs Profile_checkcast QQQ
++              ShouldNotReachHere();
++            }
++            // Constant pool may have actual klass or unresolved klass. If it is
++            // unresolved we must resolve it
++            if (METHOD->constants()->tag_at(index).is_unresolved_klass()) {
++              CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception);
++            }
++            klassOop klassOf = (klassOop) *(METHOD->constants()->obj_at_addr(index));
++            klassOop objKlassOop = STACK_OBJECT(-1)->klass(); //ebx
++            //
++            // Check for compatibilty. This check must not GC!!
++            // Seems way more expensive now that we must dispatch
++            //
++            if (objKlassOop != klassOf &&
++                !objKlassOop->klass_part()->is_subtype_of(klassOf)) {
++              ResourceMark rm(THREAD);
++              const char* objName = Klass::cast(objKlassOop)->external_name();
++              const char* klassName = Klass::cast(klassOf)->external_name();
++              char* message = SharedRuntime::generate_class_cast_message(
++                objName, klassName);
++              VM_JAVA_ERROR(vmSymbols::java_lang_ClassCastException(), message);
++            }
++          } else {
++            if (UncommonNullCast) {
++//              istate->method()->set_null_cast_seen();
++// [RGV] Not sure what to do here!
++
++            }
++          }
++          UPDATE_PC_AND_CONTINUE(3);
++
++      CASE(_instanceof):
++          if (STACK_OBJECT(-1) == NULL) {
++            SET_STACK_INT(0, -1);
++          } else {
++            u2 index = Bytes::get_Java_u2(pc+1);
++            // Constant pool may have actual klass or unresolved klass. If it is
++            // unresolved we must resolve it
++            if (METHOD->constants()->tag_at(index).is_unresolved_klass()) {
++              CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception);
++            }
++            klassOop klassOf = (klassOop) *(METHOD->constants()->obj_at_addr(index));
++            klassOop objKlassOop = STACK_OBJECT(-1)->klass();
++            //
++            // Check for compatibilty. This check must not GC!!
++            // Seems way more expensive now that we must dispatch
++            //
++            if ( objKlassOop == klassOf || objKlassOop->klass_part()->is_subtype_of(klassOf)) {
++              SET_STACK_INT(1, -1);
++            } else {
++              SET_STACK_INT(0, -1);
++            }
++          }
++          UPDATE_PC_AND_CONTINUE(3);
++
++      CASE(_ldc_w):
++      CASE(_ldc):
++        {
++          u2 index;
++          bool wide = false;
++          int incr = 2; // frequent case
++          if (opcode == Bytecodes::_ldc) {
++            index = pc[1];
++          } else {
++            index = Bytes::get_Java_u2(pc+1);
++            incr = 3;
++            wide = true;
++          }
++
++          constantPoolOop constants = METHOD->constants();
++          switch (constants->tag_at(index).value()) {
++          case JVM_CONSTANT_Integer:
++            SET_STACK_INT(constants->int_at(index), 0);
++            break;
++
++          case JVM_CONSTANT_Float:
++            SET_STACK_FLOAT(constants->float_at(index), 0);
++            break;
++
++          case JVM_CONSTANT_String:
++            SET_STACK_OBJECT(constants->resolved_string_at(index), 0);
++            break;
++
++          case JVM_CONSTANT_Class:
++            SET_STACK_OBJECT(constants->resolved_klass_at(index)->klass_part()->java_mirror(), 0);
++            break;
++
++          case JVM_CONSTANT_UnresolvedString:
++          case JVM_CONSTANT_UnresolvedClass:
++          case JVM_CONSTANT_UnresolvedClassInError:
++            CALL_VM(InterpreterRuntime::ldc(THREAD, wide), handle_exception);
++            SET_STACK_OBJECT(THREAD->vm_result(), 0);
++            THREAD->set_vm_result(NULL);
++            break;
++
++#if 0
++          CASE(_fast_igetfield):
++          CASE(_fastagetfield):
++          CASE(_fast_aload_0):
++          CASE(_fast_iaccess_0):
++          CASE(__fast_aaccess_0):
++          CASE(_fast_linearswitch):
++          CASE(_fast_binaryswitch):
++            fatal("unsupported fast bytecode");
++#endif
++
++          default:  ShouldNotReachHere();
++          }
++          UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1);
++        }
++
++      CASE(_ldc2_w):
++        {
++          u2 index = Bytes::get_Java_u2(pc+1);
++
++          constantPoolOop constants = METHOD->constants();
++          switch (constants->tag_at(index).value()) {
++
++          case JVM_CONSTANT_Long:
++             SET_STACK_LONG(constants->long_at(index), 1);
++            break;
++
++          case JVM_CONSTANT_Double:
++             SET_STACK_DOUBLE(constants->double_at(index), 1);
++            break;
++          default:  ShouldNotReachHere();
++          }
++          UPDATE_PC_AND_TOS_AND_CONTINUE(3, 2);
++        }
++
++      CASE(_invokeinterface): {
++        u2 index = Bytes::get_native_u2(pc+1);
++
++        // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases
++        // out so c++ compiler has a chance for constant prop to fold everything possible away.
++
++        ConstantPoolCacheEntry* cache = cp->entry_at(index);
++        if (!cache->is_resolved((Bytecodes::Code)opcode)) {
++          CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode),
++                  handle_exception);
++          cache = cp->entry_at(index);
++        }
++
++        istate->set_msg(call_method);
++
++        // Special case of invokeinterface called for virtual method of
++        // java.lang.Object.  See cpCacheOop.cpp for details.
++        // This code isn't produced by javac, but could be produced by
++        // another compliant java compiler.
++        if (cache->is_methodInterface()) {
++          methodOop callee;
++          CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
++          if (cache->is_vfinal()) {
++            callee = (methodOop) cache->f2();
++          } else {
++            // get receiver
++            int parms = cache->parameter_size();
++            // Same comments as invokevirtual apply here
++            instanceKlass* rcvrKlass = (instanceKlass*)
++                                 STACK_OBJECT(-parms)->klass()->klass_part();
++            callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()];
++          }
++          istate->set_callee(callee);
++          istate->set_callee_entry_point(callee->from_interpreted_entry());
++#ifdef VM_JVMTI
++          if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) {
++            istate->set_callee_entry_point(callee->interpreter_entry());
++          }
++#endif /* VM_JVMTI */
++          istate->set_bcp_advance(5);
++          UPDATE_PC_AND_RETURN(0); // I'll be back...
++        }
++
++        // this could definitely be cleaned up QQQ
++        methodOop callee;
++        klassOop iclass = (klassOop)cache->f1();
++        // instanceKlass* interface = (instanceKlass*) iclass->klass_part();
++        // get receiver
++        int parms = cache->parameter_size();
++        oop rcvr = STACK_OBJECT(-parms);
++        CHECK_NULL(rcvr);
++        instanceKlass* int2 = (instanceKlass*) rcvr->klass()->klass_part();
++        itableOffsetEntry* ki = (itableOffsetEntry*) int2->start_of_itable();
++        int i;
++        for ( i = 0 ; i < int2->itable_length() ; i++, ki++ ) {
++          if (ki->interface_klass() == iclass) break;
++        }
++        // If the interface isn't found, this class doesn't implement this
++        // interface.  The link resolver checks this but only for the first
++        // time this interface is called.
++        if (i == int2->itable_length()) {
++          VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), "");
++        }
++        int mindex = cache->f2();
++        itableMethodEntry* im = ki->first_method_entry(rcvr->klass());
++        callee = im[mindex].method();
++        if (callee == NULL) {
++          VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), "");
++        }
++
++        istate->set_callee(callee);
++        istate->set_callee_entry_point(callee->from_interpreted_entry());
++#ifdef VM_JVMTI
++        if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) {
++          istate->set_callee_entry_point(callee->interpreter_entry());
++        }
++#endif /* VM_JVMTI */
++        istate->set_bcp_advance(5);
++        UPDATE_PC_AND_RETURN(0); // I'll be back...
++      }
++
++      CASE(_invokevirtual):
++      CASE(_invokespecial):
++      CASE(_invokestatic): {
++        u2 index = Bytes::get_native_u2(pc+1);
++
++        ConstantPoolCacheEntry* cache = cp->entry_at(index);
++        // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases
++        // out so c++ compiler has a chance for constant prop to fold everything possible away.
++
++        if (!cache->is_resolved((Bytecodes::Code)opcode)) {
++          CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode),
++                  handle_exception);
++          cache = cp->entry_at(index);
++        }
++
++        istate->set_msg(call_method);
++        {
++          methodOop callee;
++          if ((Bytecodes::Code)opcode == Bytecodes::_invokevirtual) {
++            CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
++            if (cache->is_vfinal()) callee = (methodOop) cache->f2();
++            else {
++              // get receiver
++              int parms = cache->parameter_size();
++              // this works but needs a resourcemark and seems to create a vtable on every call:
++              // methodOop callee = rcvr->klass()->klass_part()->vtable()->method_at(cache->f2());
++              //
++              // this fails with an assert
++              // instanceKlass* rcvrKlass = instanceKlass::cast(STACK_OBJECT(-parms)->klass());
++              // but this works
++              instanceKlass* rcvrKlass = (instanceKlass*) STACK_OBJECT(-parms)->klass()->klass_part();
++              /*
++                Executing this code in java.lang.String:
++                    public String(char value[]) {
++                          this.count = value.length;
++                          this.value = (char[])value.clone();
++                     }
++
++                 a find on rcvr->klass()->klass_part() reports:
++                 {type array char}{type array class}
++                  - klass: {other class}
++
++                  but using instanceKlass::cast(STACK_OBJECT(-parms)->klass()) causes in assertion failure
++                  because rcvr->klass()->klass_part()->oop_is_instance() == 0
++                  However it seems to have a vtable in the right location. Huh?
++
++              */
++              callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()];
++            }
++          } else {
++            if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) {
++              CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
++            }
++            callee = (methodOop) cache->f1();
++          }
++
++          istate->set_callee(callee);
++          istate->set_callee_entry_point(callee->from_interpreted_entry());
++#ifdef VM_JVMTI
++          if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) {
++            istate->set_callee_entry_point(callee->interpreter_entry());
++          }
++#endif /* VM_JVMTI */
++          istate->set_bcp_advance(3);
++          UPDATE_PC_AND_RETURN(0); // I'll be back...
++        }
++      }
++
++      /* Allocate memory for a new java object. */
++
++      CASE(_newarray): {
++        BasicType atype = (BasicType) *(pc+1);
++        jint size = STACK_INT(-1);
++        CALL_VM(InterpreterRuntime::newarray(THREAD, atype, size),
++                handle_exception);
++        SET_STACK_OBJECT(THREAD->vm_result(), -1);
++        THREAD->set_vm_result(NULL);
++
++        UPDATE_PC_AND_CONTINUE(2);
++      }
++
++      /* Throw an exception. */
++
++      CASE(_athrow): {
++          oop except_oop = STACK_OBJECT(-1);
++          CHECK_NULL(except_oop);
++          // set pending_exception so we use common code
++          THREAD->set_pending_exception(except_oop, NULL, 0);
++          goto handle_exception;
++      }
++
++      /* goto and jsr. They are exactly the same except jsr pushes
++       * the address of the next instruction first.
++       */
++
++      CASE(_jsr): {
++          /* push bytecode index on stack */
++          SET_STACK_ADDR(((address)pc - (intptr_t)(istate->method()->code_base()) + 3), 0);
++          MORE_STACK(1);
++          /* FALL THROUGH */
++      }
++
++      CASE(_goto):
++      {
++          int16_t offset = (int16_t)Bytes::get_Java_u2(pc + 1);
++          address branch_pc = pc;
++          UPDATE_PC(offset);
++          DO_BACKEDGE_CHECKS(offset, branch_pc);
++          CONTINUE;
++      }
++
++      CASE(_jsr_w): {
++          /* push return address on the stack */
++          SET_STACK_ADDR(((address)pc - (intptr_t)(istate->method()->code_base()) + 5), 0);
++          MORE_STACK(1);
++          /* FALL THROUGH */
++      }
++
++      CASE(_goto_w):
++      {
++          int32_t offset = Bytes::get_Java_u4(pc + 1);
++          address branch_pc = pc;
++          UPDATE_PC(offset);
++          DO_BACKEDGE_CHECKS(offset, branch_pc);
++          CONTINUE;
++      }
++
++      /* return from a jsr or jsr_w */
++
++      CASE(_ret): {
++          pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(pc[1]));
++          UPDATE_PC_AND_CONTINUE(0);
++      }
++
++      /* debugger breakpoint */
++
++      CASE(_breakpoint): {
++          Bytecodes::Code original_bytecode;
++          DECACHE_STATE();
++          SET_LAST_JAVA_FRAME();
++          original_bytecode = InterpreterRuntime::get_original_bytecode_at(THREAD,
++                              METHOD, pc);
++          RESET_LAST_JAVA_FRAME();
++          CACHE_STATE();
++          if (THREAD->has_pending_exception()) goto handle_exception;
++            CALL_VM(InterpreterRuntime::_breakpoint(THREAD, METHOD, pc),
++                                                    handle_exception);
++
++          opcode = (jubyte)original_bytecode;
++          goto opcode_switch;
++      }
++
++      DEFAULT:
++          fatal2("\t*** Unimplemented opcode: %d = %s\n",
++                 opcode, Bytecodes::name((Bytecodes::Code)opcode));
++          goto finish;
++
++      } /* switch(opc) */
++
++
++#ifdef USELABELS
++    check_for_exception:
++#endif
++    {
++      if (!THREAD->has_pending_exception()) {
++        CONTINUE;
++      }
++      /* We will be gcsafe soon, so flush our state. */
++      DECACHE_PC();
++      goto handle_exception;
++    }
++  do_continue: ;
++
++  } /* while (1) interpreter loop */
++
++
++  // An exception exists in the thread state see whether this activation can handle it
++  handle_exception: {
++
++    HandleMarkCleaner __hmc(THREAD);
++    Handle except_oop(THREAD, THREAD->pending_exception());
++    // Prevent any subsequent HandleMarkCleaner in the VM
++    // from freeing the except_oop handle.
++    HandleMark __hm(THREAD);
++
++    THREAD->clear_pending_exception();
++    assert(except_oop(), "No exception to process");
++    intptr_t continuation_bci;
++    // expression stack is emptied
++    topOfStack = istate->stack_base() - Interpreter::stackElementWords();
++    CALL_VM(continuation_bci = (intptr_t)InterpreterRuntime::exception_handler_for_exception(THREAD, except_oop()),
++            handle_exception);
++
++    except_oop = (oop) THREAD->vm_result();
++    THREAD->set_vm_result(NULL);
++    if (continuation_bci >= 0) {
++      // Place exception on top of stack
++      SET_STACK_OBJECT(except_oop(), 0);
++      MORE_STACK(1);
++      pc = METHOD->code_base() + continuation_bci;
++      if (TraceExceptions) {
++        ttyLocker ttyl;
++        ResourceMark rm;
++        tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop());
++        tty->print_cr(" thrown in interpreter method <%s>", METHOD->print_value_string());
++        tty->print_cr(" at bci %d, continuing at %d for thread " INTPTR_FORMAT,
++                      pc - (intptr_t)METHOD->code_base(),
++                      continuation_bci, THREAD);
++      }
++      // for AbortVMOnException flag
++      NOT_PRODUCT(Exceptions::debug_check_abort(except_oop));
++      goto run;
++    }
++    if (TraceExceptions) {
++      ttyLocker ttyl;
++      ResourceMark rm;
++      tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop());
++      tty->print_cr(" thrown in interpreter method <%s>", METHOD->print_value_string());
++      tty->print_cr(" at bci %d, unwinding for thread " INTPTR_FORMAT,
++                    pc  - (intptr_t) METHOD->code_base(),
++                    THREAD);
++    }
++    // for AbortVMOnException flag
++    NOT_PRODUCT(Exceptions::debug_check_abort(except_oop));
++    // No handler in this activation, unwind and try again
++    THREAD->set_pending_exception(except_oop(), NULL, 0);
++    goto handle_return;
++  }  /* handle_exception: */
++
++
++
++  // Return from an interpreter invocation with the result of the interpretation
++  // on the top of the Java Stack (or a pending exception)
++
++handle_Pop_Frame:
++
++  // We don't really do anything special here except we must be aware
++  // that we can get here without ever locking the method (if sync).
++  // Also we skip the notification of the exit.
++
++  istate->set_msg(popping_frame);
++  // Clear pending so while the pop is in process
++  // we don't start another one if a call_vm is done.
++  THREAD->clr_pop_frame_pending();
++  // Let interpreter (only) see the we're in the process of popping a frame
++  THREAD->set_pop_frame_in_process();
++
++handle_return:
++  {
++    DECACHE_STATE();
++
++    bool suppress_error = istate->msg() == popping_frame;
++    bool suppress_exit_event = THREAD->has_pending_exception() || suppress_error;
++    Handle original_exception(THREAD, THREAD->pending_exception());
++    Handle illegal_state_oop(THREAD, NULL);
++
++    // We'd like a HandleMark here to prevent any subsequent HandleMarkCleaner
++    // in any following VM entries from freeing our live handles, but illegal_state_oop
++    // isn't really allocated yet and so doesn't become live until later and
++    // in unpredicatable places. Instead we must protect the places where we enter the
++    // VM. It would be much simpler (and safer) if we could allocate a real handle with
++    // a NULL oop in it and then overwrite the oop later as needed. This isn't
++    // unfortunately isn't possible.
++
++    THREAD->clear_pending_exception();
++
++    //
++    // As far as we are concerned we have returned. If we have a pending exception
++    // that will be returned as this invocation's result. However if we get any
++    // exception(s) while checking monitor state one of those IllegalMonitorStateExceptions
++    // will be our final result (i.e. monitor exception trumps a pending exception).
++    //
++
++    // If we never locked the method (or really passed the point where we would have),
++    // there is no need to unlock it (or look for other monitors), since that
++    // could not have happened.
++
++    if (THREAD->do_not_unlock()) {
++
++      // Never locked, reset the flag now because obviously any caller must
++      // have passed their point of locking for us to have gotten here.
++
++      THREAD->clr_do_not_unlock();
++    } else {
++      // At this point we consider that we have returned. We now check that the
++      // locks were properly block structured. If we find that they were not
++      // used properly we will return with an illegal monitor exception.
++      // The exception is checked by the caller not the callee since this
++      // checking is considered to be part of the invocation and therefore
++      // in the callers scope (JVM spec 8.13).
++      //
++      // Another weird thing to watch for is if the method was locked
++      // recursively and then not exited properly. This means we must
++      // examine all the entries in reverse time(and stack) order and
++      // unlock as we find them. If we find the method monitor before
++      // we are at the initial entry then we should throw an exception.
++      // It is not clear the template based interpreter does this
++      // correctly
++
++      BasicObjectLock* base = istate->monitor_base();
++      BasicObjectLock* end = (BasicObjectLock*) istate->stack_base();
++      bool method_unlock_needed = METHOD->is_synchronized();
++      // We know the initial monitor was used for the method don't check that
++      // slot in the loop
++      if (method_unlock_needed) base--;
++
++      // Check all the monitors to see they are unlocked. Install exception if found to be locked.
++      while (end < base) {
++        oop lockee = end->obj();
++        if (lockee != NULL) {
++          BasicLock* lock = end->lock();
++          markOop header = lock->displaced_header();
++          end->set_obj(NULL);
++          // If it isn't recursive we either must swap old header or call the runtime
++          if (header != NULL) {
++            if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) {
++              // restore object for the slow case
++              end->set_obj(lockee);
++              {
++                // Prevent any HandleMarkCleaner from freeing our live handles
++                HandleMark __hm(THREAD);
++                CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, end));
++              }
++            }
++          }
++          // One error is plenty
++          if (illegal_state_oop() == NULL && !suppress_error) {
++            {
++              // Prevent any HandleMarkCleaner from freeing our live handles
++              HandleMark __hm(THREAD);
++              CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD));
++            }
++            assert(THREAD->has_pending_exception(), "Lost our exception!");
++            illegal_state_oop = THREAD->pending_exception();
++            THREAD->clear_pending_exception();
++          }
++        }
++        end++;
++      }
++      // Unlock the method if needed
++      if (method_unlock_needed) {
++        if (base->obj() == NULL) {
++          // The method is already unlocked this is not good.
++          if (illegal_state_oop() == NULL && !suppress_error) {
++            {
++              // Prevent any HandleMarkCleaner from freeing our live handles
++              HandleMark __hm(THREAD);
++              CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD));
++            }
++            assert(THREAD->has_pending_exception(), "Lost our exception!");
++            illegal_state_oop = THREAD->pending_exception();
++            THREAD->clear_pending_exception();
++          }
++        } else {
++          //
++          // The initial monitor is always used for the method
++          // However if that slot is no longer the oop for the method it was unlocked
++          // and reused by something that wasn't unlocked!
++          //
++          // deopt can come in with rcvr dead because c2 knows
++          // its value is preserved in the monitor. So we can't use locals[0] at all
++          // and must use first monitor slot.
++          //
++          oop rcvr = base->obj();
++          if (rcvr == NULL) {
++            if (!suppress_error) {
++              VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), "");
++              illegal_state_oop = THREAD->pending_exception();
++              THREAD->clear_pending_exception();
++            }
++          } else {
++            BasicLock* lock = base->lock();
++            markOop header = lock->displaced_header();
++            base->set_obj(NULL);
++            // If it isn't recursive we either must swap old header or call the runtime
++            if (header != NULL) {
++              if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) {
++                // restore object for the slow case
++                base->set_obj(rcvr);
++                {
++                  // Prevent any HandleMarkCleaner from freeing our live handles
++                  HandleMark __hm(THREAD);
++                  CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base));
++                }
++                if (THREAD->has_pending_exception()) {
++                  if (!suppress_error) illegal_state_oop = THREAD->pending_exception();
++                  THREAD->clear_pending_exception();
++                }
++              }
++            }
++          }
++        }
++      }
++    }
++
++    //
++    // Notify jvmti/jvmdi
++    //
++    // NOTE: we do not notify a method_exit if we have a pending exception,
++    // including an exception we generate for unlocking checks.  In the former
++    // case, JVMDI has already been notified by our call for the exception handler
++    // and in both cases as far as JVMDI is concerned we have already returned.
++    // If we notify it again JVMDI will be all confused about how many frames
++    // are still on the stack (4340444).
++    //
++    // NOTE Further! It turns out the the JVMTI spec in fact expects to see
++    // method_exit events whenever we leave an activation unless it was done
++    // for popframe. This is nothing like jvmdi. However we are passing the
++    // tests at the moment (apparently because they are jvmdi based) so rather
++    // than change this code and possibly fail tests we will leave it alone
++    // (with this note) in anticipation of changing the vm and the tests
++    // simultaneously.
++
++
++    //
++    suppress_exit_event = suppress_exit_event || illegal_state_oop() != NULL;
++
++
++
++#ifdef VM_JVMTI
++      if (_jvmti_interp_events) {
++        // Whenever JVMTI puts a thread in interp_only_mode, method
++        // entry/exit events are sent for that thread to track stack depth.
++        if ( !suppress_exit_event && THREAD->is_interp_only_mode() ) {
++          {
++            // Prevent any HandleMarkCleaner from freeing our live handles
++            HandleMark __hm(THREAD);
++            CALL_VM_NOCHECK(InterpreterRuntime::post_method_exit(THREAD));
++          }
++        }
++      }
++#endif /* VM_JVMTI */
++
++    //
++    // See if we are returning any exception
++    // A pending exception that was pending prior to a possible popping frame
++    // overrides the popping frame.
++    //
++    assert(!suppress_error || suppress_error && illegal_state_oop() == NULL, "Error was not suppressed");
++    if (illegal_state_oop() != NULL || original_exception() != NULL) {
++      // inform the frame manager we have no result
++      istate->set_msg(throwing_exception);
++      if (illegal_state_oop() != NULL)
++        THREAD->set_pending_exception(illegal_state_oop(), NULL, 0);
++      else
++        THREAD->set_pending_exception(original_exception(), NULL, 0);
++      istate->set_return_kind((Bytecodes::Code)opcode);
++      UPDATE_PC_AND_RETURN(0);
++    }
++
++    if (istate->msg() == popping_frame) {
++      // Make it simpler on the assembly code and set the message for the frame pop.
++      // returns
++      if (istate->prev() == NULL) {
++        // We must be returning to a deoptimized frame (because popframe only happens between
++        // two interpreted frames). We need to save the current arguments in C heap so that
++        // the deoptimized frame when it restarts can copy the arguments to its expression
++        // stack and re-execute the call. We also have to notify deoptimization that this
++        // has occured and to pick the preerved args copy them to the deoptimized frame's
++        // java expression stack. Yuck.
++        //
++        THREAD->popframe_preserve_args(in_ByteSize(METHOD->size_of_parameters() * wordSize),
++                                LOCALS_SLOT(METHOD->size_of_parameters() - 1));
++        THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit);
++      }
++      UPDATE_PC_AND_RETURN(1);
++    } else {
++      // Normal return
++      // Advance the pc and return to frame manager
++      istate->set_msg(return_from_method);
++      istate->set_return_kind((Bytecodes::Code)opcode);
++      UPDATE_PC_AND_RETURN(1);
++    }
++  } /* handle_return: */
++
++// This is really a fatal error return
++
++finish:
++  DECACHE_TOS();
++  DECACHE_PC();
++
++  return;
++}
++
++/*
++ * All the code following this point is only produced once and is not present
++ * in the JVMTI version of the interpreter
++*/
++
++#ifndef VM_JVMTI
++
++// This constructor should only be used to contruct the object to signal
++// interpreter initialization. All other instances should be created by
++// the frame manager.
++BytecodeInterpreter::BytecodeInterpreter(messages msg) {
++  if (msg != initialize) ShouldNotReachHere();
++  _msg = msg;
++  _self_link = this;
++  _prev_link = NULL;
++}
++
++// Inline static functions for Java Stack and Local manipulation
++
++// The implementations are platform dependent. We have to worry about alignment
++// issues on some machines which can change on the same platform depending on
++// whether it is an LP64 machine also.
++#ifdef ASSERT
++void BytecodeInterpreter::verify_stack_tag(intptr_t *tos, frame::Tag tag, int offset) {
++  if (TaggedStackInterpreter) {
++    frame::Tag t = (frame::Tag)tos[Interpreter::expr_tag_index_at(-offset)];
++    assert(t == tag, "stack tag mismatch");
++  }
++}
++#endif // ASSERT
++
++address BytecodeInterpreter::stack_slot(intptr_t *tos, int offset) {
++  debug_only(verify_stack_tag(tos, frame::TagValue, offset));
++  return (address) tos[Interpreter::expr_index_at(-offset)];
++}
++
++jint BytecodeInterpreter::stack_int(intptr_t *tos, int offset) {
++  debug_only(verify_stack_tag(tos, frame::TagValue, offset));
++  return *((jint*) &tos[Interpreter::expr_index_at(-offset)]);
++}
++
++jfloat BytecodeInterpreter::stack_float(intptr_t *tos, int offset) {
++  debug_only(verify_stack_tag(tos, frame::TagValue, offset));
++  return *((jfloat *) &tos[Interpreter::expr_index_at(-offset)]);
++}
++
++oop BytecodeInterpreter::stack_object(intptr_t *tos, int offset) {
++  debug_only(verify_stack_tag(tos, frame::TagReference, offset));
++  return (oop)tos [Interpreter::expr_index_at(-offset)];
++}
++
++jdouble BytecodeInterpreter::stack_double(intptr_t *tos, int offset) {
++  debug_only(verify_stack_tag(tos, frame::TagValue, offset));
++  debug_only(verify_stack_tag(tos, frame::TagValue, offset-1));
++  return ((VMJavaVal64*) &tos[Interpreter::expr_index_at(-offset)])->d;
++}
++
++jlong BytecodeInterpreter::stack_long(intptr_t *tos, int offset) {
++  debug_only(verify_stack_tag(tos, frame::TagValue, offset));
++  debug_only(verify_stack_tag(tos, frame::TagValue, offset-1));
++  return ((VMJavaVal64 *) &tos[Interpreter::expr_index_at(-offset)])->l;
++}
++
++void BytecodeInterpreter::tag_stack(intptr_t *tos, frame::Tag tag, int offset) {
++  if (TaggedStackInterpreter)
++    tos[Interpreter::expr_tag_index_at(-offset)] = (intptr_t)tag;
++}
++
++// only used for value types
++void BytecodeInterpreter::set_stack_slot(intptr_t *tos, address value,
++                                                        int offset) {
++  tag_stack(tos, frame::TagValue, offset);
++  *((address *)&tos[Interpreter::expr_index_at(-offset)]) = value;
++}
++
++void BytecodeInterpreter::set_stack_int(intptr_t *tos, int value,
++                                                       int offset) {
++  tag_stack(tos, frame::TagValue, offset);
++  *((jint *)&tos[Interpreter::expr_index_at(-offset)]) = value;
++}
++
++void BytecodeInterpreter::set_stack_float(intptr_t *tos, jfloat value,
++                                                         int offset) {
++  tag_stack(tos, frame::TagValue, offset);
++  *((jfloat *)&tos[Interpreter::expr_index_at(-offset)]) = value;
++}
++
++void BytecodeInterpreter::set_stack_object(intptr_t *tos, oop value,
++                                                          int offset) {
++  tag_stack(tos, frame::TagReference, offset);
++  *((oop *)&tos[Interpreter::expr_index_at(-offset)]) = value;
++}
++
++// needs to be platform dep for the 32 bit platforms.
++void BytecodeInterpreter::set_stack_double(intptr_t *tos, jdouble value,
++                                                          int offset) {
++  tag_stack(tos, frame::TagValue, offset);
++  tag_stack(tos, frame::TagValue, offset-1);
++  ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d = value;
++}
++
++void BytecodeInterpreter::set_stack_double_from_addr(intptr_t *tos,
++                                              address addr, int offset) {
++  tag_stack(tos, frame::TagValue, offset);
++  tag_stack(tos, frame::TagValue, offset-1);
++  (((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d =
++                        ((VMJavaVal64*)addr)->d);
++}
++
++void BytecodeInterpreter::set_stack_long(intptr_t *tos, jlong value,
++                                                        int offset) {
++  tag_stack(tos, frame::TagValue, offset);
++  ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb;
++  tag_stack(tos, frame::TagValue, offset-1);
++  ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l = value;
++}
++
++void BytecodeInterpreter::set_stack_long_from_addr(intptr_t *tos,
++                                            address addr, int offset) {
++  tag_stack(tos, frame::TagValue, offset);
++  ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb;
++  tag_stack(tos, frame::TagValue, offset-1);
++  ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l =
++                        ((VMJavaVal64*)addr)->l;
++}
++
++// Locals
++
++#ifdef ASSERT
++void BytecodeInterpreter::verify_locals_tag(intptr_t *locals, frame::Tag tag,
++                                     int offset) {
++  if (TaggedStackInterpreter) {
++    frame::Tag t = (frame::Tag)locals[Interpreter::local_tag_index_at(-offset)];
++    assert(t == tag, "locals tag mismatch");
++  }
++}
++#endif // ASSERT
++address BytecodeInterpreter::locals_slot(intptr_t* locals, int offset) {
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
++  return (address)locals[Interpreter::local_index_at(-offset)];
++}
++jint BytecodeInterpreter::locals_int(intptr_t* locals, int offset) {
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
++  return (jint)locals[Interpreter::local_index_at(-offset)];
++}
++jfloat BytecodeInterpreter::locals_float(intptr_t* locals, int offset) {
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
++  return (jfloat)locals[Interpreter::local_index_at(-offset)];
++}
++oop BytecodeInterpreter::locals_object(intptr_t* locals, int offset) {
++  debug_only(verify_locals_tag(locals, frame::TagReference, offset));
++  return (oop)locals[Interpreter::local_index_at(-offset)];
++}
++jdouble BytecodeInterpreter::locals_double(intptr_t* locals, int offset) {
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
++  return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d;
++}
++jlong BytecodeInterpreter::locals_long(intptr_t* locals, int offset) {
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset+1));
++  return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l;
++}
++
++// Returns the address of locals value.
++address BytecodeInterpreter::locals_long_at(intptr_t* locals, int offset) {
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset+1));
++  return ((address)&locals[Interpreter::local_index_at(-(offset+1))]);
++}
++address BytecodeInterpreter::locals_double_at(intptr_t* locals, int offset) {
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
++  debug_only(verify_locals_tag(locals, frame::TagValue, offset+1));
++  return ((address)&locals[Interpreter::local_index_at(-(offset+1))]);
++}
++
++void BytecodeInterpreter::tag_locals(intptr_t *locals, frame::Tag tag, int offset) {
++  if (TaggedStackInterpreter)
++    locals[Interpreter::local_tag_index_at(-offset)] = (intptr_t)tag;
++}
++
++// Used for local value or returnAddress
++void BytecodeInterpreter::set_locals_slot(intptr_t *locals,
++                                   address value, int offset) {
++  tag_locals(locals, frame::TagValue, offset);
++  *((address*)&locals[Interpreter::local_index_at(-offset)]) = value;
++}
++void BytecodeInterpreter::set_locals_int(intptr_t *locals,
++                                   jint value, int offset) {
++  tag_locals(locals, frame::TagValue, offset);
++  *((jint *)&locals[Interpreter::local_index_at(-offset)]) = value;
++}
++void BytecodeInterpreter::set_locals_float(intptr_t *locals,
++                                   jfloat value, int offset) {
++  tag_locals(locals, frame::TagValue, offset);
++  *((jfloat *)&locals[Interpreter::local_index_at(-offset)]) = value;
++}
++void BytecodeInterpreter::set_locals_object(intptr_t *locals,
++                                   oop value, int offset) {
++  tag_locals(locals, frame::TagReference, offset);
++  *((oop *)&locals[Interpreter::local_index_at(-offset)]) = value;
++}
++void BytecodeInterpreter::set_locals_double(intptr_t *locals,
++                                   jdouble value, int offset) {
++  tag_locals(locals, frame::TagValue, offset);
++  tag_locals(locals, frame::TagValue, offset+1);
++  ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = value;
++}
++void BytecodeInterpreter::set_locals_long(intptr_t *locals,
++                                   jlong value, int offset) {
++  tag_locals(locals, frame::TagValue, offset);
++  tag_locals(locals, frame::TagValue, offset+1);
++  ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = value;
++}
++void BytecodeInterpreter::set_locals_double_from_addr(intptr_t *locals,
++                                   address addr, int offset) {
++  tag_locals(locals, frame::TagValue, offset);
++  tag_locals(locals, frame::TagValue, offset+1);
++  ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = ((VMJavaVal64*)addr)->d;
++}
++void BytecodeInterpreter::set_locals_long_from_addr(intptr_t *locals,
++                                   address addr, int offset) {
++  tag_locals(locals, frame::TagValue, offset);
++  tag_locals(locals, frame::TagValue, offset+1);
++  ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = ((VMJavaVal64*)addr)->l;
++}
++
++void BytecodeInterpreter::astore(intptr_t* tos,    int stack_offset,
++                          intptr_t* locals, int locals_offset) {
++  // Copy tag from stack to locals.  astore's operand can be returnAddress
++  // and may not be TagReference
++  if (TaggedStackInterpreter) {
++    frame::Tag t = (frame::Tag) tos[Interpreter::expr_tag_index_at(-stack_offset)];
++    locals[Interpreter::local_tag_index_at(-locals_offset)] = (intptr_t)t;
++  }
++  intptr_t value = tos[Interpreter::expr_index_at(-stack_offset)];
++  locals[Interpreter::local_index_at(-locals_offset)] = value;
++}
++
++
++void BytecodeInterpreter::copy_stack_slot(intptr_t *tos, int from_offset,
++                                   int to_offset) {
++  if (TaggedStackInterpreter) {
++    tos[Interpreter::expr_tag_index_at(-to_offset)] =
++                      (intptr_t)tos[Interpreter::expr_tag_index_at(-from_offset)];
++  }
++  tos[Interpreter::expr_index_at(-to_offset)] =
++                      (intptr_t)tos[Interpreter::expr_index_at(-from_offset)];
++}
++
++void BytecodeInterpreter::dup(intptr_t *tos) {
++  copy_stack_slot(tos, -1, 0);
++}
++void BytecodeInterpreter::dup2(intptr_t *tos) {
++  copy_stack_slot(tos, -2, 0);
++  copy_stack_slot(tos, -1, 1);
++}
++
++void BytecodeInterpreter::dup_x1(intptr_t *tos) {
++  /* insert top word two down */
++  copy_stack_slot(tos, -1, 0);
++  copy_stack_slot(tos, -2, -1);
++  copy_stack_slot(tos, 0, -2);
++}
++
++void BytecodeInterpreter::dup_x2(intptr_t *tos) {
++  /* insert top word three down  */
++  copy_stack_slot(tos, -1, 0);
++  copy_stack_slot(tos, -2, -1);
++  copy_stack_slot(tos, -3, -2);
++  copy_stack_slot(tos, 0, -3);
++}
++void BytecodeInterpreter::dup2_x1(intptr_t *tos) {
++  /* insert top 2 slots three down */
++  copy_stack_slot(tos, -1, 1);
++  copy_stack_slot(tos, -2, 0);
++  copy_stack_slot(tos, -3, -1);
++  copy_stack_slot(tos, 1, -2);
++  copy_stack_slot(tos, 0, -3);
++}
++void BytecodeInterpreter::dup2_x2(intptr_t *tos) {
++  /* insert top 2 slots four down */
++  copy_stack_slot(tos, -1, 1);
++  copy_stack_slot(tos, -2, 0);
++  copy_stack_slot(tos, -3, -1);
++  copy_stack_slot(tos, -4, -2);
++  copy_stack_slot(tos, 1, -3);
++  copy_stack_slot(tos, 0, -4);
++}
++
++
++void BytecodeInterpreter::swap(intptr_t *tos) {
++  // swap top two elements
++  intptr_t val = tos[Interpreter::expr_index_at(1)];
++  frame::Tag t;
++  if (TaggedStackInterpreter) {
++    t = (frame::Tag) tos[Interpreter::expr_tag_index_at(1)];
++  }
++  // Copy -2 entry to -1
++  copy_stack_slot(tos, -2, -1);
++  // Store saved -1 entry into -2
++  if (TaggedStackInterpreter) {
++    tos[Interpreter::expr_tag_index_at(2)] = (intptr_t)t;
++  }
++  tos[Interpreter::expr_index_at(2)] = val;
++}
++// --------------------------------------------------------------------------------
++// Non-product code
++#ifndef PRODUCT
++
++const char* BytecodeInterpreter::C_msg(BytecodeInterpreter::messages msg) {
++  switch (msg) {
++     case BytecodeInterpreter::no_request:  return("no_request");
++     case BytecodeInterpreter::initialize:  return("initialize");
++     // status message to C++ interpreter
++     case BytecodeInterpreter::method_entry:  return("method_entry");
++     case BytecodeInterpreter::method_resume:  return("method_resume");
++     case BytecodeInterpreter::got_monitors:  return("got_monitors");
++     case BytecodeInterpreter::rethrow_exception:  return("rethrow_exception");
++     // requests to frame manager from C++ interpreter
++     case BytecodeInterpreter::call_method:  return("call_method");
++     case BytecodeInterpreter::return_from_method:  return("return_from_method");
++     case BytecodeInterpreter::more_monitors:  return("more_monitors");
++     case BytecodeInterpreter::throwing_exception:  return("throwing_exception");
++     case BytecodeInterpreter::popping_frame:  return("popping_frame");
++     case BytecodeInterpreter::do_osr:  return("do_osr");
++     // deopt
++     case BytecodeInterpreter::deopt_resume:  return("deopt_resume");
++     case BytecodeInterpreter::deopt_resume2:  return("deopt_resume2");
++     default: return("BAD MSG");
++  }
++}
++void
++BytecodeInterpreter::print() {
++  tty->print_cr("thread: " INTPTR_FORMAT, (uintptr_t) this->_thread);
++  tty->print_cr("bcp: " INTPTR_FORMAT, (uintptr_t) this->_bcp);
++  tty->print_cr("locals: " INTPTR_FORMAT, (uintptr_t) this->_locals);
++  tty->print_cr("constants: " INTPTR_FORMAT, (uintptr_t) this->_constants);
++  {
++    ResourceMark rm;
++    char *method_name = _method->name_and_sig_as_C_string();
++    tty->print_cr("method: " INTPTR_FORMAT "[ %s ]",  (uintptr_t) this->_method, method_name);
++  }
++  tty->print_cr("mdx: " INTPTR_FORMAT, (uintptr_t) this->_mdx);
++  tty->print_cr("stack: " INTPTR_FORMAT, (uintptr_t) this->_stack);
++  tty->print_cr("msg: %s", C_msg(this->_msg));
++  tty->print_cr("result_to_call._callee: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee);
++  tty->print_cr("result_to_call._callee_entry_point: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee_entry_point);
++  tty->print_cr("result_to_call._bcp_advance: %d ", this->_result._to_call._bcp_advance);
++  tty->print_cr("osr._osr_buf: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_buf);
++  tty->print_cr("osr._osr_entry: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_entry);
++  tty->print_cr("result_return_kind 0x%x ", (int) this->_result._return_kind);
++  tty->print_cr("prev_link: " INTPTR_FORMAT, (uintptr_t) this->_prev_link);
++  tty->print_cr("native_mirror: " INTPTR_FORMAT, (uintptr_t) this->_oop_temp);
++  tty->print_cr("stack_base: " INTPTR_FORMAT, (uintptr_t) this->_stack_base);
++  tty->print_cr("stack_limit: " INTPTR_FORMAT, (uintptr_t) this->_stack_limit);
++  tty->print_cr("monitor_base: " INTPTR_FORMAT, (uintptr_t) this->_monitor_base);
++#ifdef SPARC
++  tty->print_cr("last_Java_pc: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_pc);
++  tty->print_cr("frame_bottom: " INTPTR_FORMAT, (uintptr_t) this->_frame_bottom);
++  tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult);
++  tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult);
++#endif
++#ifdef IA64
++  tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp);
++#endif // IA64
++  tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link);
++}
++
++extern "C" {
++    void PI(uintptr_t arg) {
++        ((BytecodeInterpreter*)arg)->print();
++    }
++}
++#endif // PRODUCT
++
++#endif // JVMTI
++#endif // CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -0,0 +1,572 @@
++/*
++ * Copyright 2002-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++#ifdef CC_INTERP
++
++// CVM definitions find hotspot equivalents...
++
++union VMJavaVal64 {
++    jlong   l;
++    jdouble d;
++    uint32_t      v[2];
++};
++
++
++typedef class BytecodeInterpreter* interpreterState;
++
++struct call_message {
++    class methodOopDesc* _callee;    /* method to call during call_method request */
++    address   _callee_entry_point;   /* address to jump to for call_method request */
++    int       _bcp_advance;          /* size of the invoke bytecode operation */
++};
++
++struct osr_message {
++    address _osr_buf;                 /* the osr buffer */
++    address _osr_entry;               /* the entry to the osr method */
++};
++
++struct osr_result {
++  nmethod* nm;                       /* osr nmethod */
++  address return_addr;               /* osr blob return address */
++};
++
++// Result returned to frame manager
++union frame_manager_message {
++    call_message _to_call;            /* describes callee */
++    Bytecodes::Code _return_kind;     /* i_return, a_return, ... */
++    osr_message _osr;                 /* describes the osr */
++    osr_result _osr_result;           /* result of OSR request */
++};
++
++class BytecodeInterpreter : StackObj {
++friend class SharedRuntime;
++friend class AbstractInterpreterGenerator;
++friend class CppInterpreterGenerator;
++friend class InterpreterGenerator;
++friend class InterpreterMacroAssembler;
++friend class frame;
++friend class SharedRuntime;
++friend class VMStructs;
++
++public:
++    enum messages {
++         no_request = 0,            // unused
++         initialize,                // Perform one time interpreter initializations (assumes all switches set)
++         // status message to C++ interpreter
++         method_entry,              // initial method entry to interpreter
++         method_resume,             // frame manager response to return_from_method request (assuming a frame to resume)
++         deopt_resume,              // returning from a native call into a deopted frame
++         deopt_resume2,             // deopt resume as a result of a PopFrame
++         got_monitors,              // frame manager response to more_monitors request
++         rethrow_exception,         // unwinding and throwing exception
++         // requests to frame manager from C++ interpreter
++         call_method,               // request for new frame from interpreter, manager responds with method_entry
++         return_from_method,        // request from interpreter to unwind, manager responds with method_continue
++         more_monitors,             // need a new monitor
++         throwing_exception,        // unwind stack and rethrow
++         popping_frame,             // unwind call and retry call
++         do_osr                     // request this invocation be OSR's
++    };
++
++private:
++    JavaThread*           _thread;        // the vm's java thread pointer
++    address               _bcp;           // instruction pointer
++    intptr_t*             _locals;        // local variable pointer
++    constantPoolCacheOop  _constants;     // constant pool cache
++    methodOop             _method;        // method being executed
++    DataLayout*           _mdx;           // compiler profiling data for current bytecode
++    intptr_t*             _stack;         // expression stack
++    messages              _msg;           // frame manager <-> interpreter message
++    frame_manager_message _result;        // result to frame manager
++    interpreterState      _prev_link;     // previous interpreter state
++    oop                   _oop_temp;      // mirror for interpreted native, null otherwise
++    intptr_t*             _stack_base;    // base of expression stack
++    intptr_t*             _stack_limit;   // limit of expression stack
++    BasicObjectLock*      _monitor_base;  // base of monitors on the native stack
++
++
++public:
++  // Constructor is only used by the initialization step. All other instances are created
++  // by the frame manager.
++  BytecodeInterpreter(messages msg);
++
++//
++// Deoptimization support
++//
++static void layout_interpreterState(interpreterState to_fill,
++                                    frame* caller,
++                                    frame* interpreter_frame,
++                                    methodOop method,
++                                    intptr_t* locals,
++                                    intptr_t* stack,
++                                    intptr_t* stack_base,
++                                    intptr_t* monitor_base,
++                                    intptr_t* frame_bottom,
++                                    bool top_frame);
++
++/*
++ * Generic 32-bit wide "Java slot" definition. This type occurs
++ * in operand stacks, Java locals, object fields, constant pools.
++ */
++union VMJavaVal32 {
++    jint     i;
++    jfloat   f;
++    class oopDesc*   r;
++    uint32_t raw;
++};
++
++/*
++ * Generic 64-bit Java value definition
++ */
++union VMJavaVal64 {
++    jlong   l;
++    jdouble d;
++    uint32_t      v[2];
++};
++
++/*
++ * Generic 32-bit wide "Java slot" definition. This type occurs
++ * in Java locals, object fields, constant pools, and
++ * operand stacks (as a CVMStackVal32).
++ */
++typedef union VMSlotVal32 {
++    VMJavaVal32    j;     /* For "Java" values */
++    address        a;     /* a return created by jsr or jsr_w */
++} VMSlotVal32;
++
++
++/*
++ * Generic 32-bit wide stack slot definition.
++ */
++union VMStackVal32 {
++    VMJavaVal32    j;     /* For "Java" values */
++    VMSlotVal32    s;     /* any value from a "slot" or locals[] */
++};
++
++inline JavaThread* thread() { return _thread; }
++
++inline address bcp() { return _bcp; }
++inline void set_bcp(address new_bcp) { _bcp = new_bcp; }
++
++inline intptr_t* locals() { return _locals; }
++
++inline constantPoolCacheOop constants() { return _constants; }
++inline methodOop method() { return _method; }
++inline DataLayout* mdx() { return _mdx; }
++inline void set_mdx(DataLayout *new_mdx) { _mdx = new_mdx; }
++
++inline messages msg() { return _msg; }
++inline void set_msg(messages new_msg) { _msg = new_msg; }
++
++inline methodOop callee() { return _result._to_call._callee; }
++inline void set_callee(methodOop new_callee) { _result._to_call._callee = new_callee; }
++inline void set_callee_entry_point(address entry) { _result._to_call._callee_entry_point = entry; }
++inline void set_osr_buf(address buf) { _result._osr._osr_buf = buf; }
++inline void set_osr_entry(address entry) { _result._osr._osr_entry = entry; }
++inline int bcp_advance() { return _result._to_call._bcp_advance; }
++inline void set_bcp_advance(int count) { _result._to_call._bcp_advance = count; }
++
++inline void set_return_kind(Bytecodes::Code kind) { _result._return_kind = kind; }
++
++inline interpreterState prev() { return _prev_link; }
++
++inline intptr_t* stack() { return _stack; }
++inline void set_stack(intptr_t* new_stack) { _stack = new_stack; }
++
++
++inline intptr_t* stack_base() { return _stack_base; }
++inline intptr_t* stack_limit() { return _stack_limit; }
++
++inline BasicObjectLock* monitor_base() { return _monitor_base; }
++
++/*
++ * 64-bit Arithmetic:
++ *
++ * The functions below follow the semantics of the
++ * ladd, land, ldiv, lmul, lor, lxor, and lrem bytecodes,
++ * respectively.
++ */
++
++static jlong VMlongAdd(jlong op1, jlong op2);
++static jlong VMlongAnd(jlong op1, jlong op2);
++static jlong VMlongDiv(jlong op1, jlong op2);
++static jlong VMlongMul(jlong op1, jlong op2);
++static jlong VMlongOr (jlong op1, jlong op2);
++static jlong VMlongSub(jlong op1, jlong op2);
++static jlong VMlongXor(jlong op1, jlong op2);
++static jlong VMlongRem(jlong op1, jlong op2);
++
++/*
++ * Shift:
++ *
++ * The functions below follow the semantics of the
++ * lushr, lshl, and lshr bytecodes, respectively.
++ */
++
++static jlong VMlongUshr(jlong op1, jint op2);
++static jlong VMlongShl (jlong op1, jint op2);
++static jlong VMlongShr (jlong op1, jint op2);
++
++/*
++ * Unary:
++ *
++ * Return the negation of "op" (-op), according to
++ * the semantics of the lneg bytecode.
++ */
++
++static jlong VMlongNeg(jlong op);
++
++/*
++ * Return the complement of "op" (~op)
++ */
++
++static jlong VMlongNot(jlong op);
++
++
++/*
++ * Comparisons to 0:
++ */
++
++static int32_t VMlongLtz(jlong op);     /* op <= 0 */
++static int32_t VMlongGez(jlong op);     /* op >= 0 */
++static int32_t VMlongEqz(jlong op);     /* op == 0 */
++
++/*
++ * Between operands:
++ */
++
++static int32_t VMlongEq(jlong op1, jlong op2);    /* op1 == op2 */
++static int32_t VMlongNe(jlong op1, jlong op2);    /* op1 != op2 */
++static int32_t VMlongGe(jlong op1, jlong op2);    /* op1 >= op2 */
++static int32_t VMlongLe(jlong op1, jlong op2);    /* op1 <= op2 */
++static int32_t VMlongLt(jlong op1, jlong op2);    /* op1 <  op2 */
++static int32_t VMlongGt(jlong op1, jlong op2);    /* op1 >  op2 */
++
++/*
++ * Comparisons (returning an jint value: 0, 1, or -1)
++ *
++ * Between operands:
++ *
++ * Compare "op1" and "op2" according to the semantics of the
++ * "lcmp" bytecode.
++ */
++
++static int32_t VMlongCompare(jlong op1, jlong op2);
++
++/*
++ * Convert int to long, according to "i2l" bytecode semantics
++ */
++static jlong VMint2Long(jint val);
++
++/*
++ * Convert long to int, according to "l2i" bytecode semantics
++ */
++static jint VMlong2Int(jlong val);
++
++/*
++ * Convert long to float, according to "l2f" bytecode semantics
++ */
++static jfloat VMlong2Float(jlong val);
++
++/*
++ * Convert long to double, according to "l2d" bytecode semantics
++ */
++static jdouble VMlong2Double(jlong val);
++
++/*
++ * Java floating-point float value manipulation.
++ *
++ * The result argument is, once again, an lvalue.
++ *
++ * Arithmetic:
++ *
++ * The functions below follow the semantics of the
++ * fadd, fsub, fmul, fdiv, and frem bytecodes,
++ * respectively.
++ */
++
++static jfloat VMfloatAdd(jfloat op1, jfloat op2);
++static jfloat VMfloatSub(jfloat op1, jfloat op2);
++static jfloat VMfloatMul(jfloat op1, jfloat op2);
++static jfloat VMfloatDiv(jfloat op1, jfloat op2);
++static jfloat VMfloatRem(jfloat op1, jfloat op2);
++
++/*
++ * Unary:
++ *
++ * Return the negation of "op" (-op), according to
++ * the semantics of the fneg bytecode.
++ */
++
++static jfloat VMfloatNeg(jfloat op);
++
++/*
++ * Comparisons (returning an int value: 0, 1, or -1)
++ *
++ * Between operands:
++ *
++ * Compare "op1" and "op2" according to the semantics of the
++ * "fcmpl" (direction is -1) or "fcmpg" (direction is 1) bytecodes.
++ */
++
++static int32_t VMfloatCompare(jfloat op1, jfloat op2,
++                              int32_t direction);
++/*
++ * Conversion:
++ */
++
++/*
++ * Convert float to double, according to "f2d" bytecode semantics
++ */
++
++static jdouble VMfloat2Double(jfloat op);
++
++/*
++ ******************************************
++ * Java double floating-point manipulation.
++ ******************************************
++ *
++ * The result argument is, once again, an lvalue.
++ *
++ * Conversions:
++ */
++
++/*
++ * Convert double to int, according to "d2i" bytecode semantics
++ */
++
++static jint VMdouble2Int(jdouble val);
++
++/*
++ * Convert double to float, according to "d2f" bytecode semantics
++ */
++
++static jfloat VMdouble2Float(jdouble val);
++
++/*
++ * Convert int to double, according to "i2d" bytecode semantics
++ */
++
++static jdouble VMint2Double(jint val);
++
++/*
++ * Arithmetic:
++ *
++ * The functions below follow the semantics of the
++ * dadd, dsub, ddiv, dmul, and drem bytecodes, respectively.
++ */
++
++static jdouble VMdoubleAdd(jdouble op1, jdouble op2);
++static jdouble VMdoubleSub(jdouble op1, jdouble op2);
++static jdouble VMdoubleDiv(jdouble op1, jdouble op2);
++static jdouble VMdoubleMul(jdouble op1, jdouble op2);
++static jdouble VMdoubleRem(jdouble op1, jdouble op2);
++
++/*
++ * Unary:
++ *
++ * Return the negation of "op" (-op), according to
++ * the semantics of the dneg bytecode.
++ */
++
++static jdouble VMdoubleNeg(jdouble op);
++
++/*
++ * Comparisons (returning an int32_t value: 0, 1, or -1)
++ *
++ * Between operands:
++ *
++ * Compare "op1" and "op2" according to the semantics of the
++ * "dcmpl" (direction is -1) or "dcmpg" (direction is 1) bytecodes.
++ */
++
++static int32_t VMdoubleCompare(jdouble op1, jdouble op2, int32_t direction);
++
++/*
++ * Copy two typeless 32-bit words from one location to another.
++ * This is semantically equivalent to:
++ *
++ * to[0] = from[0];
++ * to[1] = from[1];
++ *
++ * but this interface is provided for those platforms that could
++ * optimize this into a single 64-bit transfer.
++ */
++
++static void VMmemCopy64(uint32_t to[2], const uint32_t from[2]);
++
++
++// Arithmetic operations
++
++/*
++ * Java arithmetic methods.
++ * The functions below follow the semantics of the
++ * iadd, isub, imul, idiv, irem, iand, ior, ixor,
++ * and ineg bytecodes, respectively.
++ */
++
++static jint VMintAdd(jint op1, jint op2);
++static jint VMintSub(jint op1, jint op2);
++static jint VMintMul(jint op1, jint op2);
++static jint VMintDiv(jint op1, jint op2);
++static jint VMintRem(jint op1, jint op2);
++static jint VMintAnd(jint op1, jint op2);
++static jint VMintOr (jint op1, jint op2);
++static jint VMintXor(jint op1, jint op2);
++
++/*
++ * Shift Operation:
++ * The functions below follow the semantics of the
++ * iushr, ishl, and ishr bytecodes, respectively.
++ */
++
++static jint VMintUshr(jint op, jint num);
++static jint VMintShl (jint op, jint num);
++static jint VMintShr (jint op, jint num);
++
++/*
++ * Unary Operation:
++ *
++ * Return the negation of "op" (-op), according to
++ * the semantics of the ineg bytecode.
++ */
++
++static jint VMintNeg(jint op);
++
++/*
++ * Int Conversions:
++ */
++
++/*
++ * Convert int to float, according to "i2f" bytecode semantics
++ */
++
++static jfloat VMint2Float(jint val);
++
++/*
++ * Convert int to byte, according to "i2b" bytecode semantics
++ */
++
++static jbyte VMint2Byte(jint val);
++
++/*
++ * Convert int to char, according to "i2c" bytecode semantics
++ */
++
++static jchar VMint2Char(jint val);
++
++/*
++ * Convert int to short, according to "i2s" bytecode semantics
++ */
++
++static jshort VMint2Short(jint val);
++
++/*=========================================================================
++ * Bytecode interpreter operations
++ *=======================================================================*/
++
++static void dup(intptr_t *tos);
++static void dup2(intptr_t *tos);
++static void dup_x1(intptr_t *tos);    /* insert top word two down */
++static void dup_x2(intptr_t *tos);    /* insert top word three down  */
++static void dup2_x1(intptr_t *tos);   /* insert top 2 slots three down */
++static void dup2_x2(intptr_t *tos);   /* insert top 2 slots four down */
++static void swap(intptr_t *tos);      /* swap top two elements */
++
++// umm don't like this method modifies its object
++
++// The Interpreter used when
++static void run(interpreterState istate);
++// The interpreter used if JVMTI needs interpreter events
++static void runWithChecks(interpreterState istate);
++static void End_Of_Interpreter(void);
++
++// Inline static functions for Java Stack and Local manipulation
++
++static address stack_slot(intptr_t *tos, int offset);
++static jint stack_int(intptr_t *tos, int offset);
++static jfloat stack_float(intptr_t *tos, int offset);
++static oop stack_object(intptr_t *tos, int offset);
++static jdouble stack_double(intptr_t *tos, int offset);
++static jlong stack_long(intptr_t *tos, int offset);
++
++static void tag_stack(intptr_t *tos, frame::Tag tag, int offset);
++
++// only used for value types
++static void set_stack_slot(intptr_t *tos, address value, int offset);
++static void set_stack_int(intptr_t *tos, int value, int offset);
++static void set_stack_float(intptr_t *tos, jfloat value, int offset);
++static void set_stack_object(intptr_t *tos, oop value, int offset);
++
++// needs to be platform dep for the 32 bit platforms.
++static void set_stack_double(intptr_t *tos, jdouble value, int offset);
++static void set_stack_long(intptr_t *tos, jlong value, int offset);
++
++static void set_stack_double_from_addr(intptr_t *tos, address addr, int offset);
++static void set_stack_long_from_addr(intptr_t *tos, address addr, int offset);
++
++// Locals
++
++static address locals_slot(intptr_t* locals, int offset);
++static jint locals_int(intptr_t* locals, int offset);
++static jfloat locals_float(intptr_t* locals, int offset);
++static oop locals_object(intptr_t* locals, int offset);
++static jdouble locals_double(intptr_t* locals, int offset);
++static jlong locals_long(intptr_t* locals, int offset);
++
++static address locals_long_at(intptr_t* locals, int offset);
++static address locals_double_at(intptr_t* locals, int offset);
++
++static void tag_locals(intptr_t *locals, frame::Tag tag, int offset);
++
++static void set_locals_slot(intptr_t *locals, address value, int offset);
++static void set_locals_int(intptr_t *locals, jint value, int offset);
++static void set_locals_float(intptr_t *locals, jfloat value, int offset);
++static void set_locals_object(intptr_t *locals, oop value, int offset);
++static void set_locals_double(intptr_t *locals, jdouble value, int offset);
++static void set_locals_long(intptr_t *locals, jlong value, int offset);
++static void set_locals_double_from_addr(intptr_t *locals,
++                                   address addr, int offset);
++static void set_locals_long_from_addr(intptr_t *locals,
++                                   address addr, int offset);
++
++static void astore(intptr_t* topOfStack, int stack_offset,
++                   intptr_t* locals,     int locals_offset);
++
++// Support for dup and swap
++static void copy_stack_slot(intptr_t *tos, int from_offset, int to_offset);
++
++#ifndef PRODUCT
++static void verify_locals_tag(intptr_t *locals, frame::Tag tag, int offset);
++static void verify_stack_tag(intptr_t *tos, frame::Tag tag, int offset);
++static const char* C_msg(BytecodeInterpreter::messages msg);
++void print();
++#endif // PRODUCT
++
++    // Platform fields/methods
++# include "incls/_bytecodeInterpreter_pd.hpp.incl"
++
++}; // BytecodeInterpreter
++
++#endif // CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -0,0 +1,44 @@
++/*
++ * Copyright 2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++// This file holds platform-independant bodies of inline functions for the C++ based interpreter
++
++#ifdef CC_INTERP
++
++#ifdef ASSERT
++extern "C" { typedef void (*verify_oop_fn_t)(oop, const char *);};
++#define VERIFY_OOP(o) \
++        /*{ verify_oop_fn_t verify_oop_entry = \
++            *StubRoutines::verify_oop_subroutine_entry_address(); \
++          if (verify_oop_entry) { \
++             (*verify_oop_entry)((o), "Not an oop!"); \
++          } \
++        }*/
++#else
++#define VERIFY_OOP(o)
++#endif
++
++// Platform dependent data manipulation
++# include "incls/_bytecodeInterpreter_pd.inline.hpp.incl"
++#endif // CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xml openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xml
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xml	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xml	2007-12-14 08:57:02.000000000 +0100
+@@ -0,0 +1,10 @@
++<?xml version="1.0"?> 
++<!-- 
++     Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
++     SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
++-->
++<!DOCTYPE processcode [
++  <!ELEMENT processcode ANY>
++]>
++<processcode>
++</processcode>
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xsl openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xsl
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xsl	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xsl	2007-12-14 08:57:02.000000000 +0100
+@@ -0,0 +1,21 @@
++<?xml version="1.0"?> 
++<!-- 
++     Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
++     SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
++-->
++
++<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
++
++<xsl:template match="processcode">
++<xsl:text>
++#define VM_JVMTI
++#include "bytecodeInterpreter.cpp"
++</xsl:text>
++<xsl:text disable-output-escaping = "yes">
++
++</xsl:text>
++
++<xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
++</xsl:template>
++
++</xsl:stylesheet>
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodes.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodes.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodes.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodes.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)bytecodes.cpp	1.97 07/06/21 09:48:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodes.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodes.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodes.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodes.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)bytecodes.hpp	1.79 07/06/21 09:48:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -359,4 +356,3 @@
+   // Initialization
+   static void        initialize     ();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeStream.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodeStream.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeStream.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeStream.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)bytecodeStream.cpp	1.47 07/06/21 09:48:41 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeStream.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodeStream.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeStream.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeStream.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)bytecodeStream.hpp	1.54 07/06/21 09:48:41 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -173,5 +170,3 @@
+ 
+   bool            is_active_breakpoint() const   { return Bytecodes::is_active_breakpoint_at(bcp()); }
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)bytecodeTracer.cpp	1.52 07/06/08 15:21:46 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -56,9 +53,9 @@
+   bool      is_wide()                { return _is_wide; }
+ 
+ 
+-  void      print_constant(int i);
+-  void      print_attributes(Bytecodes::Code code, int bci);
+-  void      bytecode_epilog(int bci);
++  void      print_constant(int i, outputStream* st = tty);
++  void      print_attributes(Bytecodes::Code code, int bci, outputStream* st = tty);
++  void      bytecode_epilog(int bci, outputStream* st = tty);
+ 
+  public:
+   BytecodePrinter() {
+@@ -67,7 +64,7 @@
+ 
+   // This method is called while executing the raw bytecodes, so none of
+   // the adjustments that BytecodeStream performs applies.
+-  void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2) {
++  void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
+     ResourceMark rm;
+     if (_current_method != method()) {
+       // Note 1: This code will not work as expected with true MT/MP.
+@@ -76,10 +73,10 @@
+       // _current_method pointer happens to have the same bits as
+       // the incoming method.  We could lose a line of trace output.
+       // This is acceptable in a debug-only feature.
+-      tty->cr();
+-      tty->print("[%d] ", (int) Thread::current()->osthread()->thread_id());
+-      method->print_name(tty);
+-      tty->cr();
++      st->cr();
++      st->print("[%d] ", (int) Thread::current()->osthread()->thread_id());
++      method->print_name(st);
++      st->cr();
+       _current_method = method();
+     }
+     Bytecodes::Code code;
+@@ -90,12 +87,12 @@
+       code = Bytecodes::code_at(bcp);
+     }
+     int bci = bcp - method->code_base();
+-    tty->print("[%d] ", (int) Thread::current()->osthread()->thread_id());
++    st->print("[%d] ", (int) Thread::current()->osthread()->thread_id());
+     if (Verbose) {
+-      tty->print("%8d  %4d  " INTPTR_FORMAT " " INTPTR_FORMAT " %s", 
++      st->print("%8d  %4d  " INTPTR_FORMAT " " INTPTR_FORMAT " %s",
+ 	   BytecodeCounter::counter_value(), bci, tos, tos2, Bytecodes::name(code));
+     } else {
+-      tty->print("%8d  %4d  %s", 
++      st->print("%8d  %4d  %s",
+ 	   BytecodeCounter::counter_value(), bci, Bytecodes::name(code));
+     }
+     _next_pc = is_wide() ? bcp+2 : bcp+1;
+@@ -107,7 +104,7 @@
+ 
+   // Used for methodOop::print_codes().  The input bcp comes from
+   // BytecodeStream, which will skip wide bytecodes.
+-  void trace(methodHandle method, address bcp) {
++  void trace(methodHandle method, address bcp, outputStream* st) {
+     _current_method = method();
+     ResourceMark rm;
+     Bytecodes::Code code = Bytecodes::code_at(bcp);
+@@ -119,13 +116,13 @@
+     int bci = bcp - method->code_base();
+     // Print bytecode index and name
+     if (is_wide()) {
+-      tty->print("%d %s_w", bci, Bytecodes::name(code));
++      st->print("%d %s_w", bci, Bytecodes::name(code));
+     } else {
+-      tty->print("%d %s", bci, Bytecodes::name(code));
++      st->print("%d %s", bci, Bytecodes::name(code));
+     }
+     _next_pc = is_wide() ? bcp+2 : bcp+1;
+-    print_attributes(code, bci);
+-    bytecode_epilog(bci);
++    print_attributes(code, bci, st);
++    bytecode_epilog(bci, st);
+   }
+ };
+ 
+@@ -146,7 +143,7 @@
+ }
+ 
+ 
+-void BytecodeTracer::trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2 ) {
++void BytecodeTracer::trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
+   if (TraceBytecodes && BytecodeCounter::counter_value() >= TraceBytecodesAt) {
+     ttyLocker ttyl;  // 5065316: keep the following output coherent
+     // The ttyLocker also prevents races between two threads
+@@ -161,81 +158,81 @@
+     // We put the locker on the static trace method, not the
+     // virtual one, because the clients of this module go through
+     // the static method.
+-    _closure->trace(method, bcp, tos, tos2);
++    _closure->trace(method, bcp, tos, tos2, st);
+   }
+ }
+ 
+-void BytecodeTracer::trace(methodHandle method, address bcp) {
++void BytecodeTracer::trace(methodHandle method, address bcp, outputStream* st) {
+   ttyLocker ttyl;  // 5065316: keep the following output coherent
+-  _closure->trace(method, bcp);
++  _closure->trace(method, bcp, st);
+ }
+ 
+-void print_oop(oop value) {
++void print_oop(oop value, outputStream* st) {
+   if (value == NULL) {
+-    tty->print_cr(" NULL");
++    st->print_cr(" NULL");
+   } else {
+     EXCEPTION_MARK;
+     Handle h_value (THREAD, value);
+     symbolHandle sym = java_lang_String::as_symbol(h_value, CATCH);
+     if (sym->utf8_length() > 32) {
+-      tty->print_cr(" ....");
++      st->print_cr(" ....");
+     } else {
+-      sym->print(); tty->cr();
++      sym->print_on(st); st->cr();
+     }
+   }
+ }
+ 
+-void BytecodePrinter::print_constant(int i) {
++void BytecodePrinter::print_constant(int i, outputStream* st) {
+   constantPoolOop constants = method()->constants();
+   constantTag tag = constants->tag_at(i);
+ 
+   if (tag.is_int()) { 
+-    tty->print_cr(" " INT32_FORMAT, constants->int_at(i));
++    st->print_cr(" " INT32_FORMAT, constants->int_at(i));
+   } else if (tag.is_long()) {
+-    tty->print_cr(" " INT64_FORMAT, constants->long_at(i));
++    st->print_cr(" " INT64_FORMAT, constants->long_at(i));
+   } else if (tag.is_float()) { 
+-    tty->print_cr(" %f", constants->float_at(i));
++    st->print_cr(" %f", constants->float_at(i));
+   } else if (tag.is_double()) {
+-    tty->print_cr(" %f", constants->double_at(i));
++    st->print_cr(" %f", constants->double_at(i));
+   } else if (tag.is_string()) { 
+     oop string = constants->resolved_string_at(i);
+-    print_oop(string);
++    print_oop(string, st);
+   } else if (tag.is_unresolved_string()) { 
+-    tty->print_cr(" <unresolved string at %d>", i);  
++    st->print_cr(" <unresolved string at %d>", i);
+   } else if (tag.is_klass()) { 
+-    tty->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name());
++    st->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name());
+   } else if (tag.is_unresolved_klass()) { 
+-    tty->print_cr(" <unresolved klass at %d>", i);  
++    st->print_cr(" <unresolved klass at %d>", i);
+   } else ShouldNotReachHere();  
+ }
+ 
+ 
+-void BytecodePrinter::print_attributes(Bytecodes::Code code, int bci) {
++void BytecodePrinter::print_attributes(Bytecodes::Code code, int bci, outputStream* st) {
+   // Show attributes of pre-rewritten codes
+   code = Bytecodes::java_code(code);
+   // If the code doesn't have any fields there's nothing to print.
+   // note this is ==1 because the tableswitch and lookupswitch are
+   // zero size (for some reason) and we want to print stuff out for them.
+   if (Bytecodes::length_for(code) == 1) {
+-    tty->cr();
++    st->cr();
+     return;
+   }
+ 
+   switch(code) {
+     // Java specific bytecodes only matter.
+     case Bytecodes::_bipush:
+-      tty->print_cr(" " INT32_FORMAT, get_byte());
++      st->print_cr(" " INT32_FORMAT, get_byte());
+       break;
+     case Bytecodes::_sipush: 
+-      tty->print_cr(" " INT32_FORMAT, get_short());
++      st->print_cr(" " INT32_FORMAT, get_short());
+       break;
+     case Bytecodes::_ldc:
+-      print_constant(get_index());
++      print_constant(get_index(), st);
+       break;
+ 
+     case Bytecodes::_ldc_w:
+     case Bytecodes::_ldc2_w:
+-      print_constant(get_big_index());
++      print_constant(get_big_index(), st);
+       break;
+ 
+     case Bytecodes::_iload:
+@@ -248,13 +245,13 @@
+     case Bytecodes::_fstore:
+     case Bytecodes::_dstore:
+     case Bytecodes::_astore:
+-      tty->print_cr(" #%d", get_index_special());
++      st->print_cr(" #%d", get_index_special());
+       break;
+ 
+     case Bytecodes::_iinc:
+       { int index = get_index_special();
+         jint offset = is_wide() ? get_short(): get_byte();    
+-        tty->print_cr(" #%d " INT32_FORMAT, index, offset);
++        st->print_cr(" #%d " INT32_FORMAT, index, offset);
+       }
+       break;    
+ 
+@@ -264,14 +261,14 @@
+         if (str == NULL || atype == T_OBJECT || atype == T_ARRAY) {
+           assert(false, "Unidentified basic type");
+         }
+-        tty->print_cr(" %s", str);
++        st->print_cr(" %s", str);
+       }
+       break;
+     case Bytecodes::_anewarray: {
+         int klass_index = get_big_index();
+         constantPoolOop constants = method()->constants();
+         symbolOop name = constants->klass_name_at(klass_index);
+-        tty->print_cr(" %s ", name->as_C_string());
++        st->print_cr(" %s ", name->as_C_string());
+       }
+       break;
+     case Bytecodes::_multianewarray: {
+@@ -279,7 +276,7 @@
+         int nof_dims = get_index();
+         constantPoolOop constants = method()->constants();
+         symbolOop name = constants->klass_name_at(klass_index);
+-        tty->print_cr(" %s %d", name->as_C_string(), nof_dims);
++        st->print_cr(" %s %d", name->as_C_string(), nof_dims);
+       }
+       break;
+ 
+@@ -301,15 +298,15 @@
+     case Bytecodes::_if_acmpne:
+     case Bytecodes::_goto:
+     case Bytecodes::_jsr:
+-      tty->print_cr(" %d", bci + get_short());
++      st->print_cr(" %d", bci + get_short());
+       break;
+ 
+     case Bytecodes::_goto_w:
+     case Bytecodes::_jsr_w:
+-      tty->print_cr(" %d", bci + get_int());
++      st->print_cr(" %d", bci + get_int());
+       break;
+ 
+-    case Bytecodes::_ret: tty->print_cr(" %d", get_index_special()); break;
++    case Bytecodes::_ret: st->print_cr(" %d", get_index_special()); break;
+ 
+     case Bytecodes::_tableswitch:
+       { align();
+@@ -321,16 +318,16 @@
+         for (int i = 0; i < len; i++) {
+           dest[i] = bci + get_int();
+         }
+-        tty->print(" %d " INT32_FORMAT " " INT32_FORMAT " ",
++        st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ",
+                       default_dest, lo, hi); 
+         int first = true;
+         for (int ll = lo; ll <= hi; ll++, first = false)  {
+           int idx = ll - lo;
+           const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" :
+                                        ", %d:" INT32_FORMAT " (delta: %d)";
+-          tty->print(format, ll, dest[idx], dest[idx]-bci);
++          st->print(format, ll, dest[idx], dest[idx]-bci);
+         }
+-        tty->cr();
++        st->cr();
+       }
+       break;
+     case Bytecodes::_lookupswitch:
+@@ -343,14 +340,14 @@
+           key [i] = get_int();
+           dest[i] = bci + get_int();
+         };
+-        tty->print(" %d %d ", default_dest, len); 
++        st->print(" %d %d ", default_dest, len);
+         bool first = true;
+         for (int ll = 0; ll < len; ll++, first = false)  {
+           const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT :
+                                        ", " INT32_FORMAT ":" INT32_FORMAT ;
+-          tty->print(format, key[ll], dest[ll]);
++          st->print(format, key[ll], dest[ll]);
+         }
+-        tty->cr();
++        st->cr();
+       }
+       break;
+ 
+@@ -361,7 +358,7 @@
+         int i = get_big_index();
+         constantPoolOop constants = method()->constants();
+         symbolOop field = constants->name_ref_at(i);
+-        tty->print_cr(" %d <%s>", i, field->as_C_string()); 
++        st->print_cr(" %d <%s>", i, field->as_C_string());
+       }
+       break;
+ 
+@@ -372,7 +369,7 @@
+         constantPoolOop constants = method()->constants();
+         symbolOop name = constants->name_ref_at(i);
+         symbolOop signature = constants->signature_ref_at(i);
+-        tty->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string()); 
++        st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string());
+       }
+       break;
+ 
+@@ -383,7 +380,7 @@
+         constantPoolOop constants = method()->constants();
+         symbolOop name = constants->name_ref_at(i);
+         symbolOop signature = constants->signature_ref_at(i);
+-        tty->print_cr(" %d <%s> <%s> %d", i, name->as_C_string(), signature->as_C_string(), n);
++        st->print_cr(" %d <%s> <%s> %d", i, name->as_C_string(), signature->as_C_string(), n);
+       }
+       break;
+ 
+@@ -393,7 +390,7 @@
+       { int i = get_big_index();
+         constantPoolOop constants = method()->constants();
+         symbolOop name = constants->klass_name_at(i);
+-        tty->print_cr(" %d <%s>", i, name->as_C_string()); 
++        st->print_cr(" %d <%s>", i, name->as_C_string());
+       }
+       break;
+ 
+@@ -408,14 +405,14 @@
+ }
+ 
+ 
+-void BytecodePrinter::bytecode_epilog(int bci) {
++void BytecodePrinter::bytecode_epilog(int bci, outputStream* st) {
+   methodDataOop mdo = method()->method_data();
+   if (mdo != NULL) {
+     ProfileData* data = mdo->bci_to_data(bci);
+     if (data != NULL) {
+-      tty->print("  %d", mdo->dp_to_di(data->dp()));
+-      tty->fill_to(6);
+-      data->print_data_on(tty);
++      st->print("  %d", mdo->dp_to_di(data->dp()));
++      st->fill_to(6);
++      data->print_data_on(st);
+     }
+   }
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)bytecodeTracer.hpp	1.24 07/05/05 17:05:37 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -45,8 +42,8 @@
+   static BytecodeClosure* closure()				                      { return _closure; }
+   static void             set_closure(BytecodeClosure* closure)	{ _closure = closure; }
+ 
+-  static void             trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2);
+-  static void             trace(methodHandle method, address bcp);
++  static void             trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st = tty);
++  static void             trace(methodHandle method, address bcp, outputStream* st = tty);
+ };
+ 
+ 
+@@ -54,8 +51,8 @@
+ 
+ class BytecodeClosure {
+  public:
+-  virtual void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2) = 0;
+-  virtual void trace(methodHandle method, address bcp) = 0;
++  virtual void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) = 0;
++  virtual void trace(methodHandle method, address bcp, outputStream* st) = 0;
+ };
+ 
+ #endif // !PRODUCT
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.cpp openjdk/hotspot/src/share/vm/interpreter/cInterpreter.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/cInterpreter.cpp	1970-01-01 01:00:00.000000000 +0100
+@@ -1,359 +0,0 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cInterpreter.cpp	1.30 07/05/17 15:54:05 JVM"
+-#endif
+-/*
+- * Copyright 2002-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+- * CA 95054 USA or visit www.sun.com if you need additional information or
+- * have any questions.
+- *  
+- */
+-
+-/*
+- * Note:
+- * In order to eliminate the overhead of testing JVMTI flags
+- * during non debuging execution, we generate two version of the Interpreter.
+- * The first one is generated via the dependency in the includeDB mechanism 
+- * and is read in as part of the _cInterpreter.cpp.incl line below.
+- *
+- * The second and JVMTI enabled interpreter is brought in below after
+- * the line defining VM_JVMTI to 1.
+- * 
+- * On startup, the assembly generated to enter the Interpreter will be
+- * pointed at either InterpretMethod or InterpretMethodWithChecks depending
+- * on the state of the JVMTI flags..
+- */
+-#undef VM_JVMTI
+-
+-#include "incls/_precompiled.incl"
+-#include "incls/_cInterpreter.cpp.incl"
+-
+-#ifdef CC_INTERP
+-
+-
+-#define VM_JVMTI 1
+-
+-// Build the Interpreter that is used if JVMTI is enabled
+-#include "cInterpretMethod.hpp"
+-
+-// This constructor should only be used to contruct the object to signal
+-// interpreter initialization. All other instances should be created by
+-// the frame manager.
+-cInterpreter::cInterpreter(messages msg) {
+-  if (msg != initialize) ShouldNotReachHere(); 
+-  _msg = msg; 
+-  _self_link = this;
+-  _prev_link = NULL;
+-}
+-
+-// Dummy function so we can determine if a pc is within the interpreter.
+-// This is really a hack. Seems like adding state to thread ala last_Java_sp, etc.
+-// would be cleaner.
+-//
+-void cInterpreter::End_Of_Interpreter(void) {
+-}
+-
+-// Inline static functions for Java Stack and Local manipulation
+-
+-// The implementations are platform dependent. We have to worry about alignment
+-// issues on some machines which can change on the same platform depending on
+-// whether it is an LP64 machine also.
+-#ifdef ASSERT
+-void cInterpreter::verify_stack_tag(intptr_t *tos, frame::Tag tag, int offset) {
+-  if (TaggedStackInterpreter) {
+-    frame::Tag t = (frame::Tag)tos[Interpreter::expr_tag_index_at(-offset)];
+-    assert(t == tag, "stack tag mismatch");
+-  }
+-}
+-#endif // ASSERT
+-
+-address cInterpreter::stack_slot(intptr_t *tos, int offset) {
+-  debug_only(verify_stack_tag(tos, frame::TagValue, offset));
+-  return (address) tos[Interpreter::expr_index_at(-offset)];
+-}
+-
+-jint cInterpreter::stack_int(intptr_t *tos, int offset) {
+-  debug_only(verify_stack_tag(tos, frame::TagValue, offset));
+-  return *((jint*) &tos[Interpreter::expr_index_at(-offset)]);
+-}
+-
+-jfloat cInterpreter::stack_float(intptr_t *tos, int offset) {
+-  debug_only(verify_stack_tag(tos, frame::TagValue, offset));
+-  return *((jfloat *) &tos[Interpreter::expr_index_at(-offset)]);
+-}
+-
+-oop cInterpreter::stack_object(intptr_t *tos, int offset) {
+-  debug_only(verify_stack_tag(tos, frame::TagReference, offset));
+-  return (oop)tos [Interpreter::expr_index_at(-offset)];
+-}
+-
+-jdouble cInterpreter::stack_double(intptr_t *tos, int offset) {
+-  debug_only(verify_stack_tag(tos, frame::TagValue, offset));
+-  debug_only(verify_stack_tag(tos, frame::TagValue, offset-1));
+-  return ((VMJavaVal64*) &tos[Interpreter::expr_index_at(-offset)])->d;
+-}
+-
+-jlong cInterpreter::stack_long(intptr_t *tos, int offset) {
+-  debug_only(verify_stack_tag(tos, frame::TagValue, offset));
+-  debug_only(verify_stack_tag(tos, frame::TagValue, offset-1));
+-  return ((VMJavaVal64 *) &tos[Interpreter::expr_index_at(-offset)])->l;
+-}
+-
+-void cInterpreter::tag_stack(intptr_t *tos, frame::Tag tag, int offset) {
+-  if (TaggedStackInterpreter)
+-    tos[Interpreter::expr_tag_index_at(-offset)] = (intptr_t)tag;
+-}
+-
+-// only used for value types
+-void cInterpreter::set_stack_slot(intptr_t *tos, address value,
+-                                                        int offset) {
+-  tag_stack(tos, frame::TagValue, offset);
+-  *((address *)&tos[Interpreter::expr_index_at(-offset)]) = value;
+-}
+-
+-void cInterpreter::set_stack_int(intptr_t *tos, int value, 
+-                                                       int offset) {
+-  tag_stack(tos, frame::TagValue, offset);
+-  *((jint *)&tos[Interpreter::expr_index_at(-offset)]) = value;
+-}
+-
+-void cInterpreter::set_stack_float(intptr_t *tos, jfloat value, 
+-                                                         int offset) {
+-  tag_stack(tos, frame::TagValue, offset);
+-  *((jfloat *)&tos[Interpreter::expr_index_at(-offset)]) = value;
+-}
+-
+-void cInterpreter::set_stack_object(intptr_t *tos, oop value, 
+-                                                          int offset) {
+-  tag_stack(tos, frame::TagReference, offset);
+-  *((oop *)&tos[Interpreter::expr_index_at(-offset)]) = value;
+-}
+-
+-// needs to be platform dep for the 32 bit platforms.
+-void cInterpreter::set_stack_double(intptr_t *tos, jdouble value, 
+-                                                          int offset) {
+-  tag_stack(tos, frame::TagValue, offset);
+-  tag_stack(tos, frame::TagValue, offset-1);
+-  ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d = value;
+-}
+-
+-void cInterpreter::set_stack_double_from_addr(intptr_t *tos,
+-                                              address addr, int offset) {
+-  tag_stack(tos, frame::TagValue, offset);
+-  tag_stack(tos, frame::TagValue, offset-1);
+-  (((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d =
+-                        ((VMJavaVal64*)addr)->d);
+-}
+-
+-void cInterpreter::set_stack_long(intptr_t *tos, jlong value, 
+-                                                        int offset) {
+-  tag_stack(tos, frame::TagValue, offset);
+-  ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb;
+-  tag_stack(tos, frame::TagValue, offset-1);
+-  ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l = value;
+-}
+-
+-void cInterpreter::set_stack_long_from_addr(intptr_t *tos, 
+-                                            address addr, int offset) {
+-  tag_stack(tos, frame::TagValue, offset);
+-  ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb;
+-  tag_stack(tos, frame::TagValue, offset-1);
+-  ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l =
+-                        ((VMJavaVal64*)addr)->l;
+-}
+-
+-// Locals
+-
+-#ifdef ASSERT
+-void cInterpreter::verify_locals_tag(intptr_t *locals, frame::Tag tag,
+-                                     int offset) {
+-  if (TaggedStackInterpreter) {
+-    frame::Tag t = (frame::Tag)locals[Interpreter::local_tag_index_at(-offset)];
+-    assert(t == tag, "locals tag mismatch");
+-  }
+-}
+-#endif // ASSERT
+-address cInterpreter::locals_slot(intptr_t* locals, int offset) {
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
+-  return (address)locals[Interpreter::local_index_at(-offset)];
+-}
+-jint cInterpreter::locals_int(intptr_t* locals, int offset) {
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
+-  return (jint)locals[Interpreter::local_index_at(-offset)];
+-}
+-jfloat cInterpreter::locals_float(intptr_t* locals, int offset) {
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
+-  return (jfloat)locals[Interpreter::local_index_at(-offset)];
+-}
+-oop cInterpreter::locals_object(intptr_t* locals, int offset) {
+-  debug_only(verify_locals_tag(locals, frame::TagReference, offset));
+-  return (oop)locals[Interpreter::local_index_at(-offset)];
+-}
+-jdouble cInterpreter::locals_double(intptr_t* locals, int offset) {
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
+-  return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d;
+-}
+-jlong cInterpreter::locals_long(intptr_t* locals, int offset) {
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset+1));
+-  return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l;
+-}
+-
+-// Returns the address of locals value.
+-address cInterpreter::locals_long_at(intptr_t* locals, int offset) {
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset+1));
+-  return ((address)&locals[Interpreter::local_index_at(-(offset+1))]);
+-}
+-address cInterpreter::locals_double_at(intptr_t* locals, int offset) {
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset));
+-  debug_only(verify_locals_tag(locals, frame::TagValue, offset+1));
+-  return ((address)&locals[Interpreter::local_index_at(-(offset+1))]);
+-}
+-
+-void cInterpreter::tag_locals(intptr_t *locals, frame::Tag tag, int offset) {
+-  if (TaggedStackInterpreter)
+-    locals[Interpreter::local_tag_index_at(-offset)] = (intptr_t)tag;
+-}
+-
+-// Used for local value or returnAddress
+-void cInterpreter::set_locals_slot(intptr_t *locals,
+-                                   address value, int offset) {
+-  tag_locals(locals, frame::TagValue, offset);
+-  *((address*)&locals[Interpreter::local_index_at(-offset)]) = value;
+-}
+-void cInterpreter::set_locals_int(intptr_t *locals,
+-                                   jint value, int offset) {
+-  tag_locals(locals, frame::TagValue, offset);
+-  *((jint *)&locals[Interpreter::local_index_at(-offset)]) = value;
+-}
+-void cInterpreter::set_locals_float(intptr_t *locals,
+-                                   jfloat value, int offset) {
+-  tag_locals(locals, frame::TagValue, offset);
+-  *((jfloat *)&locals[Interpreter::local_index_at(-offset)]) = value;
+-}
+-void cInterpreter::set_locals_object(intptr_t *locals,
+-                                   oop value, int offset) {
+-  tag_locals(locals, frame::TagReference, offset);
+-  *((oop *)&locals[Interpreter::local_index_at(-offset)]) = value;
+-}
+-void cInterpreter::set_locals_double(intptr_t *locals,
+-                                   jdouble value, int offset) {
+-  tag_locals(locals, frame::TagValue, offset);
+-  tag_locals(locals, frame::TagValue, offset+1);
+-  ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = value;
+-}
+-void cInterpreter::set_locals_long(intptr_t *locals,
+-                                   jlong value, int offset) {
+-  tag_locals(locals, frame::TagValue, offset);
+-  tag_locals(locals, frame::TagValue, offset+1);
+-  ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = value;
+-}
+-void cInterpreter::set_locals_double_from_addr(intptr_t *locals,
+-                                   address addr, int offset) {
+-  tag_locals(locals, frame::TagValue, offset);
+-  tag_locals(locals, frame::TagValue, offset+1);
+-  ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = ((VMJavaVal64*)addr)->d;
+-}
+-void cInterpreter::set_locals_long_from_addr(intptr_t *locals,
+-                                   address addr, int offset) {
+-  tag_locals(locals, frame::TagValue, offset);
+-  tag_locals(locals, frame::TagValue, offset+1);
+-  ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = ((VMJavaVal64*)addr)->l;
+-}
+-
+-void cInterpreter::astore(intptr_t* tos,    int stack_offset,
+-                          intptr_t* locals, int locals_offset) {
+-  // Copy tag from stack to locals.  astore's operand can be returnAddress
+-  // and may not be TagReference
+-  if (TaggedStackInterpreter) {
+-    frame::Tag t = (frame::Tag) tos[Interpreter::expr_tag_index_at(-stack_offset)];
+-    locals[Interpreter::local_tag_index_at(-locals_offset)] = (intptr_t)t;
+-  }
+-  intptr_t value = tos[Interpreter::expr_index_at(-stack_offset)];
+-  locals[Interpreter::local_index_at(-locals_offset)] = value;
+-}
+-
+-
+-void cInterpreter::copy_stack_slot(intptr_t *tos, int from_offset,
+-                                   int to_offset) {
+-  if (TaggedStackInterpreter) {
+-    tos[Interpreter::expr_tag_index_at(-to_offset)] =
+-                      (intptr_t)tos[Interpreter::expr_tag_index_at(-from_offset)];
+-  }
+-  tos[Interpreter::expr_index_at(-to_offset)] =
+-                      (intptr_t)tos[Interpreter::expr_index_at(-from_offset)];
+-}
+-
+-void cInterpreter::dup(intptr_t *tos) {
+-  copy_stack_slot(tos, -1, 0);
+-}
+-void cInterpreter::dup2(intptr_t *tos) {
+-  copy_stack_slot(tos, -2, 0);
+-  copy_stack_slot(tos, -1, 1);
+-}
+-
+-void cInterpreter::dup_x1(intptr_t *tos) {
+-  /* insert top word two down */
+-  copy_stack_slot(tos, -1, 0);
+-  copy_stack_slot(tos, -2, -1);
+-  copy_stack_slot(tos, 0, -2);
+-}
+-
+-void cInterpreter::dup_x2(intptr_t *tos) {
+-  /* insert top word three down  */
+-  copy_stack_slot(tos, -1, 0);
+-  copy_stack_slot(tos, -2, -1);
+-  copy_stack_slot(tos, -3, -2);
+-  copy_stack_slot(tos, 0, -3);
+-}
+-void cInterpreter::dup2_x1(intptr_t *tos) {
+-  /* insert top 2 slots three down */
+-  copy_stack_slot(tos, -1, 1);
+-  copy_stack_slot(tos, -2, 0);
+-  copy_stack_slot(tos, -3, -1);
+-  copy_stack_slot(tos, 1, -2);
+-  copy_stack_slot(tos, 0, -3);
+-}
+-void cInterpreter::dup2_x2(intptr_t *tos) {
+-  /* insert top 2 slots four down */
+-  copy_stack_slot(tos, -1, 1);
+-  copy_stack_slot(tos, -2, 0);
+-  copy_stack_slot(tos, -3, -1);
+-  copy_stack_slot(tos, -4, -2);
+-  copy_stack_slot(tos, 1, -3);
+-  copy_stack_slot(tos, 0, -4);
+-}
+-
+-
+-void cInterpreter::swap(intptr_t *tos) {
+-  // swap top two elements
+-  intptr_t val = tos[Interpreter::expr_index_at(1)];
+-  frame::Tag t;
+-  if (TaggedStackInterpreter) {
+-    t = (frame::Tag) tos[Interpreter::expr_tag_index_at(1)];
+-  }
+-  // Copy -2 entry to -1
+-  copy_stack_slot(tos, -2, -1);
+-  // Store saved -1 entry into -2
+-  tos[Interpreter::expr_tag_index_at(2)] = (intptr_t)t;
+-  tos[Interpreter::expr_index_at(2)] = val;
+-}
+-#endif
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/cInterpreter.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/cInterpreter.hpp	1970-01-01 01:00:00.000000000 +0100
+@@ -1,565 +0,0 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cInterpreter.hpp	1.23 07/05/17 15:54:24 JVM"
+-#endif
+-/*
+- * Copyright 2002-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+- * CA 95054 USA or visit www.sun.com if you need additional information or
+- * have any questions.
+- *  
+- */
+-
+-#ifdef CC_INTERP
+-
+-// CVM definitions find hotspot equivalents...
+-
+-union VMJavaVal64 {
+-    jlong   l;
+-    jdouble d;
+-    uint32_t      v[2];
+-};
+-
+-
+-typedef class cInterpreter* interpreterState;
+-
+-struct call_message {
+-    methodOop _callee;               /* method to call during call_method request */
+-    address   _callee_entry_point;   /* address to jump to for call_method request */
+-    int       _bcp_advance;          /* size of the invoke bytecode operation */
+-};
+-
+-struct osr_message {
+-    address _osr_buf;                 /* the osr buffer */
+-    address _osr_entry;               /* the entry to the osr method */
+-};
+-
+-// Result returned to frame manager
+-union frame_manager_message {
+-    call_message _to_call;            /* describes callee */
+-    Bytecodes::Code _return_kind;     /* i_return, a_return, ... */
+-    osr_message _osr;                 /* describes the osr */
+-};
+-
+-class cInterpreter : StackObj {
+-friend class AbstractInterpreterGenerator;
+-friend class InterpreterGenerator;
+-friend class InterpreterMacroAssembler;
+-friend class frame;
+-friend class VMStructs;
+-
+-public:
+-    enum messages {
+-         no_request = 0,            // unused
+-         initialize,                // Perform one time interpreter initializations (assumes all switches set)
+-         // status message to C++ interpreter
+-         method_entry,              // initial method entry to interpreter
+-         method_resume,             // frame manager response to return_from_method request (assuming a frame to resume)
+-         deopt_resume,              // returning from a native call into a deopted frame
+-         deopt_resume2,             // deopt resume as a result of a PopFrame
+-         got_monitors,              // frame manager response to more_monitors request
+-         rethrow_exception,         // unwinding and throwing exception
+-         // requests to frame manager from C++ interpreter
+-         call_method,               // request for new frame from interpreter, manager responds with method_entry
+-         do_osr,                    // osr the current method
+-         return_from_method,        // request from interpreter to unwind, manager responds with method_continue
+-         more_monitors,             // need a new monitor
+-	 throwing_exception,        // unwind stack and rethrow
+-	 popping_frame              // unwind call and retry call
+-    };
+-
+-private:
+-    JavaThread*           _thread;        // the vm's java thread pointer
+-    address               _bcp;           // instruction pointer
+-    intptr_t*             _locals;        // local variable pointer
+-    constantPoolCacheOop  _constants;     // constant pool cache
+-    methodOop             _method;        // method being executed
+-    DataLayout*           _mdx;           // compiler profiling data for current bytecode
+-    intptr_t*             _stack;         // expression stack
+-    messages              _msg;           // frame manager <-> interpreter message
+-    frame_manager_message _result;        // result to frame manager
+-    interpreterState      _prev_link;     // previous interpreter state
+-    oop                   _oop_temp;      // mirror for interpreted native, null otherwise
+-    // These are likely platform dependent fields
+-    // jint*  sender_sp;                  // previous stack pointer
+-    intptr_t*             _stack_base;    // base of expression stack
+-    intptr_t*             _stack_limit;   // limit of expression stack
+-    BasicObjectLock*      _monitor_base;  // base of monitors on the native stack
+-
+-
+-public:
+-  // Constructor is only used by the initialization step. All other instances are created
+-  // by the frame manager.
+-  cInterpreter(messages msg);
+-
+-//
+-// Deoptimization support
+-//
+-static void layout_interpreterState(interpreterState to_fill,
+-				    frame* caller,
+-				    frame* interpreter_frame,
+-				    methodOop method,
+-				    intptr_t* locals,
+-				    intptr_t* stack,
+-				    intptr_t* stack_base,
+-				    intptr_t* monitor_base,
+-				    intptr_t* frame_bottom,
+-				    bool top_frame);
+-
+-/*
+- * Generic 32-bit wide "Java slot" definition. This type occurs
+- * in operand stacks, Java locals, object fields, constant pools.
+- */
+-union VMJavaVal32 {
+-    jint     i;
+-    jfloat   f;
+-    oop      r;
+-    uint32_t raw;
+-};
+-
+-/*
+- * Generic 64-bit Java value definition
+- */
+-union VMJavaVal64 {
+-    jlong   l;
+-    jdouble d;
+-    uint32_t      v[2];
+-};
+-
+-/*
+- * Generic 32-bit wide "Java slot" definition. This type occurs
+- * in Java locals, object fields, constant pools, and
+- * operand stacks (as a CVMStackVal32).
+- */
+-typedef union VMSlotVal32 {
+-    VMJavaVal32    j;     /* For "Java" values */
+-    address        a;     /* a return created by jsr or jsr_w */
+-} VMSlotVal32;
+-
+-
+-/*
+- * Generic 32-bit wide stack slot definition.
+- */
+-union VMStackVal32 {
+-    VMJavaVal32    j;     /* For "Java" values */
+-    VMSlotVal32    s;     /* any value from a "slot" or locals[] */
+-};
+-
+-inline JavaThread* thread() { return _thread; }
+-
+-inline address bcp() { return _bcp; }
+-inline void set_bcp(address new_bcp) { _bcp = new_bcp; }
+-
+-inline intptr_t* locals() { return _locals; }
+-
+-inline constantPoolCacheOop constants() { return _constants; }
+-inline methodOop method() { return _method; }
+-inline DataLayout* mdx() { return _mdx; }
+-
+-inline messages msg() { return _msg; }
+-inline void set_msg(messages new_msg) { _msg = new_msg; }
+-
+-inline methodOop callee() { return _result._to_call._callee; }
+-inline void set_callee(methodOop new_callee) { _result._to_call._callee = new_callee; }
+-inline void set_callee_entry_point(address entry) { _result._to_call._callee_entry_point = entry; }
+-inline void set_osr_buf(address buf) { _result._osr._osr_buf = buf; }
+-inline void set_osr_entry(address entry) { _result._osr._osr_entry = entry; }
+-inline int bcp_advance() { return _result._to_call._bcp_advance; }
+-inline void set_bcp_advance(int count) { _result._to_call._bcp_advance = count; }
+-
+-inline void set_return_kind(Bytecodes::Code kind) { _result._return_kind = kind; }
+-
+-inline interpreterState prev() { return _prev_link; }
+-
+-inline intptr_t* stack() { return _stack; }
+-inline void set_stack(intptr_t* new_stack) { _stack = new_stack; }
+-
+-
+-inline intptr_t* stack_base() { return _stack_base; }
+-inline intptr_t* stack_limit() { return _stack_limit; }
+-
+-inline BasicObjectLock* monitor_base() { return _monitor_base; }
+-
+-/*
+- * 64-bit Arithmetic:
+- *
+- * The functions below follow the semantics of the
+- * ladd, land, ldiv, lmul, lor, lxor, and lrem bytecodes,
+- * respectively.
+- */
+-
+-static jlong VMlongAdd(jlong op1, jlong op2);
+-static jlong VMlongAnd(jlong op1, jlong op2);
+-static jlong VMlongDiv(jlong op1, jlong op2);
+-static jlong VMlongMul(jlong op1, jlong op2);
+-static jlong VMlongOr (jlong op1, jlong op2);
+-static jlong VMlongSub(jlong op1, jlong op2);
+-static jlong VMlongXor(jlong op1, jlong op2);
+-static jlong VMlongRem(jlong op1, jlong op2);
+-
+-/*
+- * Shift:
+- *
+- * The functions below follow the semantics of the
+- * lushr, lshl, and lshr bytecodes, respectively.
+- */
+-
+-static jlong VMlongUshr(jlong op1, jint op2);
+-static jlong VMlongShl (jlong op1, jint op2);
+-static jlong VMlongShr (jlong op1, jint op2);
+-
+-/*
+- * Unary:
+- *
+- * Return the negation of "op" (-op), according to
+- * the semantics of the lneg bytecode.
+- */
+-
+-static jlong VMlongNeg(jlong op);
+-
+-/*
+- * Return the complement of "op" (~op)
+- */
+-
+-static jlong VMlongNot(jlong op);
+-
+-
+-/*
+- * Comparisons to 0:
+- */
+-
+-static int32_t VMlongLtz(jlong op);     /* op <= 0 */
+-static int32_t VMlongGez(jlong op);     /* op >= 0 */
+-static int32_t VMlongEqz(jlong op);     /* op == 0 */
+-
+-/*
+- * Between operands:
+- */
+-
+-static int32_t VMlongEq(jlong op1, jlong op2);    /* op1 == op2 */
+-static int32_t VMlongNe(jlong op1, jlong op2);    /* op1 != op2 */
+-static int32_t VMlongGe(jlong op1, jlong op2);    /* op1 >= op2 */
+-static int32_t VMlongLe(jlong op1, jlong op2);    /* op1 <= op2 */
+-static int32_t VMlongLt(jlong op1, jlong op2);    /* op1 <  op2 */
+-static int32_t VMlongGt(jlong op1, jlong op2);    /* op1 >  op2 */
+-
+-/*
+- * Comparisons (returning an jint value: 0, 1, or -1)
+- *
+- * Between operands:
+- *
+- * Compare "op1" and "op2" according to the semantics of the
+- * "lcmp" bytecode.
+- */
+-
+-static int32_t VMlongCompare(jlong op1, jlong op2);
+-
+-/*
+- * Convert int to long, according to "i2l" bytecode semantics
+- */
+-static jlong VMint2Long(jint val);
+-
+-/*
+- * Convert long to int, according to "l2i" bytecode semantics
+- */
+-static jint VMlong2Int(jlong val);
+-
+-/*
+- * Convert long to float, according to "l2f" bytecode semantics
+- */
+-static jfloat VMlong2Float(jlong val);
+-
+-/*
+- * Convert long to double, according to "l2d" bytecode semantics
+- */
+-static jdouble VMlong2Double(jlong val);
+-
+-/*
+- * Java floating-point float value manipulation.
+- *
+- * The result argument is, once again, an lvalue.
+- *
+- * Arithmetic:
+- *
+- * The functions below follow the semantics of the
+- * fadd, fsub, fmul, fdiv, and frem bytecodes,
+- * respectively.
+- */
+-
+-static jfloat VMfloatAdd(jfloat op1, jfloat op2);
+-static jfloat VMfloatSub(jfloat op1, jfloat op2);
+-static jfloat VMfloatMul(jfloat op1, jfloat op2);
+-static jfloat VMfloatDiv(jfloat op1, jfloat op2);
+-static jfloat VMfloatRem(jfloat op1, jfloat op2);
+-
+-/*
+- * Unary:
+- *
+- * Return the negation of "op" (-op), according to
+- * the semantics of the fneg bytecode.
+- */
+-
+-static jfloat VMfloatNeg(jfloat op);
+-
+-/*
+- * Comparisons (returning an int value: 0, 1, or -1)
+- *
+- * Between operands:
+- *
+- * Compare "op1" and "op2" according to the semantics of the
+- * "fcmpl" (direction is -1) or "fcmpg" (direction is 1) bytecodes.
+- */
+-
+-static int32_t VMfloatCompare(jfloat op1, jfloat op2,
+-                              int32_t direction);
+-/*
+- * Conversion:
+- */
+-
+-/*
+- * Convert float to double, according to "f2d" bytecode semantics
+- */
+-
+-static jdouble VMfloat2Double(jfloat op);
+-
+-/*
+- ******************************************
+- * Java double floating-point manipulation.
+- ******************************************
+- *
+- * The result argument is, once again, an lvalue.
+- *
+- * Conversions:
+- */
+-
+-/*
+- * Convert double to int, according to "d2i" bytecode semantics
+- */
+-
+-static jint VMdouble2Int(jdouble val);
+-
+-/*
+- * Convert double to float, according to "d2f" bytecode semantics
+- */
+-
+-static jfloat VMdouble2Float(jdouble val);
+-
+-/*
+- * Convert int to double, according to "i2d" bytecode semantics
+- */
+-
+-static jdouble VMint2Double(jint val);
+-
+-/*
+- * Arithmetic:
+- *
+- * The functions below follow the semantics of the
+- * dadd, dsub, ddiv, dmul, and drem bytecodes, respectively.
+- */
+-
+-static jdouble VMdoubleAdd(jdouble op1, jdouble op2);
+-static jdouble VMdoubleSub(jdouble op1, jdouble op2);
+-static jdouble VMdoubleDiv(jdouble op1, jdouble op2);
+-static jdouble VMdoubleMul(jdouble op1, jdouble op2);
+-static jdouble VMdoubleRem(jdouble op1, jdouble op2);
+-
+-/*
+- * Unary:
+- *
+- * Return the negation of "op" (-op), according to
+- * the semantics of the dneg bytecode.
+- */
+-
+-static jdouble VMdoubleNeg(jdouble op);
+-
+-/*
+- * Comparisons (returning an int32_t value: 0, 1, or -1)
+- *
+- * Between operands:
+- *
+- * Compare "op1" and "op2" according to the semantics of the
+- * "dcmpl" (direction is -1) or "dcmpg" (direction is 1) bytecodes.
+- */
+-
+-static int32_t VMdoubleCompare(jdouble op1, jdouble op2, int32_t direction);
+-
+-/*
+- * Copy two typeless 32-bit words from one location to another.
+- * This is semantically equivalent to:
+- * 
+- * to[0] = from[0];
+- * to[1] = from[1];
+- *
+- * but this interface is provided for those platforms that could
+- * optimize this into a single 64-bit transfer.
+- */
+-
+-static void VMmemCopy64(uint32_t to[2], const uint32_t from[2]);
+-
+-
+-// Arithmetic operations
+-
+-/*
+- * Java arithmetic methods. 
+- * The functions below follow the semantics of the
+- * iadd, isub, imul, idiv, irem, iand, ior, ixor,
+- * and ineg bytecodes, respectively.
+- */
+-
+-static jint VMintAdd(jint op1, jint op2);
+-static jint VMintSub(jint op1, jint op2);
+-static jint VMintMul(jint op1, jint op2);
+-static jint VMintDiv(jint op1, jint op2);
+-static jint VMintRem(jint op1, jint op2);
+-static jint VMintAnd(jint op1, jint op2);
+-static jint VMintOr (jint op1, jint op2);
+-static jint VMintXor(jint op1, jint op2);
+-
+-/*
+- * Shift Operation:
+- * The functions below follow the semantics of the
+- * iushr, ishl, and ishr bytecodes, respectively.
+- */
+-
+-static jint VMintUshr(jint op, jint num);
+-static jint VMintShl (jint op, jint num);
+-static jint VMintShr (jint op, jint num);
+-
+-/*
+- * Unary Operation:
+- *
+- * Return the negation of "op" (-op), according to
+- * the semantics of the ineg bytecode.
+- */
+-
+-static jint VMintNeg(jint op);
+-
+-/*
+- * Int Conversions:
+- */
+-
+-/*
+- * Convert int to float, according to "i2f" bytecode semantics
+- */
+-
+-static jfloat VMint2Float(jint val);
+-
+-/*
+- * Convert int to byte, according to "i2b" bytecode semantics
+- */
+-
+-static jbyte VMint2Byte(jint val);
+-
+-/*
+- * Convert int to char, according to "i2c" bytecode semantics
+- */
+-
+-static jchar VMint2Char(jint val);
+-
+-/*
+- * Convert int to short, according to "i2s" bytecode semantics
+- */
+-
+-static jshort VMint2Short(jint val);
+-
+-/*=========================================================================
+- * Bytecode interpreter operations
+- *=======================================================================*/
+-
+-static void dup(intptr_t *tos);
+-static void dup2(intptr_t *tos);
+-static void dup_x1(intptr_t *tos);    /* insert top word two down */
+-static void dup_x2(intptr_t *tos);    /* insert top word three down  */
+-static void dup2_x1(intptr_t *tos);   /* insert top 2 slots three down */
+-static void dup2_x2(intptr_t *tos);   /* insert top 2 slots four down */
+-static void swap(intptr_t *tos);      /* swap top two elements */
+-
+-// umm don't like this method modifies its object
+-
+-// The Interpreter used when 
+-static void InterpretMethod(interpreterState istate);
+-// The interpreter used if JVMTI needs interpreter events
+-static void InterpretMethodWithChecks(interpreterState istate);
+-static void End_Of_Interpreter(void);
+-
+-// Inline static functions for Java Stack and Local manipulation
+-
+-static address stack_slot(intptr_t *tos, int offset);
+-static jint stack_int(intptr_t *tos, int offset);
+-static jfloat stack_float(intptr_t *tos, int offset);
+-static oop stack_object(intptr_t *tos, int offset);
+-static jdouble stack_double(intptr_t *tos, int offset);
+-static jlong stack_long(intptr_t *tos, int offset);
+-
+-static void tag_stack(intptr_t *tos, frame::Tag tag, int offset);
+-
+-// only used for value types
+-static void set_stack_slot(intptr_t *tos, address value, int offset);
+-static void set_stack_int(intptr_t *tos, int value, int offset);
+-static void set_stack_float(intptr_t *tos, jfloat value, int offset);
+-static void set_stack_object(intptr_t *tos, oop value, int offset);
+-
+-// needs to be platform dep for the 32 bit platforms.
+-static void set_stack_double(intptr_t *tos, jdouble value, int offset);
+-static void set_stack_long(intptr_t *tos, jlong value, int offset);
+-
+-static void set_stack_double_from_addr(intptr_t *tos, address addr, int offset);
+-static void set_stack_long_from_addr(intptr_t *tos, address addr, int offset);
+-
+-// Locals
+-
+-static address locals_slot(intptr_t* locals, int offset);
+-static jint locals_int(intptr_t* locals, int offset);
+-static jfloat locals_float(intptr_t* locals, int offset);
+-static oop locals_object(intptr_t* locals, int offset);
+-static jdouble locals_double(intptr_t* locals, int offset);
+-static jlong locals_long(intptr_t* locals, int offset);
+-
+-static address locals_long_at(intptr_t* locals, int offset);
+-static address locals_double_at(intptr_t* locals, int offset);
+-
+-static void tag_locals(intptr_t *locals, frame::Tag tag, int offset);
+-
+-static void set_locals_slot(intptr_t *locals, address value, int offset);
+-static void set_locals_int(intptr_t *locals, jint value, int offset);
+-static void set_locals_float(intptr_t *locals, jfloat value, int offset);
+-static void set_locals_object(intptr_t *locals, oop value, int offset);
+-static void set_locals_double(intptr_t *locals, jdouble value, int offset);
+-static void set_locals_long(intptr_t *locals, jlong value, int offset);
+-static void set_locals_double_from_addr(intptr_t *locals,
+-                                   address addr, int offset);
+-static void set_locals_long_from_addr(intptr_t *locals,
+-                                   address addr, int offset);
+-
+-static void astore(intptr_t* topOfStack, int stack_offset,
+-                   intptr_t* locals,     int locals_offset);
+-
+-// Support for dup and swap
+-static void copy_stack_slot(intptr_t *tos, int from_offset, int to_offset);
+-
+-#ifndef PRODUCT
+-static void verify_locals_tag(intptr_t *locals, frame::Tag tag, int offset);
+-static void verify_stack_tag(intptr_t *tos, frame::Tag tag, int offset);
+-#endif // PRODUCT
+-
+-    // Platform fields/methods 
+-# include "incls/_cInterpreter_pd.hpp.incl"
+-
+-}; // cInterpreter
+-
+-#endif // CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.inline.hpp openjdk/hotspot/src/share/vm/interpreter/cInterpreter.inline.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.inline.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/cInterpreter.inline.hpp	1970-01-01 01:00:00.000000000 +0100
+@@ -1,47 +0,0 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cInterpreter.inline.hpp	1.9 07/05/05 17:05:37 JVM"
+-#endif
+-/*
+- * Copyright 2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+- * CA 95054 USA or visit www.sun.com if you need additional information or
+- * have any questions.
+- *  
+- */
+-
+-// This file holds platform-independant bodies of inline functions for the C++ based interpreter
+-
+-#ifdef CC_INTERP
+-
+-#ifdef ASSERT
+-extern "C" { typedef void (*verify_oop_fn_t)(oop, const char *);};
+-#define VERIFY_OOP(o) \
+-	/*{ verify_oop_fn_t verify_oop_entry = \
+-            *StubRoutines::verify_oop_subroutine_entry_address(); \
+-          if (verify_oop_entry) { \
+-	     (*verify_oop_entry)((o), "Not an oop!"); \
+-	  } \
+-	}*/
+-#else
+-#define VERIFY_OOP(o)
+-#endif
+-
+-// Platform dependent data manipulation
+-# include "incls/_cInterpreter_pd.inline.hpp.incl"
+-#endif // CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cInterpretMethod.hpp openjdk/hotspot/src/share/vm/interpreter/cInterpretMethod.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/cInterpretMethod.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/cInterpretMethod.hpp	1970-01-01 01:00:00.000000000 +0100
+@@ -1,2617 +0,0 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cInterpretMethod.hpp	1.68 07/05/17 15:54:02 JVM"
+-#endif
+-/*
+- * Copyright 2002-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+- * CA 95054 USA or visit www.sun.com if you need additional information or
+- * have any questions.
+- *  
+- */
+-
+-#ifndef CINTERPRETERBODY_ONCE
+-#define CINTERPERTERBODY_ONCE 
+-#endif
+-
+-/*
+- * This code was converted from CVM sources to C++ and the Hotspot VM
+- */
+-
+-#ifdef CC_INTERP
+-
+-/*
+- * USELABELS - If using GCC, then use labels for the opcode dispatching
+- * rather -then a switch statement. This improves performance because it
+- * gives us the oportunity to have the instructions that calculate the
+- * next opcode to jump to be intermixed with the rest of the instructions
+- * that implement the opcode (see UPDATE_PC_AND_TOS_AND_CONTINUE macro).
+- */
+-#undef USELABELS
+-#ifdef __GNUC__
+-/* 
+-   ASSERT signifies debugging. It is much easier to step thru bytecodes if we
+-   don't use the computed goto approach.
+-*/
+-#ifndef ASSERT
+-#define USELABELS
+-#endif
+-#endif
+-
+-#undef CASE
+-#ifdef USELABELS
+-#define CASE(opcode) opc ## opcode
+-#define DEFAULT opc_default
+-#else
+-#define CASE(opcode) case Bytecodes:: opcode
+-#define DEFAULT default
+-#endif
+-
+-/*
+- * PREFETCH_OPCCODE - Some compilers do better if you prefetch the next 
+- * opcode before going back to the top of the while loop, rather then having
+- * the top of the while loop handle it. This provides a better opportunity
+- * for instruction scheduling. Some compilers just do this prefetch
+- * automatically. Some actually end up with worse performance if you
+- * force the prefetch. Solaris gcc seems to do better, but cc does worse.
+- */
+-#undef PREFETCH_OPCCODE
+-#define PREFETCH_OPCCODE
+-
+-/*
+-  Interpreter safepoint: it is expected that the interpreter will have no live
+-  handles of its own creation live at an interpreter safepoint. Therefore we
+-  run a HandleMarkCleaner and trash all handles allocated in the call chain
+-  since the JavaCalls::call_helper invocation that initiated the chain.
+-  There really shouldn't be any handles remaining to trash but this is cheap
+-  in relation to a safepoint.
+-*/
+-#define SAFEPOINT                                                                 \
+-    if ( SafepointSynchronize::is_synchronizing()) {                              \
+-        {                                                                         \
+-          /* zap freed handles rather than GC'ing them */                         \
+-          HandleMarkCleaner __hmc(THREAD);                                        \
+-        }                                                                         \
+-        CALL_VM(SafepointSynchronize::block(THREAD), handle_exception);           \
+-    }
+-
+-/*
+- * VM_JAVA_ERROR - Macro for throwing a java exception from
+- * the interpreter loop. Should really be a CALL_VM but there
+- * is no entry point to do the transition to vm so we just
+- * do it by hand here.
+- */
+-#define VM_JAVA_ERROR_NO_JUMP(name, msg)                                                  \
+-    DECACHE_STATE();                                                              \
+-    SET_LAST_JAVA_FRAME();                                                        \
+-    {                                                                             \
+-       ThreadInVMfromJava trans(THREAD);                                          \
+-       Exceptions::_throw_msg(THREAD, __FILE__, __LINE__, name, msg, NULL, NULL); \
+-    }                                                                             \
+-    RESET_LAST_JAVA_FRAME();                                                      \
+-    CACHE_STATE();                                                                
+-
+-// Normal throw of a java error
+-#define VM_JAVA_ERROR(name, msg)                                                  \
+-    VM_JAVA_ERROR_NO_JUMP(name, msg)                                              \
+-    goto handle_exception;
+-
+-#ifdef PRODUCT
+-#define DO_UPDATE_INSTRUCTION_COUNT(opcode)
+-#else
+-#define DO_UPDATE_INSTRUCTION_COUNT(opcode)                                                          \
+-{                                                                                                    \
+-    BytecodeCounter::_counter_value++;                                                               \
+-    BytecodeHistogram::_counters[(Bytecodes::Code)opcode]++;                                         \
+-    if (StopInterpreterAt && StopInterpreterAt == BytecodeCounter::_counter_value) os::breakpoint(); \
+-    if (TraceBytecodes) {                                                                            \
+-      CALL_VM((void)SharedRuntime::trace_bytecode(THREAD, 0,               \
+-                                   topOfStack[Interpreter::expr_index_at(1)],   \
+-                                   topOfStack[Interpreter::expr_index_at(2)]),  \
+-                                   handle_exception);                      \
+-    }                                                                      \
+-}
+-#endif
+-
+-#undef DEBUGGER_SINGLE_STEP_NOTIFY
+-#ifdef VM_JVMTI
+-/* NOTE: (kbr) This macro must be called AFTER the PC has been
+-   incremented. JvmtiExport::at_single_stepping_point() may cause a
+-   breakpoint opcode to get inserted at the current PC to allow the
+-   debugger to coalesce single-step events.
+-   
+-   As a result if we call at_single_stepping_point() we refetch opcode
+-   to get the current opcode. This will override any other prefetching
+-   that might have occurred.
+-*/
+-#define DEBUGGER_SINGLE_STEP_NOTIFY()                                            \
+-{                                                                                \
+-      if (_jvmti_interp_events) {                                                \
+-        if (JvmtiExport::should_post_single_step()) {                            \
+-          DECACHE_STATE();                                                       \
+-          SET_LAST_JAVA_FRAME();                                                 \
+-          ThreadInVMfromJava trans(THREAD);                                      \
+-          JvmtiExport::at_single_stepping_point(THREAD,                          \
+-                                          istate->method(),                      \
+-                                          pc);                                   \
+-          RESET_LAST_JAVA_FRAME();                                               \
+-          CACHE_STATE();                                                         \
+-          if (THREAD->pop_frame_pending() &&                                     \
+-              !THREAD->pop_frame_in_process()) {                                 \
+-            goto handle_Pop_Frame;                                               \
+-          }                                                                      \
+-          opcode = *pc;                                                          \
+-        }                                                                        \
+-      }                                                                          \
+-}
+-#else
+-#define DEBUGGER_SINGLE_STEP_NOTIFY() 
+-#endif
+-
+-/*
+- * CONTINUE - Macro for executing the next opcode.
+- */
+-#undef CONTINUE
+-#ifdef USELABELS
+-// Have to do this dispatch this way in C++ because otherwise gcc complains about crossing an
+-// initialization (which is is the initialization of the table pointer...)
+-#define DISPATCH(opcode) goto *dispatch_table[opcode]
+-#define CONTINUE {                              \
+-        opcode = *pc;                           \
+-        DO_UPDATE_INSTRUCTION_COUNT(opcode);    \
+-        DEBUGGER_SINGLE_STEP_NOTIFY();          \
+-        DISPATCH(opcode);                       \
+-    }
+-#else
+-#ifdef PREFETCH_OPCCODE
+-#define CONTINUE {                              \
+-        opcode = *pc;                           \
+-        DO_UPDATE_INSTRUCTION_COUNT(opcode);    \
+-        DEBUGGER_SINGLE_STEP_NOTIFY();          \
+-        continue;                               \
+-    }
+-#else
+-#define CONTINUE {                              \
+-        DO_UPDATE_INSTRUCTION_COUNT(opcode);    \
+-        DEBUGGER_SINGLE_STEP_NOTIFY();          \
+-        continue;                               \
+-    }
+-#endif
+-#endif
+-
+-// JavaStack Implementation
+-#define MORE_STACK(count)  \
+-    (topOfStack -= ((count) * Interpreter::stackElementWords()))
+-
+-
+-#define UPDATE_PC(opsize) {pc += opsize; }
+-/*
+- * UPDATE_PC_AND_TOS - Macro for updating the pc and topOfStack.
+- */
+-#undef UPDATE_PC_AND_TOS
+-#define UPDATE_PC_AND_TOS(opsize, stack) \
+-    {pc += opsize; MORE_STACK(stack); }
+-
+-/*
+- * UPDATE_PC_AND_TOS_AND_CONTINUE - Macro for updating the pc and topOfStack,
+- * and executing the next opcode. It's somewhat similar to the combination
+- * of UPDATE_PC_AND_TOS and CONTINUE, but with some minor optimizations.
+- */
+-#undef UPDATE_PC_AND_TOS_AND_CONTINUE
+-#ifdef USELABELS
+-#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) {         \
+-        pc += opsize; opcode = *pc; MORE_STACK(stack);          \
+-        DO_UPDATE_INSTRUCTION_COUNT(opcode);                    \
+-        DEBUGGER_SINGLE_STEP_NOTIFY();                          \
+-        DISPATCH(opcode);                                       \
+-    }
+-
+-#define UPDATE_PC_AND_CONTINUE(opsize) {                        \
+-        pc += opsize; opcode = *pc;                             \
+-        DO_UPDATE_INSTRUCTION_COUNT(opcode);                    \
+-        DEBUGGER_SINGLE_STEP_NOTIFY();                          \
+-        DISPATCH(opcode);                                       \
+-    }
+-#else
+-#ifdef PREFETCH_OPCCODE
+-#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) {         \
+-        pc += opsize; opcode = *pc; MORE_STACK(stack);          \
+-        DO_UPDATE_INSTRUCTION_COUNT(opcode);                    \
+-        DEBUGGER_SINGLE_STEP_NOTIFY();                          \
+-        goto do_continue;                                       \
+-    }
+-
+-#define UPDATE_PC_AND_CONTINUE(opsize) {                        \
+-        pc += opsize; opcode = *pc;                             \
+-        DO_UPDATE_INSTRUCTION_COUNT(opcode);                    \
+-        DEBUGGER_SINGLE_STEP_NOTIFY();                          \
+-        goto do_continue;                                       \
+-    }
+-#else
+-#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \
+-        pc += opsize; MORE_STACK(stack);                \
+-        DO_UPDATE_INSTRUCTION_COUNT(opcode);            \
+-        DEBUGGER_SINGLE_STEP_NOTIFY();                  \
+-        goto do_continue;                               \
+-    }
+-
+-#define UPDATE_PC_AND_CONTINUE(opsize) {                \
+-        pc += opsize;                                   \
+-        DO_UPDATE_INSTRUCTION_COUNT(opcode);            \
+-        DEBUGGER_SINGLE_STEP_NOTIFY();                  \
+-        goto do_continue;                               \
+-    }
+-#endif /* PREFETCH_OPCCODE */
+-#endif /* USELABELS */
+-
+-// About to call a new method, update the save the adjusted pc and return to frame manager
+-#define UPDATE_PC_AND_RETURN(opsize)  \
+-   DECACHE_TOS();                     \
+-   istate->set_bcp(pc+opsize);        \
+-   return;
+-
+-
+-#define METHOD istate->method()
+-#define INVOCATION_COUNT METHOD->invocation_counter()
+-#define BACKEDGE_COUNT METHOD->backedge_counter()
+-
+-
+-#define INCR_INVOCATION_COUNT INVOCATION_COUNT->increment()
+-#define OSR_REQUEST(res, branch_pc) \
+-            CALL_VM(res=InterpreterRuntime::frequency_counter_overflow(THREAD, branch_pc), handle_exception);
+-/*
+- * For those opcodes that need to have a GC point on a backwards branch
+- */
+-
+-// Backedge counting is kind of strange. The asm interpreter will increment
+-// the backedge counter as a separate counter but it does it's comparisons
+-// to the sum (scaled) of invocation counter and backedge count to make
+-// a decision. Seems kind of odd to sum them together like that
+-
+-// skip is delta from current bcp/bci for target, branch_pc is pre-branch bcp
+-
+-
+-#define DO_BACKEDGE_CHECKS(skip, branch_pc)                                                         \
+-    if ((skip) <= 0) {                                                                              \
+-      if (UseCompiler && UseLoopCounter) {                                                          \
+-        bool do_OSR = UseOnStackReplacement;                                                        \
+-        BACKEDGE_COUNT->increment();                                                                \
+-        if (do_OSR) do_OSR = BACKEDGE_COUNT->reached_InvocationLimit();                             \
+-        if (do_OSR) {                                                                               \
+-          nmethod*  osr_nmethod;                                                                    \
+-          OSR_REQUEST(osr_nmethod, branch_pc);                                                      \
+-          if (osr_nmethod->osr_entry_bci() != InvalidOSREntryBci) {                                 \
+-            intptr_t* buf;                                                                          \
+-            CALL_VM(buf=SharedRuntime::OSR_migration_begin(THREAD), handle_exception);              \
+-            istate->set_msg(do_osr);                                                                \
+-            istate->set_osr_buf((address)buf);                                                      \
+-            istate->set_osr_entry(osr_nmethod->osr_entry());                                        \
+-            return;                                                                                 \
+-          }                                                                                         \
+-        } else {                                                                                    \
+-          INCR_INVOCATION_COUNT;                                                                    \
+-          SAFEPOINT;                                                                                \
+-        }                                                                                           \
+-      }  /* UseCompiler ... */                                                                      \
+-      INCR_INVOCATION_COUNT;                                                                        \
+-      SAFEPOINT;                                                                                    \
+-    }
+-
+-/*
+- * Macros for accessing the stack.
+- */
+-#undef STACK_INT
+-#undef STACK_FLOAT
+-#undef STACK_OBJECT
+-#undef STACK_DOUBLE
+-#undef STACK_LONG
+-// JavaStack Implementation
+-
+-#define STACK_SLOT(offset)       stack_slot(topOfStack, (offset))
+-#define STACK_INT(offset)        stack_int(topOfStack, (offset))
+-#define STACK_FLOAT(offset)      stack_float(topOfStack, (offset))
+-#define STACK_OBJECT(offset)     stack_object(topOfStack, (offset))
+-#define STACK_DOUBLE(offset)     stack_double(topOfStack, (offset))
+-#define STACK_LONG(offset)       stack_long(topOfStack, (offset))
+-
+-
+-#define SET_STACK_SLOT(value, offset)            \
+-        set_stack_slot(topOfStack, (value), (offset))
+-#define SET_STACK_INT(value, offset)             \
+-        set_stack_int(topOfStack, (value), (offset))
+-#define SET_STACK_FLOAT(value, offset)           \
+-        set_stack_float(topOfStack, (value), (offset))
+-#define SET_STACK_OBJECT(value, offset)          \
+-        set_stack_object(topOfStack, (value), (offset))
+-#define SET_STACK_DOUBLE(value, offset)          \
+-        set_stack_double(topOfStack, (value), (offset))
+-#define SET_STACK_DOUBLE_FROM_ADDR(addr, offset) \
+-        set_stack_double_from_addr(topOfStack, (addr), (offset))
+-#define SET_STACK_LONG(value, offset)            \
+-        set_stack_long(topOfStack, (value), (offset))
+-#define SET_STACK_LONG_FROM_ADDR(addr, offset)   \
+-        set_stack_long_from_addr(topOfStack, (addr), (offset))
+-
+-#define LOCALS_SLOT(offset)      locals_slot(locals, (offset))
+-#define LOCALS_INT(offset)       locals_int(locals,  (offset))
+-#define LOCALS_FLOAT(offset)     locals_float(locals, (offset))
+-#define LOCALS_OBJECT(offset)    locals_object(locals, (offset))
+-#define LOCALS_DOUBLE(offset)    locals_double(locals, (offset))
+-#define LOCALS_LONG(offset)      locals_long(locals, (offset))
+-#define LOCALS_LONG_AT(offset)   locals_long_at(locals, (offset))
+-#define LOCALS_DOUBLE_AT(offset) locals_double_at(locals, (offset))
+-
+-
+-#define SET_LOCALS_SLOT(value, offset)            \
+-        set_locals_slot(locals, (value), (offset))
+-#define SET_LOCALS_INT(value, offset)             \
+-        set_locals_int(locals, (value), (offset))
+-#define SET_LOCALS_FLOAT(value, offset)           \
+-        set_locals_float(locals, (value), (offset))
+-#define SET_LOCALS_OBJECT(value, offset)          \
+-        set_locals_object(locals, (value), (offset))
+-#define SET_LOCALS_DOUBLE(value, offset)          \
+-        set_locals_double(locals, (value), (offset))
+-#define SET_LOCALS_LONG(value, offset)            \
+-        set_locals_long(locals, (value), (offset))
+-#define SET_LOCALS_DOUBLE_FROM_ADDR(addr, offset) \
+-        set_locals_double_from_addr(locals, (addr), (offset))
+-#define SET_LOCALS_LONG_FROM_ADDR(addr, offset)   \
+-        set_locals_long_from_addr(locals, (addr), (offset))
+-
+-
+-/*
+- * Macros for caching and flushing the interpreter state. Some local
+- * variables need to be flushed out to the frame before we do certain
+- * things (like pushing frames or becomming gc safe) and some need to 
+- * be recached later (like after popping a frame). We could use one
+- * macro to cache or decache everything, but this would be less then
+- * optimal because we don't always need to cache or decache everything
+- * because some things we know are already cached or decached.
+- */
+-#undef DECACHE_TOS
+-#undef CACHE_TOS
+-#undef CACHE_PREV_TOS
+-#define DECACHE_TOS()    istate->set_stack(topOfStack);
+-
+-#define CACHE_TOS()      topOfStack = (intptr_t *)istate->stack();
+-
+-#undef DECACHE_PC
+-#undef CACHE_PC
+-#define DECACHE_PC()    istate->set_bcp(pc);
+-#define CACHE_PC()      pc = istate->bcp();
+-#define CACHE_CP()      cp = istate->constants();
+-#define CACHE_LOCALS()  locals = istate->locals();
+-#undef CACHE_FRAME
+-#define CACHE_FRAME()   
+- 
+-/*
+- * CHECK_NULL - Macro for throwing a NullPointerException if the object
+- * passed is a null ref.
+- * On some architectures/platforms it should be possible to do this implicitly
+- */
+-#undef CHECK_NULL
+-#define CHECK_NULL(obj_)                                                 \
+-    if ((obj_) == 0) {                                                   \
+-        VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), "");  \
+-    }
+-
+-#define VMdoubleConstZero() 0.0
+-#define VMdoubleConstOne() 1.0
+-#define VMlongConstZero() (max_jlong-max_jlong)
+-#define VMlongConstOne() ((max_jlong-max_jlong)+1)
+-
+-/*
+- * Alignment
+- */
+-/* #define VMalignWordUp(val)          (((juint)(val) + 3) & ~3) */
+-#define VMalignWordUp(val)          (((uintptr_t)(val) + 3) & ~3)
+-
+-// Decache the interpreter state that interpreter modifies directly (i.e. GC is indirect mod)
+-#define DECACHE_STATE() DECACHE_PC(); DECACHE_TOS();
+-
+-// Reload interpreter state after calling the VM or a possible GC
+-#define CACHE_STATE()   \
+-        CACHE_TOS();    \
+-        CACHE_PC();     \
+-        CACHE_CP();     \
+-        CACHE_LOCALS();
+-
+-// Call the VM don't check for pending exceptions
+-#define CALL_VM_NOCHECK(func)                                     \
+-          DECACHE_STATE();                                        \
+-          SET_LAST_JAVA_FRAME();                                  \
+-          func;                                                   \
+-          RESET_LAST_JAVA_FRAME();                                \
+-          CACHE_STATE();                                          \
+-          if (THREAD->pop_frame_pending() &&                      \
+-              !THREAD->pop_frame_in_process()) {                  \
+-            goto handle_Pop_Frame;                                \
+-          }
+-
+-// Call the VM and check for pending exceptions
+-#define CALL_VM(func, label) {                                    \
+-          CALL_VM_NOCHECK(func);                                  \
+-          if (THREAD->pending_exception()) goto label;            \
+-        }
+-
+-/*
+- * cInterpreter::InterpretMethod(interpreterState istate)
+- * cInterpreter::InterpretMethodWithChecks(interpreterState istate)
+- *
+- * The real deal. This is where byte codes actually get interpreted.
+- * Basically it's a big while loop that iterates until we return from
+- * the method passed in.
+- *
+- * The InterpretMethodWithChecks is used if JVMTI is enabled.
+- *
+- */
+-#if defined(VM_JVMTI)
+-void
+-cInterpreter::InterpretMethodWithChecks(interpreterState istate) {
+-#else
+-void
+-cInterpreter::InterpretMethod(interpreterState istate) {
+-#endif
+-
+-  // In order to simplify some tests based on switches set at runtime
+-  // we invoke the interpreter a single time after switches are enabled 
+-  // and set simpler to to test variables rather than method calls or complex
+-  // boolean expressions.
+-
+-  static int initialized = 0;
+-#ifdef VM_JVMTI
+-  static bool _jvmti_interp_events = 0;
+-#endif
+-
+-  static int _compiling;  // (UseCompiler || CountCompiledCalls)
+-
+-#ifdef ASSERT
+-  // Verify linkages.
+-  interpreterState l = istate;
+-  do {
+-    assert(l == l->_self_link, "bad link");
+-    l = l->_prev_link;
+-  } while (l != NULL);
+-  // Screwups with stack management usually cause us to overwrite istate
+-  // save a copy so we can verify it.
+-  interpreterState orig = istate;
+-#endif
+-
+-  static volatile jbyte* _byte_map_base; // adjusted card table base for oop store barrier
+-
+-  register intptr_t*        topOfStack = (intptr_t *)istate->stack(); /* access with STACK macros */
+-  register address          pc = istate->bcp();
+-  register jubyte opcode;
+-  register intptr_t*        locals = istate->locals();
+-  register constantPoolCacheOop  cp = istate->constants(); // method()->constants()->cache()
+-#ifdef LOTS_OF_REGS
+-  register JavaThread*      THREAD = istate->thread();
+-  register volatile jbyte*  BYTE_MAP_BASE = _byte_map_base;
+-#else
+-#undef THREAD
+-#define THREAD istate->thread()
+-#undef BYTE_MAP_BASE
+-#define BYTE_MAP_BASE _byte_map_base
+-#endif
+-
+-#ifdef USELABELS
+-  const static void* const opclabels_data[256] = { 
+-/* 0x00 */ &&opc_nop,     &&opc_aconst_null,&&opc_iconst_m1,&&opc_iconst_0,
+-/* 0x04 */ &&opc_iconst_1,&&opc_iconst_2,   &&opc_iconst_3, &&opc_iconst_4,
+-/* 0x08 */ &&opc_iconst_5,&&opc_lconst_0,   &&opc_lconst_1, &&opc_fconst_0,
+-/* 0x0C */ &&opc_fconst_1,&&opc_fconst_2,   &&opc_dconst_0, &&opc_dconst_1,
+-
+-/* 0x10 */ &&opc_bipush, &&opc_sipush, &&opc_ldc,    &&opc_ldc_w,
+-/* 0x14 */ &&opc_ldc2_w, &&opc_iload,  &&opc_lload,  &&opc_fload,
+-/* 0x18 */ &&opc_dload,  &&opc_aload,  &&opc_iload_0,&&opc_iload_1,
+-/* 0x1C */ &&opc_iload_2,&&opc_iload_3,&&opc_lload_0,&&opc_lload_1,
+-
+-/* 0x20 */ &&opc_lload_2,&&opc_lload_3,&&opc_fload_0,&&opc_fload_1,
+-/* 0x24 */ &&opc_fload_2,&&opc_fload_3,&&opc_dload_0,&&opc_dload_1,
+-/* 0x28 */ &&opc_dload_2,&&opc_dload_3,&&opc_aload_0,&&opc_aload_1,
+-/* 0x2C */ &&opc_aload_2,&&opc_aload_3,&&opc_iaload, &&opc_laload,
+-
+-/* 0x30 */ &&opc_faload,  &&opc_daload,  &&opc_aaload,  &&opc_baload,
+-/* 0x34 */ &&opc_caload,  &&opc_saload,  &&opc_istore,  &&opc_lstore,
+-/* 0x38 */ &&opc_fstore,  &&opc_dstore,  &&opc_astore,  &&opc_istore_0,
+-/* 0x3C */ &&opc_istore_1,&&opc_istore_2,&&opc_istore_3,&&opc_lstore_0,
+-
+-/* 0x40 */ &&opc_lstore_1,&&opc_lstore_2,&&opc_lstore_3,&&opc_fstore_0,
+-/* 0x44 */ &&opc_fstore_1,&&opc_fstore_2,&&opc_fstore_3,&&opc_dstore_0,
+-/* 0x48 */ &&opc_dstore_1,&&opc_dstore_2,&&opc_dstore_3,&&opc_astore_0,
+-/* 0x4C */ &&opc_astore_1,&&opc_astore_2,&&opc_astore_3,&&opc_iastore,
+-
+-/* 0x50 */ &&opc_lastore,&&opc_fastore,&&opc_dastore,&&opc_aastore,
+-/* 0x54 */ &&opc_bastore,&&opc_castore,&&opc_sastore,&&opc_pop,
+-/* 0x58 */ &&opc_pop2,   &&opc_dup,    &&opc_dup_x1, &&opc_dup_x2,
+-/* 0x5C */ &&opc_dup2,   &&opc_dup2_x1,&&opc_dup2_x2,&&opc_swap,
+-
+-/* 0x60 */ &&opc_iadd,&&opc_ladd,&&opc_fadd,&&opc_dadd,
+-/* 0x64 */ &&opc_isub,&&opc_lsub,&&opc_fsub,&&opc_dsub,
+-/* 0x68 */ &&opc_imul,&&opc_lmul,&&opc_fmul,&&opc_dmul,
+-/* 0x6C */ &&opc_idiv,&&opc_ldiv,&&opc_fdiv,&&opc_ddiv,
+-
+-/* 0x70 */ &&opc_irem, &&opc_lrem, &&opc_frem,&&opc_drem,
+-/* 0x74 */ &&opc_ineg, &&opc_lneg, &&opc_fneg,&&opc_dneg,
+-/* 0x78 */ &&opc_ishl, &&opc_lshl, &&opc_ishr,&&opc_lshr,
+-/* 0x7C */ &&opc_iushr,&&opc_lushr,&&opc_iand,&&opc_land,
+-
+-/* 0x80 */ &&opc_ior, &&opc_lor,&&opc_ixor,&&opc_lxor,
+-/* 0x84 */ &&opc_iinc,&&opc_i2l,&&opc_i2f, &&opc_i2d,
+-/* 0x88 */ &&opc_l2i, &&opc_l2f,&&opc_l2d, &&opc_f2i,
+-/* 0x8C */ &&opc_f2l, &&opc_f2d,&&opc_d2i, &&opc_d2l,
+-
+-/* 0x90 */ &&opc_d2f,  &&opc_i2b,  &&opc_i2c,  &&opc_i2s,
+-/* 0x94 */ &&opc_lcmp, &&opc_fcmpl,&&opc_fcmpg,&&opc_dcmpl,
+-/* 0x98 */ &&opc_dcmpg,&&opc_ifeq, &&opc_ifne, &&opc_iflt,
+-/* 0x9C */ &&opc_ifge, &&opc_ifgt, &&opc_ifle, &&opc_if_icmpeq,
+-
+-/* 0xA0 */ &&opc_if_icmpne,&&opc_if_icmplt,&&opc_if_icmpge,  &&opc_if_icmpgt,
+-/* 0xA4 */ &&opc_if_icmple,&&opc_if_acmpeq,&&opc_if_acmpne,  &&opc_goto,
+-/* 0xA8 */ &&opc_jsr,      &&opc_ret,      &&opc_tableswitch,&&opc_lookupswitch,
+-/* 0xAC */ &&opc_ireturn,  &&opc_lreturn,  &&opc_freturn,    &&opc_dreturn,
+-
+-/* 0xB0 */ &&opc_areturn,     &&opc_return,         &&opc_getstatic,    &&opc_putstatic,
+-/* 0xB4 */ &&opc_getfield,    &&opc_putfield,       &&opc_invokevirtual,&&opc_invokespecial,
+-/* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,NULL,               &&opc_new,
+-/* 0xBC */ &&opc_newarray,    &&opc_anewarray,      &&opc_arraylength,  &&opc_athrow,
+-
+-/* 0xC0 */ &&opc_checkcast,   &&opc_instanceof,     &&opc_monitorenter, &&opc_monitorexit,
+-/* 0xC4 */ &&opc_wide,        &&opc_multianewarray, &&opc_ifnull,       &&opc_ifnonnull,
+-/* 0xC8 */ &&opc_goto_w,      &&opc_jsr_w,          &&opc_breakpoint,   &&opc_fast_igetfield,
+-/* 0xCC */ &&opc_fastagetfield,&&opc_fast_aload_0,  &&opc_fast_iaccess_0, &&opc__fast_aaccess_0,
+-
+-/* 0xD0 */ &&opc_fast_linearswitch, &&opc_fast_binaryswitch, &&opc_return_register_finalizer,      &&opc_default,
+-/* 0xD4 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+-/* 0xD8 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+-/* 0xDC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+-
+-/* 0xE0 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+-/* 0xE4 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+-/* 0xE8 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+-/* 0xEC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+-
+-/* 0xF0 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+-/* 0xF4 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+-/* 0xF8 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
+-/* 0xFC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default
+-  };
+-  register uintptr_t *dispatch_table = (uintptr_t*)&opclabels_data[0];
+-#endif /* USELABELS */
+-
+-#ifdef ASSERT
+-  // this will trigger a VERIFY_OOP on entry
+-  if (istate->msg() != initialize && ! istate->method()->is_static()) {
+-    oop rcvr = LOCALS_OBJECT(0);
+-  }
+-#endif
+-
+-  /* QQQ this should be a stack method so we don't know actual direction */
+-  assert(istate->msg() == initialize ||
+-         topOfStack >= istate->stack_limit() &&
+-         topOfStack < istate->stack_base(), 
+-         "Stack top out of range");
+-
+-  switch (istate->msg()) {
+-    case initialize: {
+-      if (initialized++) ShouldNotReachHere(); // Only one initialize call
+-      _compiling = (UseCompiler || CountCompiledCalls);
+-#ifdef VM_JVMTI
+-      _jvmti_interp_events = JvmtiExport::can_post_interpreter_events();
+-#endif
+-      BarrierSet* bs = Universe::heap()->barrier_set();
+-      assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
+-      _byte_map_base = (volatile jbyte*)(((CardTableModRefBS*)bs)->byte_map_base);
+-      return;
+-    }
+-    break;
+-    case method_entry: {
+-      THREAD->set_do_not_unlock();
+-      // count invocations
+-      assert(initialized, "Interpreter not initialized");
+-      if (_compiling) {
+-        if (ProfileInterpreter) {
+-          istate->method()->increment_interpreter_invocation_count();
+-        }
+-        INCR_INVOCATION_COUNT;
+-        if (istate->method()->invocation_counter()->has_overflowed()) {
+-            CALL_VM((void)InterpreterRuntime::frequency_counter_overflow(THREAD, NULL), handle_exception);
+-
+-            // We no longer retry on a counter overflow
+-
+-            // istate->set_msg(retry_method);
+-            // THREAD->clr_do_not_unlock();
+-            // return;
+-        }
+-        SAFEPOINT;
+-      }
+-
+-#ifdef HACK
+-      {
+-        ResourceMark rm;
+-        char *method_name = istate->method()->name_and_sig_as_C_string();
+-        if (strstr(method_name, "SecurityManager$1") != NULL) os::breakpoint();
+-      }
+-#endif // HACK
+-
+-
+-      // lock method if synchronized
+-      if (istate->method()->is_synchronized()) {
+-          // oop rcvr = locals[0].j.r;
+-          oop rcvr;
+-          if (istate->method()->is_static()) {
+-            rcvr = istate->method()->constants()->pool_holder()->klass_part()->java_mirror();
+-          } else {
+-            rcvr = LOCALS_OBJECT(0);
+-          }
+-          // The initial monitor is ours for the taking
+-          BasicObjectLock* mon = &istate->monitor_base()[-1];
+-          oop monobj = mon->obj();
+-          assert(mon->obj() == rcvr, "method monitor mis-initialized");
+-
+-          markOop displaced = rcvr->mark()->set_unlocked();
+-          mon->lock()->set_displaced_header(displaced);
+-          if (Atomic::cmpxchg_ptr(mon, rcvr->mark_addr(), displaced) != displaced) {
+-            // Is it simple recursive case?
+-            if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
+-              mon->lock()->set_displaced_header(NULL);
+-            } else {
+-              CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
+-            }
+-          }
+-      }
+-      THREAD->clr_do_not_unlock();
+-
+-      // Notify jvmti
+-#ifdef VM_JVMTI
+-      if (_jvmti_interp_events) {
+-        // Whenever JVMTI puts a thread in interp_only_mode, method
+-        // entry/exit events are sent for that thread to track stack depth.  
+-        if (THREAD->is_interp_only_mode()) {
+-          CALL_VM(InterpreterRuntime::post_method_entry(THREAD), 
+-                  handle_exception);
+-        }
+-      }
+-#endif /* VM_JVMTI */
+-
+-      goto run;
+-    }
+-
+-    case popping_frame: {
+-      // returned from a java call to pop the frame, restart the call
+-      // clear the message so we don't confuse ourselves later
+-      assert(THREAD->pop_frame_in_process(), "wrong frame pop state");
+-      istate->set_msg(no_request);
+-      THREAD->clr_pop_frame_in_process();
+-      goto run;
+-    }
+-
+-    case method_resume: {
+-#ifdef HACK
+-      {
+-        ResourceMark rm;
+-        char *method_name = istate->method()->name_and_sig_as_C_string();
+-        if (strstr(method_name, "SecurityManager$1") != NULL) os::breakpoint();
+-      }
+-#endif // HACK
+-      // returned from a java call, continue executing.
+-      if (THREAD->pop_frame_pending() && !THREAD->pop_frame_in_process()) {
+-        goto handle_Pop_Frame;
+-      }
+- 
+-      if (THREAD->has_pending_exception()) goto handle_exception;
+-      // Update the pc by the saved amount of the invoke bytecode size
+-      UPDATE_PC(istate->bcp_advance());
+-      goto run;
+-    }
+-
+-    case deopt_resume2: {
+-      // Returned from an opcode that will reexecute. Deopt was
+-      // a result of a PopFrame request.
+-      //
+-      goto run;
+-    }
+-
+-    case deopt_resume: {
+-      // Returned from an opcode that has completed. The stack has
+-      // the result all we need to do is skip across the bytecode
+-      // and continue (assuming there is no exception pending)
+-      // 
+-      // compute continuation length
+-      //
+-      UPDATE_PC(Bytecodes::length_at(pc));
+-      if (THREAD->has_pending_exception()) goto handle_exception;
+-      goto run;
+-    }
+-    case got_monitors: {
+-      // continue locking now that we have a monitor to use
+-      // we expect to find newly allocated monitor at the "top" of the monitor stack.
+-      oop lockee = STACK_OBJECT(-1);
+-      // derefing's lockee ought to provoke implicit null check
+-      // find a free monitor
+-      BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base();
+-      assert(entry->obj() == NULL, "Frame manager didn't allocate the monitor");
+-      entry->set_obj(lockee);
+-
+-      markOop displaced = lockee->mark()->set_unlocked();
+-      entry->lock()->set_displaced_header(displaced);
+-      if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) {
+-        // Is it simple recursive case?
+-        if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
+-          entry->lock()->set_displaced_header(NULL);
+-        } else {
+-          CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
+-        }
+-      }
+-      UPDATE_PC_AND_TOS(1, -1);
+-      goto run;
+-    }
+-    default: {
+-      fatal("Unexpected message from frame manager");
+-    }
+-  }
+-
+-run:
+-
+-  DO_UPDATE_INSTRUCTION_COUNT(*pc)
+-  DEBUGGER_SINGLE_STEP_NOTIFY();
+-#ifdef PREFETCH_OPCCODE
+-  opcode = *pc;  /* prefetch first opcode */
+-#endif
+-
+-#ifndef USELABELS
+-  while (1)
+-#endif
+-  {
+-#ifndef PREFETCH_OPCCODE
+-      opcode = *pc;
+-#endif
+-      // Seems like this happens twice per opcode. At worst this is only
+-      // need at entry to the loop.
+-      // DEBUGGER_SINGLE_STEP_NOTIFY();
+-      /* Using this labels avoids double breakpoints when quickening and
+-       * when returing from transition frames.
+-       */
+-  opcode_switch:
+-      assert(istate == orig, "Corrupted istate");
+-      /* QQQ Hmm this has knowledge of direction, ought to be a stack method */
+-      assert(topOfStack >= istate->stack_limit(), "Stack overrun");
+-      assert(topOfStack < istate->stack_base(), "Stack underrun");
+-
+-#ifdef USELABELS
+-      DISPATCH(opcode);
+-#else
+-      switch (opcode)
+-#endif
+-      {
+-      CASE(_nop):
+-          UPDATE_PC_AND_CONTINUE(1);
+-
+-          /* Push miscellaneous constants onto the stack. */
+-
+-      CASE(_aconst_null):
+-          SET_STACK_OBJECT(NULL, 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-
+-#undef  OPC_CONST_n
+-#define OPC_CONST_n(opcode, const_type, value)                          \
+-      CASE(opcode):                                                     \
+-          SET_STACK_ ## const_type(value, 0);                           \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-
+-          OPC_CONST_n(_iconst_m1,   INT,       -1);
+-          OPC_CONST_n(_iconst_0,    INT,        0);
+-          OPC_CONST_n(_iconst_1,    INT,        1);
+-          OPC_CONST_n(_iconst_2,    INT,        2);
+-          OPC_CONST_n(_iconst_3,    INT,        3);
+-          OPC_CONST_n(_iconst_4,    INT,        4);
+-          OPC_CONST_n(_iconst_5,    INT,        5);
+-          OPC_CONST_n(_fconst_0,    FLOAT,      0.0);
+-          OPC_CONST_n(_fconst_1,    FLOAT,      1.0);
+-          OPC_CONST_n(_fconst_2,    FLOAT,      2.0);
+-
+-#if 0
+-#undef  OPC_CONST2_n
+-#define OPC_CONST2_n(opcname, value, key)                               \
+-      CASE(_##opcname):                                                 \
+-      {                                                                 \
+-         VM##key##2Jvm(&STACK_INFO(DTOS(0)).raw,                        \
+-             VM##key##Const##value());                                  \
+-         UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);                          \
+-      }
+-#endif
+-
+-#undef  OPC_CONST2_n
+-#define OPC_CONST2_n(opcname, value, key, kind)                         \
+-      CASE(_##opcname):                                                 \
+-      {                                                                 \
+-          SET_STACK_ ## kind(VM##key##Const##value(), 1);               \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);                         \
+-      }
+-         OPC_CONST2_n(dconst_0, Zero, double, DOUBLE);
+-         OPC_CONST2_n(dconst_1, One,  double, DOUBLE);
+-         OPC_CONST2_n(lconst_0, Zero, long, LONG);
+-         OPC_CONST2_n(lconst_1, One,  long, LONG);
+-
+-         /* Load constant from constant pool: */
+-
+-          /* Push a 1-byte signed integer value onto the stack. */
+-      CASE(_bipush):
+-          SET_STACK_INT((jbyte)(pc[1]), 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1);
+-
+-          /* Push a 2-byte signed integer constant onto the stack. */
+-      CASE(_sipush):
+-          SET_STACK_INT((int16_t)Bytes::get_Java_u2(pc + 1), 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);
+-
+-          /* load from local variable */
+-
+-      CASE(_aload):
+-          SET_STACK_OBJECT(LOCALS_OBJECT(pc[1]), 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1);
+-
+-      CASE(_iload):
+-      CASE(_fload):
+-          SET_STACK_SLOT(LOCALS_SLOT(pc[1]), 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1);
+-
+-      CASE(_lload):
+-          SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(pc[1]), 1);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(2, 2);
+-
+-      CASE(_dload):
+-          SET_STACK_DOUBLE_FROM_ADDR(LOCALS_DOUBLE_AT(pc[1]), 1);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(2, 2);
+-
+-#undef  OPC_LOAD_n
+-#define OPC_LOAD_n(num)                                                 \
+-      CASE(_aload_##num):                                               \
+-          SET_STACK_OBJECT(LOCALS_OBJECT(num), 0);                      \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);                         \
+-                                                                        \
+-      CASE(_iload_##num):                                               \
+-      CASE(_fload_##num):                                               \
+-          SET_STACK_SLOT(LOCALS_SLOT(num), 0);                          \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);                         \
+-                                                                        \
+-      CASE(_lload_##num):                                               \
+-          SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(num), 1);             \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);                         \
+-      CASE(_dload_##num):                                               \
+-          SET_STACK_DOUBLE_FROM_ADDR(LOCALS_DOUBLE_AT(num), 1);         \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
+-
+-          OPC_LOAD_n(0);
+-          OPC_LOAD_n(1);
+-          OPC_LOAD_n(2);
+-          OPC_LOAD_n(3);
+-
+-          /* store to a local variable */
+-
+-      CASE(_astore):
+-          astore(topOfStack, -1, locals, pc[1]);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(2, -1);
+-
+-      CASE(_istore):
+-      CASE(_fstore):
+-          SET_LOCALS_SLOT(STACK_SLOT(-1), pc[1]);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(2, -1);
+-
+-      CASE(_lstore):
+-          SET_LOCALS_LONG(STACK_LONG(-1), pc[1]);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(2, -2);
+-
+-      CASE(_dstore):
+-          SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), pc[1]);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(2, -2);
+-
+-      CASE(_wide): {
+-          uint16_t reg = Bytes::get_Java_u2(pc + 2);
+-
+-          opcode = pc[1];
+-          switch(opcode) {
+-              case Bytecodes::_aload:
+-                  SET_STACK_OBJECT(LOCALS_OBJECT(reg), 0); 
+-                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1);
+-
+-              case Bytecodes::_iload:
+-              case Bytecodes::_fload:
+-                  SET_STACK_SLOT(LOCALS_SLOT(reg), 0); 
+-                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1);
+-
+-              case Bytecodes::_lload:
+-                  SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(reg), 1);
+-                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, 2);
+-
+-              case Bytecodes::_dload:
+-                  SET_STACK_DOUBLE_FROM_ADDR(LOCALS_LONG_AT(reg), 1);
+-                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, 2);
+-
+-              case Bytecodes::_astore:
+-                  astore(topOfStack, -1, locals, reg);
+-                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, -1);
+-
+-              case Bytecodes::_istore:
+-              case Bytecodes::_fstore:
+-                  SET_LOCALS_SLOT(STACK_SLOT(-1), reg);
+-                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, -1);
+-
+-              case Bytecodes::_lstore:
+-                  SET_LOCALS_LONG(STACK_LONG(-1), reg);
+-                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, -2);
+-
+-              case Bytecodes::_dstore:
+-                  SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), reg);
+-                  UPDATE_PC_AND_TOS_AND_CONTINUE(4, -2);
+-
+-              case Bytecodes::_iinc: {
+-                  int16_t offset = (int16_t)Bytes::get_Java_u2(pc+4); 
+-                  // Be nice to see what this generates.... QQQ
+-                  SET_LOCALS_INT(LOCALS_INT(reg) + offset, reg);
+-                  UPDATE_PC_AND_CONTINUE(6);
+-              }
+-              case Bytecodes::_ret:
+-                  pc = istate->method()->code_base() + (intptr_t)(LOCALS_SLOT(reg));
+-                  UPDATE_PC_AND_CONTINUE(0);
+-              default:
+-                  VM_JAVA_ERROR(vmSymbols::java_lang_InternalError(), "undefined opcode");
+-          }
+-      }
+-
+-
+-#undef  OPC_STORE_n
+-#define OPC_STORE_n(num)                                                \
+-      CASE(_astore_##num):                                              \
+-          astore(topOfStack, -1, locals, num);                          \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                        \
+-      CASE(_istore_##num):                                              \
+-      CASE(_fstore_##num):                                              \
+-          SET_LOCALS_SLOT(STACK_SLOT(-1), num);                         \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
+-
+-          OPC_STORE_n(0);
+-          OPC_STORE_n(1);
+-          OPC_STORE_n(2);
+-          OPC_STORE_n(3);
+-
+-#undef  OPC_DSTORE_n
+-#define OPC_DSTORE_n(num)                                               \
+-      CASE(_dstore_##num):                                              \
+-          SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), num);                     \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);                        \
+-      CASE(_lstore_##num):                                              \
+-          SET_LOCALS_LONG(STACK_LONG(-1), num);                         \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);
+-
+-          OPC_DSTORE_n(0);
+-          OPC_DSTORE_n(1);
+-          OPC_DSTORE_n(2);
+-          OPC_DSTORE_n(3);
+-
+-          /* stack pop, dup, and insert opcodes */
+-
+-         
+-      CASE(_pop):                /* Discard the top item on the stack */
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
+-
+-         
+-      CASE(_pop2):               /* Discard the top 2 items on the stack */
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);
+-
+-          
+-      CASE(_dup):               /* Duplicate the top item on the stack */
+-          dup(topOfStack);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-
+-      CASE(_dup2):              /* Duplicate the top 2 items on the stack */
+-          dup2(topOfStack);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
+-
+-      CASE(_dup_x1):    /* insert top word two down */
+-          dup_x1(topOfStack);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-
+-      CASE(_dup_x2):    /* insert top word three down  */
+-          dup_x2(topOfStack);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-
+-      CASE(_dup2_x1):   /* insert top 2 slots three down */
+-          dup2_x1(topOfStack);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
+-
+-      CASE(_dup2_x2):   /* insert top 2 slots four down */
+-          dup2_x2(topOfStack);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
+-
+-      CASE(_swap): {        /* swap top two elements on the stack */
+-          swap(topOfStack);
+-          UPDATE_PC_AND_CONTINUE(1);
+-      }
+-
+-          /* Perform various binary integer operations */
+-
+-#undef  OPC_INT_BINARY 
+-#define OPC_INT_BINARY(opcname, opname, test)                           \
+-      CASE(_i##opcname):                                                \
+-          if (test && (STACK_INT(-1) == 0)) {                           \
+-              VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \
+-                            "/ by int zero");                           \
+-          }                                                             \
+-          SET_STACK_INT(VMint##opname(STACK_INT(-2),                    \
+-                                      STACK_INT(-1)),                   \
+-                                      -2);                              \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                        \
+-      CASE(_l##opcname):                                                \
+-      {                                                                 \
+-          if (test) {                                                   \
+-            jlong l1 = STACK_LONG(-1);                                  \
+-            if (VMlongEqz(l1)) {                                        \
+-              VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \
+-                            "/ by long zero");                          \
+-            }                                                           \
+-          }                                                             \
+-          /* First long at (-1,-2) next long at (-3,-4) */              \
+-          SET_STACK_LONG(VMlong##opname(STACK_LONG(-3),                 \
+-                                        STACK_LONG(-1)),                \
+-                                        -3);                            \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);                        \
+-      }
+-
+-      OPC_INT_BINARY(add, Add, 0);
+-      OPC_INT_BINARY(sub, Sub, 0);
+-      OPC_INT_BINARY(mul, Mul, 0);
+-      OPC_INT_BINARY(and, And, 0);
+-      OPC_INT_BINARY(or,  Or,  0);
+-      OPC_INT_BINARY(xor, Xor, 0);
+-      OPC_INT_BINARY(div, Div, 1);
+-      OPC_INT_BINARY(rem, Rem, 1);
+-
+-
+-      /* Perform various binary floating number operations */
+-      /* On some machine/platforms/compilers div zero check can be implicit */
+-
+-#undef  OPC_FLOAT_BINARY 
+-#define OPC_FLOAT_BINARY(opcname, opname)                                  \
+-      CASE(_d##opcname): {                                                 \
+-          SET_STACK_DOUBLE(VMdouble##opname(STACK_DOUBLE(-3),              \
+-                                            STACK_DOUBLE(-1)),             \
+-                                            -3);                           \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);                           \
+-      }                                                                    \
+-      CASE(_f##opcname):                                                   \
+-          SET_STACK_FLOAT(VMfloat##opname(STACK_FLOAT(-2),                 \
+-                                          STACK_FLOAT(-1)),                \
+-                                          -2);                             \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
+-
+-
+-     OPC_FLOAT_BINARY(add, Add);
+-     OPC_FLOAT_BINARY(sub, Sub);
+-     OPC_FLOAT_BINARY(mul, Mul);
+-     OPC_FLOAT_BINARY(div, Div);
+-     OPC_FLOAT_BINARY(rem, Rem);
+-
+-      /* Shift operations                                  
+-       * Shift left int and long: ishl, lshl           
+-       * Logical shift right int and long w/zero extension: iushr, lushr
+-       * Arithmetic shift right int and long w/sign extension: ishr, lshr
+-       */
+-
+-#undef  OPC_SHIFT_BINARY
+-#define OPC_SHIFT_BINARY(opcname, opname)                               \
+-      CASE(_i##opcname):                                                \
+-         SET_STACK_INT(VMint##opname(STACK_INT(-2),                     \
+-                                     STACK_INT(-1)),                    \
+-                                     -2);                               \
+-         UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                         \
+-      CASE(_l##opcname):                                                \
+-      {                                                                 \
+-         SET_STACK_LONG(VMlong##opname(STACK_LONG(-2),                  \
+-                                       STACK_INT(-1)),                  \
+-                                       -2);                             \
+-         UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                         \
+-      }
+-    
+-      OPC_SHIFT_BINARY(shl, Shl);
+-      OPC_SHIFT_BINARY(shr, Shr);
+-      OPC_SHIFT_BINARY(ushr, Ushr);
+-
+-     /* Increment local variable by constant */ 
+-      CASE(_iinc): 
+-      {
+-          // locals[pc[1]].j.i += (jbyte)(pc[2]);
+-          SET_LOCALS_INT(LOCALS_INT(pc[1]) + (jbyte)(pc[2]), pc[1]);
+-          UPDATE_PC_AND_CONTINUE(3);
+-      }
+-
+-     /* negate the value on the top of the stack */
+-
+-      CASE(_ineg):
+-         SET_STACK_INT(VMintNeg(STACK_INT(-1)), -1); 
+-         UPDATE_PC_AND_CONTINUE(1);
+-
+-      CASE(_fneg):
+-         SET_STACK_FLOAT(VMfloatNeg(STACK_FLOAT(-1)), -1); 
+-         UPDATE_PC_AND_CONTINUE(1);
+-
+-      CASE(_lneg):
+-      {
+-         SET_STACK_LONG(VMlongNeg(STACK_LONG(-1)), -1); 
+-         UPDATE_PC_AND_CONTINUE(1);
+-      }
+-
+-      CASE(_dneg):
+-      {
+-         SET_STACK_DOUBLE(VMdoubleNeg(STACK_DOUBLE(-1)), -1); 
+-         UPDATE_PC_AND_CONTINUE(1);
+-      }
+-
+-      /* Conversion operations */
+-
+-      CASE(_i2f):       /* convert top of stack int to float */
+-         SET_STACK_FLOAT(VMint2Float(STACK_INT(-1)), -1);
+-         UPDATE_PC_AND_CONTINUE(1);
+-
+-      CASE(_i2l):       /* convert top of stack int to long */
+-      {
+-          // this is ugly QQQ
+-          jlong r = VMint2Long(STACK_INT(-1));
+-          MORE_STACK(-1); // Pop
+-          SET_STACK_LONG(r, 1);
+-
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
+-      }
+-
+-      CASE(_i2d):       /* convert top of stack int to double */
+-      {
+-          // this is ugly QQQ (why cast to jlong?? )
+-          jdouble r = (jlong)STACK_INT(-1);
+-          MORE_STACK(-1); // Pop
+-          SET_STACK_DOUBLE(r, 1);
+-
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
+-      }
+-
+-      CASE(_l2i):       /* convert top of stack long to int */
+-      {
+-          jint r = VMlong2Int(STACK_LONG(-1));
+-          MORE_STACK(-2); // Pop
+-          SET_STACK_INT(r, 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-      }
+-      
+-      CASE(_l2f):   /* convert top of stack long to float */
+-      {
+-          jlong r = STACK_LONG(-1);
+-          MORE_STACK(-2); // Pop
+-          SET_STACK_FLOAT(VMlong2Float(r), 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-      }
+-
+-      CASE(_l2d):       /* convert top of stack long to double */
+-      {
+-          jlong r = STACK_LONG(-1);
+-          MORE_STACK(-2); // Pop
+-          SET_STACK_DOUBLE(VMlong2Double(r), 1);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
+-      }
+-
+-      CASE(_f2i):  /* Convert top of stack float to int */
+-          SET_STACK_INT(SharedRuntime::f2i(STACK_FLOAT(-1)), -1); 
+-          UPDATE_PC_AND_CONTINUE(1);
+-
+-      CASE(_f2l):  /* convert top of stack float to long */
+-      {
+-          jlong r = SharedRuntime::f2l(STACK_FLOAT(-1));
+-          MORE_STACK(-1); // POP
+-          SET_STACK_LONG(r, 1);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
+-      }
+-
+-      CASE(_f2d):  /* convert top of stack float to double */
+-      {
+-          jfloat f;
+-          jdouble r;
+-          f = STACK_FLOAT(-1);
+-#ifdef IA64
+-          // IA64 gcc bug
+-          r = ( f == 0.0f ) ? (jdouble) f : (jdouble) f + ia64_double_zero;
+-#else
+-          r = (jdouble) f;
+-#endif
+-          MORE_STACK(-1); // POP
+-          SET_STACK_DOUBLE(r, 1);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
+-      }
+-
+-      CASE(_d2i): /* convert top of stack double to int */
+-      {
+-          jint r1 = SharedRuntime::d2i(STACK_DOUBLE(-1));
+-          MORE_STACK(-2);
+-          SET_STACK_INT(r1, 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-      }
+-
+-      CASE(_d2f): /* convert top of stack double to float */
+-      {
+-          jfloat r1 = VMdouble2Float(STACK_DOUBLE(-1));
+-          MORE_STACK(-2);
+-          SET_STACK_FLOAT(r1, 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-      }
+-
+-      CASE(_d2l): /* convert top of stack double to long */
+-      {
+-          jlong r1 = SharedRuntime::d2l(STACK_DOUBLE(-1));
+-          MORE_STACK(-2);
+-          SET_STACK_LONG(r1, 1);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);
+-      }
+-
+-      CASE(_i2b):
+-          SET_STACK_INT(VMint2Byte(STACK_INT(-1)), -1);
+-          UPDATE_PC_AND_CONTINUE(1);
+-
+-      CASE(_i2c):
+-          SET_STACK_INT(VMint2Char(STACK_INT(-1)), -1);
+-          UPDATE_PC_AND_CONTINUE(1);
+-
+-      CASE(_i2s):
+-          SET_STACK_INT(VMint2Short(STACK_INT(-1)), -1);
+-          UPDATE_PC_AND_CONTINUE(1);
+-
+-      /* comparison operators */
+-
+-
+-#define COMPARISON_OP(name, comparison)                                      \
+-      CASE(_if_icmp##name): {                                                \
+-          int skip = (STACK_INT(-2) comparison STACK_INT(-1))                \
+-                      ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;             \
+-          address branch_pc = pc;                                            \
+-          UPDATE_PC_AND_TOS(skip, -2);                                       \
+-          DO_BACKEDGE_CHECKS(skip, branch_pc);                               \
+-          CONTINUE;                                                          \
+-      }                                                                      \
+-      CASE(_if##name): {                                                     \
+-          int skip = (STACK_INT(-1) comparison 0)                            \
+-                      ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;             \
+-          address branch_pc = pc;                                            \
+-          UPDATE_PC_AND_TOS(skip, -1);                                       \
+-          DO_BACKEDGE_CHECKS(skip, branch_pc);                               \
+-          CONTINUE;                                                          \
+-      }
+-
+-#define COMPARISON_OP2(name, comparison)                                     \
+-      COMPARISON_OP(name, comparison)                                        \
+-      CASE(_if_acmp##name): {                                                \
+-          int skip = (STACK_OBJECT(-2) comparison STACK_OBJECT(-1))          \
+-                       ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;            \
+-          address branch_pc = pc;                                            \
+-          UPDATE_PC_AND_TOS(skip, -2);                                       \
+-          DO_BACKEDGE_CHECKS(skip, branch_pc);                               \
+-          CONTINUE;                                                          \
+-      }
+-
+-#define NULL_COMPARISON_NOT_OP(name)                                         \
+-      CASE(_if##name): {                                                     \
+-          int skip = (!(STACK_OBJECT(-1) == 0))                              \
+-                      ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;             \
+-          address branch_pc = pc;                                            \
+-          UPDATE_PC_AND_TOS(skip, -1);                                       \
+-          DO_BACKEDGE_CHECKS(skip, branch_pc);                               \
+-          CONTINUE;                                                          \
+-      }
+-
+-#define NULL_COMPARISON_OP(name)                                             \
+-      CASE(_if##name): {                                                     \
+-          int skip = ((STACK_OBJECT(-1) == 0))                               \
+-                      ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;             \
+-          address branch_pc = pc;                                            \
+-          UPDATE_PC_AND_TOS(skip, -1);                                       \
+-          DO_BACKEDGE_CHECKS(skip, branch_pc);                               \
+-          CONTINUE;                                                          \
+-      }
+-      COMPARISON_OP(lt, <);
+-      COMPARISON_OP(gt, >);
+-      COMPARISON_OP(le, <=);
+-      COMPARISON_OP(ge, >=);
+-      COMPARISON_OP2(eq, ==);  /* include ref comparison */
+-      COMPARISON_OP2(ne, !=);  /* include ref comparison */
+-      NULL_COMPARISON_OP(null);
+-      NULL_COMPARISON_NOT_OP(nonnull);
+-
+-      /* Goto pc at specified offset in switch table. */
+-
+-      CASE(_tableswitch): {
+-          jint* lpc  = (jint*)VMalignWordUp(pc+1);
+-          int32_t  key  = STACK_INT(-1);
+-          int32_t  low  = Bytes::get_Java_u4((address)&lpc[1]);
+-          int32_t  high = Bytes::get_Java_u4((address)&lpc[2]);
+-          int32_t  skip;
+-          key -= low;
+-          skip = ((uint32_t) key > (uint32_t)(high - low))
+-                      ? Bytes::get_Java_u4((address)&lpc[0])
+-                      : Bytes::get_Java_u4((address)&lpc[key + 3]);
+-          // Does this really need a full backedge check (osr?)
+-          address branch_pc = pc;
+-          UPDATE_PC_AND_TOS(skip, -1);
+-          DO_BACKEDGE_CHECKS(skip, branch_pc);
+-          CONTINUE;
+-      }
+-
+-      /* Goto pc whose table entry matches specified key */
+-
+-      CASE(_lookupswitch): {
+-          jint* lpc  = (jint*)VMalignWordUp(pc+1);
+-          int32_t  key  = STACK_INT(-1);
+-          int32_t  skip = Bytes::get_Java_u4((address) lpc); /* default amount */
+-          int32_t  npairs = Bytes::get_Java_u4((address) &lpc[1]);
+-          while (--npairs >= 0) {
+-              lpc += 2;
+-              if (key == (int32_t)Bytes::get_Java_u4((address)lpc)) {
+-                  skip = Bytes::get_Java_u4((address)&lpc[1]);
+-                  break;
+-              }
+-          }
+-          address branch_pc = pc;
+-          UPDATE_PC_AND_TOS(skip, -1);
+-          DO_BACKEDGE_CHECKS(skip, branch_pc);
+-          CONTINUE;
+-      }
+-
+-      CASE(_fcmpl):
+-      CASE(_fcmpg):
+-      {
+-          SET_STACK_INT(VMfloatCompare(STACK_FLOAT(-2), 
+-                                        STACK_FLOAT(-1), 
+-                                        (opcode == Bytecodes::_fcmpl ? -1 : 1)),
+-                        -2);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
+-      }
+-
+-      CASE(_dcmpl):
+-      CASE(_dcmpg):
+-      {
+-          int r = VMdoubleCompare(STACK_DOUBLE(-3),
+-                                  STACK_DOUBLE(-1),
+-                                  (opcode == Bytecodes::_dcmpl ? -1 : 1));
+-          MORE_STACK(-4); // Pop 
+-          SET_STACK_INT(r, 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-      }
+-
+-      CASE(_lcmp):
+-      {
+-          int r = VMlongCompare(STACK_LONG(-3), STACK_LONG(-1));
+-          MORE_STACK(-4);
+-          SET_STACK_INT(r, 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
+-      }
+-
+-
+-      /* Return from a method */
+-
+-      CASE(_areturn):
+-      CASE(_ireturn):
+-      CASE(_freturn):
+-      {
+-          // Allow a safepoint before returning to frame manager.
+-          SAFEPOINT;
+-
+-          goto handle_return;
+-      }
+-
+-      CASE(_lreturn):
+-      CASE(_dreturn):
+-      {
+-          // Allow a safepoint before returning to frame manager.
+-          SAFEPOINT;
+-          goto handle_return;
+-      }
+-
+-      CASE(_return_register_finalizer): {
+-
+-          oop rcvr = LOCALS_OBJECT(0);
+-          if (rcvr->klass()->klass_part()->has_finalizer()) {
+-            CALL_VM(InterpreterRuntime::register_finalizer(THREAD, rcvr), handle_exception);
+-          }
+-          goto handle_return;
+-      }
+-      CASE(_return): {
+-
+-          // Allow a safepoint before returning to frame manager.
+-          SAFEPOINT;
+-          goto handle_return;
+-      }
+-
+-      /* Array access byte-codes */
+-
+-      /* Every array access byte-code starts out like this */
+-#define ARRAY_INTRO(arrayOff)                                                  \
+-      arrayOopDesc* arrObj = (arrayOopDesc*)STACK_OBJECT(arrayOff);            \
+-      jint     index  = STACK_INT(arrayOff + 1);                               \
+-      char message[jintAsStringSize];                                          \
+-      CHECK_NULL(arrObj);                                                      \
+-      if ((uint32_t)index >= (uint32_t)arrObj->length()) {                     \
+-          sprintf(message, "%d", index);                                       \
+-          VM_JAVA_ERROR(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), \
+-                        message);                                              \
+-      }                                                 
+-
+-      /* 32-bit loads. These handle conversion from < 32-bit types */
+-#define ARRAY_LOADTO32(T, T2, format, stackRes, extra)                                \
+-      {                                                                               \
+-          ARRAY_INTRO(-2);                                                            \
+-          extra;                                                                      \
+-          SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), \
+-                           -2);                                                       \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                                      \
+-      }
+-
+-      /* 64-bit loads */
+-#define ARRAY_LOADTO64(T,T2, stackRes, extra)                                              \
+-      {                                                                                    \
+-          ARRAY_INTRO(-2);                                                                 \
+-          SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), -1); \
+-          extra;                                                                           \
+-          UPDATE_PC_AND_CONTINUE(1);                                            \
+-      }
+-
+-      CASE(_iaload):
+-          ARRAY_LOADTO32(T_INT, jint,   "%d",   STACK_INT, 0);
+-      CASE(_faload):
+-          ARRAY_LOADTO32(T_FLOAT, jfloat, "%f",   STACK_FLOAT, 0);
+-      CASE(_aaload):
+-          ARRAY_LOADTO32(T_OBJECT, oop,   INTPTR_FORMAT, STACK_OBJECT, 0);
+-      CASE(_baload):
+-          ARRAY_LOADTO32(T_BYTE, jbyte,  "%d",   STACK_INT, 0);
+-      CASE(_caload):
+-          ARRAY_LOADTO32(T_CHAR,  jchar, "%d",   STACK_INT, 0);
+-      CASE(_saload):
+-          ARRAY_LOADTO32(T_SHORT, jshort, "%d",   STACK_INT, 0);
+-      CASE(_laload):
+-          ARRAY_LOADTO64(T_LONG, jlong, STACK_LONG, 0);
+-      CASE(_daload):
+-          ARRAY_LOADTO64(T_DOUBLE, jdouble, STACK_DOUBLE, 0);
+-
+-      /* 32-bit stores. These handle conversion to < 32-bit types */
+-#define ARRAY_STOREFROM32(T, T2, format, stackSrc, extra)                            \
+-      {                                                                              \
+-          ARRAY_INTRO(-3);                                                           \
+-          extra;                                                                     \
+-          *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3);                                     \
+-      }
+-
+-      /* 64-bit stores */
+-#define ARRAY_STOREFROM64(T, T2, stackSrc, extra)                                    \
+-      {                                                                              \
+-          ARRAY_INTRO(-4);                                                           \
+-          extra;                                                                     \
+-          *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -4);                                     \
+-      }
+-
+-      CASE(_iastore):
+-          ARRAY_STOREFROM32(T_INT, jint,   "%d",   STACK_INT, 0);
+-      CASE(_fastore):
+-          ARRAY_STOREFROM32(T_FLOAT, jfloat, "%f",   STACK_FLOAT, 0);
+-      /*
+-       * This one looks different because of the assignability check
+-       */
+-      CASE(_aastore): {
+-          oop rhsObject = STACK_OBJECT(-1);
+-          ARRAY_INTRO( -3);
+-          // arrObj, index are set
+-          if (rhsObject != NULL) {
+-            /* Check assignability of rhsObject into arrObj */
+-            klassOop rhsKlassOop = rhsObject->klass(); // EBX (subclass)
+-            assert(arrObj->klass()->klass()->klass_part()->oop_is_objArrayKlass(), "Ack not an objArrayKlass");
+-            klassOop elemKlassOop = ((objArrayKlass*) arrObj->klass()->klass_part())->element_klass(); // superklass EAX
+-            //
+-            // Check for compatibilty. This check must not GC!!
+-            // Seems way more expensive now that we must dispatch
+-            //
+-            if (rhsKlassOop != elemKlassOop && !rhsKlassOop->klass_part()->is_subtype_of(elemKlassOop)) { // ebx->is...
+-              VM_JAVA_ERROR(vmSymbols::java_lang_ArrayStoreException(), "");
+-            }
+-          }
+-          oop* elem_loc = (oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop));
+-          // *(oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop)) = rhsObject;
+-          *elem_loc = rhsObject;
+-          // Mark the card
+-          OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)elem_loc >> CardTableModRefBS::card_shift], 0);
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3);
+-      }
+-      CASE(_bastore):
+-          ARRAY_STOREFROM32(T_BYTE, jbyte,  "%d",   STACK_INT, 0);
+-      CASE(_castore):
+-          ARRAY_STOREFROM32(T_CHAR, jchar,  "%d",   STACK_INT, 0);
+-      CASE(_sastore):
+-          ARRAY_STOREFROM32(T_SHORT, jshort, "%d",   STACK_INT, 0);
+-      CASE(_lastore):
+-          ARRAY_STOREFROM64(T_LONG, jlong, STACK_LONG, 0);
+-      CASE(_dastore):
+-          ARRAY_STOREFROM64(T_DOUBLE, jdouble, STACK_DOUBLE, 0);
+-
+-      CASE(_arraylength):
+-      {
+-          arrayOopDesc *ary = (arrayOopDesc *) STACK_OBJECT(-1);
+-          CHECK_NULL(ary);
+-          SET_STACK_INT(ary->length(), -1);
+-          UPDATE_PC_AND_CONTINUE(1);
+-      }
+-
+-      /* monitorenter and monitorexit for locking/unlocking an object */
+-
+-      CASE(_monitorenter): {
+-        oop lockee = STACK_OBJECT(-1);
+-        // derefing's lockee ought to provoke implicit null check
+-        CHECK_NULL(lockee);
+-        // find a free monitor or one already allocated for this object
+-        // if we find a matching object then we need a new monitor
+-        // since this is recursive enter
+-        BasicObjectLock* limit = istate->monitor_base();
+-        BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base();
+-        BasicObjectLock* entry = NULL;
+-        while (most_recent != limit ) {
+-          if (most_recent->obj() == NULL) entry = most_recent;
+-          else if (most_recent->obj() == lockee) break;
+-          most_recent++;
+-        }
+-        if (entry != NULL) {
+-          entry->set_obj(lockee);
+-          markOop displaced = lockee->mark()->set_unlocked();
+-          entry->lock()->set_displaced_header(displaced);
+-          if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) {
+-            // Is it simple recursive case?
+-            if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
+-              entry->lock()->set_displaced_header(NULL);
+-            } else {
+-              CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
+-            }
+-          }
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
+-        } else {
+-          istate->set_msg(more_monitors);
+-          // HACK FIX LATER
+-          // Why was this needed? Seems to be useless now
+-          // istate->set_callee((methodOop) lockee);
+-          UPDATE_PC_AND_RETURN(0); // Re-execute
+-        }
+-      }
+-
+-      CASE(_monitorexit): {
+-        oop lockee = STACK_OBJECT(-1);
+-        CHECK_NULL(lockee);
+-        // derefing's lockee ought to provoke implicit null check
+-        // find our monitor slot
+-        BasicObjectLock* limit = istate->monitor_base();
+-        BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base();
+-        while (most_recent != limit ) {
+-          if ((most_recent)->obj() == lockee) {
+-            BasicLock* lock = most_recent->lock();
+-            markOop header = lock->displaced_header();
+-            most_recent->set_obj(NULL);
+-            // If it isn't recursive we either must swap old header or call the runtime
+-            if (header != NULL) {
+-              if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) {
+-                // restore object for the slow case
+-                most_recent->set_obj(lockee);
+-                CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception);
+-              }
+-            }
+-            UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
+-          }
+-          most_recent++;
+-        }
+-        // Need to throw illegal monitor state exception
+-        CALL_VM(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD), handle_exception);
+-        // Should never reach here...
+-        assert(false, "Should have thrown illegal monitor exception");
+-      }
+-
+-      /* All of the non-quick opcodes. */
+-
+-      /* -Set clobbersCpIndex true if the quickened opcode clobbers the
+-       *  constant pool index in the instruction.
+-       */
+-      CASE(_getfield):
+-      CASE(_getstatic):
+-        {
+-          u2 index;
+-          ConstantPoolCacheEntry* cache;
+-          index = Bytes::get_native_u2(pc+1);
+-
+-          // QQQ Need to make this as inlined as possible. Probably need to 
+-          // split all the bytecode cases out so c++ compiler has a chance 
+-          // for constant prop to fold everything possible away.
+-
+-          cache = cp->entry_at(index);
+-          if (!cache->is_resolved((Bytecodes::Code)opcode)) {
+-            CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode), 
+-                    handle_exception);
+-            cache = cp->entry_at(index);
+-          }
+-
+-#ifdef VM_JVMTI
+-          if (_jvmti_interp_events) {
+-            int *count_addr;
+-            oop obj;
+-            // Check to see if a field modification watch has been set 
+-            // before we take the time to call into the VM.
+-            count_addr = (int *)JvmtiExport::get_field_access_count_addr();
+-            if ( *count_addr > 0 ) {
+-              if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) {
+-                obj = (oop)NULL;
+-              } else {
+-                obj = (oop) STACK_OBJECT(-1);
+-              }
+-              CALL_VM(InterpreterRuntime::post_field_access(THREAD, 
+-                                          obj, 
+-                                          cache),
+-                                          handle_exception);
+-            }
+-          }
+-#endif /* VM_JVMTI */
+-
+-          oop obj;
+-          if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) {
+-            obj = (oop) cache->f1();
+-            MORE_STACK(1);  // Assume single slot push
+-          } else {
+-            obj = (oop) STACK_OBJECT(-1);
+-            CHECK_NULL(obj);
+-          }
+-
+-          //
+-          // Now store the result on the stack
+-          //
+-          TosState tos_type = cache->flag_state();
+-          int field_offset = cache->f2();
+-          if (cache->is_volatile()) {
+-            if (tos_type == atos) {
+-              SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1);
+-            } else if (tos_type == itos) {
+-              SET_STACK_INT(obj->int_field_acquire(field_offset), -1);
+-            } else if (tos_type == ltos) {
+-              SET_STACK_LONG(obj->long_field_acquire(field_offset), 0);
+-              MORE_STACK(1);
+-            } else if (tos_type == btos) {
+-              SET_STACK_INT(obj->byte_field_acquire(field_offset), -1);
+-            } else if (tos_type == ctos) {
+-              SET_STACK_INT(obj->char_field_acquire(field_offset), -1);
+-            } else if (tos_type == stos) {
+-              SET_STACK_INT(obj->short_field_acquire(field_offset), -1);
+-            } else if (tos_type == ftos) {
+-              SET_STACK_FLOAT(obj->float_field_acquire(field_offset), -1);
+-            } else {
+-              SET_STACK_DOUBLE(obj->double_field_acquire(field_offset), 0);
+-              MORE_STACK(1);
+-            }
+-          } else {
+-            if (tos_type == atos) {
+-              SET_STACK_OBJECT(obj->obj_field(field_offset), -1);
+-            } else if (tos_type == itos) {
+-              SET_STACK_INT(obj->int_field(field_offset), -1);
+-            } else if (tos_type == ltos) {
+-              SET_STACK_LONG(obj->long_field(field_offset), 0);
+-              MORE_STACK(1);
+-            } else if (tos_type == btos) {
+-              SET_STACK_INT(obj->byte_field(field_offset), -1);
+-            } else if (tos_type == ctos) {
+-              SET_STACK_INT(obj->char_field(field_offset), -1);
+-            } else if (tos_type == stos) {
+-              SET_STACK_INT(obj->short_field(field_offset), -1);
+-            } else if (tos_type == ftos) {
+-              SET_STACK_FLOAT(obj->float_field(field_offset), -1);
+-            } else {
+-              SET_STACK_DOUBLE(obj->double_field(field_offset), 0);
+-              MORE_STACK(1);
+-            }
+-          }
+-
+-          UPDATE_PC_AND_CONTINUE(3);
+-         }
+-
+-      CASE(_putfield):
+-      CASE(_putstatic):
+-        {
+-          u2 index = Bytes::get_native_u2(pc+1);
+-          ConstantPoolCacheEntry* cache = cp->entry_at(index);
+-          if (!cache->is_resolved((Bytecodes::Code)opcode)) {
+-            CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode), 
+-                    handle_exception);
+-            cache = cp->entry_at(index);
+-          }
+-
+-#ifdef VM_JVMTI
+-          if (_jvmti_interp_events) {
+-            int *count_addr;
+-            oop obj;
+-            // Check to see if a field modification watch has been set 
+-            // before we take the time to call into the VM.
+-            count_addr = (int *)JvmtiExport::get_field_modification_count_addr();
+-            if ( *count_addr > 0 ) {
+-              if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) {
+-                obj = (oop)NULL;
+-              }
+-              else {
+-                if (cache->is_long() || cache->is_double()) {
+-                  obj = (oop) STACK_OBJECT(-3);
+-                } else {
+-                  obj = (oop) STACK_OBJECT(-2);
+-                }
+-              }
+-
+-              CALL_VM(InterpreterRuntime::post_field_modification(THREAD,
+-                                          obj, 
+-                                          cache, 
+-                                          (jvalue *)STACK_SLOT(-1)),  
+-                                          handle_exception);
+-            }
+-          }
+-#endif /* VM_JVMTI */
+-
+-          // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases
+-          // out so c++ compiler has a chance for constant prop to fold everything possible away.
+-
+-          oop obj;
+-          int count;
+-          TosState tos_type = cache->flag_state();
+-
+-          count = -1;
+-          if (tos_type == ltos || tos_type == dtos) {
+-            --count;
+-          }
+-          if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) {
+-            obj = (oop) cache->f1();
+-          } else {
+-            --count;
+-            obj = (oop) STACK_OBJECT(count);
+-            CHECK_NULL(obj);
+-          }
+-
+-          //
+-          // Now store the result
+-          //
+-          int field_offset = cache->f2();
+-          if (cache->is_volatile()) {
+-            if (tos_type == itos) {
+-              obj->release_int_field_put(field_offset, STACK_INT(-1));
+-            } else if (tos_type == atos) {
+-              obj->release_obj_field_put(field_offset, STACK_OBJECT(-1));
+-              OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0);
+-            } else if (tos_type == btos) {
+-              obj->release_byte_field_put(field_offset, STACK_INT(-1));
+-            } else if (tos_type == ltos) {
+-              obj->release_long_field_put(field_offset, STACK_LONG(-1));
+-            } else if (tos_type == ctos) {
+-              obj->release_char_field_put(field_offset, STACK_INT(-1));
+-            } else if (tos_type == stos) {
+-              obj->release_short_field_put(field_offset, STACK_INT(-1));
+-            } else if (tos_type == ftos) {
+-              obj->release_float_field_put(field_offset, STACK_FLOAT(-1));
+-            } else {
+-              obj->release_double_field_put(field_offset, STACK_DOUBLE(-1));
+-            }
+-            OrderAccess::storeload();
+-          } else {
+-            if (tos_type == itos) {
+-              obj->int_field_put(field_offset, STACK_INT(-1));
+-            } else if (tos_type == atos) {
+-              obj->obj_field_put(field_offset, STACK_OBJECT(-1));
+-              OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0);
+-            } else if (tos_type == btos) {
+-              obj->byte_field_put(field_offset, STACK_INT(-1));
+-            } else if (tos_type == ltos) {
+-              obj->long_field_put(field_offset, STACK_LONG(-1));
+-            } else if (tos_type == ctos) {
+-              obj->char_field_put(field_offset, STACK_INT(-1));
+-            } else if (tos_type == stos) {
+-              obj->short_field_put(field_offset, STACK_INT(-1));
+-            } else if (tos_type == ftos) {
+-              obj->float_field_put(field_offset, STACK_FLOAT(-1));
+-            } else {
+-              obj->double_field_put(field_offset, STACK_DOUBLE(-1));
+-            }
+-          }
+-
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(3, count);
+-        }  
+-
+-      CASE(_new): {
+-        u2 index = Bytes::get_Java_u2(pc+1);
+-        constantPoolOop constants = istate->method()->constants();
+-        if (!constants->tag_at(index).is_unresolved_klass()) {
+-          // Make sure klass is initialized and doesn't have a finalizer
+-          oop entry = (klassOop) *constants->obj_at_addr(index);
+-          assert(entry->is_klass(), "Should be resolved klass");
+-          klassOop k_entry = (klassOop) entry;
+-          assert(k_entry->klass_part()->oop_is_instance(), "Should be instanceKlass");
+-          instanceKlass* ik = (instanceKlass*) k_entry->klass_part();
+-          if ( ik->is_initialized() && ik->can_be_fastpath_allocated() ) {
+-            size_t obj_size = ik->size_helper();
+-            oop result = NULL;
+-            bool need_zero = false;
+-            if (UseTLAB) {
+-              result = (oop) THREAD->tlab().allocate(obj_size);
+-            }
+-            if (result == NULL) {
+-              need_zero = true;
+-              // Try allocate in shared eden
+-        retry:
+-              HeapWord* compare_to = *Universe::heap()->top_addr();
+-              HeapWord* new_top = compare_to + obj_size;
+-              if (new_top <= *Universe::heap()->end_addr()) {
+-                if (Atomic::cmpxchg_ptr(new_top, Universe::heap()->top_addr(), compare_to) != compare_to) {
+-                  goto retry;
+-                }
+-                result = (oop) compare_to;
+-              }
+-            }
+-            if (result != NULL) {
+-              // Initialize object (if nonzero size and need) and then the header
+-              if (need_zero ) {
+-                HeapWord* to_zero = (HeapWord*) result + sizeof(oopDesc) / oopSize;
+-                obj_size -= sizeof(oopDesc) / oopSize;
+-                if (obj_size > 0 ) {
+-                  memset(to_zero, 0, obj_size * HeapWordSize);
+-                }
+-              }
+-              if (UseBiasedLocking) {
+-                result->set_mark(ik->prototype_header());
+-              } else {
+-                result->set_mark(markOopDesc::prototype());
+-              }
+-              result->set_klass(k_entry);
+-              SET_STACK_OBJECT(result, 0);
+-              UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);
+-            }
+-          }
+-        }
+-        // Slow case allocation
+-        CALL_VM(InterpreterRuntime::_new(THREAD, istate->method()->constants(), index),
+-                handle_exception);
+-        SET_STACK_OBJECT(THREAD->vm_result(), 0);
+-        THREAD->set_vm_result(NULL);
+-        UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);
+-      }
+-      CASE(_anewarray): {
+-        u2 index = Bytes::get_Java_u2(pc+1);
+-        jint size = STACK_INT(-1);
+-        CALL_VM(InterpreterRuntime::anewarray(THREAD, istate->method()->constants(), index, size),
+-                handle_exception);
+-        SET_STACK_OBJECT(THREAD->vm_result(), -1);
+-        THREAD->set_vm_result(NULL);
+-        UPDATE_PC_AND_CONTINUE(3);
+-      }
+-      CASE(_multianewarray): {
+-        jint dims = *(pc+3);
+-        jint size = STACK_INT(-1);
+-        // stack grows down, dimensions are up!
+-        jint *dimarray =
+-                   (jint*)&topOfStack[dims * Interpreter::stackElementWords()+ 
+-                                      Interpreter::stackElementWords()-1];
+-        //adjust pointer to start of stack element
+-        CALL_VM(InterpreterRuntime::multianewarray(THREAD, dimarray),
+-                handle_exception);
+-        SET_STACK_OBJECT(THREAD->vm_result(), -dims);
+-        THREAD->set_vm_result(NULL);
+-        UPDATE_PC_AND_TOS_AND_CONTINUE(4, -(dims-1));
+-      }
+-      CASE(_checkcast):
+-          if (STACK_OBJECT(-1) != NULL) {
+-            u2 index = Bytes::get_Java_u2(pc+1);
+-            if (ProfileInterpreter) {
+-              // needs Profile_checkcast QQQ
+-              ShouldNotReachHere();
+-            }
+-            // Constant pool may have actual klass or unresolved klass. If it is
+-            // unresolved we must resolve it
+-            if (istate->method()->constants()->tag_at(index).is_unresolved_klass()) {
+-              CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception);
+-            }
+-            klassOop klassOf = (klassOop) *(istate->method()->constants()->obj_at_addr(index));
+-            klassOop objKlassOop = STACK_OBJECT(-1)->klass(); //ebx
+-            //
+-            // Check for compatibilty. This check must not GC!!
+-            // Seems way more expensive now that we must dispatch
+-            //
+-            if (objKlassOop != klassOf && 
+-                !objKlassOop->klass_part()->is_subtype_of(klassOf)) {
+-              ResourceMark rm(THREAD);  
+-              const char* objName = Klass::cast(objKlassOop)->external_name();
+-              const char* klassName = Klass::cast(klassOf)->external_name();
+-              char* message = SharedRuntime::generate_class_cast_message(
+-                objName, klassName);
+-              VM_JAVA_ERROR(vmSymbols::java_lang_ClassCastException(), message);
+-            }
+-          } else {
+-            if (UncommonNullCast) {
+-//              istate->method()->set_null_cast_seen();
+-// [RGV] Not sure what to do here!
+-              ShouldNotReachHere();
+-
+-            }
+-          }
+-          UPDATE_PC_AND_CONTINUE(3);
+-
+-      CASE(_instanceof):
+-          if (STACK_OBJECT(-1) == NULL) {
+-            SET_STACK_INT(0, -1);
+-          } else {
+-            u2 index = Bytes::get_Java_u2(pc+1);
+-            // Constant pool may have actual klass or unresolved klass. If it is
+-            // unresolved we must resolve it
+-            if (istate->method()->constants()->tag_at(index).is_unresolved_klass()) {
+-              CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception);
+-            }
+-            klassOop klassOf = (klassOop) *(istate->method()->constants()->obj_at_addr(index));
+-            klassOop objKlassOop = STACK_OBJECT(-1)->klass();
+-            //
+-            // Check for compatibilty. This check must not GC!!
+-            // Seems way more expensive now that we must dispatch
+-            //
+-            if ( objKlassOop == klassOf || objKlassOop->klass_part()->is_subtype_of(klassOf)) {
+-              SET_STACK_INT(1, -1);
+-            } else {
+-              SET_STACK_INT(0, -1);
+-            }
+-          }
+-          UPDATE_PC_AND_CONTINUE(3);
+-
+-      CASE(_ldc_w):
+-      CASE(_ldc):
+-        {
+-          u2 index;
+-          bool wide = false;
+-          int incr = 2; // frequent case
+-          if (opcode == Bytecodes::_ldc) {
+-            index = pc[1];
+-          } else {
+-            index = Bytes::get_Java_u2(pc+1);
+-            incr = 3;
+-            wide = true;
+-          }
+-
+-          constantPoolOop constants = istate->method()->constants();
+-          switch (constants->tag_at(index).value()) {
+-          case JVM_CONSTANT_Integer:
+-            SET_STACK_INT(constants->int_at(index), 0);
+-            break;
+-
+-          case JVM_CONSTANT_Float:
+-            SET_STACK_FLOAT(constants->float_at(index), 0);
+-            break;
+-
+-          case JVM_CONSTANT_String:
+-            SET_STACK_OBJECT(constants->resolved_string_at(index), 0);
+-            break;
+-
+-          case JVM_CONSTANT_Class:
+-            SET_STACK_OBJECT(constants->resolved_klass_at(index)->klass_part()->java_mirror(), 0);
+-            break;
+-
+-          case JVM_CONSTANT_UnresolvedString:
+-          case JVM_CONSTANT_UnresolvedClass:
+-	  case JVM_CONSTANT_UnresolvedClassInError:
+-            CALL_VM(InterpreterRuntime::ldc(THREAD, wide), handle_exception);
+-            SET_STACK_OBJECT(THREAD->vm_result(), 0);
+-            THREAD->set_vm_result(NULL);
+-            break;
+-
+-#if 0
+-          CASE(_fast_igetfield):
+-          CASE(_fastagetfield):
+-          CASE(_fast_aload_0):
+-          CASE(_fast_iaccess_0):
+-          CASE(__fast_aaccess_0):
+-          CASE(_fast_linearswitch):
+-          CASE(_fast_binaryswitch):
+-            fatal("unsupported fast bytecode");
+-#endif
+-
+-          default:  ShouldNotReachHere();
+-          }
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1);
+-        }
+-
+-      CASE(_ldc2_w):
+-        {
+-          u2 index = Bytes::get_Java_u2(pc+1);
+-
+-          constantPoolOop constants = istate->method()->constants();
+-          switch (constants->tag_at(index).value()) {
+-
+-          case JVM_CONSTANT_Long:
+-             SET_STACK_LONG(constants->long_at(index), 1);
+-            break;
+-
+-          case JVM_CONSTANT_Double:
+-             SET_STACK_DOUBLE(constants->double_at(index), 1);
+-            break;
+-          default:  ShouldNotReachHere();
+-          }
+-          UPDATE_PC_AND_TOS_AND_CONTINUE(3, 2);
+-        }
+-
+-      CASE(_invokeinterface): {
+-        u2 index = Bytes::get_native_u2(pc+1);
+-
+-        // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases
+-        // out so c++ compiler has a chance for constant prop to fold everything possible away.
+-
+-        ConstantPoolCacheEntry* cache = cp->entry_at(index);
+-        if (!cache->is_resolved((Bytecodes::Code)opcode)) {
+-          CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode), 
+-                  handle_exception);
+-          cache = cp->entry_at(index);
+-        }
+-
+-        istate->set_msg(call_method);
+-
+-        // Special case of invokeinterface called for virtual method of
+-        // java.lang.Object.  See cpCacheOop.cpp for details.
+-        // This code isn't produced by javac, but could be produced by
+-        // another compliant java compiler.
+-        if (cache->is_methodInterface()) {
+-          methodOop callee;
+-          CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
+-          if (cache->is_vfinal()) {
+-            callee = (methodOop) cache->f2();
+-          } else {
+-            // get receiver
+-            int parms = cache->parameter_size();
+-            // Same comments as invokevirtual apply here
+-            instanceKlass* rcvrKlass = (instanceKlass*)
+-                                 STACK_OBJECT(-parms)->klass()->klass_part();
+-            callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()];
+-          }
+-          istate->set_callee(callee);
+-          istate->set_callee_entry_point(callee->from_interpreted_entry());
+-#ifdef VM_JVMTI
+-          if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) {
+-            istate->set_callee_entry_point(callee->interpreter_entry());
+-          }
+-#endif /* VM_JVMTI */
+-          istate->set_bcp_advance(5);
+-          UPDATE_PC_AND_RETURN(0); // I'll be back...
+-        }
+-
+-        // this could definitely be cleaned up QQQ
+-        methodOop callee;
+-        klassOop iclass = (klassOop)cache->f1();
+-        // instanceKlass* interface = (instanceKlass*) iclass->klass_part();
+-        // get receiver
+-        int parms = cache->parameter_size();
+-        oop rcvr = STACK_OBJECT(-parms);
+-        CHECK_NULL(rcvr); 
+-        instanceKlass* int2 = (instanceKlass*) rcvr->klass()->klass_part();
+-        itableOffsetEntry* ki = (itableOffsetEntry*) int2->start_of_itable();
+-        int i;
+-        for ( i = 0 ; i < int2->itable_length() ; i++, ki++ ) {
+-          if (ki->interface_klass() == iclass) break;
+-        }
+-        // If the interface isn't found, this class doesn't implement this
+-        // interface.  The link resolver checks this but only for the first
+-        // time this interface is called.
+-        if (i == int2->itable_length()) {
+-          VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), "");
+-        }
+-        int mindex = cache->f2();
+-        itableMethodEntry* im = ki->first_method_entry(rcvr->klass());
+-        callee = im[mindex].method();
+-        if (callee == NULL) {
+-          VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), "");
+-        }
+-        
+-        istate->set_callee(callee);
+-        istate->set_callee_entry_point(callee->from_interpreted_entry());
+-#ifdef VM_JVMTI
+-        if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) {
+-          istate->set_callee_entry_point(callee->interpreter_entry());
+-        }
+-#endif /* VM_JVMTI */
+-        istate->set_bcp_advance(5);
+-        UPDATE_PC_AND_RETURN(0); // I'll be back...
+-      }
+-
+-      CASE(_invokevirtual):
+-      CASE(_invokespecial):
+-      CASE(_invokestatic): {
+-        u2 index = Bytes::get_native_u2(pc+1);
+-
+-        ConstantPoolCacheEntry* cache = cp->entry_at(index);
+-        // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases
+-        // out so c++ compiler has a chance for constant prop to fold everything possible away.
+-
+-        if (!cache->is_resolved((Bytecodes::Code)opcode)) {
+-          CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode), 
+-                  handle_exception);
+-          cache = cp->entry_at(index);
+-        }
+-     
+-        istate->set_msg(call_method);
+-        {
+-          methodOop callee;
+-          if ((Bytecodes::Code)opcode == Bytecodes::_invokevirtual) {
+-            CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
+-            if (cache->is_vfinal()) callee = (methodOop) cache->f2();
+-            else {
+-              // get receiver
+-              int parms = cache->parameter_size();
+-              // this works but needs a resourcemark and seems to create a vtable on every call:
+-              // methodOop callee = rcvr->klass()->klass_part()->vtable()->method_at(cache->f2());
+-              // 
+-              // this fails with an assert
+-              // instanceKlass* rcvrKlass = instanceKlass::cast(STACK_OBJECT(-parms)->klass());
+-              // but this works
+-              instanceKlass* rcvrKlass = (instanceKlass*) STACK_OBJECT(-parms)->klass()->klass_part();
+-              /*
+-                Executing this code in java.lang.String:
+-                    public String(char value[]) {
+-                          this.count = value.length;
+-                          this.value = (char[])value.clone();
+-                     }
+-
+-                 a find on rcvr->klass()->klass_part() reports:
+-                 {type array char}{type array class} 
+-                  - klass: {other class}
+-
+-                  but using instanceKlass::cast(STACK_OBJECT(-parms)->klass()) causes in assertion failure
+-                  because rcvr->klass()->klass_part()->oop_is_instance() == 0
+-                  However it seems to have a vtable in the right location. Huh?
+-
+-              */
+-              callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()];
+-            }
+-          } else {
+-            if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) {
+-              CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
+-            }
+-            callee = (methodOop) cache->f1();
+-          }
+-
+-          istate->set_callee(callee);
+-          istate->set_callee_entry_point(callee->from_interpreted_entry());
+-#ifdef VM_JVMTI
+-          if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) {
+-            istate->set_callee_entry_point(callee->interpreter_entry());
+-          }
+-#endif /* VM_JVMTI */
+-          istate->set_bcp_advance(3);
+-          UPDATE_PC_AND_RETURN(0); // I'll be back...
+-        }
+-      }
+-
+-      /* Allocate memory for a new java object. */
+-
+-      CASE(_newarray): {
+-        BasicType atype = (BasicType) *(pc+1);
+-        jint size = STACK_INT(-1);
+-        CALL_VM(InterpreterRuntime::newarray(THREAD, atype, size),
+-                handle_exception);
+-        SET_STACK_OBJECT(THREAD->vm_result(), -1);
+-        THREAD->set_vm_result(NULL);
+-
+-        UPDATE_PC_AND_CONTINUE(2);
+-      }
+-
+-      /* Throw an exception. */
+-
+-      CASE(_athrow): {
+-          oop except_oop = STACK_OBJECT(-1);
+-          CHECK_NULL(except_oop);
+-          // set pending_exception so we use common code
+-          THREAD->set_pending_exception(except_oop, NULL, 0);
+-          goto handle_exception;
+-      }
+-
+-      /* goto and jsr. They are exactly the same except jsr pushes
+-       * the address of the next instruction first.
+-       */
+-
+-      CASE(_jsr): {
+-          /* push bytecode index on stack */
+-          SET_STACK_SLOT(((address)pc - (intptr_t)(istate->method()->code_base()) + 3), 0);
+-          MORE_STACK(1);
+-          /* FALL THROUGH */
+-      }
+-
+-      CASE(_goto):
+-      {
+-          int16_t offset = (int16_t)Bytes::get_Java_u2(pc + 1);
+-          address branch_pc = pc;
+-          UPDATE_PC(offset);
+-          DO_BACKEDGE_CHECKS(offset, branch_pc);
+-          CONTINUE;
+-      }
+-
+-      CASE(_jsr_w): {
+-          /* push return address on the stack */
+-          SET_STACK_SLOT(((address)pc - (intptr_t)(istate->method()->code_base()) + 5), 0);
+-          MORE_STACK(1);
+-          /* FALL THROUGH */
+-      }
+-
+-      CASE(_goto_w):
+-      {
+-          int32_t offset = Bytes::get_Java_u4(pc + 1);
+-          address branch_pc = pc;
+-          UPDATE_PC(offset);
+-          DO_BACKEDGE_CHECKS(offset, branch_pc);
+-          CONTINUE;
+-      }
+-
+-      /* return from a jsr or jsr_w */
+-
+-      CASE(_ret): {
+-          pc = istate->method()->code_base() + (intptr_t)(LOCALS_SLOT(pc[1]));
+-          UPDATE_PC_AND_CONTINUE(0);
+-      }
+-
+-      /* debugger breakpoint */
+-
+-      CASE(_breakpoint): {
+-          Bytecodes::Code original_bytecode;
+-          DECACHE_STATE();                                        
+-          SET_LAST_JAVA_FRAME();                                  
+-          original_bytecode = InterpreterRuntime::get_original_bytecode_at(THREAD, 
+-                              istate->method(), pc);
+-          RESET_LAST_JAVA_FRAME();
+-          CACHE_STATE();
+-          if (THREAD->pending_exception()) goto handle_exception;
+-            CALL_VM(InterpreterRuntime::_breakpoint(THREAD, istate->method(), pc),
+-                                                    handle_exception);
+-
+-          opcode = (jubyte)original_bytecode;
+-          goto opcode_switch;
+-      }
+-
+-      DEFAULT:
+-          fatal2("\t*** Unimplemented opcode: %d = %s\n",
+-                 opcode, Bytecodes::name((Bytecodes::Code)opcode));
+-          goto finish;
+-
+-      } /* switch(opc) */
+-
+-      
+-#ifdef USELABELS
+-    check_for_exception: 
+-#endif
+-    {
+-      if (!THREAD->has_pending_exception()) {
+-        CONTINUE;
+-      }
+-      /* We will be gcsafe soon, so flush our state. */
+-      DECACHE_PC();
+-      goto handle_exception;
+-    }
+-  do_continue: ;
+-
+-  } /* while (1) interpreter loop */
+-
+-
+-  // An exception exists in the thread state see whether this activation can handle it
+-  handle_exception: {
+-
+-    HandleMarkCleaner __hmc(THREAD);
+-    Handle except_oop(THREAD, THREAD->pending_exception());
+-    // Prevent any subsequent HandleMarkCleaner in the VM 
+-    // from freeing the except_oop handle.
+-    HandleMark __hm(THREAD);
+-
+-    THREAD->clear_pending_exception();
+-    assert(except_oop(), "No exception to process");
+-    intptr_t continuation_bci;
+-    // expression stack is emptied
+-    topOfStack = istate->stack_base() - Interpreter::stackElementWords();
+-    CALL_VM(continuation_bci = (intptr_t)InterpreterRuntime::exception_handler_for_exception(THREAD, except_oop()), 
+-            handle_exception);
+-
+-    except_oop = (oop) THREAD->vm_result();
+-    THREAD->set_vm_result(NULL);
+-    if (continuation_bci >= 0) {
+-      // Place exception on top of stack
+-      SET_STACK_OBJECT(except_oop(), 0);
+-      MORE_STACK(1);
+-      pc = istate->method()->code_base() + continuation_bci;
+-      if (TraceExceptions) {
+-        ttyLocker ttyl;
+-        ResourceMark rm;
+-        tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop());
+-        tty->print_cr(" thrown in interpreter method <%s>", istate->method()->print_value_string());
+-        tty->print_cr(" at bci %d, continuing at %d for thread " INTPTR_FORMAT,
+-                      pc - (intptr_t)istate->method()->code_base(),
+-                      continuation_bci, THREAD);
+-      }
+-      // for AbortVMOnException flag
+-      NOT_PRODUCT(Exceptions::debug_check_abort(except_oop));
+-      goto run;
+-    }
+-    if (TraceExceptions) {
+-      ttyLocker ttyl;
+-      ResourceMark rm;
+-      tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop());
+-      tty->print_cr(" thrown in interpreter method <%s>", istate->method()->print_value_string());
+-      tty->print_cr(" at bci %d, unwinding for thread " INTPTR_FORMAT,
+-                    pc  - (intptr_t) istate->method()->code_base(),
+-                    THREAD);
+-    }
+-    // for AbortVMOnException flag
+-    NOT_PRODUCT(Exceptions::debug_check_abort(except_oop));
+-    // No handler in this activation, unwind and try again
+-    THREAD->set_pending_exception(except_oop(), NULL, 0);
+-    goto handle_return;
+-  }  /* handle_exception: */
+-      
+-
+-
+-  // Return from an interpreter invocation with the result of the interpretation
+-  // on the top of the Java Stack (or a pending exception)
+-
+-handle_Pop_Frame:
+-
+-  // We don't really do anything special here except we must be aware
+-  // that we can get here without ever locking the method (if sync).
+-  // Also we skip the notification of the exit.
+-
+-  istate->set_msg(popping_frame);
+-  // Clear pending so while the pop is in process
+-  // we don't start another one if a call_vm is done.
+-  THREAD->clr_pop_frame_pending();
+-  // Let interpreter (only) see the we're in the process of popping a frame
+-  THREAD->set_pop_frame_in_process();
+-
+-handle_return:
+-  {
+-    DECACHE_STATE();
+-
+-    bool suppress_error = istate->msg() == popping_frame;
+-    bool suppress_exit_event = THREAD->has_pending_exception() || suppress_error;
+-    Handle original_exception(THREAD, THREAD->pending_exception());
+-    Handle illegal_state_oop(THREAD, NULL);
+-
+-    // We'd like a HandleMark here to prevent any subsequent HandleMarkCleaner
+-    // in any following VM entries from freeing our live handles, but illegal_state_oop
+-    // isn't really allocated yet and so doesn't become live until later and
+-    // in unpredicatable places. Instead we must protect the places where we enter the
+-    // VM. It would be much simpler (and safer) if we could allocate a real handle with
+-    // a NULL oop in it and then overwrite the oop later as needed. This isn't
+-    // unfortunately isn't possible.
+-
+-    THREAD->clear_pending_exception();
+-
+-    //
+-    // As far as we are concerned we have returned. If we have a pending exception
+-    // that will be returned as this invocation's result. However if we get any
+-    // exception(s) while checking monitor state one of those IllegalMonitorStateExceptions
+-    // will be our final result (i.e. monitor exception trumps a pending exception).
+-    //
+-
+-    // If we never locked the method (or really passed the point where we would have),
+-    // there is no need to unlock it (or look for other monitors), since that
+-    // could not have happened.
+-
+-    if (!THREAD->do_not_unlock()) {
+-      // At this point we consider that we have returned. We now check that the
+-      // locks were properly block structured. If we find that they were not
+-      // used properly we will return with an illegal monitor exception.
+-      // The exception is checked by the caller not the callee since this
+-      // checking is considered to be part of the invocation and therefore
+-      // in the callers scope (JVM spec 8.13).
+-      //
+-      // Another weird thing to watch for is if the method was locked
+-      // recursively and then not exited properly. This means we must
+-      // examine all the entries in reverse time(and stack) order and
+-      // unlock as we find them. If we find the method monitor before
+-      // we are at the initial entry then we should throw an exception.
+-      // It is not clear the template based interpreter does this
+-      // correctly
+-        
+-      BasicObjectLock* base = istate->monitor_base();
+-      BasicObjectLock* end = (BasicObjectLock*) istate->stack_base();
+-      bool method_unlock_needed = istate->method()->is_synchronized();
+-      // We know the initial monitor was used for the method don't check that
+-      // slot in the loop
+-      if (method_unlock_needed) base--;
+-
+-      // Check all the monitors to see they are unlocked. Install exception if found to be locked.
+-      while (end < base) {
+-        oop lockee = end->obj();
+-        if (lockee != NULL) {
+-          BasicLock* lock = end->lock();
+-          markOop header = lock->displaced_header();
+-          end->set_obj(NULL);
+-          // If it isn't recursive we either must swap old header or call the runtime
+-          if (header != NULL) {
+-            if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) {
+-              // restore object for the slow case
+-              end->set_obj(lockee);
+-              {
+-                // Prevent any HandleMarkCleaner from freeing our live handles
+-                HandleMark __hm(THREAD); 
+-                CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, end));
+-              }
+-            }
+-          }
+-          // One error is plenty
+-          if (illegal_state_oop() == NULL && !suppress_error) {
+-            {
+-              // Prevent any HandleMarkCleaner from freeing our live handles
+-              HandleMark __hm(THREAD); 
+-              CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD));
+-            }
+-            assert(THREAD->has_pending_exception(), "Lost our exception!");
+-            illegal_state_oop = THREAD->pending_exception();
+-            THREAD->clear_pending_exception();
+-          }
+-        }
+-        end++;
+-      }
+-      // Unlock the method if needed
+-      if (method_unlock_needed) {
+-        if (base->obj() == NULL) {
+-          // The method is already unlocked this is not good.
+-          if (illegal_state_oop() == NULL && !suppress_error) {
+-            {
+-              // Prevent any HandleMarkCleaner from freeing our live handles
+-              HandleMark __hm(THREAD); 
+-              CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD));
+-            }
+-            assert(THREAD->has_pending_exception(), "Lost our exception!");
+-            illegal_state_oop = THREAD->pending_exception();
+-            THREAD->clear_pending_exception();
+-          }
+-        } else {
+-          //
+-          // The initial monitor is always used for the method
+-          // However if that slot is no longer the oop for the method it was unlocked
+-          // and reused by something that wasn't unlocked!
+-          //
+-          // deopt can come in with rcvr dead because c2 knows
+-          // its value is preserved in the monitor. So we can't use locals[0] at all
+-          // and must use first monitor slot.
+-          //
+-          oop rcvr = base->obj();
+-          if (rcvr == NULL) {
+-            if (!suppress_error) {
+-              VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), "");
+-              illegal_state_oop = THREAD->pending_exception();
+-              THREAD->clear_pending_exception();
+-            }
+-          } else {
+-            BasicLock* lock = base->lock();
+-            markOop header = lock->displaced_header();
+-            base->set_obj(NULL);
+-            // If it isn't recursive we either must swap old header or call the runtime
+-            if (header != NULL) {
+-              if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) {
+-                // restore object for the slow case
+-                base->set_obj(rcvr);
+-                {
+-                  // Prevent any HandleMarkCleaner from freeing our live handles
+-                  HandleMark __hm(THREAD); 
+-                  CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base));
+-                }
+-                if (THREAD->has_pending_exception()) {
+-                  if (!suppress_error) illegal_state_oop = THREAD->pending_exception();
+-                  THREAD->clear_pending_exception();
+-                }
+-              }
+-            }
+-          }
+-        }
+-      }
+-    }
+-
+-    //
+-    // Notify jvmti
+-    //
+-    // NOTE: we do not notify a method_exit if we have a pending exception,
+-    // including an exception we generate for unlocking checks.  In the former
+-    // case, JVMDI has already been notified by our call for the exception handler
+-    // and in both cases as far as JVMDI is concerned we have already returned.
+-    // If we notify it again JVMDI will be all confused about how many frames
+-    // are still on the stack (4340444).
+-    //
+-    //
+-    // NOTE Further! It turns out the the JVMTI spec in fact expects to see
+-    // method_exit events whenever we leave an activation unless it was done
+-    // for popframe. This is nothing like jvmdi. However
+-    // we are passing the tests at the moment (apparently becuase they are
+-    // jvmdi based) so rather than change this code and possibly fail tests
+-    // we will leave it alone (with this note) in anticipation of changing
+-    // the vm and the tests simultaneously.
+-
+-
+-    //
+-    suppress_exit_event = suppress_exit_event || illegal_state_oop() != NULL;
+-
+-
+-
+-#ifdef VM_JVMTI
+-      if (_jvmti_interp_events) {
+-        // Whenever JVMTI puts a thread in interp_only_mode, method
+-        // entry/exit events are sent for that thread to track stack depth.  
+-        if ( !suppress_exit_event && THREAD->is_interp_only_mode() ) {
+-          {
+-            // Prevent any HandleMarkCleaner from freeing our live handles
+-            HandleMark __hm(THREAD); 
+-            CALL_VM_NOCHECK(InterpreterRuntime::post_method_exit(THREAD));
+-          }
+-        }
+-      }
+-#endif /* VM_JVMTI */
+-
+-    //
+-    // See if we are returning any exception
+-    // A pending exception that was pending prior to a possible popping frame
+-    // overrides the popping frame.
+-    //
+-    assert(!suppress_error || suppress_error && illegal_state_oop() == NULL, "Error was not suppressed");
+-    if (illegal_state_oop() != NULL || original_exception() != NULL) {
+-      // inform the frame manager we have no result
+-      istate->set_msg(throwing_exception);
+-      if (illegal_state_oop() != NULL) 
+-        THREAD->set_pending_exception(illegal_state_oop(), NULL, 0);
+-      else
+-        THREAD->set_pending_exception(original_exception(), NULL, 0);
+-      istate->set_return_kind((Bytecodes::Code)opcode);
+-      UPDATE_PC_AND_RETURN(0);
+-    }
+-
+-    if (istate->msg() == popping_frame) {
+-      // Make it simpler on the assembly code and set the message for the frame pop.
+-      // returns
+-      if (istate->prev() == NULL) {
+-        // We must be returning to a deoptimized frame (because popframe only happens between
+-        // two interpreted frames). We need to save the current arguments in C heap so that
+-        // the deoptimized frame when it restarts can copy the arguments to its expression
+-        // stack and re-execute the call. We also have to notify deoptimization that this
+-        // has occured and to pick the preerved args copy them to the deoptimized frame's
+-        // java expression stack. Yuck.
+-        //
+-        THREAD->popframe_preserve_args(in_ByteSize(istate->method()->size_of_parameters() * wordSize),
+-                                LOCALS_SLOT(istate->method()->size_of_parameters() - 1));
+-        THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit);
+-      }
+-      UPDATE_PC_AND_RETURN(1);
+-    } else {
+-      // Normal return
+-      // Advance the pc and return to frame manager
+-      istate->set_msg(return_from_method);
+-      istate->set_return_kind((Bytecodes::Code)opcode);
+-      UPDATE_PC_AND_RETURN(1);
+-    }
+-  } /* handle_return: */
+-
+-// This is really a fatal error return
+-
+-finish:
+-  DECACHE_TOS();
+-  DECACHE_PC();
+-
+-  return;
+-}
+-
+-#endif // CC_INTERP
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cppInterpreter.cpp openjdk/hotspot/src/share/vm/interpreter/cppInterpreter.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/cppInterpreter.cpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/cppInterpreter.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,135 @@
++/*
++ * Copyright 1997-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++#include "incls/_precompiled.incl"
++#include "incls/_cppInterpreter.cpp.incl"
++
++#ifdef CC_INTERP
++# define __ _masm->
++
++void CppInterpreter::initialize() {
++  if (_code != NULL) return;
++  AbstractInterpreter::initialize();
++
++  // generate interpreter
++  { ResourceMark rm;
++    TraceTime timer("Interpreter generation", TraceStartupTime);
++    int code_size = InterpreterCodeSize;
++    NOT_PRODUCT(code_size *= 4;)  // debug uses extra interpreter code space
++    _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
++                          "Interpreter");
++    InterpreterGenerator g(_code);
++    if (PrintInterpreter) print();
++  }
++
++
++  // Allow c++ interpreter to do one initialization now that switches are set, etc.
++  BytecodeInterpreter start_msg(BytecodeInterpreter::initialize);
++  if (JvmtiExport::can_post_interpreter_events())
++    BytecodeInterpreter::runWithChecks(&start_msg);
++  else
++    BytecodeInterpreter::run(&start_msg);
++}
++
++
++address    CppInterpreter::_tosca_to_stack         [AbstractInterpreter::number_of_result_handlers];
++address    CppInterpreter::_stack_to_stack         [AbstractInterpreter::number_of_result_handlers];
++address    CppInterpreter::_stack_to_native_abi    [AbstractInterpreter::number_of_result_handlers];
++
++CppInterpreterGenerator::CppInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) {
++}
++
++static const BasicType types[Interpreter::number_of_result_handlers] = {
++  T_BOOLEAN,
++  T_CHAR   ,
++  T_BYTE   ,
++  T_SHORT  ,
++  T_INT    ,
++  T_LONG   ,
++  T_VOID   ,
++  T_FLOAT  ,
++  T_DOUBLE ,
++  T_OBJECT
++};
++
++void CppInterpreterGenerator::generate_all() {
++  AbstractInterpreterGenerator::generate_all();
++
++  { CodeletMark cm(_masm, "result handlers for native calls");
++    // The various result converter stublets.
++    int is_generated[Interpreter::number_of_result_handlers];
++    memset(is_generated, 0, sizeof(is_generated));
++    int _tosca_to_stack_is_generated[Interpreter::number_of_result_handlers];
++    int _stack_to_stack_is_generated[Interpreter::number_of_result_handlers];
++    int _stack_to_native_abi_is_generated[Interpreter::number_of_result_handlers];
++
++    memset(_tosca_to_stack_is_generated, 0, sizeof(_tosca_to_stack_is_generated));
++    memset(_stack_to_stack_is_generated, 0, sizeof(_stack_to_stack_is_generated));
++    memset(_stack_to_native_abi_is_generated, 0, sizeof(_stack_to_native_abi_is_generated));
++    for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {
++      BasicType type = types[i];
++      if (!is_generated[Interpreter::BasicType_as_index(type)]++) {
++        Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);
++      }
++      if (!_tosca_to_stack_is_generated[Interpreter::BasicType_as_index(type)]++) {
++        Interpreter::_tosca_to_stack[Interpreter::BasicType_as_index(type)] = generate_tosca_to_stack_converter(type);
++      }
++      if (!_stack_to_stack_is_generated[Interpreter::BasicType_as_index(type)]++) {
++        Interpreter::_stack_to_stack[Interpreter::BasicType_as_index(type)] = generate_stack_to_stack_converter(type);
++      }
++      if (!_stack_to_native_abi_is_generated[Interpreter::BasicType_as_index(type)]++) {
++        Interpreter::_stack_to_native_abi[Interpreter::BasicType_as_index(type)] = generate_stack_to_native_abi_converter(type);
++      }
++    }
++  }
++
++
++#define method_entry(kind) Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind)
++
++  { CodeletMark cm(_masm, "(kind = frame_manager)");
++    // all non-native method kinds
++    method_entry(zerolocals);
++    method_entry(zerolocals_synchronized);
++    method_entry(empty);
++    method_entry(accessor);
++    method_entry(abstract);
++    method_entry(java_lang_math_sin   );
++    method_entry(java_lang_math_cos   );
++    method_entry(java_lang_math_tan   );
++    method_entry(java_lang_math_abs   );
++    method_entry(java_lang_math_sqrt  );
++    method_entry(java_lang_math_log   );
++    method_entry(java_lang_math_log10 );
++    Interpreter::_native_entry_begin = Interpreter::code()->code_end();
++    method_entry(native);
++    method_entry(native_synchronized);
++    Interpreter::_native_entry_end = Interpreter::code()->code_end();
++  }
++
++
++#undef method_entry
++
++}
++
++#endif // CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cppInterpreterGenerator.hpp openjdk/hotspot/src/share/vm/interpreter/cppInterpreterGenerator.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/cppInterpreterGenerator.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/cppInterpreterGenerator.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,47 @@
++/*
++ * Copyright 1997-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++// This file contains the platform-independant parts
++// of the template interpreter generator.
++
++#ifdef CC_INTERP
++
++class CppInterpreterGenerator: public AbstractInterpreterGenerator {
++  protected:
++  // shared code sequences
++  // Converter for native abi result to tosca result
++  address generate_result_handler_for(BasicType type);
++  address generate_tosca_to_stack_converter(BasicType type);
++  address generate_stack_to_stack_converter(BasicType type);
++  address generate_stack_to_native_abi_converter(BasicType type);
++
++  void generate_all();
++
++ public:
++  CppInterpreterGenerator(StubQueue* _code);
++
++   #include "incls/_cppInterpreterGenerator_pd.hpp.incl"
++};
++
++#endif // CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cppInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/cppInterpreter.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/cppInterpreter.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/cppInterpreter.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,83 @@
++/*
++ * Copyright 1997-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++#ifdef CC_INTERP
++
++// This file contains the platform-independant parts
++// of the c++ interpreter
++
++class CppInterpreter: public AbstractInterpreter {
++  friend class VMStructs;
++  friend class Interpreter; // contains()
++  friend class InterpreterGenerator; // result handlers
++  friend class CppInterpreterGenerator; // result handlers
++ public:
++
++
++ protected:
++
++  // tosca result -> stack result
++  static address    _tosca_to_stack[number_of_result_handlers];  // converts tosca to C++ interpreter stack result
++  // stack result -> stack result
++  static address    _stack_to_stack[number_of_result_handlers];  // pass result between C++ interpreter calls
++  // stack result -> native abi result
++  static address    _stack_to_native_abi[number_of_result_handlers];  // converts C++ interpreter results to native abi
++
++  // this is to allow frame and only frame to use contains().
++  friend class      frame;
++
++ public:
++  // Initialization/debugging
++  static void       initialize();
++  // this only returns whether a pc is within generated code for the interpreter.
++
++  // This is a moderately dubious interface for the c++ interpreter. Only
++  // frame code and debug.cpp should be using it.
++  static bool       contains(address pc);
++
++ public:
++
++
++  // No displatch table to switch so no need for these to do anything special
++  static void notice_safepoints() {}
++  static void ignore_safepoints() {}
++
++  static address    native_result_to_tosca()                    { return (address)_native_abi_to_tosca; } // aka result handler
++  static address    tosca_result_to_stack()                     { return (address)_tosca_to_stack; }
++  static address    stack_result_to_stack()                     { return (address)_stack_to_stack; }
++  static address    stack_result_to_native()                    { return (address)_stack_to_native_abi; }
++
++  static address    native_result_to_tosca(int index)           { return _native_abi_to_tosca[index]; } // aka result handler
++  static address    tosca_result_to_stack(int index)            { return _tosca_to_stack[index]; }
++  static address    stack_result_to_stack(int index)            { return _stack_to_stack[index]; }
++  static address    stack_result_to_native(int index)           { return _stack_to_native_abi[index]; }
++
++  static address    return_entry  (TosState state, int length);
++  static address    deopt_entry   (TosState state, int length);
++
++#include "incls/_cppInterpreter_pd.hpp.incl"
++
++};
++
++#endif // CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/interpreter.cpp openjdk/hotspot/src/share/vm/interpreter/interpreter.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/interpreter.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/interpreter.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)interpreter.cpp	1.246 07/06/08 15:21:43 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -63,58 +60,20 @@
+ 
+ 
+ //------------------------------------------------------------------------------------------------------------------------
+-// Implementation of AbstractInterpreter
+-
+-
+-// Define a prototype interface
+-DEF_STUB_INTERFACE(InterpreterCodelet);
+-
++// Implementation of  platform independent aspects of Interpreter
+ 
+ void AbstractInterpreter::initialize() {
+   if (_code != NULL) return;
+ 
+-  // assertions
+-#ifndef CC_INTERP
+-  assert((int)Bytecodes::number_of_codes <= (int)DispatchTable::length, 
+-         "dispatch table too small");
+-#endif /* !CC_INTERP */
+-
+   // make sure 'imported' classes are initialized
+   if (CountBytecodes || TraceBytecodes || StopInterpreterAt) BytecodeCounter::reset();
+   if (PrintBytecodeHistogram)                                BytecodeHistogram::reset();
+   if (PrintBytecodePairHistogram)                            BytecodePairHistogram::reset();
+-#ifndef CC_INTERP
+-  TemplateTable::initialize();
+-#endif /* !CC_INTERP */
+-  InvocationCounter::reinitialize(DelayCompilationDuringStartup);
+ 
+-  // generate interpreter
+-  { ResourceMark rm;
+-    TraceTime timer("Interpreter generation", TraceStartupTime);    
+-    int code_size = Interpreter::InterpreterCodeSize;
+-    NOT_PRODUCT(code_size *= 4;)  // debug uses extra interpreter code space
+-    _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
+-                          "Interpreter");
+-    InterpreterGenerator g(_code);
+-    if (PrintInterpreter) print();
+-  }
++  InvocationCounter::reinitialize(DelayCompilationDuringStartup);
+ 
+-#ifdef CC_INTERP
+-  {
+-    // Allow c++ interpreter to do one initialization now that switches are set, etc.
+-    cInterpreter start_msg(cInterpreter::initialize);
+-    if (JvmtiExport::can_post_interpreter_events())
+-      cInterpreter::InterpretMethodWithChecks(&start_msg);
+-    else
+-      cInterpreter::InterpretMethod(&start_msg);
+-  }
+-#else
+-  // initialize dispatch table
+-  _active_table = _normal_table;
+-#endif // CC_INTERP
+ }
+ 
+-
+ void AbstractInterpreter::print() {
+   tty->cr();
+   tty->print_cr("----------------------------------------------------------------------");
+@@ -159,312 +118,28 @@
+   }
+ }
+ 
+-
+-#ifndef CC_INTERP
+-//------------------------------------------------------------------------------------------------------------------------
+-// Implementation of EntryPoint
+-
+-EntryPoint::EntryPoint() {
+-  assert(number_of_states == 9, "check the code below");
+-  _entry[btos] = NULL;
+-  _entry[ctos] = NULL;
+-  _entry[stos] = NULL;
+-  _entry[atos] = NULL;
+-  _entry[itos] = NULL;
+-  _entry[ltos] = NULL;
+-  _entry[ftos] = NULL;
+-  _entry[dtos] = NULL;
+-  _entry[vtos] = NULL;
+-}
+-
+-
+-EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) {
+-  assert(number_of_states == 9, "check the code below");
+-  _entry[btos] = bentry;
+-  _entry[ctos] = centry;
+-  _entry[stos] = sentry;
+-  _entry[atos] = aentry;
+-  _entry[itos] = ientry;
+-  _entry[ltos] = lentry;
+-  _entry[ftos] = fentry;
+-  _entry[dtos] = dentry;
+-  _entry[vtos] = ventry;
+-}
+-
+-
+-void EntryPoint::set_entry(TosState state, address entry) {
+-  assert(0 <= state && state < number_of_states, "state out of bounds");
+-  _entry[state] = entry;
+-}
+-
+-
+-address EntryPoint::entry(TosState state) const {
+-  assert(0 <= state && state < number_of_states, "state out of bounds");
+-  return _entry[state];
+-}
+-
+-
+-void EntryPoint::print() {
+-  tty->print("[");
+-  for (int i = 0; i < number_of_states; i++) {
+-    if (i > 0) tty->print(", ");
+-    tty->print(INTPTR_FORMAT, _entry[i]);
+-  }
+-  tty->print("]");
+-}
+-
+-
+-bool EntryPoint::operator == (const EntryPoint& y) {
+-  int i = number_of_states;
+-  while (i-- > 0) {
+-    if (_entry[i] != y._entry[i]) return false;
+-  }
+-  return true;
+-}
+-
+-
+-//------------------------------------------------------------------------------------------------------------------------
+-// Implementation of DispatchTable
+-
+-EntryPoint DispatchTable::entry(int i) const {
+-  assert(0 <= i && i < length, "index out of bounds");
+-  return
+-    EntryPoint(
+-      _table[btos][i],
+-      _table[ctos][i],
+-      _table[stos][i],
+-      _table[atos][i],
+-      _table[itos][i],
+-      _table[ltos][i],
+-      _table[ftos][i],
+-      _table[dtos][i],
+-      _table[vtos][i]
+-    );
+-}
+-
+-
+-void DispatchTable::set_entry(int i, EntryPoint& entry) {
+-  assert(0 <= i && i < length, "index out of bounds");
+-  assert(number_of_states == 9, "check the code below");
+-  _table[btos][i] = entry.entry(btos);
+-  _table[ctos][i] = entry.entry(ctos);
+-  _table[stos][i] = entry.entry(stos);
+-  _table[atos][i] = entry.entry(atos);
+-  _table[itos][i] = entry.entry(itos);
+-  _table[ltos][i] = entry.entry(ltos);
+-  _table[ftos][i] = entry.entry(ftos);
+-  _table[dtos][i] = entry.entry(dtos);
+-  _table[vtos][i] = entry.entry(vtos);
+-}
+-
+-
+-bool DispatchTable::operator == (DispatchTable& y) {
+-  int i = length;
+-  while (i-- > 0) {
+-    EntryPoint t = y.entry(i); // for compiler compatibility (BugId 4150096)
+-    if (!(entry(i) == t)) return false;
+-  }
+-  return true;
+-}
+-#endif // CC_INTERP
+-
+-
+ //------------------------------------------------------------------------------------------------------------------------
+ // Implementation of interpreter
+ 
+ StubQueue* AbstractInterpreter::_code                                       = NULL;
+ bool       AbstractInterpreter::_notice_safepoints                          = false;
+-
+ address    AbstractInterpreter::_rethrow_exception_entry                    = NULL;
+-#ifndef CC_INTERP
+-address    AbstractInterpreter::_remove_activation_entry                    = NULL;
+-address    AbstractInterpreter::_remove_activation_preserving_args_entry    = NULL;
+-
+-
+-address    AbstractInterpreter::_throw_ArrayIndexOutOfBoundsException_entry = NULL;
+-address    AbstractInterpreter::_throw_ArrayStoreException_entry            = NULL;
+-address    AbstractInterpreter::_throw_ArithmeticException_entry            = NULL;
+-address    AbstractInterpreter::_throw_ClassCastException_entry             = NULL;
+-address    AbstractInterpreter::_throw_NullPointerException_entry           = NULL;
+-address    AbstractInterpreter::_throw_StackOverflowError_entry             = NULL;
+-address    AbstractInterpreter::_throw_exception_entry                      = NULL;
+-
+-#ifndef PRODUCT
+-EntryPoint AbstractInterpreter::_trace_code;
+-#endif // !PRODUCT
+-EntryPoint AbstractInterpreter::_return_entry[AbstractInterpreter::number_of_return_entries];
+-EntryPoint AbstractInterpreter::_earlyret_entry;
+-EntryPoint AbstractInterpreter::_deopt_entry [AbstractInterpreter::number_of_deopt_entries ];
+-EntryPoint AbstractInterpreter::_continuation_entry;
+-EntryPoint AbstractInterpreter::_safept_entry;
+-
+-address    AbstractInterpreter::_return_3_addrs_by_index[AbstractInterpreter::number_of_return_addrs];
+-address    AbstractInterpreter::_return_5_addrs_by_index[AbstractInterpreter::number_of_return_addrs];
+-
+-DispatchTable AbstractInterpreter::_active_table;
+-DispatchTable AbstractInterpreter::_normal_table;
+-DispatchTable AbstractInterpreter::_safept_table;
+-address    AbstractInterpreter::_wentry_point[DispatchTable::length];
+-#endif // CC_INTERP
+ 
+ address    AbstractInterpreter::_native_entry_begin                         = NULL;
+ address    AbstractInterpreter::_native_entry_end                           = NULL;
+ address    AbstractInterpreter::_slow_signature_handler;
+ address    AbstractInterpreter::_entry_table            [AbstractInterpreter::number_of_method_entries];
+ address    AbstractInterpreter::_native_abi_to_tosca    [AbstractInterpreter::number_of_result_handlers];
+-#ifdef CC_INTERP
+-address    AbstractInterpreter::_tosca_to_stack         [AbstractInterpreter::number_of_result_handlers];
+-address    AbstractInterpreter::_stack_to_stack         [AbstractInterpreter::number_of_result_handlers];
+-address    AbstractInterpreter::_stack_to_native_abi    [AbstractInterpreter::number_of_result_handlers];
+-#endif
+-
+-
+-//------------------------------------------------------------------------------------------------------------------------
+-// A CodeletMark serves as an automatic creator/initializer for Codelets
+-// (As a subclass of ResourceMark it automatically GC's the allocated
+-// code buffer and assemblers).
+-
+-class CodeletMark: ResourceMark {
+- private:
+-  InterpreterCodelet*         _clet;
+-  InterpreterMacroAssembler** _masm;
+-  CodeBuffer                  _cb;
+-
+-  int codelet_size() {
+-    // Request the whole code buffer (minus a little for alignment).
+-    // The commit call below trims it back for each codelet.
+-    int codelet_size = AbstractInterpreter::code()->available_space() - 2*K;
+-
+-    // Guarantee there's a little bit of code space left.
+-    guarantee (codelet_size > 0 && (size_t)codelet_size >  2*K,
+-               "not enough space for interpreter generation");
+-
+-    return codelet_size;
+-  }
+-
+- public:
+-  CodeletMark(
+-    InterpreterMacroAssembler*& masm,
+-    const char* description,
+-    Bytecodes::Code bytecode = Bytecodes::_illegal):
+-    _clet((InterpreterCodelet*)AbstractInterpreter::code()->request(codelet_size())),
+-    _cb(_clet->code_begin(), _clet->code_size())
+-
+-  { // request all space (add some slack for Codelet data)
+-    assert (_clet != NULL, "we checked not enough space already");
+-
+-    // initialize Codelet attributes
+-    _clet->initialize(description, bytecode);
+-    // create assembler for code generation
+-    masm  = new InterpreterMacroAssembler(&_cb);
+-    _masm = &masm;
+-  }  
+-  
+-  ~CodeletMark() {
+-    // align so printing shows nop's instead of random code at the end (Codelets are aligned)
+-    (*_masm)->align(wordSize);
+-    // make sure all code is in code buffer
+-    (*_masm)->flush();
+-
+-
+-    // commit Codelet
+-    AbstractInterpreter::code()->commit((*_masm)->code()->pure_code_size());
+-    // make sure nobody can use _masm outside a CodeletMark lifespan
+-    *_masm = NULL;
+-  }
+-};
+-
+ 
+ //------------------------------------------------------------------------------------------------------------------------
+ // Generation of complete interpreter
+ 
+ AbstractInterpreterGenerator::AbstractInterpreterGenerator(StubQueue* _code) {
+   _masm                      = NULL;
+-#ifndef CC_INTERP
+-  _unimplemented_bytecode    = NULL;
+-  _illegal_bytecode_sequence = NULL;
+-#endif // CC_INTERP
+ }
+ 
+ 
+-void AbstractInterpreterGenerator::generate_all() {
+-#ifndef CC_INTERP
+-  { CodeletMark cm(_masm, "error exits");
+-    _unimplemented_bytecode    = generate_error_exit("unimplemented bytecode");
+-    _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified");
+-  }
+-
+-#ifndef PRODUCT
+-  if (TraceBytecodes) {
+-    CodeletMark cm(_masm, "bytecode tracing support");
+-    Interpreter::_trace_code =
+-      EntryPoint(
+-        generate_trace_code(btos),
+-        generate_trace_code(ctos),
+-        generate_trace_code(stos),
+-        generate_trace_code(atos),
+-        generate_trace_code(itos),
+-        generate_trace_code(ltos),
+-        generate_trace_code(ftos),
+-        generate_trace_code(dtos),
+-        generate_trace_code(vtos)
+-      );
+-  }
+-#endif // !PRODUCT
+-
+-  { CodeletMark cm(_masm, "return entry points");
+-    for (int i = 0; i < Interpreter::number_of_return_entries; i++) {
+-      Interpreter::_return_entry[i] =
+-        EntryPoint(
+-          generate_return_entry_for(itos, i),
+-          generate_return_entry_for(itos, i),
+-          generate_return_entry_for(itos, i),
+-          generate_return_entry_for(atos, i),
+-          generate_return_entry_for(itos, i),
+-          generate_return_entry_for(ltos, i),
+-          generate_return_entry_for(ftos, i),
+-          generate_return_entry_for(dtos, i),
+-          generate_return_entry_for(vtos, i)
+-        );
+-    }
+-  }
+-
+-  { CodeletMark cm(_masm, "earlyret entry points");
+-    Interpreter::_earlyret_entry =
+-      EntryPoint(
+-        generate_earlyret_entry_for(btos),
+-        generate_earlyret_entry_for(ctos),
+-        generate_earlyret_entry_for(stos),
+-        generate_earlyret_entry_for(atos),
+-        generate_earlyret_entry_for(itos),
+-        generate_earlyret_entry_for(ltos),
+-        generate_earlyret_entry_for(ftos),
+-        generate_earlyret_entry_for(dtos),
+-        generate_earlyret_entry_for(vtos)
+-      );
+-  }
+-
+-  { CodeletMark cm(_masm, "deoptimization entry points");
+-    for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) {
+-      Interpreter::_deopt_entry[i] =
+-        EntryPoint(
+-          generate_deopt_entry_for(itos, i),
+-          generate_deopt_entry_for(itos, i),
+-          generate_deopt_entry_for(itos, i),
+-          generate_deopt_entry_for(atos, i),
+-          generate_deopt_entry_for(itos, i),
+-          generate_deopt_entry_for(ltos, i),
+-          generate_deopt_entry_for(ftos, i),
+-          generate_deopt_entry_for(dtos, i),
+-          generate_deopt_entry_for(vtos, i)
+-        );
+-    }
+-  }
+-
+-#endif // !CC_INTERP
+-
+-  { CodeletMark cm(_masm, "result handlers for native calls");
+-    const BasicType types[Interpreter::number_of_result_handlers] = {
++static const BasicType types[Interpreter::number_of_result_handlers] = {
+       T_BOOLEAN,
+       T_CHAR   ,
+       T_BYTE   ,
+@@ -475,297 +150,16 @@
+       T_FLOAT  ,
+       T_DOUBLE ,
+       T_OBJECT
+-    };
+-    // The various result converter stublets.
+-    int is_generated[Interpreter::number_of_result_handlers];
+-    memset(is_generated, 0, sizeof(is_generated));
+-#ifdef CC_INTERP
+-    int _tosca_to_stack_is_generated[Interpreter::number_of_result_handlers];
+-    int _stack_to_stack_is_generated[Interpreter::number_of_result_handlers];
+-    int _stack_to_native_abi_is_generated[Interpreter::number_of_result_handlers];
+-
+-    memset(_tosca_to_stack_is_generated, 0, sizeof(_tosca_to_stack_is_generated));
+-    memset(_stack_to_stack_is_generated, 0, sizeof(_stack_to_stack_is_generated));
+-    memset(_stack_to_native_abi_is_generated, 0, sizeof(_stack_to_native_abi_is_generated));
+-#endif
+-    for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {
+-      BasicType type = types[i];
+-      if (!is_generated[Interpreter::BasicType_as_index(type)]++) {
+-	Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);
+-      }
+-#ifdef CC_INTERP
+-      if (!_tosca_to_stack_is_generated[Interpreter::BasicType_as_index(type)]++) {
+-	Interpreter::_tosca_to_stack[Interpreter::BasicType_as_index(type)] = generate_tosca_to_stack_converter(type);
+-      }
+-      if (!_stack_to_stack_is_generated[Interpreter::BasicType_as_index(type)]++) {
+-	Interpreter::_stack_to_stack[Interpreter::BasicType_as_index(type)] = generate_stack_to_stack_converter(type);
+-      }
+-      if (!_stack_to_native_abi_is_generated[Interpreter::BasicType_as_index(type)]++) {
+-	Interpreter::_stack_to_native_abi[Interpreter::BasicType_as_index(type)] = generate_stack_to_native_abi_converter(type);
+-      }
+-#endif
+-    }
+-  }
+-
+-  { CodeletMark cm(_masm, "slow signature handler");
+-    Interpreter::_slow_signature_handler = generate_slow_signature_handler();
+-  }
+-
+-#ifndef CC_INTERP
+-  for (int j = 0; j < number_of_states; j++) {
+-    const TosState states[] = {btos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos};
+-    Interpreter::_return_3_addrs_by_index[Interpreter::TosState_as_index(states[j])] = Interpreter::return_entry(states[j], 3);
+-    Interpreter::_return_5_addrs_by_index[Interpreter::TosState_as_index(states[j])] = Interpreter::return_entry(states[j], 5);
+-  }
+-
+-  { CodeletMark cm(_masm, "continuation entry points");
+-    Interpreter::_continuation_entry =
+-      EntryPoint(
+-        generate_continuation_for(btos),
+-        generate_continuation_for(ctos),
+-        generate_continuation_for(stos),
+-        generate_continuation_for(atos),
+-        generate_continuation_for(itos),
+-        generate_continuation_for(ltos),
+-        generate_continuation_for(ftos),
+-        generate_continuation_for(dtos),
+-        generate_continuation_for(vtos)
+-      );
+-  }
+-
+-  { CodeletMark cm(_masm, "safepoint entry points");
+-    Interpreter::_safept_entry =
+-      EntryPoint(
+-	generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+-	generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+-	generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+-	generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+-        generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+-        generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+-        generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+-        generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+-        generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint))
+-      );
+-  }
+-
+-  { CodeletMark cm(_masm, "exception handling");
+-    // (Note: this is not safepoint safe because thread may return to compiled code)
+-    generate_throw_exception();
+-  }
+-
+-  { CodeletMark cm(_masm, "throw exception entrypoints");
+-    Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException");
+-    Interpreter::_throw_ArrayStoreException_entry            = generate_klass_exception_handler("java/lang/ArrayStoreException"                 );
+-    Interpreter::_throw_ArithmeticException_entry            = generate_exception_handler("java/lang/ArithmeticException"           , "/ by zero");
+-    Interpreter::_throw_ClassCastException_entry             = generate_ClassCastException_handler();
+-    Interpreter::_throw_NullPointerException_entry           = generate_exception_handler("java/lang/NullPointerException"          , NULL       );
+-    Interpreter::_throw_StackOverflowError_entry             = generate_StackOverflowError_handler();
+-  }
+-#endif // !CC_INTERP
+-
+-
+-#ifdef CC_INTERP
+-
+-#define method_entry(kind) Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind)
+-
+-  { CodeletMark cm(_masm, "(kind = frame_manager)");
+-    // all non-native method kinds  
+-    method_entry(zerolocals);
+-    method_entry(zerolocals_synchronized);
+-    method_entry(empty);
+-    method_entry(accessor);
+-    method_entry(abstract);
+-    method_entry(java_lang_math_sin   );
+-    method_entry(java_lang_math_cos   );
+-    method_entry(java_lang_math_tan   );
+-    method_entry(java_lang_math_abs   );
+-    method_entry(java_lang_math_sqrt  );
+-    method_entry(java_lang_math_log   );
+-    method_entry(java_lang_math_log10 );
+-    Interpreter::_native_entry_begin = Interpreter::code()->code_end();
+-    method_entry(native);
+-    method_entry(native_synchronized);
+-    Interpreter::_native_entry_end = Interpreter::code()->code_end();
+-  }
+-
+-#else
+-
+-#define method_entry(kind)                                                                    \
+-  { CodeletMark cm(_masm, "method entry point (kind = " #kind ")");                    \
+-    Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind);  \
+-  }
+-
+-  // all non-native method kinds  
+-  method_entry(zerolocals)
+-  method_entry(zerolocals_synchronized)
+-  method_entry(empty)
+-  method_entry(accessor)
+-  method_entry(abstract)
+-  method_entry(java_lang_math_sin  )
+-  method_entry(java_lang_math_cos  )
+-  method_entry(java_lang_math_tan  )
+-  method_entry(java_lang_math_abs  )
+-  method_entry(java_lang_math_sqrt )
+-  method_entry(java_lang_math_log  )
+-  method_entry(java_lang_math_log10)
+-
+-  // all native method kinds (must be one contiguous block)
+-  Interpreter::_native_entry_begin = Interpreter::code()->code_end();
+-  method_entry(native)
+-  method_entry(native_synchronized)
+-  Interpreter::_native_entry_end = Interpreter::code()->code_end();
+-
+-#endif // !CC_INTERP
+-
+-#undef method_entry
+-
+-#ifndef CC_INTERP
+-  // Bytecodes
+-  set_entry_points_for_all_bytes();
+-  set_safepoints_for_all_bytes();
+-#endif // !CC_INTERP
+-}
+-
+-
+-//------------------------------------------------------------------------------------------------------------------------
+-
+-#ifndef CC_INTERP
+-address AbstractInterpreterGenerator::generate_error_exit(const char* msg) {
+-  address entry = __ pc();
+-  __ stop(msg);
+-  return entry;
+-}
+-
+-
+-//------------------------------------------------------------------------------------------------------------------------
+-
+-void AbstractInterpreterGenerator::set_entry_points_for_all_bytes() {
+-  for (int i = 0; i < DispatchTable::length; i++) {
+-    Bytecodes::Code code = (Bytecodes::Code)i;
+-    if (Bytecodes::is_defined(code)) {
+-      set_entry_points(code);
+-    } else {
+-      set_unimplemented(i);
+-    }
+-  }
+-}
+-
+-
+-void AbstractInterpreterGenerator::set_safepoints_for_all_bytes() {
+-  for (int i = 0; i < DispatchTable::length; i++) {
+-    Bytecodes::Code code = (Bytecodes::Code)i;
+-    if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry);
+-  }
+-}
+-
+-
+-void AbstractInterpreterGenerator::set_unimplemented(int i) {
+-  address e = _unimplemented_bytecode;
+-  EntryPoint entry(e, e, e, e, e, e, e, e, e);
+-  Interpreter::_normal_table.set_entry(i, entry);
+-  Interpreter::_wentry_point[i] = _unimplemented_bytecode;
+-}
+-
+-
+-void AbstractInterpreterGenerator::set_entry_points(Bytecodes::Code code) {
+-  CodeletMark cm(_masm, Bytecodes::name(code), code);
+-  // initialize entry points
+-  assert(_unimplemented_bytecode    != NULL, "should have been generated before");
+-  assert(_illegal_bytecode_sequence != NULL, "should have been generated before");
+-  address bep = _illegal_bytecode_sequence;
+-  address cep = _illegal_bytecode_sequence;
+-  address sep = _illegal_bytecode_sequence;
+-  address aep = _illegal_bytecode_sequence;
+-  address iep = _illegal_bytecode_sequence;
+-  address lep = _illegal_bytecode_sequence;
+-  address fep = _illegal_bytecode_sequence;
+-  address dep = _illegal_bytecode_sequence;
+-  address vep = _unimplemented_bytecode;
+-  address wep = _unimplemented_bytecode;
+-  // code for short & wide version of bytecode
+-  if (Bytecodes::is_defined(code)) {
+-    Template* t = TemplateTable::template_for(code);
+-    assert(t->is_valid(), "just checking");
+-    set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);
+-  }
+-  if (Bytecodes::wide_is_defined(code)) {
+-    Template* t = TemplateTable::template_for_wide(code);
+-    assert(t->is_valid(), "just checking");
+-    set_wide_entry_point(t, wep);
+-  }
+-  // set entry points
+-  EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep);
+-  Interpreter::_normal_table.set_entry(code, entry);
+-  Interpreter::_wentry_point[code] = wep;
+-}
+-
++};
+ 
+-void AbstractInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) {
+-  assert(t->is_valid(), "template must exist");
+-  assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions")
+-  wep = __ pc(); generate_and_dispatch(t);
+-}
++void AbstractInterpreterGenerator::generate_all() {
+ 
+ 
+-void AbstractInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {
+-  assert(t->is_valid(), "template must exist");
+-  switch (t->tos_in()) {
+-    case btos: vep = __ pc(); __ pop(btos); bep = __ pc(); generate_and_dispatch(t); break;
+-    case ctos: vep = __ pc(); __ pop(ctos); sep = __ pc(); generate_and_dispatch(t); break;
+-    case stos: vep = __ pc(); __ pop(stos); sep = __ pc(); generate_and_dispatch(t); break;
+-    case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
+-    case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
+-    case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
+-    case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;
+-    case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;
+-    case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);     break;
+-    default  : ShouldNotReachHere();                                                 break;
++  { CodeletMark cm(_masm, "slow signature handler");
++    Interpreter::_slow_signature_handler = generate_slow_signature_handler();
+   }
+-}
+-
+ 
+-//------------------------------------------------------------------------------------------------------------------------
+-
+-void AbstractInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {
+-#ifndef CC_INTERP
+-  if (PrintBytecodeHistogram)                                    histogram_bytecode(t);
+-#ifndef PRODUCT
+-  // debugging code
+-  if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode();
+-  if (PrintBytecodePairHistogram)                                histogram_bytecode_pair(t);
+-  if (TraceBytecodes)                                            trace_bytecode(t);
+-  if (StopInterpreterAt > 0)                                     stop_interpreter_at();
+-  __ verify_FPU(1, t->tos_in());
+-#endif // !PRODUCT
+-  int step;
+-  if (!t->does_dispatch()) { 
+-    step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
+-    if (tos_out == ilgl) tos_out = t->tos_out();
+-    // compute bytecode size
+-    assert(step > 0, "just checkin'");    
+-    // setup stuff for dispatching next bytecode 
+-    if (ProfileInterpreter && VerifyDataPointer
+-        && methodDataOopDesc::bytecode_has_profile(t->bytecode())) {
+-      __ verify_method_data_pointer();
+-    }
+-    __ dispatch_prolog(tos_out, step);
+-  }
+-  // generate template
+-  t->generate(_masm);
+-  // advance
+-  if (t->does_dispatch()) {
+-#ifdef ASSERT
+-    // make sure execution doesn't go beyond this point if code is broken
+-    __ should_not_reach_here();
+-#endif // ASSERT
+-  } else {
+-    // dispatch to next bytecode
+-    __ dispatch_epilog(tos_out, step);
+-  }
+-#endif
+ }
+-#endif /* !CC_INTERP */
+-
+ 
+ //------------------------------------------------------------------------------------------------------------------------
+ // Entry points
+@@ -867,21 +261,6 @@
+ }
+ #endif // PRODUCT
+ 
+-
+-#ifndef CC_INTERP
+-address AbstractInterpreter::return_entry(TosState state, int length) {
+-  guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length");
+-  return _return_entry[length].entry(state);
+-}
+-
+-
+-address AbstractInterpreter::deopt_entry(TosState state, int length) {
+-  guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length");
+-  return _deopt_entry[length].entry(state);
+-}
+-
+-#endif /* CC_INTERP */
+-
+ static BasicType constant_pool_type(methodOop method, int index) {
+   constantTag tag = method->constants()->tag_at(index);
+        if (tag.is_int              ()) return T_INT;
+@@ -959,7 +338,7 @@
+       // reexecute the operation and TOS value is on stack
+       assert(is_top_frame, "must be top frame");
+       use_next_mdp = false;
+-      return deopt_entry(vtos, 0);
++      return Interpreter::deopt_entry(vtos, 0);
+       break;
+ 
+ #ifdef COMPILER1
+@@ -996,18 +375,6 @@
+       type = constant_pool_type( method, Bytes::get_Java_u2(bcp+1) ); 
+       break;
+ 
+-    case Bytecodes::_return: {
+-      // This is used for deopt during registration of finalizers
+-      // during Object.<init>.  We simply need to resume execution at
+-      // the standard return vtos bytecode to pop the frame normally.
+-      // reexecuting the real bytecode would cause double registration
+-      // of the finalizable object.
+-#ifndef CC_INTERP
+-      assert(is_top_frame, "must be on top");
+-      return _normal_table.entry(Bytecodes::_return).entry(vtos);
+-#endif // CC_INTERP
+-    }
+-
+     default:
+       type = Bytecodes::result_type(code);
+       break;
+@@ -1016,60 +383,8 @@
+   // return entry point for computed continuation state & bytecode length
+   return
+     is_top_frame
+-    ? deopt_entry (as_TosState(type), length)
+-    : return_entry(as_TosState(type), length);
+-}
+-
+-
+-#ifndef CC_INTERP
+-
+-//------------------------------------------------------------------------------------------------------------------------
+-// Suport for invokes
+-
+-int AbstractInterpreter::TosState_as_index(TosState state) {
+-  assert( state < number_of_states , "Invalid state in TosState_as_index");
+-  assert(0 <= (int)state && (int)state < AbstractInterpreter::number_of_return_addrs, "index out of bounds");
+-  return (int)state;
+-}
+-
+-#endif // CC_INTERP
+-
+-//------------------------------------------------------------------------------------------------------------------------
+-// Safepoint suppport
+-
+-#ifndef CC_INTERP
+-static inline void copy_table(address* from, address* to, int size) {
+-  // Copy non-overlapping tables. The copy has to occur word wise for MT safety.
+-  while (size-- > 0) *to++ = *from++;
+-}
+-#endif
+-
+-void AbstractInterpreter::notice_safepoints() {
+-  if (!_notice_safepoints) {
+-    // switch to safepoint dispatch table
+-    _notice_safepoints = true;
+-#ifndef CC_INTERP
+-    copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address));
+-#endif
+-  }
+-}
+-
+-
+-// switch from the dispatch table which notices safepoints back to the
+-// normal dispatch table.  So that we can notice single stepping points,
+-// keep the safepoint dispatch table if we are single stepping in JVMTI.
+-// Note that the should_post_single_step test is exactly as fast as the 
+-// JvmtiExport::_enabled test and covers both cases.
+-void AbstractInterpreter::ignore_safepoints() {
+-  if (_notice_safepoints) {
+-    if (!JvmtiExport::should_post_single_step()) {
+-      // switch to normal dispatch table
+-      _notice_safepoints = false;
+-#ifndef CC_INTERP
+-      copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address));
+-#endif
+-    }
+-  }
++    ? Interpreter::deopt_entry (as_TosState(type), length)
++    : Interpreter::return_entry(as_TosState(type), length);
+ }
+ 
+ void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/interpreterGenerator.hpp openjdk/hotspot/src/share/vm/interpreter/interpreterGenerator.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/interpreterGenerator.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/interpreterGenerator.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,38 @@
++/*
++ * Copyright 1997-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++// This file contains the platform-independant parts
++// of the interpreter generator.
++
++
++class InterpreterGenerator: public CC_INTERP_ONLY(CppInterpreterGenerator)
++                                   NOT_CC_INTERP(TemplateInterpreterGenerator) {
++
++public:
++
++InterpreterGenerator(StubQueue* _code);
++
++#include "incls/_interpreterGenerator_pd.hpp.incl"
++
++};
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/interpreter.hpp openjdk/hotspot/src/share/vm/interpreter/interpreter.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/interpreter.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/interpreter.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)interpreter.hpp	1.153 07/05/17 15:54:31 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -66,397 +63,72 @@
+   Bytecodes::Code bytecode() const               { return _bytecode; }
+ };
+ 
+-
+-#ifndef CC_INTERP
+-//------------------------------------------------------------------------------------------------------------------------
+-// A little wrapper class to group tosca-specific entry points into a unit.
+-// (tosca = Top-Of-Stack CAche)
+-
+-class EntryPoint VALUE_OBJ_CLASS_SPEC {
+- private:
+-  address _entry[number_of_states];
+-
+- public:
+-  // Construction
+-  EntryPoint();
+-  EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry);
+-
+-  // Attributes
+-  address entry(TosState state) const;                // return target address for a given tosca state
+-  void    set_entry(TosState state, address entry);   // set    target address for a given tosca state
+-  void    print();
+-
+-  // Comparison
+-  bool operator == (const EntryPoint& y);             // for debugging only
+-};
++// Define a prototype interface
++DEF_STUB_INTERFACE(InterpreterCodelet);
+ 
+ 
+ //------------------------------------------------------------------------------------------------------------------------
+-// A little wrapper class to group tosca-specific dispatch tables into a unit.
+-
+-class DispatchTable VALUE_OBJ_CLASS_SPEC {
+- public:
+-  enum { length = 1 << BitsPerByte };                 // an entry point for each byte value (also for undefined bytecodes)
++// A CodeletMark serves as an automatic creator/initializer for Codelets
++// (As a subclass of ResourceMark it automatically GC's the allocated
++// code buffer and assemblers).
+ 
++class CodeletMark: ResourceMark {
+  private:
+-  address _table[number_of_states][length];	      // dispatch tables, indexed by tosca and bytecode
++  InterpreterCodelet*         _clet;
++  InterpreterMacroAssembler** _masm;
++  CodeBuffer                  _cb;
+ 
+- public:
+-  // Attributes
+-  EntryPoint entry(int i) const;                      // return entry point for a given bytecode i
+-  void       set_entry(int i, EntryPoint& entry);     // set    entry point for a given bytecode i
+-  address*   table_for(TosState state) 		{ return _table[state]; }
+-  address*   table_for()			{ return table_for((TosState)0); }
+-  int	     distance_from(address *table)	{ return table - table_for(); }
+-  int	     distance_from(TosState state)	{ return distance_from(table_for(state)); }
+-
+-  // Comparison
+-  bool operator == (DispatchTable& y);                // for debugging only
+-};
++  int codelet_size() {
++    // Request the whole code buffer (minus a little for alignment).
++    // The commit call below trims it back for each codelet.
++    int codelet_size = AbstractInterpreter::code()->available_space() - 2*K;
+ 
+-#endif // CC_INTERP
+-
+-//------------------------------------------------------------------------------------------------------------------------
+-// The C++ interface to the bytecode interpreter.
+-
+-class AbstractInterpreter: AllStatic {
+-  friend class VMStructs;
+-  friend class Interpreter;
+- public:
+-  enum MethodKind {        
+-    zerolocals,                                                 // method needs locals initialization
+-    zerolocals_synchronized,                                    // method needs locals initialization & is synchronized
+-    native,                                                     // native method
+-    native_synchronized,                                        // native method & is synchronized
+-    empty,                                                      // empty method (code: _return)
+-    accessor,                                                   // accessor method (code: _aload_0, _getfield, _(a|i)return)
+-    abstract,                                                   // abstract method (throws an AbstractMethodException)
+-    java_lang_math_sin,                                         // implementation of java.lang.Math.sin   (x)
+-    java_lang_math_cos,                                         // implementation of java.lang.Math.cos   (x)
+-    java_lang_math_tan,                                         // implementation of java.lang.Math.tan   (x)
+-    java_lang_math_abs,                                         // implementation of java.lang.Math.abs   (x)
+-    java_lang_math_sqrt,                                        // implementation of java.lang.Math.sqrt  (x)
+-    java_lang_math_log,                                         // implementation of java.lang.Math.log   (x)
+-    java_lang_math_log10,                                       // implementation of java.lang.Math.log10 (x)
+-    number_of_method_entries,
+-    invalid = -1
+-  };
+-
+-  enum SomeConstants {
+-#ifndef CC_INTERP
+-    number_of_return_entries  = 9,                              // number of return entry points
+-    number_of_deopt_entries   = 9,                              // number of deoptimization entry points
+-    number_of_return_addrs    = 9,                              // number of return addresses
+-#endif // CC_INTERP
+-    number_of_result_handlers = 10                              // number of result handlers for native calls
+-  };    
+-
+- protected:
+-  static StubQueue* _code;                                      // the interpreter code (codelets)
+-  
+-  static address    _rethrow_exception_entry;                   // rethrows an activation in previous frame
+-#ifdef HOTSWAP
+-  static address    _remove_activation_preserving_args_entry;   // continuation address when current frame is being popped
+-#endif // HOTSWAP
+-
+-#ifndef CC_INTERP
+-  static address    _throw_ArrayIndexOutOfBoundsException_entry;
+-  static address    _throw_ArrayStoreException_entry;
+-  static address    _throw_ArithmeticException_entry;
+-  static address    _throw_ClassCastException_entry;
+-  static address    _throw_NullPointerException_entry;
+-  static address    _throw_StackOverflowError_entry;
+-  static address    _throw_exception_entry;
+-
+-  static address    _remove_activation_entry;                   // continuation address if an exception is not handled by current frame
+-
+-#ifndef PRODUCT
+-  static EntryPoint _trace_code;
+-#endif // !PRODUCT
+-  static EntryPoint _return_entry[number_of_return_entries];    // entry points to return to from a call
+-  static EntryPoint _earlyret_entry;                            // entry point to return early from a call
+-  static EntryPoint _deopt_entry[number_of_deopt_entries];      // entry points to return to from a deoptimization
+-  static EntryPoint _continuation_entry;
+-  static EntryPoint _safept_entry;
+-
+-  static address    _return_3_addrs_by_index[number_of_return_addrs];     // for invokevirtual   return entries
+-  static address    _return_5_addrs_by_index[number_of_return_addrs];     // for invokeinterface return entries
+-
+-  static DispatchTable _active_table;                           // the active    dispatch table (used by the interpreter for dispatch)
+-  static DispatchTable _normal_table;                           // the normal    dispatch table (used to set the active table in normal mode)
+-  static DispatchTable _safept_table;                           // the safepoint dispatch table (used to set the active table for safepoints)
+-  static address       _wentry_point[DispatchTable::length];    // wide instructions only (vtos tosca always)
+-  
+-#endif // CC_INTERP
+-  static bool       _notice_safepoints;                         // true if safepoints are activated
+-
+-  static address    _native_entry_begin;                        // Region for native entry code
+-  static address    _native_entry_end;
+-
+-  // method entry points
+-  static address    _entry_table[number_of_method_entries];     // entry points for a given method
+-  static address    _native_abi_to_tosca[number_of_result_handlers];  // for native method result handlers
+-#ifdef CC_INTERP
+-  // tosca result -> stack result
+-  static address    _tosca_to_stack[number_of_result_handlers];  // converts tosca to C++ interpreter stack result
+-  // stack result -> stack result
+-  static address    _stack_to_stack[number_of_result_handlers];  // pass result between C++ interpreter calls
+-  // stack result -> native abi result
+-  static address    _stack_to_native_abi[number_of_result_handlers];  // converts C++ interpreter results to native abi
+-#endif
+-  static address    _slow_signature_handler;                              // the native method generic (slow) signature handler
+-
+-
+-  
+-  friend class      TemplateTable;
+-  friend class      AbstractInterpreterGenerator;
+-  friend class              InterpreterGenerator;
+-  friend class      InterpreterMacroAssembler;
++    // Guarantee there's a little bit of code space left.
++    guarantee (codelet_size > 0 && (size_t)codelet_size >  2*K,
++               "not enough space for interpreter generation");
+ 
+- public:
+-  // Initialization/debugging
+-  static void       initialize();
+-  static StubQueue* code()                                      { return _code; }
+-  // this only returns whether a pc is within generated code for the interpreter.
+-#ifdef CC_INTERP
+- private:
+-  // for the c++ based interpreter this misses much code.  make sure it doesn't get called.
+-#endif // CC_INTERP
+-  static bool       contains(address pc)                        { return _code->contains(pc); }
++    return codelet_size;
++  }
+ 
+  public:
++  CodeletMark(
++    InterpreterMacroAssembler*& masm,
++    const char* description,
++    Bytecodes::Code bytecode = Bytecodes::_illegal):
++    _clet((InterpreterCodelet*)AbstractInterpreter::code()->request(codelet_size())),
++    _cb(_clet->code_begin(), _clet->code_size())
+ 
+-  // Method activation
+-  static MethodKind method_kind(methodHandle m);
+-  static address    entry_for_kind(MethodKind k)                { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; }
+-  static address    entry_for_method(methodHandle m)            { return _entry_table[method_kind(m)]; }
+-
+-  static void       print_method_kind(MethodKind kind)          PRODUCT_RETURN;
+-
+-  // Runtime support
+-
+-  static address    rethrow_exception_entry()                   { return _rethrow_exception_entry; }
+-
+-  static address    return_entry  (TosState state, int length); // length = invoke bytecode length (to advance to next bytecode)
+-  static address    deopt_entry   (TosState state, int length); // length = invoke bytecode length (to advance to next bytecode)
+-
+-#ifdef HOTSWAP
+-  static address    remove_activation_preserving_args_entry()   { return _remove_activation_preserving_args_entry; }
+-#endif // HOTSWAP
+-
+-#ifndef CC_INTERP
+-  static address    remove_activation_early_entry(TosState state) { return _earlyret_entry.entry(state); }
+-  static address    remove_activation_entry()                   { return _remove_activation_entry; }
+-  static address    throw_exception_entry()                     { return _throw_exception_entry; }
+-  static address    throw_ArithmeticException_entry()           { return _throw_ArithmeticException_entry; }
+-  static address    throw_NullPointerException_entry()          { return _throw_NullPointerException_entry; }
+-  static address    throw_StackOverflowError_entry()            { return _throw_StackOverflowError_entry; }
+-
+-  // Code generation
+-#ifndef PRODUCT
+-  static address    trace_code    (TosState state)              { return _trace_code.entry(state); }
+-#endif // !PRODUCT
+-  static address    continuation  (TosState state)              { return _continuation_entry.entry(state); }
+-  static address*   dispatch_table(TosState state)              { return _active_table.table_for(state); }
+-  static address*   dispatch_table()                            { return _active_table.table_for(); }
+-  static int        distance_from_dispatch_table(TosState state){ return _active_table.distance_from(state); }
+-  static address*   normal_table(TosState state)                { return _normal_table.table_for(state); }
+-  static address*   normal_table()                              { return _normal_table.table_for(); }
+-
+-  // Support for invokes
+-  static address*   return_3_addrs_by_index_table()             { return _return_3_addrs_by_index; }
+-  static address*   return_5_addrs_by_index_table()             { return _return_5_addrs_by_index; }
+-  static int        TosState_as_index(TosState state);          // computes index into return_3_entry_by_index table
+-#endif // CC_INTERP
+-
+-
+-  // Activation size in words for a method that is just being called.
+-  // Parameters haven't been pushed so count them too.
+-  static int        size_top_interpreter_activation(methodOop method);
+-
+-  // Deoptimization support
+-  static address    continuation_for(methodOop method,
+-				     address bcp,
+-				     int callee_parameters,
+-				     bool is_top_frame,
+-				     bool& use_next_mdp);
+-
+-  // share implementation of size_activation and layout_activation:
+-  static int        size_activation(methodOop method,
+-				    int temps,
+-                                    int popframe_args,
+-				    int monitors,
+-				    int callee_params,
+-				    int callee_locals,
+-				    bool is_top_frame);
+-
+-  static int       layout_activation(methodOop method,
+-				      int temps,
+-                                      int popframe_args,
+-				      int monitors,
+-				      int callee_params,
+-				      int callee_locals,
+-				      frame* caller,
+-				      frame* interpreter_frame,
+-				      bool is_top_frame);
+-
+-  // Runtime support
+-  static bool       is_not_reached(                       methodHandle method, int bci);
+-  // Safepoint support
+-  static void       notice_safepoints();                        // stops the thread when reaching a safepoint
+-  static void       ignore_safepoints();                        // ignores safepoints
+-
+-  // Support for native calls
+-  static address    slow_signature_handler()                    { return _slow_signature_handler; }
+-  static address    result_handler(BasicType type)              { return _native_abi_to_tosca[BasicType_as_index(type)]; }
+-  static int        BasicType_as_index(BasicType type);         // computes index into result_handler_by_index table
+-  static bool       in_native_entry(address pc)                 { return _native_entry_begin <= pc && pc < _native_entry_end; }
+-  // Debugging/printing
+-  static InterpreterCodelet* codelet_containing(address pc)     { return (InterpreterCodelet*)_code->stub_containing(pc); }
+-  static void       print();                                    // prints the interpreter code
+-#ifdef CC_INTERP
+-  static address    native_result_to_tosca()                    { return (address)_native_abi_to_tosca; } // aka result handler
+-  static address    tosca_result_to_stack()                     { return (address)_tosca_to_stack; }
+-  static address    stack_result_to_stack()                     { return (address)_stack_to_stack; }
+-  static address    stack_result_to_native()                    { return (address)_stack_to_native_abi; }
+-
+-  static address    native_result_to_tosca(int index)           { return _native_abi_to_tosca[index]; } // aka result handler
+-  static address    tosca_result_to_stack(int index)            { return _tosca_to_stack[index]; }
+-  static address    stack_result_to_stack(int index)            { return _stack_to_stack[index]; }
+-  static address    stack_result_to_native(int index)           { return _stack_to_native_abi[index]; }
+-#endif /* CC_INTERP */
+-
+-  // Support for Tagged Stacks
+-  //
+-  // Tags are stored on the Java Expression stack above the value:
+-  // 
+-  //  tag   
+-  //  value
+-  //
+-  // For double values:
+-  //
+-  //  tag2  
+-  //  high word
+-  //  tag1
+-  //  low word
+-
+- public:
+-  static int stackElementWords()   { return TaggedStackInterpreter ? 2 : 1; }
+-  static int stackElementSize()    { return stackElementWords()*wordSize; }
+-  static int logStackElementSize() { return
+-                 TaggedStackInterpreter? LogBytesPerWord+1 : LogBytesPerWord; }
+-
+-  // Tag is at pointer, value is one below for a stack growing down
+-  // (or above for stack growing up)
+-  static int  value_offset_in_bytes()  {
+-    return TaggedStackInterpreter ?
+-      frame::interpreter_frame_expression_stack_direction() * wordSize : 0;
+-  }
+-  static int  tag_offset_in_bytes()    { 
+-    assert(TaggedStackInterpreter, "should not call this");
+-    return 0;
+-  }
++  { // request all space (add some slack for Codelet data)
++    assert (_clet != NULL, "we checked not enough space already");
+ 
+-  // Tagged Locals
+-  // Locals are stored relative to Llocals:
+-  //
+-  // tag    <- Llocals[n]
+-  // value
+-  //
+-  // Category 2 types are indexed as:
+-  //
+-  // tag    <- Llocals[-n]
+-  // high word
+-  // tag    <- Llocals[-n+1]
+-  // low word
+-  //
+-
+-  // Local values relative to locals[n]
+-  static int  local_offset_in_bytes(int n) {
+-    return ((frame::interpreter_frame_expression_stack_direction() * n) *
+-            stackElementSize()) + value_offset_in_bytes();
+-  }
+-  static int  local_tag_offset_in_bytes(int n) {
+-    assert(TaggedStackInterpreter, "should not call this");
+-    return ((frame::interpreter_frame_expression_stack_direction() * n) * 
+-            stackElementSize()) + tag_offset_in_bytes();
++    // initialize Codelet attributes
++    _clet->initialize(description, bytecode);
++    // create assembler for code generation
++    masm  = new InterpreterMacroAssembler(&_cb);
++    _masm = &masm;
+   }
+ 
+-};
++  ~CodeletMark() {
++    // align so printing shows nop's instead of random code at the end (Codelets are aligned)
++    (*_masm)->align(wordSize);
++    // make sure all code is in code buffer
++    (*_masm)->flush();
+ 
+ 
+-//------------------------------------------------------------------------------------------------------------------------
+-// The interpreter generator.
+-
+-class Template;
+-class AbstractInterpreterGenerator: public StackObj {
+- protected:
+-  InterpreterMacroAssembler* _masm;
+-
+-#ifndef CC_INTERP
+-  // entry points for shared code sequence
+-  address _unimplemented_bytecode;
+-  address _illegal_bytecode_sequence;
+-#endif
+-
+-  // shared code sequences
+-  // Converter for native abi result to tosca result
+-  address generate_result_handler_for(BasicType type);
+-#ifdef CC_INTERP
+-  address generate_tosca_to_stack_converter(BasicType type);
+-  address generate_stack_to_stack_converter(BasicType type);
+-  address generate_stack_to_native_abi_converter(BasicType type);
+-#endif
+-  address generate_slow_signature_handler();
+-#ifndef CC_INTERP
+-  address generate_error_exit(const char* msg);
+-  address generate_StackOverflowError_handler();
+-  address generate_exception_handler(const char* name, const char* message) {
+-    return generate_exception_handler_common(name, message, false);
++    // commit Codelet
++    AbstractInterpreter::code()->commit((*_masm)->code()->pure_code_size());
++    // make sure nobody can use _masm outside a CodeletMark lifespan
++    *_masm = NULL;
+   }
+-  address generate_klass_exception_handler(const char* name) {
+-    return generate_exception_handler_common(name, NULL, true);
+-  }
+-  address generate_exception_handler_common(const char* name, const char* message, bool pass_oop);
+-  address generate_ClassCastException_handler();
+-  address generate_ArrayIndexOutOfBounds_handler(const char* name);
+-  address generate_continuation_for(TosState state);
+-  address generate_return_entry_for(TosState state, int step);
+-  address generate_earlyret_entry_for(TosState state);
+-  address generate_deopt_entry_for(TosState state, int step);
+-  address generate_safept_entry_for(TosState state, address runtime_entry);
+-  void    generate_throw_exception();
+-#endif // CC_INTERP
+-
+-  // entry point generator
+-  address generate_method_entry(AbstractInterpreter::MethodKind kind);
+-  void    generate_fast_accessor_code(); // implements UseFastAccessorMethods
+-  
+-#ifndef CC_INTERP
+-  // Instruction generation
+-  void generate_and_dispatch (Template* t, TosState tos_out = ilgl);
+-  void set_vtos_entry_points (Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep);
+-  void set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep);
+-  void set_wide_entry_point  (Template* t, address& wep);
+-
+-  void set_entry_points(Bytecodes::Code code);
+-  void set_unimplemented(int i);
+-  void set_entry_points_for_all_bytes();
+-  void set_safepoints_for_all_bytes();
+-
+-  // Helpers for generate_and_dispatch
+-  address generate_trace_code(TosState state)   PRODUCT_RETURN0;
+-  void count_bytecode()                         PRODUCT_RETURN;  
+-  void histogram_bytecode(Template* t)          PRODUCT_RETURN;
+-  void histogram_bytecode_pair(Template* t)     PRODUCT_RETURN;
+-  void trace_bytecode(Template* t)              PRODUCT_RETURN;
+-  void stop_interpreter_at()                    PRODUCT_RETURN;
+-#endif // CC_INTERP
++};
+ 
+-  void bang_stack_shadow_pages(bool native_call);
++// Wrapper classes to produce Interpreter/InterpreterGenerator from either
++// the c++ interpreter or the template interpreter.
+ 
+-  void generate_all();
++class Interpreter: public CC_INTERP_ONLY(CppInterpreter) NOT_CC_INTERP(TemplateInterpreter) {
+ 
+  public:
+-  AbstractInterpreterGenerator(StubQueue* _code);
++  // Debugging/printing
++  static InterpreterCodelet* codelet_containing(address pc)     { return (InterpreterCodelet*)_code->stub_containing(pc); }
++#include "incls/_interpreter_pd.hpp.incl"
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)interpreterRuntime.cpp	1.487 07/05/05 17:05:38 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1077,7 +1074,7 @@
+ 	    Disassembler::decode(handler, handler + buffer.code_size());
+ #ifndef PRODUCT
+ 	    tty->print_cr(" --- associated result handler ---");
+-	    address rh_begin = AbstractInterpreter::result_handler(method()->result_type());
++            address rh_begin = Interpreter::result_handler(method()->result_type());
+ 	    address rh_end = rh_begin;
+ 	    while (*(int*)rh_end != 0) {
+ 	      rh_end += sizeof(int);
+@@ -1098,13 +1095,13 @@
+     }
+     if (handler_index < 0) {
+       // use generic signature handler
+-      method->set_signature_handler(AbstractInterpreter::slow_signature_handler());
++      method->set_signature_handler(Interpreter::slow_signature_handler());
+     } else {
+       // set handler
+       method->set_signature_handler(_handlers->at(handler_index));
+     }
+   }
+-  assert(method->signature_handler() == AbstractInterpreter::slow_signature_handler() ||
++  assert(method->signature_handler() == Interpreter::slow_signature_handler() ||
+ 	 _handlers->find(method->signature_handler()) == _fingerprints->find(Fingerprinter(method).fingerprint()),
+ 	 "sanity check");
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)interpreterRuntime.hpp	1.143 07/05/05 17:05:38 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/invocationCounter.cpp openjdk/hotspot/src/share/vm/interpreter/invocationCounter.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/invocationCounter.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/invocationCounter.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)invocationCounter.cpp	1.60 07/05/05 17:05:38 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -171,4 +168,3 @@
+ void invocationCounter_init() {
+   InvocationCounter::reinitialize(DelayCompilationDuringStartup);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/invocationCounter.hpp openjdk/hotspot/src/share/vm/interpreter/invocationCounter.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/invocationCounter.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/invocationCounter.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)invocationCounter.hpp	1.49 07/05/05 17:05:39 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -89,7 +86,6 @@
+   int    limit() const                           { return CompileThreshold; }
+   Action action() const                          { return _action[state()]; }
+   int    count() const                           { return _counter >> number_of_noncount_bits; }
+-  bool   has_overflowed() const                  { return count() >= limit(); }
+ 
+   int   get_InvocationLimit() const              { return InterpreterInvocationLimit >> number_of_noncount_bits; }
+   int   get_BackwardBranchLimit() const          { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; }
+@@ -139,5 +135,3 @@
+   if (c > 0 && new_count == 0) new_count = 1; 
+   set(state(), new_count);
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/linkResolver.cpp openjdk/hotspot/src/share/vm/interpreter/linkResolver.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/linkResolver.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/linkResolver.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)linkResolver.cpp	1.174 07/05/05 17:05:40 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1001,4 +998,3 @@
+ }
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/linkResolver.hpp openjdk/hotspot/src/share/vm/interpreter/linkResolver.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/linkResolver.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/linkResolver.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)linkResolver.hpp	1.74 07/05/05 17:05:39 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -172,4 +169,3 @@
+ 
+   static void resolve_invoke         (CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/oopMapCache.cpp openjdk/hotspot/src/share/vm/interpreter/oopMapCache.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/oopMapCache.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/oopMapCache.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)oopMapCache.cpp	1.85 08/06/19 12:45:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -535,10 +532,6 @@
+     if (!_array[i].is_empty() && _array[i].method()->is_old()) {
+       // Cache entry is occupied by an old redefined method and we don't want
+       // to pin it down so flush the entry.
+-      RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d",
+-        _array[i].method()->name()->as_C_string(),
+-        _array[i].method()->signature()->as_C_string(), i));
+-
+       _array[i].flush();
+     }
+ }
+@@ -584,15 +577,6 @@
+   // Entry is not in hashtable. 
+   // Compute entry and return it
+ 
+-  if (method->should_not_be_cached()) {
+-    // It is either not safe or not a good idea to cache this methodOop
+-    // at this time. We give the caller of lookup() a copy of the
+-    // interesting info via parameter entry_for, but we don't add it to
+-    // the cache. See the gory details in methodOop.cpp.
+-    compute_one_oop_map(method, bci, entry_for);
+-    return;
+-  }
+-
+   // First search for an empty slot
+   for(i = 0; i < _probe_depth; i++) {
+     entry  = entry_at(probe + i);
+@@ -600,6 +584,12 @@
+       entry->fill(method, bci);
+       entry_for->resource_copy(entry);
+       assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
++      if (method->is_old()) {
++        // The caller of lookup() will receive a copy of the interesting
++        // info via entry_for, but we don't keep an old redefined method in
++        // the cache to avoid pinning down the method.
++        entry->flush();
++      }
+       return; 
+     }
+   }
+@@ -633,6 +623,13 @@
+   }
+   assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
+ 
++  if (method->is_old()) {
++    // The caller of lookup() will receive a copy of the interesting
++    // info via entry_for, but we don't keep an old redefined method in
++    // the cache to avoid pinning down the method.
++    entry->flush();
++  }
++
+   return;
+ }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/oopMapCache.hpp openjdk/hotspot/src/share/vm/interpreter/oopMapCache.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/oopMapCache.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/oopMapCache.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oopMapCache.hpp	1.57 07/05/05 17:05:39 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -191,4 +188,3 @@
+   // Returns total no. of bytes allocated as part of OopMapCache's
+   static long memory_usage()                     PRODUCT_RETURN0;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/rewriter.cpp openjdk/hotspot/src/share/vm/interpreter/rewriter.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/rewriter.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/rewriter.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)rewriter.cpp	1.45 07/05/05 17:05:40 JVM"
+-#endif
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -189,7 +186,7 @@
+       // will manifest itself in an easy recognizable form.
+       address bcp = original_method->bcp_from(0);
+       *bcp = (u1)Bytecodes::_shouldnotreachhere;
+-      int kind = AbstractInterpreter::method_kind(original_method);
++      int kind = Interpreter::method_kind(original_method);
+       original_method->set_interpreter_kind(kind);
+     }
+        
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/rewriter.hpp openjdk/hotspot/src/share/vm/interpreter/rewriter.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/rewriter.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/rewriter.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)rewriter.hpp	1.20 07/05/05 17:05:40 JVM"
+-#endif
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -38,4 +35,3 @@
+  public:
+   static void rewrite(instanceKlassHandle klass, TRAPS);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/templateInterpreter.cpp openjdk/hotspot/src/share/vm/interpreter/templateInterpreter.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/templateInterpreter.cpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/templateInterpreter.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,597 @@
++/*
++ * Copyright 1997-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++#include "incls/_precompiled.incl"
++#include "incls/_templateInterpreter.cpp.incl"
++
++#ifndef CC_INTERP
++
++# define __ _masm->
++
++void TemplateInterpreter::initialize() {
++  if (_code != NULL) return;
++  // assertions
++  assert((int)Bytecodes::number_of_codes <= (int)DispatchTable::length,
++         "dispatch table too small");
++
++  AbstractInterpreter::initialize();
++
++  TemplateTable::initialize();
++
++  // generate interpreter
++  { ResourceMark rm;
++    TraceTime timer("Interpreter generation", TraceStartupTime);
++    int code_size = InterpreterCodeSize;
++    NOT_PRODUCT(code_size *= 4;)  // debug uses extra interpreter code space
++    _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
++                          "Interpreter");
++    InterpreterGenerator g(_code);
++    if (PrintInterpreter) print();
++  }
++
++  // initialize dispatch table
++  _active_table = _normal_table;
++}
++
++//------------------------------------------------------------------------------------------------------------------------
++// Implementation of EntryPoint
++
++EntryPoint::EntryPoint() {
++  assert(number_of_states == 9, "check the code below");
++  _entry[btos] = NULL;
++  _entry[ctos] = NULL;
++  _entry[stos] = NULL;
++  _entry[atos] = NULL;
++  _entry[itos] = NULL;
++  _entry[ltos] = NULL;
++  _entry[ftos] = NULL;
++  _entry[dtos] = NULL;
++  _entry[vtos] = NULL;
++}
++
++
++EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) {
++  assert(number_of_states == 9, "check the code below");
++  _entry[btos] = bentry;
++  _entry[ctos] = centry;
++  _entry[stos] = sentry;
++  _entry[atos] = aentry;
++  _entry[itos] = ientry;
++  _entry[ltos] = lentry;
++  _entry[ftos] = fentry;
++  _entry[dtos] = dentry;
++  _entry[vtos] = ventry;
++}
++
++
++void EntryPoint::set_entry(TosState state, address entry) {
++  assert(0 <= state && state < number_of_states, "state out of bounds");
++  _entry[state] = entry;
++}
++
++
++address EntryPoint::entry(TosState state) const {
++  assert(0 <= state && state < number_of_states, "state out of bounds");
++  return _entry[state];
++}
++
++
++void EntryPoint::print() {
++  tty->print("[");
++  for (int i = 0; i < number_of_states; i++) {
++    if (i > 0) tty->print(", ");
++    tty->print(INTPTR_FORMAT, _entry[i]);
++  }
++  tty->print("]");
++}
++
++
++bool EntryPoint::operator == (const EntryPoint& y) {
++  int i = number_of_states;
++  while (i-- > 0) {
++    if (_entry[i] != y._entry[i]) return false;
++  }
++  return true;
++}
++
++
++//------------------------------------------------------------------------------------------------------------------------
++// Implementation of DispatchTable
++
++EntryPoint DispatchTable::entry(int i) const {
++  assert(0 <= i && i < length, "index out of bounds");
++  return
++    EntryPoint(
++      _table[btos][i],
++      _table[ctos][i],
++      _table[stos][i],
++      _table[atos][i],
++      _table[itos][i],
++      _table[ltos][i],
++      _table[ftos][i],
++      _table[dtos][i],
++      _table[vtos][i]
++    );
++}
++
++
++void DispatchTable::set_entry(int i, EntryPoint& entry) {
++  assert(0 <= i && i < length, "index out of bounds");
++  assert(number_of_states == 9, "check the code below");
++  _table[btos][i] = entry.entry(btos);
++  _table[ctos][i] = entry.entry(ctos);
++  _table[stos][i] = entry.entry(stos);
++  _table[atos][i] = entry.entry(atos);
++  _table[itos][i] = entry.entry(itos);
++  _table[ltos][i] = entry.entry(ltos);
++  _table[ftos][i] = entry.entry(ftos);
++  _table[dtos][i] = entry.entry(dtos);
++  _table[vtos][i] = entry.entry(vtos);
++}
++
++
++bool DispatchTable::operator == (DispatchTable& y) {
++  int i = length;
++  while (i-- > 0) {
++    EntryPoint t = y.entry(i); // for compiler compatibility (BugId 4150096)
++    if (!(entry(i) == t)) return false;
++  }
++  return true;
++}
++
++address    TemplateInterpreter::_remove_activation_entry                    = NULL;
++address    TemplateInterpreter::_remove_activation_preserving_args_entry    = NULL;
++
++
++address    TemplateInterpreter::_throw_ArrayIndexOutOfBoundsException_entry = NULL;
++address    TemplateInterpreter::_throw_ArrayStoreException_entry            = NULL;
++address    TemplateInterpreter::_throw_ArithmeticException_entry            = NULL;
++address    TemplateInterpreter::_throw_ClassCastException_entry             = NULL;
++address    TemplateInterpreter::_throw_NullPointerException_entry           = NULL;
++address    TemplateInterpreter::_throw_StackOverflowError_entry             = NULL;
++address    TemplateInterpreter::_throw_exception_entry                      = NULL;
++
++#ifndef PRODUCT
++EntryPoint TemplateInterpreter::_trace_code;
++#endif // !PRODUCT
++EntryPoint TemplateInterpreter::_return_entry[TemplateInterpreter::number_of_return_entries];
++EntryPoint TemplateInterpreter::_earlyret_entry;
++EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ];
++EntryPoint TemplateInterpreter::_continuation_entry;
++EntryPoint TemplateInterpreter::_safept_entry;
++
++address    TemplateInterpreter::_return_3_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
++address    TemplateInterpreter::_return_5_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
++
++DispatchTable TemplateInterpreter::_active_table;
++DispatchTable TemplateInterpreter::_normal_table;
++DispatchTable TemplateInterpreter::_safept_table;
++address    TemplateInterpreter::_wentry_point[DispatchTable::length];
++
++TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) {
++  _unimplemented_bytecode    = NULL;
++  _illegal_bytecode_sequence = NULL;
++}
++
++static const BasicType types[Interpreter::number_of_result_handlers] = {
++  T_BOOLEAN,
++  T_CHAR   ,
++  T_BYTE   ,
++  T_SHORT  ,
++  T_INT    ,
++  T_LONG   ,
++  T_VOID   ,
++  T_FLOAT  ,
++  T_DOUBLE ,
++  T_OBJECT
++};
++
++void TemplateInterpreterGenerator::generate_all() {
++  AbstractInterpreterGenerator::generate_all();
++
++  { CodeletMark cm(_masm, "error exits");
++    _unimplemented_bytecode    = generate_error_exit("unimplemented bytecode");
++    _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified");
++  }
++
++#ifndef PRODUCT
++  if (TraceBytecodes) {
++    CodeletMark cm(_masm, "bytecode tracing support");
++    Interpreter::_trace_code =
++      EntryPoint(
++        generate_trace_code(btos),
++        generate_trace_code(ctos),
++        generate_trace_code(stos),
++        generate_trace_code(atos),
++        generate_trace_code(itos),
++        generate_trace_code(ltos),
++        generate_trace_code(ftos),
++        generate_trace_code(dtos),
++        generate_trace_code(vtos)
++      );
++  }
++#endif // !PRODUCT
++
++  { CodeletMark cm(_masm, "return entry points");
++    for (int i = 0; i < Interpreter::number_of_return_entries; i++) {
++      Interpreter::_return_entry[i] =
++        EntryPoint(
++          generate_return_entry_for(itos, i),
++          generate_return_entry_for(itos, i),
++          generate_return_entry_for(itos, i),
++          generate_return_entry_for(atos, i),
++          generate_return_entry_for(itos, i),
++          generate_return_entry_for(ltos, i),
++          generate_return_entry_for(ftos, i),
++          generate_return_entry_for(dtos, i),
++          generate_return_entry_for(vtos, i)
++        );
++    }
++  }
++
++  { CodeletMark cm(_masm, "earlyret entry points");
++    Interpreter::_earlyret_entry =
++      EntryPoint(
++        generate_earlyret_entry_for(btos),
++        generate_earlyret_entry_for(ctos),
++        generate_earlyret_entry_for(stos),
++        generate_earlyret_entry_for(atos),
++        generate_earlyret_entry_for(itos),
++        generate_earlyret_entry_for(ltos),
++        generate_earlyret_entry_for(ftos),
++        generate_earlyret_entry_for(dtos),
++        generate_earlyret_entry_for(vtos)
++      );
++  }
++
++  { CodeletMark cm(_masm, "deoptimization entry points");
++    for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) {
++      Interpreter::_deopt_entry[i] =
++        EntryPoint(
++          generate_deopt_entry_for(itos, i),
++          generate_deopt_entry_for(itos, i),
++          generate_deopt_entry_for(itos, i),
++          generate_deopt_entry_for(atos, i),
++          generate_deopt_entry_for(itos, i),
++          generate_deopt_entry_for(ltos, i),
++          generate_deopt_entry_for(ftos, i),
++          generate_deopt_entry_for(dtos, i),
++          generate_deopt_entry_for(vtos, i)
++        );
++    }
++  }
++
++  { CodeletMark cm(_masm, "result handlers for native calls");
++    // The various result converter stublets.
++    int is_generated[Interpreter::number_of_result_handlers];
++    memset(is_generated, 0, sizeof(is_generated));
++
++    for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {
++      BasicType type = types[i];
++      if (!is_generated[Interpreter::BasicType_as_index(type)]++) {
++        Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);
++      }
++    }
++  }
++
++  for (int j = 0; j < number_of_states; j++) {
++    const TosState states[] = {btos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos};
++    Interpreter::_return_3_addrs_by_index[Interpreter::TosState_as_index(states[j])] = Interpreter::return_entry(states[j], 3);
++    Interpreter::_return_5_addrs_by_index[Interpreter::TosState_as_index(states[j])] = Interpreter::return_entry(states[j], 5);
++  }
++
++  { CodeletMark cm(_masm, "continuation entry points");
++    Interpreter::_continuation_entry =
++      EntryPoint(
++        generate_continuation_for(btos),
++        generate_continuation_for(ctos),
++        generate_continuation_for(stos),
++        generate_continuation_for(atos),
++        generate_continuation_for(itos),
++        generate_continuation_for(ltos),
++        generate_continuation_for(ftos),
++        generate_continuation_for(dtos),
++        generate_continuation_for(vtos)
++      );
++  }
++
++  { CodeletMark cm(_masm, "safepoint entry points");
++    Interpreter::_safept_entry =
++      EntryPoint(
++        generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
++        generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
++        generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
++        generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
++        generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
++        generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
++        generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
++        generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
++        generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint))
++      );
++  }
++
++  { CodeletMark cm(_masm, "exception handling");
++    // (Note: this is not safepoint safe because thread may return to compiled code)
++    generate_throw_exception();
++  }
++
++  { CodeletMark cm(_masm, "throw exception entrypoints");
++    Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException");
++    Interpreter::_throw_ArrayStoreException_entry            = generate_klass_exception_handler("java/lang/ArrayStoreException"                 );
++    Interpreter::_throw_ArithmeticException_entry            = generate_exception_handler("java/lang/ArithmeticException"           , "/ by zero");
++    Interpreter::_throw_ClassCastException_entry             = generate_ClassCastException_handler();
++    Interpreter::_throw_NullPointerException_entry           = generate_exception_handler("java/lang/NullPointerException"          , NULL       );
++    Interpreter::_throw_StackOverflowError_entry             = generate_StackOverflowError_handler();
++  }
++
++
++
++#define method_entry(kind)                                                                    \
++  { CodeletMark cm(_masm, "method entry point (kind = " #kind ")");                    \
++    Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind);  \
++  }
++
++  // all non-native method kinds
++  method_entry(zerolocals)
++  method_entry(zerolocals_synchronized)
++  method_entry(empty)
++  method_entry(accessor)
++  method_entry(abstract)
++  method_entry(java_lang_math_sin  )
++  method_entry(java_lang_math_cos  )
++  method_entry(java_lang_math_tan  )
++  method_entry(java_lang_math_abs  )
++  method_entry(java_lang_math_sqrt )
++  method_entry(java_lang_math_log  )
++  method_entry(java_lang_math_log10)
++
++  // all native method kinds (must be one contiguous block)
++  Interpreter::_native_entry_begin = Interpreter::code()->code_end();
++  method_entry(native)
++  method_entry(native_synchronized)
++  Interpreter::_native_entry_end = Interpreter::code()->code_end();
++
++#undef method_entry
++
++  // Bytecodes
++  set_entry_points_for_all_bytes();
++  set_safepoints_for_all_bytes();
++}
++
++//------------------------------------------------------------------------------------------------------------------------
++
++address TemplateInterpreterGenerator::generate_error_exit(const char* msg) {
++  address entry = __ pc();
++  __ stop(msg);
++  return entry;
++}
++
++
++//------------------------------------------------------------------------------------------------------------------------
++
++void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() {
++  for (int i = 0; i < DispatchTable::length; i++) {
++    Bytecodes::Code code = (Bytecodes::Code)i;
++    if (Bytecodes::is_defined(code)) {
++      set_entry_points(code);
++    } else {
++      set_unimplemented(i);
++    }
++  }
++}
++
++
++void TemplateInterpreterGenerator::set_safepoints_for_all_bytes() {
++  for (int i = 0; i < DispatchTable::length; i++) {
++    Bytecodes::Code code = (Bytecodes::Code)i;
++    if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry);
++  }
++}
++
++
++void TemplateInterpreterGenerator::set_unimplemented(int i) {
++  address e = _unimplemented_bytecode;
++  EntryPoint entry(e, e, e, e, e, e, e, e, e);
++  Interpreter::_normal_table.set_entry(i, entry);
++  Interpreter::_wentry_point[i] = _unimplemented_bytecode;
++}
++
++
++void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) {
++  CodeletMark cm(_masm, Bytecodes::name(code), code);
++  // initialize entry points
++  assert(_unimplemented_bytecode    != NULL, "should have been generated before");
++  assert(_illegal_bytecode_sequence != NULL, "should have been generated before");
++  address bep = _illegal_bytecode_sequence;
++  address cep = _illegal_bytecode_sequence;
++  address sep = _illegal_bytecode_sequence;
++  address aep = _illegal_bytecode_sequence;
++  address iep = _illegal_bytecode_sequence;
++  address lep = _illegal_bytecode_sequence;
++  address fep = _illegal_bytecode_sequence;
++  address dep = _illegal_bytecode_sequence;
++  address vep = _unimplemented_bytecode;
++  address wep = _unimplemented_bytecode;
++  // code for short & wide version of bytecode
++  if (Bytecodes::is_defined(code)) {
++    Template* t = TemplateTable::template_for(code);
++    assert(t->is_valid(), "just checking");
++    set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);
++  }
++  if (Bytecodes::wide_is_defined(code)) {
++    Template* t = TemplateTable::template_for_wide(code);
++    assert(t->is_valid(), "just checking");
++    set_wide_entry_point(t, wep);
++  }
++  // set entry points
++  EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep);
++  Interpreter::_normal_table.set_entry(code, entry);
++  Interpreter::_wentry_point[code] = wep;
++}
++
++
++void TemplateInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) {
++  assert(t->is_valid(), "template must exist");
++  assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions")
++  wep = __ pc(); generate_and_dispatch(t);
++}
++
++
++void TemplateInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {
++  assert(t->is_valid(), "template must exist");
++  switch (t->tos_in()) {
++    case btos: vep = __ pc(); __ pop(btos); bep = __ pc(); generate_and_dispatch(t); break;
++    case ctos: vep = __ pc(); __ pop(ctos); sep = __ pc(); generate_and_dispatch(t); break;
++    case stos: vep = __ pc(); __ pop(stos); sep = __ pc(); generate_and_dispatch(t); break;
++    case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
++    case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
++    case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
++    case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;
++    case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;
++    case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);     break;
++    default  : ShouldNotReachHere();                                                 break;
++  }
++}
++
++
++//------------------------------------------------------------------------------------------------------------------------
++
++void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {
++  if (PrintBytecodeHistogram)                                    histogram_bytecode(t);
++#ifndef PRODUCT
++  // debugging code
++  if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode();
++  if (PrintBytecodePairHistogram)                                histogram_bytecode_pair(t);
++  if (TraceBytecodes)                                            trace_bytecode(t);
++  if (StopInterpreterAt > 0)                                     stop_interpreter_at();
++  __ verify_FPU(1, t->tos_in());
++#endif // !PRODUCT
++  int step;
++  if (!t->does_dispatch()) {
++    step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
++    if (tos_out == ilgl) tos_out = t->tos_out();
++    // compute bytecode size
++    assert(step > 0, "just checkin'");
++    // setup stuff for dispatching next bytecode
++    if (ProfileInterpreter && VerifyDataPointer
++        && methodDataOopDesc::bytecode_has_profile(t->bytecode())) {
++      __ verify_method_data_pointer();
++    }
++    __ dispatch_prolog(tos_out, step);
++  }
++  // generate template
++  t->generate(_masm);
++  // advance
++  if (t->does_dispatch()) {
++#ifdef ASSERT
++    // make sure execution doesn't go beyond this point if code is broken
++    __ should_not_reach_here();
++#endif // ASSERT
++  } else {
++    // dispatch to next bytecode
++    __ dispatch_epilog(tos_out, step);
++  }
++}
++
++//------------------------------------------------------------------------------------------------------------------------
++// Entry points
++
++address TemplateInterpreter::return_entry(TosState state, int length) {
++  guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length");
++  return _return_entry[length].entry(state);
++}
++
++
++address TemplateInterpreter::deopt_entry(TosState state, int length) {
++  guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length");
++  return _deopt_entry[length].entry(state);
++}
++
++//------------------------------------------------------------------------------------------------------------------------
++// Suport for invokes
++
++int TemplateInterpreter::TosState_as_index(TosState state) {
++  assert( state < number_of_states , "Invalid state in TosState_as_index");
++  assert(0 <= (int)state && (int)state < TemplateInterpreter::number_of_return_addrs, "index out of bounds");
++  return (int)state;
++}
++
++
++//------------------------------------------------------------------------------------------------------------------------
++// Safepoint suppport
++
++static inline void copy_table(address* from, address* to, int size) {
++  // Copy non-overlapping tables. The copy has to occur word wise for MT safety.
++  while (size-- > 0) *to++ = *from++;
++}
++
++void TemplateInterpreter::notice_safepoints() {
++  if (!_notice_safepoints) {
++    // switch to safepoint dispatch table
++    _notice_safepoints = true;
++    copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address));
++  }
++}
++
++// switch from the dispatch table which notices safepoints back to the
++// normal dispatch table.  So that we can notice single stepping points,
++// keep the safepoint dispatch table if we are single stepping in JVMTI.
++// Note that the should_post_single_step test is exactly as fast as the
++// JvmtiExport::_enabled test and covers both cases.
++void TemplateInterpreter::ignore_safepoints() {
++  if (_notice_safepoints) {
++    if (!JvmtiExport::should_post_single_step()) {
++      // switch to normal dispatch table
++      _notice_safepoints = false;
++      copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address));
++    }
++  }
++}
++
++// If deoptimization happens, this method returns the point where to continue in
++// interpreter. For calls (invokexxxx, newxxxx) the continuation is at next
++// bci and the top of stack is in eax/edx/FPU tos.
++// For putfield/getfield, put/getstatic, the continuation is at the same
++// bci and the TOS is on stack.
++
++// Note: deopt_entry(type, 0) means reexecute bytecode
++//       deopt_entry(type, length) means continue at next bytecode
++
++address TemplateInterpreter::continuation_for(methodOop method, address bcp, int callee_parameters, bool is_top_frame, bool& use_next_mdp) {
++  assert(method->contains(bcp), "just checkin'");
++  Bytecodes::Code code   = Bytecodes::java_code_at(bcp);
++  if (code == Bytecodes::_return) {
++      // This is used for deopt during registration of finalizers
++      // during Object.<init>.  We simply need to resume execution at
++      // the standard return vtos bytecode to pop the frame normally.
++      // reexecuting the real bytecode would cause double registration
++      // of the finalizable object.
++      assert(is_top_frame, "must be on top");
++      return _normal_table.entry(Bytecodes::_return).entry(vtos);
++  } else {
++    return AbstractInterpreter::continuation_for(method, bcp, callee_parameters, is_top_frame, use_next_mdp);
++  }
++}
++
++#endif // !CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp openjdk/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,90 @@
++/*
++ * Copyright 1997-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++// This file contains the platform-independant parts
++// of the template interpreter generator.
++
++#ifndef CC_INTERP
++
++class TemplateInterpreterGenerator: public AbstractInterpreterGenerator {
++ protected:
++
++  // entry points for shared code sequence
++  address _unimplemented_bytecode;
++  address _illegal_bytecode_sequence;
++
++  // shared code sequences
++  // Converter for native abi result to tosca result
++  address generate_result_handler_for(BasicType type);
++  address generate_slow_signature_handler();
++  address generate_error_exit(const char* msg);
++  address generate_StackOverflowError_handler();
++  address generate_exception_handler(const char* name, const char* message) {
++    return generate_exception_handler_common(name, message, false);
++  }
++  address generate_klass_exception_handler(const char* name) {
++    return generate_exception_handler_common(name, NULL, true);
++  }
++  address generate_exception_handler_common(const char* name, const char* message, bool pass_oop);
++  address generate_ClassCastException_handler();
++  address generate_ArrayIndexOutOfBounds_handler(const char* name);
++  address generate_continuation_for(TosState state);
++  address generate_return_entry_for(TosState state, int step);
++  address generate_earlyret_entry_for(TosState state);
++  address generate_deopt_entry_for(TosState state, int step);
++  address generate_safept_entry_for(TosState state, address runtime_entry);
++  void    generate_throw_exception();
++
++  // entry point generator
++//   address generate_method_entry(AbstractInterpreter::MethodKind kind);
++
++  // Instruction generation
++  void generate_and_dispatch (Template* t, TosState tos_out = ilgl);
++  void set_vtos_entry_points (Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep);
++  void set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep);
++  void set_wide_entry_point  (Template* t, address& wep);
++
++  void set_entry_points(Bytecodes::Code code);
++  void set_unimplemented(int i);
++  void set_entry_points_for_all_bytes();
++  void set_safepoints_for_all_bytes();
++
++  // Helpers for generate_and_dispatch
++  address generate_trace_code(TosState state)   PRODUCT_RETURN0;
++  void count_bytecode()                         PRODUCT_RETURN;
++  void histogram_bytecode(Template* t)          PRODUCT_RETURN;
++  void histogram_bytecode_pair(Template* t)     PRODUCT_RETURN;
++  void trace_bytecode(Template* t)              PRODUCT_RETURN;
++  void stop_interpreter_at()                    PRODUCT_RETURN;
++
++  void generate_all();
++
++ public:
++  TemplateInterpreterGenerator(StubQueue* _code);
++
++  #include "incls/_templateInterpreterGenerator_pd.hpp.incl"
++
++};
++
++#endif // !CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/templateInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/templateInterpreter.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/templateInterpreter.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/interpreter/templateInterpreter.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,177 @@
++/*
++ * Copyright 1997-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++// This file contains the platform-independant parts
++// of the template interpreter and the template interpreter generator.
++
++#ifndef CC_INTERP
++
++//------------------------------------------------------------------------------------------------------------------------
++// A little wrapper class to group tosca-specific entry points into a unit.
++// (tosca = Top-Of-Stack CAche)
++
++class EntryPoint VALUE_OBJ_CLASS_SPEC {
++ private:
++  address _entry[number_of_states];
++
++ public:
++  // Construction
++  EntryPoint();
++  EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry);
++
++  // Attributes
++  address entry(TosState state) const;                // return target address for a given tosca state
++  void    set_entry(TosState state, address entry);   // set    target address for a given tosca state
++  void    print();
++
++  // Comparison
++  bool operator == (const EntryPoint& y);             // for debugging only
++};
++
++
++//------------------------------------------------------------------------------------------------------------------------
++// A little wrapper class to group tosca-specific dispatch tables into a unit.
++
++class DispatchTable VALUE_OBJ_CLASS_SPEC {
++ public:
++  enum { length = 1 << BitsPerByte };                 // an entry point for each byte value (also for undefined bytecodes)
++
++ private:
++  address _table[number_of_states][length];           // dispatch tables, indexed by tosca and bytecode
++
++ public:
++  // Attributes
++  EntryPoint entry(int i) const;                      // return entry point for a given bytecode i
++  void       set_entry(int i, EntryPoint& entry);     // set    entry point for a given bytecode i
++  address*   table_for(TosState state)          { return _table[state]; }
++  address*   table_for()                        { return table_for((TosState)0); }
++  int        distance_from(address *table)      { return table - table_for(); }
++  int        distance_from(TosState state)      { return distance_from(table_for(state)); }
++
++  // Comparison
++  bool operator == (DispatchTable& y);                // for debugging only
++};
++
++class TemplateInterpreter: public AbstractInterpreter {
++  friend class VMStructs;
++  friend class InterpreterMacroAssembler;
++  friend class TemplateInterpreterGenerator;
++  friend class TemplateTable;
++  // friend class Interpreter;
++ public:
++
++  enum MoreConstants {
++    number_of_return_entries  = 9,                              // number of return entry points
++    number_of_deopt_entries   = 9,                              // number of deoptimization entry points
++    number_of_return_addrs    = 9                              // number of return addresses
++  };
++
++ protected:
++
++  static address    _throw_ArrayIndexOutOfBoundsException_entry;
++  static address    _throw_ArrayStoreException_entry;
++  static address    _throw_ArithmeticException_entry;
++  static address    _throw_ClassCastException_entry;
++  static address    _throw_NullPointerException_entry;
++  static address    _throw_exception_entry;
++
++  static address    _throw_StackOverflowError_entry;
++
++  static address    _remove_activation_entry;                   // continuation address if an exception is not handled by current frame
++#ifdef HOTSWAP
++  static address    _remove_activation_preserving_args_entry;   // continuation address when current frame is being popped
++#endif // HOTSWAP
++
++#ifndef PRODUCT
++  static EntryPoint _trace_code;
++#endif // !PRODUCT
++  static EntryPoint _return_entry[number_of_return_entries];    // entry points to return to from a call
++  static EntryPoint _earlyret_entry;                            // entry point to return early from a call
++  static EntryPoint _deopt_entry[number_of_deopt_entries];      // entry points to return to from a deoptimization
++  static EntryPoint _continuation_entry;
++  static EntryPoint _safept_entry;
++
++  static address    _return_3_addrs_by_index[number_of_return_addrs];     // for invokevirtual   return entries
++  static address    _return_5_addrs_by_index[number_of_return_addrs];     // for invokeinterface return entries
++
++  static DispatchTable _active_table;                           // the active    dispatch table (used by the interpreter for dispatch)
++  static DispatchTable _normal_table;                           // the normal    dispatch table (used to set the active table in normal mode)
++  static DispatchTable _safept_table;                           // the safepoint dispatch table (used to set the active table for safepoints)
++  static address       _wentry_point[DispatchTable::length];    // wide instructions only (vtos tosca always)
++
++
++ public:
++  // Initialization/debugging
++  static void       initialize();
++  // this only returns whether a pc is within generated code for the interpreter.
++  static bool       contains(address pc)                        { return _code != NULL && _code->contains(pc); }
++
++ public:
++
++  static address    remove_activation_early_entry(TosState state) { return _earlyret_entry.entry(state); }
++#ifdef HOTSWAP
++  static address    remove_activation_preserving_args_entry()   { return _remove_activation_preserving_args_entry; }
++#endif // HOTSWAP
++
++  static address    remove_activation_entry()                   { return _remove_activation_entry; }
++  static address    throw_exception_entry()                     { return _throw_exception_entry; }
++  static address    throw_ArithmeticException_entry()           { return _throw_ArithmeticException_entry; }
++  static address    throw_NullPointerException_entry()          { return _throw_NullPointerException_entry; }
++  static address    throw_StackOverflowError_entry()            { return _throw_StackOverflowError_entry; }
++
++  // Code generation
++#ifndef PRODUCT
++  static address    trace_code    (TosState state)              { return _trace_code.entry(state); }
++#endif // !PRODUCT
++  static address    continuation  (TosState state)              { return _continuation_entry.entry(state); }
++  static address*   dispatch_table(TosState state)              { return _active_table.table_for(state); }
++  static address*   dispatch_table()                            { return _active_table.table_for(); }
++  static int        distance_from_dispatch_table(TosState state){ return _active_table.distance_from(state); }
++  static address*   normal_table(TosState state)                { return _normal_table.table_for(state); }
++  static address*   normal_table()                              { return _normal_table.table_for(); }
++
++  // Support for invokes
++  static address*   return_3_addrs_by_index_table()             { return _return_3_addrs_by_index; }
++  static address*   return_5_addrs_by_index_table()             { return _return_5_addrs_by_index; }
++  static int        TosState_as_index(TosState state);          // computes index into return_3_entry_by_index table
++
++  static address    return_entry  (TosState state, int length);
++  static address    deopt_entry   (TosState state, int length);
++
++  // Safepoint support
++  static void       notice_safepoints();                        // stops the thread when reaching a safepoint
++  static void       ignore_safepoints();                        // ignores safepoints
++
++  // Deoptimization support
++  static address    continuation_for(methodOop method,
++                                     address bcp,
++                                     int callee_parameters,
++                                     bool is_top_frame,
++                                     bool& use_next_mdp);
++
++#include "incls/_templateInterpreter_pd.hpp.incl"
++
++};
++
++#endif // !CC_INTERP
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/templateTable.cpp openjdk/hotspot/src/share/vm/interpreter/templateTable.cpp
+--- openjdk6/hotspot/src/share/vm/interpreter/templateTable.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/templateTable.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)templateTable.cpp	1.108 07/05/05 17:05:37 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/templateTable.hpp openjdk/hotspot/src/share/vm/interpreter/templateTable.hpp
+--- openjdk6/hotspot/src/share/vm/interpreter/templateTable.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/interpreter/templateTable.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)templateTable.hpp	1.91 07/05/05 17:05:39 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/libadt/dict.cpp openjdk/hotspot/src/share/vm/libadt/dict.cpp
+--- openjdk6/hotspot/src/share/vm/libadt/dict.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/libadt/dict.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)dict.cpp	1.35 07/05/05 17:05:41 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -384,4 +381,3 @@
+   }
+   _key = _value = NULL;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/libadt/dict.hpp openjdk/hotspot/src/share/vm/libadt/dict.hpp
+--- openjdk6/hotspot/src/share/vm/libadt/dict.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/libadt/dict.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)dict.hpp	1.24 07/05/05 17:05:40 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -118,4 +115,3 @@
+ };
+ 
+ #endif // _DICT_
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/libadt/port.cpp openjdk/hotspot/src/share/vm/libadt/port.cpp
+--- openjdk6/hotspot/src/share/vm/libadt/port.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/libadt/port.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)port.cpp	1.21 07/05/05 17:05:41 JVM"
+-#endif
+ /*
+  * Copyright 1997-1998 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/libadt/port.hpp openjdk/hotspot/src/share/vm/libadt/port.hpp
+--- openjdk6/hotspot/src/share/vm/libadt/port.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/libadt/port.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)port.hpp	1.44 07/05/05 17:05:41 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/libadt/set.cpp openjdk/hotspot/src/share/vm/libadt/set.cpp
+--- openjdk6/hotspot/src/share/vm/libadt/set.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/libadt/set.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)set.cpp	1.26 07/05/05 17:05:41 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/libadt/set.hpp openjdk/hotspot/src/share/vm/libadt/set.hpp
+--- openjdk6/hotspot/src/share/vm/libadt/set.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/libadt/set.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)set.hpp	1.23 07/05/05 17:05:41 JVM"
+-#endif
+ /*
+  * Copyright 1997 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -252,4 +249,3 @@
+ };
+ 
+ #endif // _SET_
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/libadt/vectset.cpp openjdk/hotspot/src/share/vm/libadt/vectset.cpp
+--- openjdk6/hotspot/src/share/vm/libadt/vectset.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/libadt/vectset.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vectset.cpp	1.25 07/05/05 17:05:41 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -391,5 +388,3 @@
+   } while( i<s->size );
+   return max_juint;             // No element, iterated them all
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/libadt/vectset.hpp openjdk/hotspot/src/share/vm/libadt/vectset.hpp
+--- openjdk6/hotspot/src/share/vm/libadt/vectset.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/libadt/vectset.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vectset.hpp	1.22 07/05/05 17:05:41 JVM"
+-#endif
+ /*
+  * Copyright 1997 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -177,4 +174,3 @@
+ };
+ 
+ #endif // _VECTOR_SET_
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/allocation.cpp openjdk/hotspot/src/share/vm/memory/allocation.cpp
+--- openjdk6/hotspot/src/share/vm/memory/allocation.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/allocation.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)allocation.cpp	1.72 07/05/05 17:05:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -540,4 +537,3 @@
+ }
+ 
+ #endif // Non-product
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/allocation.hpp openjdk/hotspot/src/share/vm/memory/allocation.hpp
+--- openjdk6/hotspot/src/share/vm/memory/allocation.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/allocation.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)allocation.hpp	1.77 07/05/05 17:05:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -410,4 +407,3 @@
+   ReallocMark()   PRODUCT_RETURN;
+   void check()    PRODUCT_RETURN;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/allocation.inline.hpp openjdk/hotspot/src/share/vm/memory/allocation.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/allocation.inline.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/allocation.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)allocation.inline.hpp	1.22 07/05/05 17:05:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/allocationStats.cpp openjdk/hotspot/src/share/vm/memory/allocationStats.cpp
+--- openjdk6/hotspot/src/share/vm/memory/allocationStats.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/allocationStats.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)allocationStats.cpp	1.6 07/05/05 17:05:42 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -31,4 +28,3 @@
+ // Technically this should be derived from machine speed, and
+ // ideally it would be dynamically adjusted.
+ float AllocationStats::_threshold = ((float)CMS_SweepTimerThresholdMillis)/1000;
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/allocationStats.hpp openjdk/hotspot/src/share/vm/memory/allocationStats.hpp
+--- openjdk6/hotspot/src/share/vm/memory/allocationStats.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/allocationStats.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)allocationStats.hpp	1.19 07/05/05 17:05:41 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/barrierSet.hpp openjdk/hotspot/src/share/vm/memory/barrierSet.hpp
+--- openjdk6/hotspot/src/share/vm/memory/barrierSet.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/barrierSet.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)barrierSet.hpp	1.18 07/05/05 17:05:43 JVM"
+-#endif
+ /*
+  * Copyright 2000-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/barrierSet.inline.hpp openjdk/hotspot/src/share/vm/memory/barrierSet.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/barrierSet.inline.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/barrierSet.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)barrierSet.inline.hpp	1.12 07/05/05 17:05:43 JVM"
+-#endif
+ /*
+  * Copyright 2001-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.cpp openjdk/hotspot/src/share/vm/memory/blockOffsetTable.cpp
+--- openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/blockOffsetTable.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)blockOffsetTable.cpp	1.82 07/05/05 17:05:42 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.hpp openjdk/hotspot/src/share/vm/memory/blockOffsetTable.hpp
+--- openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/blockOffsetTable.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)blockOffsetTable.hpp	1.57 07/05/05 17:05:43 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.inline.hpp openjdk/hotspot/src/share/vm/memory/blockOffsetTable.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.inline.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/blockOffsetTable.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)blockOffsetTable.inline.hpp	1.20 07/05/05 17:05:43 JVM"
+-#endif
+ /*
+  * Copyright 2000-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/cardTableModRefBS.cpp openjdk/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
+--- openjdk6/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cardTableModRefBS.cpp	1.58 07/05/29 09:44:14 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -32,9 +29,30 @@
+ # include "incls/_precompiled.incl"
+ # include "incls/_cardTableModRefBS.cpp.incl"
+ 
++size_t CardTableModRefBS::cards_required(size_t covered_words)
++{
++  // Add one for a guard card, used to detect errors.
++  const size_t words = align_size_up(covered_words, card_size_in_words);
++  return words / card_size_in_words + 1;
++}
++
++size_t CardTableModRefBS::compute_byte_map_size()
++{
++  assert(_guard_index == cards_required(_whole_heap.word_size()) - 1,
++                                        "unitialized, check declaration order");
++  assert(_page_size != 0, "unitialized, check declaration order");
++  const size_t granularity = os::vm_allocation_granularity();
++  return align_size_up(_guard_index + 1, MAX2(_page_size, granularity));
++}
++
+ CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap,
+-				     int max_covered_regions) :
+-  ModRefBarrierSet(max_covered_regions), _whole_heap(whole_heap)
++                                     int max_covered_regions):
++  ModRefBarrierSet(max_covered_regions),
++  _whole_heap(whole_heap),
++  _guard_index(cards_required(whole_heap.word_size()) - 1),
++  _last_valid_index(_guard_index - 1),
++  _page_size(os::page_size_for_region(_guard_index + 1, _guard_index + 1, 1)),
++  _byte_map_size(compute_byte_map_size())
+ {
+   _kind = BarrierSet::CardTableModRef;
+ 
+@@ -43,14 +61,7 @@
+   assert((uintptr_t(low_bound)  & (card_size - 1))  == 0, "heap must start at card boundary");
+   assert((uintptr_t(high_bound) & (card_size - 1))  == 0, "heap must end at card boundary");
+ 
+-  assert(card_size <= 512, "card_size must be less than 512");
+-  size_t heap_size_in_words = _whole_heap.word_size();
+-  // Add one for the last_card, treated as a guard card
+-  _byte_map_size = ReservedSpace::allocation_align_size_up((heap_size_in_words / 
+-                                                      card_size_in_words) + 1);
+-  // A couple of useful indicies
+-  _guard_index      = _byte_map_size - 1;
+-  _last_valid_index = _byte_map_size - 2;
++  assert(card_size <= 512, "card_size must be less than 512"); // why?
+ 
+   _covered   = new MemRegion[max_covered_regions];
+   _committed = new MemRegion[max_covered_regions];
+@@ -63,10 +74,16 @@
+   }
+   _cur_covered_regions = 0;
+ 
+-  ReservedSpace heap_rs(_byte_map_size);
++  const size_t rs_align = _page_size == (size_t) os::vm_page_size() ? 0 :
++    MAX2(_page_size, (size_t) os::vm_allocation_granularity());
++  ReservedSpace heap_rs(_byte_map_size, rs_align, false);
++  os::trace_page_sizes("card table", _guard_index + 1, _guard_index + 1,
++                       _page_size, heap_rs.base(), heap_rs.size());
+   if (!heap_rs.is_reserved()) {
+-    vm_exit_during_initialization("Could not reserve enough space for card marking array");
++    vm_exit_during_initialization("Could not reserve enough space for the "
++                                  "card marking array");
+   }
++
+   // The assember store_check code will do an unsigned shift of the oop, 
+   // then add it to byte_map_base, i.e.
+   // 
+@@ -77,11 +94,11 @@
+   assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map");
+ 
+   jbyte* guard_card = &_byte_map[_guard_index];
+-  uintptr_t guard_page = align_size_down((uintptr_t)guard_card, os::vm_page_size());
+-  _guard_region = MemRegion((HeapWord*)guard_page, os::vm_page_size());
+-  if (!os::commit_memory((char*)guard_page, os::vm_page_size())) {
++  uintptr_t guard_page = align_size_down((uintptr_t)guard_card, _page_size);
++  _guard_region = MemRegion((HeapWord*)guard_page, _page_size);
++  if (!os::commit_memory((char*)guard_page, _page_size, _page_size)) {
+     // Do better than this for Merlin
+-    vm_exit_out_of_memory(os::vm_page_size(), "card table last card");
++    vm_exit_out_of_memory(_page_size, "card table last card");
+   }
+   *guard_card = last_card;
+ 
+@@ -136,8 +153,7 @@
+   _covered[res].set_start(base);
+   _covered[res].set_word_size(0);
+   jbyte* ct_start = byte_for(base);
+-  uintptr_t ct_start_aligned =
+-    align_size_down((uintptr_t)ct_start, os::vm_page_size());
++  uintptr_t ct_start_aligned = align_size_down((uintptr_t)ct_start, _page_size);
+   _committed[res].set_start((HeapWord*)ct_start_aligned);
+   _committed[res].set_word_size(0);
+   return res;
+@@ -196,7 +212,7 @@
+     // Align the end up to a page size (starts are already aligned).
+     jbyte* new_end = byte_after(new_region.last());
+     HeapWord* new_end_aligned =
+-      (HeapWord*)align_size_up((uintptr_t)new_end, os::vm_page_size());
++      (HeapWord*)align_size_up((uintptr_t)new_end, _page_size);
+     assert(new_end_aligned >= (HeapWord*) new_end,
+            "align up, but less");
+     // The guard page is always committed and should not be committed over.
+@@ -208,7 +224,7 @@
+ 
+       assert(!new_committed.is_empty(), "Region should not be empty here");
+       if (!os::commit_memory((char*)new_committed.start(),
+-	                     new_committed.byte_size())) {
++                             new_committed.byte_size(), _page_size)) {
+         // Do better than this for Merlin
+         vm_exit_out_of_memory(new_committed.byte_size(),
+ 	        "card table expansion");
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/cardTableModRefBS.hpp openjdk/hotspot/src/share/vm/memory/cardTableModRefBS.hpp
+--- openjdk6/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cardTableModRefBS.hpp	1.51 07/05/29 09:44:14 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -43,9 +40,7 @@
+ 
+ class CardTableModRefBS: public ModRefBarrierSet {
+   // Some classes get to look at some private stuff.
+-#ifdef CC_INTERP
+-  friend class cInterpreter;
+-#endif
++  friend class BytecodeInterpreter;
+   friend class VMStructs;
+   friend class CardTableRS;
+   friend class CheckForUnmarkedOops; // Needs access to raw card bytes.
+@@ -81,16 +76,16 @@
+     return card_is_dirty_wrt_gen_iter(cv);
+   }
+ 
+-  // The region that the card table can cover.
+-  MemRegion    _whole_heap;
+-
++  // The declaration order of these const fields is important; see the
++  // constructor before changing.
++  const MemRegion _whole_heap;       // the region covered by the card table
++  const size_t    _guard_index;      // index of very last element in the card
++                                     // table; it is set to a guard value
++                                     // (last_card) and should never be modified
++  const size_t    _last_valid_index; // index of the last valid element
++  const size_t    _page_size;        // page size used when mapping _byte_map
++  const size_t    _byte_map_size;    // in bytes
+   jbyte*       _byte_map;      // the card marking array
+-  size_t       _byte_map_size;  // In bytes.
+-
+-  size_t       _last_valid_index;  // index of last valid element in card table
+-  size_t       _guard_index;       // index of very last element in card table;
+-                                   //  it is set to a guard value "last_card" and 
+-                                   // should never be modified
+ 
+   int _cur_covered_regions;
+   // The covered regions should be in address order.
+@@ -108,6 +103,12 @@
+   // uncommit the MemRegion for that page.
+   MemRegion _guard_region;
+ 
++ protected:
++  // Initialization utilities; covered_words is the size of the covered region
++  // in, um, words.
++  inline size_t cards_required(size_t covered_words);
++  inline size_t compute_byte_map_size();
++
+   // Finds and return the index of the region, if any, to which the given
+   // region would be contiguous.  If none exists, assign a new region and
+   // returns its index.  Requires that no more than the maximum number of
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/cardTableRS.cpp openjdk/hotspot/src/share/vm/memory/cardTableRS.cpp
+--- openjdk6/hotspot/src/share/vm/memory/cardTableRS.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/cardTableRS.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cardTableRS.cpp	1.45 07/05/25 12:54:50 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/cardTableRS.hpp openjdk/hotspot/src/share/vm/memory/cardTableRS.hpp
+--- openjdk6/hotspot/src/share/vm/memory/cardTableRS.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/cardTableRS.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cardTableRS.hpp	1.29 07/05/05 17:05:44 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/classify.cpp openjdk/hotspot/src/share/vm/memory/classify.cpp
+--- openjdk6/hotspot/src/share/vm/memory/classify.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/classify.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)classify.cpp	1.9 07/05/05 17:05:44 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/classify.hpp openjdk/hotspot/src/share/vm/memory/classify.hpp
+--- openjdk6/hotspot/src/share/vm/memory/classify.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/classify.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)classify.hpp	1.10 07/05/05 17:05:42 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/collectorPolicy.cpp openjdk/hotspot/src/share/vm/memory/collectorPolicy.cpp
+--- openjdk6/hotspot/src/share/vm/memory/collectorPolicy.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/collectorPolicy.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)collectorPolicy.cpp	1.89 07/06/12 09:41:19 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -149,7 +146,12 @@
+   // byte entry and the os page size is 4096, the maximum heap size should
+   // be 512*4096 = 2MB aligned.
+   size_t alignment = GenRemSet::max_alignment_constraint(rem_set_name());
+-  if (UseLargePages) {
++
++  // Parallel GC does its own alignment of the generations to avoid requiring a
++  // large page (256M on some platforms) for the permanent generation.  The
++  // other collectors should also be updated to do their own alignment and then
++  // this use of lcm() should be removed.
++  if (UseLargePages && !UseParallelGC) {
+       // in presence of large pages we have to make sure that our 
+       // alignment is large page aware 
+       alignment = lcm(os::large_page_size(), alignment);
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/collectorPolicy.hpp openjdk/hotspot/src/share/vm/memory/collectorPolicy.hpp
+--- openjdk6/hotspot/src/share/vm/memory/collectorPolicy.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/collectorPolicy.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)collectorPolicy.hpp	1.41 07/05/29 09:44:14 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -262,4 +259,3 @@
+ 
+   void initialize_gc_policy_counters();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/compactingPermGenGen.cpp openjdk/hotspot/src/share/vm/memory/compactingPermGenGen.cpp
+--- openjdk6/hotspot/src/share/vm/memory/compactingPermGenGen.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/compactingPermGenGen.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compactingPermGenGen.cpp	1.21 08/06/19 10:32:37 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,27 +26,9 @@
+ #include "incls/_compactingPermGenGen.cpp.incl"
+ 
+ 
+-// An ObjectClosure helper: Recursively adjust all pointers in an object
+-// and all objects by referenced it. Clear marks on objects in order to
+-// prevent visiting any object twice. This helper is used when the
+-// RedefineClasses() API has been called.
+-
+-class AdjustSharedObjectClosure : public ObjectClosure {
+-public:
+-  void do_object(oop obj) {
+-    if (obj->is_shared_readwrite()) {
+-      if (obj->mark()->is_marked()) {
+-        obj->init_mark();         // Don't revisit this object.
+-        obj->adjust_pointers();   // Adjust this object's references.
+-      }
+-    }
+-  }
+-};
+-
+-
+-// An OopClosure helper: Recursively adjust all pointers in an object
+-// and all objects by referenced it. Clear marks on objects in order
+-// to prevent visiting any object twice.
++// Recursively adjust all pointers in an object and all objects by
++// referenced it.  Clear marks on objects in order to prevent visiting
++// any object twice.
+ 
+ class RecursiveAdjustSharedObjectClosure : public OopClosure {
+ public:
+@@ -295,27 +274,9 @@
+ // objects in the space will page in more objects than we need.
+ // Instead, use the system dictionary as strong roots into the read
+ // write space.
+-//
+-// If a RedefineClasses() call has been made, then we have to iterate
+-// over the entire shared read-write space in order to find all the
+-// objects that need to be forwarded. For example, it is possible for
+-// an nmethod to be found and marked in GC phase-1 only for the nmethod
+-// to be freed by the time we reach GC phase-3. The underlying method
+-// is still marked, but we can't (easily) find it in GC phase-3 so we
+-// blow up in GC phase-4. With RedefineClasses() we want replaced code
+-// (EMCP or obsolete) to go away (i.e., be collectible) once it is no
+-// longer being executed by any thread so we keep minimal attachments
+-// to the replaced code. However, we can't guarantee when those EMCP
+-// or obsolete methods will be collected so they may still be out there
+-// even after we've severed our minimal attachments.
+ 
+ void CompactingPermGenGen::pre_adjust_pointers() {
+   if (spec()->enable_shared_spaces()) {
+-    if (JvmtiExport::has_redefined_a_class()) {
+-      // RedefineClasses() requires a brute force approach
+-      AdjustSharedObjectClosure blk;
+-      rw_space()->object_iterate(&blk);
+-    } else {
+       RecursiveAdjustSharedObjectClosure blk;
+       Universe::oops_do(&blk);
+       StringTable::oops_do(&blk);
+@@ -323,7 +284,6 @@
+       TraversePlaceholdersClosure tpc;
+       SystemDictionary::placeholders_do(&tpc);
+     }
+-  }
+ }
+ 
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/compactingPermGenGen.hpp openjdk/hotspot/src/share/vm/memory/compactingPermGenGen.hpp
+--- openjdk6/hotspot/src/share/vm/memory/compactingPermGenGen.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/compactingPermGenGen.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compactingPermGenGen.hpp	1.20 07/05/05 17:05:45 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -172,8 +169,7 @@
+    } 
+ 
+   inline bool is_in(const void* p) const {
+-    if (!is_in_unshared(p) && !is_in_shared(p)) return false;
+-    return true;
++    return is_in_unshared(p) || is_in_shared(p);
+   }
+ 
+   inline PermanentGenerationSpec* spec() const { return _spec; }
+@@ -237,7 +233,7 @@
+   void verify(bool allow_dirty);
+ 
+   // Serialization
+-  static void initialize_oops();
++  static void initialize_oops() KERNEL_RETURN;
+   static void serialize_oops(SerializeOopClosure* soc);
+   void serialize_bts(SerializeOopClosure* soc);
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/compactPermGen.hpp openjdk/hotspot/src/share/vm/memory/compactPermGen.hpp
+--- openjdk6/hotspot/src/share/vm/memory/compactPermGen.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/compactPermGen.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compactPermGen.hpp	1.17 07/05/05 17:05:45 JVM"
+-#endif
+ /*
+  * Copyright 2000-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/defNewGeneration.cpp openjdk/hotspot/src/share/vm/memory/defNewGeneration.cpp
+--- openjdk6/hotspot/src/share/vm/memory/defNewGeneration.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/defNewGeneration.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)defNewGeneration.cpp	1.73 07/05/22 17:24:57 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/defNewGeneration.hpp openjdk/hotspot/src/share/vm/memory/defNewGeneration.hpp
+--- openjdk6/hotspot/src/share/vm/memory/defNewGeneration.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/defNewGeneration.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)defNewGeneration.hpp	1.40 07/05/17 15:54:44 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp openjdk/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)defNewGeneration.inline.hpp	1.18 07/05/05 17:05:46 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/dump.cpp openjdk/hotspot/src/share/vm/memory/dump.cpp
+--- openjdk6/hotspot/src/share/vm/memory/dump.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/dump.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)dump.cpp	1.33 07/05/23 10:53:38 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/filemap.cpp openjdk/hotspot/src/share/vm/memory/filemap.cpp
+--- openjdk6/hotspot/src/share/vm/memory/filemap.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/filemap.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)filemap.cpp	1.25 07/05/05 17:05:41 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/filemap.hpp openjdk/hotspot/src/share/vm/memory/filemap.hpp
+--- openjdk6/hotspot/src/share/vm/memory/filemap.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/filemap.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)filemap.hpp	1.16 07/05/05 17:05:47 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/gcLocker.cpp openjdk/hotspot/src/share/vm/memory/gcLocker.cpp
+--- openjdk6/hotspot/src/share/vm/memory/gcLocker.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/gcLocker.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gcLocker.cpp	1.52 07/05/17 15:54:45 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/gcLocker.hpp openjdk/hotspot/src/share/vm/memory/gcLocker.hpp
+--- openjdk6/hotspot/src/share/vm/memory/gcLocker.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/gcLocker.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)gcLocker.hpp	1.60 07/05/17 15:54:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -286,4 +283,3 @@
+   ~No_Alloc_Verifier() {}
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/gcLocker.inline.hpp openjdk/hotspot/src/share/vm/memory/gcLocker.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/gcLocker.inline.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/gcLocker.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)gcLocker.inline.hpp	1.21 07/05/05 17:05:49 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -73,4 +70,3 @@
+     }
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/genCollectedHeap.cpp openjdk/hotspot/src/share/vm/memory/genCollectedHeap.cpp
+--- openjdk6/hotspot/src/share/vm/memory/genCollectedHeap.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/genCollectedHeap.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)genCollectedHeap.cpp	1.189 07/06/12 09:41:51 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -565,11 +562,16 @@
+       }
+     }
+ 
++    // Update "complete" boolean wrt what actually transpired --
++    // for instance, a promotion failure could have led to
++    // a whole heap collection.
++    complete = complete || (max_level_collected == n_gens() - 1);
++
+     if (PrintGCDetails) {
+       print_heap_change(gch_prev_used);
+         
+       // Print perm gen info for full GC with PrintGCDetails flag.
+-      if (full && max_level == n_gens() - 1) {
++      if (complete) {
+         print_perm_heap_change(perm_prev_used);
+       }
+     }
+@@ -578,6 +580,7 @@
+       // Adjust generation sizes.
+       _gens[j]->compute_new_size();
+     }
++
+     if (complete) {
+       // Ask the permanent generation to adjust size for full collections
+       perm()->compute_new_size();
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/genCollectedHeap.hpp openjdk/hotspot/src/share/vm/memory/genCollectedHeap.hpp
+--- openjdk6/hotspot/src/share/vm/memory/genCollectedHeap.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/genCollectedHeap.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)genCollectedHeap.hpp	1.104 07/05/29 09:44:15 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -41,6 +38,7 @@
+   friend class VM_GenCollectFull;
+   friend class VM_GenCollectFullConcurrent;
+   friend class VM_GC_HeapInspection;
++  friend class VM_HeapDumper;
+   friend class HeapInspection;
+   friend class GCCauseSetter;
+   friend class VMStructs;
+@@ -489,5 +487,5 @@
+   virtual void gc_epilogue(bool full);
+   
+ public:
+-  virtual void preload_and_dump(TRAPS);
++  virtual void preload_and_dump(TRAPS) KERNEL_RETURN;
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/generation.cpp openjdk/hotspot/src/share/vm/memory/generation.cpp
+--- openjdk6/hotspot/src/share/vm/memory/generation.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/generation.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)generation.cpp	1.245 07/05/05 17:05:51 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/generation.hpp openjdk/hotspot/src/share/vm/memory/generation.hpp
+--- openjdk6/hotspot/src/share/vm/memory/generation.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/generation.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)generation.hpp	1.195 07/05/17 15:55:02 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/generation.inline.hpp openjdk/hotspot/src/share/vm/memory/generation.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/generation.inline.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/generation.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)generation.inline.hpp	1.38 07/05/05 17:05:50 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/generationSpec.cpp openjdk/hotspot/src/share/vm/memory/generationSpec.cpp
+--- openjdk6/hotspot/src/share/vm/memory/generationSpec.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/generationSpec.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)generationSpec.cpp	1.29 07/05/29 09:44:15 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/generationSpec.hpp openjdk/hotspot/src/share/vm/memory/generationSpec.hpp
+--- openjdk6/hotspot/src/share/vm/memory/generationSpec.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/generationSpec.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)generationSpec.hpp	1.17 07/05/05 17:05:50 JVM"
+-#endif
+ /*
+  * Copyright 2001-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/genMarkSweep.cpp openjdk/hotspot/src/share/vm/memory/genMarkSweep.cpp
+--- openjdk6/hotspot/src/share/vm/memory/genMarkSweep.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/genMarkSweep.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)genMarkSweep.cpp	1.40 07/05/17 15:54:55 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/genMarkSweep.hpp openjdk/hotspot/src/share/vm/memory/genMarkSweep.hpp
+--- openjdk6/hotspot/src/share/vm/memory/genMarkSweep.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/genMarkSweep.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)genMarkSweep.hpp	1.11 07/05/05 17:05:49 JVM"
+-#endif
+ /*
+  * Copyright 2001-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/genOopClosures.hpp openjdk/hotspot/src/share/vm/memory/genOopClosures.hpp
+--- openjdk6/hotspot/src/share/vm/memory/genOopClosures.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/genOopClosures.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)genOopClosures.hpp	1.64 07/05/29 09:44:15 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/genOopClosures.inline.hpp openjdk/hotspot/src/share/vm/memory/genOopClosures.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/genOopClosures.inline.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/genOopClosures.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)genOopClosures.inline.hpp	1.40 07/05/29 09:44:15 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/genRemSet.cpp openjdk/hotspot/src/share/vm/memory/genRemSet.cpp
+--- openjdk6/hotspot/src/share/vm/memory/genRemSet.cpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/genRemSet.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)genRemSet.cpp	1.11 07/05/05 17:05:50 JVM"
+-#endif
+ /*
+  * Copyright 2001-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/genRemSet.hpp openjdk/hotspot/src/share/vm/memory/genRemSet.hpp
+--- openjdk6/hotspot/src/share/vm/memory/genRemSet.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/genRemSet.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)genRemSet.hpp	1.23 07/05/05 17:05:50 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/genRemSet.inline.hpp openjdk/hotspot/src/share/vm/memory/genRemSet.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/genRemSet.inline.hpp	2008-08-28 10:23:11.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/genRemSet.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)genRemSet.inline.hpp	1.10 07/05/05 17:05:50 JVM"
+-#endif
+ /*
+  * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/heap.cpp openjdk/hotspot/src/share/vm/memory/heap.cpp
+--- openjdk6/hotspot/src/share/vm/memory/heap.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/heap.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)heap.cpp	1.54 07/05/05 17:05:46 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -95,27 +92,37 @@
+ }
+ 
+ 
+-bool CodeHeap::reserve(size_t reserved_size, size_t committed_size, size_t segment_size) {
++bool CodeHeap::reserve(size_t reserved_size, size_t committed_size,
++                       size_t segment_size) {
++  assert(reserved_size >= committed_size, "reserved < committed");
+   assert(segment_size >= sizeof(FreeBlock), "segment size is too small");
+   assert(is_power_of_2(segment_size), "segment_size must be a power of 2");
++
+   _segment_size      = segment_size;
+   _log2_segment_size = exact_log2(segment_size);
+-  // reserve space for _memory
+-  assert(reserved_size >= committed_size, "reserved size must be >= committed size");
+-  if (!_memory.initialize(
+-        ReservedSpace(align_to_allocation_size(reserved_size),
+-                      // On Solaris using MPSS only, try for large
+-                      // page allocation of the code cache
+-                      SOLARIS_ONLY(UseMPSS ? os::large_page_size() : 0) NOT_SOLARIS(0),
+-                      SOLARIS_ONLY(UseMPSS)                             NOT_SOLARIS(false),
+-                      NULL),
+-        align_to_allocation_size(committed_size))) {
++
++  // Reserve and initialize space for _memory.
++  const size_t page_size = os::page_size_for_region(committed_size,
++                                                    reserved_size, 8);
++  const size_t granularity = os::vm_allocation_granularity();
++  const size_t r_align = MAX2(page_size, granularity);
++  const size_t r_size = align_size_up(reserved_size, r_align);
++  const size_t c_size = align_size_up(committed_size, page_size);
++
++  const size_t rs_align = page_size == (size_t) os::vm_page_size() ? 0 :
++    MAX2(page_size, granularity);
++  ReservedSpace rs(r_size, rs_align, false);
++  os::trace_page_sizes("code heap", committed_size, reserved_size, page_size,
++                       rs.base(), rs.size());
++  if (!_memory.initialize(rs, c_size)) {
+     return false;
+   }
++
+   on_code_mapping(_memory.low(), _memory.committed_size());
+   _number_of_committed_segments = number_of_segments(_memory.committed_size());
+   _number_of_reserved_segments  = number_of_segments(_memory.reserved_size());
+   assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking");
++
+   // reserve space for _segmap
+   if (!_segmap.initialize(align_to_page_size(_number_of_reserved_segments), align_to_page_size(_number_of_committed_segments))) {
+     return false;  
+@@ -123,6 +130,7 @@
+   assert(_segmap.committed_size() >= (size_t) _number_of_committed_segments, "could not commit  enough space for segment map");
+   assert(_segmap.reserved_size()  >= (size_t) _number_of_reserved_segments , "could not reserve enough space for segment map");
+   assert(_segmap.reserved_size()  >= _segmap.committed_size()     , "just checking");
++
+   // initialize remaining instance variables
+   clear();
+   return true;
+@@ -472,4 +480,3 @@
+   }
+   guarantee(count == 0, "missing free blocks");  
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/heap.hpp openjdk/hotspot/src/share/vm/memory/heap.hpp
+--- openjdk6/hotspot/src/share/vm/memory/heap.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/heap.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)heap.hpp	1.43 07/05/05 17:05:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/heapInspection.cpp openjdk/hotspot/src/share/vm/memory/heapInspection.cpp
+--- openjdk6/hotspot/src/share/vm/memory/heapInspection.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/heapInspection.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)heapInspection.cpp	1.21 07/05/29 09:44:16 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/heapInspection.hpp openjdk/hotspot/src/share/vm/memory/heapInspection.hpp
+--- openjdk6/hotspot/src/share/vm/memory/heapInspection.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/heapInspection.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)heapInspection.hpp	1.15 07/05/05 17:05:51 JVM"
+-#endif
+ /*
+  * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -25,6 +22,9 @@
+  *  
+  */
+ 
++#ifndef SERVICES_KERNEL
++
++
+ // HeapInspection
+ 
+ // KlassInfoTable is a bucket hash table that
+@@ -122,8 +122,10 @@
+   void sort();
+ };
+ 
++#endif // SERVICES_KERNEL
++
+ class HeapInspection : public AllStatic {
+  public:
+-  static void heap_inspection(outputStream* st);             
+-  static void find_instances_at_safepoint(klassOop k, GrowableArray<oop>* result);
++  static void heap_inspection(outputStream* st) KERNEL_RETURN;
++  static void find_instances_at_safepoint(klassOop k, GrowableArray<oop>* result) KERNEL_RETURN;
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/iterator.cpp openjdk/hotspot/src/share/vm/memory/iterator.cpp
+--- openjdk6/hotspot/src/share/vm/memory/iterator.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/iterator.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)iterator.cpp	1.18 07/05/05 17:05:50 JVM"
+-#endif
+ /*
+  * Copyright 1997-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -35,4 +32,3 @@
+ void VoidClosure::do_void() {
+   ShouldNotCallThis();
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/iterator.hpp openjdk/hotspot/src/share/vm/memory/iterator.hpp
+--- openjdk6/hotspot/src/share/vm/memory/iterator.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/iterator.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)iterator.hpp	1.38 07/05/05 17:05:52 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/memRegion.cpp openjdk/hotspot/src/share/vm/memory/memRegion.cpp
+--- openjdk6/hotspot/src/share/vm/memory/memRegion.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/memRegion.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)memRegion.cpp	1.23 07/05/05 17:05:52 JVM"
+-#endif
+ /*
+  * Copyright 2000-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/memRegion.hpp openjdk/hotspot/src/share/vm/memory/memRegion.hpp
+--- openjdk6/hotspot/src/share/vm/memory/memRegion.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/memRegion.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)memRegion.hpp	1.27 07/05/05 17:05:53 JVM"
+-#endif
+ /*
+  * Copyright 2000-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/modRefBarrierSet.hpp openjdk/hotspot/src/share/vm/memory/modRefBarrierSet.hpp
+--- openjdk6/hotspot/src/share/vm/memory/modRefBarrierSet.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/modRefBarrierSet.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)modRefBarrierSet.hpp	1.16 07/05/05 17:05:53 JVM"
+-#endif
+ /*
+  * Copyright 2000-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/oopFactory.cpp openjdk/hotspot/src/share/vm/memory/oopFactory.cpp
+--- openjdk6/hotspot/src/share/vm/memory/oopFactory.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/oopFactory.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)oopFactory.cpp	1.83 07/05/05 17:05:53 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -146,4 +143,3 @@
+   c->set_holder_klass(klass());
+   return c;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/oopFactory.hpp openjdk/hotspot/src/share/vm/memory/oopFactory.hpp
+--- openjdk6/hotspot/src/share/vm/memory/oopFactory.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/oopFactory.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oopFactory.hpp	1.61 07/05/05 17:05:53 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/permGen.cpp openjdk/hotspot/src/share/vm/memory/permGen.cpp
+--- openjdk6/hotspot/src/share/vm/memory/permGen.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/permGen.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)permGen.cpp	1.54 07/05/29 09:44:16 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/permGen.hpp openjdk/hotspot/src/share/vm/memory/permGen.hpp
+--- openjdk6/hotspot/src/share/vm/memory/permGen.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/permGen.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)permGen.hpp	1.38 07/05/29 09:44:16 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -74,4 +71,3 @@
+     g->update_counters();
+   }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/referencePolicy.cpp openjdk/hotspot/src/share/vm/memory/referencePolicy.cpp
+--- openjdk6/hotspot/src/share/vm/memory/referencePolicy.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/referencePolicy.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)referencePolicy.cpp	1.12 07/05/05 17:05:54 JVM"
+-#endif
+ /*
+  * Copyright 2000-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -71,4 +68,3 @@
+ 
+   return true;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/referencePolicy.hpp openjdk/hotspot/src/share/vm/memory/referencePolicy.hpp
+--- openjdk6/hotspot/src/share/vm/memory/referencePolicy.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/referencePolicy.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)referencePolicy.hpp	1.11 07/05/05 17:05:54 JVM"
+-#endif
+ /*
+  * Copyright 2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/referenceProcessor.cpp openjdk/hotspot/src/share/vm/memory/referenceProcessor.cpp
+--- openjdk6/hotspot/src/share/vm/memory/referenceProcessor.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/referenceProcessor.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)referenceProcessor.cpp	1.55 07/05/17 15:55:08 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -404,7 +401,11 @@
+   inline bool is_referent_alive() const;
+   
+   // Loads data for the current reference.
+-  inline void load_ptrs();
++  // The "allow_null_referent" argument tells us to allow for the possibility
++  // of a NULL referent in the discovered Reference object. This typically
++  // happens in the case of concurrent collectors that may have done the
++  // discovery concurrently or interleaved with mutator execution.
++  inline void load_ptrs(DEBUG_ONLY(bool allow_null_referent));
+   
+   // Move to the next discovered reference.
+   inline void next();
+@@ -475,7 +476,7 @@
+   return _is_alive->do_object_b(_referent);
+ }
+ 
+-inline void DiscoveredListIterator::load_ptrs()
++inline void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent))
+ {
+   _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
+   assert(_discovered_addr && (*_discovered_addr)->is_oop_or_null(),
+@@ -485,7 +486,10 @@
+   _referent = *_referent_addr;
+   assert(Universe::heap()->is_in_reserved_or_null(_referent),
+          "Wrong oop found in java.lang.Reference object");
+-  assert(_referent->is_oop(), "bad referent");
++  assert(allow_null_referent ?
++             _referent->is_oop_or_null()
++           : _referent->is_oop(),
++         "bad referent");
+ }
+ 
+ inline void DiscoveredListIterator::next()
+@@ -536,8 +540,8 @@
+   DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive);
+   // Decide which softly reachable refs should be kept alive.
+   while (iter.has_next()) {
+-    iter.load_ptrs();
+-    bool referent_is_dead = !iter.is_referent_alive();
++    iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));
++    bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive();
+     if (referent_is_dead && !policy->should_clear_reference(iter.obj())) {
+       if (TraceReferenceGC) {
+         gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",  
+@@ -573,7 +577,7 @@
+   assert(discovery_is_atomic(), "Error");
+   DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive);
+   while (iter.has_next()) {
+-    iter.load_ptrs();
++    iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
+     DEBUG_ONLY(oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj());)
+     assert(*next_addr == NULL, "Should not discover inactive Reference");
+     if (iter.is_referent_alive()) {
+@@ -610,7 +614,7 @@
+   assert(!discovery_is_atomic(), "Error");
+   DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive);
+   while (iter.has_next()) {
+-    iter.load_ptrs();
++    iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
+     oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
+     if ((iter.referent() == NULL || iter.is_referent_alive() ||
+          *next_addr != NULL)) {
+@@ -646,7 +650,7 @@
+   DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive);
+   while (iter.has_next()) {
+     iter.update_discovered();
+-    iter.load_ptrs();
++    iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
+     if (clear_referent) {
+       // NULL out referent pointer
+       iter.clear_referent();
+@@ -870,7 +874,7 @@
+   DiscoveredListIterator iter(refs_list, NULL, NULL);
+   size_t length = refs_list.length();
+   while (iter.has_next()) {
+-    iter.load_ptrs();
++    iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
+     oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
+     assert((*next_addr)->is_oop_or_null(), "bad next field");
+     // If referent has been cleared or Reference is not active,
+@@ -1184,7 +1188,7 @@
+   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
+   size_t length = refs_list.length();
+   while (iter.has_next()) {
+-    iter.load_ptrs();
++    iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
+     oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
+     if (iter.referent() == NULL || iter.is_referent_alive() || 
+         *next_addr != NULL) {
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/referenceProcessor.hpp openjdk/hotspot/src/share/vm/memory/referenceProcessor.hpp
+--- openjdk6/hotspot/src/share/vm/memory/referenceProcessor.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/referenceProcessor.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)referenceProcessor.hpp	1.43 07/05/05 17:05:54 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -500,4 +497,3 @@
+   oop                 _sentinel_ref; 
+   int                 _n_queues;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/resourceArea.cpp openjdk/hotspot/src/share/vm/memory/resourceArea.cpp
+--- openjdk6/hotspot/src/share/vm/memory/resourceArea.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/resourceArea.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)resourceArea.cpp	1.57 07/05/05 17:05:55 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/resourceArea.hpp openjdk/hotspot/src/share/vm/memory/resourceArea.hpp
+--- openjdk6/hotspot/src/share/vm/memory/resourceArea.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/resourceArea.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)resourceArea.hpp	1.45 07/05/05 17:05:55 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/restore.cpp openjdk/hotspot/src/share/vm/memory/restore.cpp
+--- openjdk6/hotspot/src/share/vm/memory/restore.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/restore.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)restore.cpp	1.14 07/05/05 17:05:44 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/serialize.cpp openjdk/hotspot/src/share/vm/memory/serialize.cpp
+--- openjdk6/hotspot/src/share/vm/memory/serialize.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/serialize.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)serialize.cpp	1.9 07/05/05 17:05:55 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/sharedHeap.cpp openjdk/hotspot/src/share/vm/memory/sharedHeap.cpp
+--- openjdk6/hotspot/src/share/vm/memory/sharedHeap.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/sharedHeap.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)sharedHeap.cpp	1.59 07/05/17 15:55:10 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/sharedHeap.hpp openjdk/hotspot/src/share/vm/memory/sharedHeap.hpp
+--- openjdk6/hotspot/src/share/vm/memory/sharedHeap.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/sharedHeap.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)sharedHeap.hpp	1.56 07/05/05 17:05:55 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -273,5 +270,3 @@
+ 			     size_t bytes_after,
+ 			     size_t capacity);
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/space.cpp openjdk/hotspot/src/share/vm/memory/space.cpp
+--- openjdk6/hotspot/src/share/vm/memory/space.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/space.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)space.cpp	1.217 07/05/29 09:44:13 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/space.hpp openjdk/hotspot/src/share/vm/memory/space.hpp
+--- openjdk6/hotspot/src/share/vm/memory/space.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/space.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)space.hpp	1.149 07/05/29 09:44:14 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/space.inline.hpp openjdk/hotspot/src/share/vm/memory/space.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/space.inline.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/space.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)space.inline.hpp	1.17 07/05/05 17:05:54 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/specialized_oop_closures.cpp openjdk/hotspot/src/share/vm/memory/specialized_oop_closures.cpp
+--- openjdk6/hotspot/src/share/vm/memory/specialized_oop_closures.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/specialized_oop_closures.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)specialized_oop_closures.cpp	1.14 07/05/05 17:05:56 JVM"
+-#endif
+ /*
+  * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/specialized_oop_closures.hpp openjdk/hotspot/src/share/vm/memory/specialized_oop_closures.hpp
+--- openjdk6/hotspot/src/share/vm/memory/specialized_oop_closures.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/specialized_oop_closures.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)specialized_oop_closures.hpp	1.30 07/05/29 09:44:17 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/tenuredGeneration.cpp openjdk/hotspot/src/share/vm/memory/tenuredGeneration.cpp
+--- openjdk6/hotspot/src/share/vm/memory/tenuredGeneration.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/tenuredGeneration.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)tenuredGeneration.cpp	1.47 07/05/29 09:44:17 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/tenuredGeneration.hpp openjdk/hotspot/src/share/vm/memory/tenuredGeneration.hpp
+--- openjdk6/hotspot/src/share/vm/memory/tenuredGeneration.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/tenuredGeneration.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)tenuredGeneration.hpp	1.27 07/05/29 09:44:17 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp
+--- openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)threadLocalAllocBuffer.cpp	1.55 07/07/05 17:12:38 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp
+--- openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)threadLocalAllocBuffer.hpp	1.35 07/07/05 17:12:36 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)threadLocalAllocBuffer.inline.hpp	1.29 07/05/05 17:05:56 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/universe.cpp openjdk/hotspot/src/share/vm/memory/universe.cpp
+--- openjdk6/hotspot/src/share/vm/memory/universe.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/universe.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)universe.cpp	1.359 07/05/29 09:44:16 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -52,6 +49,16 @@
+ klassOop Universe::_constantPoolCacheKlassObj         = NULL;
+ klassOop Universe::_compiledICHolderKlassObj          = NULL;
+ klassOop Universe::_systemObjArrayKlassObj            = NULL;
++oop Universe::_int_mirror                             =  NULL;
++oop Universe::_float_mirror                           =  NULL;
++oop Universe::_double_mirror                          =  NULL;
++oop Universe::_byte_mirror                            =  NULL;
++oop Universe::_bool_mirror                            =  NULL;
++oop Universe::_char_mirror                            =  NULL;
++oop Universe::_long_mirror                            =  NULL;
++oop Universe::_short_mirror                           =  NULL;
++oop Universe::_void_mirror                            =  NULL;
++oop Universe::_mirrors[T_VOID+1]                      =  { NULL /*, NULL...*/ };
+ oop      Universe::_main_thread_group                 = NULL;
+ oop      Universe::_system_thread_group               = NULL;
+ typeArrayOop Universe::_the_empty_byte_array          = NULL;
+@@ -121,11 +128,24 @@
+ }
+ 
+ void Universe::oops_do(OopClosure* f, bool do_all) {
+-  // Although most of the SystemDictionary oops are klasses,
+-  // a few non-klass objects are defined over there.
+-  // They must be treated in all ways like the random objects in Universe.
+-  // So adopt them into Universe, by the following cross-module call:
+-  SystemDictionary::shared_oops_do(f);
++
++  f->do_oop((oop*) &_int_mirror);
++  f->do_oop((oop*) &_float_mirror);
++  f->do_oop((oop*) &_double_mirror);
++  f->do_oop((oop*) &_byte_mirror);
++  f->do_oop((oop*) &_bool_mirror);
++  f->do_oop((oop*) &_char_mirror);
++  f->do_oop((oop*) &_long_mirror);
++  f->do_oop((oop*) &_short_mirror);
++  f->do_oop((oop*) &_void_mirror);
++
++  // It's important to iterate over these guys even if they are null,
++  // since that's how shared heaps are restored.
++  for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
++    f->do_oop((oop*) &_mirrors[i]);
++  }
++  assert(_mirrors[0] == NULL && _mirrors[T_BOOLEAN - 1] == NULL, "checking");
++
+   // %%% Consider moving those "shared oops" over here with the others.
+   f->do_oop((oop*)&_boolArrayKlassObj);
+   f->do_oop((oop*)&_byteArrayKlassObj);
+@@ -462,6 +482,45 @@
+   }
+ };
+ 
++void Universe::initialize_basic_type_mirrors(TRAPS) {
++  if (UseSharedSpaces) {
++    assert(_int_mirror != NULL, "already loaded");
++    assert(_void_mirror == _mirrors[T_VOID], "consistently loaded");
++  } else {
++
++    assert(_int_mirror==NULL, "basic type mirrors already initialized");
++    _int_mirror     =
++      java_lang_Class::create_basic_type_mirror("int",    T_INT, CHECK);
++    _float_mirror   =
++      java_lang_Class::create_basic_type_mirror("float",  T_FLOAT,   CHECK);
++    _double_mirror  =
++      java_lang_Class::create_basic_type_mirror("double", T_DOUBLE,  CHECK);
++    _byte_mirror    =
++      java_lang_Class::create_basic_type_mirror("byte",   T_BYTE, CHECK);
++    _bool_mirror    =
++      java_lang_Class::create_basic_type_mirror("boolean",T_BOOLEAN, CHECK);
++    _char_mirror    =
++      java_lang_Class::create_basic_type_mirror("char",   T_CHAR, CHECK);
++    _long_mirror    =
++      java_lang_Class::create_basic_type_mirror("long",   T_LONG, CHECK);
++    _short_mirror   =
++      java_lang_Class::create_basic_type_mirror("short",  T_SHORT,   CHECK);
++    _void_mirror    =
++      java_lang_Class::create_basic_type_mirror("void",   T_VOID, CHECK);
++
++    _mirrors[T_INT]     = _int_mirror;
++    _mirrors[T_FLOAT]   = _float_mirror;
++    _mirrors[T_DOUBLE]  = _double_mirror;
++    _mirrors[T_BYTE]    = _byte_mirror;
++    _mirrors[T_BOOLEAN] = _bool_mirror;
++    _mirrors[T_CHAR]    = _char_mirror;
++    _mirrors[T_LONG]    = _long_mirror;
++    _mirrors[T_SHORT]   = _short_mirror;
++    _mirrors[T_VOID]    = _void_mirror;
++    //_mirrors[T_OBJECT]  = instanceKlass::cast(_object_klass)->java_mirror();
++    //_mirrors[T_ARRAY]   = instanceKlass::cast(_object_klass)->java_mirror();
++  }
++}
+ 
+ void Universe::fixup_mirrors(TRAPS) {
+   // Bootstrap problem: all classes gets a mirror (java.lang.Class instance) assigned eagerly,
+@@ -881,44 +940,26 @@
+ }
+ 
+ 
++// %%% The Universe::flush_foo methods belong in CodeCache.
++
+ // Flushes compiled methods dependent on dependee.
+ void Universe::flush_dependents_on(instanceKlassHandle dependee) {  
+   assert_lock_strong(Compile_lock);  
++
+   if (CodeCache::number_of_nmethods_with_dependencies() == 0) return;
+ 
+   // CodeCache can only be updated by a thread_in_VM and they will all be
+   // stopped dring the safepoint so CodeCache will be safe to update without
+   // holding the CodeCache_lock.
+   
+-  // Mark all dependee and all its superclasses
+-  for (klassOop d = dependee(); d != NULL; d = instanceKlass::cast(d)->super()) {
+-    assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking");
+-    instanceKlass::cast(d)->set_is_marked_dependent(true);
+-  }
+-  // Mark transitive interfaces
+-  int i;
+-  for (i = 0; i < dependee->transitive_interfaces()->length(); i++) {
+-    instanceKlass* klass = instanceKlass::cast((klassOop)dependee->transitive_interfaces()->obj_at(i));
+-    assert(!klass->is_marked_dependent(), "checking");
+-    klass->set_is_marked_dependent(true);
+-  }
++  DepChange changes(dependee);
+ 
+   // Compute the dependent nmethods
+-  if (CodeCache::mark_for_deoptimization(dependee()) > 0) {
++  if (CodeCache::mark_for_deoptimization(changes) > 0) {
+     // At least one nmethod has been marked for deoptimization 
+     VM_Deoptimize op;  
+     VMThread::execute(&op);    
+   }
+-
+-  // Unmark all dependee and all its superclasses
+-  for (klassOop e = dependee(); e != NULL; e = instanceKlass::cast(e)->super()) {
+-    instanceKlass::cast(e)->set_is_marked_dependent(false);
+-  }
+-  // Unmark transitive interfaces
+-  for (i = 0; i < dependee->transitive_interfaces()->length(); i++) {
+-    instanceKlass* klass = instanceKlass::cast((klassOop)dependee->transitive_interfaces()->obj_at(i));
+-    klass->set_is_marked_dependent(false);
+-  }
+ }
+ 
+ #ifdef HOTSWAP
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/universe.hpp openjdk/hotspot/src/share/vm/memory/universe.hpp
+--- openjdk6/hotspot/src/share/vm/memory/universe.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/universe.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)universe.hpp	1.182 07/05/17 15:55:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -137,6 +134,18 @@
+   static klassOop _systemObjArrayKlassObj;
+ 
+   // Known objects in the VM
++
++  // Primitive objects
++  static oop _int_mirror;
++  static oop _float_mirror;
++  static oop _double_mirror;
++  static oop _byte_mirror;
++  static oop _bool_mirror;
++  static oop _char_mirror;
++  static oop _long_mirror;
++  static oop _short_mirror;
++  static oop _void_mirror;
++
+   static oop          _main_thread_group;             // Reference to the main thread group object
+   static oop          _system_thread_group;           // Reference to the system thread group object
+ 
+@@ -196,6 +205,7 @@
+   static size_t _heap_used_at_last_gc;
+ 
+   static jint initialize_heap();
++  static void initialize_basic_type_mirrors(TRAPS);
+   static void fixup_mirrors(TRAPS);
+ 
+   static void reinitialize_vtable_of(KlassHandle h_k, TRAPS);
+@@ -204,6 +214,12 @@
+ 
+   static void genesis(TRAPS);                         // Create the initial world
+ 
++  // Mirrors for primitive classes (created eagerly)
++  static oop check_mirror(oop m) {
++    assert(m != NULL, "mirror not initialized");
++    return m;
++  }
++
+   // Debugging
+   static int _verify_count;                           // number of verifies done
+   // True during call to verify().  Should only be set/cleared in verify().
+@@ -247,6 +263,24 @@
+   static klassOop systemObjArrayKlassObj()            { return _systemObjArrayKlassObj;    }
+ 
+   // Known objects in tbe VM
++  static oop int_mirror()                   { return check_mirror(_int_mirror);
++}
++  static oop float_mirror()                 { return check_mirror(_float_mirror); }
++  static oop double_mirror()                { return check_mirror(_double_mirror); }
++  static oop byte_mirror()                  { return check_mirror(_byte_mirror); }
++  static oop bool_mirror()                  { return check_mirror(_bool_mirror); }
++  static oop char_mirror()                  { return check_mirror(_char_mirror); }
++  static oop long_mirror()                  { return check_mirror(_long_mirror); }
++  static oop short_mirror()                 { return check_mirror(_short_mirror); }
++  static oop void_mirror()                  { return check_mirror(_void_mirror); }
++
++  // table of same
++  static oop _mirrors[T_VOID+1];
++
++  static oop java_mirror(BasicType t) {
++    assert((uint)t < T_VOID+1, "range check");
++    return check_mirror(_mirrors[t]);
++  }
+   static oop      main_thread_group()                 { return _main_thread_group; }
+   static void set_main_thread_group(oop group)        { _main_thread_group = group;}
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/universe.inline.hpp openjdk/hotspot/src/share/vm/memory/universe.inline.hpp
+--- openjdk6/hotspot/src/share/vm/memory/universe.inline.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/universe.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)universe.inline.hpp	1.47 07/05/05 17:05:57 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -38,6 +35,3 @@
+ inline bool Universe::field_type_should_be_aligned(BasicType type) {
+   return type == T_DOUBLE || type == T_LONG;
+ }
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/memory/watermark.hpp openjdk/hotspot/src/share/vm/memory/watermark.hpp
+--- openjdk6/hotspot/src/share/vm/memory/watermark.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/memory/watermark.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)watermark.hpp	1.14 07/05/05 17:05:56 JVM"
+-#endif
+ /*
+  * Copyright 2000-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -54,4 +51,3 @@
+ inline bool operator!=(const WaterMark& x, const WaterMark& y) {
+   return !(x == y);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayKlass.cpp openjdk/hotspot/src/share/vm/oops/arrayKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/arrayKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/arrayKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)arrayKlass.cpp	1.95 07/05/05 17:05:59 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayKlass.hpp openjdk/hotspot/src/share/vm/oops/arrayKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/arrayKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/arrayKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)arrayKlass.hpp	1.66 07/05/05 17:05:58 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -135,4 +132,3 @@
+   // Verification
+   void oop_verify_on(oop obj, outputStream* st);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayKlassKlass.cpp openjdk/hotspot/src/share/vm/oops/arrayKlassKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/arrayKlassKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/arrayKlassKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)arrayKlassKlass.cpp	1.56 07/05/29 09:44:17 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayKlassKlass.hpp openjdk/hotspot/src/share/vm/oops/arrayKlassKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/arrayKlassKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/arrayKlassKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)arrayKlassKlass.hpp	1.39 07/05/29 09:44:18 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -70,4 +67,3 @@
+   const char* internal_name() const;
+   void oop_verify_on(oop obj, outputStream* st);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayOop.cpp openjdk/hotspot/src/share/vm/oops/arrayOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/arrayOop.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/arrayOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)arrayOop.cpp	1.18 07/05/05 17:05:58 JVM"
+-#endif
+ /*
+  * Copyright 1997 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,4 +26,3 @@
+ # include "incls/_arrayOop.cpp.incl"
+ 
+ // <<this page is intentionally left blank>>
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayOop.hpp openjdk/hotspot/src/share/vm/oops/arrayOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/arrayOop.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/arrayOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)arrayOop.hpp	1.35 07/05/05 17:06:00 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp openjdk/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compiledICHolderKlass.cpp	1.41 07/05/29 09:44:18 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp openjdk/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compiledICHolderKlass.hpp	1.32 07/05/29 09:44:18 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -84,4 +81,3 @@
+   void oop_verify_on(oop obj, outputStream* st);
+ 
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/compiledICHolderOop.cpp openjdk/hotspot/src/share/vm/oops/compiledICHolderOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/compiledICHolderOop.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/compiledICHolderOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compiledICHolderOop.cpp	1.12 07/05/05 17:05:59 JVM"
+-#endif
+ /*
+  * Copyright 1998 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,4 +26,3 @@
+ # include "incls/_compiledICHolderOop.cpp.incl"
+ 
+ // <<this page is intentionally left blank>>
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/compiledICHolderOop.hpp openjdk/hotspot/src/share/vm/oops/compiledICHolderOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/compiledICHolderOop.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/compiledICHolderOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compiledICHolderOop.hpp	1.20 07/05/05 17:05:59 JVM"
+-#endif
+ /*
+  * Copyright 1998-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/constantPoolKlass.cpp openjdk/hotspot/src/share/vm/oops/constantPoolKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/constantPoolKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/constantPoolKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)constantPoolKlass.cpp	1.105 07/05/29 09:44:18 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/constantPoolKlass.hpp openjdk/hotspot/src/share/vm/oops/constantPoolKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/constantPoolKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/constantPoolKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)constantPoolKlass.hpp	1.51 07/05/29 09:44:18 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -78,4 +75,3 @@
+   static void preload_and_initialize_all_classes(oop constant_pool, TRAPS);
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/constantPoolOop.cpp openjdk/hotspot/src/share/vm/oops/constantPoolOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/constantPoolOop.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/constantPoolOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)constantPoolOop.cpp	1.104 07/05/05 17:06:01 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/constantPoolOop.hpp openjdk/hotspot/src/share/vm/oops/constantPoolOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/constantPoolOop.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/constantPoolOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)constantPoolOop.hpp	1.104 07/05/17 15:55:26 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -35,17 +32,11 @@
+ // the entry in the constant pool is a klass or String object and
+ // not a symbolOop.
+ 
+-#ifdef CC_INTERP
+-class cInterpreter;
+-#endif /* CC_INTERP */
+-
+ class SymbolHashMap;
+ 
+ class constantPoolOopDesc : public arrayOopDesc {
+   friend class VMStructs;
+-#ifdef CC_INTERP
+-  friend class cInterpreter;  // Directly extracts an oop in the pool for fast instanceof/checkcast
+-#endif /* CC_INTERP */
++  friend class BytecodeInterpreter;  // Directly extracts an oop in the pool for fast instanceof/checkcast
+  private:
+   typeArrayOop         _tags; // the tag array describing the constant pool's contents
+   constantPoolCacheOop _cache;         // the cache holding interpreter runtime information
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/constMethodKlass.cpp openjdk/hotspot/src/share/vm/oops/constMethodKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/constMethodKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/constMethodKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)constMethodKlass.cpp	1.24 07/05/29 09:44:18 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -67,7 +64,7 @@
+     CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
+   assert(!cm->is_parsable(), "Not yet safely parsable");
+   No_Safepoint_Verifier no_safepoint;
+-  cm->set_interpreter_kind(AbstractInterpreter::invalid);
++  cm->set_interpreter_kind(Interpreter::invalid);
+   cm->init_fingerprint();
+   cm->set_method(NULL);
+   cm->set_stackmap_data(NULL);
+@@ -302,4 +299,3 @@
+   // Temporarily set exception_table to point to self
+   m->set_exception_table((typeArrayOop)obj);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/constMethodKlass.hpp openjdk/hotspot/src/share/vm/oops/constMethodKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/constMethodKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/constMethodKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)constMethodKlass.hpp	1.15 07/05/29 09:44:18 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -91,4 +88,3 @@
+   bool oop_partially_loaded(oop obj) const;
+   void oop_set_partially_loaded(oop obj);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/constMethodOop.cpp openjdk/hotspot/src/share/vm/oops/constMethodOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/constMethodOop.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/constMethodOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)constMethodOop.cpp	1.11 07/05/05 17:06:00 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/constMethodOop.hpp openjdk/hotspot/src/share/vm/oops/constMethodOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/constMethodOop.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/constMethodOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)constMethodOop.hpp	1.24 07/05/05 17:05:59 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/cpCacheKlass.cpp openjdk/hotspot/src/share/vm/oops/cpCacheKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/cpCacheKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/cpCacheKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cpCacheKlass.cpp	1.46 07/05/29 09:44:18 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -206,4 +203,3 @@
+ const char* constantPoolCacheKlass::internal_name() const { 
+   return "{constant pool cache}"; 
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/cpCacheKlass.hpp openjdk/hotspot/src/share/vm/oops/cpCacheKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/cpCacheKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/cpCacheKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cpCacheKlass.hpp	1.33 07/05/29 09:44:19 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -69,4 +66,3 @@
+   const char* internal_name() const;
+   void oop_verify_on(oop obj, outputStream* st);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/cpCacheOop.cpp openjdk/hotspot/src/share/vm/oops/cpCacheOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/cpCacheOop.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/cpCacheOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cpCacheOop.cpp	1.79 07/05/29 09:44:19 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/cpCacheOop.hpp openjdk/hotspot/src/share/vm/oops/cpCacheOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/cpCacheOop.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/cpCacheOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cpCacheOop.hpp	1.74 07/05/29 09:44:19 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -326,4 +323,3 @@
+   void adjust_method_entries(methodOop* old_methods, methodOop* new_methods,
+                              int methods_length, bool * trace_name_printed);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/generateOopMap.cpp openjdk/hotspot/src/share/vm/oops/generateOopMap.cpp
+--- openjdk6/hotspot/src/share/vm/oops/generateOopMap.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/generateOopMap.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)generateOopMap.cpp	1.141 07/05/05 17:06:03 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -2537,4 +2534,3 @@
+ #endif
+   return methodHandle(THREAD, method());
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/generateOopMap.hpp openjdk/hotspot/src/share/vm/oops/generateOopMap.hpp
+--- openjdk6/hotspot/src/share/vm/oops/generateOopMap.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/generateOopMap.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)generateOopMap.hpp	1.65 07/05/05 17:06:01 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -554,6 +551,3 @@
+ 
+   // Call compute_map(CHECK) to generate info.  
+ };
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceKlass.cpp openjdk/hotspot/src/share/vm/oops/instanceKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/instanceKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/instanceKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)instanceKlass.cpp	1.323 08/06/19 10:32:38 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -768,13 +765,12 @@
+   }
+ }
+ 
+-
+-void instanceKlass::do_local_static_fields(void f(fieldDescriptor*, oop), oop obj) {  
++void instanceKlass::do_local_static_fields(FieldClosure* cl) {
+   fieldDescriptor fd;
+   int length = fields()->length();
+   for (int i = 0; i < length; i += next_offset) {
+     fd.initialize(as_klassOop(), i);
+-    if (fd.is_static()) f(&fd, obj);
++    if (fd.is_static()) cl->do_field(&fd);
+   }
+ }
+ 
+@@ -795,16 +791,16 @@
+ }
+ 
+ 
+-void instanceKlass::do_nonstatic_fields(void f(fieldDescriptor*, oop), oop obj) {
++void instanceKlass::do_nonstatic_fields(FieldClosure* cl) {
+   fieldDescriptor fd;
+   instanceKlass* super = superklass();
+   if (super != NULL) {
+-    super->do_nonstatic_fields(f, obj);
++    super->do_nonstatic_fields(cl);
+   }
+   int length = fields()->length();
+   for (int i = 0; i < length; i += next_offset) {
+     fd.initialize(as_klassOop(), i);
+-    if (!(fd.is_static())) f(&fd, obj);
++    if (!(fd.is_static())) cl->do_field(&fd);
+   }  
+ }
+ 
+@@ -1101,6 +1097,7 @@
+     _next = next;
+     _count = 1;
+   }
++  int count()                             { return _count; }
+   int increment()                         { _count += 1; return _count; }
+   int decrement()                         { _count -= 1; assert(_count >= 0, "don't underflow"); return _count; }
+   nmethodBucket* next()                   { return _next; }
+@@ -1114,7 +1111,7 @@
+ // are dependent on the klassOop that was passed in and mark them for
+ // deoptimization.  Returns the number of nmethods found.
+ //
+-int instanceKlass::mark_dependent_nmethods(klassOop dependee) {
++int instanceKlass::mark_dependent_nmethods(DepChange& changes) {
+   assert_locked_or_safepoint(CodeCache_lock);
+   int found = 0;
+   nmethodBucket* b = _dependencies;
+@@ -1122,11 +1119,12 @@
+     nmethod* nm = b->get_nmethod();
+     // since dependencies aren't removed until an nmethod becomes a zombie,
+     // the dependency list may contain nmethods which aren't alive.
+-    if (nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->is_dependent_on(dependee)) {
++    if (nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) {
+       if (TraceDependencies) {
+         ResourceMark rm;
+         tty->print_cr("Marked for deoptimization");
+-        tty->print_cr("  dependee = %s", this->external_name());
++        tty->print_cr("  context = %s", this->external_name());
++        changes.print();
+         nm->print();
+         nm->print_dependencies();
+       }
+@@ -1193,6 +1191,39 @@
+ }
+ 
+ 
++#ifndef PRODUCT
++void instanceKlass::print_dependent_nmethods(bool verbose) {
++  nmethodBucket* b = _dependencies;
++  int idx = 0;
++  while (b != NULL) {
++    nmethod* nm = b->get_nmethod();
++    tty->print("[%d] count=%d { ", idx++, b->count());
++    if (!verbose) {
++      nm->print_on(tty, "nmethod");
++      tty->print_cr(" } ");
++    } else {
++      nm->print();
++      nm->print_dependencies();
++      tty->print_cr("--- } ");
++    }
++    b = b->next();
++  }
++}
++
++
++bool instanceKlass::is_dependent_nmethod(nmethod* nm) {
++  nmethodBucket* b = _dependencies;
++  while (b != NULL) {
++    if (nm == b->get_nmethod()) {
++      return true;
++    }
++    b = b->next();
++  }
++  return false;
++}
++#endif //PRODUCT
++
++
+ void instanceKlass::follow_static_fields() {
+   oop* start = start_of_static_fields();
+   oop* end   = start + static_oop_field_size();
+@@ -1924,25 +1955,18 @@
+ }
+ 
+ // -----------------------------------------------------------------------------------------------------
+-
+ #ifndef PRODUCT
+ 
+ // Printing
+ 
+-static void print_nonstatic_fields(outputStream* st, instanceKlass* ik, oop obj) {
+-  fieldDescriptor fd;
+-  instanceKlass* super = ik->superklass();
+-  if (super != NULL) {
+-    print_nonstatic_fields(st, super, obj);
+-  }
+-  int length = ik->fields()->length();
+-  for (int i = 0; i < length; i += instanceKlass::next_offset) {
+-    fd.initialize(ik->as_klassOop(), i);
+-    if (!(fd.is_static())) {
+-      st->print("   - ");
+-      fd.print_on_for(st, obj);
+-      st->cr();
+-    }
++void FieldPrinter::do_field(fieldDescriptor* fd) {
++   if (fd->is_static() == (_obj == NULL)) {
++     _st->print("   - ");
++     fd->print_on(_st);
++     _st->cr();
++   } else {
++     fd->print_on_for(_st, _obj);
++     _st->cr();
+   }  
+ }
+ 
+@@ -1967,7 +1991,8 @@
+   }
+ 
+   st->print_cr("fields:");
+-  print_nonstatic_fields(st, this, obj);
++  FieldPrinter print_nonstatic_field(st, obj);
++  do_nonstatic_fields(&print_nonstatic_field);
+ 
+   if (as_klassOop() == SystemDictionary::class_klass()) {
+     klassOop mirrored_klass = java_lang_Class::as_klassOop(obj);
+@@ -2140,20 +2165,12 @@
+   RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d",
+     ikh->external_name(), _previous_versions->length(), emcp_method_count));
+   constantPoolHandle cp_h(ikh->constants());
+-  jobject cp_ref;
+-  if (cp_h->is_shared()) {
+-    // a shared ConstantPool requires a regular reference; a weak
+-    // reference would be collectible
+-    cp_ref = JNIHandles::make_global(cp_h);
+-  } else {
+-    cp_ref = JNIHandles::make_weak_global(cp_h);
+-  }
++  jweak cp_ref = JNIHandles::make_weak_global(cp_h);
+   PreviousVersionNode * pv_node = NULL;
+   objArrayOop old_methods = ikh->methods();
+ 
+   if (emcp_method_count == 0) {
+-    // non-shared ConstantPool gets a weak reference
+-    pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL);
++    pv_node = new PreviousVersionNode(cp_ref, NULL);
+     RC_TRACE(0x00000400,
+       ("add: all methods are obsolete; flushing any EMCP weak refs"));
+   } else {
+@@ -2173,8 +2190,7 @@
+         }
+       }
+     }
+-    // non-shared ConstantPool gets a weak reference
+-    pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs);
++    pv_node = new PreviousVersionNode(cp_ref, method_refs);
+   }
+ 
+   _previous_versions->append(pv_node);
+@@ -2192,7 +2208,7 @@
+     // check the previous versions array for a GC'ed weak refs
+     pv_node = _previous_versions->at(i);
+     cp_ref = pv_node->prev_constant_pool();
+-    assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
++    assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+     if (cp_ref == NULL) {
+       delete pv_node;
+       _previous_versions->remove_at(i);
+@@ -2265,7 +2281,7 @@
+           // check the previous versions array for a GC'ed weak refs
+           pv_node = _previous_versions->at(j);
+           cp_ref = pv_node->prev_constant_pool();
+-          assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
++          assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+           if (cp_ref == NULL) {
+             delete pv_node;
+             _previous_versions->remove_at(j);
+@@ -2363,8 +2379,8 @@
+     // been GC'ed
+     PreviousVersionNode * pv_node = _previous_versions->at(i);
+ 
+-    jobject cp_ref = pv_node->prev_constant_pool();
+-    assert(cp_ref != NULL, "cp reference was unexpectedly cleared");
++    jweak cp_ref = pv_node->prev_constant_pool();
++    assert(cp_ref != NULL, "weak reference was unexpectedly cleared");
+     if (cp_ref == NULL) {
+       continue;  // robustness
+     }
+@@ -2424,11 +2440,10 @@
+ 
+ // Construct a PreviousVersionNode entry for the array hung off
+ // the instanceKlass.
+-PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool,
+-  bool prev_cp_is_weak, GrowableArray<jweak>* prev_EMCP_methods) {
++PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool,
++  GrowableArray<jweak>* prev_EMCP_methods) {
+ 
+   _prev_constant_pool = prev_constant_pool;
+-  _prev_cp_is_weak = prev_cp_is_weak;
+   _prev_EMCP_methods = prev_EMCP_methods;
+ }
+ 
+@@ -2436,11 +2451,7 @@
+ // Destroy a PreviousVersionNode
+ PreviousVersionNode::~PreviousVersionNode() {
+   if (_prev_constant_pool != NULL) {
+-    if (_prev_cp_is_weak) {
+       JNIHandles::destroy_weak_global(_prev_constant_pool);
+-    } else {
+-      JNIHandles::destroy_global(_prev_constant_pool);
+-    }
+   }
+ 
+   if (_prev_EMCP_methods != NULL) {
+@@ -2460,8 +2471,8 @@
+   _prev_constant_pool_handle = constantPoolHandle();  // NULL handle
+   _prev_EMCP_method_handles = NULL;
+ 
+-  jobject cp_ref = pv_node->prev_constant_pool();
+-  assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared");
++  jweak cp_ref = pv_node->prev_constant_pool();
++  assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared");
+   if (cp_ref == NULL) {
+     return;  // robustness
+   }
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceKlass.hpp openjdk/hotspot/src/share/vm/oops/instanceKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/instanceKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/instanceKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)instanceKlass.hpp	1.200 08/06/19 10:32:39 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -79,10 +76,29 @@
+ class jniIdMapBase;
+ class BreakpointInfo;
+ class fieldDescriptor;
++class DepChange;
+ class nmethodBucket;
+ class PreviousVersionNode;
+ class JvmtiCachedClassFieldMap;
+ 
++// This is used in iterators below.
++class FieldClosure: public StackObj {
++public:
++  virtual void do_field(fieldDescriptor* fd) = 0;
++};
++
++#ifndef PRODUCT
++// Print fields.
++// If "obj" argument to constructor is NULL, prints static fields, otherwise prints non-static fields.
++class FieldPrinter: public FieldClosure {
++   oop _obj;
++   outputStream* _st;
++ public:
++   FieldPrinter(outputStream* st, oop obj = NULL) : _obj(obj), _st(st) {}
++   void do_field(fieldDescriptor* fd);
++};
++#endif  // !PRODUCT
++
+ class instanceKlass: public Klass {
+   friend class VMStructs;
+  public:
+@@ -478,7 +494,7 @@
+   JNIid* jni_id_for(int offset);
+ 
+   // maintenance of deoptimization dependencies
+-  int mark_dependent_nmethods(klassOop dependee);
++  int mark_dependent_nmethods(DepChange& changes);
+   void add_dependent_nmethod(nmethod* nm);
+   void remove_dependent_nmethod(nmethod* nm);
+ 
+@@ -525,9 +541,10 @@
+   bool oop_is_instance_slow() const        { return true; }
+ 
+   // Iterators
+-  void do_local_static_fields(void f(fieldDescriptor*, oop), oop obj);
++  void do_local_static_fields(FieldClosure* cl);
++  void do_nonstatic_fields(FieldClosure* cl); // including inherited fields
+   void do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAPS);
+-  void do_nonstatic_fields(void f(fieldDescriptor*, oop), oop obj); // including inherited fields
++
+   void methods_do(void f(methodOop method));
+   void array_klasses_do(void f(klassOop k));
+   void with_array_klasses_do(void f(klassOop k));
+@@ -718,6 +735,9 @@
+   // Printing
+   void oop_print_on      (oop obj, outputStream* st);
+   void oop_print_value_on(oop obj, outputStream* st);
++
++  void print_dependent_nmethods(bool verbose = false);
++  bool is_dependent_nmethod(nmethod* nm);
+ #endif
+ 
+  public:
+@@ -818,20 +838,11 @@
+ // A collection point for interesting information about the previous
+ // version(s) of an instanceKlass. This class uses weak references to
+ // the information so that the information may be collected as needed
+-// by the system. If the information is shared, then a regular
+-// reference must be used because a weak reference would be seen as
+-// collectible. A GrowableArray of PreviousVersionNodes is attached
++// by the system. A GrowableArray of PreviousVersionNodes is attached
+ // to the instanceKlass as needed. See PreviousVersionWalker below.
+ class PreviousVersionNode : public CHeapObj {
+  private:
+-  // A shared ConstantPool is never collected so we'll always have
+-  // a reference to it so we can update items in the cache. We'll
+-  // have a weak reference to a non-shared ConstantPool until all
+-  // of the methods (EMCP or obsolete) have been collected; the
+-  // non-shared ConstantPool becomes collectible at that point.
+-  jobject _prev_constant_pool;  // regular or weak reference
+-  bool    _prev_cp_is_weak;     // true if not a shared ConstantPool
+-
++  jweak _prev_constant_pool;
+   // If the previous version of the instanceKlass doesn't have any
+   // EMCP methods, then _prev_EMCP_methods will be NULL. If all the
+   // EMCP methods have been collected, then _prev_EMCP_methods can
+@@ -839,10 +850,10 @@
+   GrowableArray<jweak>* _prev_EMCP_methods;
+ 
+ public:
+-  PreviousVersionNode(jobject prev_constant_pool, bool prev_cp_is_weak,
++  PreviousVersionNode(jweak prev_constant_pool,
+     GrowableArray<jweak>* prev_EMCP_methods);
+   ~PreviousVersionNode();
+-  jobject prev_constant_pool() const {
++  jweak prev_constant_pool() const {
+     return _prev_constant_pool;
+   }
+   GrowableArray<jweak>* prev_EMCP_methods() const {
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceKlassKlass.cpp openjdk/hotspot/src/share/vm/oops/instanceKlassKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/instanceKlassKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/instanceKlassKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)instanceKlassKlass.cpp	1.156 07/05/29 09:44:20 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -473,23 +470,6 @@
+ 
+ // Printing
+ 
+-static outputStream* printing_stream = NULL;
+-
+-static void print_nonstatic_field(fieldDescriptor* fd, oop obj) {
+-  assert(printing_stream != NULL, "Invalid printing stream");
+-  printing_stream->print("   - ");
+-  fd->print_on(printing_stream);
+-  printing_stream->cr();
+-}
+-
+-static void print_static_field(fieldDescriptor* fd, oop obj) {
+-  assert(printing_stream != NULL, "Invalid printing stream");
+-  printing_stream->print("   - ");
+-  fd->print_on_for(printing_stream, obj);
+-  printing_stream->cr();
+-}
+-
+-
+ static const char* state_names[] = {
+   "unparseable_by_gc", "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error"
+ };
+@@ -584,11 +564,11 @@
+   st->print(" - vtable length      %d  (start addr: " INTPTR_FORMAT ")", ik->vtable_length(), ik->start_of_vtable());  st->cr();  
+   st->print(" - itable length      %d (start addr: " INTPTR_FORMAT ")", ik->itable_length(), ik->start_of_itable()); st->cr();
+   st->print_cr(" - static fields:");
+-  printing_stream = st;
+-  ik->do_local_static_fields(print_static_field, obj);
++  FieldPrinter print_static_field(st);
++  ik->do_local_static_fields(&print_static_field);
+   st->print_cr(" - non-static fields:");
+-  ik->do_nonstatic_fields(print_nonstatic_field, NULL);
+-  printing_stream = NULL;
++  FieldPrinter print_nonstatic_field(st, obj);
++  ik->do_nonstatic_fields(&print_nonstatic_field);
+ 
+   st->print(" - static oop maps:     ");
+   if (ik->static_oop_field_size() > 0) {
+@@ -827,4 +807,3 @@
+   assert(ik->transitive_interfaces() == NULL, "just checking");
+   ik->set_transitive_interfaces((objArrayOop) obj);   // Temporarily set transitive_interfaces to point to self
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceKlassKlass.hpp openjdk/hotspot/src/share/vm/oops/instanceKlassKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/instanceKlassKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/instanceKlassKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)instanceKlassKlass.hpp	1.54 07/05/29 09:44:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -87,4 +84,3 @@
+   bool oop_partially_loaded(oop obj) const;
+   void oop_set_partially_loaded(oop obj);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceOop.cpp openjdk/hotspot/src/share/vm/oops/instanceOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/instanceOop.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/instanceOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)instanceOop.cpp	1.14 07/05/05 17:06:03 JVM"
+-#endif
+ /*
+  * Copyright 1997 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,4 +26,3 @@
+ # include "incls/_instanceOop.cpp.incl"
+ 
+ // <<this page is intentionally left blank>>
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceOop.hpp openjdk/hotspot/src/share/vm/oops/instanceOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/instanceOop.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/instanceOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)instanceOop.hpp	1.15 07/05/05 17:06:04 JVM"
+-#endif
+ /*
+  * Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -32,5 +29,3 @@
+  public:
+   static int header_size() { return sizeof(instanceOopDesc)/HeapWordSize; }
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceRefKlass.cpp openjdk/hotspot/src/share/vm/oops/instanceRefKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/instanceRefKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/instanceRefKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)instanceRefKlass.cpp	1.90 07/05/29 09:44:20 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceRefKlass.hpp openjdk/hotspot/src/share/vm/oops/instanceRefKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/instanceRefKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/instanceRefKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)instanceRefKlass.hpp	1.62 07/05/29 09:44:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/klass.cpp openjdk/hotspot/src/share/vm/oops/klass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/klass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/klass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)klass.cpp	1.119 07/05/05 17:06:00 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/klass.hpp openjdk/hotspot/src/share/vm/oops/klass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/klass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/klass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)klass.hpp	1.142 07/05/29 09:44:17 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -768,4 +765,3 @@
+   void verify_vtable_index(int index);
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/klass.inline.hpp openjdk/hotspot/src/share/vm/oops/klass.inline.hpp
+--- openjdk6/hotspot/src/share/vm/oops/klass.inline.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/klass.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)klass.inline.hpp	1.5 07/05/05 17:06:04 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassKlass.cpp openjdk/hotspot/src/share/vm/oops/klassKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/klassKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/klassKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)klassKlass.cpp	1.69 07/05/29 09:44:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -97,8 +94,8 @@
+   // The following are in the perm gen and are treated
+   // specially in a later phase of a perm gen collection; ...
+   assert(oop(k)->is_perm(), "should be in perm");
+-  assert(oop(k->adr_subklass())->is_perm(), "should be in perm");
+-  assert(oop(k->adr_next_sibling())->is_perm(), "should be in perm");
++  assert(oop(k->subklass())->is_perm_or_null(), "should be in perm");
++  assert(oop(k->next_sibling())->is_perm_or_null(), "should be in perm");
+   // ... don't scan them normally, but remember this klassKlass
+   // for later (see, for instance, oop_follow_contents above
+   // for what MarkSweep does with it.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassKlass.hpp openjdk/hotspot/src/share/vm/oops/klassKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/klassKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/klassKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)klassKlass.hpp	1.44 07/05/29 09:44:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -82,4 +79,3 @@
+   const char* internal_name() const;
+   void oop_verify_on(oop obj, outputStream* st);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassOop.cpp openjdk/hotspot/src/share/vm/oops/klassOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/klassOop.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/klassOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)klassOop.cpp	1.14 07/05/05 17:06:04 JVM"
+-#endif
+ /*
+  * Copyright 1997 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -27,4 +24,3 @@
+ 
+ # include "incls/_precompiled.incl"
+ # include "incls/_klassOop.cpp.incl"
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassOop.hpp openjdk/hotspot/src/share/vm/oops/klassOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/klassOop.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/klassOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)klassOop.hpp	1.19 07/05/05 17:06:04 JVM"
+-#endif
+ /*
+  * Copyright 1997-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -45,6 +42,3 @@
+   // returns the Klass part containing dispatching behavior
+   Klass* klass_part()                            { return (Klass*)((address)this + klass_part_offset_in_bytes()); }
+ };
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassPS.hpp openjdk/hotspot/src/share/vm/oops/klassPS.hpp
+--- openjdk6/hotspot/src/share/vm/oops/klassPS.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/klassPS.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)klassPS.hpp	1.1 07/05/14 06:13:07 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassVtable.cpp openjdk/hotspot/src/share/vm/oops/klassVtable.cpp
+--- openjdk6/hotspot/src/share/vm/oops/klassVtable.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/klassVtable.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)klassVtable.cpp	1.146 07/07/19 12:19:09 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -738,7 +735,7 @@
+     }    
+   }
+ 
+-  // The length of the itable was either zero, or it has not yet been initialized.
++  // This lenght of the itable was either zero, or it has not yet been initialized.
+   _table_offset      = 0;
+   _size_offset_table = 0;
+   _size_method_table = 0;
+@@ -873,19 +870,16 @@
+ 
+ // Initialization
+ void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
+-  // Cannot be setup doing bootstrapping, interfaces don't have
+-  // itables, and klass with only ones entry have empty itables
+-  if (Universe::is_bootstrapping() || 
+-      _klass->is_interface() ||
+-      _klass->itable_length() == itableOffsetEntry::size()) return;
+-
+-  // There's alway an extra itable entry so we can null-terminate it.
+-  guarantee(size_offset_table() >= 1, "too small");
+-  int num_interfaces = size_offset_table() - 1;
++  // Cannot be setup doing bootstrapping
++  if (Universe::is_bootstrapping()) return;
++
++  int num_interfaces = nof_interfaces();
+   if (num_interfaces > 0) {
+-    if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count,
+-                                    _klass->name()->as_C_string());
++    if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, _klass->name()->as_C_string());
+     
++    // In debug mode, we got an extra NULL/NULL entry
++    debug_only(num_interfaces--);
++    assert(num_interfaces > 0, "to few interfaces in offset itable");
+ 
+     // Interate through all interfaces
+     int i;
+@@ -896,10 +890,12 @@
+       initialize_itable_for_interface(ioe->offset(), interf_h, checkconstraints, CHECK);      
+     } 
+ 
+-  }  
++#ifdef ASSERT
+   // Check that the last entry is empty
+-  itableOffsetEntry* ioe = offset_entry(size_offset_table() - 1);
+-  guarantee(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing");
++    itableOffsetEntry* ioe = offset_entry(i);
++    assert(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing");
++#endif
++  }
+ }
+ 
+ 
+@@ -976,7 +972,7 @@
+   }  
+ }
+ 
+-// Update entry for specific methodOop
++// Update entry for specic methodOop
+ void klassItable::initialize_with_method(methodOop m) {
+   itableMethodEntry* ime = method_entry(0);
+   for(int i = 0; i < _size_method_table; i++) {    
+@@ -1089,8 +1085,12 @@
+   CountInterfacesClosure cic;  
+   visit_all_interfaces(transitive_interfaces(), &cic);
+     
+-  // There's alway an extra itable entry so we can null-terminate it.
+-  int itable_size = calc_itable_size(cic.nof_interfaces() + 1, cic.nof_methods()); 
++  // Add one extra entry in debug mode, so we can null-terminate the table
++  int nof_methods    = cic.nof_methods();
++  int nof_interfaces = cic.nof_interfaces();
++  debug_only(if (nof_interfaces > 0) nof_interfaces++);
++
++  int itable_size = calc_itable_size(nof_interfaces, nof_methods);
+ 
+   // Statistics
+   update_stats(itable_size * HeapWordSize);  
+@@ -1110,8 +1110,8 @@
+   int nof_methods    = cic.nof_methods();
+   int nof_interfaces = cic.nof_interfaces();
+   
+-  // Add one extra entry so we can null-terminate the table
+-  nof_interfaces++;
++  // Add one extra entry in debug mode, so we can null-terminate the table
++  debug_only(if (nof_interfaces > 0) nof_interfaces++);
+   
+   assert(compute_itable_size(objArrayHandle(klass->transitive_interfaces())) ==
+          calc_itable_size(nof_interfaces, nof_methods),
+@@ -1320,5 +1320,3 @@
+ }
+ 
+ #endif // PRODUCT
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassVtable.hpp openjdk/hotspot/src/share/vm/oops/klassVtable.hpp
+--- openjdk6/hotspot/src/share/vm/oops/klassVtable.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/klassVtable.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)klassVtable.hpp	1.62 07/07/19 12:19:09 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -262,7 +259,7 @@
+   itableMethodEntry* method_entry(int i) { assert(0 <= i && i <= _size_method_table, "index out of bounds");
+                                            return &((itableMethodEntry*)method_start())[i]; }
+   
+-  int size_offset_table()                { return _size_offset_table; }
++  int nof_interfaces()                   { return _size_offset_table; }
+ 
+   // Initialization
+   void initialize_itable(bool checkconstraints, TRAPS);    
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/markOop.cpp openjdk/hotspot/src/share/vm/oops/markOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/markOop.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/markOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)markOop.cpp	1.29 08/06/19 12:45:44 JVM"
+-#endif
+ /*
+  * Copyright 1997-1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -40,32 +37,3 @@
+     st->print("age %d)", age());
+   }
+ }
+-
+-
+-// Give advice about whether the oop that contains this markOop
+-// should be cached or not.
+-bool markOopDesc::should_not_be_cached() const {
+-  // the cast is because decode_pointer() isn't marked const
+-  if (is_marked() && ((markOopDesc *)this)->decode_pointer() != NULL) {
+-    // If the oop containing this markOop is being forwarded, then
+-    // we are in the middle of GC and we do not want the containing
+-    // oop to be added to a cache. We have no way of knowing whether
+-    // the cache has already been visited by the current GC phase so
+-    // we don't know whether the forwarded oop will be properly
+-    // processed in this phase. If the forwarded oop is not properly
+-    // processed, then we'll see strange crashes or asserts during
+-    // the next GC run because the markOop will contain an unexpected
+-    // value.
+-    //
+-    // This situation has been seen when we are GC'ing a methodOop
+-    // because we use the methodOop while we're GC'ing it. Scary
+-    // stuff. Some of the uses the methodOop cause the methodOop to
+-    // be added to the OopMapCache in the instanceKlass as a side
+-    // effect. This check lets the cache maintainer know when a
+-    // cache addition would not be safe.
+-    return true;
+-  }
+-
+-  // caching the containing oop should be just fine
+-  return false;
+-}
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/markOop.hpp openjdk/hotspot/src/share/vm/oops/markOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/markOop.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/markOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)markOop.hpp	1.65 08/06/19 12:45:45 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -360,7 +357,4 @@
+ 
+   // Recover address of oop from encoded form used in mark
+   inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); }
+-
+-  // see the definition in markOop.cpp for the gory details
+-  bool should_not_be_cached() const;
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/markOop.inline.hpp openjdk/hotspot/src/share/vm/oops/markOop.inline.hpp
+--- openjdk6/hotspot/src/share/vm/oops/markOop.inline.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/markOop.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)markOop.inline.hpp	1.7 07/05/05 17:06:04 JVM"
+-#endif
+ /*
+  * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodDataKlass.cpp openjdk/hotspot/src/share/vm/oops/methodDataKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/methodDataKlass.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/methodDataKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)methodDataKlass.cpp	1.36 07/05/29 09:44:22 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -239,4 +236,3 @@
+   guarantee(m->is_perm(), "should be in permspace");
+   m->verify_data_on(st);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodDataKlass.hpp openjdk/hotspot/src/share/vm/oops/methodDataKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/methodDataKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/methodDataKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)methodDataKlass.hpp	1.30 07/05/29 09:44:23 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodDataOop.cpp openjdk/hotspot/src/share/vm/oops/methodDataOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/methodDataOop.cpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/methodDataOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)methodDataOop.cpp	1.51 07/05/29 09:44:22 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodDataOop.hpp openjdk/hotspot/src/share/vm/oops/methodDataOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/methodDataOop.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/methodDataOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)methodDataOop.hpp	1.53 07/05/29 09:44:23 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -189,6 +186,9 @@
+   intptr_t cell_at(int index) {
+     return _cells[index];
+   }
++  intptr_t* adr_cell_at(int index) {
++    return &_cells[index];
++  }
+   oop* adr_oop_at(int index) {
+     return (oop*)&(_cells[index]);
+   }
+@@ -573,6 +573,14 @@
+   uint taken() {
+     return uint_at(taken_off_set);
+   }
++  // Saturating counter
++  uint inc_taken() {
++    uint cnt = taken() + 1;
++    // Did we wrap? Will compiler screw us??
++    if (cnt == 0) cnt--;
++    set_uint_at(taken_off_set, cnt);
++    return cnt;
++  }
+   
+   int displacement() {
+     return int_at(displacement_off_set);
+@@ -858,6 +866,14 @@
+     return uint_at(not_taken_off_set);
+   }
+   
++  uint inc_not_taken() {
++    uint cnt = not_taken() + 1;
++    // Did we wrap? Will compiler screw us??
++    if (cnt == 0) cnt--;
++    set_uint_at(not_taken_off_set, cnt);
++    return cnt;
++  }
++
+   // Code generation support
+   static ByteSize not_taken_offset() {
+     return cell_offset(not_taken_off_set);
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodKlass.cpp openjdk/hotspot/src/share/vm/oops/methodKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/methodKlass.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/methodKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)methodKlass.cpp	1.120 07/05/29 09:44:23 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -362,4 +359,3 @@
+   constMethodKlass* ck = constMethodKlass::cast(xconst->klass());
+   ck->oop_set_partially_loaded(xconst);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodKlass.hpp openjdk/hotspot/src/share/vm/oops/methodKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/methodKlass.hpp	2008-08-28 10:23:12.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/methodKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)methodKlass.hpp	1.49 07/05/29 09:44:23 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -85,4 +82,3 @@
+   bool oop_partially_loaded(oop obj) const;
+   void oop_set_partially_loaded(oop obj);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodOop.cpp openjdk/hotspot/src/share/vm/oops/methodOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/methodOop.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/methodOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)methodOop.cpp	1.313 08/06/19 12:45:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -218,8 +215,8 @@
+ 
+ 
+ void methodOopDesc::set_interpreter_kind() {
+-  int kind = AbstractInterpreter::method_kind(methodOop(this));
+-  assert(kind != AbstractInterpreter::invalid,
++  int kind = Interpreter::method_kind(methodOop(this));
++  assert(kind != Interpreter::invalid,
+          "interpreter entry must be valid");
+   set_interpreter_kind(kind);
+ }
+@@ -315,7 +312,7 @@
+ 
+ #ifdef CC_INTERP
+ void methodOopDesc::set_result_index(BasicType type)          { 
+-  _result_index = AbstractInterpreter::BasicType_as_index(type); 
++  _result_index = Interpreter::BasicType_as_index(type);
+ }
+ #endif
+ 
+@@ -650,7 +647,7 @@
+ 
+   // Setup interpreter entrypoint
+   assert(this == h_method(), "wrong h_method()" );
+-  address entry = AbstractInterpreter::entry_for_method(h_method);
++  address entry = Interpreter::entry_for_method(h_method);
+   assert(entry != NULL, "interpreter entry must be non-null");
+   // Sets both _i2i_entry and _from_interpreted_entry
+   set_interpreter_entry(entry);
+@@ -768,28 +765,6 @@
+ }
+ 
+ 
+-// give advice about whether this methodOop should be cached or not
+-bool methodOopDesc::should_not_be_cached() const {
+-  if (is_old()) {
+-    // This method has been redefined. It is either EMCP or obsolete
+-    // and we don't want to cache it because that would pin the method
+-    // down and prevent it from being collectible if and when it
+-    // finishes executing.
+-    return true;
+-  }
+-
+-  if (mark()->should_not_be_cached()) {
+-    // It is either not safe or not a good idea to cache this
+-    // method at this time because of the state of the embedded
+-    // markOop. See markOop.cpp for the gory details.
+-    return true;
+-  }
+-
+-  // caching this method should be just fine
+-  return false;
+-}
+-
+-
+ methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length, 
+                                                 u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) {
+   // Code below does not work for native methods - they should never get rewritten anyway
+@@ -1080,18 +1055,18 @@
+ }
+ 
+ 
+-void methodOopDesc::print_codes() const {
+-  print_codes(0, code_size());
++void methodOopDesc::print_codes_on(outputStream* st) const {
++  print_codes_on(0, code_size(), st);
+ }
+ 
+-void methodOopDesc::print_codes(int from, int to) const {
++void methodOopDesc::print_codes_on(int from, int to, outputStream* st) const {
+   Thread *thread = Thread::current();
+   ResourceMark rm(thread);
+   methodHandle mh (thread, (methodOop)this);
+   BytecodeStream s(mh);
+   s.set_interval(from, to);
+   BytecodeTracer::set_closure(BytecodeTracer::std_closure());
+-  while (s.next() >= 0) BytecodeTracer::trace(mh, s.bcp());
++  while (s.next() >= 0) BytecodeTracer::trace(mh, s.bcp(), st);
+ }
+ #endif // not PRODUCT
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodOop.hpp openjdk/hotspot/src/share/vm/oops/methodOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/methodOop.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/methodOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)methodOop.hpp	1.220 08/06/19 12:45:48 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -368,8 +365,10 @@
+   address code_base() const           { return constMethod()->code_base(); }
+   bool    contains(address bcp) const { return constMethod()->contains(bcp); }
+ 
+-  void print_codes() const                       PRODUCT_RETURN; // prints byte codes
+-  void print_codes(int from, int to) const       PRODUCT_RETURN;
++  // prints byte codes
++  void print_codes() const            { print_codes_on(tty); }
++  void print_codes_on(outputStream* st) const                      PRODUCT_RETURN;
++  void print_codes_on(int from, int to, outputStream* st) const    PRODUCT_RETURN;
+ 
+   // checked exceptions
+   int checked_exceptions_length() const
+@@ -396,6 +395,7 @@
+   void compute_size_of_parameters(Thread *thread); // word size of parameters (receiver if any + arguments)
+   symbolOop klass_name() const;                  // returns the name of the method holder
+   BasicType result_type() const;                 // type of the method result
++  int result_type_index() const;                 // type index of the method result
+   bool is_returning_oop() const                  { BasicType r = result_type(); return (r == T_OBJECT || r == T_ARRAY); }
+   bool is_returning_fp() const                   { BasicType r = result_type(); return (r == T_FLOAT || r == T_DOUBLE); }
+ 
+@@ -524,8 +524,6 @@
+   void set_is_old()                                 { _access_flags.set_is_old(); }
+   bool is_obsolete() const                          { return access_flags().is_obsolete(); }
+   void set_is_obsolete()                            { _access_flags.set_is_obsolete(); }
+-  // see the definition in methodOop.cpp for the gory details
+-  bool should_not_be_cached() const;
+ 
+   // JVMTI Native method prefixing support:
+   bool is_prefixed_native() const                   { return access_flags().is_prefixed_native(); }
+@@ -739,5 +737,3 @@
+   void set(methodOop method);
+   void clear(methodOop method);
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayKlass.cpp openjdk/hotspot/src/share/vm/oops/objArrayKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/objArrayKlass.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/objArrayKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)objArrayKlass.cpp	1.147 07/05/29 09:44:23 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayKlass.hpp openjdk/hotspot/src/share/vm/oops/objArrayKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/objArrayKlass.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/objArrayKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)objArrayKlass.hpp	1.87 07/05/29 09:44:23 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -129,4 +126,3 @@
+   void oop_verify_old_oop(oop obj, oop* p, bool allow_dirty);
+ 
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp openjdk/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)objArrayKlassKlass.cpp	1.79 07/05/29 09:44:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -309,4 +306,3 @@
+   Klass* bk = Klass::cast(oak->bottom_klass());
+   guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(),  "invalid bottom klass");
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayKlassKlass.hpp openjdk/hotspot/src/share/vm/oops/objArrayKlassKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/objArrayKlassKlass.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/objArrayKlassKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)objArrayKlassKlass.hpp	1.48 07/05/29 09:44:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -80,4 +77,3 @@
+   void oop_verify_on(oop obj, outputStream* st);
+ 
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayOop.cpp openjdk/hotspot/src/share/vm/oops/objArrayOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/objArrayOop.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/objArrayOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)objArrayOop.cpp	1.14 07/05/05 17:06:07 JVM"
+-#endif
+ /*
+  * Copyright 1997 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,4 +26,3 @@
+ # include "incls/_objArrayOop.cpp.incl"
+ 
+ // <<this page is intentionally left blank>>
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayOop.hpp openjdk/hotspot/src/share/vm/oops/objArrayOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/objArrayOop.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/objArrayOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)objArrayOop.hpp	1.29 07/05/05 17:06:07 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.cpp openjdk/hotspot/src/share/vm/oops/oop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/oop.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/oop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)oop.cpp	1.99 07/05/29 09:44:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.hpp openjdk/hotspot/src/share/vm/oops/oop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/oop.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/oop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oop.hpp	1.116 07/05/29 09:44:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -254,7 +251,7 @@
+ #endif // SERIALGC
+ 
+   bool is_perm() const;
+-  bool is_perm_and_alloced() const;
++  bool is_perm_or_null() const;
+   bool is_shared() const;
+   bool is_shared_readonly() const;
+   bool is_shared_readwrite() const;
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.inline2.hpp openjdk/hotspot/src/share/vm/oops/oop.inline2.hpp
+--- openjdk6/hotspot/src/share/vm/oops/oop.inline2.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/oop.inline2.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oop.inline2.hpp	1.12 07/05/05 17:06:07 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -33,13 +30,7 @@
+   return Universe::heap()->is_in_permanent(this);
+ }
+ 
+-// is_perm only verifies that oop is in the reserved space for
+-// the perm gen. Things like forte stackwalking need something that
+-// assures us that the pointer is in the commited area so we don't
+-// segv checking suspicious frame contents.
+-
+-inline bool oopDesc::is_perm_and_alloced() const {
+-  return Universe::heap()->is_permanent(this);
++// Check for NULL also.
++inline bool oopDesc::is_perm_or_null() const {
++  return this == NULL || is_perm();
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.inline.hpp openjdk/hotspot/src/share/vm/oops/oop.inline.hpp
+--- openjdk6/hotspot/src/share/vm/oops/oop.inline.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/oop.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oop.inline.hpp	1.141 07/06/12 15:40:38 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -202,7 +199,8 @@
+       // technique, or when G1 is integrated (and currently uses this array chunking
+       // technique) we will need to suitably modify the assertion.
+       assert((s == klass->oop_size(this)) ||
+-             ((UseParNewGC && Universe::heap()->is_gc_active()) &&
++             (((UseParNewGC || UseParallelGC) &&
++                                           Universe::heap()->is_gc_active()) &&
+               (is_typeArray() ||
+                (is_objArray() && is_forwarded()))),
+              "wrong array object size");
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp openjdk/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp
+--- openjdk6/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oop.pcgc.inline.hpp	1.16 07/05/29 09:44:24 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.psgc.inline.hpp openjdk/hotspot/src/share/vm/oops/oop.psgc.inline.hpp
+--- openjdk6/hotspot/src/share/vm/oops/oop.psgc.inline.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/oop.psgc.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oop.psgc.inline.hpp	1.17 07/05/05 17:06:07 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -44,4 +41,3 @@
+   }
+   // Else skip it.  The typeArrayKlass in the header never needs scavenging.
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/oopsHierarchy.cpp openjdk/hotspot/src/share/vm/oops/oopsHierarchy.cpp
+--- openjdk6/hotspot/src/share/vm/oops/oopsHierarchy.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/oopsHierarchy.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oopsHierarchy.cpp	1.7 07/05/05 17:06:08 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/oopsHierarchy.hpp openjdk/hotspot/src/share/vm/oops/oopsHierarchy.hpp
+--- openjdk6/hotspot/src/share/vm/oops/oopsHierarchy.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/oopsHierarchy.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)oopsHierarchy.hpp	1.31 07/05/17 15:57:10 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/symbolKlass.cpp openjdk/hotspot/src/share/vm/oops/symbolKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/symbolKlass.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/symbolKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)symbolKlass.cpp	1.66 07/05/29 09:44:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/symbolKlass.hpp openjdk/hotspot/src/share/vm/oops/symbolKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/symbolKlass.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/symbolKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)symbolKlass.hpp	1.42 07/05/29 09:44:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -75,4 +72,3 @@
+ #endif
+   const char* internal_name() const;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/symbolOop.cpp openjdk/hotspot/src/share/vm/oops/symbolOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/symbolOop.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/symbolOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)symbolOop.cpp	1.28 07/05/05 17:06:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/symbolOop.hpp openjdk/hotspot/src/share/vm/oops/symbolOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/symbolOop.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/symbolOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)symbolOop.hpp	1.40 07/05/05 17:06:07 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -119,4 +116,3 @@
+  return (((uintptr_t)this < (uintptr_t)other) ? -1
+    : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayKlass.cpp openjdk/hotspot/src/share/vm/oops/typeArrayKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/typeArrayKlass.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/typeArrayKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)typeArrayKlass.cpp	1.125 07/05/29 09:44:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayKlass.hpp openjdk/hotspot/src/share/vm/oops/typeArrayKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/typeArrayKlass.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/typeArrayKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)typeArrayKlass.hpp	1.69 07/05/29 09:44:25 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayKlassKlass.cpp openjdk/hotspot/src/share/vm/oops/typeArrayKlassKlass.cpp
+--- openjdk6/hotspot/src/share/vm/oops/typeArrayKlassKlass.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/typeArrayKlassKlass.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)typeArrayKlassKlass.cpp	1.30 07/05/05 17:06:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -71,4 +68,3 @@
+ const char* typeArrayKlassKlass::internal_name() const {
+   return "{type array class}";
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayKlassKlass.hpp openjdk/hotspot/src/share/vm/oops/typeArrayKlassKlass.hpp
+--- openjdk6/hotspot/src/share/vm/oops/typeArrayKlassKlass.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/typeArrayKlassKlass.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)typeArrayKlassKlass.hpp	1.24 07/05/05 17:06:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -59,4 +56,3 @@
+  public:
+   const char* internal_name() const;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayOop.cpp openjdk/hotspot/src/share/vm/oops/typeArrayOop.cpp
+--- openjdk6/hotspot/src/share/vm/oops/typeArrayOop.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/typeArrayOop.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)typeArrayOop.cpp	1.14 07/05/05 17:06:08 JVM"
+-#endif
+ /*
+  * Copyright 1997 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,4 +26,3 @@
+ # include "incls/_typeArrayOop.cpp.incl"
+ 
+ // <<this page is intentionally left blank>>
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayOop.hpp openjdk/hotspot/src/share/vm/oops/typeArrayOop.hpp
+--- openjdk6/hotspot/src/share/vm/oops/typeArrayOop.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/oops/typeArrayOop.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)typeArrayOop.hpp	1.46 07/05/05 17:06:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/addnode.cpp openjdk/hotspot/src/share/vm/opto/addnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/addnode.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/addnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)addnode.cpp	1.141 07/05/05 17:06:10 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/addnode.hpp openjdk/hotspot/src/share/vm/opto/addnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/addnode.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/addnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)addnode.hpp	1.58 07/05/05 17:06:10 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/adlcVMDeps.hpp openjdk/hotspot/src/share/vm/opto/adlcVMDeps.hpp
+--- openjdk6/hotspot/src/share/vm/opto/adlcVMDeps.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/adlcVMDeps.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)adlcVMDeps.hpp	1.19 07/05/05 17:06:10 JVM"
+-#endif
+ /*
+  * Copyright 1998-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/block.cpp openjdk/hotspot/src/share/vm/opto/block.cpp
+--- openjdk6/hotspot/src/share/vm/opto/block.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/block.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)block.cpp	1.169 07/05/17 15:57:15 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -134,7 +131,7 @@
+ int Block::is_Empty() const {
+   
+   // Root or start block is not considered empty
+-  if (_nodes[0]->is_Root() || _nodes[0]->is_Start()) {
++  if (head()->is_Root() || head()->is_Start()) {
+     return not_empty; 
+   }
+ 
+@@ -167,16 +164,45 @@
+   return not_empty;
+ }
+ 
++//------------------------------has_uncommon_code------------------------------
++// Return true if the block's code implies that it is not likely to be
++// executed infrequently.  Check to see if the block ends in a Halt or
++// a low probability call.
++bool Block::has_uncommon_code() const {
++  Node* en = end();
++
++  if (en->is_Goto())
++    en = en->in(0);
++  if (en->is_Catch())
++    en = en->in(0);
++  if (en->is_Proj() && en->in(0)->is_MachCall()) {
++    MachCallNode* call = en->in(0)->as_MachCall();
++    if (call->cnt() != COUNT_UNKNOWN && call->cnt() <= PROB_UNLIKELY_MAG(4)) {
++      // This is true for slow-path stubs like new_{instance,array},
++      // slow_arraycopy, complete_monitor_locking, uncommon_trap.
++      // The magic number corresponds to the probability of an uncommon_trap,
++      // even though it is a count not a probability.
++      return true;
++    }
++  }
++
++  int op = en->is_Mach() ? en->as_Mach()->ideal_Opcode() : en->Opcode();
++  return op == Op_Halt;
++}
++
+ //------------------------------is_uncommon------------------------------------
+ // True if block is low enough frequency or guarded by a test which 
+ // mostly does not go here.
+ bool Block::is_uncommon( Block_Array &bbs ) const {
+   // Initial blocks must never be moved, so are never uncommon.
+-  if (_nodes[0]->is_Root() || _nodes[0]->is_Start())  return false;
++  if (head()->is_Root() || head()->is_Start())  return false;
+ 
+   // Check for way-low freq
+   if( _freq < BLOCK_FREQUENCY(0.00001f) ) return true;
+ 
++  // Look for code shape indicating uncommon_trap or slow path
++  if (has_uncommon_code()) return true;
++
+   const float epsilon = 0.05f;
+   const float guard_factor = PROB_UNLIKELY_MAG(4) / (1.f - epsilon);
+   uint uncommon_preds = 0;
+@@ -280,11 +306,10 @@
+     }
+     tty->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order);
+     // Dump any loop-specific bits, especially for CountedLoops.
+-    loop->dump_spec();
++    loop->dump_spec(tty);
+   }
+   tty->print(" Freq: %g",_freq);
+   if( Verbose || WizardMode ) {
+-    tty->print(" Count: %g",_cnt);
+     tty->print(" IDom: %d/#%d", _idom ? _idom->_pre_order : 0, _dom_depth);
+     tty->print(" RegPressure: %d",_reg_pressure);
+     tty->print(" IHRP Index: %d",_ihrp_index);
+@@ -521,7 +546,7 @@
+       break;
+   // Scan through block, yanking dead path from
+   // all regions and phis.
+-  dead->_nodes[0]->del_req(j);
++  dead->head()->del_req(j);
+   for( int k = 1; dead->_nodes[k]->is_Phi(); k++ )
+     dead->_nodes[k]->del_req(j);
+ }
+@@ -560,7 +585,7 @@
+   return true;
+ }
+ 
+-//------------------------------MoveEmptyToEnd---------------------------------
++//------------------------------MoveToEnd--------------------------------------
+ // Move empty and uncommon blocks to the end.
+ void PhaseCFG::MoveToEnd(Block *b, uint i) {
+   int e = b->is_Empty();
+@@ -689,8 +714,8 @@
+       ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj();
+ 
+       // Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1].
+-      assert(proj0->raw_out(0) == b->_succs[0]->_nodes[0], "Mismatch successor 0");
+-      assert(proj1->raw_out(0) == b->_succs[1]->_nodes[0], "Mismatch successor 1");
++      assert(proj0->raw_out(0) == b->_succs[0]->head(), "Mismatch successor 0");
++      assert(proj1->raw_out(0) == b->_succs[1]->head(), "Mismatch successor 1");
+ 
+       Block *bs1 = b->non_connector_successor(1);
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/block.hpp openjdk/hotspot/src/share/vm/opto/block.hpp
+--- openjdk6/hotspot/src/share/vm/opto/block.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/block.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)block.hpp	1.98 07/05/17 15:57:17 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -28,6 +25,7 @@
+ // Optimization - Graph Style
+ 
+ class Block;
++class CFGLoop;
+ class MachCallNode;
+ class Matcher;
+ class RootNode;
+@@ -80,11 +78,22 @@
+ };
+ 
+ 
++class CFGElement : public ResourceObj {
++ public:
++  float _freq; // Execution frequency (estimate)
++
++  CFGElement() : _freq(0.0f) {}
++  virtual bool is_block() { return false; }
++  virtual bool is_loop()  { return false; }
++  Block*   as_Block() { assert(is_block(), "must be block"); return (Block*)this; }
++  CFGLoop* as_CFGLoop()  { assert(is_loop(),  "must be loop");  return (CFGLoop*)this;  }
++};
++
+ //------------------------------Block------------------------------------------
+ // This class defines a Basic Block.
+ // Basic blocks are used during the output routines, and are not used during
+ // any optimization pass.  They are created late in the game.
+-class Block : public ResourceObj {
++class Block : public CFGElement {
+  public:
+   // Nodes in this block, in order
+   Node_List _nodes;
+@@ -116,6 +125,12 @@
+   uint _dom_depth;              // Depth in dominator tree for fast LCA
+   Block* _idom;                 // Immediate dominator block
+ 
++  CFGLoop *_loop;               // Loop to which this block belongs
++  uint _rpo;                    // Number in reverse post order walk
++
++  virtual bool is_block() { return true; }
++  float succ_prob(uint i); // return probability of i'th successor
++
+   Block* dom_lca(Block* that);  // Compute LCA in dominator tree.
+ #ifdef ASSERT
+   bool dominates(Block* that) {
+@@ -135,19 +150,6 @@
+   // FreqCountInvocations relative to the old value of 1500.
+ #define BLOCK_FREQUENCY(f) ((f * (float) 1500) / FreqCountInvocations)
+ 
+-  // Execution frequency (estimate)
+-  float _freq;
+-  float _cnt;
+-
+-#ifdef ASSERT
+-  // Validate _cnt and _freq
+-  bool has_valid_counts() const { 
+-    if (_freq <= 0.0f) return false;
+-    if ((_cnt <= 0.0f) && (_cnt != COUNT_UNKNOWN)) return false;
+-    return true;
+-  }
+-#endif
+-
+   // Register Pressure (estimate) for Splitting heuristic
+   uint _reg_pressure;
+   uint _ihrp_index;
+@@ -203,13 +205,13 @@
+   // Create a new Block with given head Node.
+   // Creates the (empty) predecessor arrays.
+   Block( Arena *a, Node *headnode ) 
+-    : _nodes(a), 
++    : CFGElement(),
++      _nodes(a),
+       _succs(a), 
+       _num_succs(0), 
+       _pre_order(0), 
+       _idom(0), 
+-      _freq(0.0f), 
+-      _cnt(COUNT_UNKNOWN), 
++      _loop(NULL),
+       _reg_pressure(0), 
+       _ihrp_index(1), 
+       _freg_pressure(0), 
+@@ -278,7 +280,11 @@
+     return _succs[i]->non_connector();
+   }
+ 
+-  // True if block is way uncommon
++  // Examine block's code shape to predict if it is not commonly executed.
++  bool has_uncommon_code() const;
++
++  // Use frequency calculations and code shape to predict if the block
++  // is uncommon.
+   bool is_uncommon( Block_Array &bbs ) const;
+ 
+ #ifndef PRODUCT
+@@ -330,6 +336,7 @@
+   Block_Array _bbs;             // Map Nodes to owning Basic Block
+   Block *_broot;                // Basic block of root
+   uint _rpo_ctr;
++  CFGLoop* _root_loop;
+   
+   // Per node latency estimation, valid only during GCM
+   GrowableArray<uint> _node_latency;
+@@ -384,6 +391,8 @@
+   // into Goto's so that when you enter the infinite loop you indeed hang.
+   void convert_NeverBranch_to_Goto(Block *b);
+ 
++  CFGLoop* create_loop_tree();
++
+   // Insert a node into a block, and update the _bbs
+   void insert( Block *b, uint idx, Node *n ) { 
+     b->_nodes.insert( idx, n ); 
+@@ -439,3 +448,63 @@
+ 
+ };
+ 
++//----------------------------BlockProbPair---------------------------
++// Ordered pair of Node*.
++class BlockProbPair VALUE_OBJ_CLASS_SPEC {
++protected:
++  Block* _target;      // block target
++  float  _prob;        // probability of edge to block
++public:
++  BlockProbPair() : _target(NULL), _prob(0.0) {}
++  BlockProbPair(Block* b, float p) : _target(b), _prob(p) {}
++
++  Block* get_target() const { return _target; }
++  float get_prob() const { return _prob; }
++};
++
++//------------------------------CFGLoop-------------------------------------------
++class CFGLoop : public CFGElement {
++  int _id;
++  int _depth;
++  CFGLoop *_parent;      // root of loop tree is the method level "pseudo" loop, it's parent is null
++  CFGLoop *_sibling;     // null terminated list
++  CFGLoop *_child;       // first child, use child's sibling to visit all immediately nested loops
++  GrowableArray<CFGElement*> _members; // list of members of loop
++  GrowableArray<BlockProbPair> _exits; // list of successor blocks and their probabilities
++  float _exit_prob;       // probability any loop exit is taken on a single loop iteration
++  void update_succ_freq(Block* b, float freq);
++
++ public:
++  CFGLoop(int id) :
++    CFGElement(),
++    _id(id),
++    _depth(0),
++    _parent(NULL),
++    _sibling(NULL),
++    _child(NULL),
++    _exit_prob(1.0f) {}
++  CFGLoop* parent() { return _parent; }
++  void push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk);
++  void add_member(CFGElement *s) { _members.push(s); }
++  void add_nested_loop(CFGLoop* cl);
++  Block* head() {
++    assert(_members.at(0)->is_block(), "head must be a block");
++    Block* hd = _members.at(0)->as_Block();
++    assert(hd->_loop == this, "just checking");
++    assert(hd->head()->is_Loop(), "must begin with loop head node");
++    return hd;
++  }
++  Block* backedge_block(); // Return the block on the backedge of the loop (else NULL)
++  void compute_loop_depth(int depth);
++  void compute_freq(); // compute frequency with loop assuming head freq 1.0f
++  void scale_freq();   // scale frequency by loop trip count (including outer loops)
++  bool in_loop_nest(Block* b);
++  float trip_count() const { return 1.0f / _exit_prob; }
++  virtual bool is_loop()  { return true; }
++  int id() { return _id; }
++
++#ifndef PRODUCT
++  void dump( ) const;
++  void dump_tree() const;
++#endif
++};
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/buildOopMap.cpp openjdk/hotspot/src/share/vm/opto/buildOopMap.cpp
+--- openjdk6/hotspot/src/share/vm/opto/buildOopMap.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/buildOopMap.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)buildOopMap.cpp	1.37 07/05/05 17:06:11 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/bytecodeInfo.cpp openjdk/hotspot/src/share/vm/opto/bytecodeInfo.cpp
+--- openjdk6/hotspot/src/share/vm/opto/bytecodeInfo.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/bytecodeInfo.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)bytecodeInfo.cpp	1.122 07/05/05 17:06:12 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/c2compiler.cpp openjdk/hotspot/src/share/vm/opto/c2compiler.cpp
+--- openjdk6/hotspot/src/share/vm/opto/c2compiler.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/c2compiler.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c2compiler.cpp	1.29 07/05/05 17:06:11 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/c2compiler.hpp openjdk/hotspot/src/share/vm/opto/c2compiler.hpp
+--- openjdk6/hotspot/src/share/vm/opto/c2compiler.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/c2compiler.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c2compiler.hpp	1.28 07/05/05 17:06:11 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -57,10 +54,3 @@
+   // Print compilation timers and statistics
+   void print_timers();
+ };
+-
+-
+-
+-
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/c2_globals.cpp openjdk/hotspot/src/share/vm/opto/c2_globals.cpp
+--- openjdk6/hotspot/src/share/vm/opto/c2_globals.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/c2_globals.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)c2_globals.cpp	1.14 07/05/17 15:57:19 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/c2_globals.hpp openjdk/hotspot/src/share/vm/opto/c2_globals.hpp
+--- openjdk6/hotspot/src/share/vm/opto/c2_globals.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/c2_globals.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c2_globals.hpp	1.90 07/09/25 22:01:58 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -131,6 +128,9 @@
+   notproduct(bool, PrintOptoPeephole, false,                                \
+           "Print New compiler peephole replacements")                       \
+                                                                             \
++  develop(bool, PrintCFGBlockFreq, false,                                   \
++          "Print CFG block freqencies")                                     \
++                                                                            \
+   develop(bool, TraceOptoParse, false,                                      \
+           "Trace bytecode parse and control-flow merge")                    \
+                                                                             \
+@@ -147,6 +147,10 @@
+           "UnrollLimitForProfileCheck. A higher value allows more "         \
+           "unrolling. Zero acts as a very large value." )                   \
+                                                                             \
++  product(intx, MultiArrayExpandLimit, 6,                                   \
++          "Maximum number of individual allocations in an inline-expanded " \
++          "multianewarray instruction")                                     \
++                                                                            \
+   notproduct(bool, TraceProfileTripCount, false,                            \
+           "Trace profile loop trip count information")                      \
+                                                                             \
+@@ -159,6 +163,18 @@
+   develop(bool, UseExactTypes, true,                                        \
+           "Use exact types to eliminate array store checks and v-calls")    \
+                                                                             \
++  product(intx, TrackedInitializationLimit, 50,                             \
++          "When initializing fields, track up to this many words")          \
++                                                                            \
++  product(bool, ReduceFieldZeroing, true,                                   \
++          "When initializing fields, try to avoid needless zeroing")        \
++                                                                            \
++  product(bool, ReduceInitialCardMarks, true,                               \
++          "When initializing fields, try to avoid needless card marks")     \
++                                                                            \
++  product(bool, ReduceBulkZeroing, true,                                    \
++          "When bulk-initializing, try to avoid needless zeroing")          \
++                                                                            \
+   develop_pd(intx, RegisterCostAreaRatio,                                   \
+           "Spill selection in reg allocator: scale area by (X/64K) before " \
+           "adding cost")                                                    \
+@@ -169,7 +185,7 @@
+   notproduct(bool, VerifyGraphEdges , false,                                \
+           "Verify Bi-directional Edges")                                    \
+                                                                             \
+-  notproduct(bool, VerifyDUIterators, false,                                \
++  notproduct(bool, VerifyDUIterators, true,                                 \
+           "Verify the safety of all iterations of Bi-directional Edges")    \
+                                                                             \
+   notproduct(bool, VerifyHashTableKeys, true,                               \
+@@ -211,7 +227,7 @@
+   notproduct(bool, TraceLoopUnswitching, false,                             \
+           "Trace loop unswitching")                                         \
+                                                                             \
+-  product(bool, UseSuperWord, false,                                        \
++  product(bool, UseSuperWord, true,                                         \
+           "Transform scalar operations into superword operations")          \
+                                                                             \
+   develop(bool, SuperWordRTDepCheck, false,                                 \
+@@ -233,6 +249,20 @@
+   develop(bool, SparcV9RegsHiBitsZero, true,                                \
+           "Assume Sparc V9 I&L registers on V8+ systems are zero-extended") \
+                                                                             \
++  develop(intx, PrintIdealGraphLevel, 0,                                    \
++          "Print ideal graph to XML file / network interface. "             \
++          "By default attempts to connect to the visualizer on a socket.")  \
++                                                                            \
++  develop(intx, PrintIdealGraphPort, 4444,                                  \
++          "Ideal graph printer to network port")                            \
++                                                                            \
++  develop(ccstr, PrintIdealGraphAddress, "127.0.0.1",                       \
++          "IP address to connect to visualizer")                            \
++                                                                            \
++  develop(ccstr, PrintIdealGraphFile, NULL,                                 \
++          "File to dump ideal graph to.  If set overrides the "             \
++          "use of the network")                                             \
++                                                                            \
+   product(bool, UseOldInlining, true,                                       \
+           "Enable the 1.3 inlining strategy")                               \
+                                                                             \
+@@ -343,8 +373,10 @@
+   notproduct(bool, PrintEscapeAnalysis, false,                              \
+           "Print the results of escape analysis")                           \
+                                                                             \
++  product(bool, EliminateAllocations, true,                                 \
++          "Use escape analysis to eliminate allocations")                   \
++                                                                            \
+   product(intx, MaxLabelRootDepth, 1100, 				    \
+           "Maximum times call Label_Root to prevent stack overflow")        \
+ 
+ C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/callGenerator.cpp openjdk/hotspot/src/share/vm/opto/callGenerator.cpp
+--- openjdk6/hotspot/src/share/vm/opto/callGenerator.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/callGenerator.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)callGenerator.cpp	1.47 07/05/05 17:06:12 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -403,6 +400,11 @@
+                          CallGenerator* if_hit, float hit_prob)
+     : CallGenerator(if_missed->method())
+   {
++    // The call profile data may predict the hit_prob as extreme as 0 or 1.
++    // Remove the extremes values from the range.
++    if (hit_prob > PROB_MAX)   hit_prob = PROB_MAX;
++    if (hit_prob < PROB_MIN)   hit_prob = PROB_MIN;
++
+     _predicted_receiver = predicted_receiver;
+     _if_missed          = if_missed;
+     _if_hit             = if_hit;
+@@ -556,7 +558,17 @@
+   int nargs = method()->arg_size();
+   kit.inc_sp(nargs);
+   assert(nargs <= kit.sp() && kit.sp() <= jvms->stk_size(), "sane sp w/ args pushed");
++  if (_reason == Deoptimization::Reason_class_check &&
++      _action == Deoptimization::Action_maybe_recompile) {
++    // Temp fix for 6529811
++    // Don't allow uncommon_trap to override our decision to recompile in the event
++    // of a class cast failure for a monomorphic call as it will never let us convert
++    // the call to either bi-morphic or megamorphic and can lead to unc-trap loops
++    bool keep_exact_action = true;
++    kit.uncommon_trap(_reason, _action, NULL, "monomorphic vcall checkcast", false, keep_exact_action);
++  } else {
+   kit.uncommon_trap(_reason, _action);
++  }
+   return kit.transfer_exceptions_into_jvms();
+ }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/callGenerator.hpp openjdk/hotspot/src/share/vm/opto/callGenerator.hpp
+--- openjdk6/hotspot/src/share/vm/opto/callGenerator.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/callGenerator.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)callGenerator.hpp	1.19 07/05/05 17:06:12 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/callnode.cpp openjdk/hotspot/src/share/vm/opto/callnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/callnode.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/callnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)callnode.cpp	1.235 07/05/05 17:06:13 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -39,7 +36,7 @@
+ const Type *StartNode::bottom_type() const { return _domain; }
+ const Type *StartNode::Value(PhaseTransform *phase) const { return _domain; }
+ #ifndef PRODUCT
+-void StartNode::dump_spec() const { tty->print(" #"); _domain->dump();}
++void StartNode::dump_spec(outputStream *st) const { st->print(" #"); _domain->dump_on(st);}
+ #endif
+ 
+ //------------------------------Ideal------------------------------------------
+@@ -100,13 +97,13 @@
+ };
+ 
+ #ifndef PRODUCT
+-void ParmNode::dump_spec() const {
++void ParmNode::dump_spec(outputStream *st) const {
+   if( _con < TypeFunc::Parms ) {
+-    tty->print(names[_con]);
++    st->print(names[_con]);
+   } else {
+-    tty->print("Parm%d: ",_con-TypeFunc::Parms);
++    st->print("Parm%d: ",_con-TypeFunc::Parms);
+     // Verbose and WizardMode dump bottom_type for all nodes
+-    if( !Verbose && !WizardMode )   bottom_type()->dump();
++    if( !Verbose && !WizardMode )   bottom_type()->dump_on(st);
+   }
+ }
+ #endif
+@@ -304,42 +301,42 @@
+ // Given an allocation (a Chaitin object) and a Node decide if the Node carries
+ // any defined value or not.  If it does, print out the register or constant.
+ #ifndef PRODUCT
+-static void format_helper( PhaseRegAlloc *regalloc, Node *n, const char *msg, uint i ) {
+-  if (n == NULL) { tty->print(" NULL"); return; }
++static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i ) {
++  if (n == NULL) { st->print(" NULL"); return; }
+   if( OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined
+     char buf[50];
+     regalloc->dump_register(n,buf);
+-    tty->print(" %s%d]=%s",msg,i,buf);
++    st->print(" %s%d]=%s",msg,i,buf);
+   } else {                      // No register, but might be constant  
+     const Type *t = n->bottom_type();
+     switch (t->base()) {
+     case Type::Int:  
+-      tty->print(" %s%d]=#"INT32_FORMAT,msg,i,t->is_int()->get_con()); 
++      st->print(" %s%d]=#"INT32_FORMAT,msg,i,t->is_int()->get_con());
+       break;
+     case Type::AnyPtr: 
+       assert( t == TypePtr::NULL_PTR, "" );
+-      tty->print(" %s%d]=#NULL",msg,i);
++      st->print(" %s%d]=#NULL",msg,i);
+       break;
+     case Type::AryPtr: 
+     case Type::KlassPtr:
+     case Type::InstPtr: 
+-      tty->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop());
++      st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop());
+       break;
+     case Type::RawPtr: 
+-      tty->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr());
++      st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr());
+       break;
+     case Type::DoubleCon:
+-      tty->print(" %s%d]=#%fD",msg,i,t->is_double_constant()->_d);
++      st->print(" %s%d]=#%fD",msg,i,t->is_double_constant()->_d);
+       break;
+     case Type::FloatCon:
+-      tty->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f);
++      st->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f);
+       break;
+     case Type::Long:
+-      tty->print(" %s%d]=#"INT64_FORMAT,msg,i,t->is_long()->get_con());
++      st->print(" %s%d]=#"INT64_FORMAT,msg,i,t->is_long()->get_con());
+       break;
+     case Type::Half:
+     case Type::Top:  
+-      tty->print(" %s%d]=_",msg,i);
++      st->print(" %s%d]=_",msg,i);
+       break;
+     default: ShouldNotReachHere();
+     }
+@@ -349,13 +346,13 @@
+ 
+ //------------------------------format-----------------------------------------
+ #ifndef PRODUCT
+-void JVMState::format(PhaseRegAlloc *regalloc, const Node *n) const {
+-  tty->print("        #");
++void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const {
++  st->print("        #");
+   if( _method ) {
+-    _method->print_short_name();
+-    tty->print(" @ bci:%d ",_bci);
++    _method->print_short_name(st);
++    st->print(" @ bci:%d ",_bci);
+   } else {
+-    tty->print_cr(" runtime stub ");
++    st->print_cr(" runtime stub ");
+     return;
+   }
+   if (n->is_MachSafePoint()) {
+@@ -363,37 +360,37 @@
+     uint i;
+     // Print locals
+     for( i = 0; i < (uint)loc_size(); i++ ) 
+-      format_helper( regalloc, mcall->local(this, i), "L[", i );
++      format_helper( regalloc, st, mcall->local(this, i), "L[", i );
+     // Print stack
+     for (i = 0; i < (uint)stk_size(); i++) {
+       if ((uint)(_stkoff + i) >= mcall->len()) 
+-        tty->print(" oob ");
++        st->print(" oob ");
+       else
+-       format_helper( regalloc, mcall->stack(this, i), "STK[", i );
++       format_helper( regalloc, st, mcall->stack(this, i), "STK[", i );
+     }
+     for (i = 0; (int)i < nof_monitors(); i++) {
+       Node *box = mcall->monitor_box(this, i);
+       Node *obj = mcall->monitor_obj(this, i);
+       if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
+         while( !box->is_BoxLock() )  box = box->in(1);
+-        format_helper( regalloc, box, "MON-BOX[", i );
++        format_helper( regalloc, st, box, "MON-BOX[", i );
+       } else {
+         OptoReg::Name box_reg = BoxLockNode::stack_slot(box);
+-        tty->print(" MON-BOX%d=%s+%d",
++        st->print(" MON-BOX%d=%s+%d",
+                    i,
+                    OptoReg::regname(OptoReg::c_frame_pointer),
+                    regalloc->reg2offset(box_reg));
+       }
+-      format_helper( regalloc, obj, "MON-OBJ[", i );      
++      format_helper( regalloc, st, obj, "MON-OBJ[", i );
+     }
+   }
+-  tty->print_cr("");
+-  if (caller() != NULL)  caller()->format(regalloc, n);
++  st->print_cr("");
++  if (caller() != NULL)  caller()->format(regalloc, n, st);
+ }
+ #endif
+ 
+ #ifndef PRODUCT
+-void JVMState::dump_spec() const { 
++void JVMState::dump_spec(outputStream *st) const {
+   if (_method != NULL) {
+     bool printed = false;
+     if (!Verbose) {
+@@ -410,22 +407,22 @@
+         if (endcn == NULL)  endcn = name + strlen(name);
+         while (endcn > name && endcn[-1] != '.' && endcn[-1] != '/')
+           --endcn;
+-        tty->print(" %s", endcn);
++        st->print(" %s", endcn);
+         printed = true;
+       }
+     }
+     if (!printed)
+-      _method->print_short_name(tty);
+-    tty->print(" @ bci:%d",_bci);
++      _method->print_short_name(st);
++    st->print(" @ bci:%d",_bci);
+   } else {
+-    tty->print(" runtime stub");
++    st->print(" runtime stub");
+   }
+-  if (caller() != NULL)  caller()->dump_spec();
++  if (caller() != NULL)  caller()->dump_spec(st);
+ }
+ #endif
+ 
+ #ifndef PRODUCT
+-void JVMState::dump() const {
++void JVMState::dump_on(outputStream* st) const {
+   if (_map && !((uintptr_t)_map & 1)) {
+     if (_map->len() > _map->req()) {  // _map->has_exceptions()
+       Node* ex = _map->in(_map->req());  // _map->next_exception()
+@@ -437,20 +434,20 @@
+     }
+     _map->dump(2);
+   }
+-  tty->print("JVMS depth=%d loc=%d stk=%d mon=%d end=%d mondepth=%d sp=%d bci=%d method=",
++  st->print("JVMS depth=%d loc=%d stk=%d mon=%d end=%d mondepth=%d sp=%d bci=%d method=",
+              depth(), locoff(), stkoff(), monoff(), endoff(), monitor_depth(), sp(), bci());
+   if (_method == NULL) {
+-    tty->print_cr("(none)");
++    st->print_cr("(none)");
+   } else {
+-    _method->print_name();
+-    tty->cr();
++    _method->print_name(st);
++    st->cr();
+     if (bci() >= 0 && bci() < _method->code_size()) {
+-      tty->print("    bc: ");
+-      _method->print_codes(bci(), bci()+1);
++      st->print("    bc: ");
++      _method->print_codes_on(bci(), bci()+1, st);
+     }
+   }
+   if (caller() != NULL) {
+-    caller()->dump();
++    caller()->dump_on(st);
+   }
+ }
+ 
+@@ -500,11 +497,11 @@
+   tty->print(")");
+ }
+ 
+-void CallNode::dump_spec() const { 
+-  tty->print(" "); 
+-  tf()->dump();
+-  if (_cnt != COUNT_UNKNOWN)  tty->print(" C=%f",_cnt);
+-  if (jvms() != NULL)  jvms()->dump_spec();
++void CallNode::dump_spec(outputStream *st) const {
++  st->print(" ");
++  tf()->dump_on(st);
++  if (_cnt != COUNT_UNKNOWN)  st->print(" C=%f",_cnt);
++  if (jvms() != NULL)  jvms()->dump_spec(st);
+ }
+ #endif
+ 
+@@ -567,9 +564,9 @@
+   return CallNode::cmp(call) && _method == call._method; 
+ }
+ #ifndef PRODUCT
+-void CallJavaNode::dump_spec() const { 
+-  if( _method ) _method->print_short_name();
+-  CallNode::dump_spec();
++void CallJavaNode::dump_spec(outputStream *st) const {
++  if( _method ) _method->print_short_name(st);
++  CallNode::dump_spec(st);
+ }
+ #endif
+ 
+@@ -602,20 +599,20 @@
+ }
+ 
+ #ifndef PRODUCT
+-void CallStaticJavaNode::dump_spec() const { 
+-  tty->print("# Static ");
++void CallStaticJavaNode::dump_spec(outputStream *st) const {
++  st->print("# Static ");
+   if (_name != NULL) {
+-    tty->print("%s", _name);
++    st->print("%s", _name);
+     int trap_req = uncommon_trap_request();
+     if (trap_req != 0) {
+       char buf[100];
+-      tty->print("(%s)",
++      st->print("(%s)",
+                  Deoptimization::format_trap_request(buf, sizeof(buf),
+                                                      trap_req));
+     }
+-    tty->print(" ");
++    st->print(" ");
+   }
+-  CallJavaNode::dump_spec();
++  CallJavaNode::dump_spec(st);
+ }
+ #endif
+ 
+@@ -626,9 +623,9 @@
+   return CallJavaNode::cmp(call); 
+ }
+ #ifndef PRODUCT
+-void CallDynamicJavaNode::dump_spec() const { 
+-  tty->print("# Dynamic ");
+-  CallJavaNode::dump_spec();
++void CallDynamicJavaNode::dump_spec(outputStream *st) const {
++  st->print("# Dynamic ");
++  CallJavaNode::dump_spec(st);
+ }
+ #endif
+ 
+@@ -639,10 +636,10 @@
+   return CallNode::cmp(call) && !strcmp(_name,call._name);
+ }
+ #ifndef PRODUCT
+-void CallRuntimeNode::dump_spec() const { 
+-  tty->print("# "); 
+-  tty->print(_name);
+-  CallNode::dump_spec();
++void CallRuntimeNode::dump_spec(outputStream *st) const {
++  st->print("# ");
++  st->print(_name);
++  CallNode::dump_spec(st);
+ }
+ #endif
+ 
+@@ -657,10 +654,10 @@
+ 
+ //=============================================================================
+ #ifndef PRODUCT
+-void CallLeafNode::dump_spec() const { 
+-  tty->print("# "); 
+-  tty->print(_name);
+-  CallNode::dump_spec();
++void CallLeafNode::dump_spec(outputStream *st) const {
++  st->print("# ");
++  st->print(_name);
++  CallNode::dump_spec(st);
+ }
+ #endif
+ 
+@@ -750,8 +747,8 @@
+ }
+ 
+ #ifndef PRODUCT
+-void SafePointNode::dump_spec() const { 
+-  tty->print(" SafePoint "); 
++void SafePointNode::dump_spec(outputStream *st) const {
++  st->print(" SafePoint ");
+ }
+ #endif
+ 
+@@ -830,8 +827,7 @@
+ 
+ AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype,
+                            Node *ctrl, Node *mem, Node *abio,
+-                           Node *size, Node *klass_node, Node *initial_test,
+-                           Node *eden_top, Node *eden_end)
++                           Node *size, Node *klass_node, Node *initial_test)
+   : CallNode(atype, NULL, TypeRawPtr::BOTTOM)
+ {
+   init_class_id(Class_Allocate);
+@@ -846,8 +842,6 @@
+   init_req( AllocSize          , size);
+   init_req( KlassNode          , klass_node);
+   init_req( InitialTest        , initial_test);
+-  init_req( EdenTop            , eden_top);
+-  init_req( EdenEnd            , eden_end);
+   init_req( ALength            , topnode);
+   C->add_macro_node(this);
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/callnode.hpp openjdk/hotspot/src/share/vm/opto/callnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/callnode.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/callnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)callnode.hpp	1.192 07/05/17 15:57:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -75,7 +72,7 @@
+   virtual Node *match( const ProjNode *proj, const Matcher *m );
+   virtual uint ideal_reg() const { return 0; }
+ #ifndef PRODUCT
+-  virtual void  dump_spec() const;
++  virtual void  dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -99,7 +96,7 @@
+   virtual bool  is_CFG() const { return (_con == TypeFunc::Control); }
+   virtual uint ideal_reg() const;
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -266,9 +263,12 @@
+   JVMState* clone_shallow(Compile* C) const; // retains uncloned caller
+ 
+ #ifndef PRODUCT
+-  void      format(PhaseRegAlloc *regalloc, const Node *n) const;
+-  void      dump_spec() const;
+-  void      dump() const;
++  void      format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const;
++  void      dump_spec(outputStream *st) const;
++  void      dump_on(outputStream* st) const;
++  void      dump() const {
++    dump_on(tty);
++  }
+ #endif
+ };
+ 
+@@ -393,7 +393,7 @@
+   static  bool           needs_polling_address_input();
+ 
+ #ifndef PRODUCT
+-  virtual void              dump_spec() const;
++  virtual void              dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -445,7 +445,7 @@
+ 
+ #ifndef PRODUCT
+   virtual void        dump_req()  const;
+-  virtual void        dump_spec() const;
++  virtual void        dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -476,7 +476,7 @@
+   bool  is_optimized_virtual() const      { return _optimized_virtual; }
+ 
+ #ifndef PRODUCT
+-  virtual void  dump_spec() const;
++  virtual void  dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -507,7 +507,7 @@
+ 
+   virtual int         Opcode() const;
+ #ifndef PRODUCT
+-  virtual void        dump_spec() const;
++  virtual void        dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -524,7 +524,7 @@
+   int _vtable_index;
+   virtual int   Opcode() const;
+ #ifndef PRODUCT
+-  virtual void  dump_spec() const;
++  virtual void  dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -547,7 +547,7 @@
+   virtual void  calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const;
+ 
+ #ifndef PRODUCT
+-  virtual void  dump_spec() const;
++  virtual void  dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -565,7 +565,7 @@
+   virtual int   Opcode() const;
+   virtual bool        guaranteed_safepoint()  { return false; }
+ #ifndef PRODUCT
+-  virtual void  dump_spec() const;
++  virtual void  dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -602,8 +602,6 @@
+     AllocSize   = TypeFunc::Parms,    // size (in bytes) of the new object
+     KlassNode,                        // type (maybe dynamic) of the obj.
+     InitialTest,                      // slow-path test (may be constant)
+-    EdenTop,                          // eden pointers
+-    EdenEnd,
+     ALength,                          // array length (or TOP if none)
+     ParmLimit
+   };
+@@ -613,9 +611,7 @@
+     fields[AllocSize]   = TypeInt::POS;
+     fields[KlassNode]   = TypeInstPtr::NOTNULL;
+     fields[InitialTest] = TypeInt::BOOL;
+-    fields[EdenTop]     = TypeRawPtr::NOTNULL;
+-    fields[EdenEnd]     = TypeRawPtr::NOTNULL;
+-    fields[ALength]     = TypeInt::INT;  // length >= 0
++    fields[ALength]     = TypeInt::INT;  // length (can be a bad length)
+ 
+     const TypeTuple *domain = TypeTuple::make(ParmLimit, fields);
+ 
+@@ -630,8 +626,7 @@
+ 
+   virtual uint size_of() const; // Size is bigger
+   AllocateNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio,
+-               Node *size, Node *klass_node, Node *initial_test,
+-               Node *eden_top, Node *eden_end);
++               Node *size, Node *klass_node, Node *initial_test);
+   // Expansion modifies the JVMState, so we need to clone it
+   virtual void  clone_jvms() {
+     set_jvms(jvms()->clone_deep(Compile::current()));
+@@ -651,6 +646,7 @@
+ 
+   // Fancy version which uses AddPNode::Ideal_base_and_offset to strip
+   // an offset, which is reported back to the caller.
++  // (Note:  AllocateNode::Ideal_allocation is defined in graphKit.cpp.)
+   static AllocateNode* Ideal_allocation(Node* ptr, PhaseTransform* phase,
+                                         intptr_t& offset);
+ 
+@@ -664,6 +660,15 @@
+   int minimum_header_size() {
+     return is_AllocateArray() ? sizeof(arrayOopDesc) : sizeof(oopDesc);
+   }
++
++  // Return the corresponding initialization barrier (or null if none).
++  // Walks out edges to find it...
++  // (Note: Both InitializeNode::allocation and AllocateNode::initialization
++  // are defined in graphKit.cpp, which sets up the bidirectional relation.)
++  InitializeNode* initialization();
++
++  // Convenience for initialization->maybe_set_complete(phase)
++  bool maybe_set_complete(PhaseGVN* phase);
+ };
+ 
+ //------------------------------AllocateArray---------------------------------
+@@ -674,10 +679,10 @@
+ public:
+   AllocateArrayNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio,
+                     Node* size, Node* klass_node, Node* initial_test,
+-                    Node* eden_top, Node* eden_end, Node* count_val
++                    Node* count_val
+                     )
+     : AllocateNode(C, atype, ctrl, mem, abio, size, klass_node,
+-                   initial_test, eden_top, eden_end)
++                   initial_test)
+   {
+     init_class_id(Class_AllocateArray);
+     set_req(AllocateNode::ALength, count_val);
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/cfgnode.cpp openjdk/hotspot/src/share/vm/opto/cfgnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/cfgnode.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/cfgnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)cfgnode.cpp	1.261 08/06/22 00:57:20 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -536,9 +533,16 @@
+         } 
+         else if( n->is_Region() ) { // Update all incoming edges
+           assert( !igvn->eqv(n, this), "Must be removed from DefUse edges");
+-          for( uint k=1; k < n->req(); k++ ) 
+-            if( n->in(k) == this ) 
++          uint uses_found = 0;
++          for( uint k=1; k < n->req(); k++ ) {
++            if( n->in(k) == this ) {
+               n->set_req(k, parent_ctrl);
++              uses_found++;
++            }
++          }
++          if( uses_found > 1 ) { // (--i) done at the end of the loop.
++            i -= (uses_found - 1);
++          }
+         }
+         else {
+           assert( igvn->eqv(n->in(0), this), "Expect RegionNode to be control parent");
+@@ -1551,6 +1555,64 @@
+     if (opt != NULL)  return opt;
+   }
+ 
++  if (in(1) != NULL && in(1)->Opcode() == Op_AddP && can_reshape) {
++    // Try to undo Phi of AddP:
++    //   (Phi (AddP base base y) (AddP base2 base2 y))
++    // becomes:
++    //   newbase := (Phi base base2)
++    //   (AddP newbase newbase y)
++    //
++    // This occurs as a result of unsuccessful split_thru_phi and
++    // interferes with taking advantage of addressing modes.  See the
++    // clone_shift_expressions code in matcher.cpp
++    Node* addp = in(1);
++    const Type* type = addp->in(AddPNode::Base)->bottom_type();
++    Node* y = addp->in(AddPNode::Offset);
++    if (y != NULL && addp->in(AddPNode::Base) == addp->in(AddPNode::Address)) {
++      // make sure that all the inputs are similar to the first one,
++      // i.e. AddP with base == address and same offset as first AddP
++      bool doit = true;
++      for (uint i = 2; i < req(); i++) {
++        if (in(i) == NULL ||
++            in(i)->Opcode() != Op_AddP ||
++            in(i)->in(AddPNode::Base) != in(i)->in(AddPNode::Address) ||
++            in(i)->in(AddPNode::Offset) != y) {
++          doit = false;
++          break;
++        }
++        // Accumulate type for resulting Phi
++        type = type->meet(in(i)->in(AddPNode::Base)->bottom_type());
++      }
++      Node* base = NULL;
++      if (doit) {
++        // Check for neighboring AddP nodes in a tree.
++        // If they have a base, use that it.
++        for (DUIterator_Fast kmax, k = this->fast_outs(kmax); k < kmax; k++) {
++          Node* u = this->fast_out(k);
++          if (u->is_AddP()) {
++            Node* base2 = u->in(AddPNode::Base);
++            if (base2 != NULL && !base2->is_top()) {
++              if (base == NULL)
++                base = base2;
++              else if (base != base2)
++                { doit = false; break; }
++            }
++          }
++        }
++      }
++      if (doit) {
++        if (base == NULL) {
++          base = new (phase->C, in(0)->req()) PhiNode(in(0), type, NULL);
++          for (uint i = 1; i < req(); i++) {
++            base->init_req(i, in(i)->in(AddPNode::Base));
++          }
++          phase->is_IterGVN()->register_new_node_with_optimizer(base);
++        }
++        return new (phase->C, 4) AddPNode(base, base, y);
++      }
++    }
++  }
++
+   // Split phis through memory merges, so that the memory merges will go away.
+   // Piggy-back this transformation on the search for a unique input....
+   // It will be as if the merged memory is the unique value of the phi.
+@@ -1692,12 +1754,12 @@
+ }
+ 
+ #ifndef PRODUCT
+-void PhiNode::dump_spec() const { 
+-  TypeNode::dump_spec();
++void PhiNode::dump_spec(outputStream *st) const {
++  TypeNode::dump_spec(st);
+   if (in(0) != NULL &&
+       in(0)->is_CountedLoop() &&
+       in(0)->as_CountedLoop()->phi() == this) {
+-    tty->print(" #tripcount");
++    st->print(" #tripcount");
+   }
+ }
+ #endif
+@@ -1774,9 +1836,9 @@
+ }
+ 
+ #ifndef PRODUCT
+-void JumpProjNode::dump_spec() const { 
+-  ProjNode::dump_spec();
+-   tty->print("@bci %d ",_dest_bci);
++void JumpProjNode::dump_spec(outputStream *st) const {
++  ProjNode::dump_spec(st);
++   st->print("@bci %d ",_dest_bci);
+ }
+ #endif
+ 
+@@ -1862,9 +1924,9 @@
+ 
+ 
+ #ifndef PRODUCT
+-void CatchProjNode::dump_spec() const { 
+-  ProjNode::dump_spec();
+-  tty->print("@bci %d ",_handler_bci);
++void CatchProjNode::dump_spec(outputStream *st) const {
++  ProjNode::dump_spec(st);
++  st->print("@bci %d ",_handler_bci);
+ }
+ #endif
+ 
+@@ -1886,8 +1948,7 @@
+ 
+ //=============================================================================
+ #ifndef PRODUCT
+-void NeverBranchNode::format( PhaseRegAlloc *ra_ ) const {
+-  tty->print("%s", Name());
++void NeverBranchNode::format( PhaseRegAlloc *ra_, outputStream *st) const {
++  st->print("%s", Name());
+ }
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/cfgnode.hpp openjdk/hotspot/src/share/vm/opto/cfgnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/cfgnode.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/cfgnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)cfgnode.hpp	1.115 07/05/05 17:06:11 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -170,7 +167,7 @@
+   virtual const RegMask &out_RegMask() const;
+   virtual const RegMask &in_RegMask(uint) const;
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ #ifdef ASSERT
+   void verify_adr_type(VectorSet& visited, const TypePtr* at) const;
+@@ -316,7 +313,7 @@
+   static Node* up_one_dom(Node* curr, bool linear_only = false);
+ 
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -398,7 +395,7 @@
+   int  switch_val()  const { return _switch_val; }
+   uint proj_no()     const { return _proj_no; }
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -445,7 +442,7 @@
+   int  handler_bci() const        { return _handler_bci; }
+   bool is_handler_proj() const    { return _handler_bci >= 0; }
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -479,7 +476,6 @@
+   virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { }
+   virtual uint size(PhaseRegAlloc *ra_) const { return 0; }
+ #ifndef PRODUCT
+-  virtual void format( PhaseRegAlloc * ) const;
++  virtual void format( PhaseRegAlloc *, outputStream *st ) const;
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/chaitin.cpp openjdk/hotspot/src/share/vm/opto/chaitin.cpp
+--- openjdk6/hotspot/src/share/vm/opto/chaitin.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/chaitin.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)chaitin.cpp	1.115 07/05/05 17:06:11 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1685,8 +1682,8 @@
+     tty->print("L%d",r);
+     tty->print("/N%d ",m->_idx);
+   }
+-  if( n->is_Mach() ) n->as_Mach()->dump_spec();
+-  else n->dump_spec();
++  if( n->is_Mach() ) n->as_Mach()->dump_spec(tty);
++  else n->dump_spec(tty);
+   if( _spilled_once.test(n->_idx ) ) {
+     tty->print(" Spill_1");
+     if( _spilled_twice.test(n->_idx ) ) 
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/chaitin.hpp openjdk/hotspot/src/share/vm/opto/chaitin.hpp
+--- openjdk6/hotspot/src/share/vm/opto/chaitin.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/chaitin.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)chaitin.hpp	1.159 07/05/05 17:06:09 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -295,7 +292,6 @@
+   VectorSet _spilled_twice;     // Nodes that have been spilled twice
+ 
+   LRG_List _names;              // Map from Nodes to Live RanGes
+-  uint n2lidx( const Node *n ) const { return _names[n->_idx]; }
+ 
+   // Union-find map.  Declared as a short for speed.
+   // Indexed by live-range number, it returns the compacted live-range number
+@@ -359,6 +355,8 @@
+   // Do all the real work of allocate
+   void Register_Allocate();
+ 
++  uint n2lidx( const Node *n ) const { return _names[n->_idx]; }
++
+ #ifndef PRODUCT
+   bool trace_spilling() const { return _trace_spilling; }
+ #endif
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/classes.cpp openjdk/hotspot/src/share/vm/opto/classes.cpp
+--- openjdk6/hotspot/src/share/vm/opto/classes.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/classes.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)classes.cpp	1.31 07/05/05 17:06:12 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -35,4 +32,3 @@
+ #define macro(x) int x##Node::Opcode() const { return Op_##x; }
+ #include "classes.hpp"
+ #undef macro
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/classes.hpp openjdk/hotspot/src/share/vm/opto/classes.hpp
+--- openjdk6/hotspot/src/share/vm/opto/classes.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/classes.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)classes.hpp	1.177 07/05/05 17:06:12 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -118,6 +115,7 @@
+ macro(If)
+ macro(IfFalse)
+ macro(IfTrue)
++macro(Initialize)
+ macro(JProj)
+ macro(Jump)
+ macro(JumpProj)
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/coalesce.cpp openjdk/hotspot/src/share/vm/opto/coalesce.cpp
+--- openjdk6/hotspot/src/share/vm/opto/coalesce.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/coalesce.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)coalesce.cpp	1.195 07/05/17 17:43:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -218,7 +215,7 @@
+         }
+       
+       // Dump node-specific info
+-      n->dump_spec();
++      n->dump_spec(tty);
+       tty->print("\n");
+       
+     }
+@@ -916,4 +913,3 @@
+     */
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/coalesce.hpp openjdk/hotspot/src/share/vm/opto/coalesce.hpp
+--- openjdk6/hotspot/src/share/vm/opto/coalesce.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/coalesce.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)coalesce.hpp	1.44 07/05/05 17:06:14 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -110,4 +107,3 @@
+ 
+   void update_ifg(uint lr1, uint lr2, IndexSet *n_lr1, IndexSet *n_lr2);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/compile.cpp openjdk/hotspot/src/share/vm/opto/compile.cpp
+--- openjdk6/hotspot/src/share/vm/opto/compile.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/compile.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compile.cpp	1.631 07/05/17 15:57:33 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -313,8 +310,13 @@
+   compile->init_type_arena();
+   Type::Initialize(compile);
+   _compile->set_scratch_buffer_blob(NULL);
++  _compile->begin_method();
+ }
+ CompileWrapper::~CompileWrapper() {
++  if (_compile->failing()) {
++    _compile->print_method("Failed");
++  }
++  _compile->end_method();
+   if (_compile->scratch_buffer_blob() != NULL)
+     BufferBlob::free(_compile->scratch_buffer_blob());
+   _compile->env()->set_compiler_data(NULL);
+@@ -436,6 +438,7 @@
+                   _node_bundling_base(NULL),
+ #ifndef PRODUCT
+                   _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")),
++                  _printer(IdealGraphPrinter::printer()),
+ #endif
+                   _congraph(NULL) {
+   C = this;
+@@ -561,6 +564,12 @@
+ 
+   // Drain the list.
+   Finish_Warm();
++#ifndef PRODUCT
++  if (_printer) {
++    _printer->print_inlining(this);
++  }
++#endif
++
+   if (failing())  return;
+   NOT_PRODUCT( verify_graph_edges(); )
+ 
+@@ -672,6 +681,7 @@
+     _node_bundling_base(NULL),
+ #ifndef PRODUCT
+     _trace_opto_output(TraceOptoOutput),
++    _printer(NULL),
+ #endif
+     _congraph(NULL) {
+   C = this;
+@@ -763,6 +773,7 @@
+   set_root(new (this, 3) RootNode());
+   // Now that you have a Root to point to, create the real TOP
+   set_cached_top_node( new (this, 1) ConNode(Type::TOP) );
++  set_recent_alloc(NULL, NULL);
+ 
+   // Create Debug Information Recorder to record scopes, oopmaps, etc.
+   env()->set_oop_recorder(new OopRecorder(comp_arena()));
+@@ -1177,7 +1188,7 @@
+         st->print(" +any");
+   else  st->print(" +%-3d", offset);
+   st->print(" in ");
+-  adr_type()->dump();
++  adr_type()->dump_on(st);
+   const TypeOopPtr* tjp = adr_type()->isa_oopptr();
+   if (field() != NULL && tjp) {
+     if (tjp->klass()  != field()->holder() ||
+@@ -1447,6 +1458,8 @@
+ 
+   NOT_PRODUCT( verify_graph_edges(); )
+ 
++  print_method("Start");
++
+  {
+   // Iterative Global Value Numbering, including ideal transforms
+   // Initialize IterGVN with types and values from parse-time GVN
+@@ -1455,6 +1468,9 @@
+     NOT_PRODUCT( TracePhase t2("iterGVN", &_t_iterGVN, TimeCompiler); )
+     igvn.optimize();
+   }
++
++  print_method("Iter GVN 1", 2);
++
+   if (failing())  return;
+ 
+   // get rid of the connection graph since it's information is not
+@@ -1472,6 +1488,7 @@
+       TracePhase t2("idealLoop", &_t_idealLoop, true);
+       PhaseIdealLoop ideal_loop( igvn, NULL, true );
+       loop_opts_cnt--;
++      if (major_progress()) print_method("PhaseIdealLoop 1", 2);
+       if (failing())  return;
+     }
+     // Loop opts pass if partial peeling occurred in previous pass
+@@ -1479,6 +1496,7 @@
+       TracePhase t3("idealLoop", &_t_idealLoop, true);
+       PhaseIdealLoop ideal_loop( igvn, NULL, false );
+       loop_opts_cnt--;
++      if (major_progress()) print_method("PhaseIdealLoop 2", 2);
+       if (failing())  return;
+     }
+     // Loop opts pass for loop-unrolling before CCP
+@@ -1486,6 +1504,7 @@
+       TracePhase t4("idealLoop", &_t_idealLoop, true);
+       PhaseIdealLoop ideal_loop( igvn, NULL, false );
+       loop_opts_cnt--;
++      if (major_progress()) print_method("PhaseIdealLoop 3", 2);
+     }
+   }
+   if (failing())  return;
+@@ -1497,6 +1516,8 @@
+     TracePhase t2("ccp", &_t_ccp, true);
+     ccp.do_transform();
+   }
++  print_method("PhaseCPP 1", 2);
++
+   assert( true, "Break here to ccp.dump_old2new_map()");
+     
+   // Iterative Global Value Numbering, including ideal transforms
+@@ -1505,6 +1526,9 @@
+     igvn = ccp;
+     igvn.optimize();
+   }
++
++  print_method("Iter GVN 2", 2);
++
+   if (failing())  return;
+ 
+   // Loop transforms on the ideal graph.  Range Check Elimination,
+@@ -1516,6 +1540,7 @@
+       assert( cnt++ < 40, "infinite cycle in loop optimization" );
+       PhaseIdealLoop ideal_loop( igvn, NULL, true );
+       loop_opts_cnt--;
++      if (major_progress()) print_method("PhaseIdealLoop iterations", 2);
+       if (failing())  return;
+     }
+   }
+@@ -1538,6 +1563,8 @@
+       return;
+     }
+   }
++
++  print_method("Optimize finished", 2);
+ }
+ 
+ 
+@@ -1583,6 +1610,9 @@
+ 
+     cfg.Estimate_Block_Frequency();
+     cfg.GlobalCodeMotion(m,unique(),proj_list);
++
++    print_method("Global code motion", 2);
++
+     if (failing())  return;
+     NOT_PRODUCT( verify_graph_edges(); )
+ 
+@@ -1635,6 +1665,8 @@
+     Output();
+   }
+ 
++  print_method("End");
++
+   // He's dead, Jim.
+   _cfg     = (PhaseCFG*)0xdeadbeef;
+   _regalloc = (PhaseChaitin*)0xdeadbeef;
+@@ -1703,7 +1735,7 @@
+         tty->print(" %c ", starts_bundle);
+         starts_bundle = ' ';
+         tty->print("\t");
+-        n->format(_regalloc);
++        n->format(_regalloc, tty);
+         tty->cr();
+       }
+ 
+@@ -1720,7 +1752,7 @@
+         tty->print(" %c ", starts_bundle);
+         starts_bundle = ' ';
+         tty->print("\t");
+-        delay->format(_regalloc);
++        delay->format(_regalloc, tty);
+         tty->print_cr("");
+         delay = NULL;
+       }
+@@ -2123,17 +2155,28 @@
+           CallNode *call = n->in(0)->in(0)->as_Call();
+           if (call->entry_point() == OptoRuntime::rethrow_stub()) {
+             expected_kids--;      // Rethrow always has 1 less kid
+-          } else if (call->req() > TypeFunc::Parms) {
++          } else if (call->req() > TypeFunc::Parms &&
++                     call->is_CallDynamicJava()) {
+             // Check for null receiver. In such case, the optimizer has 
+             // detected that the virtual call will always result in a null 
+             // pointer exception. The fall-through projection of this CatchNode 
+             // will not be populated.
+             Node *arg0 = call->in(TypeFunc::Parms);
+-            if (call->is_CallDynamicJava() &&
+-                arg0->is_Type() &&
++            if (arg0->is_Type() &&
+                 arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { 
+               expected_kids--;
+             }
++          } else if (call->entry_point() == OptoRuntime::new_array_Java() &&
++                     call->req() > TypeFunc::Parms+1 &&
++                     call->is_CallStaticJava()) {
++            // Check for negative array length. In such case, the optimizer has
++            // detected that the allocation attempt will always result in an
++            // exception. There is no fall-through projection of this CatchNode .
++            Node *arg1 = call->in(TypeFunc::Parms+1);
++            if (arg1->is_Type() &&
++                arg1->as_Type()->type()->join(TypeInt::POS)->empty()) {
++              expected_kids--;
++            }
+           }
+         }
+       }
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/compile.hpp openjdk/hotspot/src/share/vm/opto/compile.hpp
+--- openjdk6/hotspot/src/share/vm/opto/compile.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/compile.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compile.hpp	1.230 07/05/17 15:57:38 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -174,6 +171,9 @@
+   GrowableArray<CallGenerator*>* _intrinsics;   // List of intrinsics.
+   GrowableArray<Node*>* _macro_nodes;           // List of nodes which need to be expanded before matching.
+   ConnectionGraph*      _congraph;
++#ifndef PRODUCT
++  IdealGraphPrinter*    _printer;
++#endif
+ 
+   // Node management
+   uint                  _unique;                // Counter for unique Node indices
+@@ -185,6 +185,9 @@
+ 
+   Node*                 _immutable_memory;      // Initial memory state
+ 
++  Node*                 _recent_alloc_obj;
++  Node*                 _recent_alloc_ctl;
++
+   // Blocked array of debugging and profiling information,
+   // tracked per node.
+   enum { _log2_node_notes_block_size = 8,
+@@ -316,6 +319,23 @@
+ #ifndef PRODUCT
+   bool          trace_opto_output() const       { return _trace_opto_output; }
+ #endif
++
++  void begin_method() {
++#ifndef PRODUCT
++    if (_printer) _printer->begin_method(this);
++#endif
++  }
++  void print_method(const char * name, int level = 1) {
++#ifndef PRODUCT
++    if (_printer) _printer->print_method(this, name, level);
++#endif
++  }
++  void end_method() {
++#ifndef PRODUCT
++    if (_printer) _printer->end_method();
++#endif
++  }
++
+   int           macro_count()                   { return _macro_nodes->length(); }
+   Node*         macro_node(int idx)             { return _macro_nodes->at(idx); }
+   ConnectionGraph* congraph()                   { return _congraph;}
+@@ -373,6 +393,13 @@
+   void         init_start(StartNode* s);
+   Node*             immutable_memory();
+ 
++  Node*             recent_alloc_ctl() const    { return _recent_alloc_ctl; }
++  Node*             recent_alloc_obj() const    { return _recent_alloc_obj; }
++  void          set_recent_alloc(Node* ctl, Node* obj) {
++                                                  _recent_alloc_ctl = ctl;
++                                                  _recent_alloc_obj = obj;
++                                                }
++
+   // Handy undefined Node
+   Node*             top() const                 { return _top; }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/connode.cpp openjdk/hotspot/src/share/vm/opto/connode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/connode.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/connode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)connode.cpp	1.217 07/05/17 15:57:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -780,7 +777,7 @@
+   // remove this node's type assertion until no more loop ops can happen.
+   // The progress bit is set in the major loop optimizations THEN comes the
+   // call to IterGVN and any chance of hitting this code.  Cf. Opaque1Node.
+-  if (!phase->C->major_progress()) {
++  if (can_reshape && !phase->C->major_progress()) {
+     const TypeInt* in_type = phase->type(in(1))->isa_int();
+     if (in_type != NULL && this_type != NULL &&
+         (in_type->_lo != this_type->_lo ||
+@@ -790,12 +787,34 @@
+       // of slightly differing type assertions.  Such slight differences
+       // arise routinely as a result of loop unrolling, so this is a
+       // post-unrolling graph cleanup.  Choose a type which depends only
+-      // on my input.
+-      set_type(TypeLong::make(in_type->_lo, in_type->_hi, in_type->_widen));
++      // on my input.  (Exception:  Keep a range assertion of >=0 or <0.)
++      jlong lo1 = this_type->_lo;
++      jlong hi1 = this_type->_hi;
++      int   w1  = this_type->_widen;
++      if (lo1 != (jint)lo1 ||
++          hi1 != (jint)hi1 ||
++          lo1 > hi1) {
++        // Overflow leads to wraparound, wraparound leads to range saturation.
++        lo1 = min_jint; hi1 = max_jint;
++      } else if (lo1 >= 0) {
++        // Keep a range assertion of >=0.
++        lo1 = 0;        hi1 = max_jint;
++      } else if (hi1 < 0) {
++        // Keep a range assertion of <0.
++        lo1 = min_jint; hi1 = -1;
++      } else {
++        lo1 = min_jint; hi1 = max_jint;
++      }
++      const TypeLong* wtype = TypeLong::make(MAX2((jlong)in_type->_lo, lo1),
++                                             MIN2((jlong)in_type->_hi, hi1),
++                                             MAX2((int)in_type->_widen, w1));
++      if (wtype != type()) {
++        set_type(wtype);
+       // Note: this_type still has old type value, for the logic below.
+       this_changed = this;
+     }
+   }
++  }
+ 
+ #ifdef _LP64
+   // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y)) ,
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/connode.hpp openjdk/hotspot/src/share/vm/opto/connode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/connode.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/connode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)connode.hpp	1.160 07/05/05 17:06:13 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/divnode.cpp openjdk/hotspot/src/share/vm/opto/divnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/divnode.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/divnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)divnode.cpp	1.88 07/05/05 17:06:13 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/divnode.hpp openjdk/hotspot/src/share/vm/opto/divnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/divnode.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/divnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)divnode.hpp	1.31 07/05/05 17:06:16 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -178,4 +175,3 @@
+   // Make a divmod and associated projections from a div or mod.
+   static DivModLNode* make(Compile* C, Node* div_or_mod);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/doCall.cpp openjdk/hotspot/src/share/vm/opto/doCall.cpp
+--- openjdk6/hotspot/src/share/vm/opto/doCall.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/doCall.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)doCall.cpp	1.206 07/05/17 15:57:45 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -151,8 +148,8 @@
+           (profile.morphism() == 2 && UseBimorphicInlining)) {
+         // receiver_method = profile.method();
+         // Profiles do not suggest methods now.  Look it up in the major receiver.
+-        ciInstanceKlass* ik = profile.receiver(0)->as_instance_klass();
+-        receiver_method = call_method->resolve_invoke(jvms->method()->holder(), ik);
++        receiver_method = call_method->resolve_invoke(jvms->method()->holder(),
++                                                      profile.receiver(0));
+       }
+       if (receiver_method != NULL) {
+         // The single majority receiver sufficiently outweighs the minority.
+@@ -163,8 +160,8 @@
+           CallGenerator* next_hit_cg = NULL;
+           ciMethod* next_receiver_method = NULL;
+           if (profile.morphism() == 2 && UseBimorphicInlining) { 
+-            ciInstanceKlass* next_ik = profile.receiver(1)->as_instance_klass();
+-            next_receiver_method = call_method->resolve_invoke(jvms->method()->holder(), next_ik);
++            next_receiver_method = call_method->resolve_invoke(jvms->method()->holder(),
++                                                               profile.receiver(1));
+             if (next_receiver_method != NULL) {
+               next_hit_cg = this->call_generator(next_receiver_method, 
+                                   vtable_index, !call_is_virtual, jvms, 
+@@ -313,7 +310,7 @@
+   // Try to get the most accurate receiver type
+   if (is_virtual_or_interface) {
+     Node*              receiver_node = stack(sp() - nargs);
+-    const TypeInstPtr* receiver_type = _gvn.type(receiver_node)->isa_instptr();
++    const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr();
+     ciMethod* optimized_virtual_method = optimize_inlining(method(), bci(), klass, dest_method, receiver_type);
+ 
+     // Have the call been sufficiently improved such that it is no longer a virtual?
+@@ -768,7 +765,7 @@
+ 
+ // Identify possible target method and inlining style
+ ciMethod* Parse::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, 
+-                                   ciMethod *dest_method, const TypeInstPtr* receiver_type) {
++                                   ciMethod *dest_method, const TypeOopPtr* receiver_type) {
+   // only use for virtual or interface calls
+ 
+   // If it is obviously final, do not bother to call find_monomorphic_target,
+@@ -783,6 +780,17 @@
+   bool actual_receiver_is_exact = false;
+   ciInstanceKlass* actual_receiver = klass;
+   if (receiver_type != NULL) {
++    // Array methods are all inherited from Object, and are monomorphic.
++    if (receiver_type->isa_aryptr() &&
++        dest_method->holder() == env()->Object_klass()) {
++      return dest_method;
++    }
++
++    // All other interesting cases are instance klasses.
++    if (!receiver_type->isa_instptr()) {
++      return NULL;
++    }
++
+     ciInstanceKlass *ikl = receiver_type->klass()->as_instance_klass();
+     if (ikl->is_loaded() && ikl->is_initialized() && !ikl->is_interface() &&
+         (ikl == actual_receiver || ikl->is_subclass_of(actual_receiver))) {
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/domgraph.cpp openjdk/hotspot/src/share/vm/opto/domgraph.cpp
+--- openjdk6/hotspot/src/share/vm/opto/domgraph.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/domgraph.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)domgraph.cpp	1.75 07/05/05 17:06:16 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -281,7 +278,9 @@
+     }
+     else {
+       // Build a reverse post-order in the CFG _blocks array
+-      _blocks.map(--_rpo_ctr, bstack.pop());
++      Block *stack_top = bstack.pop();
++      stack_top->_rpo = --_rpo_ctr;
++      _blocks.map(stack_top->_rpo, stack_top);
+     }
+   }
+   return pre_order;
+@@ -663,4 +662,3 @@
+ 
+ }
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/escape.cpp openjdk/hotspot/src/share/vm/opto/escape.cpp
+--- openjdk6/hotspot/src/share/vm/opto/escape.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/escape.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)escape.cpp	1.10 07/05/17 15:58:23 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/escape.hpp openjdk/hotspot/src/share/vm/opto/escape.hpp
+--- openjdk6/hotspot/src/share/vm/opto/escape.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/escape.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)escape.hpp	1.9 07/05/17 15:58:25 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -320,4 +317,3 @@
+   void dump();
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/gcm.cpp openjdk/hotspot/src/share/vm/opto/gcm.cpp
+--- openjdk6/hotspot/src/share/vm/opto/gcm.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/gcm.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)gcm.cpp	1.251 07/05/17 15:58:45 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -743,7 +740,7 @@
+       
+     // Now schedule all uses as late as possible.
+     uint src           = self->is_Proj() ? self->in(0)->_idx : self->_idx;
+-    uint src_pre_order = _bbs[src]->_pre_order;
++    uint src_rpo = _bbs[src]->_rpo;
+       
+     // Schedule all nodes in a post-order visit
+     Node *unvisited = NULL;  // Unvisited anti-dependent Node, if any
+@@ -759,13 +756,13 @@
+ 
+       // do not traverse backward control edges
+       Node *use = n->is_Proj() ? n->in(0) : n;
+-      uint use_pre_order = _bbs[use->_idx]->_pre_order;
++      uint use_rpo = _bbs[use->_idx]->_rpo;
+ 
+-      if ( use_pre_order < src_pre_order )
++      if ( use_rpo < src_rpo )
+         continue;
+ 
+       // Phi nodes always precede uses in a basic block
+-      if ( use_pre_order == src_pre_order && use->is_Phi() )
++      if ( use_rpo == src_rpo && use->is_Phi() )
+         continue;
+ 
+       unvisited = n;      // Found unvisited
+@@ -1314,323 +1311,457 @@
+ #endif
+ }
+ 
+-#define MAXFREQ BLOCK_FREQUENCY(1e35f)
+-#define MINFREQ BLOCK_FREQUENCY(1e-35f)
+ 
+ //------------------------------Estimate_Block_Frequency-----------------------
+ // Estimate block frequencies based on IfNode probabilities.
+-// Two pass algorithm does a forward propagation in the first pass with some
+-// correction factors where static predictions are needed.  Then, the second
+-// pass pushes through changes caused by back edges.  This will give "exact"
+-// results for all dynamic frequencies, and for all staticly predicted code
+-// with loop nesting depth of one or less.  Static predictions with greater
+-// than nesting depth of one are already subject to so many static fudge
+-// factors that it is not worth iterating to a fixed point.
+ void PhaseCFG::Estimate_Block_Frequency() {
+-  assert( _blocks[0] == _broot, "" );
+   int cnts = C->method() ? C->method()->interpreter_invocation_count() : 1;
+   // Most of our algorithms will die horribly if frequency can become
+   // negative so make sure cnts is a sane value.
+   if( cnts <= 0 ) cnts = 1;
+   float f = (float)cnts/(float)FreqCountInvocations;
+-  _broot->_freq = f;
+-  _broot->_cnt  = f;
+-  // Do a two pass propagation of frequency information
+-  // PASS 1: Walk the blocks in RPO, propagating frequency info
+-  uint i;
+-  for( i = 0; i < _num_blocks; i++ ) {
++
++  // Create the loop tree and calculate loop depth.
++  _root_loop = create_loop_tree();
++  _root_loop->compute_loop_depth(0);
++
++  // Compute block frequency of each block, relative to a single loop entry.
++  _root_loop->compute_freq();
++
++  // Adjust all frequencies to be relative to a single method entry
++  _root_loop->_freq = f * 1.0;
++  _root_loop->scale_freq();
++
++  // force paths ending at uncommon traps to be infrequent
++  Block_List worklist;
++  Block* root_blk = _blocks[0];
++  for (uint i = 0; i < root_blk->num_preds(); i++) {
++    Block *pb = _bbs[root_blk->pred(i)->_idx];
++    if (pb->has_uncommon_code()) {
++      worklist.push(pb);
++    }
++  }
++  while (worklist.size() > 0) {
++    Block* uct = worklist.pop();
++    uct->_freq = PROB_MIN;
++    for (uint i = 0; i < uct->num_preds(); i++) {
++      Block *pb = _bbs[uct->pred(i)->_idx];
++      if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
++        worklist.push(pb);
++      }
++    }
++  }
++
++#ifndef PRODUCT
++  if (PrintCFGBlockFreq) {
++    tty->print_cr("CFG Block Frequencies");
++    _root_loop->dump_tree();
++    if (Verbose) {
++      tty->print_cr("PhaseCFG dump");
++      dump();
++      tty->print_cr("Node dump");
++      _root->dump(99999);
++    }
++  }
++#endif
++}
++
++//----------------------------create_loop_tree--------------------------------
++// Create a loop tree from the CFG
++CFGLoop* PhaseCFG::create_loop_tree() {
++
++#ifdef ASSERT
++  assert( _blocks[0] == _broot, "" );
++  for (uint i = 0; i < _num_blocks; i++ ) {
+     Block *b = _blocks[i];
++    // Check that _loop field are clear...we could clear them if not.
++    assert(b->_loop == NULL, "clear _loop expected");
++    // Sanity check that the RPO numbering is reflected in the _blocks array.
++    // It doesn't have to be for the loop tree to be built, but if it is not,
++    // then the blocks have been reordered since dom graph building...which
++    // may question the RPO numbering
++    assert(b->_rpo == i, "unexpected reverse post order number");
++  }
++#endif
++
++  int idct = 0;
++  CFGLoop* root_loop = new CFGLoop(idct++);
+ 
+-    // Make any necessary modifications to b's frequency
+-    int hop = b->head()->Opcode();
+-    // On first trip, scale loop heads by 10 if no counts are available
+-    if( (hop == Op_Loop || hop == Op_CountedLoop) &&
+-        (b->_cnt == COUNT_UNKNOWN) && (b->_freq < MAXFREQ) ) {
+-      // Try to figure out how much to scale the loop by; look for a
+-      // gating loop-exit test with "reasonable" back-branch
+-      // frequency.
+-
+-      // Try and find a real loop-back controlling edge and use that
+-      // frequency. If we can't find it, use the old default of 10
+-      // otherwise use the new value. This helps loops with low
+-      // frequency (like allocation contention loops with -UseTLE).
+-      // Note special treatment below of LoopNode::EntryControl edges.      
+-      Block *loopprior = b;          
+-      Block *loopback = _bbs[b->pred(LoopNode::LoopBackControl)->_idx];
+-      // See if this block ends in a test (probably not) or just a
+-      // goto the loop head.
+-      if( loopback->_num_succs == 1 &&
+-          loopback->num_preds() == 2 ) {
+-        loopprior = loopback;
+-        // NOTE: constant 1 here isn't magic, it's just that there's exactly 1
+-        // predecessor (checked just above) and predecessors are 1-based, so
+-        // the "1" refers to the first (and only) predecessor.
+-        loopback = _bbs[loopprior->pred(1)->_idx];
+-      }
+-      // Call the edge frequency leading from loopback to loopprior f.
+-      // Then scale the loop by 1/(1-f).  Thus a loop-back edge
+-      // frequency of 0.9 leads to a scale factor of 10.
+-      float f = 0.9f;           // Default scale factor
+-
+-      if( loopback->_num_succs == 2 ) {
+-        int eidx = loopback->end_idx();
+-        Node *mn = loopback->_nodes[eidx]; // Get ending Node
+-        if( mn->is_MachIf() ) {
+-          // MachIfNode has branch probability info
+-          f = mn->as_MachIf()->_prob;
+-          int taken = (loopback->_succs[1] == loopprior);
+-          assert( loopback->_succs[taken] == loopprior, "" );
+-          if( loopback->_nodes[eidx+1+taken]->Opcode() == Op_IfFalse ) 
+-            f = 1-f;              // Inverted branch sense
+-          if( f > 0.99f )         // Limit scale to 100
+-            f = 0.99f;
++  Block_List worklist;
++
++  // Assign blocks to loops
++  for(uint i = _num_blocks - 1; i > 0; i-- ) { // skip Root block
++    Block *b = _blocks[i];
++
++    if (b->head()->is_Loop()) {
++      Block* loop_head = b;
++      assert(loop_head->num_preds() - 1 == 2, "loop must have 2 predecessors");
++      Node* tail_n = loop_head->pred(LoopNode::LoopBackControl);
++      Block* tail = _bbs[tail_n->_idx];
++
++      // Defensively filter out Loop nodes for non-single-entry loops.
++      // For all reasonable loops, the head occurs before the tail in RPO.
++      if (i <= tail->_rpo) {
++
++        // The tail and (recursive) predecessors of the tail
++        // are made members of a new loop.
++
++        assert(worklist.size() == 0, "nonempty worklist");
++        CFGLoop* nloop = new CFGLoop(idct++);
++        assert(loop_head->_loop == NULL, "just checking");
++        loop_head->_loop = nloop;
++        // Add to nloop so push_pred() will skip over inner loops
++        nloop->add_member(loop_head);
++        nloop->push_pred(loop_head, LoopNode::LoopBackControl, worklist, _bbs);
++
++        while (worklist.size() > 0) {
++          Block* member = worklist.pop();
++          if (member != loop_head) {
++            for (uint j = 1; j < member->num_preds(); j++) {
++              nloop->push_pred(member, j, worklist, _bbs);
++            }
++          }
++        }
++      }
+         }
+       }
+       
+-      // Scale loop head by this much
+-      b->_freq *= 1/(1-f);
+-      assert(b->_freq > 0.0f,"Bad frequency assignment");
+-    }
+-
+-    // Push b's frequency to successors
+-    int eidx = b->end_idx();    
+-    Node *n = b->_nodes[eidx];  // Get ending Node
+-    int op = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : n->Opcode();
+-    // Switch on branch type
+-    switch( op ) {
+-    // Conditionals pass on only part of their frequency and count
+-    case Op_CountedLoopEnd:
+-    case Op_If: {
+-      int taken  = 0;  // this is the index of the TAKEN path
+-      int ntaken = 1;  // this is the index of the NOT TAKEN path
+-      // If succ[0] is the FALSE branch, invert path info
+-      if( b->_nodes[eidx+1]->Opcode() == Op_IfFalse ) {
+-        taken  = 1;
+-        ntaken = 0;
++  // Create a member list for each loop consisting
++  // of both blocks and (immediate child) loops.
++  for (uint i = 0; i < _num_blocks; i++) {
++    Block *b = _blocks[i];
++    CFGLoop* lp = b->_loop;
++    if (lp == NULL) {
++      // Not assigned to a loop. Add it to the method's pseudo loop.
++      b->_loop = root_loop;
++      lp = root_loop;
+       }
+-      float prob  = n->as_MachIf()->_prob;
+-      float nprob = 1.0f - prob;
+-      float cnt   = n->as_MachIf()->_fcnt;
+-      // If branch frequency info is available, use it
+-      if(cnt != COUNT_UNKNOWN) {
+-        float tcnt = b->_succs[taken]->_cnt;
+-        float ncnt = b->_succs[ntaken]->_cnt;
+-        // Taken Branch
+-        b->_succs[taken]->_freq += prob * cnt;
+-        b->_succs[taken]->_cnt = (tcnt == COUNT_UNKNOWN) ? (prob * cnt) : tcnt + (prob * cnt);
+-        // Not Taken Branch
+-        b->_succs[ntaken]->_freq += nprob * cnt;
+-        b->_succs[ntaken]->_cnt = (ncnt == COUNT_UNKNOWN) ? (nprob * cnt) : ncnt + (nprob * cnt);
+-      }
+-      // Otherwise, split frequency amongst children
+-      else {
+-        b->_succs[taken]->_freq  +=  prob * b->_freq;
+-        b->_succs[ntaken]->_freq += nprob * b->_freq;
+-      }
+-      // Special case for underflow caused by infrequent branches
+-      if(b->_succs[taken]->_freq < MINFREQ) b->_succs[taken]->_freq = MINFREQ;
+-      if(b->_succs[ntaken]->_freq < MINFREQ) b->_succs[ntaken]->_freq = MINFREQ;
+-      assert(b->_succs[0]->has_valid_counts(),"Bad frequency/count");
+-      assert(b->_succs[1]->has_valid_counts(),"Bad frequency/count");
+-      break;
++    if (lp == root_loop || b != lp->head()) { // loop heads are already members
++      lp->add_member(b);
+     }
+-    case Op_NeverBranch:  {
+-      b->_succs[0]->_freq += b->_freq;
+-      // Special case for underflow caused by infrequent branches
+-      if(b->_succs[0]->_freq < MINFREQ) b->_succs[0]->_freq = MINFREQ;
+-      if(b->_succs[1]->_freq < MINFREQ) b->_succs[1]->_freq = MINFREQ;
+-      break;
++    if (lp != root_loop) {
++      if (lp->parent() == NULL) {
++        // Not a nested loop. Make it a child of the method's pseudo loop.
++        root_loop->add_nested_loop(lp);
+     }
+-      // Split frequency amongst children
+-    case Op_Jump: {
+-      // Divide the frequency between all successors evenly
+-      float predfreq = b->_freq/b->_num_succs;
+-      float predcnt = COUNT_UNKNOWN;
+-      for (uint j = 0; j < b->_num_succs; j++) {
+-        b->_succs[j]->_freq += predfreq;
+-        if (b->_succs[j]->_freq < MINFREQ) {
+-          b->_succs[j]->_freq = MINFREQ;
++      if (b == lp->head()) {
++        // Add nested loop to member list of parent loop.
++        lp->parent()->add_member(lp);
+         }
+-        assert(b->_succs[j]->has_valid_counts(), "Bad frequency/count");
+       }
+-      break;
+     }      
+-      // Split frequency amongst children
+-    case Op_Catch: {
+-      // Fall-thru path gets the lion's share.
+-      float fall = (1.0f - PROB_UNLIKELY_MAG(5)*b->_num_succs)*b->_freq;
+-      // Exception exits are uncommon.
+-      float expt = PROB_UNLIKELY_MAG(5) * b->_freq;
+-      // Iterate over children pushing out frequency
+-      for( uint j = 0; j < b->_num_succs; j++ ) {
+-        const CatchProjNode *x = b->_nodes[eidx+1+j]->as_CatchProj();
+-        b->_succs[j]->_freq += 
+-          ((x->_con == CatchProjNode::fall_through_index) ? fall : expt);
+-        // Special case for underflow caused by nested catches
+-        if(b->_succs[j]->_freq < MINFREQ) b->_succs[j]->_freq = MINFREQ;
+-        assert(b->_succs[j]->has_valid_counts(), "Bad Catch frequency/count assignment");
++
++  return root_loop;
++}
++
++//------------------------------push_pred--------------------------------------
++void CFGLoop::push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk) {
++  Node* pred_n = blk->pred(i);
++  Block* pred = node_to_blk[pred_n->_idx];
++  CFGLoop *pred_loop = pred->_loop;
++  if (pred_loop == NULL) {
++    // Filter out blocks for non-single-entry loops.
++    // For all reasonable loops, the head occurs before the tail in RPO.
++    if (pred->_rpo > head()->_rpo) {
++      pred->_loop = this;
++      worklist.push(pred);
++    }
++  } else if (pred_loop != this) {
++    // Nested loop.
++    while (pred_loop->_parent != NULL && pred_loop->_parent != this) {
++      pred_loop = pred_loop->_parent;
++    }
++    // Make pred's loop be a child
++    if (pred_loop->_parent == NULL) {
++      add_nested_loop(pred_loop);
++      // Continue with loop entry predecessor.
++      Block* pred_head = pred_loop->head();
++      assert(pred_head->num_preds() - 1 == 2, "loop must have 2 predecessors");
++      assert(pred_head != head(), "loop head in only one loop");
++      push_pred(pred_head, LoopNode::EntryControl, worklist, node_to_blk);
++    } else {
++      assert(pred_loop->_parent == this && _parent == NULL, "just checking");
+       }
+-      break;
+     }
+-    // Pass frequency straight thru to target
+-    case Op_Root:
+-    case Op_Goto: {
+-      Block *bs = b->_succs[0];
+-      int hop = bs->head()->Opcode();
+-      bool notloop = (hop != Op_Loop && hop != Op_CountedLoop);
+-      // Pass count straight thru to target (except for loops)
+-      if( notloop && b->_cnt != COUNT_UNKNOWN ) {
+-        if( bs->_cnt == COUNT_UNKNOWN )
+-          bs->_cnt = 0;
+-        bs->_cnt += b->_cnt;
+-      }
+-      // Loops and counted loops have already had their heads scaled
+-      // by an amount which accounts for the backedge (but not their
+-      // entry).  Add frequency for normal blocks and loop entries.
+-      // Note special treatment above of LoopNode::LoopBackControl edges.
+-      if( notloop || bs->_freq <= 0 /*this is needed for irreducible loops*/||
+-          _bbs[bs->pred(LoopNode::EntryControl)->_idx] == b )
+-        bs->_freq += b->_freq;
++}
+ 
+-      assert(bs->has_valid_counts(), "Bad goto frequency/count assignment");
+-      break;
++//------------------------------add_nested_loop--------------------------------
++// Make cl a child of the current loop in the loop tree.
++void CFGLoop::add_nested_loop(CFGLoop* cl) {
++  assert(_parent == NULL, "no parent yet");
++  assert(cl != this, "not my own parent");
++  cl->_parent = this;
++  CFGLoop* ch = _child;
++  if (ch == NULL) {
++    _child = cl;
++  } else {
++    while (ch->_sibling != NULL) { ch = ch->_sibling; }
++    ch->_sibling = cl;
+     }
+-    // Do not push out freq to root block
+-    case Op_TailCall:
+-    case Op_TailJump:
+-    case Op_Return:
+-    case Op_Halt:
+-    case Op_Rethrow:
+-      break;
+-    default: 
+-      ShouldNotReachHere();
+-    } // End switch(op)
+-    assert(b->has_valid_counts(), "Bad first pass frequency/count");
+-  } // End for all blocks
++}
+ 
++//------------------------------compute_loop_depth-----------------------------
++// Store the loop depth in each CFGLoop object.
++// Recursively walk the children to do the same for them.
++void CFGLoop::compute_loop_depth(int depth) {
++  _depth = depth;
++  CFGLoop* ch = _child;
++  while (ch != NULL) {
++    ch->compute_loop_depth(depth + 1);
++    ch = ch->_sibling;
++  }
++}
+ 
+-  // PASS 2: Fix up loop bodies
+-  for( i = 1; i < _num_blocks; i++ ) {
+-    Block *b = _blocks[i];
+-    float freq = 0.0f;
+-    float cnt  = COUNT_UNKNOWN;
+-    // If it ends in a Halt or call marked uncommon, assume the block is uncommon.
+-    Node* be = b->end();
+-    if (be->is_Goto())
+-      be = be->in(0);
+-    if (be->is_Catch())
+-      be = be->in(0);
+-    if (be->is_Proj() && be->in(0)->is_MachCall()) {
+-      MachCallNode* call = be->in(0)->as_MachCall();
+-      if (call->cnt() != COUNT_UNKNOWN && call->cnt() <= PROB_UNLIKELY_MAG(4)) {
+-        // This is true for slow-path stubs like new_{instance,array},
+-        // slow_arraycopy, complete_monitor_locking, uncommon_trap.
+-        // The magic number corresponds to the probability of an uncommon_trap,
+-        // even though it is a count not a probability.
+-        if (b->_freq > BLOCK_FREQUENCY(1e-6))
+-          b->_freq = BLOCK_FREQUENCY(1e-6f);
+-        continue;
++//------------------------------compute_freq-----------------------------------
++// Compute the frequency of each block and loop, relative to a single entry
++// into the dominating loop head.
++void CFGLoop::compute_freq() {
++  // Bottom up traversal of loop tree (visit inner loops first.)
++  // Set loop head frequency to 1.0, then transitively
++  // compute frequency for all successors in the loop,
++  // as well as for each exit edge.  Inner loops are
++  // treated as single blocks with loop exit targets
++  // as the successor blocks.
++
++  // Nested loops first
++  CFGLoop* ch = _child;
++  while (ch != NULL) {
++    ch->compute_freq();
++    ch = ch->_sibling;
++  }
++  assert (_members.length() > 0, "no empty loops");
++  Block* hd = head();
++  hd->_freq = 1.0f;
++  for (int i = 0; i < _members.length(); i++) {
++    CFGElement* s = _members.at(i);
++    float freq = s->_freq;
++    if (s->is_block()) {
++      Block* b = s->as_Block();
++      for (uint j = 0; j < b->_num_succs; j++) {
++        Block* sb = b->_succs[j];
++        update_succ_freq(sb, freq * b->succ_prob(j));
++      }
++    } else {
++      CFGLoop* lp = s->as_CFGLoop();
++      assert(lp->_parent == this, "immediate child");
++      for (int k = 0; k < lp->_exits.length(); k++) {
++        Block* eb = lp->_exits.at(k).get_target();
++        float prob = lp->_exits.at(k).get_prob();
++        update_succ_freq(eb, freq * prob);
+       }
+     }
+-    if (be->is_Mach() && be->as_Mach()->ideal_Opcode() == Op_Halt) {
+-      if( b->_freq > BLOCK_FREQUENCY(1e-6) )
+-        b->_freq = BLOCK_FREQUENCY(1e-6f);
+-      continue;
+     }
+ 
+-    // Recompute frequency based upon predecessors' frequencies
+-    for(uint j = 1; j < b->num_preds(); j++) {
+-      // Compute the frequency passed along this path
+-      Node *pred = b->head()->in(j);
+-      // Peek through projections
+-      if(pred->is_Proj()) pred = pred->in(0);
+-      // Grab the predecessor block's frequency
+-      Block *pblock = _bbs[pred->_idx];
+-      float predfreq = pblock->_freq;
+-      float predcnt = pblock->_cnt;
+-      // Properly modify the frequency for this exit path
+-      int op = pred->is_Mach() ? pred->as_Mach()->ideal_Opcode() : pred->Opcode();
++#if 0
++  // Raise frequency of the loop backedge block, in an effort
++  // to keep it empty.  Skip the method level "loop".
++  if (_parent != NULL) {
++    CFGElement* s = _members.at(_members.length() - 1);
++    if (s->is_block()) {
++      Block* bk = s->as_Block();
++      if (bk->_num_succs == 1 && bk->_succs[0] == hd) {
++        // almost any value >= 1.0f works
++        // FIXME: raw constant
++        bk->_freq = 1.05f;
++      }
++    }
++  }
++#endif
++
++  // For all loops other than the outer, "method" loop,
++  // sum and normalize the exit probability. The "method" loop
++  // should keep the initial exit probability of 1, so that
++  // inner blocks do not get erroneously scaled.
++  if (_depth != 0) {
++    // Total the exit probabilities for this loop.
++    float exits_sum = 0.0f;
++    for (int i = 0; i < _exits.length(); i++) {
++      exits_sum += _exits.at(i).get_prob();
++    }
++
++    // Normalize the exit probabilities. Until now, the
++    // probabilities estimate the possibility of exit per
++    // a single loop iteration; afterward, they estimate
++    // the probability of exit per loop entry.
++    for (int i = 0; i < _exits.length(); i++) {
++      Block* et = _exits.at(i).get_target();
++      float new_prob = _exits.at(i).get_prob() / exits_sum;
++      BlockProbPair bpp(et, new_prob);
++      _exits.at_put(i, bpp);
++    }
++
++    // Save the total, but guard against unreasoable probability,
++    // as the value is used to estimate the loop trip count.
++    // An infinite trip count would blur relative block
++    // frequencies.
++    if (exits_sum > 1.0f) exits_sum = 1.0;
++    if (exits_sum < PROB_MIN) exits_sum = PROB_MIN;
++    _exit_prob = exits_sum;
++  }
++}
++
++//------------------------------succ_prob-------------------------------------
++// Determine the probability of reaching successor 'i' from the receiver block.
++float Block::succ_prob(uint i) {
++  int eidx = end_idx();
++  Node *n = _nodes[eidx];  // Get ending Node
++  int op = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : n->Opcode();
++
+       // Switch on branch type
+-      switch(op) {
+-      // Conditionals pass on only part of their frequency and count
++  switch( op ) {
+       case Op_CountedLoopEnd:
+       case Op_If: {
+-        float prob = pred->as_MachIf()->_prob;
+-        float cnt  = pred->as_MachIf()->_fcnt;
+-        bool path  = true;
+-        // Is this the TRUE branch or the FALSE branch?
+-        if( b->head()->in(j)->Opcode() == Op_IfFalse )
+-          path = false;
+-        // If branch frequency info is available, use it
+-        if(cnt != COUNT_UNKNOWN) {
+-          predfreq = (path) ? (prob * cnt) : ((1.0f-prob) * cnt);
+-          predcnt  = (path) ? (prob * cnt) : ((1.0f-prob) * cnt);
+-        }
+-        // Otherwise, split frequency amongst children
+-        else {
+-          predfreq = (path) ? (prob * predfreq) : ((1.0f-prob) * predfreq);
+-          predcnt  = COUNT_UNKNOWN;
++    assert (i < 2, "just checking");
++    // Conditionals pass on only part of their frequency
++    float prob  = n->as_MachIf()->_prob;
++    assert(prob >= 0.0 && prob <= 1.0, "out of range probability");
++    // If succ[i] is the FALSE branch, invert path info
++    if( _nodes[i + eidx + 1]->Opcode() == Op_IfFalse ) {
++      return 1.0f - prob; // not taken
++    } else {
++      return prob; // taken
+         }
+-        if( predfreq < MINFREQ ) predfreq = MINFREQ;
+-
+-        // Raise frequency of the loop backedge block, in an effort
+-        // to keep it empty.  Must raise it by 10%+ because counted
+-        // loops normally keep a 90/10 exit ratio.
+-        if( op == Op_CountedLoopEnd && b->num_preds() == 2 && path == true )
+-          predfreq *= 1.15f;
+-        break;
+       }
+-        // Catch splits frequency amongst multiple children
+-      case Op_Jump: {
++
++  case Op_Jump:
+         // Divide the frequency between all successors evenly
+-        predfreq = predfreq / pblock->_num_succs;
+-        predcnt = COUNT_UNKNOWN;
+-        if (predfreq < MINFREQ) predfreq = MINFREQ;
+-        break;
+-      }
+-      // Catch splits frequency amongst multiple children, favoring
+-      // fall through
++    return 1.0f/_num_succs;
++
+       case Op_Catch: {
++    const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
++    if (ci->_con == CatchProjNode::fall_through_index) {
+         // Fall-thru path gets the lion's share.
+-        float fall  = (1.0f - PROB_UNLIKELY_MAG(5)*pblock->_num_succs)*predfreq;
+-        // Exception exits are uncommon.
+-        float expt  = PROB_UNLIKELY_MAG(5) * predfreq;
+-        // Determine if this is fall-thru path
+-        const CatchProjNode *x = b->head()->in(j)->as_CatchProj();
+-        predfreq = (x->_con == CatchProjNode::fall_through_index) ? fall :expt;
+-        predcnt  = COUNT_UNKNOWN;
+-        if(predfreq < MINFREQ) predfreq = MINFREQ;
+-        break;
++      return 1.0f - PROB_UNLIKELY_MAG(5)*_num_succs;
++    } else {
++      // Presume exceptional paths are equally unlikely
++      return PROB_UNLIKELY_MAG(5);
+       }
+-      // Pass frequency straight thru to target
++  }
++
+       case Op_Root:
+       case Op_Goto:
+-      case Op_Start:
++    // Pass frequency straight thru to target
++    return 1.0f;
++
+       case Op_NeverBranch:
+-        break;
+-      // These do not push out a frequency or count
++    return 0.0f;
++
+       case Op_TailCall:
+       case Op_TailJump:
+       case Op_Return:
+       case Op_Halt:
+       case Op_Rethrow:
+-        predfreq = 0.0f;
+-        predcnt = COUNT_UNKNOWN;
+-        break;
++    // Do not push out freq to root block
++    return 0.0f;
++
+       default: 
+         ShouldNotReachHere();
+-      } // End switch(op)
+-      assert(predfreq > 0.0f,"Bad intermediate frequency");
+-      assert((predcnt > 0.0f) || (predcnt == COUNT_UNKNOWN),"Bad intermediate count");
+-      // Accumulate frequency from predecessor block
+-      freq += predfreq;
+-      if (predcnt != COUNT_UNKNOWN) {
+-        cnt = (cnt == COUNT_UNKNOWN) ? predcnt : cnt + predcnt;
+       }
++
++  return 0.0f;
++}
++
++//------------------------------update_succ_freq-------------------------------
++// Update the appropriate frequency associated with block 'b', a succesor of
++// a block in this loop.
++void CFGLoop::update_succ_freq(Block* b, float freq) {
++  if (b->_loop == this) {
++    if (b == head()) {
++      // back branch within the loop
++      // Do nothing now, the loop carried frequency will be
++      // adjust later in scale_freq().
++    } else {
++      // simple branch within the loop
++      b->_freq += freq;
++    }
++  } else if (!in_loop_nest(b)) {
++    // branch is exit from this loop
++    BlockProbPair bpp(b, freq);
++    _exits.append(bpp);
++  } else {
++    // branch into nested loop
++    CFGLoop* ch = b->_loop;
++    ch->_freq += freq;
++  }
++}
++
++//------------------------------in_loop_nest-----------------------------------
++// Determine if block b is in the receiver's loop nest.
++bool CFGLoop::in_loop_nest(Block* b) {
++  int depth = _depth;
++  CFGLoop* b_loop = b->_loop;
++  int b_depth = b_loop->_depth;
++  if (depth == b_depth) {
++    return true;
++  }
++  while (b_depth > depth) {
++    b_loop = b_loop->_parent;
++    b_depth = b_loop->_depth;
+     }
+-    // Assign new frequency
+-    b->_freq = freq;
+-    b->_cnt = cnt;
+-    assert(b->has_valid_counts(), "Bad final frequency/count assignment");
+-  } // End for all blocks
++  return b_loop == this;
+ }
++
++//------------------------------scale_freq-------------------------------------
++// Scale frequency of loops and blocks by trip counts from outer loops
++// Do a top down traversal of loop tree (visit outer loops first.)
++void CFGLoop::scale_freq() {
++  float loop_freq = _freq * trip_count();
++  for (int i = 0; i < _members.length(); i++) {
++    CFGElement* s = _members.at(i);
++    s->_freq *= loop_freq;
++  }
++  CFGLoop* ch = _child;
++  while (ch != NULL) {
++    ch->scale_freq();
++    ch = ch->_sibling;
++  }
++}
++
++#ifndef PRODUCT
++//------------------------------dump_tree--------------------------------------
++void CFGLoop::dump_tree() const {
++  dump();
++  if (_child != NULL)   _child->dump_tree();
++  if (_sibling != NULL) _sibling->dump_tree();
++}
++
++//------------------------------dump-------------------------------------------
++void CFGLoop::dump() const {
++  for (int i = 0; i < _depth; i++) tty->print("   ");
++  tty->print("%s: %d  trip_count: %6.0f freq: %6.0f\n",
++             _depth == 0 ? "Method" : "Loop", _id, trip_count(), _freq);
++  for (int i = 0; i < _depth; i++) tty->print("   ");
++  tty->print("         members:", _id);
++  int k = 0;
++  for (int i = 0; i < _members.length(); i++) {
++    if (k++ >= 6) {
++      tty->print("\n              ");
++      for (int j = 0; j < _depth+1; j++) tty->print("   ");
++      k = 0;
++    }
++    CFGElement *s = _members.at(i);
++    if (s->is_block()) {
++      Block *b = s->as_Block();
++      tty->print(" B%d(%6.3f)", b->_pre_order, b->_freq);
++    } else {
++      CFGLoop* lp = s->as_CFGLoop();
++      tty->print(" L%d(%6.3f)", lp->_id, lp->_freq);
++    }
++  }
++  tty->print("\n");
++  for (int i = 0; i < _depth; i++) tty->print("   ");
++  tty->print("         exits:  ");
++  k = 0;
++  for (int i = 0; i < _exits.length(); i++) {
++    if (k++ >= 7) {
++      tty->print("\n              ");
++      for (int j = 0; j < _depth+1; j++) tty->print("   ");
++      k = 0;
++    }
++    Block *blk = _exits.at(i).get_target();
++    float prob = _exits.at(i).get_prob();
++    tty->print(" ->%d@%d%%", blk->_pre_order, (int)(prob*100));
++  }
++  tty->print("\n");
++}
++#endif
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/generateOptoStub.cpp openjdk/hotspot/src/share/vm/opto/generateOptoStub.cpp
+--- openjdk6/hotspot/src/share/vm/opto/generateOptoStub.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/generateOptoStub.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)generateOptoStub.cpp	1.101 07/05/05 17:06:17 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -292,4 +289,3 @@
+   }
+   root()->add_req(_gvn.transform(ret));
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/graphKit.cpp openjdk/hotspot/src/share/vm/opto/graphKit.cpp
+--- openjdk6/hotspot/src/share/vm/opto/graphKit.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/graphKit.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)graphKit.cpp	1.128 07/05/17 17:43:32 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -541,11 +538,10 @@
+       // Weblogic sometimes mutates the detail message of exceptions 
+       // using reflection.
+       int offset = java_lang_Throwable::get_detailMessage_offset();
+-      uint alias_idx = C->get_alias_index(ex_con->add_offset(offset));
++      const TypePtr* adr_typ = ex_con->add_offset(offset);
+       
+       Node *adr = basic_plus_adr(ex_node, ex_node, offset);
+-      Node *store = store_to_memory(control(), adr, null(), T_OBJECT, alias_idx, false);
+-      store_barrier(store, T_OBJECT, ex_node, adr, null());
++      Node *store = store_oop_to_object(control(), ex_node, adr, adr_typ, null(), ex_con, T_OBJECT);
+         
+       add_exception_state(make_exception_state(ex_node));
+       return;
+@@ -1352,6 +1348,102 @@
+   return st;
+ }
+ 
++void GraphKit::pre_barrier(Node* ctl,
++                           Node* obj,
++                           Node* adr,
++                           uint adr_idx,
++                           Node *val,
++                           const Type* val_type,
++                           BasicType bt) {
++  BarrierSet* bs = Universe::heap()->barrier_set();
++  set_control(ctl);
++  switch (bs->kind()) {
++
++    case BarrierSet::CardTableModRef:
++    case BarrierSet::CardTableExtension:
++    case BarrierSet::ModRef:
++      break;
++
++    case BarrierSet::Other:
++    default      :
++      ShouldNotReachHere();
++
++  }
++}
++
++void GraphKit::post_barrier(Node* ctl,
++                            Node* store,
++                            Node* obj,
++                            Node* adr,
++                            uint adr_idx,
++                            Node *val,
++                            BasicType bt,
++                            bool use_precise) {
++  BarrierSet* bs = Universe::heap()->barrier_set();
++  set_control(ctl);
++  switch (bs->kind()) {
++
++    case BarrierSet::CardTableModRef:
++    case BarrierSet::CardTableExtension:
++      write_barrier_post(store, obj, adr, val, use_precise);
++      break;
++
++    case BarrierSet::ModRef:
++      break;
++
++    case BarrierSet::Other:
++    default      :
++      ShouldNotReachHere();
++
++  }
++}
++
++Node* GraphKit::store_oop_to_object(Node* ctl,
++                                    Node* obj,
++                                    Node* adr,
++                                    const TypePtr* adr_type,
++                                    Node *val,
++                                    const Type* val_type,
++                                    BasicType bt) {
++  uint adr_idx = C->get_alias_index(adr_type);
++  Node* store;
++  pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt);
++  store = store_to_memory(control(), adr, val, bt, adr_idx);
++  post_barrier(control(), store, obj, adr, adr_idx, val, bt, false);
++  return store;
++}
++
++Node* GraphKit::store_oop_to_array(Node* ctl,
++                                   Node* obj,
++                                   Node* adr,
++                                   const TypePtr* adr_type,
++                                   Node *val,
++                                   const Type* val_type,
++                                   BasicType bt) {
++  uint adr_idx = C->get_alias_index(adr_type);
++  Node* store;
++  pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt);
++  store = store_to_memory(control(), adr, val, bt, adr_idx);
++  post_barrier(control(), store, obj, adr, adr_idx, val, bt, true);
++  return store;
++}
++
++Node* GraphKit::store_oop_to_unknown(Node* ctl,
++                                     Node* obj,
++                                     Node* adr,
++                                     const TypePtr* adr_type,
++                                     Node *val,
++                                     const Type* val_type,
++                                     BasicType bt) {
++  uint adr_idx = C->get_alias_index(adr_type);
++  Node* store;
++  pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt);
++  store = store_to_memory(control(), adr, val, bt, adr_idx);
++  post_barrier(control(), store, obj, adr, adr_idx, val, bt, true);
++  return store;
++}
++
++
+ //-------------------------array_element_address-------------------------
+ Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt,
+                                       const TypeInt* sizetype) {
+@@ -1537,7 +1629,8 @@
+ // right debug info.  
+ void GraphKit::uncommon_trap(int trap_request,
+                              ciKlass* klass, const char* comment,
+-                             bool must_throw) {
++                             bool must_throw,
++                             bool keep_exact_action) {
+   if (failing())  stop();
+   if (stopped())  return; // trap reachable?
+ 
+@@ -1564,8 +1657,11 @@
+   switch (action) {
+   case Deoptimization::Action_maybe_recompile:
+   case Deoptimization::Action_reinterpret:
+-    if (Deoptimization::trap_request_index(trap_request) < 0
+-        && too_many_recompiles(reason)) {
++    // Temporary fix for 6529811 to allow virtual calls to be sure they
++    // get the chance to go from mono->bi->mega
++    if (!keep_exact_action &&
++        Deoptimization::trap_request_index(trap_request) < 0 &&
++        too_many_recompiles(reason)) {
+       // This BCI is causing too many recompilations.
+       action = Deoptimization::Action_none;
+       trap_request = Deoptimization::make_trap_request(reason, action);
+@@ -1646,30 +1742,55 @@
+ }
+ 
+ 
++//--------------------------just_allocated_object------------------------------
++// Report the object that was just allocated.
++// It must be the case that there are no intervening safepoints.
++// We use this to determine if an object is so "fresh" that
++// it does not require card marks.
++Node* GraphKit::just_allocated_object(Node* current_control) {
++  if (C->recent_alloc_ctl() == current_control)
++    return C->recent_alloc_obj();
++  return NULL;
++}
++
++
+ //------------------------------store_barrier----------------------------------
+ // Insert a write-barrier store.  This is to let generational GC work; we have 
+ // to flag all oop-stores before the next GC point.
+-void GraphKit::store_barrier(Node* oop_store, BasicType obj_type,
+-                             Node* obj, Node* adr, Node* val) {
++void GraphKit::write_barrier_post(Node* oop_store, Node* obj, Node* adr,
++                                  Node* val, bool use_precise) {
+   // No store check needed if we're storing a NULL or an old object
+   // (latter case is probably a string constant). The concurrent
+   // mark sweep garbage collector, however, needs to have all nonNull
+   // oop updates flagged via card-marks.
+-  if (val != NULL && val->is_Con() &&
+-      (!UseConcMarkSweepGC || val->bottom_type() == TypePtr::NULL_PTR)) {
++  if (val != NULL && val->is_Con()) {
+     // must be either an oop or NULL
+     const Type* t = val->bottom_type();
+-    assert( t == Type::TOP || t == TypePtr::NULL_PTR || t->is_oopptr()->const_oop() != NULL,
+-            "must be either a constant oop or NULL");
++    if (t == TypePtr::NULL_PTR || t == Type::TOP)
++      // stores of null never (?) need barriers
++      return;
++    ciObject* con = t->is_oopptr()->const_oop();
++    if (con != NULL
++        && con->is_perm()
++        && Universe::heap()->can_elide_permanent_oop_store_barriers())
+     // no store barrier needed, because no old-to-new ref created
+     return;
+   }
+ 
+-  if (obj_type == T_OBJECT) {
++  if (use_ReduceInitialCardMarks()
++      && obj == just_allocated_object(control())) {
++    // We can skip marks on a freshly-allocated object.
++    // Keep this code in sync with do_eager_card_mark in runtime.cpp.
++    // That routine eagerly marks the occasional object which is produced
++    // by the slow path, so that we don't have to do it here.
++    return;
++  }
++
++  if (!use_precise) {
+     // All card marks for a (non-array) instance are in one place:
+     adr = obj;
+   }
+-  // (Else it's an array, and we want more precise card marks.)
++  // (Else it's an array (or unknown), and we want more precise card marks.)
+   assert(adr != NULL, "");
+ 
+   // Get the alias_index for raw card-mark memory
+@@ -1681,9 +1802,8 @@
+          "Only one we handle so far.");
+   CardTableModRefBS* ct =
+     (CardTableModRefBS*)(Universe::heap()->barrier_set());
+-  Node *a = _gvn.transform(new (C, 3) URShiftXNode( cast, _gvn.intcon(CardTableModRefBS::card_shift) ));
++  Node *b = _gvn.transform(new (C, 3) URShiftXNode( cast, _gvn.intcon(CardTableModRefBS::card_shift) ));
+   // We store into a byte array, so do not bother to left-shift by zero
+-  Node *b = a;
+   // Get base of card map
+   assert(sizeof(*ct->byte_map_base) == sizeof(jbyte),
+          "adjust this code");
+@@ -2483,6 +2603,7 @@
+   if (alias_idx == Compile::AliasIdxBot) {
+     mb->set_req(TypeFunc::Memory, merged_memory()->base_memory());
+   } else {
++    assert(!(opcode == Op_Initialize && alias_idx != Compile::AliasIdxRaw), "fix caller");
+     mb->set_req(TypeFunc::Memory, memory(alias_idx));
+   }
+   Node* membar = _gvn.transform(mb);
+@@ -2602,21 +2723,6 @@
+   map()->pop_monitor( );
+ }
+ 
+-//---------------------------set_eden_pointers-------------------------
+-void GraphKit::set_eden_pointers( Node * &eden_top_adr, Node * &eden_end_adr) {
+-  CollectedHeap* ch = Universe::heap();
+-  if( UseTLAB ) {               // Private allocation: load from TLS
+-    Node *thread = _gvn.transform(new (C, 1) ThreadLocalNode());
+-    eden_top_adr = _gvn.transform( new (C, 4) AddPNode(top()/*not oop*/, thread, _gvn.MakeConX( in_bytes(JavaThread::tlab_top_offset()))));
+-    eden_end_adr = _gvn.transform( new (C, 4) AddPNode(top()/*not oop*/, thread, _gvn.MakeConX( in_bytes(JavaThread::tlab_end_offset()))));
+-  } else {                      // Shared allocation: load from globals
+-    address top_adr = (address)ch->top_addr();
+-    address end_adr = (address)ch->end_addr();
+-    eden_top_adr = makecon(TypeRawPtr::make(top_adr));
+-    eden_end_adr = basic_plus_adr( eden_top_adr, eden_top_adr, end_adr - top_adr );
+-  }
+-}
+-
+ //-------------------------------get_layout_helper-----------------------------
+ // If the given klass is a constant or known to be an array,
+ // fetch the constant layout helper value into constant_value
+@@ -2642,6 +2748,19 @@
+   return make_load(NULL, lhp, TypeInt::INT, T_INT);
+ }
+ 
++// We just put in an allocate/initialize with a big raw-memory effect.
++// Hook selected additional alias categories on the initialization.
++static void hook_memory_on_init(GraphKit& kit, int alias_idx,
++                                MergeMemNode* init_in_merge,
++                                Node* init_out_raw) {
++  DEBUG_ONLY(Node* init_in_raw = init_in_merge->base_memory());
++  assert(init_in_merge->memory_at(alias_idx) == init_in_raw, "");
++
++  Node* prevmem = kit.memory(alias_idx);
++  init_in_merge->set_memory_at(alias_idx, prevmem);
++  kit.set_memory(init_out_raw, alias_idx);
++}
++
+ //---------------------------set_output_for_allocation-------------------------
+ Node* GraphKit::set_output_for_allocation(AllocateNode* alloc,
+                                           const TypeOopPtr* oop_type,
+@@ -2664,9 +2783,45 @@
+   set_i_o(_gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::I_O, false) ) );
+   Node* rawoop = _gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::Parms) );
+  
++  // put in an initialization barrier
++  InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, rawidx,
++                                                 rawoop)->as_Initialize();
++  assert(alloc->initialization() == init,  "2-way macro link must work");
++  assert(init ->allocation()     == alloc, "2-way macro link must work");
++  if (ReduceFieldZeroing && !raw_mem_only) {
++    // Extract memory strands which may participate in the new object's
++    // initialization, and source them from the new InitializeNode.
++    // This will allow us to observe initializations when they occur,
++    // and link them properly (as a group) to the InitializeNode.
++    Node* klass_node = alloc->in(AllocateNode::KlassNode);
++    assert(init->in(InitializeNode::Memory) == malloc, "");
++    MergeMemNode* minit_in = MergeMemNode::make(C, malloc);
++    init->set_req(InitializeNode::Memory, minit_in);
++    record_for_igvn(minit_in); // fold it up later, if possible
++    Node* minit_out = memory(rawidx);
++    assert(minit_out->is_Proj() && minit_out->in(0) == init, "");
++    if (oop_type->isa_aryptr()) {
++      const TypePtr* telemref = oop_type->add_offset(Type::OffsetBot);
++      int            elemidx  = C->get_alias_index(telemref);
++      hook_memory_on_init(*this, elemidx, minit_in, minit_out);
++    } else if (oop_type->isa_instptr()) {
++      ciInstanceKlass* ik = oop_type->klass()->as_instance_klass();
++      for (int i = 0, len = ik->nof_nonstatic_fields(); i < len; i++) {
++        ciField* field = ik->nonstatic_field_at(i);
++        if (field->offset() >= TrackedInitializationLimit)
++          continue;  // do not bother to track really large numbers of fields
++        // Find (or create) the alias category for this field:
++        int fieldidx = C->alias_type(field)->index();
++        hook_memory_on_init(*this, fieldidx, minit_in, minit_out);
++      }
++    }
++  }
++
+   // Cast raw oop to the real thing...
+   Node* javaoop = new (C, 2) CheckCastPPNode(control(), rawoop, oop_type);
+   javaoop = _gvn.transform(javaoop);
++  C->set_recent_alloc(control(), javaoop);
++  assert(just_allocated_object(control()) == javaoop, "just allocated");
+  
+ #ifdef ASSERT
+   { // Verify that the AllocateNode::Ideal_foo recognizers work:
+@@ -2703,7 +2858,6 @@
+                              Node* extra_slow_test,
+                              bool raw_mem_only, // affect only raw memory
+                              Node* *return_size_val) {
+-
+   // Compute size in doublewords
+   // The size is always an integral number of doublewords, represented
+   // as a positive bytewise size stored in the klass's layout_helper.
+@@ -2713,7 +2867,6 @@
+   int   layout_is_con = (layout_val == NULL);
+ 
+   if (extra_slow_test == NULL)  extra_slow_test = intcon(0);
+-
+   // Generate the initial go-slow test.  It's either ALWAYS (return a
+   // Node for 1) or NEVER (return a NULL) or perhaps (in the reflective
+   // case) a computed value derived from the layout_helper.
+@@ -2761,16 +2914,12 @@
+   const TypeOopPtr* oop_type = tklass->as_instance_type();
+ 
+   // Now generate allocation code
+-  Node *eden_top_adr;
+-  Node *eden_end_adr;
+-  set_eden_pointers(eden_top_adr, eden_end_adr);
+-
+   AllocateNode* alloc
+     = new (C, AllocateNode::ParmLimit)
+         AllocateNode(C, AllocateNode::alloc_type(),
+                      control(), memory(Compile::AliasIdxRaw), i_o(),
+                      size, klass_node,
+-                     initial_slow_test, eden_top_adr, eden_end_adr);
++                     initial_slow_test);
+ 
+   return set_output_for_allocation(alloc, oop_type, raw_mem_only);
+ }
+@@ -2832,10 +2981,11 @@
+   int round_mask = MinObjAlignmentInBytes - 1;
+   Node* header_size = NULL;
+   int   header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE);
+-  // (T_BYTE has the smallest alignment restriction...)
++  // (T_BYTE has the weakest alignment and size restrictions...)
+   if (layout_is_con) {
+     int hsize  = Klass::layout_helper_header_size(layout_con);
+     int eshift = Klass::layout_helper_log2_element_size(layout_con);
++    BasicType etype  = Klass::layout_helper_element_type(layout_con);
+     if ((round_mask & ~right_n_bits(eshift)) == 0)
+       round_mask = 0;  // strength-reduce it if it goes away completely
+     assert((hsize & right_n_bits(eshift)) == 0, "hsize is pre-rounded");
+@@ -2866,6 +3016,17 @@
+   // Transition to native address size for all offset calculations:
+   Node* lengthx = ConvI2X(length);
+   Node* headerx = ConvI2X(header_size);
++#ifdef _LP64
++  { const TypeLong* tllen = _gvn.find_long_type(lengthx);
++    if (tllen != NULL && tllen->_lo < 0) {
++      // Add a manual constraint to a positive range.  Cf. array_element_address.
++      jlong size_max = arrayOopDesc::max_array_length(T_BYTE);
++      if (size_max > tllen->_hi)  size_max = tllen->_hi;
++      const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin);
++      lengthx = _gvn.transform( new (C, 2) ConvI2LNode(length, tlcon));
++    }
++  }
++#endif
+ 
+   // Combine header size (plus rounding) and body size.  Then round down.
+   // This computation cannot overflow, because it is used only in two
+@@ -2886,56 +3047,43 @@
+     (*return_size_val) = size;
+   }
+ 
+-  const TypeInt* length_type = _gvn.type(length)->isa_int();
+-  const TypeInt* pos_length_type = NULL;
+-  if (length_type != NULL) {
+-    pos_length_type = length_type->join(TypeInt::POS)->isa_int();
+-    if (pos_length_type == NULL || pos_length_type->empty()) {
+-      // Optimize only if length is provably non-negative.
+-      length_type     = NULL;
+-      pos_length_type = NULL;
+-    }
+-  }
+-
+-  // Cast to correct type.  Note that the klass_node may be constant or not,
+-  // and in the latter case the actual array type will be inexact also.
+-  // (This happens via a non-constant argument to inline_native_newArray.)
+-  // In any case, the value of klass_node provides the desired array type.
+-  const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type();
+-  if (ary_type->isa_aryptr() && pos_length_type != NULL) {
+-    // Try to get a better type than POS for the size
+-    ary_type = ary_type->is_aryptr()->cast_to_size(pos_length_type);
+-  }
+-
+   // Now generate allocation code
+-  Node *eden_top_adr;
+-  Node *eden_end_adr;
+-  set_eden_pointers(eden_top_adr, eden_end_adr);
+-
+   // Create the AllocateArrayNode and its result projections
+   AllocateArrayNode* alloc
+     = new (C, AllocateArrayNode::ParmLimit)
+         AllocateArrayNode(C, AllocateArrayNode::alloc_type(),
+                           control(), memory(Compile::AliasIdxRaw), i_o(),
+                           size, klass_node,
+-                          initial_slow_test,  eden_top_adr, eden_end_adr,
++                          initial_slow_test,
+                           length);
+ 
++  // Cast to correct type.  Note that the klass_node may be constant or not,
++  // and in the latter case the actual array type will be inexact also.
++  // (This happens via a non-constant argument to inline_native_newArray.)
++  // In any case, the value of klass_node provides the desired array type.
++  const TypeInt* length_type = _gvn.find_int_type(length);
++  const TypeInt* narrow_length_type = NULL;
++  const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type();
++  if (ary_type->isa_aryptr() && length_type != NULL) {
++    // Try to get a better type than POS for the size
++    ary_type = ary_type->is_aryptr()->cast_to_size(length_type);
++    narrow_length_type = ary_type->is_aryptr()->size();
++    if (narrow_length_type == length_type)
++      narrow_length_type = NULL;
++  }
++
+   Node* javaoop = set_output_for_allocation(alloc, ary_type, raw_mem_only);
+ 
+-  /*
+-    Not yet.  We don't know what to do when the cast tops out.
+   // Cast length on remaining path to be positive:
+-  if (pos_length_type != NULL &&
+-      pos_length_type != length_type &&
+-      map()->find_edge(length) >= 0) {
+-    Node* ccast = new (C, 2) CastIINode(length, pos_length_type);
++  if (narrow_length_type != NULL) {
++    Node* ccast = new (C, 2) CastIINode(length, narrow_length_type);
+     ccast->set_req(0, control());
+     _gvn.set_type_bottom(ccast);
+     record_for_igvn(ccast);
++    if (map()->find_edge(length) >= 0) {
+     replace_in_map(length, ccast);
+   }
+-  */
++  }
+ 
+   return javaoop;
+ }
+@@ -2970,3 +3118,29 @@
+   if (base == NULL)  return NULL;
+   return Ideal_allocation(base, phase);
+ }
++
++// Trace Initialize <- Proj[Parm] <- Allocate
++AllocateNode* InitializeNode::allocation() {
++  Node* rawoop = in(InitializeNode::RawAddress);
++  if (rawoop->is_Proj()) {
++    Node* alloc = rawoop->in(0);
++    if (alloc->is_Allocate()) {
++      return alloc->as_Allocate();
++    }
++  }
++  return NULL;
++}
++
++// Trace Allocate -> Proj[Parm] -> Initialize
++InitializeNode* AllocateNode::initialization() {
++  ProjNode* rawoop = proj_out(AllocateNode::RawAddress);
++  if (rawoop == NULL)  return NULL;
++  for (DUIterator_Fast imax, i = rawoop->fast_outs(imax); i < imax; i++) {
++    Node* init = rawoop->fast_out(i);
++    if (init->is_Initialize()) {
++      assert(init->as_Initialize()->allocation() == this, "2-way link");
++      return init->as_Initialize();
++    }
++  }
++  return NULL;
++}
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/graphKit.hpp openjdk/hotspot/src/share/vm/opto/graphKit.hpp
+--- openjdk6/hotspot/src/share/vm/opto/graphKit.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/graphKit.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)graphKit.hpp	1.56 07/05/17 15:58:52 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -426,6 +423,51 @@
+                         int adr_idx,
+                         bool require_atomic_access = false);
+ 
++
++  // All in one pre-barrier, store, post_barrier
++  // Insert a write-barrier'd store.  This is to let generational GC
++  // work; we have to flag all oop-stores before the next GC point.
++  //
++  // It comes in 3 flavors of store to an object, array, or unknown.
++  // We use precise card marks for arrays to avoid scanning the entire
++  // array. We use imprecise for object. We use precise for unknown
++  // since we don't know if we have an array or and object or even
++  // where the object starts.
++  //
++  // If val==NULL, it is taken to be a completely unknown value. QQQ
++
++  Node* store_oop_to_object(Node* ctl,
++                            Node* obj,   // containing obj
++                            Node* adr,  // actual adress to store val at
++                            const TypePtr* adr_type,
++                            Node* val,
++                            const Type* val_type,
++                            BasicType bt);
++
++  Node* store_oop_to_array(Node* ctl,
++                           Node* obj,   // containing obj
++                           Node* adr,  // actual adress to store val at
++                           const TypePtr* adr_type,
++                           Node* val,
++                           const Type* val_type,
++                           BasicType bt);
++
++  // Could be an array or object we don't know at compile time (unsafe ref.)
++  Node* store_oop_to_unknown(Node* ctl,
++                             Node* obj,   // containing obj
++                             Node* adr,  // actual adress to store val at
++                             const TypePtr* adr_type,
++                             Node* val,
++                             const Type* val_type,
++                             BasicType bt);
++
++  // For the few case where the barriers need special help
++  void pre_barrier(Node* ctl, Node* obj, Node* adr, uint adr_idx,
++                   Node* val, const Type* val_type, BasicType bt);
++
++  void post_barrier(Node* ctl, Node* store, Node* obj, Node* adr, uint adr_idx,
++                    Node* val, BasicType bt, bool use_precise);
++
+   // Return addressing for an array element.
+   Node* array_element_address(Node* ary, Node* idx, BasicType elembt,
+                               // Optional constraint on the array size:
+@@ -505,15 +547,15 @@
+   // Optional must_throw is the same as with add_safepoint_edges.
+   void uncommon_trap(int trap_request,
+                      ciKlass* klass = NULL, const char* reason_string = NULL,
+-                     bool must_throw = false);
++                     bool must_throw = false, bool keep_exact_action = false);
+ 
+   // Shorthand, to avoid saying "Deoptimization::" so many times.
+   void uncommon_trap(Deoptimization::DeoptReason reason,
+                      Deoptimization::DeoptAction action,
+                      ciKlass* klass = NULL, const char* reason_string = NULL,
+-                     bool must_throw = false) {
++                     bool must_throw = false, bool keep_exact_action = false) {
+     uncommon_trap(Deoptimization::make_trap_request(reason, action),
+-                  klass, reason_string, must_throw);
++                  klass, reason_string, must_throw, keep_exact_action);
+   }
+ 
+   // Report if there were too many traps at the current method and bci.
+@@ -528,14 +570,16 @@
+     return C->too_many_recompiles(method(), bci(), reason);
+   }
+ 
+-  // Insert a write-barrier'd store.  This is to let generational GC
+-  // work; we have to flag all oop-stores before the next GC point.
+-  // The obj_type value is one of T_OBJECT, T_ARRAY, or T_CONFLICT,
+-  // meaning obj is an instance, an array, or either (statically unknown).
+-  // If val==NULL, it is taken to be a completely unknown value.
+-  void store_barrier(Node *store, BasicType obj_type,
+-                     // dest object, addr within obj, and stored value:
+-                     Node* obj, Node* adr, Node* val);
++  // vanilla/CMS post barrier
++  void write_barrier_post(Node *store, Node* obj, Node* adr, Node* val, bool use_precise);
++
++  // Returns the object (if any) which was created the moment before.
++  Node* just_allocated_object(Node* current_control);
++
++  static bool use_ReduceInitialCardMarks() {
++    return (ReduceInitialCardMarks
++            && Universe::heap()->can_elide_tlab_store_barriers());
++  }
+ 
+   // Helper function to round double arguments before a call
+   void round_double_arguments(ciMethod* dest_method);
+@@ -613,7 +657,6 @@
+                             Node* *casted_receiver);
+ 
+   // implementation of object creation
+-  void set_eden_pointers(Node * &eden_top_adr, Node * &eden_end_adr);
+   Node* set_output_for_allocation(AllocateNode* alloc,
+                                   const TypeOopPtr* oop_type,
+                                   bool raw_mem_only);
+@@ -675,4 +718,3 @@
+   BuildCutout(GraphKit* kit, Node* p, float prob, float cnt = COUNT_UNKNOWN);
+   ~BuildCutout();
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/idealGraphPrinter.cpp openjdk/hotspot/src/share/vm/opto/idealGraphPrinter.cpp
+--- openjdk6/hotspot/src/share/vm/opto/idealGraphPrinter.cpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/opto/idealGraphPrinter.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,1919 @@
++/*
++ * Copyright 2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++#include "incls/_precompiled.incl"
++#include "incls/_idealGraphPrinter.cpp.incl"
++
++#ifndef PRODUCT
++
++// Constants
++// Keep consistent with Java constants
++const char *IdealGraphPrinter::INDENT = "  ";
++const char *IdealGraphPrinter::TOP_ELEMENT = "graphDocument";
++const char *IdealGraphPrinter::GROUP_ELEMENT = "group";
++const char *IdealGraphPrinter::GRAPH_ELEMENT = "graph";
++const char *IdealGraphPrinter::PROPERTIES_ELEMENT = "properties";
++const char *IdealGraphPrinter::EDGES_ELEMENT = "edges";
++const char *IdealGraphPrinter::PROPERTY_ELEMENT = "p";
++const char *IdealGraphPrinter::EDGE_ELEMENT = "edge";
++const char *IdealGraphPrinter::NODE_ELEMENT = "node";
++const char *IdealGraphPrinter::NODES_ELEMENT = "nodes";
++const char *IdealGraphPrinter::REMOVE_EDGE_ELEMENT = "removeEdge";
++const char *IdealGraphPrinter::REMOVE_NODE_ELEMENT = "removeNode";
++const char *IdealGraphPrinter::METHOD_NAME_PROPERTY = "name";
++const char *IdealGraphPrinter::METHOD_IS_PUBLIC_PROPERTY = "public";
++const char *IdealGraphPrinter::METHOD_IS_STATIC_PROPERTY = "static";
++const char *IdealGraphPrinter::TRUE_VALUE = "true";
++const char *IdealGraphPrinter::NODE_NAME_PROPERTY = "name";
++const char *IdealGraphPrinter::EDGE_NAME_PROPERTY = "name";
++const char *IdealGraphPrinter::NODE_ID_PROPERTY = "id";
++const char *IdealGraphPrinter::FROM_PROPERTY = "from";
++const char *IdealGraphPrinter::TO_PROPERTY = "to";
++const char *IdealGraphPrinter::PROPERTY_NAME_PROPERTY = "name";
++const char *IdealGraphPrinter::GRAPH_NAME_PROPERTY = "name";
++const char *IdealGraphPrinter::INDEX_PROPERTY = "index";
++const char *IdealGraphPrinter::METHOD_ELEMENT = "method";
++const char *IdealGraphPrinter::INLINE_ELEMENT = "inline";
++const char *IdealGraphPrinter::BYTECODES_ELEMENT = "bytecodes";
++const char *IdealGraphPrinter::METHOD_BCI_PROPERTY = "bci";
++const char *IdealGraphPrinter::METHOD_SHORT_NAME_PROPERTY = "shortName";
++const char *IdealGraphPrinter::CONTROL_FLOW_ELEMENT = "controlFlow";
++const char *IdealGraphPrinter::BLOCK_NAME_PROPERTY = "name";
++const char *IdealGraphPrinter::BLOCK_DOMINATOR_PROPERTY = "dom";
++const char *IdealGraphPrinter::BLOCK_ELEMENT = "block";
++const char *IdealGraphPrinter::SUCCESSORS_ELEMENT = "successors";
++const char *IdealGraphPrinter::SUCCESSOR_ELEMENT = "successor";
++const char *IdealGraphPrinter::ASSEMBLY_ELEMENT = "assembly";
++
++int IdealGraphPrinter::_file_count = 0;
++
++IdealGraphPrinter *IdealGraphPrinter::printer() {
++  if (PrintIdealGraphLevel == 0) return NULL;
++
++  JavaThread *thread = JavaThread::current();
++  if (!thread->is_Compiler_thread()) return NULL;
++
++  CompilerThread *compiler_thread = (CompilerThread *)thread;
++  if (compiler_thread->ideal_graph_printer() == NULL) {
++    IdealGraphPrinter *printer = new IdealGraphPrinter();
++    compiler_thread->set_ideal_graph_printer(printer);
++  }
++
++  return compiler_thread->ideal_graph_printer();
++}
++
++void IdealGraphPrinter::clean_up() {
++  JavaThread *p;
++  for (p = Threads::first(); p; p = p->next()) {
++    if (p->is_Compiler_thread()) {
++      CompilerThread *c = (CompilerThread *)p;
++      IdealGraphPrinter *printer = c->ideal_graph_printer();
++      if (printer) {
++        delete printer;
++      }
++      c->set_ideal_graph_printer(NULL);
++    }
++  }
++}
++
++// Constructor, either file or network output
++IdealGraphPrinter::IdealGraphPrinter() {
++
++  _traverse_outs = false;
++  _should_send_method = true;
++  _output = NULL;
++  buffer[0] = 0;
++  _depth = 0;
++  _current_method = NULL;
++  assert(!_current_method, "current method must be initialized to NULL");
++  _arena = new Arena();
++
++  _stream = new (ResourceObj::C_HEAP) networkStream();
++
++  if (PrintIdealGraphFile != NULL) {
++    ThreadCritical tc;
++    // User wants all output to go to files
++    if (_file_count != 0) {
++      ResourceMark rm;
++      stringStream st;
++      const char* dot = strrchr(PrintIdealGraphFile, '.');
++      if (dot) {
++        st.write(PrintIdealGraphFile, dot - PrintIdealGraphFile);
++        st.print("%d%s", _file_count, dot);
++      } else {
++        st.print("%s%d", PrintIdealGraphFile, _file_count);
++      }
++      _output = new (ResourceObj::C_HEAP) fileStream(st.as_string());
++    } else {
++      _output = new (ResourceObj::C_HEAP) fileStream(PrintIdealGraphFile);
++    }
++    _file_count++;
++  } else {
++    // Try to connect to visualizer
++    if (_stream->connect(PrintIdealGraphAddress, PrintIdealGraphPort)) {
++      char c = 0;
++      _stream->read(&c, 1);
++      if (c != 'y') {
++        tty->print_cr("Client available, but does not want to receive data!");
++        _stream->close();
++        delete _stream;
++        _stream = NULL;
++        return;
++      }
++      _output = _stream;
++    } else {
++      // It would be nice if we could shut down cleanly but it should
++      // be an error if we can't connect to the visualizer.
++      fatal2("Couldn't connect to visualizer at %s:%d", PrintIdealGraphAddress, PrintIdealGraphPort);
++    }
++  }
++
++  start_element(TOP_ELEMENT);
++}
++
++// Destructor, close file or network stream
++IdealGraphPrinter::~IdealGraphPrinter() {
++
++  end_element(TOP_ELEMENT);
++
++  if (_stream) {
++    delete _stream;
++    if (_stream == _output) {
++      _output = NULL;
++    }
++    _stream = NULL;
++  }
++
++  if (_output) {
++    delete _output;
++    _output = NULL;
++  }
++}
++
++void IdealGraphPrinter::print_ifg(PhaseIFG* ifg) {
++
++  // Code to print an interference graph to tty, currently not used
++
++  /*
++  if (!_current_method) return;
++   // Remove neighbor colors
++
++  for (uint i = 0; i < ifg._maxlrg; i++) {
++
++    IndexSet *s = ifg.neighbors(i);
++    IndexSetIterator elements(s);
++    uint neighbor;
++    while ((neighbor = elements.next()) != 0) {
++        tty->print_cr("Edge between %d and %d\n", i, neighbor);
++    }
++  }
++
++
++  for (uint i = 0; i < ifg._maxlrg; i++) {
++    LRG &l = ifg.lrgs(i);
++    if (l._def) {
++      OptoReg::Name name = l.reg();
++      tty->print("OptoReg::dump: ");
++      OptoReg::dump(name);
++      tty->print_cr("");
++      tty->print_cr("name=%d\n", name);
++      if (name) {
++        if (OptoReg::is_stack(name)) {
++          tty->print_cr("Stack number %d\n", OptoReg::reg2stack(name));
++
++        } else if (!OptoReg::is_valid(name)) {
++          tty->print_cr("BAD!!!");
++        } else {
++
++          if (OptoReg::is_reg(name)) {
++          tty->print_cr(OptoReg::regname(name));
++          } else {
++            int x = 0;
++          }
++        }
++        int x = 0;
++      }
++
++      if (l._def == NodeSentinel) {
++        tty->print("multiple mapping from %d: ", i);
++        for (int j=0; j<l._defs->length(); j++) {
++          tty->print("%d ", l._defs->at(j)->_idx);
++        }
++        tty->print_cr("");
++      } else {
++        tty->print_cr("mapping between %d and %d\n", i, l._def->_idx);
++      }
++    }
++  }*/
++}
++
++void IdealGraphPrinter::print_method(ciMethod *method, int bci, InlineTree *tree) {
++
++  Properties properties;
++  stringStream str;
++  method->print_name(&str);
++
++  stringStream shortStr;
++  method->print_short_name(&shortStr);
++
++
++  properties.add(new Property(METHOD_NAME_PROPERTY, str.as_string()));
++  properties.add(new Property(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string()));
++  properties.add(new Property(METHOD_BCI_PROPERTY, bci));
++  start_element(METHOD_ELEMENT, &properties);
++
++  start_element(BYTECODES_ELEMENT);
++  output()->print_cr("<![CDATA[");
++  method->print_codes_on(output());
++  output()->print_cr("]]>");
++  end_element(BYTECODES_ELEMENT);
++
++  start_element(INLINE_ELEMENT);
++  if (tree != NULL) {
++    GrowableArray<InlineTree *> subtrees = tree->subtrees();
++    for (int i = 0; i < subtrees.length(); i++) {
++      print_inline_tree(subtrees.at(i));
++    }
++  }
++  end_element(INLINE_ELEMENT);
++
++  end_element(METHOD_ELEMENT);
++  output()->flush();
++}
++
++void IdealGraphPrinter::print_inline_tree(InlineTree *tree) {
++
++  if (tree == NULL) return;
++
++  ciMethod *method = tree->method();
++  print_method(tree->method(), tree->caller_bci(), tree);
++
++}
++
++void IdealGraphPrinter::clear_nodes() {
++ // for (int i = 0; i < _nodes.length(); i++) {
++ //   _nodes.at(i)->clear_node();
++ // }
++}
++
++void IdealGraphPrinter::print_inlining(Compile* compile) {
++
++  // Print inline tree
++  if (_should_send_method) {
++    InlineTree *inlineTree = compile->ilt();
++    if (inlineTree != NULL) {
++      print_inline_tree(inlineTree);
++    } else {
++      // print this method only
++    }
++  }
++}
++
++// Has to be called whenever a method is compiled
++void IdealGraphPrinter::begin_method(Compile* compile) {
++
++  ciMethod *method = compile->method();
++  assert(_output, "output stream must exist!");
++  assert(method, "null methods are not allowed!");
++  assert(!_current_method, "current method must be null!");
++
++  _arena->destruct_contents();
++
++  start_element(GROUP_ELEMENT);
++
++  // Print properties
++  Properties properties;
++
++  // Add method name
++  stringStream strStream;
++  method->print_name(&strStream);
++  properties.add(new Property(METHOD_NAME_PROPERTY, strStream.as_string()));
++
++  if (method->flags().is_public()) {
++    properties.add(new Property(METHOD_IS_PUBLIC_PROPERTY, TRUE_VALUE));
++  }
++
++  if (method->flags().is_static()) {
++    properties.add(new Property(METHOD_IS_STATIC_PROPERTY, TRUE_VALUE));
++  }
++
++  properties.print(this);
++
++  if (_stream) {
++    char answer = 0;
++    _stream->flush();
++    int result = _stream->read(&answer, 1);
++    _should_send_method = (answer == 'y');
++  }
++
++  this->_nodes = GrowableArray<NodeDescription *>(_arena, 2, 0, NULL);
++  this->_edges = GrowableArray< EdgeDescription * >(_arena, 2, 0, NULL);
++
++
++  this->_current_method = method;
++
++
++
++  _output->flush();
++}
++
++// Has to be called whenever a method has finished compilation
++void IdealGraphPrinter::end_method() {
++
++//  if (finish && !in_method) return;
++
++  nmethod* method = (nmethod*)this->_current_method->code();
++
++  start_element(ASSEMBLY_ELEMENT);
++ // Disassembler::decode(method, _output);
++  end_element(ASSEMBLY_ELEMENT);
++
++
++  end_element(GROUP_ELEMENT);
++  _current_method = NULL;
++  _output->flush();
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc) {
++      delete desc;
++      _nodes.at_put(i, NULL);
++    }
++  }
++  this->_nodes.clear();
++
++
++  for (int i = 0; i < _edges.length(); i++) {
++   // for (int j=0; j<_edges.at(i)->length(); j++) {
++      EdgeDescription *conn = _edges.at(i);
++      conn->print(this);
++      if (conn) {
++        delete conn;
++        _edges.at_put(i, NULL);
++      }
++    //}
++    //_edges.at(i)->clear();
++    //delete _edges.at(i);
++    //_edges.at_put(i, NULL);
++  }
++  this->_edges.clear();
++
++//  in_method = false;
++}
++
++// Outputs an XML start element
++void IdealGraphPrinter::start_element(const char *s, Properties *properties /* = NULL */, bool print_indent /* = false */, bool print_return /* = true */) {
++
++  start_element_helper(s, properties, false, print_indent, print_return);
++  _depth++;
++
++}
++
++// Outputs an XML start element without body
++void IdealGraphPrinter::simple_element(const char *s, Properties *properties /* = NULL */, bool print_indent /* = false */) {
++  start_element_helper(s, properties, true, print_indent, true);
++}
++
++// Outputs an XML start element. If outputEnd is true, the element has no body.
++void IdealGraphPrinter::start_element_helper(const char *s, Properties *properties, bool outputEnd, bool print_indent /* = false */, bool print_return /* = true */) {
++
++  assert(_output, "output stream must exist!");
++
++  if (print_indent) this->print_indent();
++  _output->print("<");
++  _output->print(s);
++  if (properties) properties->print_as_attributes(this);
++
++  if (outputEnd) {
++    _output->print("/");
++  }
++
++  _output->print(">");
++  if (print_return) _output->print_cr("");
++
++}
++
++// Print indent
++void IdealGraphPrinter::print_indent() {
++  for (int i = 0; i < _depth; i++) {
++    _output->print(INDENT);
++  }
++}
++
++// Outputs an XML end element
++void IdealGraphPrinter::end_element(const char *s, bool print_indent /* = true */, bool print_return /* = true */) {
++
++  assert(_output, "output stream must exist!");
++
++  _depth--;
++
++  if (print_indent) this->print_indent();
++  _output->print("</");
++  _output->print(s);
++  _output->print(">");
++  if (print_return) _output->print_cr("");
++
++}
++
++bool IdealGraphPrinter::traverse_outs() {
++  return _traverse_outs;
++}
++
++void IdealGraphPrinter::set_traverse_outs(bool b) {
++  _traverse_outs = b;
++}
++
++void IdealGraphPrinter::walk(Node *start) {
++
++
++  VectorSet visited(Thread::current()->resource_area());
++  GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, NULL);
++  nodeStack.push(start);
++  visited.test_set(start->_idx);
++  while(nodeStack.length() > 0) {
++
++    Node *n = nodeStack.pop();
++    IdealGraphPrinter::pre_node(n, this);
++
++    if (_traverse_outs) {
++      for (DUIterator i = n->outs(); n->has_out(i); i++) {
++        Node* p = n->out(i);
++        if (!visited.test_set(p->_idx)) {
++          nodeStack.push(p);
++        }
++      }
++    }
++
++    for ( uint i = 0; i < n->len(); i++ ) {
++      if ( n->in(i) ) {
++        if (!visited.test_set(n->in(i)->_idx)) {
++          nodeStack.push(n->in(i));
++        }
++      }
++    }
++  }
++}
++
++void IdealGraphPrinter::compress(int index, GrowableArray<Block>* blocks) {
++  Block *block = blocks->adr_at(index);
++
++  int ancestor = block->ancestor();
++  assert(ancestor != -1, "");
++
++  Block *ancestor_block = blocks->adr_at(ancestor);
++  if (ancestor_block->ancestor() != -1) {
++    compress(ancestor, blocks);
++
++    int label = block->label();
++    Block *label_block = blocks->adr_at(label);
++
++    int ancestor_label = ancestor_block->label();
++    Block *ancestor_label_block = blocks->adr_at(label);
++    if (ancestor_label_block->semi() < label_block->semi()) {
++      block->set_label(ancestor_label);
++    }
++
++    block->set_ancestor(ancestor_block->ancestor());
++  }
++}
++
++int IdealGraphPrinter::eval(int index, GrowableArray<Block>* blocks) {
++  Block *block = blocks->adr_at(index);
++  if (block->ancestor() == -1) {
++    return index;
++  } else {
++    compress(index, blocks);
++    return block->label();
++  }
++}
++
++void IdealGraphPrinter::link(int index1, int index2, GrowableArray<Block>* blocks) {
++  Block *block2 = blocks->adr_at(index2);
++  block2->set_ancestor(index1);
++}
++
++void IdealGraphPrinter::build_dominators(GrowableArray<Block>* blocks) {
++
++  if (blocks->length() == 0) return;
++
++  GrowableArray<int> stack;
++  stack.append(0);
++
++  GrowableArray<Block *> array;
++
++  assert(blocks->length() > 0, "");
++  blocks->adr_at(0)->set_dominator(0);
++
++  int n = 0;
++  while(!stack.is_empty()) {
++    int index = stack.pop();
++    Block *block = blocks->adr_at(index);
++    block->set_semi(n);
++    array.append(block);
++    n = n + 1;
++    for (int i = 0; i < block->succs()->length(); i++) {
++      int succ_index = block->succs()->at(i);
++      Block *succ = blocks->adr_at(succ_index);
++      if (succ->semi() == -1) {
++        succ->set_parent(index);
++        stack.push(succ_index);
++      }
++      succ->add_pred(index);
++    }
++  }
++
++  for (int i=n-1; i>0; i--) {
++    Block *block = array.at(i);
++    int block_index = block->index();
++    for (int j=0; j<block->pred()->length(); j++) {
++      int pred_index = block->pred()->at(j);
++      int cur_index = eval(pred_index, blocks);
++
++      Block *cur_block = blocks->adr_at(cur_index);
++      if (cur_block->semi() < block->semi()) {
++        block->set_semi(cur_block->semi());
++      }
++    }
++
++    int semi_index = block->semi();
++    Block *semi_block = array.at(semi_index);
++    semi_block->add_to_bucket(block_index);
++
++    link(block->parent(), block_index, blocks);
++    Block *parent_block = blocks->adr_at(block->parent());
++
++    for (int j=0; j<parent_block->bucket()->length(); j++) {
++      int cur_index = parent_block->bucket()->at(j);
++      int new_index = eval(cur_index, blocks);
++      Block *cur_block = blocks->adr_at(cur_index);
++      Block *new_block = blocks->adr_at(new_index);
++      int dom = block->parent();
++
++      if (new_block->semi() < cur_block->semi()) {
++        dom = new_index;
++      }
++
++      cur_block->set_dominator(dom);
++    }
++
++    parent_block->clear_bucket();
++  }
++
++  for (int i=1; i < n; i++) {
++
++    Block *block = array.at(i);
++    int block_index = block->index();
++
++    int semi_index = block->semi();
++    Block *semi_block = array.at(semi_index);
++
++    if (block->dominator() != semi_block->index()) {
++      int new_dom = blocks->adr_at(block->dominator())->dominator();
++      block->set_dominator(new_dom);
++    }
++  }
++
++  for (int i = 0; i < blocks->length(); i++) {
++    if (blocks->adr_at(i)->dominator() == -1) {
++      blocks->adr_at(i)->set_dominator(0);
++    }
++  }
++
++  // Build dominates array
++  for (int i=1; i < blocks->length(); i++) {
++    Block *block = blocks->adr_at(i);
++    int dominator = block->dominator();
++    Block *dom_block = blocks->adr_at(dominator);
++    dom_block->add_dominates(i);
++    dom_block->add_child(i);
++
++    while(dominator != 0) {
++      dominator = dom_block->dominator();
++      dom_block = blocks->adr_at(dominator);
++      dom_block->add_child(i);
++    }
++  }
++}
++
++void IdealGraphPrinter::build_common_dominator(int **common_dominator, int index, GrowableArray<Block>* blocks) {
++
++  common_dominator[index][index] = index;
++  Block *block = blocks->adr_at(index);
++  for (int i = 0; i < block->dominates()->length(); i++) {
++    Block *dominated = blocks->adr_at(block->dominates()->at(i));
++
++    for (int j=0; j<dominated->children()->length(); j++) {
++      Block *child = blocks->adr_at(dominated->children()->at(j));
++      common_dominator[index][child->index()] = common_dominator[child->index()][index] = index;
++
++      for (int k=0; k<i; k++) {
++        Block *other_dominated = blocks->adr_at(block->dominates()->at(k));
++        common_dominator[child->index()][other_dominated->index()] = common_dominator[other_dominated->index()][child->index()] = index;
++
++        for (int l=0 ; l<other_dominated->children()->length(); l++) {
++          Block *other_child = blocks->adr_at(other_dominated->children()->at(l));
++          common_dominator[child->index()][other_child->index()] = common_dominator[other_child->index()][child->index()] = index;
++        }
++      }
++    }
++
++    build_common_dominator(common_dominator, dominated->index(), blocks);
++  }
++}
++
++void IdealGraphPrinter::schedule_latest(int **common_dominator, GrowableArray<Block>* blocks) {
++
++  int queue_size = _nodes.length() + 1;
++  NodeDescription **queue = NEW_RESOURCE_ARRAY(NodeDescription *, queue_size);
++  int queue_start = 0;
++  int queue_end = 0;
++  Arena *a = new Arena();
++  VectorSet on_queue(a);
++
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc) {
++      desc->init_succs();
++    }
++  }
++
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc) {
++      for (uint j=0; j<desc->node()->len(); j++) {
++        Node *n = desc->node()->in(j);
++        if (n) {
++          NodeDescription *other_desc = _nodes.at(n->_idx);
++          other_desc->add_succ(desc);
++        }
++      }
++    }
++  }
++
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc && desc->block_index() == -1) {
++
++      // Put Phi into same block as region
++      if (desc->node()->is_Phi() && desc->node()->in(0) && _nodes.at(desc->node()->in(0)->_idx)->block_index() != -1) {
++        int index = _nodes.at(desc->node()->in(0)->_idx)->block_index();
++        desc->set_block_index(index);
++        blocks->adr_at(index)->add_node(desc);
++
++      // Put Projections to same block as parent
++      } else if (desc->node()->is_block_proj() && _nodes.at(desc->node()->is_block_proj()->_idx)->block_index() != -1) {
++        int index = _nodes.at(desc->node()->is_block_proj()->_idx)->block_index();
++        desc->set_block_index(index);
++        blocks->adr_at(index)->add_node(desc);
++      } else {
++        queue[queue_end] = desc;
++        queue_end++;
++        on_queue.set(desc->node()->_idx);
++      }
++    }
++  }
++
++
++  int z = 0;
++  while(queue_start != queue_end && z < 10000) {
++
++    NodeDescription *desc = queue[queue_start];
++    queue_start = (queue_start + 1) % queue_size;
++    on_queue >>= desc->node()->_idx;
++
++    Node* node = desc->node();
++
++    if (desc->succs()->length() == 0) {
++      int x = 0;
++    }
++
++    int block_index = -1;
++    if (desc->succs()->length() != 0) {
++      for (int i = 0; i < desc->succs()->length(); i++) {
++          NodeDescription *cur_desc = desc->succs()->at(i);
++          if (cur_desc != desc) {
++            if (cur_desc->succs()->length() == 0) {
++
++              // Ignore nodes with 0 successors
++
++            } else if (cur_desc->block_index() == -1) {
++
++              // Let this node schedule first
++              block_index = -1;
++              break;
++
++            } else if (cur_desc->node()->is_Phi()){
++
++              // Special treatment for Phi functions
++              PhiNode *phi = cur_desc->node()->as_Phi();
++              assert(phi->in(0) && phi->in(0)->is_Region(), "Must have region node in first input");
++              RegionNode *region = phi->in(0)->as_Region();
++
++              for (uint j=1; j<phi->len(); j++) {
++                Node *cur_phi_input = phi->in(j);
++                if (cur_phi_input == desc->node() && region->in(j)) {
++                  NodeDescription *cur_region_input = _nodes.at(region->in(j)->_idx);
++                  if (cur_region_input->block_index() == -1) {
++
++                    // Let this node schedule first
++                    block_index = -1;
++                    break;
++                  } else {
++                    if (block_index == -1) {
++                      block_index = cur_region_input->block_index();
++                    } else {
++                      block_index = common_dominator[block_index][cur_region_input->block_index()];
++                    }
++                  }
++                }
++              }
++
++            } else {
++              if (block_index == -1) {
++                block_index = cur_desc->block_index();
++              } else {
++                block_index = common_dominator[block_index][cur_desc->block_index()];
++              }
++            }
++          }
++      }
++    }
++
++    if (block_index == -1) {
++      queue[queue_end] = desc;
++      queue_end = (queue_end + 1) % queue_size;
++      on_queue.set(desc->node()->_idx);
++      z++;
++    } else {
++      assert(desc->block_index() == -1, "");
++      desc->set_block_index(block_index);
++      blocks->adr_at(block_index)->add_node(desc);
++      z = 0;
++    }
++  }
++
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc && desc->block_index() == -1) {
++
++      //if (desc->node()->is_Proj() || desc->node()->is_Con()) {
++        Node *parent = desc->node()->in(0);
++        uint cur = 1;
++        while(!parent && cur < desc->node()->len()) {
++          parent = desc->node()->in(cur);
++          cur++;
++        }
++
++        if (parent && _nodes.at(parent->_idx)->block_index() != -1) {
++          int index = _nodes.at(parent->_idx)->block_index();
++          desc->set_block_index(index);
++          blocks->adr_at(index)->add_node(desc);
++        } else {
++          desc->set_block_index(0);
++          blocks->adr_at(0)->add_node(desc);
++          //ShouldNotReachHere();
++        }
++      //}
++      /*
++      if (desc->node()->is_block_proj() && _nodes.at(desc->node()->is_block_proj()->_idx)->block_index() != -1) {
++        int index = _nodes.at(desc->node()->is_block_proj()->_idx)->block_index();
++        desc->set_block_index(index);
++        blocks->adr_at(index)->add_node(desc);
++      } */
++    }
++  }
++
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc) {
++      desc->clear_succs();
++    }
++  }
++
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc) {
++      int block_index = desc->block_index();
++
++      assert(block_index >= 0 && block_index < blocks->length(), "Block index must be in range");
++      assert(blocks->adr_at(block_index)->nodes()->contains(desc), "Node must be child of block");
++    }
++  }
++  a->destruct_contents();
++}
++
++void IdealGraphPrinter::build_blocks(Node *root) {
++
++  Arena *a = new Arena();
++  Node_Stack stack(a, 100);
++
++  VectorSet visited(a);
++  stack.push(root, 0);
++  GrowableArray<Block> blocks(a, 2, 0, Block(0));
++
++  for (int i = 0; i < _nodes.length(); i++) {
++    if (_nodes.at(i)) _nodes.at(i)->set_block_index(-1);
++  }
++
++
++  // Order nodes such that node index is equal to idx
++  for (int i = 0; i < _nodes.length(); i++) {
++
++    if (_nodes.at(i)) {
++      NodeDescription *node = _nodes.at(i);
++      int index = node->node()->_idx;
++      if (index != i) {
++        _nodes.at_grow(index);
++        NodeDescription *tmp = _nodes.at(index);
++        *(_nodes.adr_at(index)) = node;
++        *(_nodes.adr_at(i)) = tmp;
++        i--;
++      }
++    }
++  }
++
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *node = _nodes.at(i);
++    if (node) {
++      assert(node->node()->_idx == (uint)i, "");
++    }
++  }
++
++  while(stack.is_nonempty()) {
++
++    //Node *n = stack.node();
++    //int index = stack.index();
++    Node *proj = stack.node();//n->in(index);
++    const Node *parent = proj->is_block_proj();
++    if (parent == NULL) {
++      parent = proj;
++    }
++
++    if (!visited.test_set(parent->_idx)) {
++
++      NodeDescription *end_desc = _nodes.at(parent->_idx);
++      int block_index = blocks.length();
++      Block block(block_index);
++      blocks.append(block);
++      Block *b = blocks.adr_at(block_index);
++      b->set_start(end_desc);
++     // assert(end_desc->block_index() == -1, "");
++      end_desc->set_block_index(block_index);
++      b->add_node(end_desc);
++
++      // Skip any control-pinned middle'in stuff
++      Node *p = proj;
++      NodeDescription *start_desc = NULL;
++      do {
++        proj = p;                   // Update pointer to last Control
++        if (p->in(0) == NULL) {
++          start_desc = end_desc;
++          break;
++        }
++        p = p->in(0);               // Move control forward
++        start_desc = _nodes.at(p->_idx);
++        assert(start_desc, "");
++
++        if (start_desc != end_desc && start_desc->block_index() == -1) {
++          assert(start_desc->block_index() == -1, "");
++          assert(block_index < blocks.length(), "");
++          start_desc->set_block_index(block_index);
++          b->add_node(start_desc);
++        }
++     } while( !p->is_block_proj() &&
++               !p->is_block_start() );
++
++      for (uint i = 0; i < start_desc->node()->len(); i++) {
++
++          Node *pred_node = start_desc->node()->in(i);
++
++
++          if (pred_node && pred_node != start_desc->node()) {
++            const Node *cur_parent = pred_node->is_block_proj();
++            if (cur_parent != NULL) {
++              pred_node = (Node *)cur_parent;
++            }
++
++            NodeDescription *pred_node_desc = _nodes.at(pred_node->_idx);
++            if (pred_node_desc->block_index() != -1) {
++              blocks.adr_at(pred_node_desc->block_index())->add_succ(block_index);
++            }
++          }
++      }
++
++      for (DUIterator_Fast dmax, i = end_desc->node()->fast_outs(dmax); i < dmax; i++) {
++        Node* cur_succ = end_desc->node()->fast_out(i);
++        NodeDescription *cur_succ_desc = _nodes.at(cur_succ->_idx);
++
++        DUIterator_Fast dmax2, i2 = cur_succ->fast_outs(dmax2);
++        if (cur_succ->is_block_proj() && i2 < dmax2 && !cur_succ->is_Root()) {
++
++          for (; i2<dmax2; i2++) {
++            Node *cur_succ2 = cur_succ->fast_out(i2);
++            if (cur_succ2) {
++              cur_succ_desc = _nodes.at(cur_succ2->_idx);
++              if (cur_succ_desc == NULL) {
++                // dead node so skip it
++                continue;
++              }
++              if (cur_succ2 != end_desc->node() && cur_succ_desc->block_index() != -1) {
++                b->add_succ(cur_succ_desc->block_index());
++              }
++            }
++          }
++
++        } else {
++
++          if (cur_succ != end_desc->node() && cur_succ_desc && cur_succ_desc->block_index() != -1) {
++            b->add_succ(cur_succ_desc->block_index());
++          }
++        }
++      }
++
++
++      int num_preds = p->len();
++      int bottom = -1;
++      if (p->is_Region() || p->is_Phi()) {
++        bottom = 0;
++      }
++
++      int pushed = 0;
++      for (int i=num_preds - 1; i > bottom; i--) {
++        if (p->in(i) != NULL && p->in(i) != p) {
++          stack.push(p->in(i), 0);
++          pushed++;
++        }
++      }
++
++      if (pushed == 0 && p->is_Root() && !_matcher) {
++        // Special case when backedges to root are not yet built
++        for (int i = 0; i < _nodes.length(); i++) {
++          if (_nodes.at(i) && _nodes.at(i)->node()->is_SafePoint() && _nodes.at(i)->node()->outcnt() == 0) {
++            stack.push(_nodes.at(i)->node(), 0);
++          }
++        }
++      }
++
++    } else {
++      stack.pop();
++    }
++  }
++
++  build_dominators(&blocks);
++
++  int **common_dominator = NEW_RESOURCE_ARRAY(int *, blocks.length());
++  for (int i = 0; i < blocks.length(); i++) {
++    int *cur = NEW_RESOURCE_ARRAY(int, blocks.length());
++    common_dominator[i] = cur;
++
++    for (int j=0; j<blocks.length(); j++) {
++      cur[j] = 0;
++    }
++  }
++
++  for (int i = 0; i < blocks.length(); i++) {
++    blocks.adr_at(i)->add_child(blocks.adr_at(i)->index());
++  }
++  build_common_dominator(common_dominator, 0, &blocks);
++
++  schedule_latest(common_dominator, &blocks);
++
++  start_element(CONTROL_FLOW_ELEMENT);
++
++  for (int i = 0; i < blocks.length(); i++) {
++    Block *block = blocks.adr_at(i);
++
++    Properties props;
++    props.add(new Property(BLOCK_NAME_PROPERTY, i));
++    props.add(new Property(BLOCK_DOMINATOR_PROPERTY, block->dominator()));
++    start_element(BLOCK_ELEMENT, &props);
++
++    if (block->succs()->length() > 0) {
++      start_element(SUCCESSORS_ELEMENT);
++      for (int j=0; j<block->succs()->length(); j++) {
++        int cur_index = block->succs()->at(j);
++        if (cur_index != 0 /* start_block has must not have inputs */) {
++          Properties properties;
++          properties.add(new Property(BLOCK_NAME_PROPERTY, cur_index));
++          simple_element(SUCCESSOR_ELEMENT, &properties);
++        }
++      }
++      end_element(SUCCESSORS_ELEMENT);
++    }
++
++    start_element(NODES_ELEMENT);
++
++    for (int j=0; j<block->nodes()->length(); j++) {
++      NodeDescription *n = block->nodes()->at(j);
++      Properties properties;
++      properties.add(new Property(NODE_ID_PROPERTY, n->id()));
++      simple_element(NODE_ELEMENT, &properties);
++    }
++
++    end_element(NODES_ELEMENT);
++
++    end_element(BLOCK_ELEMENT);
++  }
++
++
++  end_element(CONTROL_FLOW_ELEMENT);
++
++  a->destruct_contents();
++}
++
++void IdealGraphPrinter::print_method(Compile* compile, const char *name, int level, bool clear_nodes) {
++  print(compile, name, (Node *)compile->root(), level, clear_nodes);
++}
++
++// Print current ideal graph
++void IdealGraphPrinter::print(Compile* compile, const char *name, Node *node, int level, bool clear_nodes) {
++
++//  if (finish && !in_method) return;
++  if (!_current_method || !_should_send_method || level > PrintIdealGraphLevel) return;
++
++  assert(_current_method, "newMethod has to be called first!");
++
++  if (clear_nodes) {
++    int x = 0;
++  }
++
++  _clear_nodes = clear_nodes;
++
++  // Warning, unsafe cast?
++  _chaitin = (PhaseChaitin *)compile->regalloc();
++  _matcher = compile->matcher();
++
++
++  // Update nodes
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc) {
++      desc->set_state(Invalid);
++    }
++  }
++  Node *n = node;
++  walk(n);
++
++  // Update edges
++  for (int i = 0; i < _edges.length(); i++) {
++      _edges.at(i)->set_state(Invalid);
++  }
++
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc && desc->state() != Invalid) {
++
++      int to = desc->id();
++      uint len = desc->node()->len();
++      for (uint j=0; j<len; j++) {
++        Node *n = desc->node()->in(j);
++
++        if (n) {
++
++
++          intptr_t from = (intptr_t)n;
++
++          // Assert from node is valid
++          /*
++          bool ok = false;
++          for (int k=0; k<_nodes.length(); k++) {
++            NodeDescription *desc = _nodes.at(k);
++            if (desc && desc->id() == from) {
++              assert(desc->state() != Invalid, "");
++              ok = true;
++            }
++          }
++          assert(ok, "");*/
++
++          uint index = j;
++          if (index >= desc->node()->req()) {
++            index = desc->node()->req();
++          }
++
++          print_edge(from, to, index);
++        }
++      }
++    }
++  }
++
++  bool is_different = false;
++
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc && desc->state() != Valid) {
++      is_different = true;
++      break;
++    }
++  }
++
++  if (!is_different) {
++    for (int i = 0; i < _edges.length(); i++) {
++      EdgeDescription *conn = _edges.at(i);
++      if (conn && conn->state() != Valid) {
++        is_different = true;
++        break;
++      }
++    }
++  }
++
++  // No changes -> do not print graph
++  if (!is_different) return;
++
++  Properties properties;
++  properties.add(new Property(GRAPH_NAME_PROPERTY, (const char *)name));
++  start_element(GRAPH_ELEMENT, &properties);
++
++  start_element(NODES_ELEMENT);
++  for (int i = 0; i < _nodes.length(); i++) {
++    NodeDescription *desc = _nodes.at(i);
++    if (desc) {
++      desc->print(this);
++      if (desc->state() == Invalid) {
++        delete desc;
++        _nodes.at_put(i, NULL);
++      } else {
++        desc->set_state(Valid);
++      }
++    }
++  }
++  end_element(NODES_ELEMENT);
++
++  build_blocks(node);
++
++  start_element(EDGES_ELEMENT);
++  for (int i = 0; i < _edges.length(); i++) {
++    EdgeDescription *conn = _edges.at(i);
++
++    // Assert from and to nodes are valid
++    /*
++    if (!conn->state() == Invalid) {
++      bool ok1 = false;
++      bool ok2 = false;
++      for (int j=0; j<_nodes.length(); j++) {
++        NodeDescription *desc = _nodes.at(j);
++        if (desc && desc->id() == conn->from()) {
++          ok1 = true;
++        }
++
++        if (desc && desc->id() == conn->to()) {
++          ok2 = true;
++        }
++      }
++
++      assert(ok1, "from node not found!");
++      assert(ok2, "to node not found!");
++    }*/
++
++    conn->print(this);
++    if (conn->state() == Invalid) {
++      _edges.remove_at(i);
++      delete conn;
++      i--;
++    }
++  }
++
++  end_element(EDGES_ELEMENT);
++
++  end_element(GRAPH_ELEMENT);
++
++  _output->flush();
++}
++
++// Print edge
++void IdealGraphPrinter::print_edge(int from, int to, int index) {
++
++  EdgeDescription *conn = new EdgeDescription(from, to, index);
++  for (int i = 0; i < _edges.length(); i++) {
++    if (_edges.at(i)->equals(conn)) {
++      conn->set_state(Valid);
++      delete _edges.at(i);
++      _edges.at_put(i, conn);
++      return;
++    }
++  }
++
++  _edges.append(conn);
++}
++
++extern const char *NodeClassNames[];
++
++// Create node description
++IdealGraphPrinter::NodeDescription *IdealGraphPrinter::create_node_description(Node* node) {
++
++#ifndef PRODUCT
++  node->_in_dump_cnt++;
++  NodeDescription *desc = new NodeDescription(node);
++  desc->properties()->add(new Property(NODE_NAME_PROPERTY, (const char *)node->Name()));
++
++  const Type *t = node->bottom_type();
++  desc->properties()->add(new Property("type", (const char *)Type::msg[t->base()]));
++
++  desc->properties()->add(new Property("idx", node->_idx));
++#ifdef ASSERT
++  desc->properties()->add(new Property("debug_idx", node->_debug_idx));
++#endif
++
++
++  const jushort flags = node->flags();
++  if (flags & Node::Flag_is_Copy) {
++    desc->properties()->add(new Property("is_copy", "true"));
++  }
++  if (flags & Node::Flag_is_Call) {
++    desc->properties()->add(new Property("is_call", "true"));
++  }
++  if (flags & Node::Flag_rematerialize) {
++    desc->properties()->add(new Property("rematerialize", "true"));
++  }
++  if (flags & Node::Flag_needs_anti_dependence_check) {
++    desc->properties()->add(new Property("needs_anti_dependence_check", "true"));
++  }
++  if (flags & Node::Flag_is_macro) {
++    desc->properties()->add(new Property("is_macro", "true"));
++  }
++  if (flags & Node::Flag_is_Con) {
++    desc->properties()->add(new Property("is_con", "true"));
++  }
++  if (flags & Node::Flag_is_cisc_alternate) {
++    desc->properties()->add(new Property("is_cisc_alternate", "true"));
++  }
++  if (flags & Node::Flag_is_Branch) {
++    desc->properties()->add(new Property("is_branch", "true"));
++  }
++  if (flags & Node::Flag_is_block_start) {
++    desc->properties()->add(new Property("is_block_start", "true"));
++  }
++  if (flags & Node::Flag_is_Goto) {
++    desc->properties()->add(new Property("is_goto", "true"));
++  }
++  if (flags & Node::Flag_is_dead_loop_safe) {
++    desc->properties()->add(new Property("is_dead_loop_safe", "true"));
++  }
++  if (flags & Node::Flag_may_be_short_branch) {
++    desc->properties()->add(new Property("may_be_short_branch", "true"));
++  }
++  if (flags & Node::Flag_is_safepoint_node) {
++    desc->properties()->add(new Property("is_safepoint_node", "true"));
++  }
++  if (flags & Node::Flag_is_pc_relative) {
++    desc->properties()->add(new Property("is_pc_relative", "true"));
++  }
++
++  if (_matcher) {
++    if (_matcher->is_shared(desc->node())) {
++      desc->properties()->add(new Property("is_shared", "true"));
++    } else {
++      desc->properties()->add(new Property("is_shared", "false"));
++    }
++
++    if (_matcher->is_dontcare(desc->node())) {
++      desc->properties()->add(new Property("is_dontcare", "true"));
++    } else {
++      desc->properties()->add(new Property("is_dontcare", "false"));
++    }
++  }
++
++  if (node->is_Proj()) {
++    desc->properties()->add(new Property("con", (int)node->as_Proj()->_con));
++  }
++
++  if (node->is_Mach()) {
++    desc->properties()->add(new Property("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()]));
++  }
++
++
++
++
++
++  outputStream *oldTty = tty;
++  buffer[0] = 0;
++  stringStream s2(buffer, sizeof(buffer) - 1);
++
++  node->dump_spec(&s2);
++  assert(s2.size() < sizeof(buffer), "size in range");
++  desc->properties()->add(new Property("dump_spec", buffer));
++
++  if (node->is_block_proj()) {
++    desc->properties()->add(new Property("is_block_proj", "true"));
++  }
++
++  if (node->is_block_start()) {
++    desc->properties()->add(new Property("is_block_start", "true"));
++  }
++
++  const char *short_name = "short_name";
++  if (strcmp(node->Name(), "Parm") == 0 && node->as_Proj()->_con >= TypeFunc::Parms) {
++      int index = node->as_Proj()->_con - TypeFunc::Parms;
++      if (index >= 10) {
++        desc->properties()->add(new Property(short_name, "PA"));
++      } else {
++        sprintf(buffer, "P%d", index);
++        desc->properties()->add(new Property(short_name, buffer));
++      }
++  } else if (strcmp(node->Name(), "IfTrue") == 0) {
++     desc->properties()->add(new Property(short_name, "T"));
++  } else if (strcmp(node->Name(), "IfFalse") == 0) {
++     desc->properties()->add(new Property(short_name, "F"));
++  } else if ((node->is_Con() && node->is_Type()) || node->is_Proj()) {
++
++    if (t->base() == Type::Int && t->is_int()->is_con()) {
++      const TypeInt *typeInt = t->is_int();
++      assert(typeInt->is_con(), "must be constant");
++      jint value = typeInt->get_con();
++
++      // max. 2 chars allowed
++      if (value >= -9 && value <= 99) {
++        sprintf(buffer, "%d", value);
++        desc->properties()->add(new Property(short_name, buffer));
++      }
++      else
++      {
++        desc->properties()->add(new Property(short_name, "I"));
++      }
++    } else if (t == Type::TOP) {
++      desc->properties()->add(new Property(short_name, "^"));
++    } else if (t->base() == Type::Long && t->is_long()->is_con()) {
++      const TypeLong *typeLong = t->is_long();
++      assert(typeLong->is_con(), "must be constant");
++      jlong value = typeLong->get_con();
++
++      // max. 2 chars allowed
++      if (value >= -9 && value <= 99) {
++        sprintf(buffer, "%d", value);
++        desc->properties()->add(new Property(short_name, buffer));
++      }
++      else
++      {
++        desc->properties()->add(new Property(short_name, "L"));
++      }
++    } else if (t->base() == Type::KlassPtr) {
++      const TypeKlassPtr *typeKlass = t->is_klassptr();
++      desc->properties()->add(new Property(short_name, "CP"));
++    } else if (t->base() == Type::Control) {
++      desc->properties()->add(new Property(short_name, "C"));
++    } else if (t->base() == Type::Memory) {
++      desc->properties()->add(new Property(short_name, "M"));
++    } else if (t->base() == Type::Abio) {
++      desc->properties()->add(new Property(short_name, "IO"));
++    } else if (t->base() == Type::Return_Address) {
++      desc->properties()->add(new Property(short_name, "RA"));
++    } else if (t->base() == Type::AnyPtr) {
++      desc->properties()->add(new Property(short_name, "P"));
++    } else if (t->base() == Type::RawPtr) {
++      desc->properties()->add(new Property(short_name, "RP"));
++    } else if (t->base() == Type::AryPtr) {
++      desc->properties()->add(new Property(short_name, "AP"));
++    }
++  }
++
++  if (node->is_SafePoint()) {
++    SafePointNode *safePointNode = node->as_SafePoint();
++    if (safePointNode->jvms()) {
++      stringStream bciStream;
++      bciStream.print("%d ", safePointNode->jvms()->bci());
++      JVMState *caller = safePointNode->jvms()->caller();
++      while(caller) {
++        bciStream.print("%d ", caller->bci());
++
++        caller = caller->caller();
++      }
++      desc->properties()->add(new Property("bci", bciStream.as_string()));
++    }
++  }
++
++  if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) {
++    buffer[0] = 0;
++    _chaitin->dump_register(node, buffer);
++    desc->properties()->add(new Property("reg", buffer));
++    desc->properties()->add(new Property("lrg", _chaitin->n2lidx(node)));
++  }
++
++
++  node->_in_dump_cnt--;
++  return desc;
++#else
++  return NULL;
++#endif
++}
++
++void IdealGraphPrinter::pre_node(Node* node, void *env) {
++
++  IdealGraphPrinter *printer = (IdealGraphPrinter *)env;
++
++  NodeDescription *newDesc = printer->create_node_description(node);
++
++  if (printer->_clear_nodes) {
++
++    printer->_nodes.append(newDesc);
++  } else {
++
++    NodeDescription *desc = printer->_nodes.at_grow(node->_idx, NULL);
++
++    if (desc && desc->equals(newDesc)) {
++      //desc->set_state(Valid);
++      //desc->set_node(node);
++      delete desc;
++      printer->_nodes.at_put(node->_idx, NULL);
++      newDesc->set_state(Valid);
++      //printer->_nodes.at_put(node->_idx, newDesc);
++    } else {
++
++      if (desc && desc->id() == newDesc->id()) {
++        delete desc;
++        printer->_nodes.at_put(node->_idx, NULL);
++        newDesc->set_state(New);
++
++      }
++
++      //if (desc) {
++      //  delete desc;
++      //}
++
++      //printer->_nodes.at_put(node->_idx, newDesc);
++    }
++
++    printer->_nodes.append(newDesc);
++  }
++}
++
++void IdealGraphPrinter::post_node(Node* node, void *env) {
++}
++
++outputStream *IdealGraphPrinter::output() {
++  return _output;
++}
++
++IdealGraphPrinter::Description::Description() {
++  _state = New;
++}
++
++void IdealGraphPrinter::Description::print(IdealGraphPrinter *printer) {
++  if (_state == Invalid) {
++    print_removed(printer);
++  } else if (_state == New) {
++    print_changed(printer);
++  }
++}
++
++void IdealGraphPrinter::Description::set_state(State s) {
++  _state = s;
++}
++
++IdealGraphPrinter::State IdealGraphPrinter::Description::state() {
++  return _state;
++}
++
++void IdealGraphPrinter::Block::set_proj(NodeDescription *n) {
++  _proj = n;
++}
++
++void IdealGraphPrinter::Block::set_start(NodeDescription *n) {
++  _start = n;
++}
++
++int IdealGraphPrinter::Block::semi() {
++  return _semi;
++}
++
++int IdealGraphPrinter::Block::parent() {
++  return _parent;
++}
++
++GrowableArray<int>* IdealGraphPrinter::Block::bucket() {
++  return &_bucket;
++}
++
++GrowableArray<int>* IdealGraphPrinter::Block::children() {
++  return &_children;
++}
++
++void IdealGraphPrinter::Block::add_child(int i) {
++  _children.append(i);
++}
++
++GrowableArray<int>* IdealGraphPrinter::Block::dominates() {
++  return &_dominates;
++}
++
++void IdealGraphPrinter::Block::add_dominates(int i) {
++  _dominates.append(i);
++}
++
++void IdealGraphPrinter::Block::add_to_bucket(int i) {
++  _bucket.append(i);
++}
++
++void IdealGraphPrinter::Block::clear_bucket() {
++  _bucket.clear();
++}
++
++void IdealGraphPrinter::Block::set_dominator(int i) {
++  _dominator = i;
++}
++
++void IdealGraphPrinter::Block::set_label(int i) {
++  _label = i;
++}
++
++int IdealGraphPrinter::Block::label() {
++  return _label;
++}
++
++int IdealGraphPrinter::Block::ancestor() {
++  return _ancestor;
++}
++
++void IdealGraphPrinter::Block::set_ancestor(int i) {
++  _ancestor = i;
++}
++
++int IdealGraphPrinter::Block::dominator() {
++  return _dominator;
++}
++
++int IdealGraphPrinter::Block::index() {
++  return _index;
++}
++
++void IdealGraphPrinter::Block::set_parent(int i) {
++  _parent = i;
++}
++
++GrowableArray<int>* IdealGraphPrinter::Block::pred() {
++  return &_pred;
++}
++
++void IdealGraphPrinter::Block::set_semi(int i) {
++  _semi = i;
++}
++
++IdealGraphPrinter::Block::Block() {
++}
++
++IdealGraphPrinter::Block::Block(int index) {
++  _index = index;
++  _label = index;
++  _semi = -1;
++  _ancestor = -1;
++  _dominator = -1;
++}
++
++void IdealGraphPrinter::Block::add_pred(int i) {
++  _pred.append(i);
++}
++
++IdealGraphPrinter::NodeDescription *IdealGraphPrinter::Block::proj() {
++  return _proj;
++}
++
++IdealGraphPrinter::NodeDescription *IdealGraphPrinter::Block::start() {
++  return _start;
++}
++
++GrowableArray<int>* IdealGraphPrinter::Block::succs() {
++  return &_succs;
++}
++
++void IdealGraphPrinter::Block::add_succ(int index) {
++
++  if (this->_index == 16 && index == 15) {
++    int x = 0;
++  }
++
++  if (!_succs.contains(index)) {
++    _succs.append(index);
++  }
++}
++
++
++void IdealGraphPrinter::Block::add_node(NodeDescription *n) {
++  if (!_nodes.contains(n)) {
++    _nodes.append(n);
++  }
++}
++
++GrowableArray<IdealGraphPrinter::NodeDescription *>* IdealGraphPrinter::Block::nodes() {
++  return &_nodes;
++}
++
++int IdealGraphPrinter::NodeDescription::count = 0;
++
++IdealGraphPrinter::NodeDescription::NodeDescription(Node* node) : _node(node) {
++  _id = (intptr_t)(node);
++  _block_index = -1;
++}
++
++IdealGraphPrinter::NodeDescription::~NodeDescription() {
++  _properties.clean();
++}
++
++// void IdealGraphPrinter::NodeDescription::set_node(Node* node) {
++//   //this->_node = node;
++// }
++
++int IdealGraphPrinter::NodeDescription::block_index() {
++  return _block_index;
++}
++
++
++GrowableArray<IdealGraphPrinter::NodeDescription *>* IdealGraphPrinter::NodeDescription::succs() {
++  return &_succs;
++}
++
++void IdealGraphPrinter::NodeDescription::clear_succs() {
++  _succs.clear();
++}
++
++void IdealGraphPrinter::NodeDescription::init_succs() {
++  _succs = GrowableArray<NodeDescription *>();
++}
++
++void IdealGraphPrinter::NodeDescription::add_succ(NodeDescription *desc) {
++  _succs.append(desc);
++}
++
++void IdealGraphPrinter::NodeDescription::set_block_index(int i) {
++  _block_index = i;
++}
++
++bool IdealGraphPrinter::NodeDescription::equals(NodeDescription *desc) {
++  if (desc == NULL) return false;
++  if (desc->id() != id()) return false;
++  return properties()->equals(desc->properties());
++}
++
++Node* IdealGraphPrinter::NodeDescription::node() {
++  return _node;
++}
++
++IdealGraphPrinter::Properties* IdealGraphPrinter::NodeDescription::properties() {
++  return &_properties;
++}
++
++uint IdealGraphPrinter::NodeDescription::id() {
++  return _id;
++}
++
++void IdealGraphPrinter::NodeDescription::print_changed(IdealGraphPrinter *printer) {
++
++
++  Properties properties;
++  properties.add(new Property(NODE_ID_PROPERTY, id()));
++  printer->start_element(NODE_ELEMENT, &properties);
++
++  this->properties()->print(printer);
++
++
++  printer->end_element(NODE_ELEMENT);
++}
++
++void IdealGraphPrinter::NodeDescription::print_removed(IdealGraphPrinter *printer) {
++
++  Properties properties;
++  properties.add(new Property(NODE_ID_PROPERTY, id()));
++  printer->simple_element(REMOVE_NODE_ELEMENT, &properties);
++}
++
++IdealGraphPrinter::EdgeDescription::EdgeDescription(int from, int to, int index) {
++  this->_from = from;
++  this->_to = to;
++  this->_index = index;
++}
++
++IdealGraphPrinter::EdgeDescription::~EdgeDescription() {
++}
++
++int IdealGraphPrinter::EdgeDescription::from() {
++  return _from;
++}
++
++int IdealGraphPrinter::EdgeDescription::to() {
++  return _to;
++}
++
++void IdealGraphPrinter::EdgeDescription::print_changed(IdealGraphPrinter *printer) {
++
++  Properties properties;
++  properties.add(new Property(INDEX_PROPERTY, _index));
++  properties.add(new Property(FROM_PROPERTY, _from));
++  properties.add(new Property(TO_PROPERTY, _to));
++  printer->simple_element(EDGE_ELEMENT, &properties);
++}
++
++void IdealGraphPrinter::EdgeDescription::print_removed(IdealGraphPrinter *printer) {
++
++  Properties properties;
++  properties.add(new Property(INDEX_PROPERTY, _index));
++  properties.add(new Property(FROM_PROPERTY, _from));
++  properties.add(new Property(TO_PROPERTY, _to));
++  printer->simple_element(REMOVE_EDGE_ELEMENT, &properties);
++}
++
++bool IdealGraphPrinter::EdgeDescription::equals(IdealGraphPrinter::EdgeDescription *desc) {
++  if (desc == NULL) return false;
++  return (_from == desc->_from && _to == desc->_to && _index == desc->_index);
++}
++
++IdealGraphPrinter::Properties::Properties() : list(new (ResourceObj::C_HEAP) GrowableArray<Property *>(2, 0, NULL, true)) {
++}
++
++IdealGraphPrinter::Properties::~Properties() {
++  clean();
++  delete list;
++}
++
++void IdealGraphPrinter::Properties::add(Property *p) {
++  assert(p != NULL, "Property not NULL");
++  list->append(p);
++}
++
++void IdealGraphPrinter::Properties::print(IdealGraphPrinter *printer) {
++  printer->start_element(PROPERTIES_ELEMENT);
++
++  for (int i = 0; i < list->length(); i++) {
++    list->at(i)->print(printer);
++  }
++
++  printer->end_element(PROPERTIES_ELEMENT);
++}
++
++void IdealGraphPrinter::Properties::clean() {
++  for (int i = 0; i < list->length(); i++) {
++    delete list->at(i);
++    list->at_put(i, NULL);
++  }
++  list->clear();
++  assert(list->length() == 0, "List cleared");
++}
++
++void IdealGraphPrinter::Properties::remove(const char *name) {
++  for (int i = 0; i < list->length(); i++) {
++    if (strcmp(list->at(i)->name(), name) == 0) {
++      delete list->at(i);
++      list->remove_at(i);
++      i--;
++    }
++  }
++}
++
++void IdealGraphPrinter::Properties::print_as_attributes(IdealGraphPrinter *printer) {
++
++  for (int i = 0; i < list->length(); i++) {
++    assert(list->at(i) != NULL, "Property not null!");
++    printer->output()->print(" ");
++    list->at(i)->print_as_attribute(printer);
++  }
++}
++
++bool IdealGraphPrinter::Properties::equals(Properties* p) {
++  if (p->list->length() != this->list->length()) return false;
++
++  for (int i = 0; i < list->length(); i++) {
++    assert(list->at(i) != NULL, "Property not null!");
++    if (!list->at(i)->equals(p->list->at(i))) return false;
++  }
++
++  return true;
++}
++
++IdealGraphPrinter::Property::Property() {
++  _name = NULL;
++  _value = NULL;
++}
++
++const char *IdealGraphPrinter::Property::name() {
++  return _name;
++}
++
++IdealGraphPrinter::Property::Property(const Property* p) {
++
++  this->_name = NULL;
++  this->_value = NULL;
++
++  if (p->_name != NULL) {
++    _name = dup(p->_name);
++  }
++
++  if (p->_value) {
++    _value = dup(p->_value);
++  }
++}
++
++IdealGraphPrinter::Property::~Property() {
++
++  clean();
++}
++
++IdealGraphPrinter::Property::Property(const char *name, const char *value) {
++
++  assert(name, "Name must not be null!");
++  assert(value, "Value must not be null!");
++
++  _name = dup(name);
++  _value = dup(value);
++}
++
++IdealGraphPrinter::Property::Property(const char *name, int intValue) {
++  _name = dup(name);
++
++  stringStream stream;
++  stream.print("%d", intValue);
++  _value = dup(stream.as_string());
++}
++
++void IdealGraphPrinter::Property::clean() {
++  if (_name) {
++    delete _name;
++    _name = NULL;
++  }
++
++  if (_value) {
++    delete _value;
++    _value = NULL;
++  }
++}
++
++
++bool IdealGraphPrinter::Property::is_null() {
++  return _name == NULL;
++}
++
++void IdealGraphPrinter::Property::print(IdealGraphPrinter *printer) {
++
++  assert(!is_null(), "null properties cannot be printed!");
++  Properties properties;
++  properties.add(new Property(PROPERTY_NAME_PROPERTY, _name));
++  printer->start_element(PROPERTY_ELEMENT, &properties, false, false);
++  printer->print_xml(_value);
++  printer->end_element(PROPERTY_ELEMENT, false, true);
++}
++
++void IdealGraphPrinter::Property::print_as_attribute(IdealGraphPrinter *printer) {
++
++  printer->output()->print(_name);
++  printer->output()->print("=\"");
++  printer->print_xml(_value);
++  printer->output()->print("\"");
++}
++
++
++bool IdealGraphPrinter::Property::equals(Property* p) {
++
++  if (is_null() && p->is_null()) return true;
++  if (is_null()) return false;
++  if (p->is_null()) return false;
++
++  int cmp1 = strcmp(p->_name, _name);
++  if (cmp1 != 0) return false;
++
++  int cmp2 = strcmp(p->_value, _value);
++  if (cmp2 != 0) return false;
++
++  return true;
++}
++
++void IdealGraphPrinter::print_xml(const char *value) {
++  size_t len = strlen(value);
++
++  char buf[2];
++  buf[1] = 0;
++  for (size_t i = 0; i < len; i++) {
++    char c = value[i];
++
++    switch(c) {
++      case '<':
++        output()->print("&lt;");
++        break;
++
++      case '>':
++        output()->print("&gt;");
++        break;
++
++      default:
++        buf[0] = c;
++        output()->print(buf);
++        break;
++    }
++  }
++}
++
++#endif
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/idealGraphPrinter.hpp openjdk/hotspot/src/share/vm/opto/idealGraphPrinter.hpp
+--- openjdk6/hotspot/src/share/vm/opto/idealGraphPrinter.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/opto/idealGraphPrinter.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,323 @@
++/*
++ * Copyright 2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++#ifndef PRODUCT
++
++class Compile;
++class PhaseIFG;
++class PhaseChaitin;
++class Matcher;
++class Node;
++class InlineTree;
++class ciMethod;
++
++class IdealGraphPrinter
++{
++private:
++
++  enum State
++  {
++    Invalid,
++    Valid,
++    New
++  };
++
++private:
++
++  static const char *INDENT;
++  static const char *TOP_ELEMENT;
++  static const char *GROUP_ELEMENT;
++  static const char *GRAPH_ELEMENT;
++  static const char *PROPERTIES_ELEMENT;
++  static const char *EDGES_ELEMENT;
++  static const char *PROPERTY_ELEMENT;
++  static const char *EDGE_ELEMENT;
++  static const char *NODE_ELEMENT;
++  static const char *NODES_ELEMENT;
++  static const char *CONTROL_FLOW_ELEMENT;
++  static const char *REMOVE_EDGE_ELEMENT;
++  static const char *REMOVE_NODE_ELEMENT;
++  static const char *METHOD_NAME_PROPERTY;
++  static const char *BLOCK_NAME_PROPERTY;
++  static const char *BLOCK_DOMINATOR_PROPERTY;
++  static const char *BLOCK_ELEMENT;
++  static const char *SUCCESSORS_ELEMENT;
++  static const char *SUCCESSOR_ELEMENT;
++  static const char *METHOD_IS_PUBLIC_PROPERTY;
++  static const char *METHOD_IS_STATIC_PROPERTY;
++  static const char *TRUE_VALUE;
++  static const char *NODE_NAME_PROPERTY;
++  static const char *EDGE_NAME_PROPERTY;
++  static const char *NODE_ID_PROPERTY;
++  static const char *FROM_PROPERTY;
++  static const char *TO_PROPERTY;
++  static const char *PROPERTY_NAME_PROPERTY;
++  static const char *GRAPH_NAME_PROPERTY;
++  static const char *INDEX_PROPERTY;
++  static const char *METHOD_ELEMENT;
++  static const char *INLINE_ELEMENT;
++  static const char *BYTECODES_ELEMENT;
++  static const char *METHOD_BCI_PROPERTY;
++  static const char *METHOD_SHORT_NAME_PROPERTY;
++  static const char *ASSEMBLY_ELEMENT;
++
++  class Property {
++
++  private:
++
++    const char *_name;
++    const char *_value;
++
++  public:
++
++    Property();
++    Property(const Property* p);
++    ~Property();
++    Property(const char *name, const char *value);
++    Property(const char *name, int value);
++    bool equals(Property* p);
++    void print(IdealGraphPrinter *printer);
++    void print_as_attribute(IdealGraphPrinter *printer);
++    bool is_null();
++    void clean();
++    const char *name();
++
++    static const char* dup(const char *str) {
++      char * copy = new char[strlen(str)+1];
++      strcpy(copy, str);
++      return copy;
++    }
++
++  };
++
++  class Properties {
++
++  private:
++
++    GrowableArray<Property *> *list;
++
++  public:
++
++    Properties();
++    ~Properties();
++    void add(Property *p);
++    void remove(const char *name);
++    bool equals(Properties* p);
++    void print(IdealGraphPrinter *printer);
++    void print_as_attributes(IdealGraphPrinter *printer);
++    void clean();
++
++  };
++
++
++  class Description {
++
++  private:
++
++    State _state;
++
++  public:
++
++    Description();
++
++    State state();
++    void set_state(State s);
++    void print(IdealGraphPrinter *printer);
++    virtual void print_changed(IdealGraphPrinter *printer) = 0;
++    virtual void print_removed(IdealGraphPrinter *printer) = 0;
++
++  };
++
++  class NodeDescription : public Description{
++
++  public:
++
++    static int count;
++
++  private:
++
++    GrowableArray<NodeDescription *> _succs;
++    int _block_index;
++    uintptr_t _id;
++    Properties _properties;
++    Node* _node;
++
++  public:
++
++    NodeDescription(Node* node);
++    ~NodeDescription();
++    Node* node();
++
++    // void set_node(Node* node);
++    GrowableArray<NodeDescription *>* succs();
++    void init_succs();
++    void clear_succs();
++    void add_succ(NodeDescription *desc);
++    int block_index();
++    void set_block_index(int i);
++    Properties* properties();
++    virtual void print_changed(IdealGraphPrinter *printer);
++    virtual void print_removed(IdealGraphPrinter *printer);
++    bool equals(NodeDescription *desc);
++    uint id();
++
++  };
++
++  class Block {
++
++  private:
++
++    NodeDescription *_start;
++    NodeDescription *_proj;
++    GrowableArray<int> _succs;
++    GrowableArray<NodeDescription *> _nodes;
++    GrowableArray<int> _dominates;
++    GrowableArray<int> _children;
++    int _semi;
++    int _parent;
++    GrowableArray<int> _pred;
++    GrowableArray<int> _bucket;
++    int _index;
++    int _dominator;
++    int _ancestor;
++    int _label;
++
++  public:
++
++    Block();
++    Block(int index);
++
++    void add_node(NodeDescription *n);
++    GrowableArray<NodeDescription *>* nodes();
++    GrowableArray<int>* children();
++    void add_child(int i);
++    void add_succ(int index);
++    GrowableArray<int>* succs();
++    GrowableArray<int>* dominates();
++    void add_dominates(int i);
++    NodeDescription *start();
++    NodeDescription *proj();
++    void set_start(NodeDescription *n);
++    void set_proj(NodeDescription *n);
++
++    int label();
++    void set_label(int i);
++    int ancestor();
++    void set_ancestor(int i);
++    int index();
++    int dominator();
++    void set_dominator(int i);
++    int parent();
++    void set_parent(int i);
++    int semi();
++    GrowableArray<int>* bucket();
++    void add_to_bucket(int i);
++    void clear_bucket();
++    GrowableArray<int>* pred();
++    void set_semi(int i);
++    void add_pred(int i);
++
++  };
++
++  class EdgeDescription : public Description {
++
++  private:
++
++    int _from;
++    int _to;
++    int _index;
++  public:
++
++    EdgeDescription(int from, int to, int index);
++    ~EdgeDescription();
++
++    virtual void print_changed(IdealGraphPrinter *printer);
++    virtual void print_removed(IdealGraphPrinter *printer);
++    bool equals(EdgeDescription *desc);
++    int from();
++    int to();
++  };
++
++
++  static int _file_count;
++  networkStream *_stream;
++  outputStream *_output;
++  ciMethod *_current_method;
++  GrowableArray<NodeDescription *> _nodes;
++  GrowableArray<EdgeDescription *> _edges;
++  int _depth;
++  Arena *_arena;
++  char buffer[128];
++  bool _should_send_method;
++  PhaseChaitin* _chaitin;
++  bool _clear_nodes;
++  Matcher* _matcher;
++  bool _traverse_outs;
++
++  void start_element_helper(const char *name, Properties *properties, bool endElement, bool print_indent = false, bool print_return = true);
++  NodeDescription *create_node_description(Node* node);
++
++  static void pre_node(Node* node, void *env);
++  static void post_node(Node* node, void *env);
++
++  void schedule_latest(int **common_dominator, GrowableArray<Block>* blocks);
++  void build_common_dominator(int **common_dominator, int index, GrowableArray<Block>* blocks);
++  void compress(int index, GrowableArray<Block>* blocks);
++  int eval(int index, GrowableArray<Block>* blocks);
++  void link(int index1, int index2, GrowableArray<Block>* blocks);
++  void build_dominators(GrowableArray<Block>* blocks);
++  void build_blocks(Node *node);
++  void walk(Node *n);
++  void start_element(const char *name, Properties *properties = NULL, bool print_indent = false, bool print_return = true);
++  void simple_element(const char *name, Properties *properties = NULL, bool print_indent = false);
++  void end_element(const char *name, bool print_indent = false, bool print_return = true);
++  void print_edge(int from, int to, int index);
++  void print_indent();
++  void print_method(ciMethod *method, int bci, InlineTree *tree);
++  void print_inline_tree(InlineTree *tree);
++  void clear_nodes();
++
++  IdealGraphPrinter();
++  ~IdealGraphPrinter();
++
++public:
++
++  static void clean_up();
++  static IdealGraphPrinter *printer();
++
++  bool traverse_outs();
++  void set_traverse_outs(bool b);
++  void print_ifg(PhaseIFG* ifg);
++  outputStream *output();
++  void print_inlining(Compile* compile);
++  void begin_method(Compile* compile);
++  void end_method();
++  void print_method(Compile* compile, const char *name, int level=1, bool clear_nodes = false);
++  void print(Compile* compile, const char *name, Node *root, int level=1, bool clear_nodes = false);
++  void print_xml(const char *name);
++
++
++};
++
++#endif
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/idealKit.cpp openjdk/hotspot/src/share/vm/opto/idealKit.cpp
+--- openjdk6/hotspot/src/share/vm/opto/idealKit.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/idealKit.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)idealKit.cpp	1.7 07/05/05 17:06:29 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,15 +26,23 @@
+ #include "incls/_idealKit.cpp.incl"
+ 
+ // Static initialization
+-const uint IdealKit::first_var = 1;
++
++// This declares the position where vars are kept in the cvstate
++// For some degree of consistency we use the TypeFunc enum to
++// soak up spots in the inputs even though we only use early Control
++// and Memory slots. (So far.)
++const uint IdealKit::first_var = TypeFunc::Parms + 1;
+ 
+ //----------------------------IdealKit-----------------------------------------
+-IdealKit::IdealKit(PhaseGVN &gvn, Node* control, bool delay_all_transforms) :
++IdealKit::IdealKit(PhaseGVN &gvn, Node* control, Node* mem, bool delay_all_transforms) :
+   _gvn(gvn), C(gvn.C) {
+   _initial_ctrl = control;
++  _initial_memory = mem;
+   _delay_all_transforms = delay_all_transforms;
+   _var_ct = 0;
+   _cvstate = NULL;
++  // We can go memory state free or else we need the entire memory state
++  assert(mem == NULL || mem->Opcode() == Op_MergeMem, "memory must be pre-split");
+   int init_size = 5;
+   _pending_cvstates = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0);
+   _delay_transform  = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0);
+@@ -52,14 +57,25 @@
+ void IdealKit::if_then(Node* left, BoolTest::mask relop,
+                        Node* right, float prob, float cnt, bool push_new_state) {
+   assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new If");
+-  Node* bol = Bool(CmpI(left, right), relop);
++  Node* bol;
++  if (left->bottom_type()->isa_ptr() == NULL) {
++    if (left->bottom_type()->isa_int() != NULL) {
++      bol = Bool(CmpI(left, right), relop);
++    } else {
++      assert(left->bottom_type()->isa_long() != NULL, "what else?");
++      bol = Bool(CmpL(left, right), relop);
++    }
++
++  } else {
++    bol = Bool(CmpP(left, right), relop);
++  }
+   // Delay gvn.tranform on if-nodes until construction is finished
+   // to prevent a constant bool input from discarding a control output.
+   IfNode* iff = delay_transform(new (C, 2) IfNode(ctrl(), bol, prob, cnt))->as_If();
+   Node* then  = IfTrue(iff);
+   Node* elsen = IfFalse(iff);
+   Node* else_cvstate = copy_cvstate();
+-  else_cvstate->set_req(0, elsen);
++  else_cvstate->set_req(TypeFunc::Control, elsen);
+   _pending_cvstates->push(else_cvstate);
+   DEBUG_ONLY(if (push_new_state) _state->push(IfThenS));
+   set_ctrl(then);
+@@ -79,16 +95,42 @@
+ }
+ 
+ //-------------------------------end_if-------------------------------------
+-// Merge the "then" and "else" cvstates from an "if" via:
+-// create label, generate a goto from the current cvstate to the
+-// new label, pop the other cvstate from the if ("else" cvstate if
+-// no else_() and "then" cvstate if there was), and bind the label
+-// to the popped cvstate.
++// Merge the "then" and "else" cvstates.
++//
++// The if_then() pushed the current state for later use
++// as the initial state for a future "else" clause.  The
++// current state then became the initial state for the
++// then clause.  If an "else" clause was encountered, it will
++// pop the top state and use it for it's initial state.
++// It will also push the current state (the state at the end of
++// the "then" clause) for latter use at the end_if.
++//
++// At the endif, the states are:
++// 1) else exists a) current state is end of "else" clause
++//                b) top stack state is end of "then" clause
++//
++// 2) no else:    a) current state is end of "then" clause
++//                b) top stack state is from the "if_then" which
++//                   would have been the initial state of the else.
++//
++// Merging the states is accomplished by:
++//   1) make a label for the merge
++//   2) terminate the current state with a goto to the label
++//   3) pop the top state from the stack and make it the
++//        current state
++//   4) bind the label at the current state.  Binding a label
++//        terminates the current state with a goto to the
++//        label and makes the label's state the current state.
++//
+ void IdealKit::end_if() {
+   assert(state() & (IfThenS|ElseS), "bad state for new Endif");
+   Node* lab = make_label(1);
++
++  // Node* join_state = _pending_cvstates->pop();
++                  /* merging, join */
+   goto_(lab);
+   _cvstate = _pending_cvstates->pop();
++
+   bind(lab);
+   DEBUG_ONLY(_state->pop());
+ }
+@@ -115,7 +157,7 @@
+   if_then(value(iv), relop, limit, prob, cnt, false /* no new state */);
+   DEBUG_ONLY(_state->push(LoopS));
+   assert(ctrl()->is_IfTrue(), "true branch stays in loop");
+-  assert(_pending_cvstates->top()->in(0)->is_IfFalse(), "false branch exits loop");
++  assert(_pending_cvstates->top()->in(TypeFunc::Control)->is_IfFalse(), "false branch exits loop");
+ }
+ 
+ //-------------------------------end_loop-------------------------------------
+@@ -141,7 +183,7 @@
+   Node* lab = new_cvstate();
+   int sz = 1 + goto_ct + 1 /* fall thru */;
+   Node* reg = delay_transform(new (C, sz) RegionNode(sz));
+-  lab->init_req(0, reg);
++  lab->init_req(TypeFunc::Control, reg);
+   return lab;
+ }
+ 
+@@ -160,7 +202,7 @@
+ // all live values have phis created. Used to create phis
+ // at loop-top regions.
+ void IdealKit::goto_(Node* lab, bool bind) {
+-  Node* reg = lab->in(0);
++  Node* reg = lab->in(TypeFunc::Control);
+   // find next empty slot in region
+   uint slot = 1;
+   while (slot < reg->req() && reg->in(slot) != NULL) slot++;
+@@ -170,23 +212,40 @@
+   reg->init_req(slot, ctrl());
+   assert(first_var + _var_ct == _cvstate->req(), "bad _cvstate size");
+   for (uint i = first_var; i < _cvstate->req(); i++) {
++
++    // l is the value of var reaching the label. Could be a single value
++    // reaching the label, or a phi that merges multiples values reaching
++    // the label.  The latter is true if the label's input: in(..) is
++    // a phi whose control input is the region node for the label.
++
+     Node* l = lab->in(i);
++    // Get the current value of the var
+     Node* m = _cvstate->in(i);
++    // If the var went unused no need for a phi
+     if (m == NULL) {
+       continue;
+     } else if (l == NULL || m == l) {
++      // Only one unique value "m" is known to reach this label so a phi
++      // is not yet necessary unless:
++      //    the label is being bound and all predecessors have not been seen,
++      //    in which case "bind" will be true.
+       if (bind) {
+         m = promote_to_phi(m, reg);
+       }
++      // Record the phi/value used for this var in the label's cvstate
+       lab->set_req(i, m);
+     } else {
++      // More than one value for the variable reaches this label so
++      // a create a phi if one does not already exist.
+       if (!was_promoted_to_phi(l, reg)) {
+         l = promote_to_phi(l, reg);
+         lab->set_req(i, l);
+       }
++      // Record in the phi, the var's value from the current state
+       l->set_req(slot, m);
+     }
+   }
++  do_memory_merge(_cvstate, lab);
+   stop();
+ }
+ 
+@@ -203,6 +262,7 @@
+ void IdealKit::declares_done() {
+   _cvstate = new_cvstate();   // initialize current cvstate
+   set_ctrl(_initial_ctrl);    // initialize control in current cvstate
++  set_all_memory(_initial_memory);// initialize memory in current cvstate
+   DEBUG_ONLY(_state->push(BlockS));
+ }
+ 
+@@ -232,6 +292,8 @@
+ Node* IdealKit::copy_cvstate() {
+   Node* ns = new_cvstate();
+   for (uint i = 0; i < ns->req(); i++) ns->init_req(i, _cvstate->in(i));
++  // We must clone memory since it will be updated as we do stores.
++  ns->set_req(TypeFunc::Memory, MergeMemNode::make(C, ns->in(TypeFunc::Memory)));
+   return ns;
+ }
+ 
+@@ -256,3 +318,186 @@
+   k.declare(this);
+ }
+ 
++Node* IdealKit::memory(uint alias_idx) {
++  MergeMemNode* mem = merged_memory();
++  Node* p = mem->memory_at(alias_idx);
++  _gvn.set_type(p, Type::MEMORY);  // must be mapped
++  return p;
++}
++
++void IdealKit::set_memory(Node* mem, uint alias_idx) {
++  merged_memory()->set_memory_at(alias_idx, mem);
++}
++
++//----------------------------- make_load ----------------------------
++Node* IdealKit::load(Node* ctl,
++                     Node* adr,
++                     const Type* t,
++                     BasicType bt,
++                     int adr_idx,
++                     bool require_atomic_access) {
++
++  assert(adr_idx != Compile::AliasIdxTop, "use other make_load factory" );
++  const TypePtr* adr_type = NULL; // debug-mode-only argument
++  debug_only(adr_type = C->get_adr_type(adr_idx));
++  Node* mem = memory(adr_idx);
++  Node* ld;
++  if (require_atomic_access && bt == T_LONG) {
++    ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t);
++  } else {
++    ld = LoadNode::make(C, ctl, mem, adr, adr_type, t, bt);
++  }
++  return transform(ld);
++}
++
++Node* IdealKit::store(Node* ctl, Node* adr, Node *val, BasicType bt,
++                                int adr_idx,
++                                bool require_atomic_access) {
++  assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
++  const TypePtr* adr_type = NULL;
++  debug_only(adr_type = C->get_adr_type(adr_idx));
++  Node *mem = memory(adr_idx);
++  Node* st;
++  if (require_atomic_access && bt == T_LONG) {
++    st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val);
++  } else {
++    st = StoreNode::make(C, ctl, mem, adr, adr_type, val, bt);
++  }
++  st = transform(st);
++  set_memory(st, adr_idx);
++
++  return st;
++}
++
++// Card mark store. Must be ordered so that it will come after the store of
++// the oop.
++Node* IdealKit::storeCM(Node* ctl, Node* adr, Node *val, Node* oop_store,
++                        BasicType bt,
++                        int adr_idx) {
++  assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
++  const TypePtr* adr_type = NULL;
++  debug_only(adr_type = C->get_adr_type(adr_idx));
++  Node *mem = memory(adr_idx);
++
++  // Add required edge to oop_store, optimizer does not support precedence edges.
++  // Convert required edge to precedence edge before allocation.
++  Node* st = new (C, 5) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store);
++
++  st = transform(st);
++  set_memory(st, adr_idx);
++
++  return st;
++}
++
++//---------------------------- do_memory_merge --------------------------------
++// The memory from one merging cvstate needs to be merged with the memory for another
++// join cvstate. If the join cvstate doesn't have a merged memory yet then we
++// can just copy the state from the merging cvstate
++
++// Merge one slow path into the rest of memory.
++void IdealKit::do_memory_merge(Node* merging, Node* join) {
++
++  // Get the region for the join state
++  Node* join_region = join->in(TypeFunc::Control);
++  assert(join_region != NULL, "join region must exist");
++  if (join->in(TypeFunc::Memory) == NULL ) {
++    join->set_req(TypeFunc::Memory,  merging->in(TypeFunc::Memory));
++    return;
++  }
++
++  // The control flow for merging must have already been attached to the join region
++  // we need its index for the phis.
++  uint slot;
++  for (slot = 1; slot < join_region->req() ; slot ++ ) {
++    if (join_region->in(slot) == merging->in(TypeFunc::Control)) break;
++  }
++  assert(slot !=  join_region->req(), "edge must already exist");
++
++  MergeMemNode* join_m    = join->in(TypeFunc::Memory)->as_MergeMem();
++  MergeMemNode* merging_m = merging->in(TypeFunc::Memory)->as_MergeMem();
++
++  // join_m should be an ancestor mergemem of merging
++  // Slow path memory comes from the current map (which is from a slow call)
++  // Fast path/null path memory comes from the call's input
++
++  // Merge the other fast-memory inputs with the new slow-default memory.
++  // for (MergeMemStream mms(merged_memory(), fast_mem->as_MergeMem()); mms.next_non_empty2(); ) {
++  for (MergeMemStream mms(join_m, merging_m); mms.next_non_empty2(); ) {
++    Node* join_slice = mms.force_memory();
++    Node* merging_slice = mms.memory2();
++    if (join_slice != merging_slice) {
++      PhiNode* phi;
++      // bool new_phi = false;
++      // Is the phi for this slice one that we created for this join region or simply
++      // one we copied? If it is ours then add
++      if (join_slice->is_Phi() && join_slice->as_Phi()->region() == join_region) {
++        phi = join_slice->as_Phi();
++      } else {
++        // create the phi with join_slice filling supplying memory for all of the
++        // control edges to the join region
++        phi = PhiNode::make(join_region, join_slice, Type::MEMORY, mms.adr_type(C));
++        phi = (PhiNode*) delay_transform(phi);
++        // gvn().set_type(phi, Type::MEMORY);
++        // new_phi = true;
++      }
++      // Now update the phi with the slice for the merging slice
++      phi->set_req(slot, merging_slice/* slow_path, slow_slice */);
++      // this updates join_m with the phi
++      mms.set_memory(phi);
++    }
++  }
++}
++
++
++//----------------------------- make_call  ----------------------------
++// Trivial runtime call
++void IdealKit::make_leaf_call(const TypeFunc *slow_call_type,
++                              address slow_call,
++                              const char *leaf_name,
++                              Node* parm0,
++                              Node* parm1,
++                              Node* parm2) {
++
++  // We only handle taking in RawMem and modifying RawMem
++  const TypePtr* adr_type = TypeRawPtr::BOTTOM;
++  uint adr_idx = C->get_alias_index(adr_type);
++
++  // Clone initial memory
++  MergeMemNode* cloned_mem =  MergeMemNode::make(C, merged_memory());
++
++  // Slow-path leaf call
++  int size = slow_call_type->domain()->cnt();
++  CallNode *call =  (CallNode*)new (C, size) CallLeafNode( slow_call_type, slow_call, leaf_name, adr_type);
++
++  // Set fixed predefined input arguments
++  call->init_req( TypeFunc::Control, ctrl() );
++  call->init_req( TypeFunc::I_O    , top() )     ;   // does no i/o
++  // Narrow memory as only memory input
++  call->init_req( TypeFunc::Memory , memory(adr_idx));
++  call->init_req( TypeFunc::FramePtr, top() /* frameptr() */ );
++  call->init_req( TypeFunc::ReturnAdr, top() );
++
++  if (parm0 != NULL)  call->init_req(TypeFunc::Parms+0, parm0);
++  if (parm1 != NULL)  call->init_req(TypeFunc::Parms+1, parm1);
++  if (parm2 != NULL)  call->init_req(TypeFunc::Parms+2, parm2);
++
++  // Node *c = _gvn.transform(call);
++  call = (CallNode *) _gvn.transform(call);
++  Node *c = call; // dbx gets confused with call call->dump()
++
++  // Slow leaf call has no side-effects, sets few values
++
++  set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) ));
++
++  // Set the incoming clone of memory as current memory
++  set_all_memory(cloned_mem);
++
++  // Make memory for the call
++  Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) );
++
++  // Set the RawPtr memory state only.
++  set_memory(mem, adr_idx);
++
++  assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type),
++         "call node must be constructed correctly");
++}
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/idealKit.hpp openjdk/hotspot/src/share/vm/opto/idealKit.hpp
+--- openjdk6/hotspot/src/share/vm/opto/idealKit.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/idealKit.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)idealKit.hpp	1.7 07/05/05 17:06:17 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -93,17 +90,23 @@
+   PhaseGVN &_gvn;
+   GrowableArray<Node*>* _pending_cvstates; // stack of cvstates
+   GrowableArray<Node*>* _delay_transform;  // delay invoking gvn.transform until drain
+-  Node* _cvstate;                          // current cvstate (control and variables)
++  Node* _cvstate;                          // current cvstate (control, memory and variables)
+   uint _var_ct;                            // number of variables
+   bool _delay_all_transforms;              // flag forcing all transforms to be delayed
+   Node* _initial_ctrl;                     // saves initial control until variables declared
++  Node* _initial_memory;                   // saves initial memory  until variables declared
+ 
+   PhaseGVN& gvn() const { return _gvn; }
+   // Create a new cvstate filled with nulls
+   Node* new_cvstate();                     // Create a new cvstate
+   Node* cvstate() { return _cvstate; }     // current cvstate
+   Node* copy_cvstate();                    // copy current cvstate
+-  void set_ctrl(Node* ctrl) { _cvstate->set_req(0, ctrl); }
++  void set_ctrl(Node* ctrl) { _cvstate->set_req(TypeFunc::Control, ctrl); }
++
++  // Should this assert this is a MergeMem???
++  void set_all_memory(Node* mem){ _cvstate->set_req(TypeFunc::Memory, mem); }
++  void set_memory(Node* mem, uint alias_idx );
++  void do_memory_merge(Node* merging, Node* join);
+   void clear(Node* m);                     // clear a cvstate
+   void stop() { clear(_cvstate); }         // clear current cvstate
+   Node* delay_transform(Node* n);          
+@@ -113,7 +116,11 @@
+     return (n->is_Phi() && n->in(0) == reg);
+   }
+   void declare(IdealVariable* v) { v->set_id(_var_ct++); }
+-  static const uint first_var;
++  // This declares the position where vars are kept in the cvstate
++  // For some degree of consistency we use the TypeFunc enum to
++  // soak up spots in the inputs even though we only use early Control
++  // and Memory slots. (So far.)
++  static const uint first_var; // = TypeFunc::Parms + 1;
+ 
+ #ifdef ASSERT
+   enum State { NullS=0, BlockS=1, LoopS=2, IfThenS=4, ElseS=8, EndifS= 16 };
+@@ -121,14 +128,19 @@
+   State state() { return (State)(_state->top()); }
+ #endif
+  
++  // Users should not care about slices only MergedMem so no access for them.
++  Node* memory(uint alias_idx);
++
+  public:
+-  IdealKit(PhaseGVN &gvn, Node* control, bool delay_all_transforms = false);
++  IdealKit(PhaseGVN &gvn, Node* control, Node* memory, bool delay_all_transforms = false);
+   ~IdealKit() {
+     stop();
+     drain_delay_transform();
+   }
+   // Control
+-  Node* ctrl()                          { return _cvstate->in(0); }
++  Node* ctrl()                          { return _cvstate->in(TypeFunc::Control); }
++  Node* top()                           { return C->top(); }
++  MergeMemNode* merged_memory()         { return _cvstate->in(TypeFunc::Memory)->as_MergeMem(); }
+   void set(IdealVariable& v, Node* rhs) { _cvstate->set_req(first_var + v.id(), rhs); }
+   Node* value(IdealVariable& v)         { return _cvstate->in(first_var + v.id()); }
+   void dead(IdealVariable& v)           { set(v, (Node*)NULL); }
+@@ -145,10 +157,14 @@
+   void goto_(Node* lab, bool bind = false);
+   void declares_done();
+   void drain_delay_transform();
++
+   Node* IfTrue(IfNode* iff)  { return transform(new (C,1) IfTrueNode(iff)); }
+   Node* IfFalse(IfNode* iff) { return transform(new (C,1) IfFalseNode(iff)); }
++
+   // Data
+   Node* ConI(jint k) { return (Node*)gvn().intcon(k); }
++  Node* makecon(const Type *t)  const { return _gvn.makecon(t); }
++
+   Node* AddI(Node* l, Node* r) { return transform(new (C,3) AddINode(l, r)); }
+   Node* SubI(Node* l, Node* r) { return transform(new (C,3) SubINode(l, r)); }
+   Node* AndI(Node* l, Node* r) { return transform(new (C,3) AndINode(l, r)); }
+@@ -158,4 +174,57 @@
+   Node* Bool(Node* cmp, BoolTest::mask relop) { return transform(new (C,2) BoolNode(cmp, relop)); }
+   void  increment(IdealVariable& v, Node* j)  { set(v, AddI(value(v), j)); }
+   void  decrement(IdealVariable& v, Node* j)  { set(v, SubI(value(v), j)); }
++
++  Node* CmpL(Node* l, Node* r) { return transform(new (C,3) CmpLNode(l, r)); }
++
++  // TLS
++  Node* thread()  {  return gvn().transform(new (C, 1) ThreadLocalNode()); }
++
++  // Pointers
++  Node* AddP(Node *base, Node *ptr, Node *off) { return transform(new (C,4) AddPNode(base, ptr, off)); }
++  Node* CmpP(Node* l, Node* r) { return transform(new (C,3) CmpPNode(l, r)); }
++#ifdef _LP64
++  Node* XorX(Node* l, Node* r) { return transform(new (C,3) XorLNode(l, r)); }
++#else // _LP64
++  Node* XorX(Node* l, Node* r) { return transform(new (C,3) XorINode(l, r)); }
++#endif // _LP64
++  Node* URShiftX(Node* l, Node* r) { return transform(new (C,3) URShiftXNode(l, r)); }
++  Node* ConX(jint k) { return (Node*)gvn().MakeConX(k); }
++  Node* CastPX(Node* ctl, Node* p) { return transform(new (C,2) CastP2XNode(ctl, p)); }
++  // Add a fixed offset to a pointer
++  Node* basic_plus_adr(Node* base, Node* ptr, intptr_t offset);
++
++  // Memory operations
++
++  // This is the base version which is given an alias index.
++  Node* load(Node* ctl,
++             Node* adr,
++             const Type* t,
++             BasicType bt,
++             int adr_idx,
++             bool require_atomic_access = false);
++
++  // Return the new StoreXNode
++  Node* store(Node* ctl,
++              Node* adr,
++              Node* val,
++              BasicType bt,
++              int adr_idx,
++              bool require_atomic_access = false);
++
++  // Store a card mark ordered after store_oop
++  Node* storeCM(Node* ctl,
++                Node* adr,
++                Node* val,
++                Node* oop_store,
++                BasicType bt,
++                int adr_idx);
++
++  // Trivial call
++  void make_leaf_call(const TypeFunc *slow_call_type,
++                      address slow_call,
++                      const char *leaf_name,
++                      Node* parm0,
++                      Node* parm1 = NULL,
++                      Node* parm2 = NULL);
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/ifg.cpp openjdk/hotspot/src/share/vm/opto/ifg.cpp
+--- openjdk6/hotspot/src/share/vm/opto/ifg.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/ifg.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ifg.cpp	1.62 07/05/05 17:06:13 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -814,4 +811,3 @@
+ 
+   return must_spill;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/ifnode.cpp openjdk/hotspot/src/share/vm/opto/ifnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/ifnode.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/ifnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ifnode.cpp	1.60 07/05/17 17:43:44 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -364,13 +361,19 @@
+     Node *u = (p->Opcode() == Op_IfTrue) ? region_s : region_f;
+     // Replace p with u
+     igvn->add_users_to_worklist(p);
+-    for (DUIterator_Last jmin, j = p->last_outs(jmin); j >= jmin; --j) {
+-      Node* x = p->last_out(j);
++    for (DUIterator_Last lmin, l = p->last_outs(lmin); l >= lmin;) {
++      Node* x = p->last_out(l);
+       igvn->hash_delete(x);  
+-      for( uint j = 0; j < x->req(); j++ )
+-        if( x->in(j) == p )
+-          x->set_req_X(j,u,igvn);
++      uint uses_found = 0;
++      for( uint j = 0; j < x->req(); j++ ) {
++        if( x->in(j) == p ) {
++          x->set_req(j, u);
++          uses_found++;
++        }
+     }
++      l -= uses_found;    // we deleted 1 or more copies of this edge
++    }
++    igvn->remove_dead_node(p);
+   }
+ 
+   // Force the original merge dead
+@@ -842,8 +845,8 @@
+ 
+ //------------------------------dump_spec--------------------------------------
+ #ifndef PRODUCT
+-void IfNode::dump_spec() const { 
+-  tty->print("P=%f, C=%f",_prob,_fcnt);
++void IfNode::dump_spec(outputStream *st) const {
++  st->print("P=%f, C=%f",_prob,_fcnt);
+ }
+ #endif
+ 
+@@ -917,4 +920,3 @@
+     ? in(0)->in(0)              // IfNode control
+     : this;                     // no progress
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/indexSet.cpp openjdk/hotspot/src/share/vm/opto/indexSet.cpp
+--- openjdk6/hotspot/src/share/vm/opto/indexSet.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/indexSet.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)indexSet.cpp	1.24 07/05/05 17:06:16 JVM"
+-#endif
+ /*
+  * Copyright 1998-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/indexSet.hpp openjdk/hotspot/src/share/vm/opto/indexSet.hpp
+--- openjdk6/hotspot/src/share/vm/opto/indexSet.hpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/indexSet.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)indexSet.hpp	1.29 07/05/05 17:06:18 JVM"
+-#endif
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/lcm.cpp openjdk/hotspot/src/share/vm/opto/lcm.cpp
+--- openjdk6/hotspot/src/share/vm/opto/lcm.cpp	2008-08-28 10:23:13.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/lcm.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)lcm.cpp	1.102 07/05/17 15:58:55 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -935,7 +932,3 @@
+     }
+   }
+ }
+-
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/library_call.cpp openjdk/hotspot/src/share/vm/opto/library_call.cpp
+--- openjdk6/hotspot/src/share/vm/opto/library_call.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/library_call.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)library_call.cpp	1.164 07/05/17 15:59:02 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -76,8 +73,12 @@
+   Node* generate_guard(Node* test, RegionNode* region, float true_prob);
+   Node* generate_slow_guard(Node* test, RegionNode* region);
+   Node* generate_fair_guard(Node* test, RegionNode* region);
+-  Node* generate_negative_guard(Node* index, RegionNode* region);
+-  Node* generate_nonpositive_guard(Node* index, bool never_negative);
++  Node* generate_negative_guard(Node* index, RegionNode* region,
++                                // resulting CastII of index:
++                                Node* *pos_index = NULL);
++  Node* generate_nonpositive_guard(Node* index, bool never_negative,
++                                   // resulting CastII of index:
++                                   Node* *pos_index = NULL);
+   Node* generate_limit_guard(Node* offset, Node* subseq_length,
+                              Node* array_length,
+                              RegionNode* region);
+@@ -181,7 +182,21 @@
+                           int nargs,  // arguments on stack for debug info
+                           bool disjoint_bases = false,
+ 			  bool length_never_negative = false,
+-                          Node* slow_region = NULL);
++                          RegionNode* slow_region = NULL);
++  AllocateArrayNode* tightly_coupled_allocation(Node* ptr,
++                                                RegionNode* slow_region);
++  void generate_clear_array(const TypePtr* adr_type,
++                            Node* dest,
++                            BasicType basic_elem_type,
++                            Node* slice_off,
++                            Node* slice_len,
++                            Node* slice_end);
++  bool generate_block_arraycopy(const TypePtr* adr_type,
++                                BasicType basic_elem_type,
++                                AllocateNode* alloc,
++                                Node* src,  Node* src_offset,
++                                Node* dest, Node* dest_offset,
++                                Node* dest_size);
+   void generate_slow_arraycopy(const TypePtr* adr_type,
+                                Node* src,  Node* src_offset,
+                                Node* dest, Node* dest_offset,
+@@ -196,8 +211,8 @@
+                                    Node* src,  Node* src_offset,
+                                    Node* dest, Node* dest_offset,
+                                    Node* copy_length, int nargs);
+-  void generate_unchecked_arraycopy(BasicType basic_elem_type,
+-                                    const TypePtr* adr_type,
++  void generate_unchecked_arraycopy(const TypePtr* adr_type,
++                                    BasicType basic_elem_type,
+                                     bool disjoint_bases,
+                                     Node* src,  Node* src_offset,
+                                     Node* dest, Node* dest_offset,
+@@ -631,6 +646,14 @@
+ 
+ //------------------------------generate_guard---------------------------
+ // Helper function for generating guarded fast-slow graph structures.
++// The given 'test', if true, guards a slow path.  If the test fails
++// then a fast path can be taken.  (We generally hope it fails.)
++// In all cases, GraphKit::control() is updated to the fast path.
++// The returned value represents the control for the slow path.
++// The return value is never 'top'; it is either a valid control
++// or NULL if it is obvious that the slow path can never be taken.
++// Also, if region and the slow control are not NULL, the slow edge
++// is appended to the region.
+ Node* LibraryCallKit::generate_guard(Node* test, RegionNode* region, float true_prob) {
+   if (stopped()) {
+     // Already short circuited.
+@@ -668,7 +691,8 @@
+   return generate_guard(test, region, PROB_FAIR);
+ }
+ 
+-inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* region) {
++inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* region,
++                                                     Node* *pos_index) {
+   if (stopped())
+     return NULL;                // already stopped
+   if (_gvn.type(index)->higher_equal(TypeInt::POS)) // [0,maxint]
+@@ -676,10 +700,17 @@
+   Node* cmp_lt = _gvn.transform( new (C, 3) CmpINode(index, intcon(0)) );
+   Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) );
+   Node* is_neg = generate_guard(bol_lt, region, PROB_MIN);
++  if (is_neg != NULL && pos_index != NULL) {
++    // Emulate effect of Parse::adjust_map_after_if.
++    Node* ccast = new (C, 2) CastIINode(index, TypeInt::POS);
++    ccast->set_req(0, control());
++    (*pos_index) = _gvn.transform(ccast);
++  }
+   return is_neg;
+ }
+ 
+-inline Node* LibraryCallKit::generate_nonpositive_guard(Node* index, bool never_negative) {
++inline Node* LibraryCallKit::generate_nonpositive_guard(Node* index, bool never_negative,
++                                                        Node* *pos_index) {
+   if (stopped())
+     return NULL;                // already stopped
+   if (_gvn.type(index)->higher_equal(TypeInt::POS1)) // [1,maxint]
+@@ -688,6 +719,12 @@
+   BoolTest::mask le_or_eq = (never_negative ? BoolTest::eq : BoolTest::le);
+   Node* bol_le = _gvn.transform( new (C, 2) BoolNode(cmp_le, le_or_eq) );
+   Node* is_notp = generate_guard(bol_le, NULL, PROB_MIN);
++  if (is_notp != NULL && pos_index != NULL) {
++    // Emulate effect of Parse::adjust_map_after_if.
++    Node* ccast = new (C, 2) CastIINode(index, TypeInt::POS1);
++    ccast->set_req(0, control());
++    (*pos_index) = _gvn.transform(ccast);
++  }
+   return is_notp;
+ }
+ 
+@@ -711,10 +748,12 @@
+                                                   RegionNode* region) {
+   if (stopped())
+     return NULL;                // already stopped
+-  if (_gvn.type(offset) == TypeInt::ZERO &&
+-      _gvn.eqv_uncast(subseq_length, array_length))
++  bool zero_offset = _gvn.type(offset) == TypeInt::ZERO;
++  if (zero_offset && _gvn.eqv_uncast(subseq_length, array_length))
+     return NULL;                // common case of whole-array copy
+-  Node* last = _gvn.transform( new (C, 3) AddINode(offset, subseq_length));
++  Node* last = subseq_length;
++  if (!zero_offset)             // last += offset
++    last = _gvn.transform( new (C, 3) AddINode(last, offset));
+   Node* cmp_lt = _gvn.transform( new (C, 3) CmpUNode(array_length, last) );
+   Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) );
+   Node* is_over = generate_guard(bol_lt, region, PROB_MIN);
+@@ -862,7 +901,7 @@
+   const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin));
+   const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot);
+ 
+-  IdealKit kit(gvn(), control());
++  IdealKit kit(gvn(), control(), merged_memory());
+ #define __ kit.
+   Node* zero             = __ ConI(0);
+   Node* one              = __ ConI(1);
+@@ -1582,6 +1621,8 @@
+ 
+   // Use a flow-free graph structure, to avoid creating excess control edges
+   // which could hinder other optimizations.
++  // Since Math.min/max is often used with arraycopy, we want
++  // tightly_coupled_allocation to be able to see beyond min/max expressions.
+   Node* cmov = CMoveNode::make(C, NULL, best_bol,
+                                answer_if_false, answer_if_true,
+                                TypeInt::make(lo, hi, widen));
+@@ -1732,6 +1773,7 @@
+   Node* val;
+   debug_only(val = (Node*)(uintptr_t)-1);
+ 
++
+   if (is_store) {
+     // Get the value being stored.  (Pop it first; it was pushed last.) 
+     switch (type) {
+@@ -1901,40 +1943,28 @@
+       val = _gvn.transform( new (C, 2) CastX2PNode(val) );
+       break;
+     }
+-    Node* store = store_to_memory(control(), adr, val, type, adr_type, is_volatile);
+ 
+-    if (type == T_OBJECT
+-        && !_gvn.type(heap_base_oop)->higher_equal(TypePtr::NULL_PTR)) {
+-      if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) {
+-        store_barrier(store, T_CONFLICT, heap_base_oop, adr, val);
++    if (type != T_OBJECT ) {
++      (void) store_to_memory(control(), adr, val, type, adr_type, is_volatile);
+       } else {
+-        // Base pointer may or may not be null, so put out a conditional
+-        // store barrier.  (Yech.)
+-        Node* oldctl = control();
+-        Node* cmp = _gvn.transform( new (C, 3) CmpPNode(heap_base_oop, null()) );
+-        Node* bol = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) );
+-        IfNode* iff = create_and_map_if(oldctl, bol, PROB_MAX, COUNT_UNKNOWN);
+-        enum {
+-          heap_store_path = 1,
+-          null_base_path,
+-          num_paths
+-        };
+-        RegionNode* rgn = new (C, num_paths) RegionNode(num_paths);
+-        // fall-through path (base is null, offset is memory address)
+-        rgn->init_req(null_base_path, _gvn.transform( new (C, 1) IfFalseNode(iff) ));
+-        Node* newrawmem = PhiNode::make(rgn, memory(Compile::AliasIdxRaw));
+-        set_control(_gvn.transform( new (C, 1) IfTrueNode(iff) ));
+-        store_barrier(store, T_CONFLICT, heap_base_oop, adr, val);
+-        if (memory(Compile::AliasIdxRaw) == newrawmem->in(null_base_path)) {
+-          // The store barrier did nothing, after all.
+-          set_control(oldctl);
++      // Possibly an oop being stored to Java heap or native memory
++      if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) {
++        // oop to Java heap.
++        (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, val->bottom_type(), type);
+         } else {
+-          // Finish heap_store_path:
+-          rgn->init_req(heap_store_path, control());
+-          set_control(_gvn.transform(rgn));
+-          newrawmem->init_req(heap_store_path, memory(Compile::AliasIdxRaw));
+-          set_memory(_gvn.transform(newrawmem), Compile::AliasIdxRaw);
+-        }
++
++        // We can't tell at compile time if we are storing in the Java heap or outside
++        // of it. So we need to emit code to conditionally do the proper type of
++        // store.
++
++        IdealKit kit(gvn(), control(),  merged_memory());
++        kit.declares_done();
++        // QQQ who knows what probability is here??
++        kit.if_then(heap_base_oop, BoolTest::ne, null(), PROB_UNLIKELY(0.999)); {
++          (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, val->bottom_type(), type);
++        } kit.else_(); {
++          (void) store_to_memory(control(), adr, val, type, adr_type, is_volatile);
++        } kit.end_if();
+       }
+     }
+   }
+@@ -2004,11 +2034,12 @@
+     adr = make_unsafe_address(NULL, ptr);
+   }
+ 
++  if (is_static) {
+   assert(saved_sp == _sp, "must have correct argument count");
+-
+-  if (!is_static) {
++  } else {
+     // Pop receiver last:  it was pushed first.
+     Node *receiver = pop();
++    assert(saved_sp == _sp, "must have correct argument count");
+ 
+     // Null check on self without removing any arguments.  The argument
+     // null check technically happens in the wrong place, which can lead to
+@@ -2133,10 +2164,11 @@
+     cas = _gvn.transform(new (C, 5) CompareAndSwapLNode(control(), mem, adr, newval, oldval));
+     break;
+   case T_OBJECT:
+-    cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
+     // reference stores need a store barrier.
+     // (They don't if CAS fails, but it isn't worth checking.)
+-    store_barrier(cas, T_CONFLICT, base, adr, newval);
++    pre_barrier(control(), base, adr, alias_idx, newval, value_type, T_OBJECT);
++    cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
++    post_barrier(control(), cas, base, adr, alias_idx, newval, T_OBJECT, true);
+     break;
+   default:
+     ShouldNotReachHere();
+@@ -2217,11 +2249,13 @@
+   insert_mem_bar(Op_MemBarCPUOrder);
+   // Ensure that the store is atomic for longs:
+   bool require_atomic_access = true;
+-  Node* store = store_to_memory(control(), adr, val, type, adr_type, require_atomic_access);
++  Node* store;
+   if (type == T_OBJECT) // reference stores need a store barrier.
+-    store_barrier(store, T_CONFLICT, base, adr, val);
++    store = store_oop_to_unknown(control(), base, adr, adr_type, val, value_type, type);
++  else {
++    store = store_to_memory(control(), adr, val, type, adr_type, require_atomic_access);
++  }
+   insert_mem_bar(Op_MemBarCPUOrder);
+-
+   return true;
+ }
+ 
+@@ -2931,8 +2965,8 @@
+   }
+ 
+   // Bail out if either start or end is negative.
+-  generate_negative_guard(start, bailout);
+-  generate_negative_guard(end,   bailout);
++  generate_negative_guard(start, bailout, &start);
++  generate_negative_guard(end,   bailout, &end);
+  
+   Node* length = end;
+   if (_gvn.type(start) != TypeInt::ZERO) {
+@@ -2940,7 +2974,8 @@
+   }
+ 
+   // Bail out if length is negative.
+-  generate_negative_guard(length, bailout);
++  // ...Not needed, since the new_array will throw the right exception.
++  //generate_negative_guard(length, bailout, &length);
+  
+   if (bailout->req() > 1) {
+     PreserveJVMState pjvms(this);
+@@ -3666,8 +3701,15 @@
+     assert(obj_size != NULL, "");
+     Node* raw_obj = alloc_obj->in(1);
+     assert(raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), "");
++    if (ReduceBulkZeroing) {
++      AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn);
++      if (alloc != NULL) {
++        // We will be completely responsible for initializing this object.
++        alloc->maybe_set_complete(&_gvn);
++      }
++    }
+ 
+-    if (true) { // TO DO: check ReduceInitialCardMarks
++    if (!use_ReduceInitialCardMarks()) {
+       // If it is an oop array, it requires very special treatment,
+       // because card marking is required on each card of the array.
+       Node* is_obja = generate_objArray_guard(obj_klass, (RegionNode*)NULL);
+@@ -3687,6 +3729,11 @@
+         result_mem ->set_req(_objArray_path, reset_memory());
+       }
+     }
++    // We can dispense with card marks if we know the allocation
++    // comes out of eden (TLAB)...  In fact, ReduceInitialCardMarks
++    // causes the non-eden paths to simulate a fresh allocation,
++    // insofar that no further card marks are required to initialize
++    // the object.
+ 
+     // Otherwise, there are no card marks to worry about.
+     alloc_val->init_req(_typeArray_alloc, raw_obj);
+@@ -3731,7 +3778,12 @@
+     assert(obj_size != NULL, "");
+     Node* raw_obj = alloc_obj->in(1);
+     assert(raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), "");
+-    if (true) { // TO DO: check ReduceInitialCardMarks
++    if (ReduceBulkZeroing) {
++      AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn);
++      if (alloc != NULL && !alloc->maybe_set_complete(&_gvn))
++        alloc = NULL;
++    }
++    if (!use_ReduceInitialCardMarks()) {
+       // Put in store barrier for any and all oops we are sticking
+       // into this object.  (We could avoid this if we could prove
+       // that the object type contains no oop fields at all.)
+@@ -3786,10 +3838,14 @@
+     // The CopyArray instruction (if supported) can be optimized
+     // into a discrete set of scalar loads and stores.
+     bool disjoint_bases = true;
+-    generate_unchecked_arraycopy(T_LONG, raw_adr_type, disjoint_bases,
++    generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases,
+                                  src, NULL, dest, NULL, countx);
+     
+     // Now that the object is properly initialized, type it as an oop.
++    // Use a secondary InitializeNode memory barrier.
++    InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, raw_adr_idx,
++                                                   raw_obj)->as_Initialize();
++    init->set_complete(&_gvn);  // (there is no corresponding AllocateNode)
+     Node* new_obj = new(C, 2) CheckCastPPNode(control(), raw_obj,
+                                               TypeInstPtr::NOTNULL);
+     new_obj = _gvn.transform(new_obj);
+@@ -3798,8 +3854,14 @@
+     if (card_mark) {
+       Node* no_particular_value = NULL;
+       Node* no_particular_field = NULL;
+-      store_barrier(memory(raw_adr_type), T_OBJECT, new_obj,
+-                    no_particular_field, no_particular_value);
++      post_barrier(control(),
++                   memory(raw_adr_type),
++                   new_obj,
++                   no_particular_field,
++                   raw_adr_idx,
++                   no_particular_value,
++                   T_OBJECT,
++                   false);
+     }
+     // Present the results of the slow call.
+     result_reg->init_req(_fast_path, control());
+@@ -4085,13 +4147,59 @@
+                                    int nargs,
+ 				   bool disjoint_bases,
+ 				   bool length_never_negative,
+-                                   Node* slow_control) {
++                                   RegionNode* slow_region) {
++
++  if (slow_region == NULL) {
++    slow_region = new(C,1) RegionNode(1);
++    record_for_igvn(slow_region);
++  }
++
++  Node* original_dest      = dest;
++  AllocateArrayNode* alloc = NULL;  // used for zeroing, if needed
++  Node* raw_dest           = NULL;  // used before zeroing, if needed
++  bool  must_clear_dest    = false;
++
++  // See if this is the initialization of a newly-allocated array.
++  // If so, we will take responsibility here for initializing it to zero.
++  // (Note:  Because tightly_coupled_allocation performs checks on the
++  // out-edges of the dest, we need to avoid making derived pointers
++  // from it until we have checked its uses.)
++  if (ReduceBulkZeroing
++      && !ZeroTLAB              // pointless if already zeroed
++      && basic_elem_type != T_CONFLICT // avoid corner case
++      && !_gvn.eqv_uncast(src, dest)
++      && ((alloc = tightly_coupled_allocation(dest, slow_region))
++          != NULL)
++      && alloc->maybe_set_complete(&_gvn)) {
++    // "You break it, you buy it."
++    InitializeNode* init = alloc->initialization();
++    assert(init->is_complete(), "we just did this");
++    assert(dest->Opcode() == Op_CheckCastPP, "sanity");
++    assert(dest->in(0)->in(0) == init, "dest pinned");
++    raw_dest = dest->in(1);  // grab the raw pointer!
++    original_dest = dest;
++    dest = raw_dest;
++    adr_type = TypeRawPtr::BOTTOM;  // all initializations are into raw memory
++    // Decouple the original InitializeNode, turning it into a simple membar.
++    // We will build a new one at the end of this routine.
++    init->set_req(InitializeNode::RawAddress, top());
++    // From this point on, every exit path is responsible for
++    // initializing any non-copied parts of the object to zero.
++    must_clear_dest = true;
++  } else {
++    // No zeroing elimination here.
++    alloc             = NULL;
++    //original_dest   = dest;
++    //must_clear_dest = false;
++  }
++
+   // Results are placed here:
+-  enum { fast_path        = 1,
+-         checked_path     = 2,
+-         slow_call_path   = 3,
+-         zero_path        = 4,
+-         PATH_LIMIT       = 5
++  enum { fast_path        = 1,  // normal void-returning assembly stub
++         checked_path     = 2,  // special assembly stub with cleanup
++         slow_call_path   = 3,  // something went wrong; call the VM
++         zero_path        = 4,  // bypass when length of copy is zero
++         bcopy_path       = 5,  // copy primitive array by 64-bit blocks
++         PATH_LIMIT       = 6
+   };
+   RegionNode* result_region = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
+   PhiNode*    result_i_o    = new(C, PATH_LIMIT) PhiNode(result_region, Type::ABIO);
+@@ -4099,10 +4207,13 @@
+   record_for_igvn(result_region);
+   _gvn.set_type_bottom(result_i_o);
+   _gvn.set_type_bottom(result_memory);
++  assert(adr_type != TypePtr::BOTTOM, "must be RawMem or a T[] slice");
+ 
+-  // Other parts of the slow_control edge:
++  // The slow_control path:
++  Node* slow_control;
+   Node* slow_i_o = i_o();
+   Node* slow_mem = memory(adr_type);
++  debug_only(slow_control = (Node*) badAddress);
+ 
+   // Checked control path:
+   Node* checked_control = top();
+@@ -4111,43 +4222,123 @@
+   Node* checked_value   = NULL;
+ 
+   if (basic_elem_type == T_CONFLICT) {
+-    { PreserveJVMState pjvms(this);
++    assert(!must_clear_dest, "");
+       Node* cv = generate_generic_arraycopy(adr_type,
+                                             src, src_offset, dest, dest_offset,
+                                             copy_length, nargs);
+       if (cv == NULL)  cv = intcon(-1);  // failure (no stub available)
+       checked_control = control();
+       checked_i_o     = i_o();
+-      checked_mem     = reset_memory();
++    checked_mem     = memory(adr_type);
+       checked_value   = cv;
+-    }
+     set_control(top());         // no fast path
+   }
+ 
+   Node* not_pos = generate_nonpositive_guard(copy_length, length_never_negative);
+   if (not_pos != NULL) {
+-    Node* fast_ctrl = control();
+-
++    PreserveJVMState pjvms(this);
+     set_control(not_pos);
++
+     // (6) length must not be negative.
+     if (!length_never_negative) {
+-      if (slow_control == NULL) {
+-        slow_control = new(C,1) RegionNode(1);
+-        record_for_igvn(slow_control);
++      generate_negative_guard(copy_length, slow_region);
++    }
++
++    if (!stopped() && must_clear_dest) {
++      Node* dest_length = alloc->in(AllocateNode::ALength);
++      if (_gvn.eqv_uncast(copy_length, dest_length)
++          || _gvn.find_int_con(dest_length, 1) <= 0) {
++        // There is no zeroing to do.
++      } else {
++        // Clear the whole thing since there are no source elements to copy.
++        generate_clear_array(adr_type, dest, basic_elem_type,
++                             intcon(0), NULL,
++                             alloc->in(AllocateNode::AllocSize));
+       }
+-      generate_negative_guard(copy_length, slow_control->as_Region());
+     }
+ 
+     // Present the results of the fast call.
+     result_region->init_req(zero_path, control());
+     result_i_o   ->init_req(zero_path, i_o());
+     result_memory->init_req(zero_path, memory(adr_type));
++  }
+ 
+-    set_control(fast_ctrl);
++  if (!stopped() && must_clear_dest) {
++    // We have to initialize the *uncopied* part of the array to zero.
++    // The copy destination is the slice dest[off..off+len].  The other slices
++    // are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length].
++    Node* dest_size   = alloc->in(AllocateNode::AllocSize);
++    Node* dest_length = alloc->in(AllocateNode::ALength);
++    Node* dest_tail   = _gvn.transform( new(C,3) AddINode(dest_offset,
++                                                          copy_length) );
++
++    // If there is a head section that needs zeroing, do it now.
++    if (find_int_con(dest_offset, -1) != 0) {
++      generate_clear_array(adr_type, dest, basic_elem_type,
++                           intcon(0), dest_offset,
++                           NULL);
++    }
++
++    // Next, perform a dynamic check on the tail length.
++    // It is often zero, and we can win big if we prove this.
++    // There are two wins:  Avoid generating the ClearArray
++    // with its attendant messy index arithmetic, and upgrade
++    // the copy to a more hardware-friendly word size of 64 bits.
++    Node* tail_ctl = NULL;
++    if (!stopped() && !_gvn.eqv_uncast(dest_tail, dest_length)) {
++      Node* cmp_lt   = _gvn.transform( new(C,3) CmpINode(dest_tail, dest_length) );
++      Node* bol_lt   = _gvn.transform( new(C,2) BoolNode(cmp_lt, BoolTest::lt) );
++      tail_ctl = generate_slow_guard(bol_lt, NULL);
++      assert(tail_ctl != NULL || !stopped(), "must be an outcome");
++    }
++
++    // At this point, let's assume there is no tail.
++    if (!stopped() && alloc != NULL && basic_elem_type != T_OBJECT) {
++      // There is no tail.  Try an upgrade to a 64-bit copy.
++      bool didit = false;
++      { PreserveJVMState pjvms(this);
++        didit = generate_block_arraycopy(adr_type, basic_elem_type, alloc,
++                                         src, src_offset, dest, dest_offset,
++                                         dest_size);
++        if (didit) {
++          // Present the results of the block-copying fast call.
++          result_region->init_req(bcopy_path, control());
++          result_i_o   ->init_req(bcopy_path, i_o());
++          result_memory->init_req(bcopy_path, memory(adr_type));
++        }
++      }
++      if (didit)
++        set_control(top());     // no regular fast path
++    }
++
++    // Clear the tail, if any.
++    if (tail_ctl != NULL) {
++      Node* notail_ctl = stopped() ? NULL : control();
++      set_control(tail_ctl);
++      if (notail_ctl == NULL) {
++        generate_clear_array(adr_type, dest, basic_elem_type,
++                             dest_tail, NULL,
++                             dest_size);
++      } else {
++        // Make a local merge.
++        Node* done_ctl = new(C,3) RegionNode(3);
++        Node* done_mem = new(C,3) PhiNode(done_ctl, Type::MEMORY, adr_type);
++        done_ctl->init_req(1, notail_ctl);
++        done_mem->init_req(1, memory(adr_type));
++        generate_clear_array(adr_type, dest, basic_elem_type,
++                             dest_tail, NULL,
++                             dest_size);
++        done_ctl->init_req(2, control());
++        done_mem->init_req(2, memory(adr_type));
++        set_control( _gvn.transform(done_ctl) );
++        set_memory(  _gvn.transform(done_mem), adr_type );
++      }
++    }
+   }
+ 
++  BasicType copy_type = basic_elem_type;
+   assert(basic_elem_type != T_ARRAY, "caller must fix this");
+-  if (basic_elem_type == T_OBJECT) {
++  if (!stopped() && copy_type == T_OBJECT) {
+     // If src and dest have compatible element types, we can copy bits.
+     // Types S[] and D[] are compatible if D is a supertype of S.
+     //
+@@ -4189,17 +4380,24 @@
+       if (cv == NULL)  cv = intcon(-1);  // failure (no stub available)
+       checked_control = control();
+       checked_i_o     = i_o();
+-      checked_mem     = reset_memory();
++      checked_mem     = memory(adr_type);
+       checked_value   = cv;
+     }
+     // At this point we know we do not need type checks on oop stores.
++
++    // Let's see if we need card marks:
++    if (alloc != NULL && use_ReduceInitialCardMarks()) {
++      // If we do not need card marks, copy using the jint or jlong stub.
++      copy_type = LP64_ONLY(T_LONG) NOT_LP64(T_INT);
++      assert(type2aelembytes[basic_elem_type] == type2aelembytes[copy_type],
++             "sizes agree");
++    }
+   }
+ 
+   if (!stopped()) {
+     // Generate the fast path, if possible.
+     PreserveJVMState pjvms(this);
+-
+-    generate_unchecked_arraycopy(basic_elem_type, adr_type, disjoint_bases,
++    generate_unchecked_arraycopy(adr_type, copy_type, disjoint_bases,
+                                  src, src_offset, dest, dest_offset,
+                                  ConvI2X(copy_length));
+ 
+@@ -4210,8 +4408,10 @@
+   }
+ 
+   // Here are all the slow paths up to this point, in one bundle:
+-  if (slow_control == NULL)  slow_control = top();
+-  slow_control = _gvn.transform(slow_control);
++  slow_control = top();
++  if (slow_region != NULL)
++    slow_control = _gvn.transform(slow_region);
++  debug_only(slow_region = (RegionNode*)badAddress);
+ 
+   set_control(checked_control);
+   if (!stopped()) {
+@@ -4241,16 +4441,21 @@
+     slow_i_o2  ->init_req(2, i_o());
+     slow_mem2  ->init_req(2, memory(adr_type));
+ 
++    slow_control = _gvn.transform(slow_reg2);
++    slow_i_o     = _gvn.transform(slow_i_o2);
++    slow_mem     = _gvn.transform(slow_mem2);
++
++    if (alloc != NULL) {
++      // We'll restart from the very beginning, after zeroing the whole thing.
++      // This can cause double writes, but that's OK since dest is brand new.
++      // So we ignore the low 31 bits of the value returned from the stub.
++    } else {
+     // We must continue the copy exactly where it failed, or else
+     // another thread might see the wrong number of writes to dest.
+     Node* checked_offset = _gvn.transform( new(C, 3) XorINode(checked_value, intcon(-1)) );
+     Node* slow_offset    = new(C, 3) PhiNode(slow_reg2, TypeInt::INT);
+     slow_offset->init_req(1, intcon(0));
+     slow_offset->init_req(2, checked_offset);
+-
+-    slow_control = _gvn.transform(slow_reg2);
+-    slow_i_o     = _gvn.transform(slow_i_o2);
+-    slow_mem     = _gvn.transform(slow_mem2);
+     slow_offset  = _gvn.transform(slow_offset);
+ 
+     // Adjust the arguments by the conditionally incoming offset.
+@@ -4263,11 +4468,33 @@
+     dest_offset = dest_off_plus;
+     copy_length = length_minus;
+   }
++  }
+ 
+   set_control(slow_control);
+   if (!stopped()) {
+     // Generate the slow path, if needed.
+-    PreserveJVMState pjvms(this);   // (better safe than sorry)
++    PreserveJVMState pjvms(this);   // replace_in_map may trash the map
++
++    set_memory(slow_mem, adr_type);
++    set_i_o(slow_i_o);
++
++    if (must_clear_dest) {
++      generate_clear_array(adr_type, dest, basic_elem_type,
++                           intcon(0), NULL,
++                           alloc->in(AllocateNode::AllocSize));
++    }
++
++    if (dest != original_dest) {
++      // Promote from rawptr to oop, so it looks right in the call's GC map.
++      dest = _gvn.transform( new(C,2) CheckCastPPNode(control(), dest,
++                                                      TypeInstPtr::NOTNULL) );
++
++      // Edit the call's debug-info to avoid referring to original_dest.
++      // (The problem with original_dest is that it isn't ready until
++      // after the InitializeNode completes, but this stuff is before.)
++      // Substitute in the locally valid dest_oop.
++      replace_in_map(original_dest, dest);
++    }
+ 
+     generate_slow_arraycopy(adr_type,
+                             src, src_offset, dest, dest_offset,
+@@ -4289,6 +4516,18 @@
+   set_i_o(     _gvn.transform(result_i_o)    );
+   set_memory(  _gvn.transform(result_memory), adr_type );
+ 
++  if (dest != original_dest) {
++    // Pin the "finished" array node after the arraycopy/zeroing operations.
++    // Use a secondary InitializeNode memory barrier.
++    InitializeNode* init = insert_mem_bar_volatile(Op_Initialize,
++                                                   Compile::AliasIdxRaw,
++                                                   raw_dest)->as_Initialize();
++    init->set_complete(&_gvn);  // (there is no corresponding AllocateNode)
++    _gvn.hash_delete(original_dest);
++    original_dest->set_req(0, control());
++    _gvn.hash_find_insert(original_dest);  // put back into GVN table
++  }
++
+   // The memory edges above are precise in order to model effects around 
+   // array copyies accurately to allow value numbering of field loads around
+   // arraycopy.  Such field loads, both before and after, are common in Java 
+@@ -4304,6 +4543,265 @@
+ }
+ 
+ 
++// Helper function which determines if an arraycopy immediately follows
++// an allocation, with no intervening tests or other escapes for the object.
++AllocateArrayNode*
++LibraryCallKit::tightly_coupled_allocation(Node* ptr,
++                                           RegionNode* slow_region) {
++  if (stopped())             return NULL;  // no fast path
++  if (C->AliasLevel() == 0)  return NULL;  // no MergeMems around
++
++  AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(ptr, &_gvn);
++  if (alloc == NULL)  return NULL;
++
++  Node* rawmem = memory(Compile::AliasIdxRaw);
++  // Is the allocation's memory state untouched?
++  if (!(rawmem->is_Proj() && rawmem->in(0)->is_Initialize())) {
++    // Bail out if there have been raw-memory effects since the allocation.
++    // (Example:  There might have been a call or safepoint.)
++    return NULL;
++  }
++  rawmem = rawmem->in(0)->as_Initialize()->memory(Compile::AliasIdxRaw);
++  if (!(rawmem->is_Proj() && rawmem->in(0) == alloc)) {
++    return NULL;
++  }
++
++  // There must be no unexpected observers of this allocation.
++  for (DUIterator_Fast imax, i = ptr->fast_outs(imax); i < imax; i++) {
++    Node* obs = ptr->fast_out(i);
++    if (obs != this->map()) {
++      return NULL;
++    }
++  }
++
++  // This arraycopy must unconditionally follow the allocation of the ptr.
++  Node* alloc_ctl = ptr->in(0);
++  assert(just_allocated_object(alloc_ctl) == ptr, "most recent allo");
++
++  Node* ctl = control();
++  while (ctl != alloc_ctl) {
++    // There may be guards which feed into the slow_region.
++    // Any other control flow means that we might not get a chance
++    // to finish initializing the allocated object.
++    if ((ctl->is_IfFalse() || ctl->is_IfTrue()) && ctl->in(0)->is_If()) {
++      IfNode* iff = ctl->in(0)->as_If();
++      Node* not_ctl = iff->proj_out(1 - ctl->as_Proj()->_con);
++      assert(not_ctl != NULL && not_ctl != ctl, "found alternate");
++      if (slow_region != NULL && slow_region->find_edge(not_ctl) >= 1) {
++        ctl = iff->in(0);       // This test feeds the known slow_region.
++        continue;
++      }
++      // One more try:  Various low-level checks bottom out in
++      // uncommon traps.  If the debug-info of the trap omits
++      // any reference to the allocation, as we've already
++      // observed, then there can be no objection to the trap.
++      bool found_trap = false;
++      for (DUIterator_Fast jmax, j = not_ctl->fast_outs(jmax); j < jmax; j++) {
++        Node* obs = not_ctl->fast_out(j);
++        if (obs->in(0) == not_ctl && obs->is_Call() &&
++            (obs->as_Call()->entry_point() ==
++             SharedRuntime::uncommon_trap_blob()->instructions_begin())) {
++          found_trap = true; break;
++        }
++      }
++      if (found_trap) {
++        ctl = iff->in(0);       // This test feeds a harmless uncommon trap.
++        continue;
++      }
++    }
++    return NULL;
++  }
++
++  // If we get this far, we have an allocation which immediately
++  // precedes the arraycopy, and we can take over zeroing the new object.
++  // The arraycopy will finish the initialization, and provide
++  // a new control state to which we will anchor the destination pointer.
++
++  return alloc;
++}
++
++// Helper for initialization of arrays, creating a ClearArray.
++// It writes zero bits in [start..end), within the body of an array object.
++// The memory effects are all chained onto the 'adr_type' alias category.
++//
++// Since the object is otherwise uninitialized, we are free
++// to put a little "slop" around the edges of the cleared area,
++// as long as it does not go back into the array's header,
++// or beyond the array end within the heap.
++//
++// The lower edge can be rounded down to the nearest jint and the
++// upper edge can be rounded up to the nearest MinObjAlignmentInBytes.
++//
++// Arguments:
++//   adr_type           memory slice where writes are generated
++//   dest               oop of the destination array
++//   basic_elem_type    element type of the destination
++//   slice_idx          array index of first element to store
++//   slice_len          number of elements to store (or NULL)
++//   dest_size          total size in bytes of the array object
++//
++// Exactly one of slice_len or dest_size must be non-NULL.
++// If dest_size is non-NULL, zeroing extends to the end of the object.
++// If slice_len is non-NULL, the slice_idx value must be a constant.
++void
++LibraryCallKit::generate_clear_array(const TypePtr* adr_type,
++                                     Node* dest,
++                                     BasicType basic_elem_type,
++                                     Node* slice_idx,
++                                     Node* slice_len,
++                                     Node* dest_size) {
++  // one or the other but not both of slice_len and dest_size:
++  assert((slice_len != NULL? 1: 0) + (dest_size != NULL? 1: 0) == 1, "");
++  if (slice_len == NULL)  slice_len = top();
++  if (dest_size == NULL)  dest_size = top();
++
++  // operate on this memory slice:
++  Node* mem = memory(adr_type); // memory slice to operate on
++
++  // scaling and rounding of indexes:
++  int scale = exact_log2(type2aelembytes[basic_elem_type]);
++  int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
++  int clear_low = (-1 << scale) & (BytesPerInt  - 1);
++  int bump_bit  = (-1 << scale) & BytesPerInt;
++
++  // determine constant starts and ends
++  const intptr_t BIG_NEG = -128;
++  assert(BIG_NEG + 2*abase < 0, "neg enough");
++  intptr_t slice_idx_con = (intptr_t) find_int_con(slice_idx, BIG_NEG);
++  intptr_t slice_len_con = (intptr_t) find_int_con(slice_len, BIG_NEG);
++  if (slice_len_con == 0) {
++    return;                     // nothing to do here
++  }
++  intptr_t start_con = (abase + (slice_idx_con << scale)) & ~clear_low;
++  intptr_t end_con   = find_intptr_t_con(dest_size, -1);
++  if (slice_idx_con >= 0 && slice_len_con >= 0) {
++    assert(end_con < 0, "not two cons");
++    end_con = round_to(abase + ((slice_idx_con + slice_len_con) << scale),
++                       BytesPerLong);
++  }
++
++  if (start_con >= 0 && end_con >= 0) {
++    // Constant start and end.  Simple.
++    mem = ClearArrayNode::clear_memory(control(), mem, dest,
++                                       start_con, end_con, &_gvn);
++  } else if (start_con >= 0 && dest_size != top()) {
++    // Constant start, pre-rounded end after the tail of the array.
++    Node* end = dest_size;
++    mem = ClearArrayNode::clear_memory(control(), mem, dest,
++                                       start_con, end, &_gvn);
++  } else if (start_con >= 0 && slice_len != top()) {
++    // Constant start, non-constant end.  End needs rounding up.
++    // End offset = round_up(abase + ((slice_idx_con + slice_len) << scale), 8)
++    intptr_t end_base  = abase + (slice_idx_con << scale);
++    int      end_round = (-1 << scale) & (BytesPerLong  - 1);
++    Node*    end       = ConvI2X(slice_len);
++    if (scale != 0)
++      end = _gvn.transform( new(C,3) LShiftXNode(end, intcon(scale) ));
++    end_base += end_round;
++    end = _gvn.transform( new(C,3) AddXNode(end, MakeConX(end_base)) );
++    end = _gvn.transform( new(C,3) AndXNode(end, MakeConX(~end_round)) );
++    mem = ClearArrayNode::clear_memory(control(), mem, dest,
++                                       start_con, end, &_gvn);
++  } else if (start_con < 0 && dest_size != top()) {
++    // Non-constant start, pre-rounded end after the tail of the array.
++    // This is almost certainly a "round-to-end" operation.
++    Node* start = slice_idx;
++    start = ConvI2X(start);
++    if (scale != 0)
++      start = _gvn.transform( new(C,3) LShiftXNode( start, intcon(scale) ));
++    start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(abase)) );
++    if ((bump_bit | clear_low) != 0) {
++      int to_clear = (bump_bit | clear_low);
++      // Align up mod 8, then store a jint zero unconditionally
++      // just before the mod-8 boundary.
++      // This would only fail if the first array element were immediately
++      // after the length field, and were also at an even offset mod 8.
++      assert(((abase + bump_bit) & ~to_clear) - BytesPerInt
++             >= arrayOopDesc::length_offset_in_bytes() + BytesPerInt,
++             "store must not trash length field");
++
++      // Bump 'start' up to (or past) the next jint boundary:
++      start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(bump_bit)) );
++      // Round bumped 'start' down to jlong boundary in body of array.
++      start = _gvn.transform( new(C,3) AndXNode(start, MakeConX(~to_clear)) );
++      // Store a zero to the immediately preceding jint:
++      Node* x1 = _gvn.transform( new(C,3) AddXNode(start, MakeConX(-BytesPerInt)) );
++      Node* p1 = basic_plus_adr(dest, x1);
++      mem = StoreNode::make(C, control(), mem, p1, adr_type, intcon(0), T_INT);
++      mem = _gvn.transform(mem);
++    }
++
++    Node* end = dest_size; // pre-rounded
++    mem = ClearArrayNode::clear_memory(control(), mem, dest,
++                                       start, end, &_gvn);
++  } else {
++    // Non-constant start, unrounded non-constant end.
++    // (Nobody zeroes a random midsection of an array using this routine.)
++    ShouldNotReachHere();       // fix caller
++  }
++
++  // Done.
++  set_memory(mem, adr_type);
++}
++
++
++bool
++LibraryCallKit::generate_block_arraycopy(const TypePtr* adr_type,
++                                         BasicType basic_elem_type,
++                                         AllocateNode* alloc,
++                                         Node* src,  Node* src_offset,
++                                         Node* dest, Node* dest_offset,
++                                         Node* dest_size) {
++  // See if there is an advantage from block transfer.
++  int scale = exact_log2(type2aelembytes[basic_elem_type]);
++  if (scale >= LogBytesPerLong)
++    return false;               // it is already a block transfer
++
++  // Look at the alignment of the starting offsets.
++  int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
++  const intptr_t BIG_NEG = -128;
++  assert(BIG_NEG + 2*abase < 0, "neg enough");
++
++  intptr_t src_off  = abase + ((intptr_t) find_int_con(src_offset, -1)  << scale);
++  intptr_t dest_off = abase + ((intptr_t) find_int_con(dest_offset, -1) << scale);
++  if (src_off < 0 || dest_off < 0)
++    // At present, we can only understand constants.
++    return false;
++
++  if (((src_off | dest_off) & (BytesPerLong-1)) != 0) {
++    // Non-aligned; too bad.
++    // One more chance:  Pick off an initial 32-bit word.
++    // This is a common case, since abase can be odd mod 8.
++    if (((src_off | dest_off) & (BytesPerLong-1)) == BytesPerInt &&
++        ((src_off ^ dest_off) & (BytesPerLong-1)) == 0) {
++      Node* sptr = basic_plus_adr(src,  src_off);
++      Node* dptr = basic_plus_adr(dest, dest_off);
++      Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, adr_type);
++      store_to_memory(control(), dptr, sval, T_INT, adr_type);
++      src_off += BytesPerInt;
++      dest_off += BytesPerInt;
++    } else {
++      return false;
++    }
++  }
++  assert(src_off % BytesPerLong == 0, "");
++  assert(dest_off % BytesPerLong == 0, "");
++
++  // Do this copy by giant steps.
++  Node* sptr  = basic_plus_adr(src,  src_off);
++  Node* dptr  = basic_plus_adr(dest, dest_off);
++  Node* countx = dest_size;
++  countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(dest_off)) );
++  countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong)) );
++
++  bool disjoint_bases = true;   // since alloc != NULL
++  generate_unchecked_arraycopy(adr_type, T_LONG, disjoint_bases,
++                               sptr, NULL, dptr, NULL, countx);
++
++  return true;
++}
++
++
+ // Helper function; generates code for the slow case.
+ // We make a call to a runtime method which emulates the native method,
+ // but without the native wrapper overhead.
+@@ -4391,11 +4889,10 @@
+   return _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Parms));
+ }
+ 
+-
+ // Helper function; generates the fast out-of-line call to an arraycopy stub.
+ void
+-LibraryCallKit::generate_unchecked_arraycopy(BasicType basic_elem_type,
+-                                             const TypePtr* adr_type,
++LibraryCallKit::generate_unchecked_arraycopy(const TypePtr* adr_type,
++                                             BasicType basic_elem_type,
+                                              bool disjoint_bases,
+                                              Node* src,  Node* src_offset,
+                                              Node* dest, Node* dest_offset,
+@@ -4422,4 +4919,3 @@
+                     copyfunc_addr, copyfunc_name, adr_type,
+                     src_start, dest_start, copy_length XTOP);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/live.cpp openjdk/hotspot/src/share/vm/opto/live.cpp
+--- openjdk6/hotspot/src/share/vm/opto/live.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/live.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)live.cpp	1.70 07/05/17 17:44:00 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/live.hpp openjdk/hotspot/src/share/vm/opto/live.hpp
+--- openjdk6/hotspot/src/share/vm/opto/live.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/live.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)live.hpp	1.43 07/05/05 17:06:19 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/locknode.cpp openjdk/hotspot/src/share/vm/opto/locknode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/locknode.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/locknode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)locknode.cpp	1.49 07/05/17 15:59:05 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -123,6 +120,3 @@
+   // for a null check on Unlock.
+   shared_unlock(map()->peek_monitor_box(), map()->peek_monitor_obj());
+ } 
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/locknode.hpp openjdk/hotspot/src/share/vm/opto/locknode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/locknode.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/locknode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)locknode.hpp	1.39 07/05/17 15:59:09 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -46,8 +43,8 @@
+   static OptoReg::Name stack_slot(Node* box_node);
+ 
+ #ifndef PRODUCT
+-  virtual void format( PhaseRegAlloc * ) const;
+-  virtual void dump_spec() const { tty->print("  Lock %d",_slot); }
++  virtual void format( PhaseRegAlloc *, outputStream *st ) const;
++  virtual void dump_spec(outputStream *st) const { st->print("  Lock %d",_slot); }
+ #endif
+ };
+ 
+@@ -98,4 +95,3 @@
+   const Type *sub(const Type *t1, const Type *t2) const { return TypeInt::CC;}
+ 
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/loopnode.cpp openjdk/hotspot/src/share/vm/opto/loopnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/loopnode.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/loopnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)loopnode.cpp	1.258 07/05/17 17:44:08 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,13 +26,27 @@
+ #include "incls/_loopnode.cpp.incl"
+ 
+ //=============================================================================
++//------------------------------is_loop_iv-------------------------------------
++// Determine if a node is Counted loop induction variable.
++// The method is declared in node.hpp.
++const Node* Node::is_loop_iv() const {
++  if (this->is_Phi() && !this->as_Phi()->is_copy() &&
++      this->as_Phi()->region()->is_CountedLoop() &&
++      this->as_Phi()->region()->as_CountedLoop()->phi() == this) {
++    return this;
++  } else {
++    return NULL;
++  }
++}
++
++//=============================================================================
+ //------------------------------dump_spec--------------------------------------
+ // Dump special per-node info
+ #ifndef PRODUCT
+-void LoopNode::dump_spec() const {
+-  if( is_inner_loop () ) tty->print( "inner " );
+-  if( is_partial_peel_loop () ) tty->print( "partial_peel " );
+-  if( partial_peel_has_failed () ) tty->print( "partial_peel_failed " );
++void LoopNode::dump_spec(outputStream *st) const {
++  if( is_inner_loop () ) st->print( "inner " );
++  if( is_partial_peel_loop () ) st->print( "partial_peel " );
++  if( partial_peel_has_failed () ) st->print( "partial_peel_failed " );
+ }
+ #endif
+ 
+@@ -267,9 +278,11 @@
+   // '>' for count-down loops.  If the condition is inverted and we will
+   // be rolling through MININT to MAXINT, then bail out.
+ 
++  C->print_method("Before CountedLoop", 3);
++
+   // Check for SafePoint on backedge and remove
+   Node *sfpt = x->in(LoopNode::LoopBackControl);
+-  if( sfpt->Opcode() == Op_SafePoint ) {
++  if( sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
+     lazy_replace( sfpt, iftrue );
+     loop->_tail = iftrue;
+   }
+@@ -460,11 +473,14 @@
+ 
+   // Check for immediately preceeding SafePoint and remove
+   Node *sfpt2 = le->in(0);
+-  if( sfpt2->Opcode() == Op_SafePoint )
++  if( sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2))
+     lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
+ 
+   // Free up intermediate goo
+   _igvn.remove_dead_node(hook);
++
++  C->print_method("After CountedLoop", 3);
++
+   // Return trip counter
+   return trip_count;
+ }
+@@ -492,16 +508,16 @@
+ //------------------------------dump_spec--------------------------------------
+ // Dump special per-node info
+ #ifndef PRODUCT
+-void CountedLoopNode::dump_spec() const {
+-  LoopNode::dump_spec();
++void CountedLoopNode::dump_spec(outputStream *st) const {
++  LoopNode::dump_spec(st);
+   if( stride_is_con() ) {
+-    tty->print("stride: %d ",stride_con());
++    st->print("stride: %d ",stride_con());
+   } else {
+-    tty->print("stride: not constant ");
++    st->print("stride: not constant ");
+   }
+-  if( is_pre_loop () ) tty->print("pre of N%d" , _main_idx );
+-  if( is_main_loop() ) tty->print("main of N%d", _idx );
+-  if( is_post_loop() ) tty->print("post of N%d", _main_idx );
++  if( is_pre_loop () ) st->print("pre of N%d" , _main_idx );
++  if( is_main_loop() ) st->print("main of N%d", _idx );
++  if( is_post_loop() ) st->print("post of N%d", _main_idx );
+ }
+ #endif
+ 
+@@ -714,16 +730,16 @@
+ //------------------------------dump_spec--------------------------------------
+ // Dump special per-node info
+ #ifndef PRODUCT
+-void CountedLoopEndNode::dump_spec() const {
++void CountedLoopEndNode::dump_spec(outputStream *st) const {
+   if( in(TestValue)->is_Bool() ) {
+     BoolTest bt( test_trip()); // Added this for g++.
+ 
+-    tty->print("[");
+-    bt.dump();
+-    tty->print("]");
++    st->print("[");
++    bt.dump_on(st);
++    st->print("]");
+   }
+-  tty->print(" ");
+-  IfNode::dump_spec();
++  st->print(" ");
++  IfNode::dump_spec(st);
+ }
+ #endif
+ 
+@@ -1044,6 +1060,8 @@
+   // Cache parts in locals for easy
+   PhaseIterGVN &igvn = phase->_igvn;
+ 
++  phase->C->print_method("Before beautify loops", 3);
++
+   igvn.hash_delete(_head);      // Yank from hash before hacking edges
+ 
+   // Check for multiple fall-in paths.  Peel off a landing pad if need be.
+@@ -1107,36 +1125,180 @@
+       phase->_igvn.add_users_to_worklist(l->fast_out(i));
+   }
+ 
++  phase->C->print_method("After beautify loops", 3);
++
+   // Now recursively beautify nested loops
+   if( _child ) result |= _child->beautify_loops( phase );
+   if( _next  ) result |= _next ->beautify_loops( phase );
+   return result;
+ }
+ 
+-//------------------------------check_inner_safepts----------------------------
+-// Given dominators, try to find inner loops with calls that must always be
+-// executed (call dominates loop tail).  These loops do not need a seperate
+-// safepoint.
+-void IdealLoopTree::check_inner_safepts( PhaseIdealLoop *phase ) {
+-
+-  // No safepoints found yet?  Not irreducible?
+-  if( !_has_sfpt && !_irreducible &&
+-      // Inner loop, or at least a short trip count to walk the loop?
+-      (!_child ||
+-       (phase->dom_depth(tail()) - phase->dom_depth(_head)) < 20 ) ) {
+-    // Look for a dominating call
+-    for (Node* n = tail(); n != _head; n = phase->idom(n)) {
+-      if( n->is_Call() &&       // Found a call on idom chain?
+-         n->as_Call()->guaranteed_safepoint() ) {
++//------------------------------allpaths_check_safepts----------------------------
++// Allpaths backwards scan from loop tail, terminating each path at first safepoint
++// encountered.  Helper for check_safepts.
++void IdealLoopTree::allpaths_check_safepts(VectorSet &visited, Node_List &stack) {
++  assert(stack.size() == 0, "empty stack");
++  stack.push(_tail);
++  visited.Clear();
++  visited.set(_tail->_idx);
++  while (stack.size() > 0) {
++    Node* n = stack.pop();
++    if (n->is_Call() && n->as_Call()->guaranteed_safepoint()) {
++      // Terminate this path
++    } else if (n->Opcode() == Op_SafePoint) {
++      if (_phase->get_loop(n) != this) {
++        if (_required_safept == NULL) _required_safept = new Node_List();
++        _required_safept->push(n);  // save the one closest to the tail
++      }
++      // Terminate this path
++    } else {
++      uint start = n->is_Region() ? 1 : 0;
++      uint end   = n->is_Region() && !n->is_Loop() ? n->req() : start + 1;
++      for (uint i = start; i < end; i++) {
++        Node* in = n->in(i);
++        assert(in->is_CFG(), "must be");
++        if (!visited.test_set(in->_idx) && is_member(_phase->get_loop(in))) {
++          stack.push(in);
++        }
++      }
++    }
++  }
++}
++
++//------------------------------check_safepts----------------------------
++// Given dominators, try to find loops with calls that must always be
++// executed (call dominates loop tail).  These loops do not need non-call
++// safepoints (ncsfpt).
++//
++// A complication is that a safepoint in a inner loop may be needed
++// by an outer loop. In the following, the inner loop sees it has a
++// call (block 3) on every path from the head (block 2) to the
++// backedge (arc 3->2).  So it deletes the ncsfpt (non-call safepoint)
++// in block 2, _but_ this leaves the outer loop without a safepoint.
++//
++//          entry  0
++//                 |
++//                 v
++// outer 1,2    +->1
++//              |  |
++//              |  v
++//              |  2<---+  ncsfpt in 2
++//              |_/|\   |
++//                 | v  |
++// inner 2,3      /  3  |  call in 3
++//               /   |  |
++//              v    +--+
++//        exit  4
++//
++//
++// This method creates a list (_required_safept) of ncsfpt nodes that must
++// be protected is created for each loop. When a ncsfpt maybe deleted, it
++// is first looked for in the lists for the outer loops of the current loop.
++//
++// The insights into the problem:
++//  A) counted loops are okay
++//  B) innermost loops are okay (only an inner loop can delete
++//     a ncsfpt needed by an outer loop)
++//  C) a loop is immune from an inner loop deleting a safepoint
++//     if the loop has a call on the idom-path
++//  D) a loop is also immune if it has a ncsfpt (non-call safepoint) on the
++//     idom-path that is not in a nested loop
++//  E) otherwise, an ncsfpt on the idom-path that is nested in an inner
++//     loop needs to be prevented from deletion by an inner loop
++//
++// There are two analyses:
++//  1) The first, and cheaper one, scans the loop body from
++//     tail to head following the idom (immediate dominator)
++//     chain, looking for the cases (C,D,E) above.
++//     Since inner loops are scanned before outer loops, there is summary
++//     information about inner loops.  Inner loops can be skipped over
++//     when the tail of an inner loop is encountered.
++//
++//  2) The second, invoked if the first fails to find a call or ncsfpt on
++//     the idom path (which is rare), scans all predecessor control paths
++//     from the tail to the head, terminating a path when a call or sfpt
++//     is encountered, to find the ncsfpt's that are closest to the tail.
++//
++void IdealLoopTree::check_safepts(VectorSet &visited, Node_List &stack) {
++  // Bottom up traversal
++  IdealLoopTree* ch = _child;
++  while (ch != NULL) {
++    ch->check_safepts(visited, stack);
++    ch = ch->_next;
++  }
++
++  if (!_head->is_CountedLoop() && !_has_sfpt && _parent != NULL && !_irreducible) {
++    bool  has_call         = false; // call on dom-path
++    bool  has_local_ncsfpt = false; // ncsfpt on dom-path at this loop depth
++    Node* nonlocal_ncsfpt  = NULL;  // ncsfpt on dom-path at a deeper depth
++    // Scan the dom-path nodes from tail to head
++    for (Node* n = tail(); n != _head; n = _phase->idom(n)) {
++      if (n->is_Call() && n->as_Call()->guaranteed_safepoint()) {
++        has_call = true;
+         _has_sfpt = 1;          // Then no need for a safept!
+         break;
++      } else if (n->Opcode() == Op_SafePoint) {
++        if (_phase->get_loop(n) == this) {
++          has_local_ncsfpt = true;
++          break;
+       }
++        if (nonlocal_ncsfpt == NULL) {
++          nonlocal_ncsfpt = n; // save the one closest to the tail
+     }
++      } else {
++        IdealLoopTree* nlpt = _phase->get_loop(n);
++        if (this != nlpt) {
++          // If at an inner loop tail, see if the inner loop has already
++          // recorded seeing a call on the dom-path (and stop.)  If not,
++          // jump to the head of the inner loop.
++          assert(is_member(nlpt), "nested loop");
++          Node* tail = nlpt->_tail;
++          if (tail->in(0)->is_If()) tail = tail->in(0);
++          if (n == tail) {
++            // If inner loop has call on dom-path, so does outer loop
++            if (nlpt->_has_sfpt) {
++              has_call = true;
++              _has_sfpt = 1;
++              break;
++            }
++            // Skip to head of inner loop
++            assert(_phase->is_dominator(_head, nlpt->_head), "inner head dominated by outer head");
++            n = nlpt->_head;
++          }
++        }
++      }
++    }
++    // Record safept's that this loop needs preserved when an
++    // inner loop attempts to delete it's safepoints.
++    if (_child != NULL && !has_call && !has_local_ncsfpt) {
++      if (nonlocal_ncsfpt != NULL) {
++        if (_required_safept == NULL) _required_safept = new Node_List();
++        _required_safept->push(nonlocal_ncsfpt);
++      } else {
++        // Failed to find a suitable safept on the dom-path.  Now use
++        // an all paths walk from tail to head, looking for safepoints to preserve.
++        allpaths_check_safepts(visited, stack);
+   }
++    }
++  }
++}
+ 
+-  // Recursively
+-  if( _child ) _child->check_inner_safepts( phase );
+-  if( _next  ) _next ->check_inner_safepts( phase );
++//---------------------------is_deleteable_safept----------------------------
++// Is safept not required by an outer loop?
++bool PhaseIdealLoop::is_deleteable_safept(Node* sfpt) {
++  assert(sfpt->Opcode() == Op_SafePoint, "");
++  IdealLoopTree* lp = get_loop(sfpt)->_parent;
++  while (lp != NULL) {
++    Node_List* sfpts = lp->_required_safept;
++    if (sfpts != NULL) {
++      for (uint i = 0; i < sfpts->size(); i++) {
++        if (sfpt == sfpts->at(i))
++          return false;
++      }
++    }
++    lp = lp->_parent;
++  }
++  return true;
+ }
+ 
+ //------------------------------counted_loop-----------------------------------
+@@ -1154,7 +1316,8 @@
+ 
+     // Look for a safepoint to remove
+     for (Node* n = tail(); n != _head; n = phase->idom(n))
+-      if( n->Opcode() == Op_SafePoint ) // Found a safept?
++      if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this &&
++          phase->is_deleteable_safept(n))
+         phase->lazy_replace(n,n->in(TypeFunc::Control));
+ 
+     CountedLoopNode *cl = _head->as_CountedLoop();
+@@ -1230,6 +1393,21 @@
+         continue;
+       }
+     }
++  } else if (_parent != NULL && !_irreducible) {
++    // Not a counted loop.
++    // Look for a safepoint on the idom-path to remove, preserving the first one
++    bool found = false;
++    Node* n = tail();
++    for (; n != _head && !found; n = phase->idom(n)) {
++      if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this)
++        found = true; // Found one
++    }
++    // Skip past it and delete the others
++    for (; n != _head; n = phase->idom(n)) {
++      if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this &&
++          phase->is_deleteable_safept(n))
++        phase->lazy_replace(n,n->in(TypeFunc::Control));
++    }
+   }
+ 
+   // Recursively
+@@ -1374,7 +1552,8 @@
+   // Given dominators, try to find inner loops with calls that must
+   // always be executed (call dominates loop tail).  These loops do
+   // not need a seperate safepoint.
+-  _ltree_root->check_inner_safepts( this );
++  Node_List cisstack(a);
++  _ltree_root->check_safepts(visited, cisstack);
+ 
+   // Walk the DATA nodes and place into loops.  Find earliest control
+   // node.  For CFG nodes, the _nodes array starts out and remains
+@@ -2119,7 +2298,8 @@
+           // (the old code here would yank a 2nd safepoint after seeing a
+           // first one, even though the 1st did not dominate in the loop body
+           // and thus could be avoided indefinitely)
+-          if( !verify_me && ilt->_has_sfpt && n->Opcode() == Op_SafePoint ) {
++          if( !verify_me && ilt->_has_sfpt && n->Opcode() == Op_SafePoint &&
++              is_deleteable_safept(n)) {
+             Node *in = n->in(TypeFunc::Control);
+             lazy_replace(n,in);       // Pull safepoint now
+             // Carry on with the recursion "as if" we are walking
+@@ -2704,4 +2884,3 @@
+     }
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/loopnode.hpp openjdk/hotspot/src/share/vm/opto/loopnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/loopnode.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/loopnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)loopnode.hpp	1.143 07/06/29 13:39:53 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -87,7 +84,7 @@
+       in(2) != NULL && phase->type(in(2)) != Type::TOP;
+   }
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -214,7 +211,7 @@
+   int  node_count_before_unroll()           { return _node_count_before_unroll; }
+ 
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -246,7 +243,7 @@
+     return (CountedLoopNode*)ln; }
+ 
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -292,10 +289,13 @@
+         _has_sfpt:1,            // True if has non-call safepoint
+         _rce_candidate:1;       // True if candidate for range check elimination
+ 
++  Node_List* _required_safept;      // A inner loop cannot delete these safepts;
++
+   IdealLoopTree( PhaseIdealLoop* phase, Node *head, Node *tail )
+     : _parent(0), _next(0), _child(0),
+       _head(head), _tail(tail),
+       _phase(phase),
++      _required_safept(NULL),
+       _nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0)
+   { }
+ 
+@@ -328,10 +328,14 @@
+   // Driver for various flavors of iteration splitting
+   void iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new );
+ 
+-  // Given dominators, try to find inner loops with calls that must
+-  // always be executed (call dominates loop tail).  These loops do
+-  // not need a seperate safepoint.
+-  void check_inner_safepts( PhaseIdealLoop *phase );
++  // Given dominators, try to find loops with calls that must always be
++  // executed (call dominates loop tail).  These loops do not need non-call
++  // safepoints (ncsfpt).
++  void check_safepts(VectorSet &visited, Node_List &stack);
++
++  // Allpaths backwards scan from loop tail, terminating each path at first safepoint
++  // encountered.
++  void allpaths_check_safepts(VectorSet &visited, Node_List &stack);
+ 
+   // Convert to counted loops where possible
+   void counted_loop( PhaseIdealLoop *phase );
+@@ -649,6 +653,9 @@
+   // Recompute dom_depth
+   void recompute_dom_depth();
+ 
++  // Is safept not required by an outer loop?
++  bool is_deleteable_safept(Node* sfpt);
++
+ public:
+   // Dominators for the sea of nodes
+   void Dominators();
+@@ -910,4 +917,3 @@
+ 
+   IdealLoopTree* current() { return _curnt; }  // Return current value of iterator.
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/loopopts.cpp openjdk/hotspot/src/share/vm/opto/loopopts.cpp
+--- openjdk6/hotspot/src/share/vm/opto/loopopts.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/loopopts.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)loopopts.cpp	1.221 08/06/19 12:08:11 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -32,11 +29,6 @@
+ //------------------------------split_thru_phi---------------------------------
+ // Split Node 'n' through merge point if there is enough win.
+ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
+-  if (n->Opcode() == Op_ConvI2L && n->bottom_type() != TypeLong::LONG) {
+-    // ConvI2L may have type information on it which is unsafe to push up
+-    // so disable this for now
+-    return NULL;
+-  }
+   int wins = 0;
+   assert( !n->is_CFG(), "" );
+   assert( region->is_Region(), "" );
+@@ -608,6 +600,9 @@
+     }
+   }
+ 
++  // Use same limit as split_if_with_blocks_post
++  if( C->unique() > 35000 ) return n; // Method too big
++
+   // Split 'n' through the merge point if it is profitable
+   Node *phi = split_thru_phi( n, n_blk, policy );
+   if( !phi ) return n;
+@@ -1243,20 +1238,26 @@
+         assert( dd_r >= dom_depth(dom_lca(newuse,use)), "" );
+ 
+         // The original user of 'use' uses 'r' instead.
+-        for (DUIterator_Last lmin, l = use->last_outs(lmin); l >= lmin; --l) {
++        for (DUIterator_Last lmin, l = use->last_outs(lmin); l >= lmin;) {
+           Node* useuse = use->last_out(l);
+           _igvn.hash_delete(useuse);
+           _igvn._worklist.push(useuse);
++          uint uses_found = 0;
+           if( useuse->in(0) == use ) {
+             useuse->set_req(0, r);
++            uses_found++;
+             if( useuse->is_CFG() ) {
+               assert( dom_depth(useuse) > dd_r, "" );
+               set_idom(useuse, r, dom_depth(useuse));
+             }
+           }
+-          for( uint k = 1; k < useuse->req(); k++ )
+-            if( useuse->in(k) == use )
++          for( uint k = 1; k < useuse->req(); k++ ) {
++            if( useuse->in(k) == use ) {
+               useuse->set_req(k, r);
++              uses_found++;
++            }
++          }
++          l -= uses_found;    // we deleted 1 or more copies of this edge
+         }
+ 
+         // Now finish up 'r'
+@@ -2674,4 +2675,3 @@
+   }
+ 
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/loopTransform.cpp openjdk/hotspot/src/share/vm/opto/loopTransform.cpp
+--- openjdk6/hotspot/src/share/vm/opto/loopTransform.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/loopTransform.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)loopTransform.cpp	1.116 07/06/01 11:35:03 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/loopUnswitch.cpp openjdk/hotspot/src/share/vm/opto/loopUnswitch.cpp
+--- openjdk6/hotspot/src/share/vm/opto/loopUnswitch.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/loopUnswitch.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)loopUnswitch.cpp	1.6 07/06/29 13:39:53 JVM"
+-#endif
+ /*
+  * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/machnode.cpp openjdk/hotspot/src/share/vm/opto/machnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/machnode.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/machnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)machnode.cpp	1.199 07/05/05 17:06:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -81,7 +78,7 @@
+ //------------------------------dump_spec--------------------------------------
+ // Print any per-operand special info
+ #ifndef PRODUCT
+-void MachOper::dump_spec() const { }
++void MachOper::dump_spec(outputStream *st) const { }
+ #endif
+ 
+ //------------------------------hash-------------------------------------------
+@@ -444,35 +441,35 @@
+ #ifndef PRODUCT
+ //------------------------------dump_spec--------------------------------------
+ // Print any per-operand special info
+-void MachNode::dump_spec() const {
++void MachNode::dump_spec(outputStream *st) const {
+   uint cnt = num_opnds();
+   for( uint i=0; i<cnt; i++ )
+-    _opnds[i]->dump_spec();
++    _opnds[i]->dump_spec(st);
+   const TypePtr *t = adr_type();
+   if( t ) {
+     Compile* C = Compile::current();
+     if( C->alias_type(t)->is_volatile() )
+-      tty->print(" Volatile!");
++      st->print(" Volatile!");
+   }
+ }
+ 
+ //------------------------------dump_format------------------------------------
+ // access to virtual
+-void MachNode::dump_format(PhaseRegAlloc *ra) const {
+-  format(ra); // access to virtual
++void MachNode::dump_format(PhaseRegAlloc *ra, outputStream *st) const {
++  format(ra, st); // access to virtual
+ }
+ #endif
+ 
+ //=============================================================================
+ #ifndef PRODUCT
+-void MachTypeNode::dump_spec() const {
+-  _bottom_type->dump();
++void MachTypeNode::dump_spec(outputStream *st) const {
++  _bottom_type->dump_on(st);
+ }
+ #endif
+ 
+ //=============================================================================
+ #ifndef PRODUCT
+-void MachNullCheckNode::format( PhaseRegAlloc *ra_ ) const {
++void MachNullCheckNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
+   int reg = ra_->get_reg_first(in(1)->in(_vidx));
+   tty->print("%s %s", Name(), Matcher::regName[reg]);
+ }
+@@ -517,19 +514,19 @@
+ }
+ 
+ #ifndef PRODUCT
+-void MachProjNode::dump_spec() const {
+-  ProjNode::dump_spec();
++void MachProjNode::dump_spec(outputStream *st) const {
++  ProjNode::dump_spec(st);
+   switch (_ideal_reg) {
+-  case unmatched_proj:  tty->print("/unmatched");                         break;
+-  case fat_proj:        tty->print("/fat"); if (WizardMode) _rout.dump(); break;
++  case unmatched_proj:  st->print("/unmatched");                         break;
++  case fat_proj:        st->print("/fat"); if (WizardMode) _rout.dump(); break;
+   }
+ }
+ #endif
+ 
+ //=============================================================================
+ #ifndef PRODUCT
+-void MachIfNode::dump_spec() const {
+-  tty->print("P=%f, C=%f",_prob, _fcnt);
++void MachIfNode::dump_spec(outputStream *st) const {
++  st->print("P=%f, C=%f",_prob, _fcnt);
+ }
+ #endif
+ 
+@@ -575,11 +572,11 @@
+ const Type *MachCallNode::Value(PhaseTransform *phase) const { return tf()->range(); }
+ 
+ #ifndef PRODUCT
+-void MachCallNode::dump_spec() const { 
+-  tty->print("# "); 
+-  tf()->dump();
+-  if (_cnt != COUNT_UNKNOWN)  tty->print(" C=%f",_cnt);
+-  if (jvms() != NULL)  jvms()->dump_spec();
++void MachCallNode::dump_spec(outputStream *st) const {
++  st->print("# ");
++  tf()->dump_on(st);
++  if (_cnt != COUNT_UNKNOWN)  st->print(" C=%f",_cnt);
++  if (jvms() != NULL)  jvms()->dump_spec(st);
+ }
+ #endif
+ 
+@@ -618,12 +615,12 @@
+   return MachCallNode::cmp(call) && _method->equals(call._method); 
+ }
+ #ifndef PRODUCT
+-void MachCallJavaNode::dump_spec() const { 
++void MachCallJavaNode::dump_spec(outputStream *st) const {
+   if( _method ) {
+-    _method->print_short_name();
+-    tty->print(" ");
++    _method->print_short_name(st);
++    st->print(" ");
+   }
+-  MachCallNode::dump_spec();
++  MachCallNode::dump_spec(st);
+ }
+ #endif
+ 
+@@ -645,32 +642,32 @@
+ 
+ #ifndef PRODUCT
+ // Helper for summarizing uncommon_trap arguments.
+-void MachCallStaticJavaNode::dump_trap_args() const {
++void MachCallStaticJavaNode::dump_trap_args(outputStream *st) const {
+   int trap_req = uncommon_trap_request();
+   if (trap_req != 0) {
+     char buf[100];
+-    tty->print("(%s)",
++    st->print("(%s)",
+                Deoptimization::format_trap_request(buf, sizeof(buf),
+                                                    trap_req));
+   }
+ }
+ 
+-void MachCallStaticJavaNode::dump_spec() const { 
+-  tty->print("Static ");
++void MachCallStaticJavaNode::dump_spec(outputStream *st) const {
++  st->print("Static ");
+   if (_name != NULL) {
+-    tty->print("wrapper for: %s", _name );
+-    dump_trap_args();
+-    tty->print(" ");
++    st->print("wrapper for: %s", _name );
++    dump_trap_args(st);
++    st->print(" ");
+   }
+-  MachCallJavaNode::dump_spec();
++  MachCallJavaNode::dump_spec(st);
+ }
+ #endif
+ 
+ //=============================================================================
+ #ifndef PRODUCT
+-void MachCallDynamicJavaNode::dump_spec() const { 
+-  tty->print("Dynamic ");
+-  MachCallJavaNode::dump_spec();
++void MachCallDynamicJavaNode::dump_spec(outputStream *st) const {
++  st->print("Dynamic ");
++  MachCallJavaNode::dump_spec(st);
+ }
+ #endif
+ //=============================================================================
+@@ -680,9 +677,9 @@
+   return MachCallNode::cmp(call) && !strcmp(_name,call._name);
+ }
+ #ifndef PRODUCT
+-void MachCallRuntimeNode::dump_spec() const { 
+-  tty->print("%s ",_name);
+-  MachCallNode::dump_spec();
++void MachCallRuntimeNode::dump_spec(outputStream *st) const {
++  st->print("%s ",_name);
++  MachCallNode::dump_spec(st);
+ }
+ #endif
+ //=============================================================================
+@@ -697,14 +694,14 @@
+ 
+ //=============================================================================
+ #ifndef PRODUCT
+-void labelOper::int_format(PhaseRegAlloc *ra, const MachNode *node) const {
+-  tty->print("B%d", _block_num);
++void labelOper::int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const {
++  st->print("B%d", _block_num);
+ }
+ #endif // PRODUCT
+ 
+ //=============================================================================
+ #ifndef PRODUCT
+-void methodOper::int_format(PhaseRegAlloc *ra, const MachNode *node) const {
+-  tty->print(INTPTR_FORMAT, _method);
++void methodOper::int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const {
++  st->print(INTPTR_FORMAT, _method);
+ }
+ #endif // PRODUCT
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/machnode.hpp openjdk/hotspot/src/share/vm/opto/machnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/machnode.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/machnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)machnode.hpp	1.202 07/05/17 15:59:11 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -88,7 +85,7 @@
+     return ::as_FloatRegister(reg(ra_, node, idx));
+   }
+ 
+-#if defined(IA32)
++#if defined(IA32) || defined(AMD64)
+   XMMRegister  as_XMMRegister(PhaseRegAlloc *ra_, const Node *node)   const {
+     return ::as_XMMRegister(reg(ra_, node));
+   }
+@@ -145,10 +142,10 @@
+   virtual const char    *Name() const { return "???";}
+ 
+   // Methods to output the text version of the operand
+-  virtual void int_format(PhaseRegAlloc *,const MachNode *node) const = 0;
+-  virtual void ext_format(PhaseRegAlloc *,const MachNode *node,int idx) const=0;
++  virtual void int_format(PhaseRegAlloc *,const MachNode *node, outputStream *st) const = 0;
++  virtual void ext_format(PhaseRegAlloc *,const MachNode *node,int idx, outputStream *st) const=0;
+ 
+-  virtual void dump_spec() const; // Print per-operand info
++  virtual void dump_spec(outputStream *st) const; // Print per-operand info
+ #endif
+ };
+ 
+@@ -296,8 +293,8 @@
+ 
+ #ifndef PRODUCT
+   virtual const char *Name() const = 0; // Machine-specific name
+-  virtual void dump_spec() const; // Print per-node info
+-  void         dump_format(PhaseRegAlloc *ra) const; // access to virtual
++  virtual void dump_spec(outputStream *st) const; // Print per-node info
++  void         dump_format(PhaseRegAlloc *ra, outputStream *st) const; // access to virtual
+ #endif
+ };
+ 
+@@ -324,7 +321,7 @@
+ 
+   virtual const class Type *bottom_type() const { return _bottom_type; }
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -338,7 +335,7 @@
+ 
+ #ifndef PRODUCT
+   virtual const char *Name() const { return "Breakpoint"; }
+-  virtual void format( PhaseRegAlloc * ) const;
++  virtual void format( PhaseRegAlloc *, outputStream *st ) const;
+ #endif
+ };
+ 
+@@ -352,7 +349,7 @@
+ 
+ #ifndef PRODUCT
+   virtual const char *Name() const { return "Unvalidated-Entry-Point"; }
+-  virtual void format( PhaseRegAlloc * ) const;
++  virtual void format( PhaseRegAlloc *, outputStream *st ) const;
+ #endif
+ };
+ 
+@@ -364,11 +361,10 @@
+   virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
+   virtual uint size(PhaseRegAlloc *ra_) const;
+   virtual int reloc() const;
+-  uint implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size ) const;
+ 
+ #ifndef PRODUCT
+   virtual const char *Name() const { return "Prolog"; }
+-  virtual void format( PhaseRegAlloc * ) const;
++  virtual void format( PhaseRegAlloc *, outputStream *st ) const;
+ #endif
+ };
+ 
+@@ -393,7 +389,7 @@
+ 
+ #ifndef PRODUCT
+   virtual const char *Name() const { return "Epilog"; }
+-  virtual void format( PhaseRegAlloc * ) const;
++  virtual void format( PhaseRegAlloc *, outputStream *st ) const;
+ #endif
+ };
+ 
+@@ -414,8 +410,8 @@
+   virtual const Pipeline *pipeline() const;
+ #ifndef PRODUCT
+   virtual const char *Name() const { return "Nop"; }
+-  virtual void format( PhaseRegAlloc * ) const;
+-  virtual void dump_spec() const { } // No per-operand info
++  virtual void format( PhaseRegAlloc *, outputStream *st ) const;
++  virtual void dump_spec(outputStream *st) const { } // No per-operand info
+ #endif
+ };
+ 
+@@ -442,14 +438,14 @@
+   virtual const class Type *bottom_type() const { return _type; }
+   virtual uint ideal_reg() const { return Matcher::base2reg[_type->base()]; }
+   virtual uint oper_input_base() const { return 1; }
+-  uint implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size ) const;
++  uint implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const;
+ 
+   virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
+   virtual uint size(PhaseRegAlloc *ra_) const;
+ 
+ #ifndef PRODUCT
+   virtual const char *Name() const { return "MachSpillCopy"; }
+-  virtual void format( PhaseRegAlloc * ) const;
++  virtual void format( PhaseRegAlloc *, outputStream *st ) const;
+ #endif
+ };
+ 
+@@ -478,7 +474,7 @@
+   virtual const RegMask &out_RegMask() const { return RegMask::Empty; }
+ #ifndef PRODUCT
+   virtual const char *Name() const { return "NullCheck"; }
+-  virtual void format( PhaseRegAlloc * ) const;
++  virtual void format( PhaseRegAlloc *, outputStream *st ) const;
+ #endif
+ };
+ 
+@@ -508,7 +504,7 @@
+   // Need size_of() for virtual ProjNode::clone() 
+   virtual uint  size_of() const { return sizeof(MachProjNode); }
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -523,7 +519,7 @@
+     init_class_id(Class_MachIf);
+   }
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -652,7 +648,7 @@
+   bool returns_long() const { return tf()->return_type() == T_LONG; }
+   bool return_value_is_used() const;
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -670,7 +666,7 @@
+     init_class_id(Class_MachCallJava);
+   }
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -690,8 +686,8 @@
+ 
+   virtual int ret_addr_offset();
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
+-  void dump_trap_args() const;
++  virtual void dump_spec(outputStream *st) const;
++  void dump_trap_args(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -706,7 +702,7 @@
+   }
+   virtual int ret_addr_offset();
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -722,7 +718,7 @@
+   }
+   virtual int ret_addr_offset();
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -762,7 +758,7 @@
+   virtual uint size_of() const { return sizeof(MachTempNode); }
+ 
+ #ifndef PRODUCT
+-  virtual void format(PhaseRegAlloc *ra) const {}
++  virtual void format(PhaseRegAlloc *, outputStream *st ) const {}
+   virtual const char *Name() const { return "MachTemp";}
+ #endif
+ };
+@@ -797,8 +793,8 @@
+ #ifndef PRODUCT
+   virtual const char    *Name()   const { return "Label";}
+ 
+-  virtual void int_format(PhaseRegAlloc *ra, const MachNode *node) const;
+-  virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx) const { int_format( ra, node ); }
++  virtual void int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const;
++  virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const { int_format( ra, node, st ); }
+ #endif
+ };
+ 
+@@ -824,7 +820,7 @@
+ #ifndef PRODUCT
+   virtual const char    *Name()   const { return "Method";}
+ 
+-  virtual void int_format(PhaseRegAlloc *ra, const MachNode *node) const;
+-  virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx) const { int_format( ra, node ); }
++  virtual void int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const;
++  virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const { int_format( ra, node, st ); }
+ #endif
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/macro.cpp openjdk/hotspot/src/share/vm/opto/macro.cpp
+--- openjdk6/hotspot/src/share/vm/opto/macro.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/macro.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)macro.cpp	1.31 07/07/10 21:32:44 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -71,14 +68,14 @@
+ }
+ 
+ Node* PhaseMacroExpand::opt_iff(Node* region, Node* iff) {
+-  IfNode *opt_iff = _igvn.register_new_node_with_optimizer(iff)->as_If();
++  IfNode *opt_iff = transform_later(iff)->as_If();
+ 
+   // Fast path taken; set region slot 2
+-  Node *fast_taken = _igvn.register_new_node_with_optimizer( new (C, 1) IfFalseNode(opt_iff) );
++  Node *fast_taken = transform_later( new (C, 1) IfFalseNode(opt_iff) );
+   region->init_req(2,fast_taken); // Capture fast-control
+ 
+   // Fast path not-taken, i.e. slow path
+-  Node *slow_taken = _igvn.register_new_node_with_optimizer( new (C, 1) IfTrueNode(opt_iff) );
++  Node *slow_taken = transform_later( new (C, 1) IfTrueNode(opt_iff) );
+   return slow_taken;
+ }
+ 
+@@ -109,7 +106,7 @@
+   call->set_cnt(PROB_UNLIKELY_MAG(4));  // Same effect as RC_UNCOMMON.
+   _igvn.hash_delete(oldcall);
+   _igvn.subsume_node(oldcall, call);
+-  _igvn.register_new_node_with_optimizer(call);
++  transform_later(call);
+ 
+   return call;
+ }
+@@ -170,11 +167,29 @@
+ }
+ 
+ 
++//---------------------------set_eden_pointers-------------------------
++void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) {
++  if (UseTLAB) {                // Private allocation: load from TLS
++    Node* thread = transform_later(new (C, 1) ThreadLocalNode());
++    int tlab_top_offset = in_bytes(JavaThread::tlab_top_offset());
++    int tlab_end_offset = in_bytes(JavaThread::tlab_end_offset());
++    eden_top_adr = basic_plus_adr(top()/*not oop*/, thread, tlab_top_offset);
++    eden_end_adr = basic_plus_adr(top()/*not oop*/, thread, tlab_end_offset);
++  } else {                      // Shared allocation: load from globals
++    CollectedHeap* ch = Universe::heap();
++    address top_adr = (address)ch->top_addr();
++    address end_adr = (address)ch->end_addr();
++    eden_top_adr = makecon(TypeRawPtr::make(top_adr));
++    eden_end_adr = basic_plus_adr(eden_top_adr, end_adr - top_adr);
++  }
++}
++
++
+ Node* PhaseMacroExpand::make_load(Node* ctl, Node* mem, Node* base, int offset, const Type* value_type, BasicType bt) {
+   Node* adr = basic_plus_adr(base, offset);
+   const TypePtr* adr_type = TypeRawPtr::BOTTOM;
+   Node* value = LoadNode::make(C, ctl, mem, adr, adr_type, value_type, bt);
+-  _igvn.register_new_node_with_optimizer(value);
++  transform_later(value);
+   return value;
+ }
+ 
+@@ -182,7 +197,7 @@
+ Node* PhaseMacroExpand::make_store(Node* ctl, Node* mem, Node* base, int offset, Node* value, BasicType bt) {
+   Node* adr = basic_plus_adr(base, offset);
+   mem = StoreNode::make(C, ctl, mem, adr, NULL, value, bt);
+-  _igvn.register_new_node_with_optimizer(mem);
++  transform_later(mem);
+   return mem;
+ }
+ 
+@@ -254,8 +269,10 @@
+   Node* size_in_bytes     = alloc->in(AllocateNode::AllocSize);
+   Node* klass_node        = alloc->in(AllocateNode::KlassNode);
+   Node* initial_slow_test = alloc->in(AllocateNode::InitialTest);
+-  Node* eden_top_adr      = alloc->in(AllocateNode::EdenTop);
+-  Node* eden_end_adr      = alloc->in(AllocateNode::EdenEnd);
++
++  Node* eden_top_adr;
++  Node* eden_end_adr;
++  set_eden_pointers(eden_top_adr, eden_end_adr);
+ 
+   uint raw_idx = C->get_alias_index(TypeRawPtr::BOTTOM);
+   assert(ctrl != NULL, "must have control");
+@@ -310,13 +327,13 @@
+     // might be a TRUE for finalizers or a fancy class check for
+     // newInstance0.
+     IfNode *toobig_iff = new (C, 2) IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN);
+-    _igvn.register_new_node_with_optimizer(toobig_iff);
++    transform_later(toobig_iff);
+     // Plug the failing-too-big test into the slow-path region
+     Node *toobig_true = new (C, 1) IfTrueNode( toobig_iff );
+-    _igvn.register_new_node_with_optimizer(toobig_true);
++    transform_later(toobig_true);
+     slow_region    ->init_req( too_big_or_final_path, toobig_true );
+     toobig_false = new (C, 1) IfFalseNode( toobig_iff );
+-    _igvn.register_new_node_with_optimizer(toobig_false);
++    transform_later(toobig_false);
+   } else {         // No initial test, just fall into next case
+     toobig_false = ctrl;
+     debug_only(slow_region = NodeSentinel);
+@@ -345,8 +362,8 @@
+       // loop-back merge point.
+       contended_region    ->init_req( fall_in_path, toobig_false );
+       contended_phi_rawmem->init_req( fall_in_path, mem );
+-      _igvn.register_new_node_with_optimizer(contended_region);
+-      _igvn.register_new_node_with_optimizer(contended_phi_rawmem);
++      transform_later(contended_region);
++      transform_later(contended_phi_rawmem);
+     }
+   
+     // Load(-locked) the heap top.  
+@@ -355,32 +372,32 @@
+       ? new (C, 3) LoadPNode     ( ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM )
+       : new (C, 3) LoadPLockedNode( contended_region, contended_phi_rawmem, eden_top_adr );
+ 
+-    _igvn.register_new_node_with_optimizer(old_eden_top);
++    transform_later(old_eden_top);
+     // Add to heap top to get a new heap top
+     Node *new_eden_top = new (C, 4) AddPNode( top(), old_eden_top, size_in_bytes );
+-    _igvn.register_new_node_with_optimizer(new_eden_top);
++    transform_later(new_eden_top);
+     // Check for needing a GC; compare against heap end
+     Node *needgc_cmp = new (C, 3) CmpPNode( new_eden_top, eden_end );
+-    _igvn.register_new_node_with_optimizer(needgc_cmp);
++    transform_later(needgc_cmp);
+     Node *needgc_bol = new (C, 2) BoolNode( needgc_cmp, BoolTest::ge );
+-    _igvn.register_new_node_with_optimizer(needgc_bol);
++    transform_later(needgc_bol);
+     IfNode *needgc_iff = new (C, 2) IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN );
+-    _igvn.register_new_node_with_optimizer(needgc_iff);
++    transform_later(needgc_iff);
+     
+     // Plug the failing-heap-space-need-gc test into the slow-path region
+     Node *needgc_true = new (C, 1) IfTrueNode( needgc_iff );
+-    _igvn.register_new_node_with_optimizer(needgc_true);
++    transform_later(needgc_true);
+     if( initial_slow_test ) {
+       slow_region    ->init_req( need_gc_path, needgc_true );
+       // This completes all paths into the slow merge point
+-      _igvn.register_new_node_with_optimizer(slow_region);
++      transform_later(slow_region);
+     } else {                      // No initial slow path needed!
+       // Just fall from the need-GC path straight into the VM call.
+       slow_region    = needgc_true;
+     }
+     // No need for a GC.  Setup for the Store-Conditional
+     Node *needgc_false = new (C, 1) IfFalseNode( needgc_iff );
+-    _igvn.register_new_node_with_optimizer(needgc_false);
++    transform_later(needgc_false);
+ 
+     // Grab regular I/O before optional prefetch may change it.
+     // Slow-path does no I/O so just set it to the original I/O.
+@@ -396,28 +413,28 @@
+     Node *fast_oop_ctrl;
+     if( UseTLAB ) {
+       store_eden_top = new (C, 4) StorePNode( needgc_false, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, new_eden_top );
+-      _igvn.register_new_node_with_optimizer(store_eden_top);
++      transform_later(store_eden_top);
+       fast_oop_ctrl = needgc_false; // No contention, so this is the fast path
+     } else {
+       store_eden_top = new (C, 5) StorePConditionalNode( needgc_false, contended_phi_rawmem, eden_top_adr, new_eden_top, old_eden_top );
+-      _igvn.register_new_node_with_optimizer(store_eden_top);
++      transform_later(store_eden_top);
+       Node *contention_check = new (C, 2) BoolNode( store_eden_top, BoolTest::ne );
+-      _igvn.register_new_node_with_optimizer(contention_check);
++      transform_later(contention_check);
+       store_eden_top = new (C, 1) SCMemProjNode(store_eden_top);
+-      _igvn.register_new_node_with_optimizer(store_eden_top);
++      transform_later(store_eden_top);
+ 
+       // If not using TLABs, check to see if there was contention.
+       IfNode *contention_iff = new (C, 2) IfNode ( needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN );
+-      _igvn.register_new_node_with_optimizer(contention_iff);
++      transform_later(contention_iff);
+       Node *contention_true = new (C, 1) IfTrueNode( contention_iff );
+-      _igvn.register_new_node_with_optimizer(contention_true);
++      transform_later(contention_true);
+       // If contention, loopback and try again.
+       contended_region->init_req( contended_loopback_path, contention_true );
+       contended_phi_rawmem->init_req( contended_loopback_path, store_eden_top );
+ 
+       // Fast-path succeeded with no contention!
+       Node *contention_false = new (C, 1) IfFalseNode( contention_iff );
+-      _igvn.register_new_node_with_optimizer(contention_false);
++      transform_later(contention_false);
+       fast_oop_ctrl = contention_false;
+     }
+ 
+@@ -438,7 +455,7 @@
+ 
+       // Get base of thread-local storage area
+       Node* thread = new (C, 1) ThreadLocalNode();
+-      _igvn.register_new_node_with_optimizer(thread);
++      transform_later(thread);
+ 
+       call->init_req(TypeFunc::Parms+0, thread);
+       call->init_req(TypeFunc::Parms+1, fast_oop);
+@@ -447,11 +464,11 @@
+       call->init_req( TypeFunc::Memory , fast_oop_rawmem );
+       call->init_req( TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr) );
+       call->init_req( TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr) );
+-      _igvn.register_new_node_with_optimizer(call);
++      transform_later(call);
+       fast_oop_ctrl = new (C, 1) ProjNode(call,TypeFunc::Control);
+-      _igvn.register_new_node_with_optimizer(fast_oop_ctrl);
++      transform_later(fast_oop_ctrl);
+       fast_oop_rawmem = new (C, 1) ProjNode(call,TypeFunc::Memory);
+-      _igvn.register_new_node_with_optimizer(fast_oop_rawmem);
++      transform_later(fast_oop_rawmem);
+     }
+ 
+     // Plug in the successful fast-path into the result merge point
+@@ -476,8 +493,9 @@
+   call->init_req( TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr) );
+ 
+   call->init_req(TypeFunc::Parms+0, klass_node);
+-  if (length != NULL)
++  if (length != NULL) {
+     call->init_req(TypeFunc::Parms+1, length);
++  }
+ 
+   // Copy debug information and adjust JVMState information, then replace
+   // allocate node with the call
+@@ -487,7 +505,7 @@
+   }
+   _igvn.hash_delete(alloc);
+   _igvn.subsume_node(alloc, call);
+-  _igvn.register_new_node_with_optimizer(call);
++  transform_later(call);
+ 
+   // Identify the output projections from the allocate node and
+   // adjust any references to them.
+@@ -518,7 +536,7 @@
+   if (_memproj_catchall != NULL ) {
+     if (_memproj_fallthrough == NULL) {
+       _memproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::Memory);
+-      _igvn.register_new_node_with_optimizer(_memproj_fallthrough);
++      transform_later(_memproj_fallthrough);
+     }
+     for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) {
+       Node *use = _memproj_catchall->fast_out(i);
+@@ -536,7 +554,7 @@
+   // Replace uses of the control i_o projection with result_phi_i_o (unless we are only generating a slow call)
+   if (_ioproj_fallthrough == NULL) {
+     _ioproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::I_O);
+-    _igvn.register_new_node_with_optimizer(_ioproj_fallthrough);
++    transform_later(_ioproj_fallthrough);
+   } else if (!always_slow) {
+     for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) {
+       Node *use = _ioproj_fallthrough->fast_out(i);
+@@ -568,7 +586,7 @@
+ 
+   if (_fallthroughcatchproj != NULL) {
+     ctrl = _fallthroughcatchproj->clone();
+-    _igvn.register_new_node_with_optimizer(ctrl);
++    transform_later(ctrl);
+     _igvn.hash_delete(_fallthroughcatchproj);
+     _igvn.subsume_node(_fallthroughcatchproj, result_region);
+   } else {
+@@ -580,7 +598,7 @@
+     slow_result = top();
+   } else {
+     slow_result = _resproj->clone();
+-    _igvn.register_new_node_with_optimizer(slow_result);
++    transform_later(slow_result);
+     _igvn.hash_delete(_resproj);
+     _igvn.subsume_node(_resproj, result_phi_rawoop);
+   }
+@@ -589,13 +607,14 @@
+   result_region    ->init_req( slow_result_path, ctrl );
+   result_phi_rawoop->init_req( slow_result_path, slow_result);
+   result_phi_rawmem->init_req( slow_result_path, _memproj_fallthrough );
+-  _igvn.register_new_node_with_optimizer(result_region);
+-  _igvn.register_new_node_with_optimizer(result_phi_rawoop);
+-  _igvn.register_new_node_with_optimizer(result_phi_rawmem);
+-  _igvn.register_new_node_with_optimizer(result_phi_i_o);
++  transform_later(result_region);
++  transform_later(result_phi_rawoop);
++  transform_later(result_phi_rawmem);
++  transform_later(result_phi_i_o);
+   // This completes all paths into the result merge point
+ }
+ 
++
+ // Helper for PhaseMacroExpand::expand_allocate_common.
+ // Initializes the newly-allocated storage.
+ Node*
+@@ -603,6 +622,7 @@
+                                     Node* control, Node* rawmem, Node* object,
+                                     Node* klass_node, Node* length,
+                                     Node* size_in_bytes) {
++  InitializeNode* init = alloc->initialization();
+   // Store the klass & mark bits
+   Node* mark_node = NULL;
+   // For now only enable fast locking for non-array types
+@@ -625,13 +645,34 @@
+       header_size = Klass::layout_helper_header_size(k->layout_helper());
+   }
+ 
+-  // Now bulk-clear the object body.  There may be a padding word after the
+-  // length, but it doesn't need to be initialized.  Optimizer will expand
+-  // this to a series of Stores if it's short and fixed size.
+-  if (!ZeroTLAB) {
++  // Clear the object body, if necessary.
++  if (init == NULL) {
++    // The init has somehow disappeared; be cautious and clear everything.
++    //
++    // This can happen if a node is allocated but an uncommon trap occurs
++    // immediately.  In this case, the Initialize gets associated with the
++    // trap, and may be placed in a different (outer) loop, if the Allocate
++    // is in a loop.  If (this is rare) the inner loop gets unrolled, then
++    // there can be two Allocates to one Initialize.  The answer in all these
++    // edge cases is safety first.  It is always safe to clear immediately
++    // within an Allocate, and then (maybe or maybe not) clear some more later.
++    if (!ZeroTLAB)
+     rawmem = ClearArrayNode::clear_memory(control, rawmem, object,
+                                           header_size, size_in_bytes,
+                                           &_igvn);
++  } else {
++    if (!init->is_complete()) {
++      // Try to win by zeroing only what the init does not store.
++      // We can also try to do some peephole optimizations,
++      // such as combining some adjacent subword stores.
++      rawmem = init->complete_stores(control, rawmem, object,
++                                     header_size, size_in_bytes, &_igvn);
++    }
++
++    // We have no more use for this link, since the AllocateNode goes away:
++    init->set_req(InitializeNode::RawAddress, top());
++    // (If we keep the link, it just confuses the register allocator,
++    // who thinks he sees a real use of the address by the membar.)
+   }
+ 
+   return rawmem;
+@@ -655,42 +696,42 @@
+       Node *pf_phi_abio = new (C, 3) PhiNode( pf_region, Type::ABIO ); 
+ 
+       Node *thread = new (C, 1) ThreadLocalNode();
+-      _igvn.register_new_node_with_optimizer(thread);
++      transform_later(thread);
+ 
+       Node *eden_pf_adr = new (C, 4) AddPNode( top()/*not oop*/, thread, 
+                    _igvn.MakeConX(in_bytes(JavaThread::tlab_pf_top_offset())) );
+-      _igvn.register_new_node_with_optimizer(eden_pf_adr);
++      transform_later(eden_pf_adr);
+ 
+       Node *old_pf_wm = new (C, 3) LoadPNode( needgc_false, 
+                                    contended_phi_rawmem, eden_pf_adr, 
+                                    TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM );
+-      _igvn.register_new_node_with_optimizer(old_pf_wm);
++      transform_later(old_pf_wm);
+ 
+       // check against new_eden_top
+       Node *need_pf_cmp = new (C, 3) CmpPNode( new_eden_top, old_pf_wm );
+-      _igvn.register_new_node_with_optimizer(need_pf_cmp);
++      transform_later(need_pf_cmp);
+       Node *need_pf_bol = new (C, 2) BoolNode( need_pf_cmp, BoolTest::ge );
+-      _igvn.register_new_node_with_optimizer(need_pf_bol);
++      transform_later(need_pf_bol);
+       IfNode *need_pf_iff = new (C, 2) IfNode( needgc_false, need_pf_bol, 
+                                        PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN );
+-      _igvn.register_new_node_with_optimizer(need_pf_iff);
++      transform_later(need_pf_iff);
+       
+       // true node, add prefetchdistance
+       Node *need_pf_true = new (C, 1) IfTrueNode( need_pf_iff );
+-      _igvn.register_new_node_with_optimizer(need_pf_true);
++      transform_later(need_pf_true);
+ 
+       Node *need_pf_false = new (C, 1) IfFalseNode( need_pf_iff );
+-      _igvn.register_new_node_with_optimizer(need_pf_false);
++      transform_later(need_pf_false);
+ 
+       Node *new_pf_wmt = new (C, 4) AddPNode( top(), old_pf_wm, 
+                                     _igvn.MakeConX(AllocatePrefetchDistance) );
+-      _igvn.register_new_node_with_optimizer(new_pf_wmt );
++      transform_later(new_pf_wmt );
+       new_pf_wmt->set_req(0, need_pf_true);
+ 
+       Node *store_new_wmt = new (C, 4) StorePNode( need_pf_true, 
+                                        contended_phi_rawmem, eden_pf_adr, 
+                                        TypeRawPtr::BOTTOM, new_pf_wmt );
+-      _igvn.register_new_node_with_optimizer(store_new_wmt);
++      transform_later(store_new_wmt);
+ 
+       // adding prefetches
+       pf_phi_abio->init_req( fall_in_path, i_o );
+@@ -704,9 +745,9 @@
+       for ( uint i = 0; i < lines; i++ ) {
+         prefetch_adr = new (C, 4) AddPNode( old_pf_wm, new_pf_wmt, 
+                                             _igvn.MakeConX(distance) );
+-        _igvn.register_new_node_with_optimizer(prefetch_adr);
++        transform_later(prefetch_adr);
+         prefetch = new (C, 3) PrefetchWriteNode( i_o, prefetch_adr );
+-        _igvn.register_new_node_with_optimizer(prefetch);
++        transform_later(prefetch);
+         distance += step_size;
+         i_o = prefetch;
+       }
+@@ -718,9 +759,9 @@
+       pf_phi_rawmem->init_req( fall_in_path, contended_phi_rawmem );
+       pf_phi_rawmem->init_req( pf_path, store_new_wmt );
+ 
+-      _igvn.register_new_node_with_optimizer(pf_region);
+-      _igvn.register_new_node_with_optimizer(pf_phi_rawmem);
+-      _igvn.register_new_node_with_optimizer(pf_phi_abio);
++      transform_later(pf_region);
++      transform_later(pf_phi_rawmem);
++      transform_later(pf_phi_abio);
+ 
+       needgc_false = pf_region;
+       contended_phi_rawmem = pf_phi_rawmem;
+@@ -736,14 +777,14 @@
+       for ( uint i = 0; i < lines; i++ ) {
+         prefetch_adr = new (C, 4) AddPNode( old_eden_top, new_eden_top, 
+                                             _igvn.MakeConX(distance) );
+-        _igvn.register_new_node_with_optimizer(prefetch_adr);
++        transform_later(prefetch_adr);
+         prefetch = new (C, 3) PrefetchWriteNode( i_o, prefetch_adr );
+         // Do not let it float too high, since if eden_top == eden_end, 
+         // both might be null.
+         if( i == 0 ) { // Set control for first prefetch, next follows it
+           prefetch->init_req(0, needgc_false);
+         }
+-        _igvn.register_new_node_with_optimizer(prefetch);
++        transform_later(prefetch);
+         distance += step_size;
+         i_o = prefetch;
+       }
+@@ -813,7 +854,7 @@
+   // Make the merge point
+   Node *region = new (C, 3) RegionNode(3);
+   
+-  Node *bol = _igvn.register_new_node_with_optimizer(new (C, 2) BoolNode(flock,BoolTest::ne));
++  Node *bol = transform_later(new (C, 2) BoolNode(flock,BoolTest::ne));
+   Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
+   // Optimize test; set region slot 2
+   Node *slow_path = opt_iff(region,iff);
+@@ -834,20 +875,20 @@
+   // disconnect fall-through projection from call and create a new one
+   // hook up users of fall-through projection to region
+   Node *slow_ctrl = _fallthroughproj->clone();
+-  _igvn.register_new_node_with_optimizer(slow_ctrl);
++  transform_later(slow_ctrl);
+   _igvn.hash_delete(_fallthroughproj);
+   _fallthroughproj->disconnect_inputs(NULL);
+   region->init_req(1, slow_ctrl);
+   // region inputs are now complete
+-  _igvn.register_new_node_with_optimizer(region);
++  transform_later(region);
+   _igvn.subsume_node(_fallthroughproj, region);
+ 
+   // create a Phi for the memory state
+   Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+-  Node *memproj = _igvn.register_new_node_with_optimizer( new (C, 1) ProjNode(call, TypeFunc::Memory) );
++  Node *memproj = transform_later( new (C, 1) ProjNode(call, TypeFunc::Memory) );
+   mem_phi->init_req(1, memproj );
+   mem_phi->init_req(2, mem);
+-  _igvn.register_new_node_with_optimizer(mem_phi);
++  transform_later(mem_phi);
+     _igvn.hash_delete(_memproj_fallthrough);
+   _igvn.subsume_node(_memproj_fallthrough, mem_phi);
+ 
+@@ -874,8 +915,8 @@
+   RegionNode *region = new (C, 3) RegionNode(3);
+ 
+   FastUnlockNode *funlock = new (C, 3) FastUnlockNode( ctrl, obj, box );
+-  funlock = _igvn.register_new_node_with_optimizer( funlock )->as_FastUnlock();
+-  Node *bol = _igvn.register_new_node_with_optimizer(new (C, 2) BoolNode(funlock,BoolTest::ne));
++  funlock = transform_later( funlock )->as_FastUnlock();
++  Node *bol = transform_later(new (C, 2) BoolNode(funlock,BoolTest::ne));
+   Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
+   // Optimize test; set region slot 2
+   Node *slow_path = opt_iff(region,iff);
+@@ -892,20 +933,20 @@
+   // disconnect fall-through projection from call and create a new one
+   // hook up users of fall-through projection to region
+   Node *slow_ctrl = _fallthroughproj->clone();
+-  _igvn.register_new_node_with_optimizer(slow_ctrl);
++  transform_later(slow_ctrl);
+   _igvn.hash_delete(_fallthroughproj);
+   _fallthroughproj->disconnect_inputs(NULL);
+   region->init_req(1, slow_ctrl);
+   // region inputs are now complete
+-  _igvn.register_new_node_with_optimizer(region);
++  transform_later(region);
+   _igvn.subsume_node(_fallthroughproj, region);
+ 
+   // create a Phi for the memory state
+   Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+-  Node *memproj = _igvn.register_new_node_with_optimizer( new(C, 1) ProjNode(call, TypeFunc::Memory) );
++  Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
+   mem_phi->init_req(1, memproj );
+   mem_phi->init_req(2, mem);
+-  _igvn.register_new_node_with_optimizer(mem_phi);
++  transform_later(mem_phi);
+     _igvn.hash_delete(_memproj_fallthrough);
+   _igvn.subsume_node(_memproj_fallthrough, mem_phi);
+ 
+@@ -952,4 +993,3 @@
+   _igvn.optimize();
+   return false;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/macro.hpp openjdk/hotspot/src/share/vm/opto/macro.hpp
+--- openjdk6/hotspot/src/share/vm/opto/macro.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/macro.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)macro.hpp	1.10 07/07/02 18:45:21 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -43,11 +40,22 @@
+   Node* basic_plus_adr(Node* base, int offset) {
+     return (offset == 0)? base: basic_plus_adr(base, MakeConX(offset));
+   }
++  Node* basic_plus_adr(Node* base, Node* ptr, int offset) {
++    return (offset == 0)? ptr: basic_plus_adr(base, ptr, MakeConX(offset));
++  }
+   Node* basic_plus_adr(Node* base, Node* offset) {
+-    Node* adr = new (C, 4) AddPNode(base, base, offset);
+-    _igvn.register_new_node_with_optimizer(adr);
+-    return adr;
++    return basic_plus_adr(base, base, offset);
++  }
++  Node* basic_plus_adr(Node* base, Node* ptr, Node* offset) {
++    Node* adr = new (C, 4) AddPNode(base, ptr, offset);
++    return transform_later(adr);
++  }
++  Node* transform_later(Node* n) {
++    // equivalent to _gvn.transform in GraphKit, Ideal, etc.
++    _igvn.register_new_node_with_optimizer(n);
++    return n;
+   }
++  void set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr);
+   Node* make_load( Node* ctl, Node* mem, Node* base, int offset,
+                    const Type* value_type, BasicType bt);
+   Node* make_store(Node* ctl, Node* mem, Node* base, int offset,
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/matcher.cpp openjdk/hotspot/src/share/vm/opto/matcher.cpp
+--- openjdk6/hotspot/src/share/vm/opto/matcher.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/matcher.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)matcher.cpp	1.386 07/05/05 17:06:19 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -272,6 +269,8 @@
+   find_shared( C->root() );
+   find_shared( C->top() );
+ 
++  C->print_method("Before Matching", 2);
++
+   // Swap out to old-space; emptying new-space 
+   Arena *old = C->node_arena()->move_contents(C->old_arena());
+ 
+@@ -1803,6 +1802,16 @@
+                   shift->in(2)->get_int() <= 3 ) { 
+                 set_visited(shift);  // Flag as visited now
+                 mstack.push(shift->in(2), Visit);
++#ifdef _LP64
++                // Allow Matcher to match the rule which bypass
++                // ConvI2L operation for an array index on LP64
++                // if the index value is positive.
++                if( shift->in(1)->Opcode() == Op_ConvI2L &&
++                    shift->in(1)->as_Type()->type()->is_long()->_lo >= 0 ) {
++                  set_visited(shift->in(1));  // Flag as visited now
++                  mstack.push(shift->in(1)->in(1), Pre_Visit);
++                } else
++#endif
+                 mstack.push(shift->in(1), Pre_Visit);
+               } else {
+                 mstack.push(shift, Pre_Visit);
+@@ -2112,4 +2121,3 @@
+       _kids[i]->dump(depth+1);
+ }
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/matcher.hpp openjdk/hotspot/src/share/vm/opto/matcher.hpp
+--- openjdk6/hotspot/src/share/vm/opto/matcher.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/matcher.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)matcher.hpp	1.187 07/05/05 17:06:19 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -234,6 +231,11 @@
+   // Vector ideal reg
+   static const uint vector_ideal_reg(void);
+ 
++  // Used to determine a "low complexity" 64-bit constant.  (Zero is simple.)
++  // The standard of comparison is one (StoreL ConL) vs. two (StoreI ConI).
++  // Depends on the details of 64-bit constant generation on the CPU.
++  static const bool isSimpleConstant64(jlong con);
++
+   // These calls are all generated by the ADLC
+ 
+   // TRUE - grows up, FALSE - grows down (Intel)
+@@ -321,6 +323,13 @@
+   // Is this branch offset small enough to be addressed by a short branch?
+   bool is_short_branch_offset(int offset);
+ 
++  // Optional scaling for the parameter to the ClearArray/CopyArray node.
++  static const bool init_array_count_is_in_bytes;
++
++  // Threshold small size (in bytes) for a ClearArray/CopyArray node.
++  // Anything this size or smaller may get converted to discrete scalar stores.
++  static const int init_array_short_size;
++
+   // Should the Matcher clone shifts on addressing modes, expecting them to
+   // be subsumed into complex addressing expressions or compute them into
+   // registers?  True for Intel but false for most RISCs
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/memnode.cpp openjdk/hotspot/src/share/vm/opto/memnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/memnode.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/memnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)memnode.cpp	1.238 08/06/19 10:10:54 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -43,7 +40,7 @@
+ }
+ 
+ #ifndef PRODUCT
+-void MemNode::dump_spec() const {
++void MemNode::dump_spec(outputStream *st) const {
+   if (in(Address) == NULL)  return; // node is dead
+ #ifndef ASSERT
+   // fake the missing field
+@@ -51,37 +48,37 @@
+   if (in(Address) != NULL)
+     _adr_type = in(Address)->bottom_type()->isa_ptr();
+ #endif
+-  dump_adr_type(this, _adr_type);
++  dump_adr_type(this, _adr_type, st);
+ 
+   Compile* C = Compile::current();
+   if( C->alias_type(_adr_type)->is_volatile() )
+-    tty->print(" Volatile!");
++    st->print(" Volatile!");
+ }
+ 
+-void MemNode::dump_adr_type(const Node* mem, const TypePtr* adr_type) {
+-  tty->print(" @");
++void MemNode::dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st) {
++  st->print(" @");
+   if (adr_type == NULL) {
+-    tty->print("NULL");
++    st->print("NULL");
+   } else {
+-    adr_type->dump();
++    adr_type->dump_on(st);
+     Compile* C = Compile::current();
+     Compile::AliasType* atp = NULL;
+     if (C->have_alias_type(adr_type))  atp = C->alias_type(adr_type);
+     if (atp == NULL)
+-      tty->print(", idx=?\?;");
++      st->print(", idx=?\?;");
+     else if (atp->index() == Compile::AliasIdxBot)
+-      tty->print(", idx=Bot;");
++      st->print(", idx=Bot;");
+     else if (atp->index() == Compile::AliasIdxTop)
+-      tty->print(", idx=Top;");
++      st->print(", idx=Top;");
+     else if (atp->index() == Compile::AliasIdxRaw)
+-      tty->print(", idx=Raw;");
++      st->print(", idx=Raw;");
+     else {
+       ciField* field = atp->field();
+       if (field) {
+-        tty->print(", name=");
+-        field->print_name_on(tty);
++        st->print(", name=");
++        field->print_name_on(st);
+       }
+-      tty->print(", idx=%d;", atp->index());
++      st->print(", idx=%d;", atp->index());
+     }
+   }
+ }
+@@ -111,6 +108,20 @@
+   // Avoid independent memory operations
+   Node* old_mem = mem;
+ 
++  if (mem->is_Proj() && mem->in(0)->is_Initialize()) {
++    InitializeNode* init = mem->in(0)->as_Initialize();
++    if (init->is_complete()) {  // i.e., after macro expansion
++      const TypePtr* tp = t_adr->is_ptr();
++      uint alias_idx = phase->C->get_alias_index(tp);
++      // Free this slice from the init.  It was hooked, temporarily,
++      // by GraphKit::set_output_for_allocation.
++      if (alias_idx > Compile::AliasIdxRaw) {
++        mem = init->memory(alias_idx);
++        // ...but not with the raw-pointer slice.
++      }
++    }
++  }
++
+   if (mem->is_MergeMem()) {
+     MergeMemNode* mmem = mem->as_MergeMem();
+     const TypePtr *tp = t_adr->is_ptr(); 
+@@ -167,6 +178,65 @@
+   return NULL;
+ }
+ 
++// Helper function for proving some simple control dominations.
++// Attempt to prove that control input 'dom' dominates (or equals) 'sub'.
++// Already assumes that 'dom' is available at 'sub', and that 'sub'
++// is not a constant (dominated by the method's StartNode).
++// Used by MemNode::find_previous_store to prove that the
++// control input of a memory operation predates (dominates)
++// an allocation it wants to look past.
++bool MemNode::detect_dominating_control(Node* dom, Node* sub) {
++  if (dom == NULL)      return false;
++  if (dom->is_Proj())   dom = dom->in(0);
++  if (dom->is_Start())  return true; // anything inside the method
++  if (dom->is_Root())   return true; // dom 'controls' a constant
++  int cnt = 20;                      // detect cycle or too much effort
++  while (sub != NULL) {              // walk 'sub' up the chain to 'dom'
++    if (--cnt < 0)   return false;   // in a cycle or too complex
++    if (sub == dom)  return true;
++    if (sub->is_Start())  return false;
++    if (sub->is_Root())   return false;
++    Node* up = sub->in(0);
++    if (sub == up && sub->is_Region()) {
++      for (uint i = 1; i < sub->req(); i++) {
++        Node* in = sub->in(i);
++        if (in != NULL && !in->is_top() && in != sub) {
++          up = in; break;            // take any path on the way up to 'dom'
++        }
++      }
++    }
++    if (sub == up)  return false;    // some kind of tight cycle
++    sub = up;
++  }
++  return false;
++}
++
++//---------------------detect_ptr_independence---------------------------------
++// Used by MemNode::find_previous_store to prove that two base
++// pointers are never equal.
++// The pointers are accompanied by their associated allocations,
++// if any, which have been previously discovered by the caller.
++bool MemNode::detect_ptr_independence(Node* p1, AllocateNode* a1,
++                                      Node* p2, AllocateNode* a2,
++                                      PhaseTransform* phase) {
++  // Attempt to prove that these two pointers cannot be aliased.
++  // They may both manifestly be allocations, and they should differ.
++  // Or, if they are not both allocations, they can be distinct constants.
++  // Otherwise, one is an allocation and the other a pre-existing value.
++  if (a1 == NULL && a2 == NULL) {           // neither an allocation
++    return (p1 != p2) && p1->is_Con() && p2->is_Con();
++  } else if (a1 != NULL && a2 != NULL) {    // both allocations
++    return (a1 != a2);
++  } else if (a1 != NULL) {                  // one allocation a1
++    // (Note:  p2->is_Con implies p2->in(0)->is_Root, which dominates.)
++    return detect_dominating_control(p2->in(0), a1->in(0));
++  } else { //(a2 != NULL)                   // one allocation a2
++    return detect_dominating_control(p1->in(0), a2->in(0));
++  }
++  return false;
++}
++
++
+ // The logic for reordering loads and stores uses four steps:
+ // (a) Walk carefully past stores and initializations which we
+ //     can prove are independent of this load.
+@@ -218,6 +288,15 @@
+           continue;           // (a) advance through independent store memory
+         }
+       }
++      if (st_base != base &&
++          detect_ptr_independence(base, alloc,
++                                  st_base,
++                                  AllocateNode::Ideal_allocation(st_base, phase),
++                                  phase)) {
++        // Success:  The bases are provably independent.
++        mem = mem->in(MemNode::Memory);
++        continue;           // (a) advance through independent store memory
++      }
+ 
+       // (b) At this point, if the bases or offsets do not agree, we lose,
+       // since we have not managed to prove 'this' and 'mem' independent.
+@@ -225,6 +304,41 @@
+         return mem;         // let caller handle steps (c), (d)
+       }
+ 
++    } else if (mem->is_Proj() && mem->in(0)->is_Initialize()) {
++      InitializeNode* st_init = mem->in(0)->as_Initialize();
++      AllocateNode*  st_alloc = st_init->allocation();
++      if (st_alloc == NULL)
++        break;              // something degenerated
++      bool known_identical = false;
++      bool known_independent = false;
++      if (alloc == st_alloc)
++        known_identical = true;
++      else if (alloc != NULL)
++        known_independent = true;
++      else if (ctrl != NULL &&
++               detect_dominating_control(ctrl, st_alloc->in(0)))
++        known_independent = true;
++
++      if (known_independent) {
++        // The bases are provably independent: Either they are
++        // manifestly distinct allocations, or else the control
++        // of this load dominates the store's allocation.
++        int alias_idx = phase->C->get_alias_index(adr_type());
++        if (alias_idx == Compile::AliasIdxRaw) {
++          mem = st_alloc->in(TypeFunc::Memory);
++        } else {
++          mem = st_init->memory(alias_idx);
++        }
++        continue;           // (a) advance through independent store memory
++      }
++
++      // (b) at this point, if we are not looking at a store initializing
++      // the same allocation we are loading from, we lose.
++      if (known_identical) {
++        // From caller, can_see_stored_value will consult find_captured_store.
++        return mem;         // let caller handle steps (c), (d)
++      }
++
+     }
+ 
+     // Unless there is an explicit 'continue', we must bail out here,
+@@ -460,11 +574,11 @@
+ }
+ 
+ #ifndef PRODUCT
+-void LoadNode::dump_spec() const { 
+-  MemNode::dump_spec();
++void LoadNode::dump_spec(outputStream *st) const {
++  MemNode::dump_spec(st);
+   if( !Verbose && !WizardMode ) {
+     // standard dump does this in Verbose and WizardMode
+-    tty->print(" #"); _type->dump();
++    st->print(" #"); _type->dump_on(st);
+   }
+ }
+ #endif
+@@ -520,18 +634,67 @@
+ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
+   Node* ld_adr = in(MemNode::Address);
+ 
++  // Loop around twice in the case Load -> Initialize -> Store.
++  // (See PhaseIterGVN::add_users_to_worklist, which knows about this case.)
++  for (int trip = 0; trip <= 1; trip++) {
++
+   if (st->is_Store()) {
+     Node* st_adr = st->in(MemNode::Address);
+     if (!phase->eqv(st_adr, ld_adr)) {
+-      return NULL;
++        // Try harder before giving up...  Match raw and non-raw pointers.
++        intptr_t st_off = 0;
++        AllocateNode* alloc = AllocateNode::Ideal_allocation(st_adr, phase, st_off);
++        if (alloc == NULL)       return NULL;
++        intptr_t ld_off = 0;
++        AllocateNode* allo2 = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off);
++        if (alloc != allo2)      return NULL;
++        if (ld_off != st_off)    return NULL;
++        // At this point we have proven something like this setup:
++        //  A = Allocate(...)
++        //  L = LoadQ(,  AddP(CastPP(, A.Parm),, #Off))
++        //  S = StoreQ(, AddP(,        A.Parm  , #Off), V)
++        // (Actually, we haven't yet proven the Q's are the same.)
++        // In other words, we are loading from a casted version of
++        // the same pointer-and-offset that we stored to.
++        // Thus, we are able to replace L by V.
+     }
+     // Now prove that we have a LoadQ matched to a StoreQ, for some Q.
+-    if (store_Opcode() != st->Opcode()) {
++      if (store_Opcode() != st->Opcode())
+       return NULL;
+-    }
+     return st->in(MemNode::ValueIn);
+   }
+ 
++    intptr_t offset = 0;  // scratch
++
++    // A load from a freshly-created object always returns zero.
++    // (This can happen after LoadNode::Ideal resets the load's memory input
++    // to find_captured_store, which returned InitializeNode::zero_memory.)
++    if (st->is_Proj() && st->in(0)->is_Allocate() &&
++        st->in(0) == AllocateNode::Ideal_allocation(ld_adr, phase, offset) &&
++        offset >= st->in(0)->as_Allocate()->minimum_header_size()) {
++      // return a zero value for the load's basic type
++      // (This is one of the few places where a generic PhaseTransform
++      // can create new nodes.  Think of it as lazily manifesting
++      // virtually pre-existing constants.)
++      return phase->zerocon(memory_type());
++    }
++
++    // A load from an initialization barrier can match a captured store.
++    if (st->is_Proj() && st->in(0)->is_Initialize()) {
++      InitializeNode* init = st->in(0)->as_Initialize();
++      AllocateNode* alloc = init->allocation();
++      if (alloc != NULL &&
++          alloc == AllocateNode::Ideal_allocation(ld_adr, phase, offset)) {
++        // examine a captured store value
++        st = init->find_captured_store(offset, memory_size(), phase);
++        if (st != NULL)
++          continue;             // take one more trip around
++      }
++    }
++
++    break;
++  }
++
+   return NULL;
+ }
+ 
+@@ -563,6 +726,8 @@
+ //------------------------------Ideal------------------------------------------
+ // If the load is from Field memory and the pointer is non-null, we can
+ // zero out the control input.
++// If the offset is constant and the base is an object allocation,
++// try to hook me up to the exact initializing store.
+ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+   Node* p = MemNode::Ideal_common(phase, can_reshape);
+   if (p)  return (p == NodeSentinel) ? NULL : p;
+@@ -578,16 +743,19 @@
+     set_req(MemNode::Control,ctrl);
+   }
+ 
+-  // Check for useless memory edge in some common special cases
+-  if( in(MemNode::Control) ) {
+-    Node *adr = address->is_AddP() ? address->in(AddPNode::Base) : address;
+-    if( adr->is_Proj() && adr->as_Proj()->_con == TypeFunc::Parms && 
+-        adr->in(0)->is_Start() && phase->type(adr)->is_ptr()->_ptr == TypePtr::NotNull ) {
++  // Check for useless control edge in some common special cases
++  if (in(MemNode::Control) != NULL) {
++    intptr_t ignore = 0;
++    Node*    base   = AddPNode::Ideal_base_and_offset(address, phase, ignore);
++    if (base != NULL
++        && phase->type(base)->higher_equal(TypePtr::NOTNULL)
++        && detect_dominating_control(base->in(0), phase->C->start())) {
++      // A method-invariant, non-null address (constant or 'this' argument).
+       set_req(MemNode::Control, NULL);
+     }
+   }
+ 
+-  // Check for prior array store with a different offset; make Load
++  // Check for prior store with a different base or offset; make Load
+   // independent.  Skip through any number of them.  Bail out if the stores
+   // are in an endless dead cycle and report no progress.  This is a key
+   // transform for Reflection.  However, if after skipping through the Stores
+@@ -794,7 +962,14 @@
+     }
+   }
+ 
+-  // (If loading from a freshly-allocated object, could produce zero here.)
++  // If we are loading from a freshly-allocated object, produce a zero,
++  // if the load is provably beyond the header of the object.
++  // (Also allow a variable load from a fresh array to produce zero.)
++  if (ReduceFieldZeroing) {
++    Node* value = can_see_stored_value(mem,phase);
++    if (value != NULL && value->is_Con())
++      return value->bottom_type();
++  }
+ 
+   return _type;
+ }
+@@ -974,6 +1149,13 @@
+       // according to the element type's subclassing.
+       return TypeKlassPtr::make(tkls->ptr(), elem, 0/*offset*/);
+     }
++    if( klass->is_instance_klass() && tkls->klass_is_exact() &&
++        (uint)tkls->offset() == Klass::super_offset_in_bytes() + sizeof(oopDesc)) {
++      ciKlass* sup = klass->as_instance_klass()->super();
++      // The field is Klass::_super.  Return its (constant) value.
++      // (Folds up the 2nd indirection in aClassConstant.getSuperClass().)
++      return sup ? TypeKlassPtr::make(sup) : TypePtr::NULL_PTR;
++    }
+   }
+ 
+   // Bailout case
+@@ -1082,8 +1264,8 @@
+   }
+ 
+   return this;
+-}
+ 
++}
+ //=============================================================================
+ //---------------------------StoreNode::make-----------------------------------
+ // Polymorphic factory method:
+@@ -1126,6 +1308,8 @@
+ 
+ //------------------------------Ideal------------------------------------------
+ // Change back-to-back Store(, p, x) -> Store(m, p, y) to Store(m, p, x).
++// When a store immediately follows a relevant allocation/initialization,
++// try to capture it into the initialization, or hoist it above.
+ Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+   Node* p = MemNode::Ideal_common(phase, can_reshape);
+   if (p)  return (p == NodeSentinel) ? NULL : p;
+@@ -1135,7 +1319,7 @@
+ 
+   // Back-to-back stores to same address?  Fold em up.
+   // Generally unsafe if I have intervening uses...
+-  if (can_reshape && mem->is_Store() && phase->eqv( mem->in(MemNode::Address), address )) {
++  if (mem->is_Store() && phase->eqv_uncast(mem->in(MemNode::Address), address)) {
+     // Looking at a dead closed cycle of memory?
+     assert(mem != mem->in(MemNode::Memory), "dead loop in StoreNode::Ideal");
+ 
+@@ -1163,6 +1347,24 @@
+     }
+   }
+ 
++  // Capture an unaliased, unconditional, simple store into an initializer.
++  // Or, if it is independent of the allocation, hoist it above the allocation.
++  if (ReduceFieldZeroing && /*can_reshape &&*/
++      mem->is_Proj() && mem->in(0)->is_Initialize()) {
++    InitializeNode* init = mem->in(0)->as_Initialize();
++    intptr_t offset = init->can_capture_store(this, phase);
++    if (offset > 0) {
++      Node* moved = init->capture_store(this, offset, phase);
++      // If the InitializeNode captured me, it made a raw copy of me,
++      // and I need to disappear.
++      if (moved != NULL) {
++        // %%% hack to ensure that Ideal returns a new node:
++        mem = MergeMemNode::make(phase->C, mem);
++        return mem;             // fold me away
++      }
++    }
++  }
++
+   return NULL;                  // No further progress
+ }
+ 
+@@ -1181,6 +1383,7 @@
+ //------------------------------Identity---------------------------------------
+ // Remove redundant stores:
+ //   Store(m, p, Load(m, p)) changes to m.
++//   Store(, p, x) -> Store(m, p, x) changes to Store(m, p, x).
+ Node *StoreNode::Identity( PhaseTransform *phase ) {
+   Node* mem = in(MemNode::Memory);
+   Node* adr = in(MemNode::Address);
+@@ -1188,12 +1391,42 @@
+ 
+   // Load then Store?  Then the Store is useless
+   if (val->is_Load() &&
+-      val->as_Load()->memory_size() == this->memory_size() &&
+-      phase->eqv( val->in(MemNode::Address), adr ) &&
+-      phase->eqv( val->in(MemNode::Memory ), mem )) {
++      phase->eqv_uncast( val->in(MemNode::Address), adr ) &&
++      phase->eqv_uncast( val->in(MemNode::Memory ), mem ) &&
++      val->as_Load()->store_Opcode() == Opcode()) {
++    return mem;
++  }
++
++  // Two stores in a row of the same value?
++  if (mem->is_Store() &&
++      phase->eqv_uncast( mem->in(MemNode::Address), adr ) &&
++      phase->eqv_uncast( mem->in(MemNode::ValueIn), val ) &&
++      mem->Opcode() == Opcode()) {
++    return mem;
++  }
++
++  // Store of zero anywhere into a freshly-allocated object?
++  // Then the store is useless.
++  // (It must already have been captured by the InitializeNode.)
++  if (ReduceFieldZeroing && phase->type(val)->is_zero_type()) {
++    // a newly allocated object is already all-zeroes everywhere
++    if (mem->is_Proj() && mem->in(0)->is_Allocate()) {
+     return mem;
+   }
+ 
++    // the store may also apply to zero-bits in an earlier object
++    Node* prev_mem = find_previous_store(phase);
++    // Steps (a), (b):  Walk past independent stores to find an exact match.
++    if (prev_mem != NULL) {
++      Node* prev_val = can_see_stored_value(prev_mem, phase);
++      if (prev_val != NULL && phase->eqv(prev_val, val)) {
++        // prev_val and val might differ by a cast; it would be good
++        // to keep the more informative of the two.
++        return mem;
++      }
++    }
++  }
++
+   return this;
+ }
+ 
+@@ -1320,16 +1553,9 @@
+ 
+ //------------------------------Value-----------------------------------------
+ const Type *StoreCMNode::Value( PhaseTransform *phase ) const {
+-  // Either input is TOP ==> the result is TOP
+-  const Type *t = phase->type( in(MemNode::Memory) );
+-  if( t == Type::TOP ) return Type::TOP;
+-  t = phase->type( in(MemNode::Address) );
+-  if( t == Type::TOP ) return Type::TOP;
+-  t = phase->type( in(MemNode::ValueIn) );
+-  if( t == Type::TOP ) return Type::TOP;
+   // If extra input is TOP ==> the result is TOP
+-  t = phase->type( in(MemNode::OopStore) );
+-  if( t == Type::TOP ) return Type::TOP;
++  const Type *t1 = phase->type( in(MemNode::OopStore) );
++  if( t1 == Type::TOP ) return Type::TOP;
+ 
+   return StoreNode::Value( phase );
+ }
+@@ -1376,16 +1602,20 @@
+ //------------------------------Idealize---------------------------------------
+ // Clearing a short array is faster with stores
+ Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape){
+-  const TypeInt *t = phase->type(in(2))->isa_int();
+-  if( !t ) return NULL;
+-  if( !t->is_con() ) return NULL;
+-  int con = t->get_con();       // Length is in doublewords
+-  // Length too long; use fast hardware clear
+-  if( con > 8 ) return NULL;
++  const int unit = BytesPerLong;
++  const TypeX* t = phase->type(in(2))->isa_intptr_t();
++  if (!t)  return NULL;
++  if (!t->is_con())  return NULL;
++  intptr_t raw_count = t->get_con();
++  intptr_t size = raw_count;
++  if (!Matcher::init_array_count_is_in_bytes) size *= unit;
+   // Clearing nothing uses the Identity call.
+   // Negative clears are possible on dead ClearArrays
+   // (see jck test stmt114.stmt11402.val).
+-  if( con <= 0 ) return NULL;
++  if (size <= 0 || size % unit != 0)  return NULL;
++  intptr_t count = size / unit;
++  // Length too long; use fast hardware clear
++  if (size > Matcher::init_array_short_size)  return NULL;
+   Node *mem = in(1);
+   if( phase->type(mem)==Type::TOP ) return NULL;
+   Node *adr = in(3);
+@@ -1402,8 +1632,8 @@
+   Node *zero = phase->makecon(TypeLong::ZERO);
+   Node *off  = phase->MakeConX(BytesPerLong);
+   mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero);
+-  con--;
+-  while( con-- ) {
++  count--;
++  while( count-- ) {
+     mem = phase->transform(mem);
+     adr = phase->transform(new (phase->C, 4) AddPNode(base,adr,off));
+     mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero);
+@@ -1421,8 +1651,7 @@
+   intptr_t offset = start_offset;
+ 
+   int unit = BytesPerLong;
+-
+-  if (unit == BytesPerLong && (offset % BytesPerLong) != 0) {
++  if ((offset % unit) != 0) {
+     Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(offset));
+     adr = phase->transform(adr);
+     const TypePtr* atp = TypeRawPtr::BOTTOM;
+@@ -1433,20 +1662,60 @@
+   assert((offset % unit) == 0, "");
+ 
+   // Initialize the remaining stuff, if any, with a ClearArray.
+-  Node* zbase = phase->MakeConX(offset);
+-  Node* zsize = phase->transform( new (C, 3) SubXNode(end_offset, zbase) );
+-  Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT);
++  return clear_memory(ctl, mem, dest, phase->MakeConX(offset), end_offset, phase);
++}
++
++Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest,
++                                   Node* start_offset,
++                                   Node* end_offset,
++                                   PhaseGVN* phase) {
++  Compile* C = phase->C;
++  int unit = BytesPerLong;
++  Node* zbase = start_offset;
++  Node* zend  = end_offset;
+ 
+   // Scale to the unit required by the CPU:
++  if (!Matcher::init_array_count_is_in_bytes) {
+   Node* shift = phase->intcon(exact_log2(unit));
+-  zsize = phase->transform( new (C, 3) URShiftXNode(zsize, shift) );
++    zbase = phase->transform( new(C,3) URShiftXNode(zbase, shift) );
++    zend  = phase->transform( new(C,3) URShiftXNode(zend,  shift) );
++  }
++
++  Node* zsize = phase->transform( new(C,3) SubXNode(zend, zbase) );
++  Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT);
+ 
+   // Bulk clear double-words
+-  Node* adr = phase->transform( new (C, 4) AddPNode(dest, dest, zbase) );
++  Node* adr = phase->transform( new(C,4) AddPNode(dest, dest, start_offset) );
+   mem = new (C, 4) ClearArrayNode(ctl, mem, zsize, adr);
+   return phase->transform(mem);
+ }
+ 
++Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest,
++                                   intptr_t start_offset,
++                                   intptr_t end_offset,
++                                   PhaseGVN* phase) {
++  Compile* C = phase->C;
++  assert((end_offset % BytesPerInt) == 0, "odd end offset");
++  intptr_t done_offset = end_offset;
++  if ((done_offset % BytesPerLong) != 0) {
++    done_offset -= BytesPerInt;
++  }
++  if (done_offset > start_offset) {
++    mem = clear_memory(ctl, mem, dest,
++                       start_offset, phase->MakeConX(done_offset), phase);
++  }
++  if (done_offset < end_offset) { // emit the final 32-bit store
++    Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(done_offset));
++    adr = phase->transform(adr);
++    const TypePtr* atp = TypeRawPtr::BOTTOM;
++    mem = StoreNode::make(C, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT);
++    mem = phase->transform(mem);
++    done_offset += BytesPerInt;
++  }
++  assert(done_offset == end_offset, "");
++  return mem;
++}
++
+ //=============================================================================
+ // Do we match on this edge? No memory edges
+ uint StrCompNode::match_edge(uint idx) const {
+@@ -1489,6 +1758,7 @@
+   case Op_MemBarRelease:   return new(C, len) MemBarReleaseNode(C,  atp, pn);
+   case Op_MemBarVolatile:  return new(C, len) MemBarVolatileNode(C, atp, pn);
+   case Op_MemBarCPUOrder:  return new(C, len) MemBarCPUOrderNode(C, atp, pn);
++  case Op_Initialize:      return new(C, len) InitializeNode(C,     atp, pn);
+   default:                 ShouldNotReachHere(); return NULL;
+   }
+ }
+@@ -1521,7 +1791,900 @@
+   return NULL;
+ }
+ 
+-//=============================================================================
++//===========================InitializeNode====================================
++// SUMMARY:
++// This node acts as a memory barrier on raw memory, after some raw stores.
++// The 'cooked' oop value feeds from the Initialize, not the Allocation.
++// The Initialize can 'capture' suitably constrained stores as raw inits.
++// It can coalesce related raw stores into larger units (called 'tiles').
++// It can avoid zeroing new storage for memory units which have raw inits.
++// At macro-expansion, it is marked 'complete', and does not optimize further.
++//
++// EXAMPLE:
++// The object 'new short[2]' occupies 16 bytes in a 32-bit machine.
++//   ctl = incoming control; mem* = incoming memory
++// (Note:  A star * on a memory edge denotes I/O and other standard edges.)
++// First allocate uninitialized memory and fill in the header:
++//   alloc = (Allocate ctl mem* 16 #short[].klass ...)
++//   ctl := alloc.Control; mem* := alloc.Memory*
++//   rawmem = alloc.Memory; rawoop = alloc.RawAddress
++// Then initialize to zero the non-header parts of the raw memory block:
++//   init = (Initialize alloc.Control alloc.Memory* alloc.RawAddress)
++//   ctl := init.Control; mem.SLICE(#short[*]) := init.Memory
++// After the initialize node executes, the object is ready for service:
++//   oop := (CheckCastPP init.Control alloc.RawAddress #short[])
++// Suppose its body is immediately initialized as {1,2}:
++//   store1 = (StoreC init.Control init.Memory (+ oop 12) 1)
++//   store2 = (StoreC init.Control store1      (+ oop 14) 2)
++//   mem.SLICE(#short[*]) := store2
++//
++// DETAILS:
++// An InitializeNode collects and isolates object initialization after
++// an AllocateNode and before the next possible safepoint.  As a
++// memory barrier (MemBarNode), it keeps critical stores from drifting
++// down past any safepoint or any publication of the allocation.
++// Before this barrier, a newly-allocated object may have uninitialized bits.
++// After this barrier, it may be treated as a real oop, and GC is allowed.
++//
++// The semantics of the InitializeNode include an implicit zeroing of
++// the new object from object header to the end of the object.
++// (The object header and end are determined by the AllocateNode.)
++//
++// Certain stores may be added as direct inputs to the InitializeNode.
++// These stores must update raw memory, and they must be to addresses
++// derived from the raw address produced by AllocateNode, and with
++// a constant offset.  They must be ordered by increasing offset.
++// The first one is at in(RawStores), the last at in(req()-1).
++// Unlike most memory operations, they are not linked in a chain,
++// but are displayed in parallel as users of the rawmem output of
++// the allocation.
++//
++// (See comments in InitializeNode::capture_store, which continue
++// the example given above.)
++//
++// When the associated Allocate is macro-expanded, the InitializeNode
++// may be rewritten to optimize collected stores.  A ClearArrayNode
++// may also be created at that point to represent any required zeroing.
++// The InitializeNode is then marked 'complete', prohibiting further
++// capturing of nearby memory operations.
++//
++// During macro-expansion, all captured initializations which store
++// constant values of 32 bits or smaller are coalesced (if advantagous)
++// into larger 'tiles' 32 or 64 bits.  This allows an object to be
++// initialized in fewer memory operations.  Memory words which are
++// covered by neither tiles nor non-constant stores are pre-zeroed
++// by explicit stores of zero.  (The code shape happens to do all
++// zeroing first, then all other stores, with both sequences occurring
++// in order of ascending offsets.)
++//
++// Alternatively, code may be inserted between an AllocateNode and its
++// InitializeNode, to perform arbitrary initialization of the new object.
++// E.g., the object copying intrinsics insert complex data transfers here.
++// The initialization must then be marked as 'complete' disable the
++// built-in zeroing semantics and the collection of initializing stores.
++//
++// While an InitializeNode is incomplete, reads from the memory state
++// produced by it are optimizable if they match the control edge and
++// new oop address associated with the allocation/initialization.
++// They return a stored value (if the offset matches) or else zero.
++// A write to the memory state, if it matches control and address,
++// and if it is to a constant offset, may be 'captured' by the
++// InitializeNode.  It is cloned as a raw memory operation and rewired
++// inside the initialization, to the raw oop produced by the allocation.
++// Operations on addresses which are provably distinct (e.g., to
++// other AllocateNodes) are allowed to bypass the initialization.
++//
++// The effect of all this is to consolidate object initialization
++// (both arrays and non-arrays, both piecewise and bulk) into a
++// single location, where it can be optimized as a unit.
++//
++// Only stores with an offset less than TrackedInitializationLimit words
++// will be considered for capture by an InitializeNode.  This puts a
++// reasonable limit on the complexity of optimized initializations.
++
++//---------------------------InitializeNode------------------------------------
++InitializeNode::InitializeNode(Compile* C, int adr_type, Node* rawoop)
++  : _is_complete(false),
++    MemBarNode(C, adr_type, rawoop)
++{
++  init_class_id(Class_Initialize);
++
++  assert(adr_type == Compile::AliasIdxRaw, "only valid atp");
++  assert(in(RawAddress) == rawoop, "proper init");
++  // Note:  allocation() can be NULL, for secondary initialization barriers
++}
++
++// Since this node is not matched, it will be processed by the
++// register allocator.  Declare that there are no constraints
++// on the allocation of the RawAddress edge.
++const RegMask &InitializeNode::in_RegMask(uint idx) const {
++  // This edge should be set to top, by the set_complete.  But be conservative.
++  if (idx == InitializeNode::RawAddress)
++    return *(Compile::current()->matcher()->idealreg2spillmask[in(idx)->ideal_reg()]);
++  return RegMask::Empty;
++}
++
++Node* InitializeNode::memory(uint alias_idx) {
++  Node* mem = in(Memory);
++  if (mem->is_MergeMem()) {
++    return mem->as_MergeMem()->memory_at(alias_idx);
++  } else {
++    // incoming raw memory is not split
++    return mem;
++  }
++}
++
++bool InitializeNode::is_non_zero() {
++  if (is_complete())  return false;
++  remove_extra_zeroes();
++  return (req() > RawStores);
++}
++
++void InitializeNode::set_complete(PhaseGVN* phase) {
++  assert(!is_complete(), "caller responsibility");
++  _is_complete = true;
++
++  // After this node is complete, it contains a bunch of
++  // raw-memory initializations.  There is no need for
++  // it to have anything to do with non-raw memory effects.
++  // Therefore, tell all non-raw users to re-optimize themselves,
++  // after skipping the memory effects of this initialization.
++  PhaseIterGVN* igvn = phase->is_IterGVN();
++  if (igvn)  igvn->add_users_to_worklist(this);
++}
++
++// convenience function
++// return false if the init contains any stores already
++bool AllocateNode::maybe_set_complete(PhaseGVN* phase) {
++  InitializeNode* init = initialization();
++  if (init == NULL || init->is_complete())  return false;
++  init->remove_extra_zeroes();
++  // for now, if this allocation has already collected any inits, bail:
++  if (init->is_non_zero())  return false;
++  init->set_complete(phase);
++  return true;
++}
++
++void InitializeNode::remove_extra_zeroes() {
++  if (req() == RawStores)  return;
++  Node* zmem = zero_memory();
++  uint fill = RawStores;
++  for (uint i = fill; i < req(); i++) {
++    Node* n = in(i);
++    if (n->is_top() || n == zmem)  continue;  // skip
++    if (fill < i)  set_req(fill, n);          // compact
++    ++fill;
++  }
++  // delete any empty spaces created:
++  while (fill < req()) {
++    del_req(fill);
++  }
++}
++
++// Helper for remembering which stores go with which offsets.
++intptr_t InitializeNode::get_store_offset(Node* st, PhaseTransform* phase) {
++  if (!st->is_Store())  return -1;  // can happen to dead code via subsume_node
++  intptr_t offset = -1;
++  Node* base = AddPNode::Ideal_base_and_offset(st->in(MemNode::Address),
++                                               phase, offset);
++  if (base == NULL)     return -1;  // something is dead,
++  if (offset < 0)       return -1;  //        dead, dead
++  return offset;
++}
++
++// Helper for proving that an initialization expression is
++// "simple enough" to be folded into an object initialization.
++// Attempts to prove that a store's initial value 'n' can be captured
++// within the initialization without creating a vicious cycle, such as:
++//     { Foo p = new Foo(); p.next = p; }
++// True for constants and parameters and small combinations thereof.
++bool InitializeNode::detect_init_independence(Node* n,
++                                              bool st_is_pinned,
++                                              int& count) {
++  if (n == NULL)      return true;   // (can this really happen?)
++  if (n->is_Proj())   n = n->in(0);
++  if (n == this)      return false;  // found a cycle
++  if (n->is_Con())    return true;
++  if (n->is_Start())  return true;   // params, etc., are OK
++  if (n->is_Root())   return true;   // even better
++
++  Node* ctl = n->in(0);
++  if (ctl != NULL && !ctl->is_top()) {
++    if (ctl->is_Proj())  ctl = ctl->in(0);
++    if (ctl == this)  return false;
++
++    // If we already know that the enclosing memory op is pinned right after
++    // the init, then any control flow that the store has picked up
++    // must have preceded the init, or else be equal to the init.
++    // Even after loop optimizations (which might change control edges)
++    // a store is never pinned *before* the availability of its inputs.
++    if (!MemNode::detect_dominating_control(ctl, this->in(0)))
++      return false;                  // failed to prove a good control
++
++  }
++
++  // Check data edges for possible dependencies on 'this'.
++  if ((count += 1) > 20)  return false;  // complexity limit
++  for (uint i = 1; i < n->req(); i++) {
++    Node* m = n->in(i);
++    if (m == NULL || m == n || m->is_top())  continue;
++    uint first_i = n->find_edge(m);
++    if (i != first_i)  continue;  // process duplicate edge just once
++    if (!detect_init_independence(m, st_is_pinned, count)) {
++      return false;
++    }
++  }
++
++  return true;
++}
++
++// Here are all the checks a Store must pass before it can be moved into
++// an initialization.  Returns zero if a check fails.
++// On success, returns the (constant) offset to which the store applies,
++// within the initialized memory.
++intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase) {
++  const int FAIL = 0;
++  if (st->req() != MemNode::ValueIn + 1)
++    return FAIL;                // an inscrutable StoreNode (card mark?)
++  Node* ctl = st->in(MemNode::Control);
++  if (!(ctl != NULL && ctl->is_Proj() && ctl->in(0) == this))
++    return FAIL;                // must be unconditional after the initialization
++  Node* mem = st->in(MemNode::Memory);
++  if (!(mem->is_Proj() && mem->in(0) == this))
++    return FAIL;                // must not be preceded by other stores
++  Node* adr = st->in(MemNode::Address);
++  intptr_t offset;
++  AllocateNode* alloc = AllocateNode::Ideal_allocation(adr, phase, offset);
++  if (alloc == NULL)
++    return FAIL;                // inscrutable address
++  if (alloc != allocation())
++    return FAIL;                // wrong allocation!  (store needs to float up)
++  Node* val = st->in(MemNode::ValueIn);
++  int complexity_count = 0;
++  if (!detect_init_independence(val, true, complexity_count))
++    return FAIL;                // stored value must be 'simple enough'
++
++  return offset;                // success
++}
++
++// Find the captured store in(i) which corresponds to the range
++// [start..start+size) in the initialized object.
++// If there is one, return its index i.  If there isn't, return the
++// negative of the index where it should be inserted.
++// Return 0 if the queried range overlaps an initialization boundary
++// or if dead code is encountered.
++// If size_in_bytes is zero, do not bother with overlap checks.
++int InitializeNode::captured_store_insertion_point(intptr_t start,
++                                                   int size_in_bytes,
++                                                   PhaseTransform* phase) {
++  const int FAIL = 0, MAX_STORE = BytesPerLong;
++
++  if (is_complete())
++    return FAIL;                // arraycopy got here first; punt
++
++  assert(allocation() != NULL, "must be present");
++
++  // no negatives, no header fields:
++  if (start < (intptr_t) sizeof(oopDesc))  return FAIL;
++  if (start < (intptr_t) sizeof(arrayOopDesc) &&
++      start < (intptr_t) allocation()->minimum_header_size())  return FAIL;
++
++  // after a certain size, we bail out on tracking all the stores:
++  intptr_t ti_limit = (TrackedInitializationLimit * HeapWordSize);
++  if (start >= ti_limit)  return FAIL;
++
++  for (uint i = InitializeNode::RawStores, limit = req(); ; ) {
++    if (i >= limit)  return -(int)i; // not found; here is where to put it
++
++    Node*    st     = in(i);
++    intptr_t st_off = get_store_offset(st, phase);
++    if (st_off < 0) {
++      if (st != zero_memory()) {
++        return FAIL;            // bail out if there is dead garbage
++      }
++    } else if (st_off > start) {
++      // ...we are done, since stores are ordered
++      if (st_off < start + size_in_bytes) {
++        return FAIL;            // the next store overlaps
++      }
++      return -(int)i;           // not found; here is where to put it
++    } else if (st_off < start) {
++      if (size_in_bytes != 0 &&
++          start < st_off + MAX_STORE &&
++          start < st_off + st->as_Store()->memory_size()) {
++        return FAIL;            // the previous store overlaps
++      }
++    } else {
++      if (size_in_bytes != 0 &&
++          st->as_Store()->memory_size() != size_in_bytes) {
++        return FAIL;            // mismatched store size
++      }
++      return i;
++    }
++
++    ++i;
++  }
++}
++
++// Look for a captured store which initializes at the offset 'start'
++// with the given size.  If there is no such store, and no other
++// initialization interferes, then return zero_memory (the memory
++// projection of the AllocateNode).
++Node* InitializeNode::find_captured_store(intptr_t start, int size_in_bytes,
++                                          PhaseTransform* phase) {
++  assert(stores_are_sane(phase), "");
++  int i = captured_store_insertion_point(start, size_in_bytes, phase);
++  if (i == 0) {
++    return NULL;                // something is dead
++  } else if (i < 0) {
++    return zero_memory();       // just primordial zero bits here
++  } else {
++    Node* st = in(i);           // here is the store at this position
++    assert(get_store_offset(st->as_Store(), phase) == start, "sanity");
++    return st;
++  }
++}
++
++// Create, as a raw pointer, an address within my new object at 'offset'.
++Node* InitializeNode::make_raw_address(intptr_t offset,
++                                       PhaseTransform* phase) {
++  Node* addr = in(RawAddress);
++  if (offset != 0) {
++    Compile* C = phase->C;
++    addr = phase->transform( new (C, 4) AddPNode(C->top(), addr,
++                                                 phase->MakeConX(offset)) );
++  }
++  return addr;
++}
++
++// Clone the given store, converting it into a raw store
++// initializing a field or element of my new object.
++// Caller is responsible for retiring the original store,
++// with subsume_node or the like.
++//
++// From the example above InitializeNode::InitializeNode,
++// here are the old stores to be captured:
++//   store1 = (StoreC init.Control init.Memory (+ oop 12) 1)
++//   store2 = (StoreC init.Control store1      (+ oop 14) 2)
++//
++// Here is the changed code; note the extra edges on init:
++//   alloc = (Allocate ...)
++//   rawoop = alloc.RawAddress
++//   rawstore1 = (StoreC alloc.Control alloc.Memory (+ rawoop 12) 1)
++//   rawstore2 = (StoreC alloc.Control alloc.Memory (+ rawoop 14) 2)
++//   init = (Initialize alloc.Control alloc.Memory rawoop
++//                      rawstore1 rawstore2)
++//
++Node* InitializeNode::capture_store(StoreNode* st, intptr_t start,
++                                    PhaseTransform* phase) {
++  assert(stores_are_sane(phase), "");
++
++  if (start < 0)  return NULL;
++  assert(can_capture_store(st, phase) == start, "sanity");
++
++  Compile* C = phase->C;
++  int size_in_bytes = st->memory_size();
++  int i = captured_store_insertion_point(start, size_in_bytes, phase);
++  if (i == 0)  return NULL;     // bail out
++  Node* prev_mem = NULL;        // raw memory for the captured store
++  if (i > 0) {
++    prev_mem = in(i);           // there is a pre-existing store under this one
++    set_req(i, C->top());       // temporarily disconnect it
++    // See StoreNode::Ideal 'st->outcnt() == 1' for the reason to disconnect.
++  } else {
++    i = -i;                     // no pre-existing store
++    prev_mem = zero_memory();   // a slice of the newly allocated object
++    if (i > InitializeNode::RawStores && in(i-1) == prev_mem)
++      set_req(--i, C->top());   // reuse this edge; it has been folded away
++    else
++      ins_req(i, C->top());     // build a new edge
++  }
++  Node* new_st = st->clone();
++  new_st->set_req(MemNode::Control, in(Control));
++  new_st->set_req(MemNode::Memory,  prev_mem);
++  new_st->set_req(MemNode::Address, make_raw_address(start, phase));
++  new_st = phase->transform(new_st);
++
++  // At this point, new_st might have swallowed a pre-existing store
++  // at the same offset, or perhaps new_st might have disappeared,
++  // if it redundantly stored the same value (or zero to fresh memory).
++
++  // In any case, wire it in:
++  set_req(i, new_st);
++
++  // The caller may now kill the old guy.
++  DEBUG_ONLY(Node* check_st = find_captured_store(start, size_in_bytes, phase));
++  assert(check_st == new_st || check_st == NULL, "must be findable");
++  assert(!is_complete(), "");
++  return new_st;
++}
++
++static bool store_constant(jlong* tiles, int num_tiles,
++                           intptr_t st_off, int st_size,
++                           jlong con) {
++  if ((st_off & (st_size-1)) != 0)
++    return false;               // strange store offset (assume size==2**N)
++  address addr = (address)tiles + st_off;
++  assert(st_off >= 0 && addr+st_size <= (address)&tiles[num_tiles], "oob");
++  switch (st_size) {
++  case sizeof(jbyte):  *(jbyte*) addr = (jbyte) con; break;
++  case sizeof(jchar):  *(jchar*) addr = (jchar) con; break;
++  case sizeof(jint):   *(jint*)  addr = (jint)  con; break;
++  case sizeof(jlong):  *(jlong*) addr = (jlong) con; break;
++  default: return false;        // strange store size (detect size!=2**N here)
++  }
++  return true;                  // return success to caller
++}
++
++// Coalesce subword constants into int constants and possibly
++// into long constants.  The goal, if the CPU permits,
++// is to initialize the object with a small number of 64-bit tiles.
++// Also, convert floating-point constants to bit patterns.
++// Non-constants are not relevant to this pass.
++//
++// In terms of the running example on InitializeNode::InitializeNode
++// and InitializeNode::capture_store, here is the transformation
++// of rawstore1 and rawstore2 into rawstore12:
++//   alloc = (Allocate ...)
++//   rawoop = alloc.RawAddress
++//   tile12 = 0x00010002
++//   rawstore12 = (StoreI alloc.Control alloc.Memory (+ rawoop 12) tile12)
++//   init = (Initialize alloc.Control alloc.Memory rawoop rawstore12)
++//
++void
++InitializeNode::coalesce_subword_stores(intptr_t header_size,
++                                        Node* size_in_bytes,
++                                        PhaseGVN* phase) {
++  Compile* C = phase->C;
++
++  assert(stores_are_sane(phase), "");
++  // Note:  After this pass, they are not completely sane,
++  // since there may be some overlaps.
++
++  int old_subword = 0, old_long = 0, new_int = 0, new_long = 0;
++
++  intptr_t ti_limit = (TrackedInitializationLimit * HeapWordSize);
++  intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, ti_limit);
++  size_limit = MIN2(size_limit, ti_limit);
++  size_limit = align_size_up(size_limit, BytesPerLong);
++  int num_tiles = size_limit / BytesPerLong;
++
++  // allocate space for the tile map:
++  const int small_len = DEBUG_ONLY(true ? 3 :) 30; // keep stack frames small
++  jlong  tiles_buf[small_len];
++  Node*  nodes_buf[small_len];
++  jlong  inits_buf[small_len];
++  jlong* tiles = ((num_tiles <= small_len) ? &tiles_buf[0]
++                  : NEW_RESOURCE_ARRAY(jlong, num_tiles));
++  Node** nodes = ((num_tiles <= small_len) ? &nodes_buf[0]
++                  : NEW_RESOURCE_ARRAY(Node*, num_tiles));
++  jlong* inits = ((num_tiles <= small_len) ? &inits_buf[0]
++                  : NEW_RESOURCE_ARRAY(jlong, num_tiles));
++  // tiles: exact bitwise model of all primitive constants
++  // nodes: last constant-storing node subsumed into the tiles model
++  // inits: which bytes (in each tile) are touched by any initializations
++
++  //// Pass A: Fill in the tile model with any relevant stores.
++
++  Copy::zero_to_bytes(tiles, sizeof(tiles[0]) * num_tiles);
++  Copy::zero_to_bytes(nodes, sizeof(nodes[0]) * num_tiles);
++  Copy::zero_to_bytes(inits, sizeof(inits[0]) * num_tiles);
++  Node* zmem = zero_memory(); // initially zero memory state
++  for (uint i = InitializeNode::RawStores, limit = req(); i < limit; i++) {
++    Node* st = in(i);
++    intptr_t st_off = get_store_offset(st, phase);
++
++    // Figure out the store's offset and constant value:
++    if (st_off < header_size)             continue; //skip (ignore header)
++    if (st->in(MemNode::Memory) != zmem)  continue; //skip (odd store chain)
++    int st_size = st->as_Store()->memory_size();
++    if (st_off + st_size > size_limit)    break;
++
++    // Record which bytes are touched, whether by constant or not.
++    if (!store_constant(inits, num_tiles, st_off, st_size, (jlong) -1))
++      continue;                 // skip (strange store size)
++
++    const Type* val = phase->type(st->in(MemNode::ValueIn));
++    if (!val->singleton())                continue; //skip (non-con store)
++    BasicType type = val->basic_type();
++
++    jlong con = 0;
++    switch (type) {
++    case T_INT:    con = val->is_int()->get_con();  break;
++    case T_LONG:   con = val->is_long()->get_con(); break;
++    case T_FLOAT:  con = jint_cast(val->getf());    break;
++    case T_DOUBLE: con = jlong_cast(val->getd());   break;
++    default:                              continue; //skip (odd store type)
++    }
++
++    if (type == T_LONG && Matcher::isSimpleConstant64(con) &&
++        st->Opcode() == Op_StoreL) {
++      continue;                 // This StoreL is already optimal.
++    }
++
++    // Store down the constant.
++    store_constant(tiles, num_tiles, st_off, st_size, con);
++
++    intptr_t j = st_off >> LogBytesPerLong;
++
++    if (type == T_INT && st_size == BytesPerInt
++        && (st_off & BytesPerInt) == BytesPerInt) {
++      jlong lcon = tiles[j];
++      if (!Matcher::isSimpleConstant64(lcon) &&
++          st->Opcode() == Op_StoreI) {
++        // This StoreI is already optimal by itself.
++        jint* intcon = (jint*) &tiles[j];
++        intcon[1] = 0;  // undo the store_constant()
++
++        // If the previous store is also optimal by itself, back up and
++        // undo the action of the previous loop iteration... if we can.
++        // But if we can't, just let the previous half take care of itself.
++        st = nodes[j];
++        st_off -= BytesPerInt;
++        con = intcon[0];
++        if (con != 0 && st != NULL && st->Opcode() == Op_StoreI) {
++          assert(st_off >= header_size, "still ignoring header");
++          assert(get_store_offset(st, phase) == st_off, "must be");
++          assert(in(i-1) == zmem, "must be");
++          DEBUG_ONLY(const Type* tcon = phase->type(st->in(MemNode::ValueIn)));
++          assert(con == tcon->is_int()->get_con(), "must be");
++          // Undo the effects of the previous loop trip, which swallowed st:
++          intcon[0] = 0;        // undo store_constant()
++          set_req(i-1, st);     // undo set_req(i, zmem)
++          nodes[j] = NULL;      // undo nodes[j] = st
++          --old_subword;        // undo ++old_subword
++        }
++        continue;               // This StoreI is already optimal.
++      }
++    }
++
++    // This store is not needed.
++    set_req(i, zmem);
++    nodes[j] = st;              // record for the moment
++    if (st_size < BytesPerLong) // something has changed
++          ++old_subword;        // includes int/float, but who's counting...
++    else  ++old_long;
++  }
++
++  if ((old_subword + old_long) == 0)
++    return;                     // nothing more to do
++
++  //// Pass B: Convert any non-zero tiles into optimal constant stores.
++  // Be sure to insert them before overlapping non-constant stores.
++  // (E.g., byte[] x = { 1,2,y,4 }  =>  x[int 0] = 0x01020004, x[2]=y.)
++  for (int j = 0; j < num_tiles; j++) {
++    jlong con  = tiles[j];
++    jlong init = inits[j];
++    if (con == 0)  continue;
++    jint con0,  con1;           // split the constant, address-wise
++    jint init0, init1;          // split the init map, address-wise
++    { union { jlong con; jint intcon[2]; } u;
++      u.con = con;
++      con0  = u.intcon[0];
++      con1  = u.intcon[1];
++      u.con = init;
++      init0 = u.intcon[0];
++      init1 = u.intcon[1];
++    }
++
++    Node* old = nodes[j];
++    assert(old != NULL, "need the prior store");
++    intptr_t offset = (j * BytesPerLong);
++
++    bool split = !Matcher::isSimpleConstant64(con);
++
++    if (offset < header_size) {
++      assert(offset + BytesPerInt >= header_size, "second int counts");
++      assert(*(jint*)&tiles[j] == 0, "junk in header");
++      split = true;             // only the second word counts
++      // Example:  int a[] = { 42 ... }
++    } else if (con0 == 0 && init0 == -1) {
++      split = true;             // first word is covered by full inits
++      // Example:  int a[] = { ... foo(), 42 ... }
++    } else if (con1 == 0 && init1 == -1) {
++      split = true;             // second word is covered by full inits
++      // Example:  int a[] = { ... 42, foo() ... }
++    }
++
++    // Here's a case where init0 is neither 0 nor -1:
++    //   byte a[] = { ... 0,0,foo(),0,  0,0,0,42 ... }
++    // Assuming big-endian memory, init0, init1 are 0x0000FF00, 0x000000FF.
++    // In this case the tile is not split; it is (jlong)42.
++    // The big tile is stored down, and then the foo() value is inserted.
++    // (If there were foo(),foo() instead of foo(),0, init0 would be -1.)
++
++    Node* ctl = old->in(MemNode::Control);
++    Node* adr = make_raw_address(offset, phase);
++    const TypePtr* atp = TypeRawPtr::BOTTOM;
++
++    // One or two coalesced stores to plop down.
++    Node*    st[2];
++    intptr_t off[2];
++    int  nst = 0;
++    if (!split) {
++      ++new_long;
++      off[nst] = offset;
++      st[nst++] = StoreNode::make(C, ctl, zmem, adr, atp,
++                                  phase->longcon(con), T_LONG);
++    } else {
++      // Omit either if it is a zero.
++      if (con0 != 0) {
++        ++new_int;
++        off[nst]  = offset;
++        st[nst++] = StoreNode::make(C, ctl, zmem, adr, atp,
++                                    phase->intcon(con0), T_INT);
++      }
++      if (con1 != 0) {
++        ++new_int;
++        offset += BytesPerInt;
++        adr = make_raw_address(offset, phase);
++        off[nst]  = offset;
++        st[nst++] = StoreNode::make(C, ctl, zmem, adr, atp,
++                                    phase->intcon(con1), T_INT);
++      }
++    }
++
++    // Insert second store first, then the first before the second.
++    // Insert each one just before any overlapping non-constant stores.
++    while (nst > 0) {
++      Node* st1 = st[--nst];
++      C->copy_node_notes_to(st1, old);
++      st1 = phase->transform(st1);
++      offset = off[nst];
++      assert(offset >= header_size, "do not smash header");
++      int ins_idx = captured_store_insertion_point(offset, /*size:*/0, phase);
++      guarantee(ins_idx != 0, "must re-insert constant store");
++      if (ins_idx < 0)  ins_idx = -ins_idx;  // never overlap
++      if (ins_idx > InitializeNode::RawStores && in(ins_idx-1) == zmem)
++        set_req(--ins_idx, st1);
++      else
++        ins_req(ins_idx, st1);
++    }
++  }
++
++  if (PrintCompilation && WizardMode)
++    tty->print_cr("Changed %d/%d subword/long constants into %d/%d int/long",
++                  old_subword, old_long, new_int, new_long);
++  if (C->log() != NULL)
++    C->log()->elem("comment that='%d/%d subword/long to %d/%d int/long'",
++                   old_subword, old_long, new_int, new_long);
++
++  // Clean up any remaining occurrences of zmem:
++  remove_extra_zeroes();
++}
++
++// Explore forward from in(start) to find the first fully initialized
++// word, and return its offset.  Skip groups of subword stores which
++// together initialize full words.  If in(start) is itself part of a
++// fully initialized word, return the offset of in(start).  If there
++// are no following full-word stores, or if something is fishy, return
++// a negative value.
++intptr_t InitializeNode::find_next_fullword_store(uint start, PhaseGVN* phase) {
++  int       int_map = 0;
++  intptr_t  int_map_off = 0;
++  const int FULL_MAP = right_n_bits(BytesPerInt);  // the int_map we hope for
++
++  for (uint i = start, limit = req(); i < limit; i++) {
++    Node* st = in(i);
++
++    intptr_t st_off = get_store_offset(st, phase);
++    if (st_off < 0)  break;  // return conservative answer
++
++    int st_size = st->as_Store()->memory_size();
++    if (st_size >= BytesPerInt && (st_off % BytesPerInt) == 0) {
++      return st_off;            // we found a complete word init
++    }
++
++    // update the map:
++
++    intptr_t this_int_off = align_size_down(st_off, BytesPerInt);
++    if (this_int_off != int_map_off) {
++      // reset the map:
++      int_map = 0;
++      int_map_off = this_int_off;
++    }
++
++    int subword_off = st_off - this_int_off;
++    int_map |= right_n_bits(st_size) << subword_off;
++    if ((int_map & FULL_MAP) == FULL_MAP) {
++      return this_int_off;      // we found a complete word init
++    }
++
++    // Did this store hit or cross the word boundary?
++    intptr_t next_int_off = align_size_down(st_off + st_size, BytesPerInt);
++    if (next_int_off == this_int_off + BytesPerInt) {
++      // We passed the current int, without fully initializing it.
++      int_map_off = next_int_off;
++      int_map >>= BytesPerInt;
++    } else if (next_int_off > this_int_off + BytesPerInt) {
++      // We passed the current and next int.
++      return this_int_off + BytesPerInt;
++    }
++  }
++
++  return -1;
++}
++
++
++// Called when the associated AllocateNode is expanded into CFG.
++// At this point, we may perform additional optimizations.
++// Linearize the stores by ascending offset, to make memory
++// activity as coherent as possible.
++Node* InitializeNode::complete_stores(Node* rawctl, Node* rawmem, Node* rawptr,
++                                      intptr_t header_size,
++                                      Node* size_in_bytes,
++                                      PhaseGVN* phase) {
++  assert(!is_complete(), "not already complete");
++  assert(stores_are_sane(phase), "");
++  assert(allocation() != NULL, "must be present");
++
++  remove_extra_zeroes();
++
++  if (ReduceFieldZeroing || ReduceBulkZeroing)
++    // reduce instruction count for common initialization patterns
++    coalesce_subword_stores(header_size, size_in_bytes, phase);
++
++  Node* zmem = zero_memory();   // initially zero memory state
++  Node* inits = zmem;           // accumulating a linearized chain of inits
++  #ifdef ASSERT
++  intptr_t last_init_off = sizeof(oopDesc);  // previous init offset
++  intptr_t last_init_end = sizeof(oopDesc);  // previous init offset+size
++  intptr_t last_tile_end = sizeof(oopDesc);  // previous tile offset+size
++  #endif
++  intptr_t zeroes_done = header_size;
++
++  bool do_zeroing = true;       // we might give up if inits are very sparse
++  int  big_init_gaps = 0;       // how many large gaps have we seen?
++
++  if (ZeroTLAB)  do_zeroing = false;
++  if (!ReduceFieldZeroing && !ReduceBulkZeroing)  do_zeroing = false;
++
++  for (uint i = InitializeNode::RawStores, limit = req(); i < limit; i++) {
++    Node* st = in(i);
++    intptr_t st_off = get_store_offset(st, phase);
++    if (st_off < 0)
++      break;                    // unknown junk in the inits
++    if (st->in(MemNode::Memory) != zmem)
++      break;                    // complicated store chains somehow in list
++
++    int st_size = st->as_Store()->memory_size();
++    intptr_t next_init_off = st_off + st_size;
++
++    if (do_zeroing && zeroes_done < next_init_off) {
++      // See if this store needs a zero before it or under it.
++      intptr_t zeroes_needed = st_off;
++
++      if (st_size < BytesPerInt) {
++        // Look for subword stores which only partially initialize words.
++        // If we find some, we must lay down some word-level zeroes first,
++        // underneath the subword stores.
++        //
++        // Examples:
++        //   byte[] a = { p,q,r,s }  =>  a[0]=p,a[1]=q,a[2]=r,a[3]=s
++        //   byte[] a = { x,y,0,0 }  =>  a[0..3] = 0, a[0]=x,a[1]=y
++        //   byte[] a = { 0,0,z,0 }  =>  a[0..3] = 0, a[2]=z
++        //
++        // Note:  coalesce_subword_stores may have already done this,
++        // if it was prompted by constant non-zero subword initializers.
++        // But this case can still arise with non-constant stores.
++
++        intptr_t next_full_store = find_next_fullword_store(i, phase);
++
++        // In the examples above:
++        //   in(i)          p   q   r   s     x   y     z
++        //   st_off        12  13  14  15    12  13    14
++        //   st_size        1   1   1   1     1   1     1
++        //   next_full_s.  12  16  16  16    16  16    16
++        //   z's_done      12  16  16  16    12  16    12
++        //   z's_needed    12  16  16  16    16  16    16
++        //   zsize          0   0   0   0     4   0     4
++        if (next_full_store < 0) {
++          // Conservative tack:  Zero to end of current word.
++          zeroes_needed = align_size_up(zeroes_needed, BytesPerInt);
++        } else {
++          // Zero to beginning of next fully initialized word.
++          // Or, don't zero at all, if we are already in that word.
++          assert(next_full_store >= zeroes_needed, "must go forward");
++          assert((next_full_store & (BytesPerInt-1)) == 0, "even boundary");
++          zeroes_needed = next_full_store;
++        }
++      }
++
++      if (zeroes_needed > zeroes_done) {
++        intptr_t zsize = zeroes_needed - zeroes_done;
++        // Do some incremental zeroing on rawmem, in parallel with inits.
++        zeroes_done = align_size_down(zeroes_done, BytesPerInt);
++        rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr,
++                                              zeroes_done, zeroes_needed,
++                                              phase);
++        zeroes_done = zeroes_needed;
++        if (zsize > Matcher::init_array_short_size && ++big_init_gaps > 2)
++          do_zeroing = false;   // leave the hole, next time
++      }
++    }
++
++    // Collect the store and move on:
++    st->set_req(MemNode::Memory, inits);
++    inits = st;                 // put it on the linearized chain
++    set_req(i, zmem);           // unhook from previous position
++
++    if (zeroes_done == st_off)
++      zeroes_done = next_init_off;
++
++    assert(!do_zeroing || zeroes_done >= next_init_off, "don't miss any");
++
++    #ifdef ASSERT
++    // Various order invariants.  Weaker than stores_are_sane because
++    // a large constant tile can be filled in by smaller non-constant stores.
++    assert(st_off >= last_init_off, "inits do not reverse");
++    last_init_off = st_off;
++    const Type* val = NULL;
++    if (st_size >= BytesPerInt &&
++        (val = phase->type(st->in(MemNode::ValueIn)))->singleton() &&
++        (int)val->basic_type() < (int)T_OBJECT) {
++      assert(st_off >= last_tile_end, "tiles do not overlap");
++      assert(st_off >= last_init_end, "tiles do not overwrite inits");
++      last_tile_end = MAX2(last_tile_end, next_init_off);
++    } else {
++      intptr_t st_tile_end = align_size_up(next_init_off, BytesPerLong);
++      assert(st_tile_end >= last_tile_end, "inits stay with tiles");
++      assert(st_off      >= last_init_end, "inits do not overlap");
++      last_init_end = next_init_off;  // it's a non-tile
++    }
++    #endif //ASSERT
++  }
++
++  remove_extra_zeroes();        // clear out all the zmems left over
++  add_req(inits);
++
++  if (!ZeroTLAB) {
++    // If anything remains to be zeroed, zero it all now.
++    zeroes_done = align_size_down(zeroes_done, BytesPerInt);
++    // if it is the last unused 4 bytes of an instance, forget about it
++    intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, max_jint);
++    if (zeroes_done + BytesPerLong >= size_limit) {
++      assert(allocation() != NULL, "");
++      Node* klass_node = allocation()->in(AllocateNode::KlassNode);
++      ciKlass* k = phase->type(klass_node)->is_klassptr()->klass();
++      if (zeroes_done == k->layout_helper())
++        zeroes_done = size_limit;
++    }
++    if (zeroes_done < size_limit) {
++      rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr,
++                                            zeroes_done, size_in_bytes, phase);
++    }
++  }
++
++  set_complete(phase);
++  return rawmem;
++}
++
++
++#ifdef ASSERT
++bool InitializeNode::stores_are_sane(PhaseTransform* phase) {
++  if (is_complete())
++    return true;                // stores could be anything at this point
++  intptr_t last_off = sizeof(oopDesc);
++  for (uint i = InitializeNode::RawStores; i < req(); i++) {
++    Node* st = in(i);
++    intptr_t st_off = get_store_offset(st, phase);
++    if (st_off < 0)  continue;  // ignore dead garbage
++    if (last_off > st_off) {
++      tty->print_cr("*** bad store offset at %d: %d > %d", i, last_off, st_off);
++      this->dump(2);
++      assert(false, "ascending store offsets");
++      return false;
++    }
++    last_off = st_off + st->as_Store()->memory_size();
++  }
++  return true;
++}
++#endif //ASSERT
++
++
++
++
++//============================MergeMemNode=====================================
+ // 
+ // SEMANTICS OF MEMORY MERGES:  A MergeMem is a memory state assembled from several
+ // contributing store or call operations.  Each contributor provides the memory
+@@ -1880,16 +3043,16 @@
+ 
+ //------------------------------dump_spec--------------------------------------
+ #ifndef PRODUCT
+-void MergeMemNode::dump_spec() const {
+-  tty->print(" {");
++void MergeMemNode::dump_spec(outputStream *st) const {
++  st->print(" {");
+   Node* base_mem = base_memory();
+   for( uint i = Compile::AliasIdxRaw; i < req(); i++ ) {
+     Node* mem = memory_at(i);
+-    if (mem == base_mem) { tty->print(" -"); continue; }
+-    tty->print( " N%d:", mem->_idx );
+-    Compile::current()->get_adr_type(i)->dump();
++    if (mem == base_mem) { st->print(" -"); continue; }
++    st->print( " N%d:", mem->_idx );
++    Compile::current()->get_adr_type(i)->dump_on(st);
+   }
+-  tty->print(" }");
++  st->print(" }");
+ }
+ #endif // !PRODUCT
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/memnode.hpp openjdk/hotspot/src/share/vm/opto/memnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/memnode.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/memnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)memnode.hpp	1.118 07/05/05 17:06:18 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -63,9 +60,16 @@
+     debug_only(_adr_type=at; adr_type();)
+   }
+ 
++  // Helpers for the optimizer.  Documented in memnode.cpp.
++  static bool detect_ptr_independence(Node* p1, AllocateNode* a1,
++                                      Node* p2, AllocateNode* a2,
++                                      PhaseTransform* phase);
+   static bool adr_phi_is_loop_invariant(Node* adr_phi, Node* cast);
+ 
+ public:
++  // This one should probably be a phase-specific function:
++  static bool detect_dominating_control(Node* dom, Node* sub);
++
+   // Is this Node a MemNode or some descendent?  Default is YES.
+   virtual Node *Ideal_DU_postCCP( PhaseCCP *ccp );
+ 
+@@ -105,8 +109,8 @@
+   Node* can_see_stored_value(Node* st, PhaseTransform* phase) const;
+ 
+ #ifndef PRODUCT
+-  static void dump_adr_type(const Node* mem, const TypePtr* adr_type);
+-  virtual void dump_spec() const;
++  static void dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st);
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -160,7 +164,7 @@
+   virtual int store_Opcode() const = 0;
+ 
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ protected:
+   const Type* load_array_final_field(const TypeKlassPtr *tkls,
+@@ -241,9 +245,9 @@
+   bool require_atomic_access() { return _require_atomic_access; }
+   static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt);
+ #ifndef PRODUCT
+-  virtual void dump_spec() const {
+-    LoadNode::dump_spec();
+-    if (_require_atomic_access)  tty->print(" Atomic!");
++  virtual void dump_spec(outputStream *st) const {
++    LoadNode::dump_spec(st);
++    if (_require_atomic_access)  st->print(" Atomic!");
+   }
+ #endif
+ };
+@@ -436,9 +440,9 @@
+   bool require_atomic_access() { return _require_atomic_access; }
+   static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val);
+ #ifndef PRODUCT
+-  virtual void dump_spec() const {
+-    StoreNode::dump_spec();
+-    if (_require_atomic_access)  tty->print(" Atomic!");
++  virtual void dump_spec(outputStream *st) const {
++    StoreNode::dump_spec(st);
++    if (_require_atomic_access)  st->print(" Atomic!");
+   }
+ #endif
+ };
+@@ -521,7 +525,7 @@
+   virtual uint ideal_reg() const { return 0;} // memory projections don't have a register
+   virtual const Type *Value( PhaseTransform *phase ) const;
+ #ifndef PRODUCT
+-  virtual void dump_spec() const {};
++  virtual void dump_spec(outputStream *st) const {};
+ #endif
+ };
+ 
+@@ -596,11 +600,19 @@
+   virtual uint match_edge(uint idx) const;
+ 
+   // Clear the given area of an object or array.
+-  // Assume that the end_offset is aligned mod BytesPerLong.
+-  // The start_offset (e.g., 8 or 12) must be aligned at least mod BytesPerInt.
++  // The start offset must always be aligned mod BytesPerInt.
++  // The end offset must always be aligned mod BytesPerLong.
+   // Return the new memory.
+   static Node* clear_memory(Node* control, Node* mem, Node* dest,
+                             intptr_t start_offset,
++                            intptr_t end_offset,
++                            PhaseGVN* phase);
++  static Node* clear_memory(Node* control, Node* mem, Node* dest,
++                            intptr_t start_offset,
++                            Node* end_offset,
++                            PhaseGVN* phase);
++  static Node* clear_memory(Node* control, Node* mem, Node* dest,
++                            Node* start_offset,
+                             Node* end_offset,
+                             PhaseGVN* phase);
+ };
+@@ -705,6 +717,92 @@
+   virtual uint ideal_reg() const { return 0; } // not matched in the AD file
+ };
+ 
++// Isolation of object setup after an AllocateNode and before next safepoint.
++// (See comment in memnode.cpp near InitializeNode::InitializeNode for semantics.)
++class InitializeNode: public MemBarNode {
++  friend class AllocateNode;
++
++  bool _is_complete;
++
++public:
++  enum {
++    Control    = TypeFunc::Control,
++    Memory     = TypeFunc::Memory,     // MergeMem for states affected by this op
++    RawAddress = TypeFunc::Parms+0,    // the newly-allocated raw address
++    RawStores  = TypeFunc::Parms+1     // zero or more stores (or TOP)
++  };
++
++  InitializeNode(Compile* C, int adr_type, Node* rawoop);
++  virtual int Opcode() const;
++  virtual uint size_of() const { return sizeof(*this); }
++  virtual uint ideal_reg() const { return 0; } // not matched in the AD file
++  virtual const RegMask &in_RegMask(uint) const;  // mask for RawAddress
++
++  // Manage incoming memory edges via a MergeMem on in(Memory):
++  Node* memory(uint alias_idx);
++
++  // The raw memory edge coming directly from the Allocation.
++  // The contents of this memory are *always* all-zero-bits.
++  Node* zero_memory() { return memory(Compile::AliasIdxRaw); }
++
++  // Return the corresponding allocation for this initialization (or null if none).
++  // (Note: Both InitializeNode::allocation and AllocateNode::initialization
++  // are defined in graphKit.cpp, which sets up the bidirectional relation.)
++  AllocateNode* allocation();
++
++  // Anything other than zeroing in this init?
++  bool is_non_zero();
++
++  // An InitializeNode must completed before macro expansion is done.
++  // Completion requires that the AllocateNode must be followed by
++  // initialization of the new memory to zero, then to any initializers.
++  bool is_complete() { return _is_complete; }
++
++  // Mark complete.  (Must not yet be complete.)
++  void set_complete(PhaseGVN* phase);
++
++#ifdef ASSERT
++  // ensure all non-degenerate stores are ordered and non-overlapping
++  bool stores_are_sane(PhaseTransform* phase);
++#endif //ASSERT
++
++  // See if this store can be captured; return offset where it initializes.
++  // Return 0 if the store cannot be moved (any sort of problem).
++  intptr_t can_capture_store(StoreNode* st, PhaseTransform* phase);
++
++  // Capture another store; reformat it to write my internal raw memory.
++  // Return the captured copy, else NULL if there is some sort of problem.
++  Node* capture_store(StoreNode* st, intptr_t start, PhaseTransform* phase);
++
++  // Find captured store which corresponds to the range [start..start+size).
++  // Return my own memory projection (meaning the initial zero bits)
++  // if there is no such store.  Return NULL if there is a problem.
++  Node* find_captured_store(intptr_t start, int size_in_bytes, PhaseTransform* phase);
++
++  // Called when the associated AllocateNode is expanded into CFG.
++  Node* complete_stores(Node* rawctl, Node* rawmem, Node* rawptr,
++                        intptr_t header_size, Node* size_in_bytes,
++                        PhaseGVN* phase);
++
++ private:
++  void remove_extra_zeroes();
++
++  // Find out where a captured store should be placed (or already is placed).
++  int captured_store_insertion_point(intptr_t start, int size_in_bytes,
++                                     PhaseTransform* phase);
++
++  static intptr_t get_store_offset(Node* st, PhaseTransform* phase);
++
++  Node* make_raw_address(intptr_t offset, PhaseTransform* phase);
++
++  bool detect_init_independence(Node* n, bool st_is_pinned, int& count);
++
++  void coalesce_subword_stores(intptr_t header_size, Node* size_in_bytes,
++                               PhaseGVN* phase);
++
++  intptr_t find_next_fullword_store(uint i, PhaseGVN* phase);
++};
++
+ //------------------------------MergeMem---------------------------------------
+ // (See comment in memnode.cpp near MergeMemNode::MergeMemNode for semantics.)
+ class MergeMemNode: public Node {
+@@ -747,7 +845,7 @@
+   void grow_to_match(const MergeMemNode* other);
+   bool verify_sparse() const PRODUCT_RETURN0;
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -962,4 +1060,3 @@
+   virtual uint match_edge(uint idx) const { return idx==2; }
+   virtual const Type *bottom_type() const { return Type::ABIO; }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/mulnode.cpp openjdk/hotspot/src/share/vm/opto/mulnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/mulnode.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/mulnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)mulnode.cpp	1.133 07/05/05 17:06:16 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -410,6 +407,13 @@
+   const TypeInt *t2 = phase->type( in(2) )->isa_int();
+   if( t2 && t2->is_con() ) {
+     int con = t2->get_con();
++    // Masking off high bits which are always zero is useless.
++    const TypeInt* t1 = phase->type( in(1) )->isa_int();
++    if (t1 != NULL && t1->_lo >= 0) {
++      jint t1_support = ((jint)1 << (1 + log2_intptr(t1->_hi))) - 1;
++      if ((t1_support & con) == t1_support)
++        return load;
++    }
+     uint lop = load->Opcode();      
+     if( lop == Op_LoadC &&
+         con == 0x0000FFFF )     // Already zero-extended
+@@ -536,6 +540,13 @@
+   const TypeLong *t2 = phase->type( in(2) )->isa_long();
+   if( t2 && t2->is_con() ) {
+     jlong con = t2->get_con();
++    // Masking off high bits which are always zero is useless.
++    const TypeLong* t1 = phase->type( in(1) )->isa_long();
++    if (t1 != NULL && t1->_lo >= 0) {
++      jlong t1_support = ((jlong)1 << (1 + log2_long(t1->_hi))) - 1;
++      if ((t1_support & con) == t1_support)
++        return usr;
++    }
+     uint lop = usr->Opcode();
+     // Masking off the high bits of a unsigned-shift-right is not 
+     // needed either.
+@@ -669,11 +680,27 @@
+   const TypeInt *r1 = t1->is_int(); // Handy access
+   const TypeInt *r2 = t2->is_int(); // Handy access
+ 
+-  if( !r1->is_con() || !r2->is_con() )
++  if (!r2->is_con())
+     return TypeInt::INT;
+ 
+   uint shift = r2->get_con();
+   shift &= BitsPerJavaInteger-1;  // semantics of Java shifts
++  // Shift by a multiple of 32 does nothing:
++  if (shift == 0)  return t1;
++
++  // If the shift is a constant, shift the bounds of the type,
++  // unless this could lead to an overflow.
++  if (!r1->is_con()) {
++    jint lo = r1->_lo, hi = r1->_hi;
++    if (((lo << shift) >> shift) == lo &&
++        ((hi << shift) >> shift) == hi) {
++      // No overflow.  The range shifts up cleanly.
++      return TypeInt::make((jint)lo << (jint)shift,
++                           (jint)hi << (jint)shift,
++                           MAX2(r1->_widen,r2->_widen));
++    }
++    return TypeInt::INT;
++  }
+ 
+   return TypeInt::make( (jint)r1->get_con() << (jint)shift );
+ }
+@@ -762,11 +789,27 @@
+   const TypeLong *r1 = t1->is_long(); // Handy access
+   const TypeInt  *r2 = t2->is_int();  // Handy access
+ 
+-  if( !r1->is_con() || !r2->is_con() )
++  if (!r2->is_con())
+     return TypeLong::LONG;
+ 
+   uint shift = r2->get_con();
+   shift &= (BitsPerJavaInteger*2)-1;  // semantics of Java shifts
++  // Shift by a multiple of 64 does nothing:
++  if (shift == 0)  return t1;
++
++  // If the shift is a constant, shift the bounds of the type,
++  // unless this could lead to an overflow.
++  if (!r1->is_con()) {
++    jlong lo = r1->_lo, hi = r1->_hi;
++    if (((lo << shift) >> shift) == lo &&
++        ((hi << shift) >> shift) == hi) {
++      // No overflow.  The range shifts up cleanly.
++      return TypeLong::make((jlong)lo << (jint)shift,
++                            (jlong)hi << (jint)shift,
++                            MAX2(r1->_widen,r2->_widen));
++    }
++    return TypeLong::LONG;
++  }
+ 
+   return TypeLong::make( (jlong)r1->get_con() << (jint)shift );
+ }
+@@ -1056,9 +1099,14 @@
+   if( in1_op == Op_AndI ) {
+     const TypeInt *t3 = phase->type( andi->in(2) )->isa_int();
+     if( t3 && t3->is_con() ) { // Right input is a constant
+-      const jint mask2 = t3->get_con();
++      jint mask2 = t3->get_con();
++      mask2 >>= con;  // *signed* shift downward (high-order zeroes do not help)
+       Node *newshr = phase->transform( new (phase->C, 3) URShiftINode(andi->in(1), in(2)) );
+-      return new (phase->C, 3) AndINode(newshr, phase->intcon( (mask2 >> con) & mask ));
++      return new (phase->C, 3) AndINode(newshr, phase->intcon(mask2));
++      // The negative values are easier to materialize than positive ones.
++      // A typical case from address arithmetic is ((x & ~15) >> 4).
++      // It's better to change that to ((x >> 4) & ~0) versus
++      // ((x >> 4) & 0x0FFFFFFF).  The difference is greatest in LP64.
+     }
+   }
+ 
+@@ -1184,9 +1232,10 @@
+   if( andi->Opcode() == Op_AndL ) {
+     const TypeLong *t3 = phase->type( andi->in(2) )->isa_long();
+     if( t3 && t3->is_con() ) { // Right input is a constant
+-      const jlong mask2 = t3->get_con();
++      jlong mask2 = t3->get_con();
++      mask2 >>= con;  // *signed* shift downward (high-order zeroes do not help)
+       Node *newshr = phase->transform( new (phase->C, 3) URShiftLNode(andi->in(1), in(2)) );
+-      return new (phase->C, 3) AndLNode(newshr, phase->longcon((mask2 >> con) & mask));
++      return new (phase->C, 3) AndLNode(newshr, phase->longcon(mask2));
+     }
+   }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/mulnode.hpp openjdk/hotspot/src/share/vm/opto/mulnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/mulnode.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/mulnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)mulnode.hpp	1.53 07/05/05 17:06:18 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -248,4 +245,3 @@
+   const Type *bottom_type() const { return TypeLong::LONG; }
+   virtual uint ideal_reg() const { return Op_RegL; }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/multnode.cpp openjdk/hotspot/src/share/vm/opto/multnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/multnode.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/multnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)multnode.cpp	1.60 07/05/05 17:06:23 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -96,7 +93,7 @@
+ 
+ bool ProjNode::pinned() const { return in(0)->pinned(); }
+ #ifndef PRODUCT
+-void ProjNode::dump_spec() const { tty->print("#%d",_con); if(_is_io_use) tty->print(" (i_o_use)");}
++void ProjNode::dump_spec(outputStream *st) const { st->print("#%d",_con); if(_is_io_use) st->print(" (i_o_use)");}
+ #endif
+ 
+ //----------------------------check_con----------------------------------------
+@@ -130,5 +127,3 @@
+ uint ProjNode::ideal_reg() const { 
+   return Matcher::base2reg[bottom_type()->base()];
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/multnode.hpp openjdk/hotspot/src/share/vm/opto/multnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/multnode.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/multnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)multnode.hpp	1.46 07/05/05 17:06:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -79,7 +76,6 @@
+   virtual uint ideal_reg() const;
+   virtual const RegMask &out_RegMask() const;
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/node.cpp openjdk/hotspot/src/share/vm/opto/node.cpp
+--- openjdk6/hotspot/src/share/vm/opto/node.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/node.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)node.cpp	1.227 07/05/21 15:45:56 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -898,7 +895,7 @@
+ 
+ //------------------------------format-----------------------------------------
+ // Print as assembly
+-void Node::format( PhaseRegAlloc * ) const {}
++void Node::format( PhaseRegAlloc *, outputStream *st ) const {}
+ //------------------------------emit-------------------------------------------
+ // Emit bytes starting at parameter 'ptr'.  
+ void Node::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {} 
+@@ -1369,7 +1366,7 @@
+   }
+ 
+   // Dump node-specific info
+-  dump_spec();
++  dump_spec(tty);
+ #ifdef ASSERT
+   // Dump the non-reset _debug_idx
+   if( Verbose && WizardMode ) {
+@@ -1393,7 +1390,7 @@
+     t->dump();
+   } else if( t == Type::MEMORY ) {
+     tty->print("  Memory:");
+-    MemNode::dump_adr_type(this, adr_type());
++    MemNode::dump_adr_type(this, adr_type(), tty);
+   } else if( Verbose || WizardMode ) {
+     tty->print("  Type:");
+     if( t ) {
+@@ -1408,7 +1405,7 @@
+     if (nn != NULL && !nn->is_clear()) {
+       if (nn->jvms() != NULL) {
+         tty->print(" !jvms:");
+-        nn->jvms()->dump_spec();
++        nn->jvms()->dump_spec(tty);
+       }
+     }
+   }
+@@ -1901,10 +1898,10 @@
+ //=============================================================================
+ uint TypeNode::size_of() const { return sizeof(*this); }
+ #ifndef PRODUCT
+-void TypeNode::dump_spec() const { 
++void TypeNode::dump_spec(outputStream *st) const {
+   if( !Verbose && !WizardMode ) {
+     // standard dump does this in Verbose and WizardMode
+-    tty->print(" #"); _type->dump();
++    st->print(" #"); _type->dump_on(st);
+   }
+ }
+ #endif
+@@ -1920,5 +1917,3 @@
+ uint TypeNode::ideal_reg() const { 
+   return Matcher::base2reg[_type->base()];
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/node.hpp openjdk/hotspot/src/share/vm/opto/node.hpp
+--- openjdk6/hotspot/src/share/vm/opto/node.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/node.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)node.hpp	1.221 07/05/17 17:44:27 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -59,6 +56,7 @@
+ class FastLockNode;
+ class FastUnlockNode;
+ class IfNode;
++class InitializeNode;
+ class JVMState;
+ class JumpNode;
+ class JumpProjNode;
+@@ -538,6 +536,7 @@
+         DEFINE_CLASS_ID(NeverBranch, MultiBranch, 2)
+       DEFINE_CLASS_ID(Start,       Multi, 2)
+       DEFINE_CLASS_ID(MemBar,      Multi, 3)
++        DEFINE_CLASS_ID(Initialize,    MemBar, 0)
+ 
+     DEFINE_CLASS_ID(Mach,  Node, 1)
+       DEFINE_CLASS_ID(MachReturn, Mach, 0)
+@@ -687,6 +686,7 @@
+   DEFINE_CLASS_QUERY(If)
+   DEFINE_CLASS_QUERY(IfFalse)
+   DEFINE_CLASS_QUERY(IfTrue)
++  DEFINE_CLASS_QUERY(Initialize)
+   DEFINE_CLASS_QUERY(Jump)
+   DEFINE_CLASS_QUERY(JumpProj)
+   DEFINE_CLASS_QUERY(Load)
+@@ -840,6 +840,10 @@
+   // value, if it appears (by local graph inspection) to be computed by a simple conditional.
+   bool is_iteratively_computed();
+ 
++  // Determine if a node is Counted loop induction variable.
++  // The method is defined in loopnode.cpp.
++  const Node* is_loop_iv() const;
++
+   // Return a node with opcode "opc" and same inputs as "this" if one can
+   // be found; Otherwise return NULL;
+   Node* find_similar(int opc);
+@@ -870,7 +874,7 @@
+   virtual JVMState* jvms() const;
+ 
+   // Print as assembly
+-  virtual void format( PhaseRegAlloc * ) const;
++  virtual void format( PhaseRegAlloc *, outputStream* st = tty ) const;
+   // Emit bytes starting at parameter 'ptr'
+   // Bump 'ptr' by the number of output bytes 
+   virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
+@@ -945,7 +949,7 @@
+   virtual void dump_req() const;     // Print required-edge info
+   virtual void dump_prec() const;    // Print precedence-edge info
+   virtual void dump_out() const;     // Print the output edge info
+-  virtual void dump_spec() const {}; // Print per-node info
++  virtual void dump_spec(outputStream *st) const {}; // Print per-node info
+   void verify_edges(Unique_Node_List &visited); // Verify bi-directional edges
+   void verify() const;               // Check Def-Use info for my subgraph
+   static void verify_recur(const Node *n, int verify_depth, VectorSet &old_space, VectorSet &new_space);
+@@ -1483,7 +1487,6 @@
+   virtual const Type *bottom_type() const;
+   virtual       uint  ideal_reg() const;
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/opcodes.cpp openjdk/hotspot/src/share/vm/opto/opcodes.cpp
+--- openjdk6/hotspot/src/share/vm/opto/opcodes.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/opcodes.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)opcodes.cpp	1.15 07/05/05 17:06:24 JVM"
+-#endif
+ /*
+  * Copyright 1998-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -43,4 +40,3 @@
+   "_last_class_name",
+ };
+ #undef macro
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/opcodes.hpp openjdk/hotspot/src/share/vm/opto/opcodes.hpp
+--- openjdk6/hotspot/src/share/vm/opto/opcodes.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/opcodes.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)opcodes.hpp	1.31 07/05/05 17:06:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/optoreg.hpp openjdk/hotspot/src/share/vm/opto/optoreg.hpp
+--- openjdk6/hotspot/src/share/vm/opto/optoreg.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/optoreg.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)optoreg.hpp	1.6 07/05/05 17:06:18 JVM"
+-#endif
+ /*
+  * Copyright 2006-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/output.cpp openjdk/hotspot/src/share/vm/opto/output.cpp
+--- openjdk6/hotspot/src/share/vm/opto/output.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/output.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)output.cpp	1.289 07/05/17 15:59:26 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -216,7 +213,6 @@
+           MachCallNode* call = n->as_MachCall();
+           if (call->entry_point() == OptoRuntime::new_instance_Java() ||
+               call->entry_point() == OptoRuntime::new_array_Java() ||
+-              call->entry_point() == OptoRuntime::multianewarray1_Java() ||
+               call->entry_point() == OptoRuntime::multianewarray2_Java() ||
+               call->entry_point() == OptoRuntime::multianewarray3_Java() ||
+               call->entry_point() == OptoRuntime::multianewarray4_Java() ||
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/output.hpp openjdk/hotspot/src/share/vm/opto/output.hpp
+--- openjdk6/hotspot/src/share/vm/opto/output.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/output.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)output.hpp	1.28 07/05/05 17:06:24 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -216,4 +213,3 @@
+ #endif
+ 
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/parse1.cpp openjdk/hotspot/src/share/vm/opto/parse1.cpp
+--- openjdk6/hotspot/src/share/vm/opto/parse1.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/parse1.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)parse1.cpp	1.493 07/05/17 15:59:31 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/parse2.cpp openjdk/hotspot/src/share/vm/opto/parse2.cpp
+--- openjdk6/hotspot/src/share/vm/opto/parse2.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/parse2.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)parse2.cpp	1.359 07/05/05 17:06:23 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -897,6 +894,11 @@
+       tty->print_cr("Never-taken backedge stops compilation at bci %d",bci());
+ #endif
+     repush_if_args(); // to gather stats on loop
++    // We need to mark this branch as taken so that if we recompile we will
++    // see that it is possible. In the tiered system the interpreter doesn't
++    // do profiling and by the time we get to the lower tier from the interpreter
++    // the path may be cold again. Make sure it doesn't look untaken
++    profile_taken_branch(target_bci, !ProfileInterpreter);
+     uncommon_trap(Deoptimization::Reason_unreached,
+                   Deoptimization::Action_reinterpret,
+                   NULL, "cold");
+@@ -970,6 +972,11 @@
+       tty->print_cr("Never-taken backedge stops compilation at bci %d",bci());
+ #endif
+     repush_if_args(); // to gather stats on loop
++    // We need to mark this branch as taken so that if we recompile we will
++    // see that it is possible. In the tiered system the interpreter doesn't
++    // do profiling and by the time we get to the lower tier from the interpreter
++    // the path may be cold again. Make sure it doesn't look untaken
++    profile_taken_branch(target_bci, !ProfileInterpreter);
+     uncommon_trap(Deoptimization::Reason_unreached,
+                   Deoptimization::Action_reinterpret,
+                   NULL, "cold");
+@@ -1067,6 +1074,15 @@
+     // We do not simply inspect for a null constant, since a node may
+     // optimize to 'null' later on.
+     repush_if_args();
++    // We need to mark this branch as taken so that if we recompile we will
++    // see that it is possible. In the tiered system the interpreter doesn't
++    // do profiling and by the time we get to the lower tier from the interpreter
++    // the path may be cold again. Make sure it doesn't look untaken
++    if (is_fallthrough) {
++      profile_not_taken_branch(!ProfileInterpreter);
++    } else {
++      profile_taken_branch(iter().get_dest(), !ProfileInterpreter);
++    }
+     uncommon_trap(Deoptimization::Reason_unreached,
+                   Deoptimization::Action_reinterpret,
+                   NULL,
+@@ -1498,9 +1514,9 @@
+     c = pop();                  // Oop to store
+     b = pop();                  // index (already used)
+     a = pop();                  // the array itself
++    const Type* elemtype  = _gvn.type(a)->is_aryptr()->elem();
+     const TypeAryPtr* adr_type = TypeAryPtr::OOPS;
+-    Node* store = store_to_memory(control(), d, c, T_OBJECT, adr_type);
+-    store_barrier(store, T_ARRAY, a, d, c);
++    Node* store = store_oop_to_array(control(), a, d, adr_type, c, elemtype, T_OBJECT);
+     break;
+   }
+   case Bytecodes::_lastore: {
+@@ -2140,4 +2156,16 @@
+     tty->print("\nUnhandled bytecode %s\n", Bytecodes::name(bc()) );
+     ShouldNotReachHere();
+   }
++
++#ifndef PRODUCT
++  IdealGraphPrinter *printer = IdealGraphPrinter::printer();
++  if(printer) {
++    char buffer[256];
++    sprintf(buffer, "Bytecode %d: %s", bci(), Bytecodes::name(bc()));
++    bool old = printer->traverse_outs();
++    printer->set_traverse_outs(true);
++    printer->print_method(C, buffer, 3);
++    printer->set_traverse_outs(old);
++  }
++#endif
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/parse3.cpp openjdk/hotspot/src/share/vm/opto/parse3.cpp
+--- openjdk6/hotspot/src/share/vm/opto/parse3.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/parse3.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)parse3.cpp	1.268 08/04/22 01:46:50 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -223,10 +220,18 @@
+   if (bt == T_DOUBLE)  val = dstore_rounding(val);
+ 
+   // Store the value.  
+-  Node* store = store_to_memory( control(), adr, val, bt, adr_type, is_vol );
+-
+-  // Object-writes need a store-barrier
+-  if (bt == T_OBJECT)  store_barrier(store, T_OBJECT, obj, adr, val);
++  Node* store;
++  if (bt == T_OBJECT) {
++    const TypePtr* field_type;
++    if (!field->type()->is_loaded()) {
++      field_type = TypeInstPtr::BOTTOM;
++    } else {
++      field_type = TypeOopPtr::make_from_klass(field->type()->as_klass());
++    }
++    store = store_oop_to_object( control(), obj, adr, adr_type, val, field_type, bt);
++  } else {
++    store = store_to_memory( control(), adr, val, bt, adr_type, is_vol );
++  }
+ 
+   // If reference is volatile, prevent following volatiles ops from
+   // floating up before the volatile write.
+@@ -345,6 +350,28 @@
+   push(obj);
+ }
+ 
++// Expand simple expressions like new int[3][5] and new Object[2][nonConLen].
++// Also handle the degenerate 1-dimensional case of anewarray.
++Node* Parse::expand_multianewarray(ciArrayKlass* array_klass, Node* *lengths, int ndimensions) {
++  Node* length = lengths[0];
++  assert(length != NULL, "");
++  Node* array = new_array(makecon(TypeKlassPtr::make(array_klass)), length);
++  if (ndimensions > 1) {
++    jint length_con = find_int_con(length, -1);
++    guarantee(length_con >= 0, "non-constant multianewarray");
++    ciArrayKlass* array_klass_1 = array_klass->as_obj_array_klass()->element_klass()->as_array_klass();
++    const TypePtr* adr_type = TypeAryPtr::OOPS;
++    const Type*    elemtype = _gvn.type(array)->is_aryptr()->elem();
++    const intptr_t header   = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
++    for (jint i = 0; i < length_con; i++) {
++      Node*    elem   = expand_multianewarray(array_klass_1, &lengths[1], ndimensions-1);
++      intptr_t offset = header + ((intptr_t)i << LogBytesPerWord);
++      Node*    eaddr  = basic_plus_adr(array, offset);
++      store_oop_to_array(control(), array, eaddr, adr_type, elem, elemtype, T_OBJECT);
++    }
++  }
++  return array;
++}
+ 
+ void Parse::do_multianewarray() {
+   int ndimensions = iter().get_dimensions();
+@@ -356,7 +383,8 @@
+ 
+   // Note:  Array classes are always initialized; no is_initialized check.
+ 
+-  if (ndimensions > 5) {
++  enum { MAX_DIMENSION = 5 };
++  if (ndimensions > MAX_DIMENSION || ndimensions <= 0) {
+     uncommon_trap(Deoptimization::Reason_unhandled,
+                   Deoptimization::Action_none);
+     return;
+@@ -364,75 +392,41 @@
+ 
+   kill_dead_locals();
+ 
+-  // Can use _multianewarray instead of _anewarray or _newarray
+-  // if only one dimension
+-  if( ndimensions == 1 && array_klass->is_type_array_klass() ) {
+-    // If this is for a basic type, call code for do_newarray instead
+-    BasicType element_type = array_klass->as_type_array_klass()->element_type();
+-    do_newarray(element_type);
+-    return;
+-  }
+-
+-  ciObjArrayKlass* obj_array_klass = array_klass->as_obj_array_klass();
+-
+-  // find the element type (etype)
+-  ciKlass* element_klass = obj_array_klass->base_element_klass();
+-  // Base_element is either an instance-klass or a type-array but NOT
+-  // a basic type.  We really wanted the klass of a basic type; since that's
+-  // not available we have to test for type-array here.
+-  const Type* element_type = element_klass->is_type_array_klass()
+-    ? Type::get_const_basic_type(element_klass->as_type_array_klass()->element_type())
+-    : TypeInstPtr::make(TypePtr::BotPTR, element_klass->as_instance_klass());
+-
+-  int mdimensions = obj_array_klass->dimension();
+-
+   // get the lengths from the stack (first dimension is on top)
+-  Node** length = NEW_RESOURCE_ARRAY(Node*, ndimensions + 1);
++  Node* length[MAX_DIMENSION+1];
+   length[ndimensions] = NULL;  // terminating null for make_runtime_call
+-  for (int j = ndimensions-1; j >= 0 ; j--) length[j] = pop();
++  int j;
++  for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop();
+ 
+-  // construct the array type
+-  const Type* prev_type  = element_type;
+-  ciKlass*    prev_array = element_klass->is_type_array_klass() ? element_klass : NULL;
+-
+-  // fill the lowest dimensions with unknown sizes
+-  for (int index = 0; index < mdimensions - ndimensions; index++) {
+-    const TypeAry* arr0 = TypeAry::make(prev_type, TypeInt::POS);
+-    prev_type = TypeAryPtr::make(TypePtr::BotPTR, arr0, prev_array, false, 0);
+-    prev_array = NULL; // array klasses can be lazy, except the first
+-  }
+-
+-  // Fill in the dimensions with known sizes (passed in the JVM stack)
+-  for (int i = 0; i < ndimensions; i++) {
+-    const Type* count_type = TypeInt::POS;
+-    TypePtr::PTR ptr = TypePtr::BotPTR;
+-    bool    is_exact = false;
+-    // For the outermost dimension, try to get a better type than POS for the
+-    // size.  We don't do this for inner dimmensions because we lack the 
+-    // support to invalidate the refined type when the base array is modified
+-    // by an aastore, or when it aliased via certain uses of an aaload.
+-    if (i == ndimensions - 1) {
+-      const Type* count_range_type = length[0]->bottom_type()->join(count_type);
+-      // Only improve the type if the array length is non-negative.
+-      if (!count_range_type->empty()) {
+-        count_type = count_range_type;
+-        ptr = TypePtr::NotNull;
+-      }
+-      // Only the outermost type is exact (4957832, 6587132),
+-      // since rows of the array can be either nulled out or replaced
+-      // by subarrays of sharper types.
+-      is_exact = true;
+-    } 
+-    assert(count_type->is_int(), "must be integer");
+-    const TypeAry* arr0 = TypeAry::make(prev_type, (TypeInt*)count_type);
+-    prev_type = TypeAryPtr::make(ptr, arr0, prev_array, is_exact, 0);
+-    prev_array = NULL; // array klasses can be lazy, except the first
++  // The original expression was of this form: new T[length0][length1]...
++  // It is often the case that the lengths are small (except the last).
++  // If that happens, use the fast 1-d creator a constant number of times.
++  const jint expand_limit = MIN2((juint)MultiArrayExpandLimit, (juint)100);
++  jint expand_count = 1;        // count of allocations in the expansion
++  jint expand_fanout = 1;       // running total fanout
++  for (j = 0; j < ndimensions-1; j++) {
++    jint dim_con = find_int_con(length[j], -1);
++    expand_fanout *= dim_con;
++    expand_count  += expand_fanout; // count the level-J sub-arrays
++    if (dim_con < 0
++        || dim_con > expand_limit
++        || expand_count > expand_limit) {
++      expand_count = 0;
++      break;
++    }
++  }
++
++  // Can use multianewarray instead of [a]newarray if only one dimension,
++  // or if all non-final dimensions are small constants.
++  if (expand_count == 1 || (1 <= expand_count && expand_count <= expand_limit)) {
++    Node* obj = expand_multianewarray(array_klass, &length[0], ndimensions);
++    push(obj);
++    return;
+   }
+-  const TypeAryPtr* arr = (const TypeAryPtr*)prev_type;
+ 
+   address fun = NULL;
+   switch (ndimensions) {
+-   case 1: fun = OptoRuntime::multianewarray1_Java(); break;
++  //case 1: Actually, there is no case 1.  It's handled by new_array.
+    case 2: fun = OptoRuntime::multianewarray2_Java(); break;
+    case 3: fun = OptoRuntime::multianewarray3_Java(); break;
+    case 4: fun = OptoRuntime::multianewarray4_Java(); break;
+@@ -447,6 +441,23 @@
+                               length[0], length[1], length[2],
+                               length[3], length[4]);
+   Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms));
+-  Node *cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, arr) );
+-  push( cast );
++
++  const Type* type = TypeOopPtr::make_from_klass_raw(array_klass);
++
++  // Improve the type:  We know it's not null, exact, and of a given length.
++  type = type->is_ptr()->cast_to_ptr_type(TypePtr::NotNull);
++  type = type->is_aryptr()->cast_to_exactness(true);
++
++  const TypeInt* ltype = _gvn.find_int_type(length[0]);
++  if (ltype != NULL)
++    type = type->is_aryptr()->cast_to_size(ltype);
++
++  // We cannot sharpen the nested sub-arrays, since the top level is mutable.
++
++  Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) );
++  push(cast);
++
++  // Possible improvements:
++  // - Make a fast path for small multi-arrays.  (W/ implicit init. loops.)
++  // - Issue CastII against length[*] values, to TypeInt::POS.
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/parseHelper.cpp openjdk/hotspot/src/share/vm/opto/parseHelper.cpp
+--- openjdk6/hotspot/src/share/vm/opto/parseHelper.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/parseHelper.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)parseHelper.cpp	1.196 07/05/23 17:37:28 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -347,7 +344,7 @@
+ }
+ 
+ //----------------------------profile_taken_branch-----------------------------
+-void Parse::profile_taken_branch(int target_bci) {
++void Parse::profile_taken_branch(int target_bci, bool force_update) {
+   // This is a potential osr_site if we have a backedge.
+   int cur_bci = bci();
+   bool osr_site = 
+@@ -359,14 +356,21 @@
+   // To do: factor out the the limit calculations below. These duplicate
+   // the similar limit calculations in the interpreter.
+ 
+-  if (method_data_update()) {
++  if (method_data_update() || force_update) {
+     ciMethodData* md = method()->method_data();
+     assert(md != NULL, "expected valid ciMethodData");
+     ciProfileData* data = md->bci_to_data(cur_bci);
+     assert(data->is_JumpData(), "need JumpData for taken branch");
+     increment_md_counter_at(md, data, JumpData::taken_offset());
++  }
+     
++  // In the new tiered system this is all we need to do. In the old
++  // (c2 based) tiered sytem we must do the code below.
++#ifndef TIERED
++  if (method_data_update()) {
++    ciMethodData* md = method()->method_data();
+     if (osr_site) {
++      ciProfileData* data = md->bci_to_data(cur_bci);
+       int limit = (CompileThreshold 
+                    * (OnStackReplacePercentage - InterpreterProfilePercentage)) / 100;
+       test_for_osr_md_counter_at(md, data, JumpData::taken_offset(), limit);
+@@ -379,20 +383,23 @@
+       increment_and_test_invocation_counter(limit);
+     }
+   }
++#endif // TIERED
+ 
+   // Restore the original bytecode.
+   set_bci(cur_bci);
+ }
+ 
+ //--------------------------profile_not_taken_branch---------------------------
+-void Parse::profile_not_taken_branch() {
+-  if (!method_data_update()) return;
++void Parse::profile_not_taken_branch(bool force_update) {
+ 
++  if (method_data_update() || force_update) {
+   ciMethodData* md = method()->method_data();
+   assert(md != NULL, "expected valid ciMethodData");
+   ciProfileData* data = md->bci_to_data(bci());
+   assert(data->is_BranchData(), "need BranchData for not taken branch");
+   increment_md_counter_at(md, data, BranchData::not_taken_offset());
++  }
++
+ }
+ 
+ //---------------------------------profile_call--------------------------------
+@@ -511,5 +518,3 @@
+     increment_md_counter_at(md, data, MultiBranchData::default_count_offset());
+   }
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/parse.hpp openjdk/hotspot/src/share/vm/opto/parse.hpp
+--- openjdk6/hotspot/src/share/vm/opto/parse.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/parse.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)parse.hpp	1.269 07/05/05 17:06:25 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -107,6 +104,7 @@
+   // Debug information collected during parse
+   uint        count_inlines()     const { return _count_inlines; };
+ #endif
++  GrowableArray<InlineTree*> subtrees() { return _subtrees; }
+ };
+ 
+ 
+@@ -132,6 +130,7 @@
+     Block**            _successors;
+ 
+     // Use init_node/init_graph to initialize Blocks.
++    // Block() : _live_locals((uintptr_t*)NULL,0) { ShouldNotReachHere(); }
+     Block() : _live_locals(NULL,0) { ShouldNotReachHere(); }
+ 
+    public:
+@@ -431,7 +430,7 @@
+ 
+   // Helper function to identify inlining potential at call-site
+   ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, 
+-                              ciMethod *dest_method, const TypeInstPtr* receiver_type);
++                              ciMethod *dest_method, const TypeOopPtr* receiver_type);
+     
+   // Helper function to setup for type-profile based inlining
+   bool prepare_type_profile_inline(ciInstanceKlass* prof_klass, ciMethod* prof_method);
+@@ -470,6 +469,7 @@
+   void do_newarray(BasicType elemtype);
+   void do_anewarray();
+   void do_multianewarray();
++  Node* expand_multianewarray(ciArrayKlass* array_klass, Node* *lengths, int ndimensions);
+ 
+   // implementation of jsr/ret
+   void do_jsr();
+@@ -505,8 +505,8 @@
+   void set_md_flag_at(ciMethodData* md, ciProfileData* data, int flag_constant); 
+ 
+   void profile_method_entry();
+-  void profile_taken_branch(int target_bci);
+-  void profile_not_taken_branch();
++  void profile_taken_branch(int target_bci, bool force_update = false);
++  void profile_not_taken_branch(bool force_update = false);
+   void profile_call(Node* receiver);
+   void profile_generic_call();
+   void profile_receiver_type(Node* receiver);
+@@ -553,4 +553,3 @@
+   void dump_bci(int bci);
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/phase.cpp openjdk/hotspot/src/share/vm/opto/phase.cpp
+--- openjdk6/hotspot/src/share/vm/opto/phase.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/phase.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)phase.cpp	1.59 07/05/17 16:00:26 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/phase.hpp openjdk/hotspot/src/share/vm/opto/phase.hpp
+--- openjdk6/hotspot/src/share/vm/opto/phase.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/phase.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)phase.hpp	1.53 07/05/17 16:00:29 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -114,4 +111,3 @@
+   static void print_timers();
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/phaseX.cpp openjdk/hotspot/src/share/vm/opto/phaseX.cpp
+--- openjdk6/hotspot/src/share/vm/opto/phaseX.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/phaseX.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)phaseX.cpp	1.261 07/05/05 17:06:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1335,6 +1332,18 @@
+           _worklist.push(u);
+       }
+     }
++    // If changed initialization activity, check dependent Stores
++    if (use_op == Op_Allocate || use_op == Op_AllocateArray) {
++      InitializeNode* init = use->as_Allocate()->initialization();
++      if (init != NULL) {
++        Node* imem = init->proj_out(TypeFunc::Memory);
++        if (imem != NULL)  add_users_to_worklist0(imem);
++      }
++    }
++    if (use_op == Op_Initialize) {
++      Node* imem = use->as_Initialize()->proj_out(TypeFunc::Memory);
++      if (imem != NULL)  add_users_to_worklist0(imem);
++    }
+   }
+ }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/phaseX.hpp openjdk/hotspot/src/share/vm/opto/phaseX.hpp
+--- openjdk6/hotspot/src/share/vm/opto/phaseX.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/phaseX.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)phaseX.hpp	1.119 07/05/05 17:06:26 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -517,4 +514,3 @@
+   static void print_statistics();
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/postaloc.cpp openjdk/hotspot/src/share/vm/opto/postaloc.cpp
+--- openjdk6/hotspot/src/share/vm/opto/postaloc.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/postaloc.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)postaloc.cpp	1.83 07/05/05 17:06:28 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -585,5 +582,3 @@
+ 
+   } // End for all blocks
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/regalloc.cpp openjdk/hotspot/src/share/vm/opto/regalloc.cpp
+--- openjdk6/hotspot/src/share/vm/opto/regalloc.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/regalloc.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)regalloc.cpp	1.28 07/05/05 17:06:27 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -128,4 +125,3 @@
+   }
+ }
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/regalloc.hpp openjdk/hotspot/src/share/vm/opto/regalloc.hpp
+--- openjdk6/hotspot/src/share/vm/opto/regalloc.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/regalloc.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)regalloc.hpp	1.23 07/05/05 17:06:28 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/regmask.cpp openjdk/hotspot/src/share/vm/opto/regmask.cpp
+--- openjdk6/hotspot/src/share/vm/opto/regmask.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/regmask.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)regmask.cpp	1.62 07/05/05 17:06:25 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -289,5 +286,3 @@
+   tty->print("]");
+ }
+ #endif
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/regmask.hpp openjdk/hotspot/src/share/vm/opto/regmask.hpp
+--- openjdk6/hotspot/src/share/vm/opto/regmask.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/regmask.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)regmask.hpp	1.65 07/05/05 17:06:26 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/reg_split.cpp openjdk/hotspot/src/share/vm/opto/reg_split.cpp
+--- openjdk6/hotspot/src/share/vm/opto/reg_split.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/reg_split.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)reg_split.cpp	1.81 07/05/05 17:06:27 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/rootnode.cpp openjdk/hotspot/src/share/vm/opto/rootnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/rootnode.cpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/rootnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)rootnode.cpp	1.77 07/05/05 17:06:28 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -82,5 +79,3 @@
+ const RegMask &HaltNode::out_RegMask() const { 
+   return RegMask::Empty;
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/rootnode.hpp openjdk/hotspot/src/share/vm/opto/rootnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/rootnode.hpp	2008-08-28 10:23:14.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/rootnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)rootnode.hpp	1.48 07/05/05 17:06:28 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -63,4 +60,3 @@
+   virtual uint ideal_reg() const { return NotAMachineReg; }
+   virtual uint match_edge(uint idx) const { return 0; }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/runtime.cpp openjdk/hotspot/src/share/vm/opto/runtime.cpp
+--- openjdk6/hotspot/src/share/vm/opto/runtime.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/runtime.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)runtime.cpp	1.458 07/05/17 16:00:35 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -43,7 +40,6 @@
+ // Compiled code entry points
+ address OptoRuntime::_new_instance_Java                           = NULL;
+ address OptoRuntime::_new_array_Java                              = NULL;
+-address OptoRuntime::_multianewarray1_Java                        = NULL;
+ address OptoRuntime::_multianewarray2_Java                        = NULL;
+ address OptoRuntime::_multianewarray3_Java                        = NULL;
+ address OptoRuntime::_multianewarray4_Java                        = NULL;
+@@ -89,7 +85,6 @@
+   // -------------------------------------------------------------------------------------------------------------------------------
+   gen(env, _new_instance_Java              , new_instance_Type            , new_instance_C                  ,    0 , true , false, false);
+   gen(env, _new_array_Java                 , new_array_Type               , new_array_C                     ,    0 , true , false, false);
+-  gen(env, _multianewarray1_Java           , multianewarray1_Type         , multianewarray1_C               ,    0 , true , false, false);  
+   gen(env, _multianewarray2_Java           , multianewarray2_Type         , multianewarray2_C               ,    0 , true , false, false);
+   gen(env, _multianewarray3_Java           , multianewarray3_Type         , multianewarray3_C               ,    0 , true , false, false);
+   gen(env, _multianewarray4_Java           , multianewarray4_Type         , multianewarray4_C               ,    0 , true , false, false);
+@@ -144,6 +139,21 @@
+ // We failed the fast-path allocation.  Now we need to do a scavenge or GC
+ // and try allocation again.
+ 
++void OptoRuntime::do_eager_card_mark(JavaThread* thread) {
++  // After any safepoint, just before going back to compiled code,
++  // we perform a card mark.  This lets the compiled code omit
++  // card marks for initialization of new objects.
++  // Keep this code consistent with GraphKit::store_barrier.
++
++  oop new_obj = thread->vm_result();
++  if (new_obj == NULL)  return;
++
++  assert(Universe::heap()->can_elide_tlab_store_barriers(),
++         "compiler must check this first");
++  new_obj = Universe::heap()->new_store_barrier(new_obj);
++  thread->set_vm_result(new_obj);
++}
++
+ // object allocation
+ JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(klassOopDesc* klass, JavaThread* thread))
+   JRT_BLOCK;
+@@ -182,6 +192,10 @@
+   deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
+   JRT_BLOCK_END;
+ 
++  if (GraphKit::use_ReduceInitialCardMarks()) {
++    // do them now so we don't have to do them on the fast path
++    do_eager_card_mark(thread);
++  }
+ JRT_END
+ 
+ 
+@@ -217,21 +231,13 @@
+   thread->set_vm_result(result);
+   JRT_BLOCK_END;
+ 
++  if (GraphKit::use_ReduceInitialCardMarks()) {
++    // do them now so we don't have to do them on the fast path
++    do_eager_card_mark(thread);
++  }
+ JRT_END
+ 
+-// multianewarray for one dimension
+-JRT_ENTRY(void, OptoRuntime::multianewarray1_C(klassOopDesc* elem_type, int len1, JavaThread *thread))
+-#ifndef PRODUCT
+-  SharedRuntime::_multi1_ctr++;                // multianewarray for 1 dimension
+-#endif
+-  assert(check_compiled_frame(thread), "incorrect caller");
+-  assert(oop(elem_type)->is_klass(), "not a class");
+-  jint dims[1];
+-  dims[0] = len1;
+-  oop obj = arrayKlass::cast(elem_type)->multi_allocate(1, dims, THREAD);
+-  deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
+-  thread->set_vm_result(obj);
+-JRT_END
++// Note: multianewarray for one dimension is handled inline by GraphKit::new_array.
+ 
+ // multianewarray for 2 dimensions
+ JRT_ENTRY(void, OptoRuntime::multianewarray2_C(klassOopDesc* elem_type, int len1, int len2, JavaThread *thread))
+@@ -363,10 +369,6 @@
+   return TypeFunc::make(domain, range);
+ }
+ 
+-const TypeFunc *OptoRuntime::multianewarray1_Type() {
+-  return multianewarray_Type(1);
+-}
+-
+ const TypeFunc *OptoRuntime::multianewarray2_Type() {
+   return multianewarray_Type(2);
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/runtime.hpp openjdk/hotspot/src/share/vm/opto/runtime.hpp
+--- openjdk6/hotspot/src/share/vm/opto/runtime.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/runtime.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)runtime.hpp	1.199 07/05/17 16:01:38 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -107,7 +104,6 @@
+   // References to generated stubs
+   static address _new_instance_Java;
+   static address _new_array_Java;
+-  static address _multianewarray1_Java;
+   static address _multianewarray2_Java;
+   static address _multianewarray3_Java;
+   static address _multianewarray4_Java;
+@@ -135,9 +131,11 @@
+   // Allocate storage for a objArray or typeArray
+   static void new_array_C(klassOopDesc* array_klass, int len, JavaThread *thread);
+ 
++  // Post-allocation step for implementing ReduceInitialCardMarks:
++  static void do_eager_card_mark(JavaThread* thread);
++
+   // Allocate storage for a multi-dimensional arrays
+   // Note: needs to be fixed for arbitrary number of dimensions  
+-  static void multianewarray1_C(klassOopDesc* klass, int len1, JavaThread *thread);  
+   static void multianewarray2_C(klassOopDesc* klass, int len1, int len2, JavaThread *thread);  
+   static void multianewarray3_C(klassOopDesc* klass, int len1, int len2, int len3, JavaThread *thread);  
+   static void multianewarray4_C(klassOopDesc* klass, int len1, int len2, int len3, int len4, JavaThread *thread);  
+@@ -193,7 +191,6 @@
+   // access to runtime stubs entry points for java code
+   static address new_instance_Java()                     { return _new_instance_Java; }
+   static address new_array_Java()                        { return _new_array_Java; }
+-  static address multianewarray1_Java()                  { return _multianewarray1_Java; }
+   static address multianewarray2_Java()                  { return _multianewarray2_Java; }
+   static address multianewarray3_Java()                  { return _multianewarray3_Java; }
+   static address multianewarray4_Java()                  { return _multianewarray4_Java; }
+@@ -231,7 +228,6 @@
+   static const TypeFunc* new_instance_Type(); // object allocation (slow case)
+   static const TypeFunc* new_array_Type ();   // [a]newarray (slow case)
+   static const TypeFunc* multianewarray_Type(int ndim); // multianewarray
+-  static const TypeFunc* multianewarray1_Type(); // multianewarray
+   static const TypeFunc* multianewarray2_Type(); // multianewarray
+   static const TypeFunc* multianewarray3_Type(); // multianewarray
+   static const TypeFunc* multianewarray4_Type(); // multianewarray
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/split_if.cpp openjdk/hotspot/src/share/vm/opto/split_if.cpp
+--- openjdk6/hotspot/src/share/vm/opto/split_if.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/split_if.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)split_if.cpp	1.68 07/05/05 17:06:29 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -537,4 +534,3 @@
+   if( VerifyLoopOptimizations ) verify();
+ #endif
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/subnode.cpp openjdk/hotspot/src/share/vm/opto/subnode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/subnode.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/subnode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)subnode.cpp	1.159 07/05/05 17:06:27 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -78,7 +75,7 @@
+ 
+   // Not correct for SubFnode and AddFNode (must check for infinity)
+   // Equal?  Subtract is zero
+-  if( phase->eqv(in1, in2) ) return add_id();
++  if (phase->eqv_uncast(in1, in2))  return add_id();
+ 
+   // Either input is BOTTOM ==> the result is the local BOTTOM
+   if( t1 == Type::BOTTOM || t2 == Type::BOTTOM ) 
+@@ -89,6 +86,31 @@
+ }
+ 
+ //=============================================================================
++
++//------------------------------Helper function--------------------------------
++static bool ok_to_convert(Node* inc, Node* iv) {
++    // Do not collapse (x+c0)-y if "+" is a loop increment, because the
++    // "-" is loop invariant and collapsing extends the live-range of "x"
++    // to overlap with the "+", forcing another register to be used in
++    // the loop.
++    // This test will be clearer with '&&' (apply DeMorgan's rule)
++    // but I like the early cutouts that happen here.
++    const PhiNode *phi;
++    if( ( !inc->in(1)->is_Phi() ||
++          !(phi=inc->in(1)->as_Phi()) ||
++          phi->is_copy() ||
++          !phi->region()->is_CountedLoop() ||
++          inc != phi->region()->as_CountedLoop()->incr() )
++       &&
++        // Do not collapse (x+c0)-iv if "iv" is a loop induction variable,
++        // because "x" maybe invariant.
++        ( !iv->is_loop_iv() )
++      ) {
++      return true;
++    } else {
++      return false;
++    }
++}
+ //------------------------------Ideal------------------------------------------
+ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){
+   Node *in1 = in(1);
+@@ -115,34 +137,28 @@
+   }
+ 
+   // Convert "(x+c0) - y" into (x-y) + c0"
+-  if( op1 == Op_AddI ) {
+-    // Do not collapse (x+y)-y if "+" is a loop increment, because the
+-    // "-" is loop invariant and collapsing extends the live-range of "x"
+-    // to overlap with the "+", forcing another register to be used in
+-    // the loop.
+-    const PhiNode *phi;
+-    // This test will be clearer with '&&' (apply DeMorgan's rule)
+-    // but I like the early cutouts that happen here.
+-    if( ( !in1->in(1)->is_Phi() ||
+-          !(phi=in1->in(1)->as_Phi()) ||
+-          phi->is_copy() ||
+-          !phi->region()->is_CountedLoop() ||
+-          in1 != phi->region()->as_CountedLoop()->incr() )
+-       &&
+-        // Do not collapse (x+c0)-iv if "iv" is a loop induction variable,
+-        // because "x" maybe invariant.
+-        ( !in2->is_Phi() ||
+-          !(phi=in2->as_Phi()) ||
+-          phi->is_copy() ||
+-          !phi->region()->is_CountedLoop() ||
+-          (Node*)phi != phi->region()->as_CountedLoop()->phi() )
+-      ) { 
++  // Do not collapse (x+c0)-y if "+" is a loop increment or
++  // if "y" is a loop induction variable.
++  if( op1 == Op_AddI && ok_to_convert(in1, in2) ) {
+       const Type *tadd = phase->type( in1->in(2) );
+       if( tadd->singleton() && tadd != Type::TOP ) {
+         Node *sub2 = phase->transform( new (phase->C, 3) SubINode( in1->in(1), in2 ));
+         return new (phase->C, 3) AddINode( sub2, in1->in(2) );
+       }
+     }
++
++
++  // Convert "x - (y+c0)" into "(x-y) - c0"
++  // Need the same check as in above optimization but reversed.
++  if (op2 == Op_AddI && ok_to_convert(in2, in1)) {
++    Node* in21 = in2->in(1);
++    Node* in22 = in2->in(2);
++    const TypeInt* tcon = phase->type(in22)->isa_int();
++    if (tcon != NULL && tcon->is_con()) {
++      Node* sub2 = phase->transform( new (phase->C, 3) SubINode(in1, in21) );
++      Node* neg_c0 = phase->intcon(- tcon->get_con());
++      return new (phase->C, 3) AddINode(sub2, neg_c0);
++    }
+   }
+ 
+   const Type *t1 = phase->type( in1 );
+@@ -241,23 +257,28 @@
+     return new (phase->C, 3) AddLNode(in1, phase->longcon(-i->get_con()));
+ 
+   // Convert "(x+c0) - y" into (x-y) + c0"
+-  if( op1 == Op_AddL ) {
+-    // Do not collapse (x+y)-y if "+" is a loop increment, because the
+-    // "-" is loop invariant and collapsing extends the live-range of "x"
+-    // to overlap with the "+", forcing another register to be used in
+-    // the loop.
++  // Do not collapse (x+c0)-y if "+" is a loop increment or
++  // if "y" is a loop induction variable.
++  if( op1 == Op_AddL && ok_to_convert(in1, in2) ) {
+     Node *in11 = in1->in(1);
+-    const PhiNode *phi = in11->is_Phi() ? in11->as_Phi() : NULL;
+-    if( phi == NULL ||
+-        phi->is_copy() ||
+-        !phi->region()->is_CountedLoop() ||
+-        in1 != phi->region()->as_CountedLoop()->incr() ) {
+       const Type *tadd = phase->type( in1->in(2) );
+       if( tadd->singleton() && tadd != Type::TOP ) {
+         Node *sub2 = phase->transform( new (phase->C, 3) SubLNode( in11, in2 ));
+         return new (phase->C, 3) AddLNode( sub2, in1->in(2) );
+       }
+     }
++
++  // Convert "x - (y+c0)" into "(x-y) - c0"
++  // Need the same check as in above optimization but reversed.
++  if (op2 == Op_AddL && ok_to_convert(in2, in1)) {
++    Node* in21 = in2->in(1);
++    Node* in22 = in2->in(2);
++    const TypeLong* tcon = phase->type(in22)->isa_long();
++    if (tcon != NULL && tcon->is_con()) {
++      Node* sub2 = phase->transform( new (phase->C, 3) SubLNode(in1, in21) );
++      Node* neg_c0 = phase->longcon(- tcon->get_con());
++      return new (phase->C, 3) AddLNode(sub2, neg_c0);
++    }
+   }
+                        
+   const Type *t1 = phase->type( in1 );
+@@ -837,9 +858,9 @@
+ //------------------------------dump_spec-------------------------------------
+ // Print special per-node info
+ #ifndef PRODUCT
+-void BoolTest::dump() const {
++void BoolTest::dump_on(outputStream *st) const {
+   const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"};
+-  tty->print(msg[_test]);
++  st->print(msg[_test]);
+ }
+ #endif
+ 
+@@ -1048,10 +1069,10 @@
+ //------------------------------dump_spec--------------------------------------
+ // Dump special per-node info
+ #ifndef PRODUCT
+-void BoolNode::dump_spec() const {
+-  tty->print("[");
+-  _test.dump();
+-  tty->print("]");
++void BoolNode::dump_spec(outputStream *st) const {
++  st->print("[");
++  _test.dump_on(st);
++  st->print("]");
+ }
+ #endif
+ 
+@@ -1183,4 +1204,3 @@
+   if( d2 < 0.0 ) return Type::DOUBLE;
+   return TypeD::make( SharedRuntime::dpow( d1, d2 ) );
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/subnode.hpp openjdk/hotspot/src/share/vm/opto/subnode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/subnode.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/subnode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)subnode.hpp	1.85 07/05/05 17:06:29 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -259,7 +256,7 @@
+   mask negate( ) const { return mask(_test^4); }
+   bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le); }
+ #ifndef PRODUCT
+-  void dump() const;
++  void dump_on(outputStream *st) const;
+ #endif
+ };
+ 
+@@ -289,7 +286,7 @@
+ 
+   bool is_counted_loop_exit_test();
+ #ifndef PRODUCT
+-  virtual void dump_spec() const;
++  virtual void dump_spec(outputStream *st) const;
+ #endif
+ };
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/superword.cpp openjdk/hotspot/src/share/vm/opto/superword.cpp
+--- openjdk6/hotspot/src/share/vm/opto/superword.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/superword.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)superword.cpp	1.6 07/09/25 22:02:47 JVM"
+-#endif
+ /*
+  * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1734,6 +1731,12 @@
+   assert(valid(), "Usable");
+ }
+ 
++// Following is used to create a temporary object during
++// the pattern match of an address expression.
++SWPointer::SWPointer(SWPointer* p) :
++  _mem(p->_mem), _slp(p->_slp),  _base(NULL),  _adr(NULL),
++  _scale(0), _offset(0), _invar(NULL), _negate_invar(false) {}
++
+ //------------------------scaled_iv_plus_offset--------------------
+ // Match: k*iv + offset
+ // where: k is a constant that maybe zero, and
+@@ -1789,6 +1792,25 @@
+       _scale = 1 << n->in(2)->get_int();
+       return true;
+     }
++  } else if (opc == Op_ConvI2L) {
++    if (scaled_iv_plus_offset(n->in(1))) {
++      return true;
++    }
++  } else if (opc == Op_LShiftL) {
++    if (!has_iv() && _invar == NULL) {
++      // Need to preserve the current _offset value, so
++      // create a temporary object for this expression subtree.
++      // Hacky, so should re-engineer the address pattern match.
++      SWPointer tmp(this);
++      if (tmp.scaled_iv_plus_offset(n->in(1))) {
++        if (tmp._invar == NULL) {
++          int mult = 1 << n->in(2)->get_int();
++          _scale   = tmp._scale  * mult;
++          _offset += tmp._offset * mult;
++          return true;
++        }
++      }
++    }
+   }
+   return false;
+ }
+@@ -1801,6 +1823,16 @@
+   if (opc == Op_ConI) {
+     _offset += negate ? -(n->get_int()) : n->get_int();
+     return true;
++  } else if (opc == Op_ConL) {
++    // Okay if value fits into an int
++    const TypeLong* t = n->find_long_type();
++    if (t->higher_equal(TypeLong::INT)) {
++      jlong loff = n->get_long();
++      jint  off  = (jint)loff;
++      _offset += negate ? -off : loff;
++      return true;
++    }
++    return false;
+   }
+   if (_invar != NULL) return false; // already have an invariant
+   if (opc == Op_AddI) {
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/superword.hpp openjdk/hotspot/src/share/vm/opto/superword.hpp
+--- openjdk6/hotspot/src/share/vm/opto/superword.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/superword.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)superword.hpp	1.6 07/05/17 16:01:57 JVM"
+-#endif
+ /*
+  * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -443,6 +440,9 @@
+   };
+ 
+   SWPointer(MemNode* mem, SuperWord* slp);
++  // Following is used to create a temporary object during
++  // the pattern match of an address expression.
++  SWPointer(SWPointer* p);
+ 
+   bool valid()  { return _adr != NULL; }
+   bool has_iv() { return _scale != 0; }
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/type.cpp openjdk/hotspot/src/share/vm/opto/type.cpp
+--- openjdk6/hotspot/src/share/vm/opto/type.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/type.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)type.cpp	1.253 07/05/17 16:02:23 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -662,15 +659,15 @@
+ 
+ #ifndef PRODUCT
+ //------------------------------dump2------------------------------------------
+-void Type::dump2( Dict &d, uint depth ) const {
+-  tty->print(msg[_base]);
++void Type::dump2( Dict &d, uint depth, outputStream *st ) const {
++  st->print(msg[_base]);
+ }
+ 
+ //------------------------------dump-------------------------------------------
+-void Type::dump() const {
++void Type::dump_on(outputStream *st) const {
+   ResourceMark rm;
+   Dict d(cmpkey,hashkey);       // Stop recursive type dumping
+-  dump2(d,1);
++  dump2(d,1, st);
+ }
+ 
+ //------------------------------data-------------------------------------------
+@@ -859,9 +856,9 @@
+ //------------------------------dump2------------------------------------------
+ // Dump float constant Type
+ #ifndef PRODUCT
+-void TypeF::dump2( Dict &d, uint depth ) const {
+-  Type::dump2(d,depth);
+-  tty->print("%f", _f);
++void TypeF::dump2( Dict &d, uint depth, outputStream *st ) const {
++  Type::dump2(d,depth, st);
++  st->print("%f", _f);
+ }
+ #endif
+ 
+@@ -971,9 +968,9 @@
+ //------------------------------dump2------------------------------------------
+ // Dump double constant Type
+ #ifndef PRODUCT
+-void TypeD::dump2( Dict &d, uint depth ) const {
+-  Type::dump2(d,depth);
+-  tty->print("%f", _d);
++void TypeD::dump2( Dict &d, uint depth, outputStream *st ) const {
++  Type::dump2(d,depth,st);
++  st->print("%f", _d);
+ }
+ #endif
+ 
+@@ -1205,29 +1202,29 @@
+   return buf;
+ }
+ 
+-void TypeInt::dump2( Dict &d, uint depth ) const {
++void TypeInt::dump2( Dict &d, uint depth, outputStream *st ) const {
+   char buf[40], buf2[40];
+   if (_lo == min_jint && _hi == max_jint)
+-    tty->print("int");
++    st->print("int");
+   else if (is_con()) 
+-    tty->print("int:%s", intname(buf, get_con()));
++    st->print("int:%s", intname(buf, get_con()));
+   else if (_lo == BOOL->_lo && _hi == BOOL->_hi) 
+-    tty->print("bool");
++    st->print("bool");
+   else if (_lo == BYTE->_lo && _hi == BYTE->_hi)
+-    tty->print("byte");
++    st->print("byte");
+   else if (_lo == CHAR->_lo && _hi == CHAR->_hi) 
+-    tty->print("char");
++    st->print("char");
+   else if (_lo == SHORT->_lo && _hi == SHORT->_hi) 
+-    tty->print("short");
++    st->print("short");
+   else if (_hi == max_jint)
+-    tty->print("int:>=%s", intname(buf, _lo));
++    st->print("int:>=%s", intname(buf, _lo));
+   else if (_lo == min_jint)
+-    tty->print("int:<=%s", intname(buf, _hi));
++    st->print("int:<=%s", intname(buf, _hi));
+   else
+-    tty->print("int:%s..%s", intname(buf, _lo), intname(buf2, _hi));
++    st->print("int:%s..%s", intname(buf, _lo), intname(buf2, _hi));
+ 
+   if (_widen != 0 && this != TypeInt::INT)
+-    tty->print(":%.*s", _widen, "wwww");
++    st->print(":%.*s", _widen, "wwww");
+ }
+ #endif
+ 
+@@ -1469,21 +1466,21 @@
+   return buf;
+ }
+ 
+-void TypeLong::dump2( Dict &d, uint depth ) const {
++void TypeLong::dump2( Dict &d, uint depth, outputStream *st ) const {
+   char buf[80], buf2[80];
+   if (_lo == min_jlong && _hi == max_jlong)
+-    tty->print("long");
++    st->print("long");
+   else if (is_con()) 
+-    tty->print("long:%s", longname(buf, get_con()));
++    st->print("long:%s", longname(buf, get_con()));
+   else if (_hi == max_jlong)
+-    tty->print("long:>=%s", longname(buf, _lo));
++    st->print("long:>=%s", longname(buf, _lo));
+   else if (_lo == min_jlong)
+-    tty->print("long:<=%s", longname(buf, _hi));
++    st->print("long:<=%s", longname(buf, _hi));
+   else
+-    tty->print("long:%s..%s", longname(buf, _lo), longname(buf2, _hi));
++    st->print("long:%s..%s", longname(buf, _lo), longname(buf2, _hi));
+ 
+   if (_widen != 0 && this != TypeLong::LONG)
+-    tty->print(":%.*s", _widen, "wwww");
++    st->print(":%.*s", _widen, "wwww");
+ }
+ #endif
+ 
+@@ -1669,24 +1666,24 @@
+ //------------------------------dump2------------------------------------------
+ // Dump signature Type
+ #ifndef PRODUCT
+-void TypeTuple::dump2( Dict &d, uint depth ) const {
+-  tty->print("{");
++void TypeTuple::dump2( Dict &d, uint depth, outputStream *st ) const {
++  st->print("{");
+   if( !depth || d[this] ) {     // Check for recursive print
+-    tty->print("...}");
++    st->print("...}");
+     return;
+   }
+   d.Insert((void*)this, (void*)this);   // Stop recursion
+   if( _cnt ) {
+     uint i;
+     for( i=0; i<_cnt-1; i++ ) {
+-      tty->print("%d:", i);
+-      _fields[i]->dump2(d, depth-1);
+-      tty->print(", ");
++      st->print("%d:", i);
++      _fields[i]->dump2(d, depth-1, st);
++      st->print(", ");
+     }
+-    tty->print("%d:", i);
+-    _fields[i]->dump2(d, depth-1);
++    st->print("%d:", i);
++    _fields[i]->dump2(d, depth-1, st);
+   }
+-  tty->print("}");
++  st->print("}");
+ }
+ #endif
+ 
+@@ -1708,8 +1705,20 @@
+ //=============================================================================
+ // Convenience common pre-built types.
+ 
++inline const TypeInt* normalize_array_size(const TypeInt* size) {
++  // Certain normalizations keep us sane when comparing types.
++  // We do not want arrayOop variables to differ only by the wideness
++  // of their index types.  Pick minimum wideness, since that is the
++  // forced wideness of small ranges anyway.
++  if (size->_widen != Type::WidenMin)
++    return TypeInt::make(size->_lo, size->_hi, Type::WidenMin);
++  else
++    return size;
++}
++
+ //------------------------------make-------------------------------------------
+ const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) {
++  size = normalize_array_size(size);
+   return (TypeAry*)(new TypeAry(elem,size))->hashcons();
+ }
+ 
+@@ -1742,7 +1751,9 @@
+ //------------------------------xdual------------------------------------------
+ // Dual: compute field-by-field dual
+ const Type *TypeAry::xdual() const {
+-  return new TypeAry( _elem->dual(), _size->dual()->is_int() );
++  const TypeInt* size_dual = _size->dual()->is_int();
++  size_dual = normalize_array_size(size_dual);
++  return new TypeAry( _elem->dual(), size_dual);
+ }
+ 
+ //------------------------------eq---------------------------------------------
+@@ -1761,11 +1772,11 @@
+ 
+ //------------------------------dump2------------------------------------------
+ #ifndef PRODUCT
+-void TypeAry::dump2( Dict &d, uint depth ) const {
+-  _elem->dump2(d, depth);
+-  tty->print("[");
+-  _size->dump2(d, depth);
+-  tty->print("]");
++void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const {
++  _elem->dump2(d, depth, st);
++  st->print("[");
++  _size->dump2(d, depth, st);
++  st->print("]");
+ }
+ #endif
+ 
+@@ -1930,12 +1941,12 @@
+ };
+ 
+ #ifndef PRODUCT
+-void TypePtr::dump2( Dict &d, uint depth ) const {
+-  if( _ptr == Null ) tty->print("NULL");
+-  else tty->print("%s *", ptr_msg[_ptr]);
+-  if( _offset == OffsetTop ) tty->print("+top");
+-  else if( _offset == OffsetBot ) tty->print("+bot");
+-  else if( _offset ) tty->print("+%d", _offset);
++void TypePtr::dump2( Dict &d, uint depth, outputStream *st ) const {
++  if( _ptr == Null ) st->print("NULL");
++  else st->print("%s *", ptr_msg[_ptr]);
++  if( _offset == OffsetTop ) st->print("+top");
++  else if( _offset == OffsetBot ) st->print("+bot");
++  else if( _offset ) st->print("+%d", _offset);
+ }
+ #endif
+ 
+@@ -2073,11 +2084,11 @@
+ 
+ //------------------------------dump2------------------------------------------
+ #ifndef PRODUCT
+-void TypeRawPtr::dump2( Dict &d, uint depth ) const {
++void TypeRawPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
+   if( _ptr == Constant ) 
+-    tty->print(INTPTR_FORMAT, _bits);
++    st->print(INTPTR_FORMAT, _bits);
+   else
+-    tty->print("rawptr:%s", ptr_msg[_ptr]);
++    st->print("rawptr:%s", ptr_msg[_ptr]);
+ }
+ #endif
+ 
+@@ -2402,18 +2413,18 @@
+ 
+ //------------------------------dump2------------------------------------------
+ #ifndef PRODUCT
+-void TypeOopPtr::dump2( Dict &d, uint depth ) const {
+-  tty->print("oopptr:%s", ptr_msg[_ptr]);
+-  if( _klass_is_exact ) tty->print(":exact");
+-  if( const_oop() ) tty->print(INTPTR_FORMAT, const_oop());
++void TypeOopPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
++  st->print("oopptr:%s", ptr_msg[_ptr]);
++  if( _klass_is_exact ) st->print(":exact");
++  if( const_oop() ) st->print(INTPTR_FORMAT, const_oop());
+   switch( _offset ) {
+-  case OffsetTop: tty->print("+top"); break;
+-  case OffsetBot: tty->print("+any"); break;
++  case OffsetTop: st->print("+top"); break;
++  case OffsetBot: st->print("+any"); break;
+   case         0: break;
+-  default:        tty->print("+%d",_offset); break;
++  default:        st->print("+%d",_offset); break;
+   }
+   if (_instance_id != UNKNOWN_INSTANCE)
+-    tty->print(",iid=%d",_instance_id);
++    st->print(",iid=%d",_instance_id);
+ }
+ #endif
+ 
+@@ -2904,38 +2915,38 @@
+ //------------------------------dump2------------------------------------------
+ // Dump oop Type
+ #ifndef PRODUCT
+-void TypeInstPtr::dump2( Dict &d, uint depth ) const {
++void TypeInstPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
+   // Print the name of the klass.
+-  klass()->print_name();
++  klass()->print_name_on(st);
+ 
+   switch( _ptr ) {
+   case Constant:
+     // TO DO: Make CI print the hex address of the underlying oop.
+     if (WizardMode || Verbose) {
+-      const_oop()->print_oop();
++      const_oop()->print_oop(st);
+     }
+   case BotPTR:
+     if (!WizardMode && !Verbose) {
+-      if( _klass_is_exact ) tty->print(":exact");
++      if( _klass_is_exact ) st->print(":exact");
+       break;
+     }
+   case TopPTR:
+   case AnyNull:
+   case NotNull:
+-    tty->print(":%s", ptr_msg[_ptr]);
+-    if( _klass_is_exact ) tty->print(":exact");
++    st->print(":%s", ptr_msg[_ptr]);
++    if( _klass_is_exact ) st->print(":exact");
+     break;
+   }
+ 
+   if( _offset ) {               // Dump offset, if any
+-    if( _offset == OffsetBot )      tty->print("+any");
+-    else if( _offset == OffsetTop ) tty->print("+unknown");
+-    else tty->print("+%d", _offset);
++    if( _offset == OffsetBot )      st->print("+any");
++    else if( _offset == OffsetTop ) st->print("+unknown");
++    else st->print("+%d", _offset);
+   }
+ 
+-  tty->print(" *");
++  st->print(" *");
+   if (_instance_id != UNKNOWN_INSTANCE)
+-    tty->print(",iid=%d",_instance_id);
++    st->print(",iid=%d",_instance_id);
+ }
+ #endif
+ 
+@@ -3001,15 +3012,50 @@
+   return make(ptr(), const_oop(), _ary, klass(), exact, _offset, instance_id);
+ }
+ 
++//-----------------------------narrow_size_type-------------------------------
++// Local cache for arrayOopDesc::max_array_length(etype),
++// which is kind of slow (and cached elsewhere by other users).
++static jint max_array_length_cache[T_CONFLICT+1];
++static jint max_array_length(BasicType etype) {
++  jint& cache = max_array_length_cache[etype];
++  jint res = cache;
++  if (res == 0) {
++    switch (etype) {
++    case T_CONFLICT:
++    case T_ILLEGAL:
++    case T_VOID:
++      etype = T_BYTE;           // will produce conservatively high value
++    }
++    cache = res = arrayOopDesc::max_array_length(etype);
++  }
++  return res;
++}
++
++// Narrow the given size type to the index range for the given array base type.
++// Return NULL if the resulting int type becomes empty.
++const TypeInt* TypeAryPtr::narrow_size_type(const TypeInt* size, BasicType elem) {
++  jint hi = size->_hi;
++  jint lo = size->_lo;
++  jint min_lo = 0;
++  jint max_hi = max_array_length(elem);
++  //if (index_not_size)  --max_hi;     // type of a valid array index, FTR
++  bool chg = false;
++  if (lo < min_lo) { lo = min_lo; chg = true; }
++  if (hi > max_hi) { hi = max_hi; chg = true; }
++  if (lo > hi)
++    return NULL;
++  if (!chg)
++    return size;
++  return TypeInt::make(lo, hi, Type::WidenMin);
++}
++
+ //-------------------------------cast_to_size----------------------------------
+ const TypeAryPtr* TypeAryPtr::cast_to_size(const TypeInt* new_size) const {
+-  if (new_size == size() || new_size == NULL)  return this;
+-  if (new_size->_lo < 0) {
+-    new_size = new_size->join(TypeInt::POS)->is_int();
+-    if (new_size == size())  return this;
+-  }
+-  if (new_size->empty())      // Negative length arrays will produce weird
++  assert(new_size != NULL, "");
++  new_size = narrow_size_type(new_size, elem()->basic_type());
++  if (new_size == NULL)       // Negative length arrays will produce weird
+     new_size = TypeInt::ZERO; // intermediate dead fast-path goo
++  if (new_size == size())  return this;
+   const TypeAry* new_ary = TypeAry::make(elem(), new_size);
+   return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset);
+ }
+@@ -3198,33 +3244,33 @@
+ 
+ //------------------------------dump2------------------------------------------
+ #ifndef PRODUCT
+-void TypeAryPtr::dump2( Dict &d, uint depth ) const {
+-  _ary->dump2(d,depth);
++void TypeAryPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
++  _ary->dump2(d,depth,st);
+   switch( _ptr ) {
+   case Constant:
+-    const_oop()->print();
++    const_oop()->print(st);
+     break;
+   case BotPTR:
+     if (!WizardMode && !Verbose) {
+-      if( _klass_is_exact ) tty->print(":exact");
++      if( _klass_is_exact ) st->print(":exact");
+       break;
+     }
+   case TopPTR:
+   case AnyNull:
+   case NotNull:
+-    tty->print(":%s", ptr_msg[_ptr]);
+-    if( _klass_is_exact ) tty->print(":exact");
++    st->print(":%s", ptr_msg[_ptr]);
++    if( _klass_is_exact ) st->print(":exact");
+     break;
+   }
+ 
+-  tty->print("*");
++  st->print("*");
+   if (_instance_id != UNKNOWN_INSTANCE)
+-    tty->print(",iid=%d",_instance_id);
++    st->print(",iid=%d",_instance_id);
+   if( !_offset ) return;
+-  if( _offset == OffsetTop )      tty->print("+undefined");
+-  else if( _offset == OffsetBot ) tty->print("+any");
+-  else if( _offset < 12 )         tty->print("+%d",_offset);
+-  else                            tty->print("[%d]", (_offset-12)/4 );
++  if( _offset == OffsetTop )      st->print("+undefined");
++  else if( _offset == OffsetBot ) st->print("+any");
++  else if( _offset < 12 )         st->print("+%d",_offset);
++  else                            st->print("[%d]", (_offset-12)/4 );
+ }
+ #endif
+ 
+@@ -3524,15 +3570,15 @@
+ //------------------------------dump2------------------------------------------
+ // Dump Klass Type
+ #ifndef PRODUCT
+-void TypeKlassPtr::dump2( Dict & d, uint depth ) const {
++void TypeKlassPtr::dump2( Dict & d, uint depth, outputStream *st ) const {
+   switch( _ptr ) {
+   case Constant:
+-    tty->print("precise ");
++    st->print("precise ");
+   case NotNull:
+     {
+       const char *name = klass()->name()->as_utf8();
+       if( name ) {
+-        tty->print("klass %s: " INTPTR_FORMAT, name, klass());
++        st->print("klass %s: " INTPTR_FORMAT, name, klass());
+       } else {
+         ShouldNotReachHere();
+       }
+@@ -3541,18 +3587,18 @@
+     if( !WizardMode && !Verbose && !_klass_is_exact ) break;
+   case TopPTR:
+   case AnyNull:
+-    tty->print(":%s", ptr_msg[_ptr]);
+-    if( _klass_is_exact ) tty->print(":exact");
++    st->print(":%s", ptr_msg[_ptr]);
++    if( _klass_is_exact ) st->print(":exact");
+     break;
+   }
+ 
+   if( _offset ) {               // Dump offset, if any
+-    if( _offset == OffsetBot )      { tty->print("+any"); }
+-    else if( _offset == OffsetTop ) { tty->print("+unknown"); }
+-    else                            { tty->print("+%d", _offset); }
++    if( _offset == OffsetBot )      { st->print("+any"); }
++    else if( _offset == OffsetTop ) { st->print("+unknown"); }
++    else                            { st->print("+%d", _offset); }
+   }
+ 
+-  tty->print(" *");
++  st->print(" *");
+ }
+ #endif
+ 
+@@ -3627,31 +3673,31 @@
+ //------------------------------dump2------------------------------------------
+ // Dump Function Type
+ #ifndef PRODUCT
+-void TypeFunc::dump2( Dict &d, uint depth ) const {
++void TypeFunc::dump2( Dict &d, uint depth, outputStream *st ) const {
+   if( _range->_cnt <= Parms )
+-    tty->print("void");
++    st->print("void");
+   else {
+     uint i;
+     for (i = Parms; i < _range->_cnt-1; i++) {
+-      _range->field_at(i)->dump2(d,depth);
+-      tty->print("/");
++      _range->field_at(i)->dump2(d,depth,st);
++      st->print("/");
+     }
+-    _range->field_at(i)->dump2(d,depth);
++    _range->field_at(i)->dump2(d,depth,st);
+   }
+-  tty->print(" ");
+-  tty->print("( ");
++  st->print(" ");
++  st->print("( ");
+   if( !depth || d[this] ) {     // Check for recursive dump
+-    tty->print("...)");
++    st->print("...)");
+     return;
+   }
+   d.Insert((void*)this,(void*)this);    // Stop recursion
+   if (Parms < _domain->_cnt)
+-    _domain->field_at(Parms)->dump2(d,depth-1);
++    _domain->field_at(Parms)->dump2(d,depth-1,st);
+   for (uint i = Parms+1; i < _domain->_cnt; i++) {
+-    tty->print(", ");
+-    _domain->field_at(i)->dump2(d,depth-1);
++    st->print(", ");
++    _domain->field_at(i)->dump2(d,depth-1,st);
+   }
+-  tty->print(" )");
++  st->print(" )");
+ }
+ 
+ //------------------------------print_flattened--------------------------------
+@@ -3703,4 +3749,3 @@
+   }
+   return range()->field_at(TypeFunc::Parms)->basic_type();
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/type.hpp openjdk/hotspot/src/share/vm/opto/type.hpp
+--- openjdk6/hotspot/src/share/vm/opto/type.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/type.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)type.hpp	1.156 07/05/17 16:02:31 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -244,8 +241,11 @@
+   // Printing, statistics
+   static const char * const msg[lastype]; // Printable strings  
+ #ifndef PRODUCT
+-  void         dump() const;
+-  virtual void dump2( Dict &d, uint depth ) const;
++  void         dump_on(outputStream *st) const;
++  void         dump() const {
++    dump_on(tty);
++  }
++  virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
+   static  void dump_stats();
+   static  void verify_lastype();          // Check that arrays match type enum
+ #endif
+@@ -326,7 +326,7 @@
+   static const TypeF *ZERO; // positive zero only
+   static const TypeF *ONE;
+ #ifndef PRODUCT
+-  virtual void dump2(Dict &d, uint depth) const;
++  virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
+ #endif
+ };
+ 
+@@ -353,7 +353,7 @@
+   static const TypeD *ZERO; // positive zero only
+   static const TypeD *ONE;
+ #ifndef PRODUCT
+-  virtual void dump2(Dict &d, uint depth) const;
++  virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
+ #endif
+ };
+ 
+@@ -407,7 +407,7 @@
+   static const TypeInt *INT;
+   static const TypeInt *SYMINT; // symmetric range [-max_jint..max_jint]
+ #ifndef PRODUCT
+-  virtual void dump2(Dict &d, uint depth) const;
++  virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
+ #endif
+ };
+ 
+@@ -451,7 +451,7 @@
+   static const TypeLong *INT;    // 32-bit subrange [min_jint..max_jint]
+   static const TypeLong *UINT;   // 32-bit unsigned [0..max_juint]
+ #ifndef PRODUCT
+-  virtual void dump2( Dict &d, uint ) const;// Specialized per-Type dumping
++  virtual void dump2( Dict &d, uint, outputStream *st  ) const;// Specialized per-Type dumping
+ #endif
+ };
+ 
+@@ -503,7 +503,7 @@
+   static const TypeTuple *INT_PAIR;
+   static const TypeTuple *LONG_PAIR;
+ #ifndef PRODUCT
+-  virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping
++  virtual void dump2( Dict &d, uint, outputStream *st  ) const; // Specialized per-Type dumping
+ #endif
+ };
+ 
+@@ -530,7 +530,7 @@
+   virtual const Type *xdual() const;    // Compute dual right now.
+   bool ary_must_be_exact() const;  // true if arrays of such are never generic
+ #ifndef PRODUCT
+-  virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping
++  virtual void dump2( Dict &d, uint, outputStream *st  ) const; // Specialized per-Type dumping
+ #endif
+ };
+ 
+@@ -591,7 +591,7 @@
+   static const TypePtr *NOTNULL;
+   static const TypePtr *BOTTOM;
+ #ifndef PRODUCT
+-  virtual void dump2( Dict &d, uint depth ) const;
++  virtual void dump2( Dict &d, uint depth, outputStream *st  ) const;
+ #endif
+ };
+ 
+@@ -623,7 +623,7 @@
+   static const TypeRawPtr *BOTTOM;
+   static const TypeRawPtr *NOTNULL;
+ #ifndef PRODUCT
+-  virtual void dump2( Dict &d, uint depth ) const;
++  virtual void dump2( Dict &d, uint depth, outputStream *st  ) const;
+ #endif
+ };
+ 
+@@ -709,7 +709,7 @@
+   // Convenience common pre-built type.
+   static const TypeOopPtr *BOTTOM;
+ #ifndef PRODUCT
+-  virtual void dump2( Dict &d, uint depth ) const;
++  virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
+ #endif
+ };
+ 
+@@ -780,7 +780,7 @@
+   static const TypeInstPtr *MARK;
+   static const TypeInstPtr *KLASS;
+ #ifndef PRODUCT
+-  virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping
++  virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
+ #endif
+ };
+ 
+@@ -837,8 +837,10 @@
+     return _array_body_type[elem];
+   }
+   static const TypeAryPtr *_array_body_type[T_CONFLICT+1];
++  // sharpen the type of an int which is used as an array size
++  static const TypeInt* narrow_size_type(const TypeInt* size, BasicType elem);
+ #ifndef PRODUCT
+-  virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping
++  virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
+ #endif
+ };
+ 
+@@ -875,7 +877,7 @@
+   static const TypeKlassPtr* OBJECT; // Not-null object klass or below
+   static const TypeKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same
+ #ifndef PRODUCT
+-  virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping
++  virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
+ #endif
+ };
+ 
+@@ -914,7 +916,7 @@
+   BasicType return_type() const;
+ 
+ #ifndef PRODUCT
+-  virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping
++  virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
+   void print_flattened() const; // Print a 'flattened' signature
+ #endif
+   // Convenience common pre-built types.
+@@ -1120,4 +1122,3 @@
+ #define ConvX2L(x)   ConvI2L(x)
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/vectornode.cpp openjdk/hotspot/src/share/vm/opto/vectornode.cpp
+--- openjdk6/hotspot/src/share/vm/opto/vectornode.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/vectornode.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vectornode.cpp	1.5 07/05/17 16:02:33 JVM"
+-#endif
+ /*
+  * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/opto/vectornode.hpp openjdk/hotspot/src/share/vm/opto/vectornode.hpp
+--- openjdk6/hotspot/src/share/vm/opto/vectornode.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/opto/vectornode.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vectornode.hpp	1.6 07/05/17 16:02:36 JVM"
+-#endif
+ /*
+  * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/evmCompat.cpp openjdk/hotspot/src/share/vm/prims/evmCompat.cpp
+--- openjdk6/hotspot/src/share/vm/prims/evmCompat.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/evmCompat.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)evmCompat.cpp	1.12 07/05/05 17:06:31 JVM"
+-#endif
+ /*
+  * Copyright 1999-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/forte.cpp openjdk/hotspot/src/share/vm/prims/forte.cpp
+--- openjdk6/hotspot/src/share/vm/prims/forte.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/forte.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)forte.cpp	1.69 07/05/17 16:02:39 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -403,40 +400,6 @@
+   } while (!fill_from_frame());
+ }
+ 
+-
+-// is_valid_method() exists in fprofiler.cpp and now here.
+-// We need one central version of this routine.
+-
+-bool forte_is_valid_method(methodOop method) {
+-
+-  if (method == NULL || 
+-      // The methodOop is extracted via an offset from the current
+-      // interpreter frame. With AsyncGetCallTrace() the interpreter
+-      // frame may still be under construction so we need to make
+-      // sure that we got an aligned oop before we try to use it.
+-      !Space::is_aligned(method) ||
+-      !Universe::heap()->is_in((void*)method) ||
+-      // See if GC became active after we entered AsyncGetCallTrace()
+-      // and before we try to use the methodOop. This routine is
+-      // used in validation of the top_frame so we don't have any
+-      // other data to flush if we bail due to GC here.
+-      // Yes, there is still a window after this check and before
+-      // we use methodOop below, but we can't lock out GC so that
+-      // has to be an acceptable risk.
+-      Universe::heap()->is_gc_active() ||
+-      //
+-      // is_perm_and_alloced() needs to be checked before klass() because you can
+-      // get a method pointing into the unmapped part of the heap's
+-      // reserved area (e.g., a very high address just within bounds),
+-      // and the instruction which loads the class will SIGSEGV.
+-      !method->is_perm_and_alloced() || 
+-      method->klass() != Universe::methodKlassObj()) {
+-    return false;   // doesn't look good
+-  }
+-  return true;      // hopefully this is a method indeed
+-}
+-
+-
+ // Determine if 'fr' is a walkable, compiled frame.
+ // *is_compiled_p is set to true if the frame is compiled and if it
+ // is, then *is_walkable_p is set to true if it is also walkable.
+@@ -505,7 +468,7 @@
+       // access address in order not to trigger asserts that
+       // are built in interpreter_frame_method function
+       methodOop method = *fr->interpreter_frame_method_addr();
+-      if (forte_is_valid_method(method)) {
++      if (Universe::heap()->is_valid_method(method)) {
+         intptr_t bcx = fr->interpreter_frame_bcx();
+         int      bci = method->validate_bci_from_bcx(bcx);
+         // note: bci is set to -1 if not a valid bci
+@@ -680,6 +643,8 @@
+     return;
+   }
+ 
++  CollectedHeap* ch = Universe::heap();
++
+   if (method != NULL) {
+     // The method is not stored GC safe so see if GC became active
+     // after we entered AsyncGetCallTrace() and before we try to
+@@ -687,7 +652,7 @@
+     // Yes, there is still a window after this check and before
+     // we use methodOop below, but we can't lock out GC so that
+     // has to be an acceptable risk.
+-    if (!forte_is_valid_method(method)) {
++    if (!ch->is_valid_method(method)) {
+       trace->num_frames = -2;
+       return;
+     }
+@@ -725,7 +690,7 @@
+     // Yes, there is still a window after this check and before
+     // we use methodOop below, but we can't lock out GC so that
+     // has to be an acceptable risk.
+-    if (!forte_is_valid_method(method)) {
++    if (!ch->is_valid_method(method)) {
+       // we throw away everything we've gathered in this sample since
+       // none of it is safe
+       trace->num_frames = -2;
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/forte.hpp openjdk/hotspot/src/share/vm/prims/forte.hpp
+--- openjdk6/hotspot/src/share/vm/prims/forte.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/forte.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)forte.hpp	1.7 07/05/05 17:06:31 JVM"
+-#endif
+ /*
+  * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,6 +26,7 @@
+ 
+ class Forte : AllStatic {
+  public:
+-   static void register_stub(const char* name, address start, address end);    
++   static void register_stub(const char* name, address start, address end)
++                                                 KERNEL_RETURN;
+                                                  // register internal VM stub
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/hpi_imported.h openjdk/hotspot/src/share/vm/prims/hpi_imported.h
+--- openjdk6/hotspot/src/share/vm/prims/hpi_imported.h	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/hpi_imported.h	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)hpi_imported.h	1.17 07/05/05 17:06:31 JVM"
+-#endif
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -318,4 +315,3 @@
+ #endif
+ 
+ #endif /* !_JAVASOFT_HPI_H_ */
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jniCheck.cpp openjdk/hotspot/src/share/vm/prims/jniCheck.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jniCheck.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jniCheck.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jniCheck.cpp	1.49 07/05/05 17:06:30 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -237,6 +234,10 @@
+   }
+   klassOop k_oop = oopObj->klass();
+ 
++  if (!jfieldIDWorkaround::is_valid_jfieldID(k_oop, fid)) {
++    ReportJNIFatalError(thr, fatal_wrong_field);
++  }
++
+   /* make sure the field exists */
+   int offset = jfieldIDWorkaround::from_instance_jfieldID(k_oop, fid);
+   if (!instanceKlass::cast(k_oop)->contains_field_offset(offset))
+@@ -2046,5 +2047,3 @@
+ 
+   return &checked_jni_NativeInterface;
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jniCheck.hpp openjdk/hotspot/src/share/vm/prims/jniCheck.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jniCheck.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jniCheck.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jniCheck.hpp	1.11 07/05/05 17:06:32 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jni.cpp openjdk/hotspot/src/share/vm/prims/jni.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jni.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jni.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jni.cpp	1.435 07/06/28 16:50:01 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1854,7 +1851,9 @@
+ JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))
+   JNIWrapper("GetStaticObjectField");
+   DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID);
++#ifndef JNICHECK_KERNEL
+   DEBUG_ONLY(klassOop param_k = jniCheck::validate_class(thread, clazz);)
++#endif // JNICHECK_KERNEL
+   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
+   assert(id->is_static_field_id(), "invalid static field id");
+   // Keep JVMTI addition small and only check enabled flag here.
+@@ -3145,7 +3144,11 @@
+ 
+ // Returns the function structure
+ struct JNINativeInterface_* jni_functions() {
++#ifndef JNICHECK_KERNEL
+   if (CheckJNICalls) return jni_functions_check();
++#else  // JNICHECK_KERNEL
++  if (CheckJNICalls) warning("-Xcheck:jni is not supported in kernel vm.");
++#endif // JNICHECK_KERNEL
+   return &jni_NativeInterface;
+ }
+ 
+@@ -3577,4 +3580,3 @@
+     jni_GetEnv,
+     jni_AttachCurrentThreadAsDaemon
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jniFastGetField.cpp openjdk/hotspot/src/share/vm/prims/jniFastGetField.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jniFastGetField.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jniFastGetField.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jniFastGetField.cpp	1.8 07/05/05 17:06:32 JVM"
+-#endif
+ /*
+  * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -40,4 +37,3 @@
+   }
+   return (address)-1;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jniFastGetField.hpp openjdk/hotspot/src/share/vm/prims/jniFastGetField.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jniFastGetField.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jniFastGetField.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jniFastGetField.hpp	1.8 07/05/05 17:06:32 JVM"
+-#endif
+ /*
+  * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jni.h openjdk/hotspot/src/share/vm/prims/jni.h
+--- openjdk6/hotspot/src/share/vm/prims/jni.h	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jni.h	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jni.h	1.45 07/05/05 17:06:31 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1960,6 +1957,3 @@
+ #endif /* __cplusplus */
+ 
+ #endif /* !_JAVASOFT_JNI_H_ */
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jni_md.h openjdk/hotspot/src/share/vm/prims/jni_md.h
+--- openjdk6/hotspot/src/share/vm/prims/jni_md.h	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jni_md.h	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jni_md.h	1.25 07/05/05 17:06:34 JVM"
+-#endif
+ /*
+  * Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvm.cpp openjdk/hotspot/src/share/vm/prims/jvm.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvm.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvm.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvm.cpp	1.567 07/08/20 16:28:14 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -612,7 +609,7 @@
+   oop mirror = NULL;
+   BasicType t = name2type(utf);
+   if (t != T_ILLEGAL && t != T_OBJECT && t != T_ARRAY) {
+-    mirror = SystemDictionary::java_mirror(t);
++    mirror = Universe::java_mirror(t);
+   }
+   if (mirror == NULL) {
+     THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), (char*) utf);
+@@ -3980,14 +3977,14 @@
+     // Do class based checks
+     if (java_lang_Class::is_primitive(mirror())) {
+       const char* msg = "";
+-      if      (mirror == SystemDictionary::bool_mirror())   msg = "java/lang/Boolean";
+-      else if (mirror == SystemDictionary::char_mirror())   msg = "java/lang/Character";
+-      else if (mirror == SystemDictionary::float_mirror())  msg = "java/lang/Float";
+-      else if (mirror == SystemDictionary::double_mirror()) msg = "java/lang/Double";
+-      else if (mirror == SystemDictionary::byte_mirror())   msg = "java/lang/Byte";
+-      else if (mirror == SystemDictionary::short_mirror())  msg = "java/lang/Short";
+-      else if (mirror == SystemDictionary::int_mirror())    msg = "java/lang/Integer";
+-      else if (mirror == SystemDictionary::long_mirror())   msg = "java/lang/Long";
++      if      (mirror == Universe::bool_mirror())   msg = "java/lang/Boolean";
++      else if (mirror == Universe::char_mirror())   msg = "java/lang/Character";
++      else if (mirror == Universe::float_mirror())  msg = "java/lang/Float";
++      else if (mirror == Universe::double_mirror()) msg = "java/lang/Double";
++      else if (mirror == Universe::byte_mirror())   msg = "java/lang/Byte";
++      else if (mirror == Universe::short_mirror())  msg = "java/lang/Short";
++      else if (mirror == Universe::int_mirror())    msg = "java/lang/Integer";
++      else if (mirror == Universe::long_mirror())   msg = "java/lang/Long";
+       THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), msg);
+     }
+ 
+@@ -4492,6 +4489,10 @@
+   // consider to expose this new capability in the sun.rt.jvmCapabilities jvmstat
+   // counter defined in runtimeService.cpp.
+   info->is_attachable = AttachListener::is_attach_supported();
++#ifdef KERNEL
++  info->is_kernel_jvm = 1; // true;
++#else  // KERNEL
++  info->is_kernel_jvm = 0; // false;
++#endif // KERNEL
+ }
+ JVM_END
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvm.h openjdk/hotspot/src/share/vm/prims/jvm.h
+--- openjdk6/hotspot/src/share/vm/prims/jvm.h	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvm.h	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvm.h	1.87 07/08/20 16:26:30 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1499,7 +1496,8 @@
+      * the new bit is also added in the main/baseline.
+      */
+     unsigned int is_attachable : 1;
+-    unsigned int : 31;
++    unsigned int is_kernel_jvm : 1;
++    unsigned int : 30;
+     unsigned int : 32;
+     unsigned int : 32;
+ } jvm_version_info;
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvm_misc.hpp openjdk/hotspot/src/share/vm/prims/jvm_misc.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvm_misc.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvm_misc.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvm_misc.hpp	1.24 07/05/05 17:06:34 JVM"
+-#endif
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiAgentThread.hpp openjdk/hotspot/src/share/vm/prims/jvmtiAgentThread.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiAgentThread.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiAgentThread.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiAgentThread.hpp	1.13 07/05/05 17:06:36 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp openjdk/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiClassFileReconstituter.cpp	1.21 07/05/05 17:06:36 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp openjdk/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiClassFileReconstituter.hpp	1.15 07/05/05 17:06:36 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp openjdk/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiCodeBlobEvents.cpp	1.20 07/05/05 17:06:36 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.hpp openjdk/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiCodeBlobEvents.hpp	1.11 07/05/05 17:06:35 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnter.hpp openjdk/hotspot/src/share/vm/prims/jvmtiEnter.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEnter.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEnter.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiEnter.hpp	1.8 07/05/05 17:06:35 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnter.xsl openjdk/hotspot/src/share/vm/prims/jvmtiEnter.xsl
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEnter.xsl	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEnter.xsl	2007-12-14 08:57:03.000000000 +0100
+@@ -465,6 +465,13 @@
+   <xsl:apply-templates select="parameters" mode="signature"/>
+   <xsl:text>) {
+ </xsl:text>
++
++  <xsl:if test="not(contains(@jkernel,'yes'))">
++  <xsl:text>&#xA;#ifdef JVMTI_KERNEL &#xA;</xsl:text>
++  <xsl:text>  return JVMTI_ERROR_NOT_AVAILABLE; &#xA;</xsl:text>
++  <xsl:text>#else &#xA;</xsl:text>
++  </xsl:if>
++
+   <xsl:apply-templates select="." mode="traceSetUp"/>
+   <xsl:choose>
+     <xsl:when test="count(@phase)=0 or contains(@phase,'live')">
+@@ -584,9 +591,13 @@
+     </xsl:otherwise>
+   </xsl:choose>
+   <xsl:text>  return err;
+-}
+-
+ </xsl:text>
++
++  <xsl:if test="not(contains(@jkernel,'yes'))">
++  <xsl:text>#endif // JVMTI_KERNEL&#xA;</xsl:text>
++  </xsl:if>
++
++  <xsl:text>}&#xA;</xsl:text>
+ </xsl:template>
+ 
+ <xsl:template match="function" mode="doCall">
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp openjdk/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiEnvBase.cpp	1.89 07/05/17 16:04:59 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -56,8 +53,10 @@
+ 
+   JvmtiManageCapabilities::initialize();
+ 
++#ifndef JVMTI_KERNEL
+   // register extension functions and events
+   JvmtiExtensions::register_extensions();
++#endif // !JVMTI_KERNEL
+ 
+ #ifdef JVMTI_TRACE
+   JvmtiTrace::initialize();
+@@ -150,9 +149,6 @@
+   // checking for a valid environment when setting callbacks (while
+   // holding the JvmtiThreadState_lock).
+ 
+-  JvmtiTagMap* tag_map_to_deallocate = _tag_map;
+-  set_tag_map(NULL);
+-
+   // Mark as invalid.
+   _magic = DISPOSED_MAGIC;
+ 
+@@ -163,10 +159,14 @@
+   // Same situation as with events (see above)
+   set_native_method_prefixes(0, NULL);
+ 
++#ifndef JVMTI_KERNEL
++  JvmtiTagMap* tag_map_to_deallocate = _tag_map;
++  set_tag_map(NULL);
+   // A tag map can be big, deallocate it now
+   if (tag_map_to_deallocate != NULL) {
+     delete tag_map_to_deallocate;
+   }
++#endif // !JVMTI_KERNEL
+ 
+   _needs_clean_up = true;
+ }
+@@ -178,11 +178,14 @@
+   // There is a small window of time during which the tag map of a 
+   // disposed environment could have been reallocated.
+   // Make sure it is gone.
++#ifndef JVMTI_KERNEL
+   JvmtiTagMap* tag_map_to_deallocate = _tag_map;
+   set_tag_map(NULL);
++  // A tag map can be big, deallocate it now
+   if (tag_map_to_deallocate != NULL) {
+     delete tag_map_to_deallocate;
+   }
++#endif // !JVMTI_KERNEL
+ 
+   _magic = BAD_MAGIC;
+ }
+@@ -399,7 +402,6 @@
+   }
+ }
+ 
+-
+ // Called from JVMTI entry points which perform stack walking. If the
+ // associated JavaThread is the current thread, then wait_for_suspend
+ // is not used. Otherwise, it determines if we should wait for the
+@@ -523,6 +525,8 @@
+   return (jclass)jni_reference(Klass::cast(k)->java_mirror());
+ }
+ 
++#ifndef JVMTI_KERNEL
++
+ // 
+ // Field Information 
+ // 
+@@ -1408,3 +1412,4 @@
+   }
+ }
+ 
++#endif // !JVMTI_KERNEL
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp openjdk/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiEnvBase.hpp	1.68 07/05/23 10:53:43 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -56,6 +53,11 @@
+ 
+  public:  
+ 
++  enum {
++    JDK15_JVMTI_VERSION = JVMTI_VERSION_1_0 +  33,  /* version: 1.0.33  */
++    JDK16_JVMTI_VERSION = JVMTI_VERSION_1_1 + 102   /* version: 1.1.102 */
++  };
++
+   static jvmtiPhase  get_phase()                    { return _phase; }
+   static void  set_phase(jvmtiPhase phase)          { _phase = phase; }
+   static bool is_vm_live()                          { return _phase == JVMTI_PHASE_LIVE; } 
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnv.cpp openjdk/hotspot/src/share/vm/prims/jvmtiEnv.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEnv.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEnv.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiEnv.cpp	1.162 07/05/23 10:53:40 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -35,12 +32,10 @@
+  // FIXLATER: hook into JvmtiTrace
+ #define TraceJVMTICalls false
+ 
+-JvmtiEnv::JvmtiEnv() : JvmtiEnvBase()
+-{
++JvmtiEnv::JvmtiEnv() : JvmtiEnvBase() {
+ }
+ 
+-JvmtiEnv::~JvmtiEnv() 
+-{
++JvmtiEnv::~JvmtiEnv() {
+ }
+ 
+ JvmtiEnv*
+@@ -91,6 +86,517 @@
+   return deallocate(mem);
+ } /* end Deallocate */
+ 
++// Threads_lock NOT held, java_thread not protected by lock
++// java_thread - pre-checked
++// data - NULL is a valid value, must be checked
++jvmtiError
++JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) {
++  JvmtiThreadState* state = java_thread->jvmti_thread_state();
++  if (state == NULL) {
++    if (data == NULL) {
++      // leaving state unset same as data set to NULL
++      return JVMTI_ERROR_NONE;
++    }
++    // otherwise, create the state
++    state = JvmtiThreadState::state_for(java_thread);
++  }
++  state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data);
++  return JVMTI_ERROR_NONE;
++} /* end SetThreadLocalStorage */
++
++
++// Threads_lock NOT held
++// thread - NOT pre-checked
++// data_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetThreadLocalStorage(jthread thread, void** data_ptr) {
++  JavaThread* current_thread = JavaThread::current();
++  if (thread == NULL) {
++    JvmtiThreadState* state = current_thread->jvmti_thread_state();
++    *data_ptr = (state == NULL) ? NULL :
++      state->env_thread_state(this)->get_agent_thread_local_storage_data();
++  } else {
++
++    // jvmti_GetThreadLocalStorage is "in native" and doesn't transition
++    // the thread to _thread_in_vm. However, when the TLS for a thread
++    // other than the current thread is required we need to transition
++    // from native so as to resolve the jthread.
++
++    ThreadInVMfromNative __tiv(current_thread);
++    __ENTRY(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)
++    debug_only(VMNativeEntryWrapper __vew;)
++
++    oop thread_oop = JNIHandles::resolve_external_guard(thread);
++    if (thread_oop == NULL) {
++      return JVMTI_ERROR_INVALID_THREAD;
++    }
++    if (!thread_oop->is_a(SystemDictionary::thread_klass())) {
++      return JVMTI_ERROR_INVALID_THREAD;
++    }
++    JavaThread* java_thread = java_lang_Thread::thread(thread_oop);
++    if (java_thread == NULL) {
++      return JVMTI_ERROR_THREAD_NOT_ALIVE;
++    }
++    JvmtiThreadState* state = java_thread->jvmti_thread_state();
++    *data_ptr = (state == NULL) ? NULL :
++      state->env_thread_state(this)->get_agent_thread_local_storage_data();
++  }
++  return JVMTI_ERROR_NONE;
++} /* end GetThreadLocalStorage */
++
++  //
++  // Class functions
++  //
++
++// class_count_ptr - pre-checked for NULL
++// classes_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) {
++  return JvmtiGetLoadedClasses::getLoadedClasses(this, class_count_ptr, classes_ptr);
++} /* end GetLoadedClasses */
++
++
++// initiating_loader - NULL is a valid value, must be checked
++// class_count_ptr - pre-checked for NULL
++// classes_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) {
++  return JvmtiGetLoadedClasses::getClassLoaderClasses(this, initiating_loader,
++                                                  class_count_ptr, classes_ptr);
++} /* end GetClassLoaderClasses */
++
++// k_mirror - may be primitive, this must be checked
++// is_modifiable_class_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::IsModifiableClass(oop k_mirror, jboolean* is_modifiable_class_ptr) {
++  *is_modifiable_class_ptr = VM_RedefineClasses::is_modifiable_class(k_mirror)?
++                                                       JNI_TRUE : JNI_FALSE;
++  return JVMTI_ERROR_NONE;
++} /* end IsModifiableClass */
++
++// class_count - pre-checked to be greater than or equal to 0
++// classes - pre-checked for NULL
++jvmtiError
++JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
++//TODO: add locking
++
++  int index;
++  JavaThread* current_thread = JavaThread::current();
++  ResourceMark rm(current_thread);
++
++  jvmtiClassDefinition* class_definitions =
++                            NEW_RESOURCE_ARRAY(jvmtiClassDefinition, class_count);
++  NULL_CHECK(class_definitions, JVMTI_ERROR_OUT_OF_MEMORY);
++
++  for (index = 0; index < class_count; index++) {
++    HandleMark hm(current_thread);
++
++    jclass jcls = classes[index];
++    oop k_mirror = JNIHandles::resolve_external_guard(jcls);
++    if (k_mirror == NULL) {
++      return JVMTI_ERROR_INVALID_CLASS;
++    }
++    if (!k_mirror->is_a(SystemDictionary::class_klass())) {
++      return JVMTI_ERROR_INVALID_CLASS;
++    }
++
++    if (java_lang_Class::is_primitive(k_mirror)) {
++      return JVMTI_ERROR_UNMODIFIABLE_CLASS;
++    }
++
++    klassOop k_oop = java_lang_Class::as_klassOop(k_mirror);
++    KlassHandle klass(current_thread, k_oop);
++
++    jint status = klass->jvmti_class_status();
++    if (status & (JVMTI_CLASS_STATUS_ERROR)) {
++      return JVMTI_ERROR_INVALID_CLASS;
++    }
++    if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
++      return JVMTI_ERROR_UNMODIFIABLE_CLASS;
++    }
++
++    instanceKlassHandle ikh(current_thread, k_oop);
++    if (ikh->get_cached_class_file_bytes() == NULL) {
++      // not cached, we need to reconstitute the class file from VM representation
++      constantPoolHandle  constants(current_thread, ikh->constants());
++      ObjectLocker ol(constants, current_thread);    // lock constant pool while we query it
++
++      JvmtiClassFileReconstituter reconstituter(ikh);
++      if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
++        return reconstituter.get_error();
++      }
++
++      class_definitions[index].class_byte_count = (jint)reconstituter.class_file_size();
++      class_definitions[index].class_bytes      = (unsigned char*)
++                                                       reconstituter.class_file_bytes();
++    } else {
++      // it is cached, get it from the cache
++      class_definitions[index].class_byte_count = ikh->get_cached_class_file_len();
++      class_definitions[index].class_bytes      = ikh->get_cached_class_file_bytes();
++    }
++    class_definitions[index].klass              = jcls;
++  }
++  VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
++  VMThread::execute(&op);
++  return (op.check_error());
++} /* end RetransformClasses */
++
++
++// class_count - pre-checked to be greater than or equal to 0
++// class_definitions - pre-checked for NULL
++jvmtiError
++JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) {
++//TODO: add locking
++  VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
++  VMThread::execute(&op);
++  return (op.check_error());
++} /* end RedefineClasses */
++
++
++  //
++  // Object functions
++  //
++
++// size_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) {
++  oop mirror = JNIHandles::resolve_external_guard(object);
++  NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
++
++  if (mirror->klass() == SystemDictionary::class_klass()) {
++    if (!java_lang_Class::is_primitive(mirror)) {
++        mirror = java_lang_Class::as_klassOop(mirror);
++        assert(mirror != NULL, "class for non-primitive mirror must exist");
++    }
++  }
++
++  *size_ptr = mirror->size() * wordSize;
++  return JVMTI_ERROR_NONE;
++} /* end GetObjectSize */
++
++  //
++  // Method functions
++  //
++
++// prefix - NULL is a valid value, must be checked
++jvmtiError
++JvmtiEnv::SetNativeMethodPrefix(const char* prefix) {
++  return prefix == NULL?
++              SetNativeMethodPrefixes(0, NULL) :
++              SetNativeMethodPrefixes(1, (char**)&prefix);
++} /* end SetNativeMethodPrefix */
++
++
++// prefix_count - pre-checked to be greater than or equal to 0
++// prefixes - pre-checked for NULL
++jvmtiError
++JvmtiEnv::SetNativeMethodPrefixes(jint prefix_count, char** prefixes) {
++  // Have to grab JVMTI thread state lock to be sure that some thread
++  // isn't accessing the prefixes at the same time we are setting them.
++  // No locks during VM bring-up.
++  if (Threads::number_of_threads() == 0) {
++    return set_native_method_prefixes(prefix_count, prefixes);
++  } else {
++    MutexLocker mu(JvmtiThreadState_lock);
++    return set_native_method_prefixes(prefix_count, prefixes);
++  }
++} /* end SetNativeMethodPrefixes */
++
++  //
++  // Event Management functions
++  //
++
++// callbacks - NULL is a valid value, must be checked
++// size_of_callbacks - pre-checked to be greater than or equal to 0
++jvmtiError
++JvmtiEnv::SetEventCallbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks) {
++  JvmtiEventController::set_event_callbacks(this, callbacks, size_of_callbacks);
++  return JVMTI_ERROR_NONE;
++} /* end SetEventCallbacks */
++
++
++// event_thread - NULL is a valid value, must be checked
++jvmtiError
++JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread,   ...) {
++  JavaThread* java_thread = NULL;
++  if (event_thread != NULL) {
++    oop thread_oop = JNIHandles::resolve_external_guard(event_thread);
++    if (thread_oop == NULL) {
++      return JVMTI_ERROR_INVALID_THREAD;
++    }
++    if (!thread_oop->is_a(SystemDictionary::thread_klass())) {
++      return JVMTI_ERROR_INVALID_THREAD;
++    }
++    java_thread = java_lang_Thread::thread(thread_oop);
++    if (java_thread == NULL) {
++      return JVMTI_ERROR_THREAD_NOT_ALIVE;
++    }
++  }
++
++  // event_type must be valid
++  if (!JvmtiEventController::is_valid_event_type(event_type)) {
++    return JVMTI_ERROR_INVALID_EVENT_TYPE;
++  }
++
++  // global events cannot be controlled at thread level.
++  if (java_thread != NULL && JvmtiEventController::is_global_event(event_type)) {
++    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
++  }
++
++  bool enabled = (mode == JVMTI_ENABLE);
++
++  // assure that needed capabilities are present
++  if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
++    return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
++  }
++
++  if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
++    record_class_file_load_hook_enabled();
++  }
++  JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled);
++
++  return JVMTI_ERROR_NONE;
++} /* end SetEventNotificationMode */
++
++  //
++  // Capability functions
++  //
++
++// capabilities_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) {
++  JvmtiManageCapabilities::get_potential_capabilities(get_capabilities(),
++                                                      get_prohibited_capabilities(),
++                                                      capabilities_ptr);
++  return JVMTI_ERROR_NONE;
++} /* end GetPotentialCapabilities */
++
++
++// capabilities_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::AddCapabilities(const jvmtiCapabilities* capabilities_ptr) {
++  return JvmtiManageCapabilities::add_capabilities(get_capabilities(),
++                                                   get_prohibited_capabilities(),
++                                                   capabilities_ptr,
++                                                   get_capabilities());
++} /* end AddCapabilities */
++
++
++// capabilities_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) {
++  JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities());
++  return JVMTI_ERROR_NONE;
++} /* end RelinquishCapabilities */
++
++
++// capabilities_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetCapabilities(jvmtiCapabilities* capabilities_ptr) {
++  JvmtiManageCapabilities::copy_capabilities(get_capabilities(), capabilities_ptr);
++  return JVMTI_ERROR_NONE;
++} /* end GetCapabilities */
++
++  //
++  // Class Loader Search functions
++  //
++
++// segment - pre-checked for NULL
++jvmtiError
++JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) {
++  jvmtiPhase phase = get_phase();
++  if (phase == JVMTI_PHASE_ONLOAD) {
++    Arguments::append_sysclasspath(segment);
++    return JVMTI_ERROR_NONE;
++  } else {
++    assert(phase == JVMTI_PHASE_LIVE, "sanity check");
++
++    // create the zip entry
++    ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
++    if (zip_entry == NULL) {
++      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
++    }
++
++    // lock the loader
++    Thread* thread = Thread::current();
++    HandleMark hm;
++    Handle loader_lock = Handle(thread, SystemDictionary::system_loader_lock());
++
++    ObjectLocker ol(loader_lock, thread);
++
++    // add the jar file to the bootclasspath
++    if (TraceClassLoading) {
++      tty->print_cr("[Opened %s]", zip_entry->name());
++    }
++    ClassLoader::add_to_list(zip_entry);
++    return JVMTI_ERROR_NONE;
++  }
++
++} /* end AddToBootstrapClassLoaderSearch */
++
++
++// segment - pre-checked for NULL
++jvmtiError
++JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) {
++  jvmtiPhase phase = get_phase();
++
++  if (phase == JVMTI_PHASE_ONLOAD) {
++    for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
++      if (strcmp("java.class.path", p->key()) == 0) {
++        p->append_value(segment);
++        break;
++      }
++    }
++    return JVMTI_ERROR_NONE;
++  } else {
++    HandleMark hm;
++
++    assert(phase == JVMTI_PHASE_LIVE, "sanity check");
++
++    // create the zip entry (which will open the zip file and hence
++    // check that the segment is indeed a zip file).
++    ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
++    if (zip_entry == NULL) {
++      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
++    }
++    delete zip_entry;   // no longer needed
++
++    // lock the loader
++    Thread* THREAD = Thread::current();
++    Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
++
++    ObjectLocker ol(loader, THREAD);
++
++    // need the path as java.lang.String
++    Handle path = java_lang_String::create_from_str(segment, THREAD);
++    if (HAS_PENDING_EXCEPTION) {
++      CLEAR_PENDING_EXCEPTION;
++      return JVMTI_ERROR_INTERNAL;
++    }
++
++    instanceKlassHandle loader_ik(THREAD, loader->klass());
++
++    // Invoke the appendToClassPathForInstrumentation method - if the method
++    // is not found it means the loader doesn't support adding to the class path
++    // in the live phase.
++    {
++      JavaValue res(T_VOID);
++      JavaCalls::call_special(&res,
++                              loader,
++                              loader_ik,
++                              vmSymbolHandles::appendToClassPathForInstrumentation_name(),
++                              vmSymbolHandles::appendToClassPathForInstrumentation_signature(),
++                              path,
++                              THREAD);
++      if (HAS_PENDING_EXCEPTION) {
++        symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
++        CLEAR_PENDING_EXCEPTION;
++
++        if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) {
++          return JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED;
++        } else {
++          return JVMTI_ERROR_INTERNAL;
++        }
++      }
++    }
++
++    return JVMTI_ERROR_NONE;
++  }
++} /* end AddToSystemClassLoaderSearch */
++
++  //
++  // General functions
++  //
++
++// phase_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetPhase(jvmtiPhase* phase_ptr) {
++  *phase_ptr = get_phase();
++  return JVMTI_ERROR_NONE;
++} /* end GetPhase */
++
++
++jvmtiError
++JvmtiEnv::DisposeEnvironment() {
++  dispose();
++  return JVMTI_ERROR_NONE;
++} /* end DisposeEnvironment */
++
++
++// data - NULL is a valid value, must be checked
++jvmtiError
++JvmtiEnv::SetEnvironmentLocalStorage(const void* data) {
++  set_env_local_storage(data);
++  return JVMTI_ERROR_NONE;
++} /* end SetEnvironmentLocalStorage */
++
++
++// data_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetEnvironmentLocalStorage(void** data_ptr) {
++  *data_ptr = (void*)get_env_local_storage();
++  return JVMTI_ERROR_NONE;
++} /* end GetEnvironmentLocalStorage */
++
++// version_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetVersionNumber(jint* version_ptr) {
++  *version_ptr = JVMTI_VERSION;
++  return JVMTI_ERROR_NONE;
++} /* end GetVersionNumber */
++
++
++// name_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetErrorName(jvmtiError error, char** name_ptr) {
++  if (error < JVMTI_ERROR_NONE || error > JVMTI_ERROR_MAX) {
++    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
++  }
++  const char *name = JvmtiUtil::error_name(error);
++  if (name == NULL) {
++    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
++  }
++  size_t len = strlen(name) + 1;
++  jvmtiError err = allocate(len, (unsigned char**)name_ptr);
++  if (err == JVMTI_ERROR_NONE) {
++    memcpy(*name_ptr, name, len);
++  }
++  return err;
++} /* end GetErrorName */
++
++
++jvmtiError
++JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) {
++  switch (flag) {
++  case JVMTI_VERBOSE_OTHER:
++    // ignore
++    break;
++  case JVMTI_VERBOSE_CLASS:
++    TraceClassLoading = value != 0;
++    TraceClassUnloading = value != 0;
++    break;
++  case JVMTI_VERBOSE_GC:
++    PrintGC = value != 0;
++    TraceClassUnloading = value != 0;
++    break;
++  case JVMTI_VERBOSE_JNI:
++    PrintJNIResolving = value != 0;
++    break;
++  default:
++    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
++  };
++  return JVMTI_ERROR_NONE;
++} /* end SetVerboseFlag */
++
++
++// format_ptr - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) {
++  *format_ptr = JVMTI_JLOCATION_JVMBCI;
++  return JVMTI_ERROR_NONE;
++} /* end GetJLocationFormat */
++
++#ifndef JVMTI_KERNEL
+ 
+   //
+   // Thread functions
+@@ -550,102 +1056,42 @@
+ // proc - pre-checked for NULL
+ // arg - NULL is a valid value, must be checked
+ jvmtiError
+-JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) {
+-  oop thread_oop = JNIHandles::resolve_external_guard(thread);
+-  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::thread_klass())) {
+-    return JVMTI_ERROR_INVALID_THREAD;
+-  }
+-  if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
+-    return JVMTI_ERROR_INVALID_PRIORITY;
+-  }
+-
+-  //Thread-self
+-  JavaThread* current_thread = JavaThread::current(); 
+-
+-  Handle thread_hndl(current_thread, thread_oop);
+-  {
+-    MutexLocker mu(Threads_lock); // grab Threads_lock
+-
+-    JvmtiAgentThread *new_thread = new JvmtiAgentThread(this, proc, arg);
+-
+-    // At this point it may be possible that no osthread was created for the
+-    // JavaThread due to lack of memory.
+-    if (new_thread == NULL || new_thread->osthread() == NULL) {
+-      if (new_thread) delete new_thread;
+-      return JVMTI_ERROR_OUT_OF_MEMORY;
+-    }
+-
+-    java_lang_Thread::set_thread(thread_hndl(), new_thread);
+-    java_lang_Thread::set_priority(thread_hndl(), (ThreadPriority)priority);
+-    java_lang_Thread::set_daemon(thread_hndl());
+-
+-    new_thread->set_threadObj(thread_hndl());
+-    Threads::add(new_thread);
+-    Thread::start(new_thread);
+-  } // unlock Threads_lock
+-
+-  return JVMTI_ERROR_NONE;
+-} /* end RunAgentThread */
+-
+-
+-// Threads_lock NOT held, java_thread not protected by lock
+-// java_thread - pre-checked
+-// data - NULL is a valid value, must be checked
+-jvmtiError
+-JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) {
+-  JvmtiThreadState* state = java_thread->jvmti_thread_state();
+-  if (state == NULL) {
+-    if (data == NULL) {
+-      // leaving state unset same as data set to NULL
+-      return JVMTI_ERROR_NONE;
+-    }
+-    // otherwise, create the state
+-    state = JvmtiThreadState::state_for(java_thread);
+-  }
+-  state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data);
+-  return JVMTI_ERROR_NONE;
+-} /* end SetThreadLocalStorage */
+-
+-
+-// Threads_lock NOT held
+-// thread - NOT pre-checked
+-// data_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetThreadLocalStorage(jthread thread, void** data_ptr) {
+-  JavaThread* current_thread = JavaThread::current();
+-  if (thread == NULL) {
+-    JvmtiThreadState* state = current_thread->jvmti_thread_state();
+-    *data_ptr = (state == NULL) ? NULL :
+-      state->env_thread_state(this)->get_agent_thread_local_storage_data();
+-  } else {
+-
+-    // jvmti_GetThreadLocalStorage is "in native" and doesn't transition
+-    // the thread to _thread_in_vm. However, when the TLS for a thread
+-    // other than the current thread is required we need to transition
+-    // from native so as to resolve the jthread.
+-
+-    ThreadInVMfromNative __tiv(current_thread);
+-    __ENTRY(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread) 
+-    debug_only(VMNativeEntryWrapper __vew;) 
+-
+-    oop thread_oop = JNIHandles::resolve_external_guard(thread);
+-    if (thread_oop == NULL) {
+-      return JVMTI_ERROR_INVALID_THREAD;
+-    }
+-    if (!thread_oop->is_a(SystemDictionary::thread_klass())) {
++JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) {
++  oop thread_oop = JNIHandles::resolve_external_guard(thread);
++  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::thread_klass())) {
+       return JVMTI_ERROR_INVALID_THREAD;
+     }
+-    JavaThread* java_thread = java_lang_Thread::thread(thread_oop); 
+-    if (java_thread == NULL) {
+-      return JVMTI_ERROR_THREAD_NOT_ALIVE;
++  if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
++    return JVMTI_ERROR_INVALID_PRIORITY;
+     }
+-    JvmtiThreadState* state = java_thread->jvmti_thread_state();
+-    *data_ptr = (state == NULL) ? NULL :
+-      state->env_thread_state(this)->get_agent_thread_local_storage_data();
++
++  //Thread-self
++  JavaThread* current_thread = JavaThread::current();
++
++  Handle thread_hndl(current_thread, thread_oop);
++  {
++    MutexLocker mu(Threads_lock); // grab Threads_lock
++
++    JvmtiAgentThread *new_thread = new JvmtiAgentThread(this, proc, arg);
++
++    // At this point it may be possible that no osthread was created for the
++    // JavaThread due to lack of memory.
++    if (new_thread == NULL || new_thread->osthread() == NULL) {
++      if (new_thread) delete new_thread;
++      return JVMTI_ERROR_OUT_OF_MEMORY;
+   }
+-  return JVMTI_ERROR_NONE;
+-} /* end GetThreadLocalStorage */
+ 
++    java_lang_Thread::set_thread(thread_hndl(), new_thread);
++    java_lang_Thread::set_priority(thread_hndl(), (ThreadPriority)priority);
++    java_lang_Thread::set_daemon(thread_hndl());
++
++    new_thread->set_threadObj(thread_hndl());
++    Threads::add(new_thread);
++    Thread::start(new_thread);
++  } // unlock Threads_lock
++
++  return JVMTI_ERROR_NONE;
++} /* end RunAgentThread */
+ 
+   //
+   // Thread Group functions
+@@ -1554,28 +2000,10 @@
+   return JVMTI_ERROR_NONE;
+ } /* end ClearFieldModificationWatch */
+ 
+-
+   //
+   // Class functions
+   // 
+ 
+-// class_count_ptr - pre-checked for NULL
+-// classes_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) {
+-  return JvmtiGetLoadedClasses::getLoadedClasses(this, class_count_ptr, classes_ptr);
+-} /* end GetLoadedClasses */
+-
+-
+-// initiating_loader - NULL is a valid value, must be checked
+-// class_count_ptr - pre-checked for NULL
+-// classes_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) {
+-  return JvmtiGetLoadedClasses::getClassLoaderClasses(this, initiating_loader, 
+-                                                  class_count_ptr, classes_ptr);
+-} /* end GetClassLoaderClasses */
+-
+ 
+ // k_mirror - may be primitive, this must be checked
+ // signature_ptr - NULL is a valid value, must be checked
+@@ -1982,16 +2410,6 @@
+ 
+ 
+ // k_mirror - may be primitive, this must be checked
+-// is_modifiable_class_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::IsModifiableClass(oop k_mirror, jboolean* is_modifiable_class_ptr) {
+-  *is_modifiable_class_ptr = VM_RedefineClasses::is_modifiable_class(k_mirror)?
+-                                                       JNI_TRUE : JNI_FALSE;
+-  return JVMTI_ERROR_NONE;
+-} /* end IsModifiableClass */
+-
+-
+-// k_mirror - may be primitive, this must be checked
+ // classloader_ptr - pre-checked for NULL
+ jvmtiError
+ JvmtiEnv::GetClassLoader(oop k_mirror, jobject* classloader_ptr) {
+@@ -2046,108 +2464,10 @@
+   return JVMTI_ERROR_NONE;
+ } /* end GetSourceDebugExtension */
+ 
+-
+-// class_count - pre-checked to be greater than or equal to 0
+-// classes - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
+-//TODO: add locking
+-
+-  int index;
+-  JavaThread* current_thread = JavaThread::current(); 
+-  ResourceMark rm(current_thread);  
+-
+-  jvmtiClassDefinition* class_definitions = 
+-                            NEW_RESOURCE_ARRAY(jvmtiClassDefinition, class_count);
+-  NULL_CHECK(class_definitions, JVMTI_ERROR_OUT_OF_MEMORY);
+-
+-  for (index = 0; index < class_count; index++) {
+-    HandleMark hm(current_thread);
+-
+-    jclass jcls = classes[index];
+-    oop k_mirror = JNIHandles::resolve_external_guard(jcls);
+-    if (k_mirror == NULL) {
+-      return JVMTI_ERROR_INVALID_CLASS;
+-    }
+-    if (!k_mirror->is_a(SystemDictionary::class_klass())) {
+-      return JVMTI_ERROR_INVALID_CLASS;
+-    }
+-
+-    if (java_lang_Class::is_primitive(k_mirror)) {
+-      return JVMTI_ERROR_UNMODIFIABLE_CLASS;   
+-    }
+-    
+-    klassOop k_oop = java_lang_Class::as_klassOop(k_mirror);
+-    KlassHandle klass(current_thread, k_oop);
+-    
+-    jint status = klass->jvmti_class_status();
+-    if (status & (JVMTI_CLASS_STATUS_ERROR)) {
+-      return JVMTI_ERROR_INVALID_CLASS;
+-    }
+-    if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
+-      return JVMTI_ERROR_UNMODIFIABLE_CLASS;   
+-    }
+-
+-    instanceKlassHandle ikh(current_thread, k_oop);
+-    if (ikh->get_cached_class_file_bytes() == NULL) {
+-      // not cached, we need to reconstitute the class file from VM representation
+-      constantPoolHandle  constants(current_thread, ikh->constants());
+-      ObjectLocker ol(constants, current_thread);    // lock constant pool while we query it
+-      
+-      JvmtiClassFileReconstituter reconstituter(ikh);
+-      if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
+-        return reconstituter.get_error();
+-      }
+-
+-      class_definitions[index].class_byte_count = (jint)reconstituter.class_file_size();
+-      class_definitions[index].class_bytes      = (unsigned char*)
+-                                                       reconstituter.class_file_bytes();
+-    } else {
+-      // it is cached, get it from the cache
+-      class_definitions[index].class_byte_count = ikh->get_cached_class_file_len();
+-      class_definitions[index].class_bytes      = ikh->get_cached_class_file_bytes();
+-    }
+-    class_definitions[index].klass              = jcls;
+-  }
+-  VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
+-  VMThread::execute(&op);
+-  return (op.check_error());
+-} /* end RetransformClasses */
+-
+-
+-// class_count - pre-checked to be greater than or equal to 0
+-// class_definitions - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) {
+-//TODO: add locking
+-  VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
+-  VMThread::execute(&op);
+-  return (op.check_error());
+-} /* end RedefineClasses */
+-
+-
+   //
+   // Object functions
+   // 
+ 
+-// size_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) {
+-  oop mirror = JNIHandles::resolve_external_guard(object);
+-  NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
+-
+-  if (mirror->klass() == SystemDictionary::class_klass()) {
+-    if (!java_lang_Class::is_primitive(mirror)) {
+-	mirror = java_lang_Class::as_klassOop(mirror);
+-	assert(mirror != NULL, "class for non-primitive mirror must exist");
+-    }
+-  }
+-
+-  *size_ptr = mirror->size() * wordSize;
+-  return JVMTI_ERROR_NONE;
+-} /* end GetObjectSize */
+-
+-
+ // hash_code_ptr - pre-checked for NULL
+ jvmtiError
+ JvmtiEnv::GetObjectHashCode(jobject object, jint* hash_code_ptr) {
+@@ -2538,32 +2858,6 @@
+   return JVMTI_ERROR_NONE;
+ } /* end IsMethodObsolete */
+ 
+-
+-// prefix - NULL is a valid value, must be checked
+-jvmtiError
+-JvmtiEnv::SetNativeMethodPrefix(const char* prefix) {
+-  return prefix == NULL? 
+-              SetNativeMethodPrefixes(0, NULL) : 
+-              SetNativeMethodPrefixes(1, (char**)&prefix);
+-} /* end SetNativeMethodPrefix */
+-
+-
+-// prefix_count - pre-checked to be greater than or equal to 0
+-// prefixes - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::SetNativeMethodPrefixes(jint prefix_count, char** prefixes) {
+-  // Have to grab JVMTI thread state lock to be sure that some thread
+-  // isn't accessing the prefixes at the same time we are setting them. 
+-  // No locks during VM bring-up.
+-  if (Threads::number_of_threads() == 0) {
+-    return set_native_method_prefixes(prefix_count, prefixes);
+-  } else {
+-    MutexLocker mu(JvmtiThreadState_lock);
+-    return set_native_method_prefixes(prefix_count, prefixes);
+-  }
+-} /* end SetNativeMethodPrefixes */
+-
+-
+   //
+   // Raw Monitor functions
+   // 
+@@ -2853,6 +3147,7 @@
+   // JNI Function Interception functions
+   // 
+ 
++
+ // function_table - pre-checked for NULL
+ jvmtiError
+ JvmtiEnv::SetJNIFunctionTable(const jniNativeInterface* function_table) {
+@@ -2864,73 +3159,20 @@
+ } /* end SetJNIFunctionTable */
+ 
+ 
+-// function_table - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) {
+-  *function_table=(jniNativeInterface*)jvmtiMalloc(sizeof(jniNativeInterface));
+-  if (*function_table == NULL)
+-    return JVMTI_ERROR_OUT_OF_MEMORY;
+-  memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface));
+-  return JVMTI_ERROR_NONE;
+-} /* end GetJNIFunctionTable */
+-
+-
+-  //
+-  // Event Management functions
+-  // 
+-
+-// callbacks - NULL is a valid value, must be checked
+-// size_of_callbacks - pre-checked to be greater than or equal to 0
+-jvmtiError
+-JvmtiEnv::SetEventCallbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks) {
+-  JvmtiEventController::set_event_callbacks(this, callbacks, size_of_callbacks);
+-  return JVMTI_ERROR_NONE;
+-} /* end SetEventCallbacks */
+-
+-
+-// event_thread - NULL is a valid value, must be checked
+-jvmtiError
+-JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread,   ...) {
+-  JavaThread* java_thread = NULL;
+-  if (event_thread != NULL) {
+-    oop thread_oop = JNIHandles::resolve_external_guard(event_thread);
+-    if (thread_oop == NULL) {
+-      return JVMTI_ERROR_INVALID_THREAD;
+-    }
+-    if (!thread_oop->is_a(SystemDictionary::thread_klass())) {
+-      return JVMTI_ERROR_INVALID_THREAD;
+-    }
+-    java_thread = java_lang_Thread::thread(thread_oop); 
+-    if (java_thread == NULL) {
+-      return JVMTI_ERROR_THREAD_NOT_ALIVE;
+-    }
+-  }
+-
+-  // event_type must be valid
+-  if (!JvmtiEventController::is_valid_event_type(event_type)) {
+-    return JVMTI_ERROR_INVALID_EVENT_TYPE;
+-  }
+-
+-  // global events cannot be controlled at thread level.
+-  if (java_thread != NULL && JvmtiEventController::is_global_event(event_type)) {
+-    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+-  }
+-       
+-  bool enabled = (mode == JVMTI_ENABLE);
+-
+-  // assure that needed capabilities are present
+-  if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
+-    return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
+-  }
+-       
+-  if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
+-    record_class_file_load_hook_enabled();
+-  }
+-  JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled);
+-  
++// function_table - pre-checked for NULL
++jvmtiError
++JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) {
++  *function_table=(jniNativeInterface*)jvmtiMalloc(sizeof(jniNativeInterface));
++  if (*function_table == NULL)
++    return JVMTI_ERROR_OUT_OF_MEMORY;
++  memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface));
+   return JVMTI_ERROR_NONE;
+-} /* end SetEventNotificationMode */
++} /* end GetJNIFunctionTable */
++
+ 
++  //
++  // Event Management functions
++  //
+ 
+ jvmtiError
+ JvmtiEnv::GenerateEvents(jvmtiEvent event_type) {
+@@ -2980,47 +3222,6 @@
+   return JvmtiExtensions::set_event_callback(this, extension_event_index, callback);
+ } /* end SetExtensionEventCallback */
+ 
+-
+-  //
+-  // Capability functions
+-  // 
+-
+-// capabilities_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) {
+-  JvmtiManageCapabilities::get_potential_capabilities(get_capabilities(), 
+-                                                      get_prohibited_capabilities(),
+-                                                      capabilities_ptr);
+-  return JVMTI_ERROR_NONE;
+-} /* end GetPotentialCapabilities */
+-
+-
+-// capabilities_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::AddCapabilities(const jvmtiCapabilities* capabilities_ptr) {
+-  return JvmtiManageCapabilities::add_capabilities(get_capabilities(), 
+-                                                   get_prohibited_capabilities(),
+-                                                   capabilities_ptr, 
+-                                                   get_capabilities());
+-} /* end AddCapabilities */
+-
+-
+-// capabilities_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) {
+-  JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities());
+-  return JVMTI_ERROR_NONE;  
+-} /* end RelinquishCapabilities */
+-
+-
+-// capabilities_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetCapabilities(jvmtiCapabilities* capabilities_ptr) {
+-  JvmtiManageCapabilities::copy_capabilities(get_capabilities(), capabilities_ptr);
+-  return JVMTI_ERROR_NONE;  
+-} /* end GetCapabilities */
+-
+-
+   //
+   // Timers functions
+   // 
+@@ -3082,115 +3283,6 @@
+   return JVMTI_ERROR_NONE;
+ } /* end GetAvailableProcessors */
+ 
+-
+-  //
+-  // Class Loader Search functions
+-  // 
+-
+-// segment - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) {
+-  jvmtiPhase phase = get_phase();
+-  if (phase == JVMTI_PHASE_ONLOAD) {
+-    Arguments::append_sysclasspath(segment);
+-    return JVMTI_ERROR_NONE;
+-  } else {
+-    assert(phase == JVMTI_PHASE_LIVE, "sanity check");
+-
+-    // create the zip entry
+-    ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
+-    if (zip_entry == NULL) {
+-      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+-    }
+-
+-    // lock the loader 
+-    Thread* thread = Thread::current();
+-    HandleMark hm;
+-    Handle loader_lock = Handle(thread, SystemDictionary::system_loader_lock());
+-
+-    ObjectLocker ol(loader_lock, thread);
+-
+-    // add the jar file to the bootclasspath
+-    if (TraceClassLoading) {
+-      tty->print_cr("[Opened %s]", zip_entry->name());
+-    }
+-    ClassLoader::add_to_list(zip_entry);
+-    return JVMTI_ERROR_NONE;
+-  }
+-
+-} /* end AddToBootstrapClassLoaderSearch */
+-
+-
+-// segment - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) {
+-  jvmtiPhase phase = get_phase();
+-
+-  if (phase == JVMTI_PHASE_ONLOAD) {
+-    for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
+-      if (strcmp("java.class.path", p->key()) == 0) {
+-	p->append_value(segment);
+- 	break;	
+-      }
+-    }
+-    return JVMTI_ERROR_NONE;
+-  } else {
+-    HandleMark hm;
+-
+-    assert(phase == JVMTI_PHASE_LIVE, "sanity check");
+-
+-    // create the zip entry (which will open the zip file and hence
+-    // check that the segment is indeed a zip file).
+-    ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
+-    if (zip_entry == NULL) {
+-      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+-    }
+-    delete zip_entry;	// no longer needed
+-
+-    // lock the loader
+-    Thread* THREAD = Thread::current();
+-    Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
+-
+-    ObjectLocker ol(loader, THREAD);
+-
+-    // need the path as java.lang.String
+-    Handle path = java_lang_String::create_from_str(segment, THREAD);
+-    if (HAS_PENDING_EXCEPTION) {
+-      CLEAR_PENDING_EXCEPTION;
+-      return JVMTI_ERROR_INTERNAL;
+-    }
+-
+-    instanceKlassHandle loader_ik(THREAD, loader->klass());
+-
+-    // Invoke the appendToClassPathForInstrumentation method - if the method
+-    // is not found it means the loader doesn't support adding to the class path
+-    // in the live phase.
+-    {
+-      JavaValue res(T_VOID);
+-      JavaCalls::call_special(&res,
+-			      loader,
+-			      loader_ik,
+-                              vmSymbolHandles::appendToClassPathForInstrumentation_name(),
+-                              vmSymbolHandles::appendToClassPathForInstrumentation_signature(),
+-			      path,
+-                              THREAD);
+-      if (HAS_PENDING_EXCEPTION) {
+-	symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
+-	CLEAR_PENDING_EXCEPTION;
+-
+-	if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) {
+-	  return JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED;
+-	} else {
+-	  return JVMTI_ERROR_INTERNAL;
+-	}
+-      }
+-    }
+-
+-    return JVMTI_ERROR_NONE;
+-  }
+-} /* end AddToSystemClassLoaderSearch */
+-
+-
+   //
+   // System Properties functions
+   // 
+@@ -3263,96 +3355,4 @@
+   return err;
+ } /* end SetSystemProperty */
+ 
+-
+-  //
+-  // General functions
+-  // 
+-
+-// phase_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetPhase(jvmtiPhase* phase_ptr) {
+-  *phase_ptr = get_phase();
+-  return JVMTI_ERROR_NONE;
+-} /* end GetPhase */
+-
+-
+-jvmtiError
+-JvmtiEnv::DisposeEnvironment() {
+-  dispose();
+-  return JVMTI_ERROR_NONE;
+-} /* end DisposeEnvironment */
+-
+-
+-// data - NULL is a valid value, must be checked
+-jvmtiError
+-JvmtiEnv::SetEnvironmentLocalStorage(const void* data) {
+-  set_env_local_storage(data);
+-  return JVMTI_ERROR_NONE;
+-} /* end SetEnvironmentLocalStorage */
+-
+-
+-// data_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetEnvironmentLocalStorage(void** data_ptr) {
+-  *data_ptr = (void*)get_env_local_storage();
+-  return JVMTI_ERROR_NONE;
+-} /* end GetEnvironmentLocalStorage */
+-
+-
+-// version_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetVersionNumber(jint* version_ptr) {
+-  *version_ptr = JVMTI_VERSION;
+-  return JVMTI_ERROR_NONE;
+-} /* end GetVersionNumber */
+-
+-
+-// name_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetErrorName(jvmtiError error, char** name_ptr) {
+-  if (error < JVMTI_ERROR_NONE || error > JVMTI_ERROR_MAX) {
+-    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+-  }
+-  const char *name = JvmtiUtil::error_name(error);
+-  if (name == NULL) {
+-    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+-  }
+-  size_t len = strlen(name) + 1;
+-  jvmtiError err = allocate(len, (unsigned char**)name_ptr);
+-  if (err == JVMTI_ERROR_NONE) {
+-    memcpy(*name_ptr, name, len);
+-  }
+-  return err;
+-} /* end GetErrorName */
+-
+-
+-jvmtiError
+-JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) {
+-  switch (flag) {
+-  case JVMTI_VERBOSE_OTHER:
+-    // ignore
+-    break;
+-  case JVMTI_VERBOSE_CLASS:
+-    TraceClassLoading = value != 0;
+-    TraceClassUnloading = value != 0;
+-    break;
+-  case JVMTI_VERBOSE_GC:
+-    PrintGC = value != 0;
+-    TraceClassUnloading = value != 0;
+-    break;
+-  case JVMTI_VERBOSE_JNI:
+-    PrintJNIResolving = value != 0;
+-    break;
+-  default:
+-    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+-  };    
+-  return JVMTI_ERROR_NONE;
+-} /* end SetVerboseFlag */
+-
+-
+-// format_ptr - pre-checked for NULL
+-jvmtiError
+-JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) {
+-  *format_ptr = JVMTI_JLOCATION_JVMBCI;
+-  return JVMTI_ERROR_NONE;
+-} /* end GetJLocationFormat */
++#endif // !JVMTI_KERNEL
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnvFill.java openjdk/hotspot/src/share/vm/prims/jvmtiEnvFill.java
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEnvFill.java	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEnvFill.java	2007-12-14 08:57:03.000000000 +0100
+@@ -211,7 +211,7 @@
+ 		top.add(line);
+ 	    } else {
+ 		trimmed = line.trim();
+-		if (!trimmed.equals("") && !trimmed.startsWith("//")) {
++                if (!trimmed.equals("") && !trimmed.startsWith("//") && !trimmed.startsWith("#")) {
+ 		    error("only comments and blank lines allowed between functions");
+ 		}
+ 		before.add(line);
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp openjdk/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiEnvThreadState.cpp	1.23 07/05/23 10:53:46 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -314,4 +311,3 @@
+     clear_current_location();
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp openjdk/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiEnvThreadState.hpp	1.17 07/05/05 17:06:37 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -176,4 +173,3 @@
+ };
+ 
+ #endif   /* _JAVA_JVMTIENVTHREADSTATE_H_ */
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.cpp openjdk/hotspot/src/share/vm/prims/jvmtiEventController.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEventController.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiEventController.cpp	1.56 07/05/23 10:53:48 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -322,7 +319,7 @@
+ void VM_ChangeSingleStep::doit() {
+   JvmtiEventControllerPrivate::set_should_post_single_step(_on);
+   if (_on) {
+-    AbstractInterpreter::notice_safepoints();
++    Interpreter::notice_safepoints();
+   }
+ }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.hpp openjdk/hotspot/src/share/vm/prims/jvmtiEventController.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEventController.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiEventController.hpp	1.22 07/05/05 17:06:37 JVM"
+-#endif
+ /*
+  * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.inline.hpp openjdk/hotspot/src/share/vm/prims/jvmtiEventController.inline.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.inline.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEventController.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiEventController.inline.hpp	1.14 07/05/05 17:06:37 JVM"
+-#endif
+ /*
+  * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -102,4 +99,3 @@
+ inline bool JvmtiEventController::is_enabled(jvmtiEvent event_type) {
+   return _universal_global_event_enabled.is_enabled(event_type);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiExport.cpp openjdk/hotspot/src/share/vm/prims/jvmtiExport.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiExport.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiExport.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiExport.cpp	1.125 07/05/29 09:44:25 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -36,7 +33,6 @@
+ #define EVT_TRACE(evt,out)
+ #endif
+ 
+-
+ ///////////////////////////////////////////////////////////////
+ //
+ // JvmtiEventTransition
+@@ -268,225 +264,58 @@
+   }
+ };
+ 
+-static inline klassOop oop_to_klassOop(oop obj) {
+-  klassOop k = obj->klass();
+-
+-  // if the object is a java.lang.Class then return the java mirror
+-  if (k == SystemDictionary::class_klass()) {
+-    if (!java_lang_Class::is_primitive(obj)) {
+-      k = java_lang_Class::as_klassOop(obj);
+-      assert(k != NULL, "class for non-primitive mirror must exist");      
+-    }
+-  }  
+-  return k;
+-}
+-
+-class JvmtiVMObjectAllocEventMark : public JvmtiClassEventMark  {
+- private:
+-   jobject _jobj;
+-   jlong    _size;
+- public:
+-   JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klassOop(obj)) {
+-     _jobj = (jobject)to_jobject(obj);
+-     _size = obj->size() * wordSize;
+-   };
+-   jobject jni_jobject() { return _jobj; }
+-   jlong size() { return _size; }
+-};
+-
+-class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark {
+- private:
+-  jint _code_size;
+-  const void *_code_data;
+-  jint _map_length;
+-  jvmtiAddrLocationMap *_map;
+-  const void *_compile_info;    
+- public:
+-  JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm)
+-          : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
+-    _code_data = nm->code_begin();
+-    _code_size = nm->code_size();
+-    _compile_info = NULL; /* no info for our VM. */
+-    JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
+-  }
+-  ~JvmtiCompiledMethodLoadEventMark() {
+-     FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map);
+-  }
+-    
+-  jint code_size() { return _code_size; }
+-  const void *code_data() { return _code_data; }
+-  jint map_length() { return _map_length; }
+-  const jvmtiAddrLocationMap* map() { return _map; }
+-  const void *compile_info() { return _compile_info; }
+-};
++//////////////////////////////////////////////////////////////////////////////
+ 
++int               JvmtiExport::_field_access_count                        = 0;
++int               JvmtiExport::_field_modification_count                  = 0;
+ 
++bool              JvmtiExport::_can_access_local_variables                = false;
++bool              JvmtiExport::_can_examine_or_deopt_anywhere             = false;
++bool              JvmtiExport::_can_hotswap_or_post_breakpoint            = false;
++bool              JvmtiExport::_can_modify_any_class                      = false;
++bool              JvmtiExport::_can_walk_any_space                        = false;
+ 
+-class JvmtiMonitorEventMark : public JvmtiThreadEventMark {
+-private:
+-  jobject _jobj;
+-public:
+-  JvmtiMonitorEventMark(JavaThread *thread, oop object) 
+-          : JvmtiThreadEventMark(thread){
+-     _jobj = to_jobject(object);
+-  }
+-  jobject jni_object() { return _jobj; }
+-};
++bool              JvmtiExport::_has_redefined_a_class                     = false;
++bool              JvmtiExport::_all_dependencies_are_recorded             = false;
+ 
+-///////////////////////////////////////////////////////////////
+ //
+-// pending CompiledMethodUnload support
++// field access management
+ //
+ 
+-bool JvmtiExport::_have_pending_compiled_method_unload_events;		
+-GrowableArray<jmethodID>* JvmtiExport::_pending_compiled_method_unload_method_ids;	
+-GrowableArray<const void *>* JvmtiExport::_pending_compiled_method_unload_code_begins;	
+-JavaThread* JvmtiExport::_current_poster;
+-
+-// post any pending CompiledMethodUnload events
+-
+-void JvmtiExport::post_pending_compiled_method_unload_events() {
+-  JavaThread* self = JavaThread::current();
+-  assert(!self->owns_locks(), "can't hold locks");
+-
+-  // Indicates if this is the first activiation of this function.
+-  // In theory the profiler's callback could call back into VM and provoke
+-  // another CompiledMethodLoad event to be posted from this thread. As the
+-  // stack rewinds we need to ensure that the original activation does the
+-  // completion and notifies any waiters.
+-  bool first_activation = false;
+-
+-  // the jmethodID (may not be valid) to be used for a single event
+-  jmethodID method;
+-  const void *code_begin;
+-
+-  // grab the monitor and check if another thread is already posting
+-  // events. If there is another thread posting events then we wait
+-  // until it completes. (In theory we could check the pending events to
+-  // see if any of the addresses overlap with the event that we want to
+-  // post but as it will happen so rarely we just block any thread waiting
+-  // to post a CompiledMethodLoad or DynamicCodeGenerated event until all
+-  // pending CompiledMethodUnload events have been posted).
+-  //
+-  // If another thread isn't posting we examine the list of pending jmethodIDs.
+-  // If the list is empty then we are done. If it's not empty then this thread
+-  // (self) becomes the pending event poster and we remove the top (last) 
+-  // event from the list. Note that this means we remove the newest event first
+-  // but as they are all CompiledMethodUnload events the order doesn't matter.
+-  // Once we have removed a jmethodID then we exit the monitor. Any other thread
+-  // wanting to post a CompiledMethodLoad or DynamicCodeGenerated event will 
+-  // be forced to wait on the monitor.
+-  {
+-    MutexLocker mu(JvmtiPendingEvent_lock);
+-    if (_current_poster != self) {
+-      while (_current_poster != NULL) {
+-        JvmtiPendingEvent_lock->wait();
+-      }
+-    }     
+-    if ((_pending_compiled_method_unload_method_ids == NULL) || 
+-        (_pending_compiled_method_unload_method_ids->length() == 0)) {
+-      return;
+-    }
+-    if (_current_poster == NULL) {
+-      _current_poster = self;
+-      first_activation = true;
+-    } else {
+-      // re-entrant
+-      guarantee(_current_poster == self, "checking");
+-    }
+-    method = _pending_compiled_method_unload_method_ids->pop();     
+-    code_begin = _pending_compiled_method_unload_code_begins->pop();     
+-  }
+-
+-  // This thread is the pending event poster so it first posts the CompiledMethodUnload
+-  // event for the jmethodID that has been removed from the list. Once posted it
+-  // re-grabs the monitor and checks the list again. If the list is empty then and this
+-  // is the first activation of the function then we reset the _have_pending_events
+-  // flag, cleanup _current_poster to indicate that no thread is now servicing the
+-  // pending events list, and finally notify any thread that might be waiting.
+-  for (;;) {
+-    EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
+-                   ("JVMTI [%s] method compile unload event triggered",  
+-                   JvmtiTrace::safe_get_thread_name(self)));
+-
+-    // post the event for each environment that has this event enabled.
+-    JvmtiEnvIterator it; 
+-    for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
+-      if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {
+-        EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
+-                  ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT, 
+-                  JvmtiTrace::safe_get_thread_name(self), method));
+- 
+-        JvmtiEventMark jem(self);
+-        JvmtiJavaThreadEventTransition jet(self);
+-        jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;
+-        if (callback != NULL) {
+-          (*callback)(env->jvmti_external(), method, code_begin);
+-        }
+-      }
+-    }
+-
+-    // event posted, now re-grab monitor and get the next event
+-    // If there's no next event then we are done. If this is the first
+-    // activiation of this function by this thread notify any waiters
+-    // so that they can post.
+-    {
+-      MutexLocker ml(JvmtiPendingEvent_lock);      
+-      if (_pending_compiled_method_unload_method_ids->length() == 0) {
+-	if (first_activation) {
+-	  _have_pending_compiled_method_unload_events = false;
+-	  _current_poster = NULL;
+-	  JvmtiPendingEvent_lock->notify_all();
+-	}
+-	return;
+-      }
+-      method = _pending_compiled_method_unload_method_ids->pop();    
+-      code_begin = _pending_compiled_method_unload_code_begins->pop();
+-    }
+-  }
++// interpreter generator needs the address of the counter
++address JvmtiExport::get_field_access_count_addr() {
++  // We don't grab a lock because we don't want to
++  // serialize field access between all threads. This means that a
++  // thread on another processor can see the wrong count value and
++  // may either miss making a needed call into post_field_access()
++  // or will make an unneeded call into post_field_access(). We pay
++  // this price to avoid slowing down the VM when we aren't watching
++  // field accesses.
++  // Other access/mutation safe by virtue of being in VM state.
++  return (address)(&_field_access_count);
+ }
+ 
+-///////////////////////////////////////////////////////////////
+ //
+-// JvmtiExport
++// field modification management
+ //
+ 
+-void JvmtiExport::post_raw_breakpoint(JavaThread *thread, methodOop method, address location) {
+-  HandleMark hm(thread);
+-  methodHandle mh(thread, method);
+-
+-  JvmtiThreadState *state = thread->jvmti_thread_state();
+-  if (state == NULL) {
+-    return;
+-  }
+-  EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Trg Breakpoint triggered",  
+-                      JvmtiTrace::safe_get_thread_name(thread)));
+-  JvmtiEnvThreadStateIterator it(state); 
+-  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
+-    ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT);
+-    if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) {
+-      ThreadState old_os_state = thread->osthread()->get_state();
+-      thread->osthread()->set_state(BREAKPOINTED);
+-      EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint sent %s.%s @ %d",  
+-                     JvmtiTrace::safe_get_thread_name(thread),
+-                     (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
+-                     (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
+-                     location - mh()->code_base() ));
++// interpreter generator needs the address of the counter
++address JvmtiExport::get_field_modification_count_addr() {
++  // We don't grab a lock because we don't
++  // want to serialize field modification between all threads. This
++  // means that a thread on another processor can see the wrong
++  // count value and may either miss making a needed call into
++  // post_field_modification() or will make an unneeded call into
++  // post_field_modification(). We pay this price to avoid slowing
++  // down the VM when we aren't watching field modifications.
++  // Other access/mutation safe by virtue of being in VM state.
++  return (address)(&_field_modification_count);
++}
+ 
+-      JvmtiEnv *env = ets->get_env();
+-      JvmtiLocationEventMark jem(thread, mh, location);
+-      JvmtiJavaThreadEventTransition jet(thread);
+-      jvmtiEventBreakpoint callback = env->callbacks()->Breakpoint;
+-      if (callback != NULL) {
+-        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 
+-                    jem.jni_methodID(), jem.location());
+-      }
+ 
+-      ets->set_breakpoint_posted();
+-      thread->osthread()->set_state(old_os_state);
+-    }
+-  }
+-}
++///////////////////////////////////////////////////////////////
++// Functions needed by java.lang.instrument for starting up javaagent.
++///////////////////////////////////////////////////////////////
+ 
+ jint  
+ JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
+@@ -516,65 +345,14 @@
+   }
+ }
+ 
++void JvmtiExport::enter_primordial_phase() {
++  JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL);
++}
+ 
+-//////////////////////////////////////////////////////////////////////////////
+-
+-int               JvmtiExport::_field_access_count                        = 0;
+-int               JvmtiExport::_field_modification_count                  = 0;
+-
+-bool              JvmtiExport::_can_get_source_debug_extension            = false;
+-bool              JvmtiExport::_can_examine_or_deopt_anywhere             = false;
+-bool              JvmtiExport::_can_maintain_original_method_order        = false;
+-bool              JvmtiExport::_can_post_interpreter_events               = false;
+-bool              JvmtiExport::_can_hotswap_or_post_breakpoint            = false;
+-bool              JvmtiExport::_can_modify_any_class                      = false;
+-bool              JvmtiExport::_can_walk_any_space                        = false;
+-bool              JvmtiExport::_can_access_local_variables                = false;
+-bool              JvmtiExport::_can_post_exceptions                       = false;
+-bool              JvmtiExport::_can_post_breakpoint                       = false;
+-bool              JvmtiExport::_can_post_field_access                     = false;
+-bool              JvmtiExport::_can_post_field_modification               = false;
+-bool              JvmtiExport::_can_post_method_entry                     = false;
+-bool              JvmtiExport::_can_post_method_exit                      = false;
+-bool              JvmtiExport::_can_pop_frame                             = false;
+-bool              JvmtiExport::_can_force_early_return                    = false;
+-
+-bool              JvmtiExport::_should_post_single_step                   = false;
+-bool              JvmtiExport::_should_post_field_access                  = false;
+-bool              JvmtiExport::_should_post_field_modification            = false;
+-bool              JvmtiExport::_should_post_class_load                    = false;
+-bool              JvmtiExport::_should_post_class_prepare                 = false;
+-bool              JvmtiExport::_should_post_class_unload                  = false;
+-bool              JvmtiExport::_should_post_thread_life                   = false;
+-bool              JvmtiExport::_should_clean_up_heap_objects              = false;
+-bool              JvmtiExport::_should_post_class_file_load_hook          = false;
+-bool              JvmtiExport::_should_post_native_method_bind            = false;
+-bool              JvmtiExport::_should_post_dynamic_code_generated        = false;
+-bool              JvmtiExport::_should_post_data_dump                     = false;
+-bool              JvmtiExport::_should_post_compiled_method_load          = false;
+-bool              JvmtiExport::_should_post_compiled_method_unload        = false;
+-bool              JvmtiExport::_should_post_monitor_contended_enter       = false;
+-bool              JvmtiExport::_should_post_monitor_contended_entered     = false;
+-bool              JvmtiExport::_should_post_monitor_wait                  = false;
+-bool              JvmtiExport::_should_post_monitor_waited                = false;
+-bool              JvmtiExport::_should_post_garbage_collection_start      = false;
+-bool              JvmtiExport::_should_post_garbage_collection_finish     = false;
+-bool		  JvmtiExport::_should_post_object_free			  = false;
+-bool		  JvmtiExport::_should_post_resource_exhausted        	  = false;
+-bool              JvmtiExport::_should_post_vm_object_alloc               = false;
+-bool              JvmtiExport::_has_redefined_a_class                     = false;
+-bool		  JvmtiExport::_all_dependencies_are_recorded		  = false;
+-
+-
+-
+-void JvmtiExport::enter_primordial_phase() { 
+-  JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL);
+-}
+-
+-void JvmtiExport::enter_start_phase() { 
+-  JvmtiManageCapabilities::recompute_always_capabilities();
+-  JvmtiEnvBase::set_phase(JVMTI_PHASE_START);
+-}
++void JvmtiExport::enter_start_phase() {
++  JvmtiManageCapabilities::recompute_always_capabilities();
++  JvmtiEnvBase::set_phase(JVMTI_PHASE_START);
++}
+ 
+ void JvmtiExport::enter_onload_phase() { 
+   JvmtiEnvBase::set_phase(JVMTI_PHASE_ONLOAD);
+@@ -584,191 +362,573 @@
+   JvmtiEnvBase::set_phase(JVMTI_PHASE_LIVE);
+ }
+ 
+-
+-
+-////////////////////////////////////////////////////////////////////////////////////////////////
+-
+-
+-//
+-// field access management
+-//
+-
+-// interpreter generator needs the address of the counter
+-address JvmtiExport::get_field_access_count_addr() {
+-  // We don't grab a lock because we don't want to
+-  // serialize field access between all threads. This means that a
+-  // thread on another processor can see the wrong count value and
+-  // may either miss making a needed call into post_field_access()
+-  // or will make an unneeded call into post_field_access(). We pay
+-  // this price to avoid slowing down the VM when we aren't watching
+-  // field accesses.
+-  // Other access/mutation safe by virtue of being in VM state.
+-  return (address)(&_field_access_count);
+-}
+-
+-
+ //
+-// field modification management
++// JVMTI events that the VM posts to the debugger and also startup agent
++// and call the agent's premain() for java.lang.instrument.
+ //
+ 
+-// interpreter generator needs the address of the counter
+-address JvmtiExport::get_field_modification_count_addr() {
+-  // We don't grab a lock because we don't
+-  // want to serialize field modification between all threads. This
+-  // means that a thread on another processor can see the wrong
+-  // count value and may either miss making a needed call into
+-  // post_field_modification() or will make an unneeded call into
+-  // post_field_modification(). We pay this price to avoid slowing
+-  // down the VM when we aren't watching field modifications.
+-  // Other access/mutation safe by virtue of being in VM state.
+-  return (address)(&_field_modification_count);
+-}
+-
++void JvmtiExport::post_vm_start() {
++  EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Trg VM start event triggered" ));
+ 
+-//
+-// JVMTI single step management
+-//
+-void JvmtiExport::at_single_stepping_point(JavaThread *thread, methodOop method, address location) {
+-  assert(JvmtiExport::should_post_single_step(), "must be single stepping");
++  // can now enable some events
++  JvmtiEventController::vm_start();
+ 
+-  HandleMark hm(thread);
+-  methodHandle mh(thread, method);
++  JvmtiEnvIterator it;
++  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
++    if (env->is_enabled(JVMTI_EVENT_VM_START)) {
++      EVT_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Evt VM start event sent" ));
+ 
+-  // update information about current location and post a step event
+-  JvmtiThreadState *state = thread->jvmti_thread_state();
+-  if (state == NULL) {
+-    return;
+-  }
+-  EVT_TRIG_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Trg Single Step triggered",  
+-                      JvmtiTrace::safe_get_thread_name(thread)));
+-  if (!state->hide_single_stepping()) {
+-    if (state->is_pending_step_for_popframe()) {
+-      state->process_pending_step_for_popframe();
++      JavaThread *thread  = JavaThread::current();
++      JvmtiThreadEventMark jem(thread);
++      JvmtiJavaThreadEventTransition jet(thread);
++      jvmtiEventVMStart callback = env->callbacks()->VMStart;
++      if (callback != NULL) {
++        (*callback)(env->jvmti_external(), jem.jni_env());
+     }
+-    if (state->is_pending_step_for_earlyret()) {
+-      state->process_pending_step_for_earlyret();
+     }
+-    JvmtiExport::post_single_step(thread, mh(), location);
+   }
+ }
+ 
+ 
+-void JvmtiExport::expose_single_stepping(JavaThread *thread) {
+-  JvmtiThreadState *state = thread->jvmti_thread_state();
+-  if (state != NULL) {
+-    state->clear_hide_single_stepping();
+-  }
+-}
++void JvmtiExport::post_vm_initialized() {
++  EVT_TRIG_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Trg VM init event triggered" ));
+ 
++  // can now enable events
++  JvmtiEventController::vm_init();
+ 
+-bool JvmtiExport::hide_single_stepping(JavaThread *thread) {
+-  JvmtiThreadState *state = thread->jvmti_thread_state();
+-  if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) { 
+-    state->set_hide_single_stepping();
+-    return true; 
+-  } else {
+-    return false; 
++  JvmtiEnvIterator it;
++  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
++    if (env->is_enabled(JVMTI_EVENT_VM_INIT)) {
++      EVT_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Evt VM init event sent" ));
++
++      JavaThread *thread  = JavaThread::current();
++      JvmtiThreadEventMark jem(thread);
++      JvmtiJavaThreadEventTransition jet(thread);
++      jvmtiEventVMInit callback = env->callbacks()->VMInit;
++      if (callback != NULL) {
++        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
++      }
++    }
+   }
+ }
+ 
+-//
+-// JVMTI events that the VM posts to the debugger
+-//
+-
+-void JvmtiExport::post_vm_start() {
+-  EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Trg VM start event triggered" ));
+ 
+-  // can now enable some events 
+-  JvmtiEventController::vm_start();
++void JvmtiExport::post_vm_death() {
++  EVT_TRIG_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Trg VM death event triggered" ));
+ 
+   JvmtiEnvIterator it; 
+   for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
+-    if (env->is_enabled(JVMTI_EVENT_VM_START)) {
+-      EVT_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Evt VM start event sent" ));
++    if (env->is_enabled(JVMTI_EVENT_VM_DEATH)) {
++      EVT_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Evt VM death event sent" ));
+ 
+       JavaThread *thread  = JavaThread::current();
+-      JvmtiThreadEventMark jem(thread);
++      JvmtiEventMark jem(thread);
+       JvmtiJavaThreadEventTransition jet(thread);
+-      jvmtiEventVMStart callback = env->callbacks()->VMStart;
++      jvmtiEventVMDeath callback = env->callbacks()->VMDeath;
+       if (callback != NULL) {
+         (*callback)(env->jvmti_external(), jem.jni_env());
+       }
+     }
+   }  
++
++  JvmtiEnvBase::set_phase(JVMTI_PHASE_DEAD);
++  JvmtiEventController::vm_death();
++}
++
++char**
++JvmtiExport::get_all_native_method_prefixes(int* count_ptr) {
++  // Have to grab JVMTI thread state lock to be sure environment doesn't
++  // go away while we iterate them.  No locks during VM bring-up.
++  if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) {
++    return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
++  } else {
++    MutexLocker mu(JvmtiThreadState_lock);
++    return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
++  }
+ }
+ 
++class JvmtiClassFileLoadHookPoster : public StackObj {
++ private:
++  symbolHandle         _h_name;
++  Handle               _class_loader;
++  Handle               _h_protection_domain;
++  unsigned char **     _data_ptr;
++  unsigned char **     _end_ptr;
++  JavaThread *         _thread;
++  jint                 _curr_len;
++  unsigned char *      _curr_data;
++  JvmtiEnv *           _curr_env;
++  jint *               _cached_length_ptr;
++  unsigned char **     _cached_data_ptr;
++  JvmtiThreadState *   _state;
++  KlassHandle *        _h_class_being_redefined;
++  JvmtiClassLoadKind   _load_kind;
++
++ public:
++  inline JvmtiClassFileLoadHookPoster(symbolHandle h_name, Handle class_loader,
++                                      Handle h_protection_domain,
++                                      unsigned char **data_ptr, unsigned char **end_ptr,
++                                      unsigned char **cached_data_ptr,
++                                      jint *cached_length_ptr) {
++    _h_name = h_name;
++    _class_loader = class_loader;
++    _h_protection_domain = h_protection_domain;
++    _data_ptr = data_ptr;
++    _end_ptr = end_ptr;
++    _thread = JavaThread::current();
++    _curr_len = *end_ptr - *data_ptr;
++    _curr_data = *data_ptr;
++    _curr_env = NULL;
++    _cached_length_ptr = cached_length_ptr;
++    _cached_data_ptr = cached_data_ptr;
++    *_cached_length_ptr = 0;
++    *_cached_data_ptr = NULL;
++
++    _state = _thread->jvmti_thread_state();
++    if (_state != NULL) {
++      _h_class_being_redefined = _state->get_class_being_redefined();
++      _load_kind = _state->get_class_load_kind();
++      // Clear class_being_redefined flag here. The action
++      // from agent handler could generate a new class file load
++      // hook event and if it is not cleared the new event generated
++      // from regular class file load could have this stale redefined
++      // class handle info.
++      _state->clear_class_being_redefined();
++    } else {
++      // redefine and retransform will always set the thread state
++      _h_class_being_redefined = (KlassHandle *) NULL;
++      _load_kind = jvmti_class_load_kind_load;
++    }
++  }
++
++  void post() {
++//    EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
++//                   ("JVMTI [%s] class file load hook event triggered",
++//                    JvmtiTrace::safe_get_thread_name(_thread)));
++    post_all_envs();
++    copy_modified_data();
++  }
++
++ private:
++  void post_all_envs() {
++    if (_load_kind != jvmti_class_load_kind_retransform) {
++      // for class load and redefine,
++      // call the non-retransformable agents
++      JvmtiEnvIterator it;
++      for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
++        if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
++          // non-retransformable agents cannot retransform back,
++          // so no need to cache the original class file bytes
++          post_to_env(env, false);
++        }
++      }
++    }
++    JvmtiEnvIterator it;
++    for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
++      // retransformable agents get all events
++      if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
++        // retransformable agents need to cache the original class file
++        // bytes if changes are made via the ClassFileLoadHook
++        post_to_env(env, true);
++      }
++    }
++  }
++
++  void post_to_env(JvmtiEnv* env, bool caching_needed) {
++    unsigned char *new_data = NULL;
++    jint new_len = 0;
++//    EVT_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
++//     ("JVMTI [%s] class file load hook event sent %s  data_ptr = %d, data_len = %d",
++//               JvmtiTrace::safe_get_thread_name(_thread),
++//               _h_name.is_null() ? "NULL" : _h_name->as_utf8(),
++//               _curr_data, _curr_len ));
++    JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader,
++                                    _h_protection_domain,
++                                    _h_class_being_redefined);
++    JvmtiJavaThreadEventTransition jet(_thread);
++    JNIEnv* jni_env =  (JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL)?
++                                                        NULL : jem.jni_env();
++    jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook;
++    if (callback != NULL) {
++      (*callback)(env->jvmti_external(), jni_env,
++                  jem.class_being_redefined(),
++                  jem.jloader(), jem.class_name(),
++                  jem.protection_domain(),
++                  _curr_len, _curr_data,
++                  &new_len, &new_data);
++    }
++    if (new_data != NULL) {
++      // this agent has modified class data.
++      if (caching_needed && *_cached_data_ptr == NULL) {
++        // data has been changed by the new retransformable agent
++        // and it hasn't already been cached, cache it
++        *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len);
++        memcpy(*_cached_data_ptr, _curr_data, _curr_len);
++        *_cached_length_ptr = _curr_len;
++      }
++
++      if (_curr_data != *_data_ptr) {
++        // curr_data is previous agent modified class data.
++        // And this has been changed by the new agent so
++        // we can delete it now.
++        _curr_env->Deallocate(_curr_data);
++      }
++
++      // Class file data has changed by the current agent.
++      _curr_data = new_data;
++      _curr_len = new_len;
++      // Save the current agent env we need this to deallocate the
++      // memory allocated by this agent.
++      _curr_env = env;
++    }
++  }
++
++  void copy_modified_data() {
++    // if one of the agent has modified class file data.
++    // Copy modified class data to new resources array.
++    if (_curr_data != *_data_ptr) {
++      *_data_ptr = NEW_RESOURCE_ARRAY(u1, _curr_len);
++      memcpy(*_data_ptr, _curr_data, _curr_len);
++      *_end_ptr = *_data_ptr + _curr_len;
++      _curr_env->Deallocate(_curr_data);
++    }
++  }
++};
++
++bool JvmtiExport::_should_post_class_file_load_hook = false;
++
++// this entry is for class file load hook on class load, redefine and retransform
++void JvmtiExport::post_class_file_load_hook(symbolHandle h_name,
++                                            Handle class_loader,
++                                            Handle h_protection_domain,
++                                            unsigned char **data_ptr,
++                                            unsigned char **end_ptr,
++                                            unsigned char **cached_data_ptr,
++                                            jint *cached_length_ptr) {
++  JvmtiClassFileLoadHookPoster poster(h_name, class_loader,
++                                      h_protection_domain,
++                                      data_ptr, end_ptr,
++                                      cached_data_ptr,
++                                      cached_length_ptr);
++  poster.post();
++}
++
++void JvmtiExport::report_unsupported(bool on) {
++  // If any JVMTI service is turned on, we need to exit before native code
++  // tries to access nonexistant services.
++  if (on) {
++    vm_exit_during_initialization("Java Kernel does not support JVMTI.");
++  }
++}
++
++
++#ifndef JVMTI_KERNEL
++static inline klassOop oop_to_klassOop(oop obj) {
++  klassOop k = obj->klass();
++
++  // if the object is a java.lang.Class then return the java mirror
++  if (k == SystemDictionary::class_klass()) {
++    if (!java_lang_Class::is_primitive(obj)) {
++      k = java_lang_Class::as_klassOop(obj);
++      assert(k != NULL, "class for non-primitive mirror must exist");
++    }
++  }
++  return k;
++}
++
++class JvmtiVMObjectAllocEventMark : public JvmtiClassEventMark  {
++ private:
++   jobject _jobj;
++   jlong    _size;
++ public:
++   JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klassOop(obj)) {
++     _jobj = (jobject)to_jobject(obj);
++     _size = obj->size() * wordSize;
++   };
++   jobject jni_jobject() { return _jobj; }
++   jlong size() { return _size; }
++};
++
++class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark {
++ private:
++  jint _code_size;
++  const void *_code_data;
++  jint _map_length;
++  jvmtiAddrLocationMap *_map;
++  const void *_compile_info;
++ public:
++  JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm)
++          : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
++    _code_data = nm->code_begin();
++    _code_size = nm->code_size();
++    _compile_info = NULL; /* no info for our VM. */
++    JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
++  }
++  ~JvmtiCompiledMethodLoadEventMark() {
++     FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map);
++  }
++
++  jint code_size() { return _code_size; }
++  const void *code_data() { return _code_data; }
++  jint map_length() { return _map_length; }
++  const jvmtiAddrLocationMap* map() { return _map; }
++  const void *compile_info() { return _compile_info; }
++};
++
++
++
++class JvmtiMonitorEventMark : public JvmtiThreadEventMark {
++private:
++  jobject _jobj;
++public:
++  JvmtiMonitorEventMark(JavaThread *thread, oop object)
++          : JvmtiThreadEventMark(thread){
++     _jobj = to_jobject(object);
++  }
++  jobject jni_object() { return _jobj; }
++};
++
++///////////////////////////////////////////////////////////////
++//
++// pending CompiledMethodUnload support
++//
++
++bool JvmtiExport::_have_pending_compiled_method_unload_events;
++GrowableArray<jmethodID>* JvmtiExport::_pending_compiled_method_unload_method_ids;
++GrowableArray<const void *>* JvmtiExport::_pending_compiled_method_unload_code_begins;
++JavaThread* JvmtiExport::_current_poster;
++
++// post any pending CompiledMethodUnload events
++
++void JvmtiExport::post_pending_compiled_method_unload_events() {
++  JavaThread* self = JavaThread::current();
++  assert(!self->owns_locks(), "can't hold locks");
++
++  // Indicates if this is the first activiation of this function.
++  // In theory the profiler's callback could call back into VM and provoke
++  // another CompiledMethodLoad event to be posted from this thread. As the
++  // stack rewinds we need to ensure that the original activation does the
++  // completion and notifies any waiters.
++  bool first_activation = false;
++
++  // the jmethodID (may not be valid) to be used for a single event
++  jmethodID method;
++  const void *code_begin;
++
++  // grab the monitor and check if another thread is already posting
++  // events. If there is another thread posting events then we wait
++  // until it completes. (In theory we could check the pending events to
++  // see if any of the addresses overlap with the event that we want to
++  // post but as it will happen so rarely we just block any thread waiting
++  // to post a CompiledMethodLoad or DynamicCodeGenerated event until all
++  // pending CompiledMethodUnload events have been posted).
++  //
++  // If another thread isn't posting we examine the list of pending jmethodIDs.
++  // If the list is empty then we are done. If it's not empty then this thread
++  // (self) becomes the pending event poster and we remove the top (last)
++  // event from the list. Note that this means we remove the newest event first
++  // but as they are all CompiledMethodUnload events the order doesn't matter.
++  // Once we have removed a jmethodID then we exit the monitor. Any other thread
++  // wanting to post a CompiledMethodLoad or DynamicCodeGenerated event will
++  // be forced to wait on the monitor.
++  {
++    MutexLocker mu(JvmtiPendingEvent_lock);
++    if (_current_poster != self) {
++      while (_current_poster != NULL) {
++        JvmtiPendingEvent_lock->wait();
++      }
++    }
++    if ((_pending_compiled_method_unload_method_ids == NULL) ||
++        (_pending_compiled_method_unload_method_ids->length() == 0)) {
++      return;
++    }
++    if (_current_poster == NULL) {
++      _current_poster = self;
++      first_activation = true;
++    } else {
++      // re-entrant
++      guarantee(_current_poster == self, "checking");
++    }
++    method = _pending_compiled_method_unload_method_ids->pop();
++    code_begin = _pending_compiled_method_unload_code_begins->pop();
++  }
++
++  // This thread is the pending event poster so it first posts the CompiledMethodUnload
++  // event for the jmethodID that has been removed from the list. Once posted it
++  // re-grabs the monitor and checks the list again. If the list is empty then and this
++  // is the first activation of the function then we reset the _have_pending_events
++  // flag, cleanup _current_poster to indicate that no thread is now servicing the
++  // pending events list, and finally notify any thread that might be waiting.
++  for (;;) {
++    EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
++                   ("JVMTI [%s] method compile unload event triggered",
++                   JvmtiTrace::safe_get_thread_name(self)));
++
++    // post the event for each environment that has this event enabled.
++    JvmtiEnvIterator it;
++    for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
++      if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {
++        EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
++                  ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT,
++                  JvmtiTrace::safe_get_thread_name(self), method));
++
++        JvmtiEventMark jem(self);
++        JvmtiJavaThreadEventTransition jet(self);
++        jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;
++        if (callback != NULL) {
++          (*callback)(env->jvmti_external(), method, code_begin);
++        }
++      }
++    }
++
++    // event posted, now re-grab monitor and get the next event
++    // If there's no next event then we are done. If this is the first
++    // activiation of this function by this thread notify any waiters
++    // so that they can post.
++    {
++      MutexLocker ml(JvmtiPendingEvent_lock);
++      if (_pending_compiled_method_unload_method_ids->length() == 0) {
++        if (first_activation) {
++          _have_pending_compiled_method_unload_events = false;
++          _current_poster = NULL;
++          JvmtiPendingEvent_lock->notify_all();
++        }
++        return;
++      }
++      method = _pending_compiled_method_unload_method_ids->pop();
++      code_begin = _pending_compiled_method_unload_code_begins->pop();
++    }
++  }
++}
++
++///////////////////////////////////////////////////////////////
++//
++// JvmtiExport
++//
++
++void JvmtiExport::post_raw_breakpoint(JavaThread *thread, methodOop method, address location) {
++  HandleMark hm(thread);
++  methodHandle mh(thread, method);
++
++  JvmtiThreadState *state = thread->jvmti_thread_state();
++  if (state == NULL) {
++    return;
++  }
++  EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Trg Breakpoint triggered",
++                      JvmtiTrace::safe_get_thread_name(thread)));
++  JvmtiEnvThreadStateIterator it(state);
++  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
++    ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT);
++    if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) {
++      ThreadState old_os_state = thread->osthread()->get_state();
++      thread->osthread()->set_state(BREAKPOINTED);
++      EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint sent %s.%s @ %d",
++                     JvmtiTrace::safe_get_thread_name(thread),
++                     (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
++                     (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
++                     location - mh()->code_base() ));
++
++      JvmtiEnv *env = ets->get_env();
++      JvmtiLocationEventMark jem(thread, mh, location);
++      JvmtiJavaThreadEventTransition jet(thread);
++      jvmtiEventBreakpoint callback = env->callbacks()->Breakpoint;
++      if (callback != NULL) {
++        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
++                    jem.jni_methodID(), jem.location());
++      }
++
++      ets->set_breakpoint_posted();
++      thread->osthread()->set_state(old_os_state);
++    }
++  }
++}
++
++//////////////////////////////////////////////////////////////////////////////
++
++bool              JvmtiExport::_can_get_source_debug_extension            = false;
++bool              JvmtiExport::_can_maintain_original_method_order        = false;
++bool              JvmtiExport::_can_post_interpreter_events               = false;
++bool              JvmtiExport::_can_post_exceptions                       = false;
++bool              JvmtiExport::_can_post_breakpoint                       = false;
++bool              JvmtiExport::_can_post_field_access                     = false;
++bool              JvmtiExport::_can_post_field_modification               = false;
++bool              JvmtiExport::_can_post_method_entry                     = false;
++bool              JvmtiExport::_can_post_method_exit                      = false;
++bool              JvmtiExport::_can_pop_frame                             = false;
++bool              JvmtiExport::_can_force_early_return                    = false;
++
++bool              JvmtiExport::_should_post_single_step                   = false;
++bool              JvmtiExport::_should_post_field_access                  = false;
++bool              JvmtiExport::_should_post_field_modification            = false;
++bool              JvmtiExport::_should_post_class_load                    = false;
++bool              JvmtiExport::_should_post_class_prepare                 = false;
++bool              JvmtiExport::_should_post_class_unload                  = false;
++bool              JvmtiExport::_should_post_thread_life                   = false;
++bool              JvmtiExport::_should_clean_up_heap_objects              = false;
++bool              JvmtiExport::_should_post_native_method_bind            = false;
++bool              JvmtiExport::_should_post_dynamic_code_generated        = false;
++bool              JvmtiExport::_should_post_data_dump                     = false;
++bool              JvmtiExport::_should_post_compiled_method_load          = false;
++bool              JvmtiExport::_should_post_compiled_method_unload        = false;
++bool              JvmtiExport::_should_post_monitor_contended_enter       = false;
++bool              JvmtiExport::_should_post_monitor_contended_entered     = false;
++bool              JvmtiExport::_should_post_monitor_wait                  = false;
++bool              JvmtiExport::_should_post_monitor_waited                = false;
++bool              JvmtiExport::_should_post_garbage_collection_start      = false;
++bool              JvmtiExport::_should_post_garbage_collection_finish     = false;
++bool              JvmtiExport::_should_post_object_free                   = false;
++bool              JvmtiExport::_should_post_resource_exhausted            = false;
++bool              JvmtiExport::_should_post_vm_object_alloc               = false;
++
++////////////////////////////////////////////////////////////////////////////////////////////////
+ 
+-void JvmtiExport::post_vm_initialized() {
+-  EVT_TRIG_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Trg VM init event triggered" ));
+ 
+-  // can now enable events 
+-  JvmtiEventController::vm_init();
++//
++// JVMTI single step management
++//
++void JvmtiExport::at_single_stepping_point(JavaThread *thread, methodOop method, address location) {
++  assert(JvmtiExport::should_post_single_step(), "must be single stepping");
+ 
+-  JvmtiEnvIterator it; 
+-  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
+-    if (env->is_enabled(JVMTI_EVENT_VM_INIT)) {
+-      EVT_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Evt VM init event sent" ));
++  HandleMark hm(thread);
++  methodHandle mh(thread, method);
+ 
+-      JavaThread *thread  = JavaThread::current();
+-      JvmtiThreadEventMark jem(thread);
+-      JvmtiJavaThreadEventTransition jet(thread);
+-      jvmtiEventVMInit callback = env->callbacks()->VMInit;
+-      if (callback != NULL) {
+-        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
++  // update information about current location and post a step event
++  JvmtiThreadState *state = thread->jvmti_thread_state();
++  if (state == NULL) {
++    return;
++  }
++  EVT_TRIG_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Trg Single Step triggered",
++                      JvmtiTrace::safe_get_thread_name(thread)));
++  if (!state->hide_single_stepping()) {
++    if (state->is_pending_step_for_popframe()) {
++      state->process_pending_step_for_popframe();
+       }
++    if (state->is_pending_step_for_earlyret()) {
++      state->process_pending_step_for_earlyret();
+     }
++    JvmtiExport::post_single_step(thread, mh(), location);
+   }  
+ }
+ 
+ 
+-extern "C" {
+-  typedef void (JNICALL *Agent_OnUnload_t)(JavaVM *);
+-}
+-
+-void JvmtiExport::post_vm_death() {
+-  EVT_TRIG_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Trg VM death event triggered" ));
+-
+-  JvmtiEnvIterator it; 
+-  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
+-    if (env->is_enabled(JVMTI_EVENT_VM_DEATH)) {
+-      EVT_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Evt VM death event sent" ));
+-      
+-      JavaThread *thread  = JavaThread::current();
+-      JvmtiEventMark jem(thread);
+-      JvmtiJavaThreadEventTransition jet(thread);
+-      jvmtiEventVMDeath callback = env->callbacks()->VMDeath;
+-      if (callback != NULL) {
+-        (*callback)(env->jvmti_external(), jem.jni_env());
+-      }
+-    }
++void JvmtiExport::expose_single_stepping(JavaThread *thread) {
++  JvmtiThreadState *state = thread->jvmti_thread_state();
++  if (state != NULL) {
++    state->clear_hide_single_stepping();
+   }
++}
+ 
+-  JvmtiEnvBase::set_phase(JVMTI_PHASE_DEAD);
+-  JvmtiEventController::vm_death();
+-
+-  // Send any Agent_OnUnload notifications
+-  const char *on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS;
+-  extern struct JavaVM_ main_vm;
+-  for (AgentLibrary* agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
+-
+-    // Find the Agent_OnUnload function.
+-    for (uint symbol_index = 0; symbol_index < ARRAY_SIZE(on_unload_symbols); symbol_index++) {
+-      Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t,
+-               hpi::dll_lookup(agent->os_lib(), on_unload_symbols[symbol_index]));
+ 
+-      // Invoke the Agent_OnUnload function
+-      if (unload_entry != NULL) {
+-        JavaThread* thread = JavaThread::current();
+-        ThreadToNativeFromVM ttn(thread);
+-        HandleMark hm(thread);
+-        (*unload_entry)(&main_vm);
+-        break;
+-      }
+-    }
++bool JvmtiExport::hide_single_stepping(JavaThread *thread) {
++  JvmtiThreadState *state = thread->jvmti_thread_state();
++  if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
++    state->set_hide_single_stepping();
++    return true;
++  } else {
++    return false;
+   }
+ }
+ 
+-
+ void JvmtiExport::post_class_load(JavaThread *thread, klassOop klass) {
+   HandleMark hm(thread);  
+   KlassHandle kh(thread, klass);
+@@ -1533,170 +1693,6 @@
+   }
+ }
+ 
+-class JvmtiClassFileLoadHookPoster : public StackObj {
+- private:
+-  symbolHandle         _h_name;
+-  Handle               _class_loader;
+-  Handle               _h_protection_domain;
+-  unsigned char **     _data_ptr;
+-  unsigned char **     _end_ptr;
+-  JavaThread *         _thread;
+-  jint                 _curr_len;
+-  unsigned char *      _curr_data;
+-  JvmtiEnv *           _curr_env; 
+-  jint *               _cached_length_ptr;
+-  unsigned char **     _cached_data_ptr;
+-  JvmtiThreadState *   _state;
+-  KlassHandle *        _h_class_being_redefined;
+-  JvmtiClassLoadKind   _load_kind;
+-
+- public:
+-  inline JvmtiClassFileLoadHookPoster(symbolHandle h_name, Handle class_loader,
+-                                      Handle h_protection_domain, 
+-                                      unsigned char **data_ptr, unsigned char **end_ptr, 
+-                                      unsigned char **cached_data_ptr, 
+-                                      jint *cached_length_ptr) {
+-    _h_name = h_name;
+-    _class_loader = class_loader;
+-    _h_protection_domain = h_protection_domain;
+-    _data_ptr = data_ptr;
+-    _end_ptr = end_ptr;
+-    _thread = JavaThread::current();
+-    _curr_len = *end_ptr - *data_ptr;
+-    _curr_data = *data_ptr;
+-    _curr_env = NULL; 
+-    _cached_length_ptr = cached_length_ptr;
+-    _cached_data_ptr = cached_data_ptr;
+-    *_cached_length_ptr = 0;
+-    *_cached_data_ptr = NULL;
+-
+-    _state = _thread->jvmti_thread_state();
+-    if (_state != NULL) {
+-      _h_class_being_redefined = _state->get_class_being_redefined();
+-      _load_kind = _state->get_class_load_kind();
+-      // Clear class_being_redefined flag here. The action 
+-      // from agent handler could generate a new class file load
+-      // hook event and if it is not cleared the new event generated
+-      // from regular class file load could have this stale redefined
+-      // class handle info. 
+-      _state->clear_class_being_redefined();
+-    } else {
+-      // redefine and retransform will always set the thread state
+-      _h_class_being_redefined = (KlassHandle *) NULL;
+-      _load_kind = jvmti_class_load_kind_load;
+-    }
+-  }
+-
+-  void post() {
+-//    EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
+-//                   ("JVMTI [%s] class file load hook event triggered",  
+-//                    JvmtiTrace::safe_get_thread_name(_thread)));
+-    post_all_envs();
+-    copy_modified_data();
+-  }
+-
+- private:
+-  void post_all_envs() {
+-    if (_load_kind != jvmti_class_load_kind_retransform) {
+-      // for class load and redefine, 
+-      // call the non-retransformable agents
+-      JvmtiEnvIterator it; 
+-      for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
+-        if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
+-          // non-retransformable agents cannot retransform back,
+-          // so no need to cache the original class file bytes
+-          post_to_env(env, false);
+-        }
+-      }
+-    }
+-    JvmtiEnvIterator it; 
+-    for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
+-      // retransformable agents get all events
+-      if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
+-        // retransformable agents need to cache the original class file 
+-        // bytes if changes are made via the ClassFileLoadHook
+-        post_to_env(env, true);
+-      }
+-    }
+-  }
+-
+-  void post_to_env(JvmtiEnv* env, bool caching_needed) {
+-    unsigned char *new_data = NULL;
+-    jint new_len = 0;
+-//    EVT_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
+-//     ("JVMTI [%s] class file load hook event sent %s  data_ptr = %d, data_len = %d",  
+-//               JvmtiTrace::safe_get_thread_name(_thread),
+-//               _h_name.is_null() ? "NULL" : _h_name->as_utf8(),
+-//               _curr_data, _curr_len ));
+-    JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader, 
+-                                    _h_protection_domain, 
+-                                    _h_class_being_redefined);
+-    JvmtiJavaThreadEventTransition jet(_thread);
+-    JNIEnv* jni_env =  (JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL)? 
+-                                                        NULL : jem.jni_env();
+-    jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook;
+-    if (callback != NULL) {
+-      (*callback)(env->jvmti_external(), jni_env,
+-                  jem.class_being_redefined(),
+-                  jem.jloader(), jem.class_name(), 
+-                  jem.protection_domain(),
+-                  _curr_len, _curr_data,
+-                  &new_len, &new_data);
+-    }
+-    if (new_data != NULL) {
+-      // this agent has modified class data. 
+-      if (caching_needed && *_cached_data_ptr == NULL) {
+-        // data has been changed by the new retransformable agent
+-        // and it hasn't already been cached, cache it
+-        *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len);
+-        memcpy(*_cached_data_ptr, _curr_data, _curr_len);
+-        *_cached_length_ptr = _curr_len;
+-      }
+-
+-      if (_curr_data != *_data_ptr) {
+-        // curr_data is previous agent modified class data.
+-        // And this has been changed by the new agent so
+-        // we can delete it now.           
+-        _curr_env->Deallocate(_curr_data);
+-      }
+-
+-      // Class file data has changed by the current agent.
+-      _curr_data = new_data;
+-      _curr_len = new_len;
+-      // Save the current agent env we need this to deallocate the
+-      // memory allocated by this agent.
+-      _curr_env = env;
+-    }
+-  }
+-
+-  void copy_modified_data() {
+-    // if one of the agent has modified class file data.
+-    // Copy modified class data to new resources array.
+-    if (_curr_data != *_data_ptr) {
+-      *_data_ptr = NEW_RESOURCE_ARRAY(u1, _curr_len);
+-      memcpy(*_data_ptr, _curr_data, _curr_len);
+-      *_end_ptr = *_data_ptr + _curr_len;
+-      _curr_env->Deallocate(_curr_data);
+-    }
+-  }
+-};
+-
+-// this entry is for class file load hook on class load, redefine and retransform
+-void JvmtiExport::post_class_file_load_hook(symbolHandle h_name, 
+-                                            Handle class_loader,
+-                                            Handle h_protection_domain, 
+-                                            unsigned char **data_ptr, 
+-                                            unsigned char **end_ptr, 
+-                                            unsigned char **cached_data_ptr, 
+-                                            jint *cached_length_ptr) {
+-  JvmtiClassFileLoadHookPoster poster(h_name, class_loader, 
+-                                      h_protection_domain, 
+-                                      data_ptr, end_ptr,
+-                                      cached_data_ptr, 
+-                                      cached_length_ptr);
+-  poster.post();
+-}
+-
+ void JvmtiExport::post_native_method_bind(methodOop method, address* function_ptr) {
+   JavaThread* thread = JavaThread::current();    
+   assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
+@@ -2133,19 +2129,6 @@
+   }
+ }
+ 
+-
+-char**
+-JvmtiExport::get_all_native_method_prefixes(int* count_ptr) {
+-  // Have to grab JVMTI thread state lock to be sure environment doesn't
+-  // go away while we iterate them.  No locks during VM bring-up.
+-  if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) {
+-    return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
+-  } else {
+-    MutexLocker mu(JvmtiThreadState_lock);
+-    return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
+-  }
+-}
+-
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ 
+ void JvmtiExport::cleanup_thread(JavaThread* thread) {
+@@ -2175,6 +2158,7 @@
+   typedef jint (JNICALL *OnAttachEntry_t)(JavaVM*, char *, void *);
+ }
+ 
++#ifndef SERVICES_KERNEL
+ jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {
+   char ebuf[1024];
+   char buffer[JVM_MAXPATHLEN];
+@@ -2252,6 +2236,7 @@
+   }
+   return result;
+ }
++#endif // SERVICES_KERNEL
+ 
+ // CMS has completed referencing processing so may need to update
+ // tag maps. 
+@@ -2506,5 +2491,4 @@
+   // Notify heap/object tagging support
+   JvmtiTagMap::gc_epilogue(_full);
+ }
+-
+-
++#endif // JVMTI_KERNEL
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiExport.hpp openjdk/hotspot/src/share/vm/prims/jvmtiExport.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiExport.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiExport.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiExport.hpp	1.95 07/05/05 17:06:37 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -36,6 +33,23 @@
+ class JvmtiThreadState;
+ class AttachOperation;
+ 
++#ifndef JVMTI_KERNEL
++#define JVMTI_SUPPORT_FLAG(key)                                         \
++  private:                                                              \
++  static bool  _##key;                                                  \
++  public:                                                               \
++  inline static void set_##key(bool on)       { _##key = (on != 0); }   \
++  inline static bool key()                    { return _##key; }
++#else  // JVMTI_KERNEL
++#define JVMTI_SUPPORT_FLAG(key)                                           \
++  private:                                                                \
++  const static bool _##key = false;                                       \
++  public:                                                                 \
++  inline static void set_##key(bool on)       { report_unsupported(on); } \
++  inline static bool key()                    { return _##key; }
++#endif // JVMTI_KERNEL
++
++
+ // This class contains the JVMTI interface for the rest of hotspot.
+ //
+ class JvmtiExport : public AllStatic {
+@@ -43,93 +57,65 @@
+   static int         _field_access_count;
+   static int         _field_modification_count;
+ 
+-  static bool        _can_get_source_debug_extension;
++  static bool        _can_access_local_variables;
+   static bool        _can_examine_or_deopt_anywhere;
+-  static bool        _can_maintain_original_method_order;
+-  static bool        _can_post_interpreter_events;
+   static bool        _can_hotswap_or_post_breakpoint;
+   static bool        _can_modify_any_class;
+   static bool	     _can_walk_any_space;
+-  static bool        _can_access_local_variables;
+-  static bool        _can_post_exceptions;
+-  static bool        _can_post_breakpoint;
+-  static bool        _can_post_field_access;
+-  static bool        _can_post_field_modification;
+-  static bool        _can_post_method_entry;
+-  static bool        _can_post_method_exit;
+-  static bool        _can_pop_frame;
+-  static bool        _can_force_early_return;
+-
+-  static bool        _should_post_single_step;
+-  static bool        _should_post_field_access;
+-  static bool        _should_post_field_modification;
+-  static bool        _should_post_class_load;
+-  static bool        _should_post_class_prepare;
+-  static bool        _should_post_class_unload;
+-  static bool        _should_post_class_file_load_hook;
+-  static bool        _should_post_native_method_bind;
+-  static bool        _should_post_compiled_method_load;
+-  static bool        _should_post_compiled_method_unload;
+-  static bool        _should_post_dynamic_code_generated;
+-  static bool        _should_post_monitor_contended_enter;
+-  static bool        _should_post_monitor_contended_entered;
+-  static bool        _should_post_monitor_wait;
+-  static bool        _should_post_monitor_waited;
+-  static bool        _should_post_data_dump;
+-  static bool        _should_post_garbage_collection_start;
+-  static bool        _should_post_garbage_collection_finish;
+-  static bool        _should_post_thread_life;
+-  static bool	     _should_post_object_free;
+-  static bool	     _should_post_resource_exhausted;
+-  static bool        _should_clean_up_heap_objects;
+-  static bool        _should_post_vm_object_alloc;    
+ 
++  JVMTI_SUPPORT_FLAG(can_get_source_debug_extension)
++  JVMTI_SUPPORT_FLAG(can_maintain_original_method_order)
++  JVMTI_SUPPORT_FLAG(can_post_interpreter_events)
++  JVMTI_SUPPORT_FLAG(can_post_exceptions)
++  JVMTI_SUPPORT_FLAG(can_post_breakpoint)
++  JVMTI_SUPPORT_FLAG(can_post_field_access)
++  JVMTI_SUPPORT_FLAG(can_post_field_modification)
++  JVMTI_SUPPORT_FLAG(can_post_method_entry)
++  JVMTI_SUPPORT_FLAG(can_post_method_exit)
++  JVMTI_SUPPORT_FLAG(can_pop_frame)
++  JVMTI_SUPPORT_FLAG(can_force_early_return)
++
++  friend class JvmtiEventControllerPrivate;  // should only modify these flags
++  JVMTI_SUPPORT_FLAG(should_post_single_step)
++  JVMTI_SUPPORT_FLAG(should_post_field_access)
++  JVMTI_SUPPORT_FLAG(should_post_field_modification)
++  JVMTI_SUPPORT_FLAG(should_post_class_load)
++  JVMTI_SUPPORT_FLAG(should_post_class_prepare)
++  JVMTI_SUPPORT_FLAG(should_post_class_unload)
++  JVMTI_SUPPORT_FLAG(should_post_native_method_bind)
++  JVMTI_SUPPORT_FLAG(should_post_compiled_method_load)
++  JVMTI_SUPPORT_FLAG(should_post_compiled_method_unload)
++  JVMTI_SUPPORT_FLAG(should_post_dynamic_code_generated)
++  JVMTI_SUPPORT_FLAG(should_post_monitor_contended_enter)
++  JVMTI_SUPPORT_FLAG(should_post_monitor_contended_entered)
++  JVMTI_SUPPORT_FLAG(should_post_monitor_wait)
++  JVMTI_SUPPORT_FLAG(should_post_monitor_waited)
++  JVMTI_SUPPORT_FLAG(should_post_data_dump)
++  JVMTI_SUPPORT_FLAG(should_post_garbage_collection_start)
++  JVMTI_SUPPORT_FLAG(should_post_garbage_collection_finish)
++
++  // ------ the below maybe don't have to be (but are for now)
++  // fixed conditions here ------------
++  // any events can be enabled
++  JVMTI_SUPPORT_FLAG(should_post_thread_life)
++  JVMTI_SUPPORT_FLAG(should_post_object_free)
++  JVMTI_SUPPORT_FLAG(should_post_resource_exhausted)
++
++  // we are holding objects on the heap - need to talk to GC - e.g.
++  // breakpoint info
++  JVMTI_SUPPORT_FLAG(should_clean_up_heap_objects)
++  JVMTI_SUPPORT_FLAG(should_post_vm_object_alloc)
++
++  // If flag cannot be implemented, give an error if on=true
++  static void report_unsupported(bool on);
+ 
+   // these should only be called by the friend class
+   friend class JvmtiManageCapabilities;
+-  inline static void set_can_get_source_debug_extension(bool on)       { _can_get_source_debug_extension = (on != 0); }
+   inline static void set_can_examine_or_deopt_anywhere(bool on)        { _can_examine_or_deopt_anywhere = (on != 0); }
+-  inline static void set_can_maintain_original_method_order(bool on)   { _can_maintain_original_method_order = (on != 0); }
+-  inline static void set_can_post_interpreter_events(bool on)          { _can_post_interpreter_events = (on != 0); }
+-  inline static void set_can_hotswap_or_post_breakpoint(bool on)       { _can_hotswap_or_post_breakpoint = (on != 0); }
+   inline static void set_can_modify_any_class(bool on)                 { _can_modify_any_class = (on != 0); }
+-  inline static void set_can_walk_any_space(bool on)		       { _can_walk_any_space = (on != 0); }
+   inline static void set_can_access_local_variables(bool on)           { _can_access_local_variables = (on != 0); }
+-  inline static void set_can_post_exceptions(bool on)                  { _can_post_exceptions = (on != 0); }
+-  inline static void set_can_post_breakpoint(bool on)                  { _can_post_breakpoint = (on != 0); }
+-  inline static void set_can_post_field_access(bool on)                { _can_post_field_access = (on != 0); }
+-  inline static void set_can_post_field_modification(bool on)          { _can_post_field_modification = (on != 0); }
+-  inline static void set_can_post_method_entry(bool on)                { _can_post_method_entry = (on != 0); }
+-  inline static void set_can_post_method_exit(bool on)                 { _can_post_method_exit = (on != 0); }
+-  inline static void set_can_pop_frame(bool on)                        { _can_pop_frame = (on != 0); }
+-  inline static void set_can_force_early_return(bool on)               { _can_force_early_return = (on != 0); }
+-
+-  // these should only be called by the friend class
+-  friend class JvmtiEventControllerPrivate;
+-  inline static void set_should_post_single_step(bool on)              { _should_post_single_step = on; }
+-  inline static void set_should_post_field_access(bool on)             { _should_post_field_access = on; }
+-  inline static void set_should_post_field_modification(bool on)       { _should_post_field_modification = on; }
+-  inline static void set_should_post_class_load(bool on)               { _should_post_class_load = on; }
+-  inline static void set_should_post_class_prepare(bool on)            { _should_post_class_prepare = on; }
+-  inline static void set_should_post_class_unload(bool on)             { _should_post_class_unload = on; }
+-  inline static void set_should_post_class_file_load_hook(bool on)     { _should_post_class_file_load_hook = on;  }   
+-  inline static void set_should_post_native_method_bind(bool on)       { _should_post_native_method_bind = on; }
+-  inline static void set_should_post_compiled_method_load(bool on)     { _should_post_compiled_method_load = on; }
+-  inline static void set_should_post_compiled_method_unload(bool on)   { _should_post_compiled_method_unload = on; }
+-  inline static void set_should_post_dynamic_code_generated(bool on)   { _should_post_dynamic_code_generated = on;  }   
+-  inline static void set_should_post_monitor_contended_enter(bool on)  { _should_post_monitor_contended_enter = on; }
+-  inline static void set_should_post_monitor_contended_entered(bool on){ _should_post_monitor_contended_entered = on; }
+-  inline static void set_should_post_monitor_wait(bool on)             { _should_post_monitor_wait = on; }
+-  inline static void set_should_post_monitor_waited(bool on)           { _should_post_monitor_waited = on; }
+-  inline static void set_should_post_garbage_collection_start(bool on) { _should_post_garbage_collection_start = on; }
+-  inline static void set_should_post_garbage_collection_finish(bool on){ _should_post_garbage_collection_finish = on; }
+-  inline static void set_should_post_data_dump(bool on)                { _should_post_data_dump = on;  }   
+-  inline static void set_should_post_object_free(bool on)	       { _should_post_object_free = on; }
+-  inline static void set_should_post_resource_exhausted(bool on)       { _should_post_resource_exhausted = on; }
+-  inline static void set_should_post_vm_object_alloc(bool on)	       { _should_post_vm_object_alloc = on; }    
+-
+-  inline static void set_should_post_thread_life(bool on)              { _should_post_thread_life = on; }
+-  inline static void set_should_clean_up_heap_objects(bool on)         { _should_clean_up_heap_objects = on; }
++  inline static void set_can_hotswap_or_post_breakpoint(bool on)       { _can_hotswap_or_post_breakpoint = (on != 0); }
++  inline static void set_can_walk_any_space(bool on)                   { _can_walk_any_space = (on != 0); }
+ 
+   enum {
+     JVMTI_VERSION_MASK   = 0x70000000,
+@@ -162,7 +148,7 @@
+   // posts a DynamicCodeGenerated event (internal/private implementation). 
+   // The public post_dynamic_code_generated* functions make use of the
+   // internal implementation.
+-  static void post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end);
++  static void post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) KERNEL_RETURN;
+ 
+ 
+   // GenerateEvents support to allow posting of CompiledMethodLoad and
+@@ -171,9 +157,9 @@
+ 
+   static void post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length, 
+ 				        const void *code_begin, const jint map_length, 
+-					const jvmtiAddrLocationMap* map);
++                                        const jvmtiAddrLocationMap* map) KERNEL_RETURN;
+   static void post_dynamic_code_generated(JvmtiEnv* env, const char *name, const void *code_begin, 
+-					  const void *code_end);
++                                          const void *code_end) KERNEL_RETURN;
+ 
+   // The RedefineClasses() API breaks some invariants in the "regular"
+   // system. For example, there are sanity checks when GC'ing nmethods
+@@ -233,70 +219,11 @@
+   static void enter_live_phase();
+ 
+   // ------ can_* conditions (below) are set at OnLoad and never changed ------------
+-
+-  inline static bool can_get_source_debug_extension()             { return _can_get_source_debug_extension; }
+-
+-  // BP, expression stack, hotswap, interp_only, local_var, monitor info
+   inline static bool can_examine_or_deopt_anywhere()              { return _can_examine_or_deopt_anywhere; }
+-
+-  // JVMDI spec requires this, does this matter for JVMTI?
+-  inline static bool can_maintain_original_method_order()         { return _can_maintain_original_method_order; }
+-
+-  // any of single-step, method-entry/exit, frame-pop, and field-access/modification
+-  inline static bool can_post_interpreter_events()                { return _can_post_interpreter_events; }
+-
+-  inline static bool can_hotswap_or_post_breakpoint()             { return _can_hotswap_or_post_breakpoint; }
+-
+   inline static bool can_modify_any_class()                       { return _can_modify_any_class; }
+-
+-  inline static bool can_walk_any_space()			  { return _can_walk_any_space; }
+-
+-  // can retrieve frames, set/get local variables or hotswap
+   inline static bool can_access_local_variables()                 { return _can_access_local_variables; }
+-
+-  // throw or catch
+-  inline static bool can_post_exceptions()                        { return _can_post_exceptions; }
+-
+-  inline static bool can_post_breakpoint()                        { return _can_post_breakpoint; }
+-  inline static bool can_post_field_access()                      { return _can_post_field_access; }
+-  inline static bool can_post_field_modification()                { return _can_post_field_modification; }
+-  inline static bool can_post_method_entry()                      { return _can_post_method_entry; }
+-  inline static bool can_post_method_exit()                       { return _can_post_method_exit; }
+-  inline static bool can_pop_frame()                              { return _can_pop_frame; }
+-  inline static bool can_force_early_return()                     { return _can_force_early_return; }
+-
+-
+-  // ------ the below maybe don't have to be (but are for now) fixed conditions here ------------
+-  // any events can be enabled
+-  inline static bool should_post_thread_life()                   { return _should_post_thread_life; }
+-
+-
+-  // ------ DYNAMIC conditions here ------------
+-
+-  inline static bool should_post_single_step()                    { return _should_post_single_step; }
+-  inline static bool should_post_field_access()                   { return _should_post_field_access; }
+-  inline static bool should_post_field_modification()             { return _should_post_field_modification; }
+-  inline static bool should_post_class_load()                     { return _should_post_class_load; }
+-  inline static bool should_post_class_prepare()                  { return _should_post_class_prepare; }
+-  inline static bool should_post_class_unload()                   { return _should_post_class_unload; }
+-  inline static bool should_post_class_file_load_hook()           { return _should_post_class_file_load_hook; }
+-  inline static bool should_post_native_method_bind()             { return _should_post_native_method_bind; }
+-  inline static bool should_post_compiled_method_load()           { return _should_post_compiled_method_load; }
+-  inline static bool should_post_compiled_method_unload()         { return _should_post_compiled_method_unload; }
+-  inline static bool should_post_dynamic_code_generated()         { return _should_post_dynamic_code_generated; }
+-  inline static bool should_post_monitor_contended_enter()        { return _should_post_monitor_contended_enter; }
+-  inline static bool should_post_monitor_contended_entered()      { return _should_post_monitor_contended_entered; }
+-  inline static bool should_post_monitor_wait()                   { return _should_post_monitor_wait; }
+-  inline static bool should_post_monitor_waited()                 { return _should_post_monitor_waited; }
+-  inline static bool should_post_data_dump()                      { return _should_post_data_dump; }
+-  inline static bool should_post_garbage_collection_start()       { return _should_post_garbage_collection_start; }
+-  inline static bool should_post_garbage_collection_finish()      { return _should_post_garbage_collection_finish; }
+-  inline static bool should_post_object_free()			  { return _should_post_object_free; }
+-  inline static bool should_post_resource_exhausted()		  { return _should_post_resource_exhausted; }
+-  inline static bool should_post_vm_object_alloc()		  { return _should_post_vm_object_alloc; }
+-
+-  // we are holding objects on the heap - need to talk to GC - e.g. breakpoint info
+-  inline static bool should_clean_up_heap_objects()               { return _should_clean_up_heap_objects; }
++  inline static bool can_hotswap_or_post_breakpoint()             { return _can_hotswap_or_post_breakpoint; }
++  inline static bool can_walk_any_space()                         { return _can_walk_any_space; }
+ 
+   // field access management
+   static address  get_field_access_count_addr();
+@@ -310,84 +237,89 @@
+   static bool is_jvmdi_version(jint version)                      { return (version & JVMTI_VERSION_MASK) == JVMDI_VERSION_VALUE; }
+   static jint get_jvmti_interface(JavaVM *jvm, void **penv, jint version);
+   
+-
+   // single stepping management methods
+-  static void at_single_stepping_point(JavaThread *thread, methodOop method, address location);
+-  static void expose_single_stepping(JavaThread *thread);
+-  static bool hide_single_stepping(JavaThread *thread);
++  static void at_single_stepping_point(JavaThread *thread, methodOop method, address location) KERNEL_RETURN;
++  static void expose_single_stepping(JavaThread *thread) KERNEL_RETURN;
++  static bool hide_single_stepping(JavaThread *thread) KERNEL_RETURN_(return false;);
+ 
+   // Methods that notify the debugger that something interesting has happened in the VM.
+   static void post_vm_start              (); 
+   static void post_vm_initialized        (); 
+   static void post_vm_death              ();
+   
+-  static void post_single_step           (JavaThread *thread, methodOop method, address location);
+-  static void post_raw_breakpoint        (JavaThread *thread, methodOop method, address location);
++  static void post_single_step           (JavaThread *thread, methodOop method, address location) KERNEL_RETURN;
++  static void post_raw_breakpoint        (JavaThread *thread, methodOop method, address location) KERNEL_RETURN;
+   
+-  static void post_exception_throw       (JavaThread *thread, methodOop method, address location, oop exception);
+-  static void notice_unwind_due_to_exception (JavaThread *thread, methodOop method, address location, oop exception, bool in_handler_frame);
++  static void post_exception_throw       (JavaThread *thread, methodOop method, address location, oop exception) KERNEL_RETURN;
++  static void notice_unwind_due_to_exception (JavaThread *thread, methodOop method, address location, oop exception, bool in_handler_frame) KERNEL_RETURN;
+ 
+   static oop jni_GetField_probe          (JavaThread *thread, jobject jobj,
+-    oop obj, klassOop klass, jfieldID fieldID, bool is_static);
++    oop obj, klassOop klass, jfieldID fieldID, bool is_static)
++    KERNEL_RETURN_(return NULL;);
+   static oop jni_GetField_probe_nh       (JavaThread *thread, jobject jobj,
+-    oop obj, klassOop klass, jfieldID fieldID, bool is_static);
++    oop obj, klassOop klass, jfieldID fieldID, bool is_static)
++    KERNEL_RETURN_(return NULL;);
+   static void post_field_access_by_jni   (JavaThread *thread, oop obj,
+-    klassOop klass, jfieldID fieldID, bool is_static);
++    klassOop klass, jfieldID fieldID, bool is_static) KERNEL_RETURN;
+   static void post_field_access          (JavaThread *thread, methodOop method,
+-    address location, KlassHandle field_klass, Handle object, jfieldID field);
++    address location, KlassHandle field_klass, Handle object, jfieldID field) KERNEL_RETURN;
+   static oop jni_SetField_probe          (JavaThread *thread, jobject jobj,
+     oop obj, klassOop klass, jfieldID fieldID, bool is_static, char sig_type,
+-    jvalue *value);
++    jvalue *value) KERNEL_RETURN_(return NULL;);
+   static oop jni_SetField_probe_nh       (JavaThread *thread, jobject jobj,
+     oop obj, klassOop klass, jfieldID fieldID, bool is_static, char sig_type,
+-    jvalue *value);
++    jvalue *value) KERNEL_RETURN_(return NULL;);
+   static void post_field_modification_by_jni(JavaThread *thread, oop obj,
+     klassOop klass, jfieldID fieldID, bool is_static, char sig_type,
+     jvalue *value);
+   static void post_raw_field_modification(JavaThread *thread, methodOop method,
+     address location, KlassHandle field_klass, Handle object, jfieldID field,
+-    char sig_type, jvalue *value);
++    char sig_type, jvalue *value) KERNEL_RETURN;
+ 
+-  static void post_method_entry          (JavaThread *thread, methodOop method, frame current_frame);
+-  static void post_method_exit           (JavaThread *thread, methodOop method, frame current_frame);
++  static void post_method_entry          (JavaThread *thread, methodOop method, frame current_frame) KERNEL_RETURN;
++  static void post_method_exit           (JavaThread *thread, methodOop method, frame current_frame) KERNEL_RETURN;
+ 
+-  static void post_class_load            (JavaThread *thread, klassOop klass);
+-  static void post_class_unload          (klassOop klass);
+-  static void post_class_prepare         (JavaThread *thread, klassOop klass);
++  static void post_class_load            (JavaThread *thread, klassOop klass) KERNEL_RETURN;
++  static void post_class_unload          (klassOop klass) KERNEL_RETURN;
++  static void post_class_prepare         (JavaThread *thread, klassOop klass) KERNEL_RETURN;
+   
+-  static void post_thread_start          (JavaThread *thread);
+-  static void post_thread_end            (JavaThread *thread);
++  static void post_thread_start          (JavaThread *thread) KERNEL_RETURN;
++  static void post_thread_end            (JavaThread *thread) KERNEL_RETURN;
+ 
++  // Support for java.lang.instrument agent loading.
++  static bool _should_post_class_file_load_hook;
++  inline static void set_should_post_class_file_load_hook(bool on)     { _should_post_class_file_load_hook = on;  }
++  inline static bool should_post_class_file_load_hook()           { return _should_post_class_file_load_hook; }
+   static void post_class_file_load_hook(symbolHandle h_name, Handle class_loader, 
+                                         Handle h_protection_domain, 
+                                         unsigned char **data_ptr, unsigned char **end_ptr, 
+                                         unsigned char **cached_data_ptr, 
+                                         jint *cached_length_ptr);
+-  static void post_native_method_bind(methodOop method, address* function_ptr);
+-  static void post_compiled_method_load(nmethod *nm);
+-  static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end);
++  static void post_native_method_bind(methodOop method, address* function_ptr) KERNEL_RETURN;
++  static void post_compiled_method_load(nmethod *nm) KERNEL_RETURN;
++  static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) KERNEL_RETURN;
+ 
+   // used at a safepoint to post a CompiledMethodUnload event
+-  static void post_compiled_method_unload_at_safepoint(jmethodID mid, const void *code_begin);
++  static void post_compiled_method_unload_at_safepoint(jmethodID mid, const void *code_begin) KERNEL_RETURN;
+ 
+   // similiar to post_dynamic_code_generated except that it can be used to
+   // post a DynamicCodeGenerated event while holding locks in the VM. Any event
+   // posted using this function is recorded by the enclosing event collector
+   // -- JvmtiDynamicCodeEventCollector.
+-  static void post_dynamic_code_generated_while_holding_locks(const char* name, address code_begin, address code_end); 
++  static void post_dynamic_code_generated_while_holding_locks(const char* name, address code_begin, address code_end) KERNEL_RETURN;
+ 
+-  static void post_garbage_collection_finish();
+-  static void post_garbage_collection_start();
+-  static void post_data_dump();
+-  static void post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr);
+-  static void post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr);
+-  static void post_monitor_wait(JavaThread *thread, oop obj, jlong timeout);
+-  static void post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out);
+-  static void post_object_free(JvmtiEnv* env, jlong tag);
+-  static void post_resource_exhausted(jint resource_exhausted_flags, const char* detail);
+-  static void record_vm_internal_object_allocation(oop object);
++  static void post_garbage_collection_finish() KERNEL_RETURN;
++  static void post_garbage_collection_start() KERNEL_RETURN;
++  static void post_data_dump() KERNEL_RETURN;
++  static void post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) KERNEL_RETURN;
++  static void post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) KERNEL_RETURN;
++  static void post_monitor_wait(JavaThread *thread, oop obj, jlong timeout) KERNEL_RETURN;
++  static void post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) KERNEL_RETURN;
++  static void post_object_free(JvmtiEnv* env, jlong tag) KERNEL_RETURN;
++  static void post_resource_exhausted(jint resource_exhausted_flags, const char* detail) KERNEL_RETURN;
++  static void record_vm_internal_object_allocation(oop object) KERNEL_RETURN;
+   // Post objects collected by vm_object_alloc_event_collector.
+-  static void post_vm_object_alloc(JavaThread *thread, oop object);  
++  static void post_vm_object_alloc(JavaThread *thread, oop object) KERNEL_RETURN;
+   // Collects vm internal objects for later event posting.
+   inline static void vm_object_alloc_event_collector(oop object) {
+     if (should_post_vm_object_alloc()) {
+@@ -395,20 +327,22 @@
+     }      
+   }
+ 
+-  static void cleanup_thread             (JavaThread* thread);  
++  static void cleanup_thread             (JavaThread* thread) KERNEL_RETURN;
+ 
+-  static void oops_do(OopClosure* f);
++  static void oops_do(OopClosure* f) KERNEL_RETURN;
+ 
+-  static void transition_pending_onload_raw_monitors();
++  static void transition_pending_onload_raw_monitors() KERNEL_RETURN;
+ 
++#ifndef SERVICES_KERNEL
+   // attach support
+   static jint load_agent_library(AttachOperation* op, outputStream* out);
++#endif // SERVICES_KERNEL
+ 
+   // SetNativeMethodPrefix support
+   static char** get_all_native_method_prefixes(int* count_ptr);
+ 
+   // call after CMS has completed referencing processing
+-  static void cms_ref_processing_epilogue();
++  static void cms_ref_processing_epilogue() KERNEL_RETURN;
+ };
+ 
+ // Support class used by JvmtiDynamicCodeEventCollector and others. It
+@@ -471,8 +405,8 @@
+   void register_stub(const char* name, address start, address end);
+ 
+  public:
+-  JvmtiDynamicCodeEventCollector();
+-  ~JvmtiDynamicCodeEventCollector();
++  JvmtiDynamicCodeEventCollector()  KERNEL_RETURN;
++  ~JvmtiDynamicCodeEventCollector() KERNEL_RETURN;
+   bool is_dynamic_code_event()   { return true; }
+     
+ };
+@@ -504,8 +438,8 @@
+   static void oops_do_for_all_threads(OopClosure* f);
+     
+  public:
+-  JvmtiVMObjectAllocEventCollector(); 
+-  ~JvmtiVMObjectAllocEventCollector();
++  JvmtiVMObjectAllocEventCollector()  KERNEL_RETURN;
++  ~JvmtiVMObjectAllocEventCollector() KERNEL_RETURN;
+   bool is_vm_object_alloc_event()   { return true; }
+ 
+   bool is_enabled()		    { return _enable; }
+@@ -535,8 +469,8 @@
+   bool was_enabled()	{ return _collector != NULL; }  
+ 
+  public:
+-  NoJvmtiVMObjectAllocMark();
+-  ~NoJvmtiVMObjectAllocMark();
++  NoJvmtiVMObjectAllocMark() KERNEL_RETURN;
++  ~NoJvmtiVMObjectAllocMark() KERNEL_RETURN;
+ };
+ 
+ 
+@@ -546,8 +480,8 @@
+   bool _full;				// marks a "full" GC
+   unsigned int _invocation_count;	// GC invocation count
+  protected:
+-  JvmtiGCMarker(bool full);		// protected 
+-  ~JvmtiGCMarker();			// protected
++  JvmtiGCMarker(bool full) KERNEL_RETURN;       // protected
++  ~JvmtiGCMarker() KERNEL_RETURN;               // protected
+ };
+ 
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiExtensions.cpp openjdk/hotspot/src/share/vm/prims/jvmtiExtensions.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiExtensions.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiExtensions.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiExtensions.cpp	1.11 07/05/05 17:06:38 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiExtensions.hpp openjdk/hotspot/src/share/vm/prims/jvmtiExtensions.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiExtensions.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiExtensions.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiExtensions.hpp	1.8 07/05/05 17:06:38 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp openjdk/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiGetLoadedClasses.cpp	1.13 07/05/05 17:06:38 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.hpp openjdk/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.hpp	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiGetLoadedClasses.hpp	1.8 07/05/05 17:06:38 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiImpl.cpp openjdk/hotspot/src/share/vm/prims/jvmtiImpl.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiImpl.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiImpl.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiImpl.cpp	1.63 07/05/17 16:05:04 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -80,291 +77,6 @@
+     _start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg);
+ }
+ 
+-//
+-// class JvmtiUtil
+-//
+-
+-ResourceArea* JvmtiUtil::_single_threaded_resource_area = NULL;
+-
+-ResourceArea* JvmtiUtil::single_threaded_resource_area() {
+-  if (_single_threaded_resource_area == NULL) {
+-    // lazily create the single threaded resource area
+-    // pick a size which is not a standard since the pools don't exist yet
+-    _single_threaded_resource_area = new ResourceArea(Chunk::non_pool_size);
+-  }
+-  return _single_threaded_resource_area;
+-}
+-
+-//
+-// class JvmtiTrace
+-//
+-// Support for JVMTI tracing code
+-//
+-// ------------
+-// Usage:
+-//    -XX:TraceJVMTI=DESC,DESC,DESC
+-//
+-//    DESC is   DOMAIN ACTION KIND
+-//
+-//    DOMAIN is function name
+-//              event name
+-//              "all" (all functions and events)
+-//              "func" (all functions except boring)
+-//              "allfunc" (all functions)
+-//              "event" (all events)
+-//              "ec" (event controller)
+-//
+-//    ACTION is "+" (add)
+-//              "-" (remove)
+-//
+-//    KIND is
+-//     for func
+-//              "i" (input params)
+-//              "e" (error returns)
+-//              "o" (output)
+-//     for event
+-//              "t" (event triggered aka posted)
+-//              "s" (event sent)
+-//
+-// Example:
+-//            -XX:TraceJVMTI=ec+,GetCallerFrame+ie,Breakpoint+s
+-
+-#ifdef JVMTI_TRACE
+-
+-bool JvmtiTrace::_initialized = false;
+-bool JvmtiTrace::_on = false;
+-bool JvmtiTrace::_trace_event_controller = false;
+-
+-void JvmtiTrace::initialize() {
+-  if (_initialized) {
+-    return;
+-  }
+-  SafeResourceMark rm;
+-  
+-  const char *very_end;
+-  const char *curr;
+-  if (strlen(TraceJVMTI)) {
+-    curr = TraceJVMTI;
+-  } else {
+-    curr = "";  // hack in fixed tracing here
+-  }
+-  very_end = curr + strlen(curr);
+-  while (curr < very_end) {
+-    const char *curr_end = strchr(curr, ',');
+-    if (curr_end == NULL) {
+-      curr_end = very_end;
+-    }
+-    const char *op_pos = strchr(curr, '+');
+-    const char *minus_pos = strchr(curr, '-');
+-    if (minus_pos != NULL && (minus_pos < op_pos || op_pos == NULL)) {
+-      op_pos = minus_pos;
+-    }
+-    char op;
+-    const char *flags = op_pos + 1;
+-    const char *flags_end = curr_end;
+-    if (op_pos == NULL || op_pos > curr_end) {
+-      flags = "ies";
+-      flags_end = flags + strlen(flags);
+-      op_pos = curr_end;
+-      op = '+';
+-    } else {
+-      op = *op_pos;
+-    }
+-    jbyte bits = 0;
+-    for (; flags < flags_end; ++flags) {
+-      switch (*flags) {
+-      case 'i': 
+-        bits |= SHOW_IN;
+-        break;
+-      case 'I': 
+-        bits |= SHOW_IN_DETAIL;
+-        break;
+-      case 'e': 
+-        bits |= SHOW_ERROR;
+-        break;
+-      case 'o': 
+-        bits |= SHOW_OUT;
+-        break;
+-      case 'O': 
+-        bits |= SHOW_OUT_DETAIL;
+-        break;
+-      case 't': 
+-        bits |= SHOW_EVENT_TRIGGER;
+-        break;
+-      case 's': 
+-        bits |= SHOW_EVENT_SENT;
+-        break;
+-      default:
+-        tty->print_cr("Invalid trace flag '%c'", *flags);
+-        break;
+-      }
+-    }
+-    const int FUNC = 1;
+-    const int EXCLUDE  = 2;
+-    const int ALL_FUNC = 4;
+-    const int EVENT = 8;
+-    const int ALL_EVENT = 16;
+-    int domain = 0;
+-    size_t len = op_pos - curr;
+-    if (op_pos == curr) {
+-      domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT | EXCLUDE;
+-    } else if (len==3 && strncmp(curr, "all", 3)==0) {
+-      domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT;
+-    } else if (len==7 && strncmp(curr, "allfunc", 7)==0) {
+-      domain = ALL_FUNC | FUNC;
+-    } else if (len==4 && strncmp(curr, "func", 4)==0) {
+-      domain = ALL_FUNC | FUNC | EXCLUDE;
+-    } else if (len==8 && strncmp(curr, "allevent", 8)==0) {
+-      domain = ALL_EVENT | EVENT;
+-    } else if (len==5 && strncmp(curr, "event", 5)==0) {
+-      domain = ALL_EVENT | EVENT;
+-    } else if (len==2 && strncmp(curr, "ec", 2)==0) {
+-      _trace_event_controller = true;
+-      tty->print_cr("JVMTI Tracing the event controller");
+-    } else {
+-      domain = FUNC | EVENT;  // go searching
+-    }
+-
+-    int exclude_index = 0;
+-    if (domain & FUNC) {
+-      if (domain & ALL_FUNC) {
+-        if (domain & EXCLUDE) {
+-          tty->print("JVMTI Tracing all significant functions");
+-        } else {
+-          tty->print_cr("JVMTI Tracing all functions");
+-        }
+-      }
+-      for (int i = 0; i <= _max_function_index; ++i) {
+-        if (domain & EXCLUDE && i == _exclude_functions[exclude_index]) {
+-          ++exclude_index;
+-        } else {
+-          bool do_op = false;
+-          if (domain & ALL_FUNC) {
+-            do_op = true;
+-          } else {
+-            const char *fname = function_name(i);
+-            if (fname != NULL) {
+-              size_t fnlen = strlen(fname);
+-              if (len==fnlen && strncmp(curr, fname, fnlen)==0) {
+-                tty->print_cr("JVMTI Tracing the function: %s", fname);
+-                do_op = true;
+-              }
+-            }
+-          }
+-          if (do_op) {
+-            if (op == '+') {
+-              _trace_flags[i] |= bits;
+-            } else {
+-              _trace_flags[i] &= ~bits;
+-            }
+-            _on = true;
+-          }
+-        }
+-      }
+-    }
+-    if (domain & EVENT) {
+-      if (domain & ALL_EVENT) {
+-        tty->print_cr("JVMTI Tracing all events");
+-      }
+-      for (int i = 0; i <= _max_event_index; ++i) {
+-        bool do_op = false;
+-        if (domain & ALL_EVENT) {
+-          do_op = true;
+-        } else {
+-          const char *ename = event_name(i);
+-          if (ename != NULL) {
+-            size_t evtlen = strlen(ename);
+-            if (len==evtlen && strncmp(curr, ename, evtlen)==0) {
+-              tty->print_cr("JVMTI Tracing the event: %s", ename);
+-              do_op = true;
+-            }
+-          }
+-        }
+-        if (do_op) {
+-          if (op == '+') {
+-            _event_trace_flags[i] |= bits;
+-          } else {
+-            _event_trace_flags[i] &= ~bits;
+-          }
+-          _on = true;
+-        }
+-      }
+-    }
+-    if (!_on && (domain & (FUNC|EVENT))) {
+-      tty->print_cr("JVMTI Trace domain not found");
+-    }
+-    curr = curr_end + 1;
+-  }
+-  _initialized = true;
+-}
+-
+-
+-void JvmtiTrace::shutdown() {
+-  int i;
+-  _on = false;
+-  _trace_event_controller = false;
+-  for (i = 0; i <= _max_function_index; ++i) {
+-    _trace_flags[i] = 0;
+-  }
+-  for (i = 0; i <= _max_event_index; ++i) {
+-    _event_trace_flags[i] = 0;
+-  }
+-}
+-
+-
+-const char* JvmtiTrace::enum_name(const char** names, const jint* values, jint value) {
+-  for (int index = 0; names[index] != 0; ++index) {
+-    if (values[index] == value) {
+-      return names[index];
+-    }
+-  }
+-  return "*INVALID-ENUM-VALUE*";
+-}
+-
+-
+-// return a valid string no matter what state the thread is in
+-const char *JvmtiTrace::safe_get_thread_name(Thread *thread) {
+-  if (thread == NULL) {
+-    return "NULL";
+-  }
+-  if (!thread->is_Java_thread()) {
+-    return thread->name();
+-  }
+-  JavaThread *java_thread = (JavaThread *)thread;
+-  oop threadObj = java_thread->threadObj();
+-  if (threadObj == NULL) {
+-    return "NULL";
+-  }
+-  typeArrayOop name = java_lang_Thread::name(threadObj);
+-  if (name == NULL) {
+-    return "<NOT FILLED IN>";
+-  }
+-  return UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
+-}
+-    
+-
+-// return the name of the current thread
+-const char *JvmtiTrace::safe_get_current_thread_name() {
+-  if (JvmtiEnv::is_vm_live()) {
+-    return JvmtiTrace::safe_get_thread_name(Thread::current());
+-  } else {
+-    return "VM not live";
+-  }
+-}
+-
+-// return a valid string no matter what the state of k_mirror
+-const char * JvmtiTrace::get_class_name(oop k_mirror) {
+-  if (java_lang_Class::is_primitive(k_mirror)) {
+-    return "primitive";
+-  }
+-  klassOop k_oop = java_lang_Class::as_klassOop(k_mirror);
+-  if (k_oop == NULL) {
+-    return "INVALID";
+-  }
+-  return Klass::cast(k_oop)->external_name();
+-}
+-
+-#endif /*JVMTI_TRACE */
+ 
+ //
+ // class GrowableCache - private methods
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiImpl.hpp openjdk/hotspot/src/share/vm/prims/jvmtiImpl.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiImpl.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiImpl.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiImpl.hpp	1.102 07/05/23 10:53:50 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -476,147 +473,5 @@
+   static void print();
+ };
+ 
+-
+-///////////////////////////////////////////////////////////////
+-//
+-// class JvmtiUtil
+-//
+-// class for miscellaneous jvmti utility static methods
+-//
+-
+-class JvmtiUtil : AllStatic {
+-
+-  static ResourceArea* _single_threaded_resource_area;
+-
+-  static const char* _error_names[];
+-  static const bool  _event_threaded[];
+-
+-public:
+-
+-  static ResourceArea* single_threaded_resource_area();
+-
+-  static const char* error_name(int num)    { return _error_names[num]; }    // To Do: add range checking
+-
+-  static const bool has_event_capability(jvmtiEvent event_type, const jvmtiCapabilities* capabilities_ptr);
+-
+-  static const bool  event_threaded(int num) {
+-    if (num >= JVMTI_MIN_EVENT_TYPE_VAL && num <= JVMTI_MAX_EVENT_TYPE_VAL) {
+-      return _event_threaded[num];
+-    }
+-    if (num >= EXT_MIN_EVENT_TYPE_VAL && num <= EXT_MAX_EVENT_TYPE_VAL) {
+-      return false;
+-    }
+-    ShouldNotReachHere();
+-    return false;
+-  }
+-};
+-
+-
+-///////////////////////////////////////////////////////////////
+-//
+-// class SafeResourceMark
+-//
+-// ResourceMarks that work before threads exist
+-//
+-
+-class SafeResourceMark : public ResourceMark {
+-
+-  ResourceArea* safe_resource_area() {
+-    Thread* thread;
+-
+-    if (Threads::number_of_threads() == 0) {
+-      return JvmtiUtil::single_threaded_resource_area();
+-    }
+-    thread = ThreadLocalStorage::thread();
+-    if (thread == NULL) {
+-      return JvmtiUtil::single_threaded_resource_area();
+-    }
+-    return thread->resource_area();
+-  }
+-
+- public:
+-
+-  SafeResourceMark() : ResourceMark(safe_resource_area()) {}
+-
+-};
+-
+-
+-///////////////////////////////////////////////////////////////
+-//
+-// class JvmtiTrace
+-//
+-// Support for JVMTI tracing code
+-//
+-
+-// Support tracing except in product build on the client compiler
+-#ifndef PRODUCT
+-#define JVMTI_TRACE 1
+-#else
+-#ifdef COMPILER2
+-#define JVMTI_TRACE 1
+-#endif
+-#endif
+-
+-#ifdef JVMTI_TRACE
+-
+-class JvmtiTrace : AllStatic {
+-
+-  static bool        _initialized;
+-  static bool        _on;
+-  static bool        _trace_event_controller;
+-  static jbyte       _trace_flags[];
+-  static jbyte       _event_trace_flags[];
+-  static const char* _event_names[];
+-  static jint        _max_function_index;
+-  static jint        _max_event_index;
+-  static short       _exclude_functions[];
+-  static const char* _function_names[];
+-
+-public:
+-
+-  enum {
+-    SHOW_IN =              01,
+-    SHOW_OUT =             02,
+-    SHOW_ERROR =           04,
+-    SHOW_IN_DETAIL =      010,
+-    SHOW_OUT_DETAIL =     020,
+-    SHOW_EVENT_TRIGGER =  040,
+-    SHOW_EVENT_SENT =    0100
+-  };
+-
+-  static bool tracing()                     { return _on; }
+-  static bool trace_event_controller()      { return _trace_event_controller; }
+-  static jbyte trace_flags(int num)         { return _trace_flags[num]; }
+-  static jbyte event_trace_flags(int num)   { return _event_trace_flags[num]; }
+-  static const char* function_name(int num) { return _function_names[num]; } // To Do: add range checking
+-
+-  static const char* event_name(int num) {
+-    static char* ext_event_name = (char*)"(extension event)";
+-    if (num >= JVMTI_MIN_EVENT_TYPE_VAL && num <= JVMTI_MAX_EVENT_TYPE_VAL) {
+-      return _event_names[num];
+-    } else {
+-      return ext_event_name;
+-    }
+-  }
+-
+-  static const char* enum_name(const char** names, const jint* values, jint value);
+-
+-  static void initialize();
+-  static void shutdown();
+-
+-  // return a valid string no matter what state the thread is in
+-  static const char *safe_get_thread_name(Thread *thread);
+-    
+-  // return the name of the current thread
+-  static const char *safe_get_current_thread_name();
+-       
+-  // return a valid string no matter what the state of k_mirror
+-  static const char *get_class_name(oop k_mirror);
+-};
+-
+-#endif /*JVMTI_TRACE */
+-
+-
+ // Utility macro that checks for NULL pointers:
+ #define NULL_CHECK(X, Y) if ((X) == NULL) { return (Y); } 
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiManageCapabilities.cpp	1.44 07/05/05 17:06:40 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -458,5 +455,3 @@
+ }
+ 
+ #endif
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiManageCapabilities.hpp openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiManageCapabilities.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiManageCapabilities.hpp	1.11 07/05/05 17:06:39 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiRedefineClasses.cpp	1.78 07/05/05 17:06:41 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -3050,9 +3047,11 @@
+   klassOop the_class_oop = java_lang_Class::as_klassOop(the_class_mirror);
+   instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop);
+ 
++#ifndef JVMTI_KERNEL
+   // Remove all breakpoints in methods of this class
+   JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
+   jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop); 
++#endif // !JVMTI_KERNEL
+ 
+   if (the_class_oop == Universe::reflect_invoke_cache()->klass()) {
+     // We are redefining java.lang.reflect.Method. Method.invoke() is
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiRedefineClasses.hpp	1.41 08/06/19 12:45:49 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -334,108 +331,6 @@
+ //   coordinate a cleanup of these constants with Runtime.
+ //
+ 
+-
+-// RedefineClasses tracing support via the TraceRedefineClasses
+-// option. A bit is assigned to each group of trace messages.
+-// Groups of messages are individually selectable. We have to use
+-// decimal values on the command line since the command option
+-// parsing logic doesn't like non-decimal numerics. The HEX values
+-// are used in the actual RC_TRACE() calls for sanity. To achieve
+-// the old cumulative behavior, pick the level after the one in
+-// which you are interested and subtract one, e.g., 33554431 will
+-// print every tracing message.
+-// 
+-//    0x00000000 |          0 - default; no tracing messages
+-//    0x00000001 |          1 - name each target class before loading, after
+-//                              loading and after redefinition is completed
+-//    0x00000002 |          2 - print info if parsing, linking or
+-//                              verification throws an exception
+-//    0x00000004 |          4 - print timer info for the VM operation
+-//    0x00000008 |          8 - print subclass counter updates
+-//    0x00000010 |         16 - unused
+-//    0x00000020 |         32 - unused
+-//    0x00000040 |         64 - unused
+-//    0x00000080 |        128 - unused
+-//    0x00000100 |        256 - previous class weak reference addition
+-//    0x00000200 |        512 - previous class weak reference mgmt during
+-//                              class unloading checks (GC)
+-//    0x00000400 |       1024 - previous class weak reference mgmt during
+-//                              add previous ops (GC)
+-//    0x00000800 |       2048 - previous class breakpoint mgmt
+-//    0x00001000 |       4096 - unused
+-//    0x00002000 |       8192 - unused
+-//    0x00004000 |      16384 - unused
+-//    0x00008000 |      32768 - old/new method matching/add/delete 
+-//    0x00010000 |      65536 - impl details: CP size info
+-//    0x00020000 |     131072 - impl details: CP merge pass info
+-//    0x00040000 |     262144 - impl details: CP index maps
+-//    0x00080000 |     524288 - impl details: modified CP index values
+-//    0x00100000 |    1048576 - impl details: vtable updates
+-//    0x00200000 |    2097152 - impl details: itable updates
+-//    0x00400000 |    4194304 - impl details: constant pool cache updates
+-//    0x00800000 |    8388608 - impl details: methodComparator info
+-//    0x01000000 |   16777216 - impl details: nmethod evolution info
+-//    0x02000000 |   33554432 - impl details: annotation updates
+-//    0x04000000 |   67108864 - impl details: StackMapTable updates
+-//    0x08000000 |  134217728 - impl details: OopMapCache updates
+-//    0x10000000 |  268435456 - unused
+-//    0x20000000 |  536870912 - unused
+-//    0x40000000 | 1073741824 - unused
+-//    0x80000000 | 2147483648 - unused
+-//
+-// Note: The ResourceMark is to cleanup resource allocated args.
+-//   The "while (0)" is so we can use semi-colon at end of RC_TRACE().
+-#define RC_TRACE(level, args) \
+-  if ((TraceRedefineClasses & level) != 0) { \
+-    ResourceMark rm; \
+-    tty->print("RedefineClasses-0x%x: ", level); \
+-    tty->print_cr args; \
+-  } while (0)
+-
+-#define RC_TRACE_WITH_THREAD(level, thread, args) \
+-  if ((TraceRedefineClasses & level) != 0) { \
+-    ResourceMark rm(thread); \
+-    tty->print("RedefineClasses-0x%x: ", level); \
+-    tty->print_cr args; \
+-  } while (0)
+-
+-#define RC_TRACE_MESG(args) \
+-  { \
+-    ResourceMark rm; \
+-    tty->print("RedefineClasses: "); \
+-    tty->print_cr args; \
+-  } while (0)
+-
+-// Macro for checking if TraceRedefineClasses has a specific bit
+-// enabled. Returns true if the bit specified by level is set.
+-#define RC_TRACE_ENABLED(level) ((TraceRedefineClasses & level) != 0)
+-
+-// Macro for checking if TraceRedefineClasses has one or more bits
+-// set in a range of bit values. Returns true if one or more bits
+-// is set in the range from low..high inclusive. Assumes that low
+-// and high are single bit values.
+-//
+-// ((high << 1) - 1)
+-//     Yields a mask that removes bits greater than the high bit value.
+-//     This algorithm doesn't work with highest bit.
+-// ~(low - 1)
+-//     Yields a mask that removes bits lower than the low bit value.
+-#define RC_TRACE_IN_RANGE(low, high) \
+-(((TraceRedefineClasses & ((high << 1) - 1)) & ~(low - 1)) != 0)
+-
+-// Timer support macros. Only do timer operations if timer tracing
+-// is enabled. The "while (0)" is so we can use semi-colon at end of
+-// the macro.
+-#define RC_TIMER_START(t) \
+-  if (RC_TRACE_ENABLED(0x00000004)) { \
+-    t.start(); \
+-  } while (0)
+-#define RC_TIMER_STOP(t) \
+-  if (RC_TRACE_ENABLED(0x00000004)) { \
+-    t.stop(); \
+-  } while (0)
+-
+-
+ class VM_RedefineClasses: public VM_Operation {
+  private:
+   // These static fields are needed by SystemDictionary::classes_do()
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,123 @@
++/*
++ * Copyright 2003-2006 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++// RedefineClasses tracing support via the TraceRedefineClasses
++// option. A bit is assigned to each group of trace messages.
++// Groups of messages are individually selectable. We have to use
++// decimal values on the command line since the command option
++// parsing logic doesn't like non-decimal numerics. The HEX values
++// are used in the actual RC_TRACE() calls for sanity. To achieve
++// the old cumulative behavior, pick the level after the one in
++// which you are interested and subtract one, e.g., 33554431 will
++// print every tracing message.
++//
++//    0x00000000 |          0 - default; no tracing messages
++//    0x00000001 |          1 - name each target class before loading, after
++//                              loading and after redefinition is completed
++//    0x00000002 |          2 - print info if parsing, linking or
++//                              verification throws an exception
++//    0x00000004 |          4 - print timer info for the VM operation
++//    0x00000008 |          8 - print subclass counter updates
++//    0x00000010 |         16 - unused
++//    0x00000020 |         32 - unused
++//    0x00000040 |         64 - unused
++//    0x00000080 |        128 - unused
++//    0x00000100 |        256 - previous class weak reference addition
++//    0x00000200 |        512 - previous class weak reference mgmt during
++//                              class unloading checks (GC)
++//    0x00000400 |       1024 - previous class weak reference mgmt during
++//                              add previous ops (GC)
++//    0x00000800 |       2048 - previous class breakpoint mgmt
++//    0x00001000 |       4096 - unused
++//    0x00002000 |       8192 - unused
++//    0x00004000 |      16384 - unused
++//    0x00008000 |      32768 - old/new method matching/add/delete
++//    0x00010000 |      65536 - impl details: CP size info
++//    0x00020000 |     131072 - impl details: CP merge pass info
++//    0x00040000 |     262144 - impl details: CP index maps
++//    0x00080000 |     524288 - impl details: modified CP index values
++//    0x00100000 |    1048576 - impl details: vtable updates
++//    0x00200000 |    2097152 - impl details: itable updates
++//    0x00400000 |    4194304 - impl details: constant pool cache updates
++//    0x00800000 |    8388608 - impl details: methodComparator info
++//    0x01000000 |   16777216 - impl details: nmethod evolution info
++//    0x02000000 |   33554432 - impl details: annotation updates
++//    0x04000000 |   67108864 - impl details: StackMapTable updates
++//    0x08000000 |  134217728 - unused
++//    0x10000000 |  268435456 - unused
++//    0x20000000 |  536870912 - unused
++//    0x40000000 | 1073741824 - unused
++//    0x80000000 | 2147483648 - unused
++//
++// Note: The ResourceMark is to cleanup resource allocated args.
++//   The "while (0)" is so we can use semi-colon at end of RC_TRACE().
++#define RC_TRACE(level, args) \
++  if ((TraceRedefineClasses & level) != 0) { \
++    ResourceMark rm; \
++    tty->print("RedefineClasses-0x%x: ", level); \
++    tty->print_cr args; \
++  } while (0)
++
++#define RC_TRACE_WITH_THREAD(level, thread, args) \
++  if ((TraceRedefineClasses & level) != 0) { \
++    ResourceMark rm(thread); \
++    tty->print("RedefineClasses-0x%x: ", level); \
++    tty->print_cr args; \
++  } while (0)
++
++#define RC_TRACE_MESG(args) \
++  { \
++    ResourceMark rm; \
++    tty->print("RedefineClasses: "); \
++    tty->print_cr args; \
++  } while (0)
++
++// Macro for checking if TraceRedefineClasses has a specific bit
++// enabled. Returns true if the bit specified by level is set.
++#define RC_TRACE_ENABLED(level) ((TraceRedefineClasses & level) != 0)
++
++// Macro for checking if TraceRedefineClasses has one or more bits
++// set in a range of bit values. Returns true if one or more bits
++// is set in the range from low..high inclusive. Assumes that low
++// and high are single bit values.
++//
++// ((high << 1) - 1)
++//     Yields a mask that removes bits greater than the high bit value.
++//     This algorithm doesn't work with highest bit.
++// ~(low - 1)
++//     Yields a mask that removes bits lower than the low bit value.
++#define RC_TRACE_IN_RANGE(low, high) \
++(((TraceRedefineClasses & ((high << 1) - 1)) & ~(low - 1)) != 0)
++
++// Timer support macros. Only do timer operations if timer tracing
++// is enabled. The "while (0)" is so we can use semi-colon at end of
++// the macro.
++#define RC_TIMER_START(t) \
++  if (RC_TRACE_ENABLED(0x00000004)) { \
++    t.start(); \
++  } while (0)
++#define RC_TIMER_STOP(t) \
++  if (RC_TRACE_ENABLED(0x00000004)) { \
++    t.stop(); \
++  } while (0)
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiTagMap.cpp openjdk/hotspot/src/share/vm/prims/jvmtiTagMap.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiTagMap.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiTagMap.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiTagMap.cpp	1.84 07/06/06 13:18:31 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -2251,6 +2248,15 @@
+   return true;
+ }
+ 
++// This mask is used to pass reference_info to a jvmtiHeapReferenceCallback
++// only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed.
++#define REF_INFO_MASK  ((1 << JVMTI_HEAP_REFERENCE_FIELD)         \
++                      | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD)  \
++                      | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \
++                      | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \
++                      | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL)   \
++                      | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL))
++
+ // invoke the object reference callback to report a reference
+ inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind,
+ 					                               oop referrer, 
+@@ -2294,7 +2300,7 @@
+ 
+   // invoke the callback
+   int res = (*cb)(ref_kind, 
+-                  &reference_info,
++                  (REF_INFO_MASK & (1 << ref_kind)) ? &reference_info : NULL,
+                   wrapper.klass_tag(),
+                   wrapper.referrer_klass_tag(),
+                   wrapper.obj_size(),
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiTagMap.hpp openjdk/hotspot/src/share/vm/prims/jvmtiTagMap.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiTagMap.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiTagMap.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiTagMap.hpp	1.25 07/05/05 17:06:40 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -136,4 +133,3 @@
+ };
+ 
+ #endif   /* _JAVA_JVMTI_TAG_MAP_H_ */
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.cpp openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvmtiThreadState.cpp	1.44 07/05/05 17:06:36 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.hpp openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiThreadState.hpp	1.35 07/05/05 17:06:40 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.inline.hpp openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.inline.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.inline.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvmtiThreadState.inline.hpp	1.7 07/05/05 17:06:40 JVM"
+-#endif
+ /*
+  * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -63,4 +60,3 @@
+ void JvmtiThreadState::set_head_env_thread_state(JvmtiEnvThreadState* ets) {
+   _head_env_thread_state = ets; 
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiTrace.cpp openjdk/hotspot/src/share/vm/prims/jvmtiTrace.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiTrace.cpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/prims/jvmtiTrace.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,297 @@
++/*
++ * Copyright 2003-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++# include "incls/_precompiled.incl"
++# include "incls/_jvmtiTrace.cpp.incl"
++
++//
++// class JvmtiTrace
++//
++// Support for JVMTI tracing code
++//
++// ------------
++// Usage:
++//    -XX:TraceJVMTI=DESC,DESC,DESC
++//
++//    DESC is   DOMAIN ACTION KIND
++//
++//    DOMAIN is function name
++//              event name
++//              "all" (all functions and events)
++//              "func" (all functions except boring)
++//              "allfunc" (all functions)
++//              "event" (all events)
++//              "ec" (event controller)
++//
++//    ACTION is "+" (add)
++//              "-" (remove)
++//
++//    KIND is
++//     for func
++//              "i" (input params)
++//              "e" (error returns)
++//              "o" (output)
++//     for event
++//              "t" (event triggered aka posted)
++//              "s" (event sent)
++//
++// Example:
++//            -XX:TraceJVMTI=ec+,GetCallerFrame+ie,Breakpoint+s
++
++#ifdef JVMTI_TRACE
++
++bool JvmtiTrace::_initialized = false;
++bool JvmtiTrace::_on = false;
++bool JvmtiTrace::_trace_event_controller = false;
++
++void JvmtiTrace::initialize() {
++  if (_initialized) {
++    return;
++  }
++  SafeResourceMark rm;
++
++  const char *very_end;
++  const char *curr;
++  if (strlen(TraceJVMTI)) {
++    curr = TraceJVMTI;
++  } else {
++    curr = "";  // hack in fixed tracing here
++  }
++  very_end = curr + strlen(curr);
++  while (curr < very_end) {
++    const char *curr_end = strchr(curr, ',');
++    if (curr_end == NULL) {
++      curr_end = very_end;
++    }
++    const char *op_pos = strchr(curr, '+');
++    const char *minus_pos = strchr(curr, '-');
++    if (minus_pos != NULL && (minus_pos < op_pos || op_pos == NULL)) {
++      op_pos = minus_pos;
++    }
++    char op;
++    const char *flags = op_pos + 1;
++    const char *flags_end = curr_end;
++    if (op_pos == NULL || op_pos > curr_end) {
++      flags = "ies";
++      flags_end = flags + strlen(flags);
++      op_pos = curr_end;
++      op = '+';
++    } else {
++      op = *op_pos;
++    }
++    jbyte bits = 0;
++    for (; flags < flags_end; ++flags) {
++      switch (*flags) {
++      case 'i':
++        bits |= SHOW_IN;
++        break;
++      case 'I':
++        bits |= SHOW_IN_DETAIL;
++        break;
++      case 'e':
++        bits |= SHOW_ERROR;
++        break;
++      case 'o':
++        bits |= SHOW_OUT;
++        break;
++      case 'O':
++        bits |= SHOW_OUT_DETAIL;
++        break;
++      case 't':
++        bits |= SHOW_EVENT_TRIGGER;
++        break;
++      case 's':
++        bits |= SHOW_EVENT_SENT;
++        break;
++      default:
++        tty->print_cr("Invalid trace flag '%c'", *flags);
++        break;
++      }
++    }
++    const int FUNC = 1;
++    const int EXCLUDE  = 2;
++    const int ALL_FUNC = 4;
++    const int EVENT = 8;
++    const int ALL_EVENT = 16;
++    int domain = 0;
++    size_t len = op_pos - curr;
++    if (op_pos == curr) {
++      domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT | EXCLUDE;
++    } else if (len==3 && strncmp(curr, "all", 3)==0) {
++      domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT;
++    } else if (len==7 && strncmp(curr, "allfunc", 7)==0) {
++      domain = ALL_FUNC | FUNC;
++    } else if (len==4 && strncmp(curr, "func", 4)==0) {
++      domain = ALL_FUNC | FUNC | EXCLUDE;
++    } else if (len==8 && strncmp(curr, "allevent", 8)==0) {
++      domain = ALL_EVENT | EVENT;
++    } else if (len==5 && strncmp(curr, "event", 5)==0) {
++      domain = ALL_EVENT | EVENT;
++    } else if (len==2 && strncmp(curr, "ec", 2)==0) {
++      _trace_event_controller = true;
++      tty->print_cr("JVMTI Tracing the event controller");
++    } else {
++      domain = FUNC | EVENT;  // go searching
++    }
++
++    int exclude_index = 0;
++    if (domain & FUNC) {
++      if (domain & ALL_FUNC) {
++        if (domain & EXCLUDE) {
++          tty->print("JVMTI Tracing all significant functions");
++        } else {
++          tty->print_cr("JVMTI Tracing all functions");
++        }
++      }
++      for (int i = 0; i <= _max_function_index; ++i) {
++        if (domain & EXCLUDE && i == _exclude_functions[exclude_index]) {
++          ++exclude_index;
++        } else {
++          bool do_op = false;
++          if (domain & ALL_FUNC) {
++            do_op = true;
++          } else {
++            const char *fname = function_name(i);
++            if (fname != NULL) {
++              size_t fnlen = strlen(fname);
++              if (len==fnlen && strncmp(curr, fname, fnlen)==0) {
++                tty->print_cr("JVMTI Tracing the function: %s", fname);
++                do_op = true;
++              }
++            }
++          }
++          if (do_op) {
++            if (op == '+') {
++              _trace_flags[i] |= bits;
++            } else {
++              _trace_flags[i] &= ~bits;
++            }
++            _on = true;
++          }
++        }
++      }
++    }
++    if (domain & EVENT) {
++      if (domain & ALL_EVENT) {
++        tty->print_cr("JVMTI Tracing all events");
++      }
++      for (int i = 0; i <= _max_event_index; ++i) {
++        bool do_op = false;
++        if (domain & ALL_EVENT) {
++          do_op = true;
++        } else {
++          const char *ename = event_name(i);
++          if (ename != NULL) {
++            size_t evtlen = strlen(ename);
++            if (len==evtlen && strncmp(curr, ename, evtlen)==0) {
++              tty->print_cr("JVMTI Tracing the event: %s", ename);
++              do_op = true;
++            }
++          }
++        }
++        if (do_op) {
++          if (op == '+') {
++            _event_trace_flags[i] |= bits;
++          } else {
++            _event_trace_flags[i] &= ~bits;
++          }
++          _on = true;
++        }
++      }
++    }
++    if (!_on && (domain & (FUNC|EVENT))) {
++      tty->print_cr("JVMTI Trace domain not found");
++    }
++    curr = curr_end + 1;
++  }
++  _initialized = true;
++}
++
++
++void JvmtiTrace::shutdown() {
++  int i;
++  _on = false;
++  _trace_event_controller = false;
++  for (i = 0; i <= _max_function_index; ++i) {
++    _trace_flags[i] = 0;
++  }
++  for (i = 0; i <= _max_event_index; ++i) {
++    _event_trace_flags[i] = 0;
++  }
++}
++
++
++const char* JvmtiTrace::enum_name(const char** names, const jint* values, jint value) {
++  for (int index = 0; names[index] != 0; ++index) {
++    if (values[index] == value) {
++      return names[index];
++    }
++  }
++  return "*INVALID-ENUM-VALUE*";
++}
++
++
++// return a valid string no matter what state the thread is in
++const char *JvmtiTrace::safe_get_thread_name(Thread *thread) {
++  if (thread == NULL) {
++    return "NULL";
++  }
++  if (!thread->is_Java_thread()) {
++    return thread->name();
++  }
++  JavaThread *java_thread = (JavaThread *)thread;
++  oop threadObj = java_thread->threadObj();
++  if (threadObj == NULL) {
++    return "NULL";
++  }
++  typeArrayOop name = java_lang_Thread::name(threadObj);
++  if (name == NULL) {
++    return "<NOT FILLED IN>";
++  }
++  return UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
++}
++
++
++// return the name of the current thread
++const char *JvmtiTrace::safe_get_current_thread_name() {
++  if (JvmtiEnv::is_vm_live()) {
++    return JvmtiTrace::safe_get_thread_name(Thread::current());
++  } else {
++    return "VM not live";
++  }
++}
++
++// return a valid string no matter what the state of k_mirror
++const char * JvmtiTrace::get_class_name(oop k_mirror) {
++  if (java_lang_Class::is_primitive(k_mirror)) {
++    return "primitive";
++  }
++  klassOop k_oop = java_lang_Class::as_klassOop(k_mirror);
++  if (k_oop == NULL) {
++    return "INVALID";
++  }
++  return Klass::cast(k_oop)->external_name();
++}
++
++#endif /*JVMTI_TRACE */
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiTrace.hpp openjdk/hotspot/src/share/vm/prims/jvmtiTrace.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiTrace.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/prims/jvmtiTrace.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,98 @@
++/*
++ * Copyright 1999-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++///////////////////////////////////////////////////////////////
++//
++// class JvmtiTrace
++//
++// Support for JVMTI tracing code
++//
++
++// Support tracing except in product build on the client compiler
++#ifndef PRODUCT
++#define JVMTI_TRACE 1
++#else
++#ifdef COMPILER2
++#define JVMTI_TRACE 1
++#endif
++#endif
++
++#ifdef JVMTI_TRACE
++
++class JvmtiTrace : AllStatic {
++
++  static bool        _initialized;
++  static bool        _on;
++  static bool        _trace_event_controller;
++  static jbyte       _trace_flags[];
++  static jbyte       _event_trace_flags[];
++  static const char* _event_names[];
++  static jint        _max_function_index;
++  static jint        _max_event_index;
++  static short       _exclude_functions[];
++  static const char* _function_names[];
++
++public:
++
++  enum {
++    SHOW_IN =              01,
++    SHOW_OUT =             02,
++    SHOW_ERROR =           04,
++    SHOW_IN_DETAIL =      010,
++    SHOW_OUT_DETAIL =     020,
++    SHOW_EVENT_TRIGGER =  040,
++    SHOW_EVENT_SENT =    0100
++  };
++
++  static bool tracing()                     { return _on; }
++  static bool trace_event_controller()      { return _trace_event_controller; }
++  static jbyte trace_flags(int num)         { return _trace_flags[num]; }
++  static jbyte event_trace_flags(int num)   { return _event_trace_flags[num]; }
++  static const char* function_name(int num) { return _function_names[num]; } // To Do: add range checking
++
++  static const char* event_name(int num) {
++    static char* ext_event_name = (char*)"(extension event)";
++    if (num >= JVMTI_MIN_EVENT_TYPE_VAL && num <= JVMTI_MAX_EVENT_TYPE_VAL) {
++      return _event_names[num];
++    } else {
++      return ext_event_name;
++    }
++  }
++
++  static const char* enum_name(const char** names, const jint* values, jint value);
++
++  static void initialize();
++  static void shutdown();
++
++  // return a valid string no matter what state the thread is in
++  static const char *safe_get_thread_name(Thread *thread);
++
++  // return the name of the current thread
++  static const char *safe_get_current_thread_name();
++
++  // return a valid string no matter what the state of k_mirror
++  static const char *get_class_name(oop k_mirror);
++};
++
++#endif /*JVMTI_TRACE */
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiUtil.cpp openjdk/hotspot/src/share/vm/prims/jvmtiUtil.cpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiUtil.cpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/prims/jvmtiUtil.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,40 @@
++/*
++ * Copyright 2003-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++# include "incls/_precompiled.incl"
++# include "incls/_jvmtiUtil.cpp.incl"
++//
++// class JvmtiUtil
++//
++
++ResourceArea* JvmtiUtil::_single_threaded_resource_area = NULL;
++
++ResourceArea* JvmtiUtil::single_threaded_resource_area() {
++  if (_single_threaded_resource_area == NULL) {
++    // lazily create the single threaded resource area
++    // pick a size which is not a standard since the pools don't exist yet
++    _single_threaded_resource_area = new ResourceArea(Chunk::non_pool_size);
++  }
++  return _single_threaded_resource_area;
++}
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiUtil.hpp openjdk/hotspot/src/share/vm/prims/jvmtiUtil.hpp
+--- openjdk6/hotspot/src/share/vm/prims/jvmtiUtil.hpp	1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/prims/jvmtiUtil.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -0,0 +1,86 @@
++/*
++ * Copyright 1999-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ */
++
++///////////////////////////////////////////////////////////////
++//
++// class JvmtiUtil
++//
++// class for miscellaneous jvmti utility static methods
++//
++
++class JvmtiUtil : AllStatic {
++
++  static ResourceArea* _single_threaded_resource_area;
++
++  static const char* _error_names[];
++  static const bool  _event_threaded[];
++
++public:
++
++  static ResourceArea* single_threaded_resource_area();
++
++  static const char* error_name(int num)    { return _error_names[num]; }    // To Do: add range checking
++
++  static const bool has_event_capability(jvmtiEvent event_type, const jvmtiCapabilities* capabilities_ptr);
++
++  static const bool  event_threaded(int num) {
++    if (num >= JVMTI_MIN_EVENT_TYPE_VAL && num <= JVMTI_MAX_EVENT_TYPE_VAL) {
++      return _event_threaded[num];
++    }
++    if (num >= EXT_MIN_EVENT_TYPE_VAL && num <= EXT_MAX_EVENT_TYPE_VAL) {
++      return false;
++    }
++    ShouldNotReachHere();
++    return false;
++  }
++};
++
++
++///////////////////////////////////////////////////////////////
++//
++// class SafeResourceMark
++//
++// ResourceMarks that work before threads exist
++//
++
++class SafeResourceMark : public ResourceMark {
++
++  ResourceArea* safe_resource_area() {
++    Thread* thread;
++
++    if (Threads::number_of_threads() == 0) {
++      return JvmtiUtil::single_threaded_resource_area();
++    }
++    thread = ThreadLocalStorage::thread();
++    if (thread == NULL) {
++      return JvmtiUtil::single_threaded_resource_area();
++    }
++    return thread->resource_area();
++  }
++
++ public:
++
++  SafeResourceMark() : ResourceMark(safe_resource_area()) {}
++
++};
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmti.xml openjdk/hotspot/src/share/vm/prims/jvmti.xml
+--- openjdk6/hotspot/src/share/vm/prims/jvmti.xml	2008-08-28 10:23:15.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/jvmti.xml	2007-12-14 08:57:03.000000000 +0100
+@@ -56,6 +56,7 @@
+ 		      callbacksafe (safe|unsafe) #IMPLIED
+                       impl CDATA #IMPLIED
+                       hide CDATA #IMPLIED
++                      jkernel (yes|no) #IMPLIED
+                       since CDATA "1.0">
+ 
+    <!ELEMENT callback ((jmethodID|jfieldID|jframeID|jrawMonitorID|jclass|jthread|jthreadGroup|jobject|
+@@ -359,7 +360,7 @@
+ <specification label="JVM(TM) Tool Interface"
+         majorversion="1"
+         minorversion="1"
+-        microversion="102">
++        microversion="109">
+   <title subtitle="Version">
+     <tm>JVM</tm> Tool Interface
+   </title>
+@@ -969,7 +970,7 @@
+       allocation libraries and mechanisms.
+     </intro>
+ 
+-    <function id="Allocate" phase="any" callbacksafe="safe" impl="notrace" num="46">
++    <function id="Allocate" jkernel="yes" phase="any" callbacksafe="safe" impl="notrace" num="46">
+       <synopsis>Allocate</synopsis>
+       <description>
+ 	Allocate an area of memory through the <jvmti/> allocator. 
+@@ -1007,7 +1008,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="Deallocate" phase="any" callbacksafe="safe" impl="notrace" num="47">
++    <function id="Deallocate" jkernel="yes" phase="any" callbacksafe="safe" impl="notrace" num="47">
+       <synopsis>Deallocate</synopsis>
+       <description>
+ 	Deallocate <code>mem</code>  using the <jvmti/> allocator. 
+@@ -2074,7 +2075,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="SetThreadLocalStorage" impl="notrace" phase="start" num="103">
++    <function id="SetThreadLocalStorage" jkernel="yes" impl="notrace" phase="start" num="103">
+       <synopsis>Set Thread Local Storage</synopsis>
+       <description>
+ 	The VM stores a pointer value associated with each environment-thread
+@@ -2114,7 +2115,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="GetThreadLocalStorage" impl="innative notrace" phase="start" num="102">
++    <function id="GetThreadLocalStorage" jkernel="yes" impl="innative notrace" phase="start" num="102">
+       <synopsis>Get Thread Local Storage</synopsis>
+       <description>
+         Called by the agent to get the value of the <jvmti/> thread-local
+@@ -6360,7 +6361,7 @@
+     <intro>
+     </intro>
+ 
+-    <function id="GetLoadedClasses" num="78">
++    <function id="GetLoadedClasses" jkernel="yes" num="78">
+       <synopsis>Get Loaded Classes</synopsis>
+       <description>
+ 	Return an array of all classes loaded in the virtual machine.
+@@ -6394,7 +6395,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="GetClassLoaderClasses" num="79">
++    <function id="GetClassLoaderClasses" jkernel="yes" num="79">
+       <synopsis>Get Classloader Classes</synopsis>
+       <description>
+ 	Returns an array of those classes for which this class loader has
+@@ -6935,7 +6936,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="IsModifiableClass" phase="start" num="45" since="1.1">
++    <function id="IsModifiableClass" jkernel="yes" phase="start" num="45" since="1.1">
+       <synopsis>Is Modifiable Class</synopsis>
+       <description>
+ 	Determines whether a class is modifiable.
+@@ -7060,7 +7061,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="RetransformClasses" num="152" since="1.1">
++    <function id="RetransformClasses" jkernel="yes" num="152" since="1.1">
+       <synopsis>Retransform Classes</synopsis>
+       <description>
+         This function facilitates the 
+@@ -7228,7 +7229,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="RedefineClasses" num="87">
++    <function id="RedefineClasses" jkernel="yes" num="87">
+       <synopsis>Redefine Classes</synopsis>
+       <typedef id="jvmtiClassDefinition" label="Class redefinition description">
+ 	<field id="klass">
+@@ -7385,7 +7386,7 @@
+ 
+   <category id="object" label="Object">
+ 
+-    <function id="GetObjectSize" phase="start" num="154">
++    <function id="GetObjectSize" jkernel="yes" phase="start" num="154">
+       <synopsis>Get Object Size</synopsis>
+       <description>
+ 	For the object indicated by <code>object</code>,
+@@ -8310,7 +8311,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="SetNativeMethodPrefix" phase="any" num="73" since="1.1">
++    <function id="SetNativeMethodPrefix" jkernel="yes" phase="any" num="73" since="1.1">
+       <synopsis>Set Native Method Prefix</synopsis>
+       <description>
+ 	This function modifies the failure handling of
+@@ -8433,7 +8434,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="SetNativeMethodPrefixes" phase="any" num="74" since="1.1">
++    <function id="SetNativeMethodPrefixes" jkernel="yes" phase="any" num="74" since="1.1">
+       <synopsis>Set Native Method Prefixes</synopsis>
+       <description>
+ 	 For a normal agent, <functionlink id="SetNativeMethodPrefix"/>
+@@ -8868,7 +8869,7 @@
+ 
+   <category id="eventManagement" label="Event Management">
+ 
+-    <function id="SetEventCallbacks" phase="onload" num="122">
++    <function id="SetEventCallbacks" jkernel="yes" phase="onload" num="122">
+       <synopsis>Set Event Callbacks</synopsis>
+       <description>
+         Set the functions to be called for each event.
+@@ -8911,7 +8912,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="SetEventNotificationMode" phase="onload" num="2">
++    <function id="SetEventNotificationMode" jkernel="yes" phase="onload" num="2">
+       <synopsis>Set Event Notification Mode</synopsis>
+       <description>
+ 	Control the generation of events. 
+@@ -9857,7 +9858,7 @@
+       </capabilityfield>
+     </capabilitiestypedef>
+ 
+-    <function id="GetPotentialCapabilities" phase="onload" num="140">
++    <function id="GetPotentialCapabilities" jkernel="yes" phase="onload" num="140">
+       <synopsis>Get Potential Capabilities</synopsis>
+       <description>
+         Returns via <paramlink id="capabilities_ptr"></paramlink> the <jvmti/> 
+@@ -9972,7 +9973,7 @@
+     </function>
+     </elide>
+ 
+-    <function id="AddCapabilities" phase="onload" num="142">
++    <function id="AddCapabilities" jkernel="yes" phase="onload" num="142">
+       <synopsis>Add Capabilities</synopsis>
+       <description>
+         Set new capabilities by adding the capabilities 
+@@ -10049,7 +10050,7 @@
+ 
+ 
+ 
+-    <function id="GetCapabilities" phase="any" num="89">
++    <function id="GetCapabilities" jkernel="yes" phase="any" num="89">
+       <synopsis>Get Capabilities</synopsis>
+         <description>
+           Returns via <paramlink id="capabilities_ptr"></paramlink> the optional <jvmti/> 
+@@ -10416,7 +10417,7 @@
+       This is useful for installing instrumentation under the correct class loader.
+     </intro>
+ 
+-    <function id="AddToBootstrapClassLoaderSearch" phase="onload" num="149">
++    <function id="AddToBootstrapClassLoaderSearch" jkernel="yes" phase="onload" num="149">
+       <synopsis>Add To Bootstrap Class Loader Search</synopsis>
+       <description>
+           This function can be used to cause instrumentation classes to be defined by the 
+@@ -10468,7 +10469,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="AddToSystemClassLoaderSearch" phase="onload" num="151" since="1.1">
++    <function id="AddToSystemClassLoaderSearch" jkernel="yes" phase="onload" num="151" since="1.1">
+       <synopsis>Add To System Class Loader Search</synopsis>
+       <description>
+ 	  This function can be used to cause instrumentation classes to be
+@@ -10685,7 +10686,7 @@
+     <intro>
+     </intro>
+ 
+-    <function id="GetPhase" phase="any" num="133">
++    <function id="GetPhase" jkernel="yes" phase="any" num="133">
+       <synopsis>Get Phase</synopsis>
+       <description>
+           Return the current phase of VM execution.  
+@@ -10747,7 +10748,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="DisposeEnvironment" phase="any" num="127">
++    <function id="DisposeEnvironment" jkernel="yes" phase="any" num="127">
+       <synopsis>Dispose Environment</synopsis>
+       <description>
+         Shutdown a <jvmti/> connection created with JNI <code>GetEnv</code>
+@@ -10793,7 +10794,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="SetEnvironmentLocalStorage" phase="any" callbacksafe="safe" impl="innative notrace" num="148">
++    <function id="SetEnvironmentLocalStorage" jkernel="yes" phase="any" callbacksafe="safe" impl="innative notrace" num="148">
+       <synopsis>Set Environment Local Storage</synopsis>
+       <description>
+ 	The VM stores a pointer value associated with each environment.
+@@ -10827,7 +10828,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="GetEnvironmentLocalStorage" phase="any" callbacksafe="safe" impl="innative notrace" num="147">
++    <function id="GetEnvironmentLocalStorage" jkernel="yes" phase="any" callbacksafe="safe" impl="innative notrace" num="147">
+       <synopsis>Get Environment Local Storage</synopsis>
+       <description>
+         Called by the agent to get the value of the <jvmti/> environment-local
+@@ -10852,7 +10853,7 @@
+       </errors>
+     </function>
+ 
+-    <function id="GetVersionNumber" phase="any" num="88">
++    <function id="GetVersionNumber" jkernel="yes" phase="any" num="88">
+       <synopsis>Get Version Number</synopsis>
+       <description>
+         Return the <jvmti/> version via <code>version_ptr</code>.
+@@ -13382,7 +13383,7 @@
+   </intro>
+ </issuessection>
+ 
+-<changehistory id="ChangeHistory" update="06/08/06">
++<changehistory id="ChangeHistory" update="09/05/07">
+   <intro>
+     The <jvmti/> specification is an evolving document with major, minor, 
+     and micro version numbers.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/methodComparator.cpp openjdk/hotspot/src/share/vm/prims/methodComparator.cpp
+--- openjdk6/hotspot/src/share/vm/prims/methodComparator.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/methodComparator.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)methodComparator.cpp	1.15 07/05/05 17:06:41 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/methodComparator.hpp openjdk/hotspot/src/share/vm/prims/methodComparator.hpp
+--- openjdk6/hotspot/src/share/vm/prims/methodComparator.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/methodComparator.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)methodComparator.hpp	1.12 07/05/05 17:06:40 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/nativeLookup.cpp openjdk/hotspot/src/share/vm/prims/nativeLookup.cpp
+--- openjdk6/hotspot/src/share/vm/prims/nativeLookup.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/nativeLookup.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)nativeLookup.cpp	1.82 07/05/05 17:06:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/nativeLookup.hpp openjdk/hotspot/src/share/vm/prims/nativeLookup.hpp
+--- openjdk6/hotspot/src/share/vm/prims/nativeLookup.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/nativeLookup.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)nativeLookup.hpp	1.27 07/05/05 17:06:41 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/perf.cpp openjdk/hotspot/src/share/vm/prims/perf.cpp
+--- openjdk6/hotspot/src/share/vm/prims/perf.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/perf.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)perf.cpp	1.15 07/05/05 17:06:34 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -314,4 +311,3 @@
+     guarantee(ok == 0, "register perf natives");
+   }
+ JVM_END
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/privilegedStack.cpp openjdk/hotspot/src/share/vm/prims/privilegedStack.cpp
+--- openjdk6/hotspot/src/share/vm/prims/privilegedStack.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/privilegedStack.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)privilegedStack.cpp	1.31 07/05/05 17:06:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -77,4 +74,3 @@
+ }
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/privilegedStack.hpp openjdk/hotspot/src/share/vm/prims/privilegedStack.hpp
+--- openjdk6/hotspot/src/share/vm/prims/privilegedStack.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/privilegedStack.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)privilegedStack.hpp	1.25 07/05/05 17:06:41 JVM"
+-#endif
+ /*
+  * Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -44,4 +41,3 @@
+   void print_on(outputStream* st) const   PRODUCT_RETURN;
+   bool contains(address addr)             PRODUCT_RETURN0;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/prims/unsafe.cpp openjdk/hotspot/src/share/vm/prims/unsafe.cpp
+--- openjdk6/hotspot/src/share/vm/prims/unsafe.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/prims/unsafe.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)unsafe.cpp	1.64 07/05/17 16:05:09 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/aprofiler.cpp openjdk/hotspot/src/share/vm/runtime/aprofiler.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/aprofiler.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/aprofiler.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)aprofiler.cpp	1.33 07/05/05 17:06:43 JVM"
+-#endif
+ /*
+  * Copyright 1997-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/aprofiler.hpp openjdk/hotspot/src/share/vm/runtime/aprofiler.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/aprofiler.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/aprofiler.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)aprofiler.hpp	1.32 07/05/05 17:06:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/arguments.cpp openjdk/hotspot/src/share/vm/runtime/arguments.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/arguments.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/arguments.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)arguments.cpp	1.333 07/09/25 22:04:01 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -545,7 +542,7 @@
+ static bool append_to_string_flag(char* name, const char* new_value, FlagValueOrigin origin) {
+   const char* old_value = "";
+   if (!CommandLineFlags::ccstrAt(name, &old_value))  return false;
+-  size_t old_len = strlen(old_value);
++  size_t old_len = old_value != NULL ? strlen(old_value) : 0;
+   size_t new_len = strlen(new_value);
+   const char* value;
+   char* free_this_too = NULL;
+@@ -589,14 +586,25 @@
+   char punct;
+   if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "%c", name, &punct) == 2 && punct == '=') {
+     const char* value = strchr(arg, '=') + 1;
+-    // Note that normal -XX:Foo=WWW accumulates.
+-    bool success = append_to_string_flag(name, value, origin);
+-    if (success)  return success;
++    Flag* flag = Flag::find_flag(name, strlen(name));
++    if (flag != NULL && flag->is_ccstr()) {
++      if (flag->ccstr_accumulates()) {
++        return append_to_string_flag(name, value, origin);
++      } else {
++        if (value[0] == '\0') {
++          value = NULL;
++        }
++        return set_string_flag(name, value, origin);
++      }
++    }
+   }
+ 
+   if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE ":%c", name, &punct) == 2 && punct == '=') {
+     const char* value = strchr(arg, '=') + 1;
+     // -XX:Foo:=xxx will reset the string flag to the given value.
++    if (value[0] == '\0') {
++      value = NULL;
++    }
+     return set_string_flag(name, value, origin);
+   }
+ 
+@@ -1253,12 +1261,6 @@
+       FLAG_SET_DEFAULT(CacheTimeMillis, true);
+     }
+ )
+-#ifdef COMPILER2
+-    if (FLAG_IS_DEFAULT(UseSuperWord)) {
+-      // Generate SIMD instructions
+-      FLAG_SET_DEFAULT(UseSuperWord, true);
+-    }
+-#endif /* COMPILER2 */
+   }
+ }
+ 
+@@ -1678,6 +1680,11 @@
+           size_t len2 = strlen(pos+1) + 1; // options start after ':'.  Final zero must be copied.
+           options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2), pos+1, len2);
+         }
++#ifdef JVMTI_KERNEL
++        if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
++          warning("profiling and debugging agents are not supported with Kernel VM");
++        } else
++#endif // JVMTI_KERNEL
+         add_init_library(name, options);
+       }
+     // -agentlib and -agentpath
+@@ -1693,7 +1700,13 @@
+         if(pos != NULL) {
+           options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(pos + 1) + 1), pos + 1);
+         }
++#ifdef JVMTI_KERNEL
++        if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
++          warning("profiling and debugging agents are not supported with Kernel VM");
++        } else
++#endif // JVMTI_KERNEL
+         add_init_agent(name, options, is_absolute_path);
++
+       }
+     // -javaagent
+     } else if (match_option(option, "-javaagent:", &tail)) {
+@@ -1831,7 +1844,12 @@
+ 	  // EVM option, ignore silently for compatibility
+     // -Xprof
+     } else if (match_option(option, "-Xprof", &tail)) {
++#ifndef FPROF_KERNEL
+       _has_profile = true;
++#else // FPROF_KERNEL
++      // do we have to exit?
++      warning("Kernel VM does not support flat profiling.");
++#endif // FPROF_KERNEL
+     // -Xaprof
+     } else if (match_option(option, "-Xaprof", &tail)) {
+       _has_alloc_profile = true;
+@@ -1882,6 +1900,9 @@
+ #elif defined(COMPILER2)
+       vm_exit_during_initialization(
+           "Dumping a shared archive is not supported on the Server JVM.", NULL);
++#elif defined(KERNEL)
++      vm_exit_during_initialization(
++          "Dumping a shared archive is not supported on the Kernel JVM.", NULL);
+ #else
+       FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true);
+       set_mode_flags(_int);	// Prevent compilation, which creates objects
+@@ -2210,6 +2231,9 @@
+     // not specified.
+     set_mode_flags(_int);
+   }
++  if (CompileThreshold == 0) {
++    set_mode_flags(_int);
++  }
+ 
+ #ifdef TIERED
+   // If we are using tiered compilation in the tiered vm then c1 will
+@@ -2423,6 +2447,9 @@
+ #ifdef SERIALGC
+   set_serial_gc_flags();
+ #endif // SERIALGC
++#ifdef KERNEL
++  no_shared_spaces();
++#endif // KERNEL
+   
+   // Set some flags for ParallelGC if needed.
+   set_parallel_gc_flags();
+@@ -2443,10 +2470,10 @@
+   // Set flags if Aggressive optimization flags (-XX:+AggressiveOpts) enabled.
+   set_aggressive_opts_flags();
+ 
+-#ifdef IA64
+-  // Biased locking is not implemented on IA64
++#ifdef CC_INTERP
++  // Biased locking is not implemented with c++ interpreter
+   FLAG_SET_DEFAULT(UseBiasedLocking, false);
+-#endif /* IA64 */
++#endif /* CC_INTERP */
+ 
+   if (PrintCommandLineFlags) {
+     CommandLineFlags::printSetFlags();
+@@ -2542,6 +2569,36 @@
+   PropertyList_add(plist, k, v);
+ }
+ 
++#ifdef KERNEL
++char *Arguments::get_kernel_properties() {
++  // Find properties starting with kernel and append them to string
++  // We need to find out how long they are first because the URL's that they
++  // might point to could get long.
++  int length = 0;
++  SystemProperty* prop;
++  for (prop = _system_properties; prop != NULL; prop = prop->next()) {
++    if (strncmp(prop->key(), "kernel.", 7 ) == 0) {
++      length += (strlen(prop->key()) + strlen(prop->value()) + 5);  // "-D ="
++    }
++  }
++  // Add one for null terminator.
++  char *props = AllocateHeap(length + 1, "get_kernel_properties");
++  if (length != 0) {
++    int pos = 0;
++    for (prop = _system_properties; prop != NULL; prop = prop->next()) {
++      if (strncmp(prop->key(), "kernel.", 7 ) == 0) {
++        jio_snprintf(&props[pos], length-pos,
++                     "-D%s=%s ", prop->key(), prop->value());
++        pos = strlen(props);
++      }
++    }
++  }
++  // null terminate props in case of null
++  props[length] = '\0';
++  return props;
++}
++#endif // KERNEL
++
+ // Copies src into buf, replacing "%%" with "%" and "%p" with pid
+ // Returns true if all of the source pointed by src has been copied over to
+ // the destination buffer pointed by buf. Otherwise, returns false.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/arguments.hpp openjdk/hotspot/src/share/vm/runtime/arguments.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/arguments.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/arguments.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)arguments.hpp	1.103 07/06/27 11:12:35 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -506,4 +503,9 @@
+ 
+   // Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid.
+   static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen);
++
++#ifdef KERNEL
++  // For java kernel vm, return property string for kernel properties.
++  static char *get_kernel_properties();
++#endif // KERNEL
+ };
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/atomic.cpp openjdk/hotspot/src/share/vm/runtime/atomic.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/atomic.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/atomic.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)atomic.cpp	1.14 07/05/05 17:06:42 JVM"
+-#endif
+ /*
+  * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/atomic.hpp openjdk/hotspot/src/share/vm/runtime/atomic.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/atomic.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/atomic.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)atomic.hpp	1.22 07/05/05 17:06:42 JVM"
+-#endif
+ /*
+  * Copyright 1999-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/biasedLocking.cpp openjdk/hotspot/src/share/vm/runtime/biasedLocking.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/biasedLocking.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/biasedLocking.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)biasedLocking.cpp	1.15 07/05/23 10:53:58 JVM"
+-#endif
+ 
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/biasedLocking.hpp openjdk/hotspot/src/share/vm/runtime/biasedLocking.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/biasedLocking.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/biasedLocking.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)biasedLocking.hpp	1.11 07/05/17 16:05:21 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/compilationPolicy.cpp openjdk/hotspot/src/share/vm/runtime/compilationPolicy.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/compilationPolicy.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/compilationPolicy.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)compilationPolicy.cpp	1.45 07/05/05 17:06:45 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -449,4 +446,3 @@
+ 
+ 
+ #endif // COMPILER2
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/compilationPolicy.hpp openjdk/hotspot/src/share/vm/runtime/compilationPolicy.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/compilationPolicy.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/compilationPolicy.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)compilationPolicy.hpp	1.15 07/05/05 17:06:44 JVM"
+-#endif
+ /*
+  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/deoptimization.cpp openjdk/hotspot/src/share/vm/runtime/deoptimization.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/deoptimization.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/deoptimization.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)deoptimization.cpp	1.282 07/05/17 16:05:24 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -89,12 +86,15 @@
+ }
+ 
+ 
+-JRT_LEAF(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(JavaThread* thread))
++// In order to make fetch_unroll_info work properly with escape
++// analysis, The method was changed from JRT_LEAF to JRT_BLOCK_ENTRY and
++// ResetNoHandleMark and HandleMark were removed from it. The actual reallocation
++// of previously eliminated objects occurs in realloc_objects, which is
++// called from the method fetch_unroll_info_helper below.
++JRT_BLOCK_ENTRY(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(JavaThread* thread))
+   // It is actually ok to allocate handles in a leaf method. It causes no safepoints,
+   // but makes the entry a little slower. There is however a little dance we have to
+   // do in debug mode to get around the NoHandleMark code in the JRT_LEAF macro
+-  ResetNoHandleMark rnhm; // No-op in release/product versions  
+-  HandleMark hm;
+ 
+   // fetch_unroll_info() is called at the beginning of the deoptimization
+   // handler. Note this fact before we start generating temporary frames
+@@ -125,13 +125,68 @@
+   // Now get the deoptee with a valid map
+   frame deoptee = stub_frame.sender(&map);
+ 
+-  // We are safepoint safe up to this call
+-  vframeArray* array = create_vframeArray(thread, deoptee, &map);
++  // Create a growable array of VFrames where each VFrame represents an inlined
++  // Java frame.  This storage is allocated with the usual system arena.
++  assert(deoptee.is_compiled_frame(), "Wrong frame type");
++  GrowableArray<compiledVFrame*>* chunk = new GrowableArray<compiledVFrame*>(10);
++  vframe* vf = vframe::new_vframe(&deoptee, &map, thread);
++  while (!vf->is_top()) {
++    assert(vf->is_compiled_frame(), "Wrong frame type");
++    chunk->push(compiledVFrame::cast(vf));
++    vf = vf->sender();
++  }
++  assert(vf->is_compiled_frame(), "Wrong frame type");
++  chunk->push(compiledVFrame::cast(vf));
+ 
+-  // We are no longer safepoint safe. If a safepoint occurs from here on
++#ifdef COMPILER2
++  // Reallocate the non-escaping objects and restore their fields. Then
++  // relock objects if synchronization on them was eliminated.
++  if (DoEscapeAnalysis && EliminateAllocations) {
++    GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
++    bool reallocated = false;
++    if (objects != NULL) {
++      JRT_BLOCK
++        reallocated = realloc_objects(thread, &deoptee, objects, THREAD);
++      JRT_END
++    }
++    if (reallocated) {
++      reassign_fields(&deoptee, &map, objects);
++#ifndef PRODUCT
++      if (TraceDeoptimization) {
++        ttyLocker ttyl;
++        tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread);
++        print_objects(objects);
++      }
++#endif
++    }
++    for (int i = 0; i < chunk->length(); i++) {
++      GrowableArray<MonitorValue*>* monitors = chunk->at(i)->scope()->monitors();
++      if (monitors != NULL) {
++        relock_objects(&deoptee, &map, monitors);
++#ifndef PRODUCT
++        if (TraceDeoptimization) {
++          ttyLocker ttyl;
++          tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread);
++          for (int j = 0; i < monitors->length(); i++) {
++            MonitorValue* mv = monitors->at(i);
++            if (mv->eliminated()) {
++              StackValue* owner = StackValue::create_stack_value(&deoptee, &map, mv->owner());
++              tty->print_cr("     object <" INTPTR_FORMAT "> locked", owner->get_obj()());
++            }
++          }
++        }
++#endif
++      }
++    }
++  }
++#endif // COMPILER2
++  // Ensure that no safepoint is taken after pointers have been stored
++  // in fields of rematerialized objects.  If a safepoint occurs from here on
+   // out the java state residing in the vframeArray will be missed.
+   No_Safepoint_Verifier no_safepoint;
+ 
++  vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk);
++
+   assert(thread->vframe_array_head() == NULL, "Pending deopt!");;
+   thread->set_vframe_array_head(array);
+ 
+@@ -194,7 +249,7 @@
+   int popframe_extra_args = 0;
+   // Create an interpreter return address for the stub to use as its return
+   // address so the skeletal frames are perfectly walkable
+-  frame_pcs[number_of_frames] = AbstractInterpreter::deopt_entry(vtos, 0);
++  frame_pcs[number_of_frames] = Interpreter::deopt_entry(vtos, 0);
+ 
+   // PopFrame requires that the preserved incoming arguments from the recently-popped topmost
+   // activation be put back on the expression stack of the caller for reexecution
+@@ -228,7 +283,7 @@
+     // as interpreted so the skeleton frame will be walkable
+     // The correct pc will be set when the skeleton frame is completely filled out
+     // The final pc we store in the loop is wrong and will be overwritten below
+-    frame_pcs[number_of_frames - 1 - index ] = AbstractInterpreter::deopt_entry(vtos, 0) - frame::pc_return_offset;
++    frame_pcs[number_of_frames - 1 - index ] = Interpreter::deopt_entry(vtos, 0) - frame::pc_return_offset;
+ 
+     callee_parameters = array->element(index)->method()->size_of_parameters();
+     callee_locals = array->element(index)->method()->max_locals();
+@@ -543,21 +598,206 @@
+   return 0;
+ }
+ 
+-vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map) {
+-  // Create a growable array of VFrames where each VFrame represents an inlined
+-  // Java frame.  This storage is allocated with the usual system arena.
+-#ifdef ASSERT
+-  assert(fr.is_compiled_frame(), "Wrong frame type");
+-#endif /* ASSERT */
+-  GrowableArray<compiledVFrame*>* chunk = new GrowableArray<compiledVFrame*>(10);  
+-  vframe* vf = vframe::new_vframe(&fr, reg_map, thread);        
+-  while (!vf->is_top()) {
+-    assert(vf->is_compiled_frame(), "Wrong frame type");
+-    chunk->push(compiledVFrame::cast(vf));
+-    vf = vf->sender();
++
++#ifdef COMPILER2
++bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) {
++  Handle pending_exception(thread->pending_exception());
++  const char* exception_file = thread->exception_file();
++  int exception_line = thread->exception_line();
++  thread->clear_pending_exception();
++
++  for (int i = 0; i < objects->length(); i++) {
++    assert(objects->at(i)->is_object(), "invalid debug information");
++    ObjectValue* sv = (ObjectValue*) objects->at(i);
++
++    KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()());
++    oop obj = NULL;
++
++    if (k->oop_is_instance()) {
++      instanceKlass* ik = instanceKlass::cast(k());
++      obj = ik->allocate_instance(CHECK_(false));
++    } else if (k->oop_is_typeArray()) {
++      typeArrayKlass* ak = typeArrayKlass::cast(k());
++      assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length");
++      int len = sv->field_size() / type2size[ak->element_type()];
++      obj = ak->allocate(len, CHECK_(false));
++    } else if (k->oop_is_objArray()) {
++      objArrayKlass* ak = objArrayKlass::cast(k());
++      obj = ak->allocate(sv->field_size(), CHECK_(false));
++    }
++
++    assert(obj != NULL, "allocation failed");
++    assert(sv->value().is_null(), "redundant reallocation");
++    sv->set_value(obj);
++  }
++
++  if (pending_exception.not_null()) {
++    thread->set_pending_exception(pending_exception(), exception_file, exception_line);
++  }
++
++  return true;
++}
++
++// This assumes that the fields are stored in ObjectValue in the same order
++// they are yielded by do_nonstatic_fields.
++class FieldReassigner: public FieldClosure {
++  frame* _fr;
++  RegisterMap* _reg_map;
++  ObjectValue* _sv;
++  instanceKlass* _ik;
++  oop _obj;
++
++  int _i;
++public:
++  FieldReassigner(frame* fr, RegisterMap* reg_map, ObjectValue* sv, oop obj) :
++    _fr(fr), _reg_map(reg_map), _sv(sv), _obj(obj), _i(0) {}
++
++  int i() const { return _i; }
++
++
++  void do_field(fieldDescriptor* fd) {
++    StackValue* value =
++      StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(i()));
++    int offset = fd->offset();
++    switch (fd->field_type()) {
++    case T_OBJECT: case T_ARRAY:
++      assert(value->type() == T_OBJECT, "Agreement.");
++      _obj->obj_field_put(offset, value->get_obj()());
++      break;
++
++    case T_LONG: case T_DOUBLE: {
++      assert(value->type() == T_INT, "Agreement.");
++      StackValue* low =
++        StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(++_i));
++      jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int());
++      _obj->long_field_put(offset, res);
++      break;
+   }
+-  assert(vf->is_compiled_frame(), "Wrong frame type");
+-  chunk->push(compiledVFrame::cast(vf));
++
++    case T_INT: case T_FLOAT: // 4 bytes.
++      assert(value->type() == T_INT, "Agreement.");
++      _obj->int_field_put(offset, (jint)value->get_int());
++      break;
++
++    case T_SHORT: case T_CHAR: // 2 bytes
++      assert(value->type() == T_INT, "Agreement.");
++      _obj->short_field_put(offset, (jshort)value->get_int());
++      break;
++
++    case T_BOOLEAN: // 1 byte
++      assert(value->type() == T_INT, "Agreement.");
++      _obj->bool_field_put(offset, (jboolean)value->get_int());
++      break;
++
++    default:
++      ShouldNotReachHere();
++    }
++    _i++;
++  }
++};
++
++// restore elements of an eliminated type array
++void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) {
++  StackValue* low;
++  jlong lval;
++  int index = 0;
++
++  for (int i = 0; i < sv->field_size(); i++) {
++    StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i));
++    switch(type) {
++      case T_BOOLEAN: obj->bool_at_put (index, (jboolean) value->get_int()); break;
++      case T_BYTE:    obj->byte_at_put (index, (jbyte)    value->get_int()); break;
++      case T_CHAR:    obj->char_at_put (index, (jchar)    value->get_int()); break;
++      case T_SHORT:   obj->short_at_put(index, (jshort)   value->get_int()); break;
++      case T_INT:     obj->int_at_put  (index, (jint)     value->get_int()); break;
++      case T_FLOAT:   obj->float_at_put(index, (jfloat)   value->get_int()); break;
++      case T_LONG:
++      case T_DOUBLE:
++        low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++i));
++        lval = jlong_from((jint)value->get_int(), (jint)low->get_int());
++        sv->value()->long_field_put(index, lval);
++        break;
++      default:
++        ShouldNotReachHere();
++    }
++    index++;
++  }
++}
++
++
++// restore fields of an eliminated object array
++void Deoptimization::reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj) {
++  for (int i = 0; i < sv->field_size(); i++) {
++    StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i));
++    assert(value->type() == T_OBJECT, "object element expected");
++    obj->obj_at_put(i, value->get_obj()());
++  }
++}
++
++
++// restore fields of all eliminated objects and arrays
++void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects) {
++  for (int i = 0; i < objects->length(); i++) {
++    ObjectValue* sv = (ObjectValue*) objects->at(i);
++    KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()());
++    Handle obj = sv->value();
++    assert(obj.not_null(), "reallocation was missed");
++
++    if (k->oop_is_instance()) {
++      instanceKlass* ik = instanceKlass::cast(k());
++      FieldReassigner reassign(fr, reg_map, sv, obj());
++      ik->do_nonstatic_fields(&reassign);
++    } else if (k->oop_is_typeArray()) {
++      typeArrayKlass* ak = typeArrayKlass::cast(k());
++      reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type());
++    } else if (k->oop_is_objArray()) {
++      reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj());
++    }
++  }
++}
++
++
++// relock objects for which synchronization was eliminated
++void Deoptimization::relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray<MonitorValue*>* monitors) {
++  for (int i = 0; i < monitors->length(); i++) {
++    MonitorValue* mv = monitors->at(i);
++    StackValue* owner = StackValue::create_stack_value(fr, reg_map, mv->owner());
++    if (mv->eliminated()) {
++      Handle obj = owner->get_obj();
++      assert(obj.not_null(), "reallocation was missed");
++      BasicLock* lock = StackValue::resolve_monitor_lock(fr, mv->basic_lock());
++      lock->set_displaced_header(obj->mark());
++      obj->set_mark((markOop) lock);
++    }
++    assert(owner->get_obj()->is_locked(), "object must be locked now");
++  }
++}
++
++
++#ifndef PRODUCT
++// print information about reallocated objects
++void Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects) {
++  fieldDescriptor fd;
++
++  for (int i = 0; i < objects->length(); i++) {
++    ObjectValue* sv = (ObjectValue*) objects->at(i);
++    KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()());
++    Handle obj = sv->value();
++
++    tty->print("     object <" INTPTR_FORMAT "> of type ", sv->value()());
++    k->as_klassOop()->print_value();
++    tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize);
++    tty->cr();
++
++    if (Verbose) {
++      k->oop_print_on(obj(), tty);
++    }
++  }
++}
++#endif
++#endif // COMPILER2
++
++vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk) {
+ 
+ #ifndef PRODUCT
+   if (TraceDeoptimization) {
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/deoptimization.hpp openjdk/hotspot/src/share/vm/runtime/deoptimization.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/deoptimization.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/deoptimization.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)deoptimization.hpp	1.91 07/05/05 17:06:46 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -27,6 +24,8 @@
+ 
+ class ProfileData;
+ class vframeArray;
++class MonitorValue;
++class ObjectValue;
+ 
+ class Deoptimization : AllStatic {
+  public:
+@@ -100,8 +99,18 @@
+   // executing in a particular CodeBlob if UseBiasedLocking is enabled
+   static void revoke_biases_of_monitors(CodeBlob* cb);
+ 
++#ifdef COMPILER2
++  // Support for restoring non-escaping objects
++  static bool realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS);
++  static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type);
++  static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj);
++  static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects);
++  static void relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray<MonitorValue*>* monitors);
++  NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects);)
++#endif // COMPILER2
++
+   public:
+-  static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map);
++  static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk);
+  
+   // Interface used for unpacking deoptimized frames 
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/extendedPC.hpp openjdk/hotspot/src/share/vm/runtime/extendedPC.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/extendedPC.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/extendedPC.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)extendedPC.hpp	1.17 07/05/05 17:06:46 JVM"
+-#endif
+ /*
+  * Copyright 1998-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fieldDescriptor.cpp openjdk/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/fieldDescriptor.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/fieldDescriptor.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)fieldDescriptor.cpp	1.56 07/05/05 17:06:46 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fieldDescriptor.hpp openjdk/hotspot/src/share/vm/runtime/fieldDescriptor.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/fieldDescriptor.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/fieldDescriptor.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)fieldDescriptor.hpp	1.46 07/05/05 17:06:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fieldType.cpp openjdk/hotspot/src/share/vm/runtime/fieldType.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/fieldType.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/fieldType.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)fieldType.cpp	1.27 07/05/05 17:06:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -93,4 +90,3 @@
+   *dimension = dim;
+   return element_type;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fieldType.hpp openjdk/hotspot/src/share/vm/runtime/fieldType.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/fieldType.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/fieldType.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)fieldType.hpp	1.28 07/05/05 17:06:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -53,4 +50,3 @@
+   // Parse field and extract array information. Works for T_ARRAY only.  
+   static BasicType get_array_info(symbolOop signature, jint* dimension, symbolOop *object_key, TRAPS);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fprofiler.cpp openjdk/hotspot/src/share/vm/runtime/fprofiler.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/fprofiler.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/fprofiler.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)fprofiler.cpp	1.136 07/05/05 17:06:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -927,16 +924,6 @@
+   FlatProfiler::record_thread_ticks();
+ }
+ 
+-inline bool is_valid_method(methodOop method) {
+-  if (method == NULL || 
+-      !method->is_perm() || 
+-      oop(method)->klass() != Universe::methodKlassObj() ||
+-      !method->is_method()) {
+-    return false;   // doesn't look good
+-  }
+-  return true;      // hopefully this is a method indeed
+-}
+-
+ void ThreadProfiler::record_interpreted_tick(frame fr, TickPosition where, int* ticks) {
+   FlatProfiler::all_int_ticks++;
+   if (!FlatProfiler::full_profile()) {
+@@ -954,7 +941,7 @@
+   if (fr.fp() != NULL) {
+     method = *fr.interpreter_frame_method_addr();
+   }
+-  if (!is_valid_method(method)) {
++  if (!Universe::heap()->is_valid_method(method)) {
+     // tick came at a bad time, stack frame not initialized correctly
+     interpreter_ticks += 1;
+     FlatProfiler::interpreter_ticks += 1;
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fprofiler.hpp openjdk/hotspot/src/share/vm/runtime/fprofiler.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/fprofiler.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/fprofiler.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)fprofiler.hpp	1.54 07/05/05 17:06:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -27,6 +24,7 @@
+ 
+ // a simple flat profiler for Java
+ 
++
+ // Forward declaration of classes defined in this header file
+ class ThreadProfiler;
+ class ThreadProfilerMark;
+@@ -50,14 +48,16 @@
+   // For now, the only thread-specific region is the class loader.
+   enum Region { noRegion, classLoaderRegion, extraRegion, maxRegion };
+ 
+-  ThreadProfilerMark(Region);
+-  ~ThreadProfilerMark();
++  ThreadProfilerMark(Region)  KERNEL_RETURN;
++  ~ThreadProfilerMark()       KERNEL_RETURN;
+ 
+ private:
+   ThreadProfiler* _pp;
+   Region _r;
+ };
+ 
++#ifndef FPROF_KERNEL
++
+ class IntervalData VALUE_OBJ_CLASS_SPEC {
+   // Just to keep these things all together
+ private:
+@@ -102,27 +102,29 @@
+   static void print_header(outputStream* st);
+   void print_data(outputStream* st);
+ };
++#endif // FPROF_KERNEL
+ 
+ class ThreadProfiler: public CHeapObj {
+ public:
+-  ThreadProfiler();
+-  ~ThreadProfiler();
++  ThreadProfiler()    KERNEL_RETURN;
++  ~ThreadProfiler()   KERNEL_RETURN;
+ 
+   // Resets the profiler
+-  void reset();
++  void reset()        KERNEL_RETURN;
+ 
+   // Activates the profiler for a certain thread
+-  void engage();
++  void engage()       KERNEL_RETURN;
+ 
+   // Deactivates the profiler
+-  void disengage();
++  void disengage()    KERNEL_RETURN;
+ 
+   // Prints the collected profiling information
+-  void print(const char* thread_name);
++  void print(const char* thread_name) KERNEL_RETURN;
+ 
+   // Garbage Collection Support
+-  void oops_do(OopClosure* f);
++  void oops_do(OopClosure* f)         KERNEL_RETURN;
+ 
++#ifndef FPROF_KERNEL
+ private:
+   // for recording ticks.
+   friend class ProfilerNode;
+@@ -206,26 +208,45 @@
+   IntervalData* interval_data_ref() {
+     return &_interval_data;
+   }
++#endif // FPROF_KERNEL
+ };
+ 
+ class FlatProfiler: AllStatic {
+ public:
+-  static void reset();
+-  static void engage(JavaThread* mainThread, bool fullProfile);
+-  static void disengage();
+-  static void print(int unused);
+-  static bool is_active();
+-  static bool full_profile() {
+-    return full_profile_flag;
+-  }
++  static void reset() KERNEL_RETURN ;
++  static void engage(JavaThread* mainThread, bool fullProfile) KERNEL_RETURN ;
++  static void disengage() KERNEL_RETURN ;
++  static void print(int unused) KERNEL_RETURN ;
++  static bool is_active() KERNEL_RETURN_(return false;) ;
+ 
+   // This is NULL if each thread has its own thread profiler,
+   // else this is the single thread profiler used by all threads.
+   // In particular it makes a difference during garbage collection,
+   // where you only want to traverse each thread profiler once.
+-  static ThreadProfiler* get_thread_profiler();
++  static ThreadProfiler* get_thread_profiler() KERNEL_RETURN_(return NULL;);
++
++  // Garbage Collection Support
++  static void oops_do(OopClosure* f) KERNEL_RETURN ;
++
++  // Support for disassembler to inspect the PCRecorder
++
++  // Returns the start address for a given pc
++  // NULL is returned if the PCRecorder is inactive
++  static address bucket_start_for(address pc) KERNEL_RETURN_(return NULL;);
++
++  enum { MillisecsPerTick = 10 };   // ms per profiling ticks
++
++  // Returns the number of ticks recorded for the bucket
++  // pc belongs to.
++  static int bucket_count_for(address pc) KERNEL_RETURN_(return 0;);
++
++#ifndef FPROF_KERNEL
+ 
+  private:
++  static bool full_profile() {
++    return full_profile_flag;
++  }
++
+   friend class ThreadProfiler;
+   // the following group of ticks cover everything that's not attributed to individual Java methods
+   static int  received_gc_ticks;      // ticks during which gc was active
+@@ -278,24 +299,6 @@
+   static void record_vm_tick();
+   static void record_thread_ticks();
+ 
+- public:
+-  enum { MillisecsPerTick = 10 };   // ms per profiling ticks
+-
+-  // Garbage Collection Support
+- public:
+-   static void oops_do(OopClosure* f);
+-
+- public:
+-  // Support for disassembler to inspect the PCRecorder
+-
+-  // Returns the start address for a given pc
+-  // NULL is returned if the PCRecorder is inactive
+-  static address bucket_start_for(address pc);
+-
+-  // Returns the number of ticks recorded for the bucket
+-  // pc belongs to.
+-  static int bucket_count_for(address pc);
+-
+   // For interval analysis
+  private:
+   static int interval_ticks_previous;  // delivered_ticks from the last interval
+@@ -304,6 +307,5 @@
+   static void interval_reset();       // reset interval data.
+   enum {interval_print_size = 10};
+   static IntervalData* interval_data;
++#endif // FPROF_KERNEL
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/frame.cpp openjdk/hotspot/src/share/vm/runtime/frame.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/frame.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/frame.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)frame.cpp	1.233 07/05/05 17:06:44 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -524,7 +521,7 @@
+   NOT_PRODUCT(address begin = pc()-40;)
+   NOT_PRODUCT(address end   = NULL;)
+ 
+-  st->print("%s frame (sp=" INTPTR_FORMAT, print_name(), sp());
++  st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp());
+   if (sp() != NULL)
+     st->print(", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), pc());
+ 
+@@ -676,7 +673,23 @@
+ 
+ void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose) const {
+   if (_cb != NULL) {
+-    if (_cb->is_buffer_blob()) {
++    if (Interpreter::contains(pc())) {
++      methodOop m = this->interpreter_frame_method();
++      if (m != NULL) {
++        m->name_and_sig_as_C_string(buf, buflen);
++        st->print("j  %s", buf);
++        st->print("+%d", this->interpreter_frame_bci());
++      } else {
++        st->print("j  " PTR_FORMAT, pc());
++      }
++    } else if (StubRoutines::contains(pc())) {
++      StubCodeDesc* desc = StubCodeDesc::desc_for(pc());
++      if (desc != NULL) {
++        st->print("v  ~StubRoutines::%s", desc->name());
++      } else {
++        st->print("v  ~StubRoutines::" PTR_FORMAT, pc());
++      }
++    } else if (_cb->is_buffer_blob()) {
+       st->print("v  ~BufferBlob::%s", ((BufferBlob *)_cb)->name());
+     } else if (_cb->is_nmethod()) {
+       methodOop m = ((nmethod *)_cb)->method();
+@@ -697,24 +710,6 @@
+     } else {
+       st->print("v  blob " PTR_FORMAT, pc());
+     }
+-  } else if (!is_init_completed()) {
+-    print_C_frame(st, buf, buflen, pc());
+-  } else if (Interpreter::contains(pc())) {
+-    methodOop m = this->interpreter_frame_method();
+-    if (m != NULL) {
+-      m->name_and_sig_as_C_string(buf, buflen);
+-      st->print("j  %s", buf);
+-      st->print("+%d", this->interpreter_frame_bci());
+-    } else {
+-      st->print("j  " PTR_FORMAT, pc());
+-    }
+-  } else if (StubRoutines::contains(pc())) {
+-    StubCodeDesc* desc = StubCodeDesc::desc_for(pc());
+-    if (desc != NULL) {
+-      st->print("v  ~StubRoutines::%s", desc->name());
+-    } else {
+-      st->print("v  ~StubRoutines::" PTR_FORMAT, pc());
+-    }
+   } else {
+     print_C_frame(st, buf, buflen, pc());
+   }
+@@ -900,7 +895,7 @@
+   // Interpreter frame in the midst of a call have a methodOop within the
+   // object. 
+   interpreterState istate = get_interpreterState();
+-  if (istate->msg() == cInterpreter::call_method) {
++  if (istate->msg() == BytecodeInterpreter::call_method) {
+     f->do_oop((oop*)&istate->_result._to_call._callee);
+   }
+ 
+@@ -1411,4 +1406,3 @@
+   _fr = thread->last_frame(); 
+   _is_done = false;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/frame.hpp openjdk/hotspot/src/share/vm/runtime/frame.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/frame.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/frame.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)frame.hpp	1.163 07/05/05 17:06:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -25,9 +22,7 @@
+  *  
+  */
+ 
+-#ifdef CC_INTERP
+-typedef class cInterpreter* interpreterState;
+-#endif /* CC_INTERP */
++typedef class BytecodeInterpreter* interpreterState;
+ 
+ class CodeBlob;
+ 
+@@ -41,9 +36,7 @@
+ class frame VALUE_OBJ_CLASS_SPEC {
+  private:
+   // Instance variables:
+-#ifndef CC_INTERP
+   intptr_t* _sp; // stack pointer (from Thread::last_Java_sp)
+-#endif // !CC_INTERP
+   address   _pc; // program counter (the next instruction after the call)
+ 
+   CodeBlob* _cb; // CodeBlob that "owns" pc
+@@ -73,10 +66,9 @@
+   address raw_pc() const;
+ 
+   void set_pc( address   newpc );
+-#ifndef CC_INTERP
+-  void set_sp( intptr_t* newsp ) { _sp = newsp; }
++
+   intptr_t* sp() const           { return _sp; }
+-#endif // !CC_INTERP
++  void set_sp( intptr_t* newsp ) { _sp = newsp; }
+ 
+ 
+   CodeBlob* cb() const           { return _cb; }
+@@ -279,7 +271,12 @@
+   jint  interpreter_frame_expression_stack_size() const;
+ 
+   intptr_t* interpreter_frame_sender_sp() const;
++
++#ifndef CC_INTERP
++  // template based interpreter deoptimization support
+   void  set_interpreter_frame_sender_sp(intptr_t* sender_sp);
++  void interpreter_frame_set_monitor_end(BasicObjectLock* value);
++#endif // CC_INTERP
+ 
+   // BasicObjectLocks:
+   //
+@@ -296,7 +293,6 @@
+   BasicObjectLock* previous_monitor_in_interpreter_frame(BasicObjectLock* current) const;
+   static int interpreter_frame_monitor_size();
+ 
+-  void interpreter_frame_set_monitor_end(BasicObjectLock* value);
+   void interpreter_frame_verify_monitor(BasicObjectLock* value) const;
+ 
+   // Tells whether the current interpreter_frame frame pointer
+@@ -471,4 +467,3 @@
+   frame *current()                { return &_fr; }
+   RegisterMap* register_map()     { return &_reg_map; }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/frame.inline.hpp openjdk/hotspot/src/share/vm/runtime/frame.inline.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/frame.inline.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/frame.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)frame.inline.hpp	1.23 07/05/05 17:06:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/globals.cpp openjdk/hotspot/src/share/vm/runtime/globals.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/globals.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/globals.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)globals.cpp	1.49 07/05/17 16:05:26 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -337,7 +334,7 @@
+   char* new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1);
+   strcpy(new_value, *value);
+   result->set_ccstr(new_value);
+-  if (result->origin == DEFAULT) {
++  if (result->origin == DEFAULT && old_value != NULL) {
+     // Prior value is NOT heap allocated, but was a literal constant.
+     char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1);
+     strcpy(old_value_to_free, old_value);
+@@ -356,7 +353,7 @@
+   char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1);
+   strcpy(new_value, value);
+   faddr->set_ccstr(new_value);
+-  if (faddr->origin != DEFAULT) {
++  if (faddr->origin != DEFAULT && old_value != NULL) {
+     // Prior value is heap allocated so free it.
+     FREE_C_HEAP_ARRAY(char, old_value);
+   }
+@@ -430,4 +427,3 @@
+ }
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/globals_extension.hpp openjdk/hotspot/src/share/vm/runtime/globals_extension.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/globals_extension.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/globals_extension.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)globals_extension.hpp	1.17 07/05/17 16:05:46 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/globals.hpp openjdk/hotspot/src/share/vm/runtime/globals.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/globals.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/globals.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)globals.hpp	1.967 07/07/13 14:51:27 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -61,6 +58,7 @@
+ define_pd_global(uintx,PermSize,    ScaleForWordSize(4*M));
+ define_pd_global(uintx,MaxPermSize, ScaleForWordSize(64*M));
+ define_pd_global(bool, NeverActAsServerClassMachine, true);
++define_pd_global(uintx, DefaultMaxRAM,               1*G);
+ #define CI_COMPILER_COUNT 0
+ #else
+ 
+@@ -73,7 +71,9 @@
+ #endif // no compilers
+ 
+ 
+-typedef const char* ccstr;  // string type alias used only in this file
++// string type aliases used only in this file
++typedef const char* ccstr;
++typedef const char* ccstrlist;   // represents string arguments which accumulate
+ 
+ enum FlagValueOrigin {
+   DEFAULT          = 0,
+@@ -117,7 +117,8 @@
+   double get_double() const     { return *((double*) addr); }
+   void set_double(double value) { *((double*) addr) = value; }
+ 
+-  bool is_ccstr() const       { return strcmp(type, "ccstr") == 0; }
++  bool is_ccstr() const          { return strcmp(type, "ccstr") == 0 || strcmp(type, "ccstrlist") == 0; }
++  bool ccstr_accumulates() const { return strcmp(type, "ccstrlist") == 0; }
+   ccstr get_ccstr() const     { return *((ccstr*) addr); }
+   void set_ccstr(ccstr value) { *((ccstr*) addr) = value; }
+ 
+@@ -305,6 +306,9 @@
+   product_pd(bool, UseLargePages,                                           \
+           "Use large page memory")                                          \
+                                                                             \
++  develop(bool, TracePageSizes, false,                                      \
++          "Trace page size selection and usage.")                           \
++                                                                            \
+   product(bool, UseNUMA, false,                                             \
+           "Use NUMA if available")                                          \
+                                                                             \
+@@ -389,6 +393,9 @@
+   develop(bool, VerifyStack, false,                                         \
+           "Verify stack of each thread when it is entering a runtime call") \
+                                                                             \
++  develop(bool, ForceUnreachable, false,                                    \
++          "(amd64) Make all non code cache addresses to be unreachable with rip-rel forcing use of 64bit literal fixups") \
++                                                                            \
+   notproduct(bool, StressDerivedPointers, false,                            \
+           "Force scavenge when a derived pointers is detected on stack "    \
+           "after rtm call")                                                 \
+@@ -459,7 +466,7 @@
+   develop(bool, DeoptimizeALot, false,                                      \
+           "deoptimize at every exit from the runtime system")               \
+                                                                             \
+-  develop(ccstr, DeoptimizeOnlyAt, "",                                      \
++  develop(ccstrlist, DeoptimizeOnlyAt, "",                                  \
+           "a comma separated list of bcis to deoptimize at")                \
+                                                                             \
+   product(bool, DeoptimizeRandom, false,                                    \
+@@ -497,7 +504,7 @@
+   develop(bool, ShowSafepointMsgs, false,                                   \
+           "Show msg. about safepoint synch.")                               \
+                                                                             \
+-  develop(bool, SafepointTimeout, false,                                    \
++  product(bool, SafepointTimeout, false,                                    \
+           "Time out and warn or fail after SafepointTimeoutDelay "          \
+           "milliseconds if failed to reach safepoint")                      \
+                                                                             \
+@@ -609,17 +616,17 @@
+   product(bool, SuppressFatalErrorMessage, false,                           \
+           "Do NO Fatal Error report [Avoid deadlock]")                      \
+                                                                             \
+-  product(ccstr, OnError, "",                                               \
++  product(ccstrlist, OnError, "",                                           \
+           "Run user-defined commands on fatal error; see VMError.cpp "      \
+           "for examples")                                                   \
+ 									    \
+-  product(ccstr, OnOutOfMemoryError, "",                                    \
++  product(ccstrlist, OnOutOfMemoryError, "",                                \
+           "Run user-defined commands on first java.lang.OutOfMemoryError")  \
+                                                                             \
+   manageable(bool, HeapDumpOnOutOfMemoryError, false,                       \
+           "Dump heap to file when java.lang.OutOfMemoryError is thrown")    \
+                                                                             \
+-  manageable(ccstr, HeapDumpPath, "",                                       \
++  manageable(ccstr, HeapDumpPath, NULL,                                     \
+           "When HeapDumpOnOutOfMemoryError is on, the path (filename or"    \
+           "directory) of the dump file (defaults to java_pid<pid>.hprof"    \
+           "in the working directory)")                                      \
+@@ -823,8 +830,6 @@
+   product(intx, FenceInstruction, 0,                                        \
+           "(Unsafe,Unstable) Experimental")                                 \
+                                                                             \
+-  product(intx, AppendRatio, 11, "(Unstable) Monitor queue fairness" )      \
+-                                                                            \
+   product(intx, SyncFlags, 0, "(Unsafe,Unstable) Experimental Sync flags" ) \
+                                                                             \
+   product(intx, SyncVerbose, 0, "(Unstable)" )                              \
+@@ -842,6 +847,10 @@
+ 	  "Prevent spurious or premature wakeups from object.wait"          \
+ 	  "(Solaris only)")                                                 \
+                                                                             \
++  product(intx, NativeMonitorTimeout, -1, "(Unstable)" )                    \
++  product(intx, NativeMonitorFlags, 0, "(Unstable)" )                       \
++  product(intx, NativeMonitorSpinLimit, 20, "(Unstable)" )                  \
++                                                                            \
+   develop(bool, UsePthreads, false,                                         \
+           "Use pthread-based instead of libthread-based synchronization "   \
+           "(SPARC only)")                                                   \
+@@ -1063,7 +1072,7 @@
+   develop(bool, TraceHPI, false,                                            \
+           "Trace Host Porting Interface (HPI)")                             \
+                                                                             \
+-  product(ccstr, HPILibPath, "",                                            \
++  product(ccstr, HPILibPath, NULL,                                          \
+           "Specify alternate path to HPI library")                          \
+                                                                             \
+   develop(bool, TraceProtectionDomainVerification, false,                   \
+@@ -1570,7 +1579,7 @@
+   product(bool, AlwaysActAsServerClassMachine, false,                       \
+           "Always act like a server-class machine")                         \
+                                                                             \
+-  product(uintx, DefaultMaxRAM, G,					    \
++  product_pd(uintx, DefaultMaxRAM,                                          \
+ 	  "Maximum real memory size for setting server class heap size")    \
+ 									    \
+   product(uintx, DefaultMaxRAMFraction, 4,				    \
+@@ -2029,7 +2038,7 @@
+   diagnostic(bool, PrintIntrinsics, false,                                  \
+           "prints attempted and successful inlining of intrinsics")         \
+                                                                             \
+-  diagnostic(ccstr, DisableIntrinsic, "",                                   \
++  diagnostic(ccstrlist, DisableIntrinsic, "",                               \
+           "do not expand intrinsics whose (internal) names appear here")    \
+                                                                             \
+   develop(bool, StressReflectiveCode, false,                                \
+@@ -2075,10 +2084,10 @@
+   diagnostic(bool, LogVMOutput, trueInDebug,                                \
+          "Save VM output to hotspot.log, or to LogFile")                    \
+                                                                             \
+-  diagnostic(ccstr, LogFile, "",                                            \
++  diagnostic(ccstr, LogFile, NULL,                                          \
+          "If LogVMOutput is on, save VM output to this file [hotspot.log]") \
+                                                                             \
+-  product(ccstr, ErrorFile, "",                                             \
++  product(ccstr, ErrorFile, NULL,                                           \
+          "If an error occurs, save the error data to this file "            \
+          "[default: ./hs_err_pid%p.log] (%p replaced with pid)")            \
+                                                                             \
+@@ -2098,7 +2107,7 @@
+           "standard exit from VM if bytecode verify error "                 \
+           "(only in debug mode)")                                           \
+                                                                             \
+-  notproduct(ccstr, AbortVMOnException, "",                                 \
++  notproduct(ccstr, AbortVMOnException, NULL,                               \
+           "Call fatal if this exception is thrown.  Example: "              \
+           "java -XX:AbortVMOnException=java.lang.NullPointerException Foo") \
+                                                                             \
+@@ -2205,9 +2214,6 @@
+   develop(bool, CountCompiledCalls, false,                                  \
+           "counts method invocations")                                      \
+                                                                             \
+-  notproduct(bool, CountVMLocks, false,                                     \
+-          "counts VM internal lock attempts and contention")                \
+-                                                                            \
+   notproduct(bool, CountRuntimeCalls, false,                                \
+           "counts VM runtime calls")                                        \
+                                                                             \
+@@ -2425,7 +2431,7 @@
+           "Guarantee a safepoint (at least) every so many milliseconds "    \
+           "(0 means none)")                                                 \
+                                                                             \
+-  develop(intx, SafepointTimeoutDelay, 10000,                               \
++  product(intx, SafepointTimeoutDelay, 10000,                               \
+           "Delay in milliseconds for option SafepointTimeout")              \
+                                                                             \
+   product(intx, NmethodSweepFraction, 4,                                    \
+@@ -2441,7 +2447,7 @@
+           "number of times to evaluate expression in assert "               \
+           "(to estimate overhead); only works with -DUSE_REPEATED_ASSERTS") \
+                                                                             \
+-  notproduct(ccstr, SuppressErrorAt, "",                                    \
++  notproduct(ccstrlist, SuppressErrorAt, "",                                \
+           "List of assertions (file:line) to muzzle")                       \
+                                                                             \
+   notproduct(uintx, HandleAllocationLimit, 1024,                            \
+@@ -2744,6 +2750,9 @@
+           "true: the scavenge order will be depth-first, "                  \
+           "false: the scavenge order will be breadth-first")                \
+                                                                             \
++  product(bool, PSChunkLargeArrays, true,                                   \
++          "true: process large arrays in chunks")                           \
++                                                                            \
+   product(uintx, GCDrainStackTargetSize, 64,                                \
+           "how many entries we'll try to leave on the stack during "        \
+           "parallel GC")                                                    \
+@@ -2834,13 +2843,13 @@
+   develop(intx, CIBreakAt,    -1,                                           \
+           "id of compilation to break at")                                  \
+                                                                             \
+-  product(ccstr, CompileOnly, "",                                           \
++  product(ccstrlist, CompileOnly, "",                                       \
+           "List of methods (pkg/class.name) to restrict compilation to")    \
+                                                                             \
+-  product(ccstr, CompileCommandFile, "",                                    \
++  product(ccstr, CompileCommandFile, NULL,                                  \
+           "Read compiler commands from this file [.hotspot_compiler]")      \
+                                                                             \
+-  product(ccstr, CompileCommand, "",                                        \
++  product(ccstrlist, CompileCommand, "",                                    \
+           "Prepend to .hotspot_compiler; e.g. log,java/lang/String.<init>") \
+                                                                             \
+   product(bool, CICompilerCountPerCPU, false,                               \
+@@ -3033,7 +3042,7 @@
+   product(bool, PerfDataSaveToFile, false,                                  \
+           "Save PerfData memory to hsperfdata_<pid> file on exit")          \
+                                                                             \
+-  product(ccstr, PerfDataSaveFile, "",                                      \
++  product(ccstr, PerfDataSaveFile, NULL,                                    \
+           "Save PerfData memory to the specified absolute pathname,"        \
+            "%p in the file name if present will be replaced by pid")        \
+                                                                             \
+@@ -3134,7 +3143,7 @@
+           "Causes the VM to pause at startup time and wait for the pause "  \
+           "file to be removed (default: ./vm.paused.<pid>)")                \
+                                                                             \
+-  diagnostic(ccstr, PauseAtStartupFile, "",                                 \
++  diagnostic(ccstr, PauseAtStartupFile, NULL,                               \
+           "The file to create and for whose removal to await when pausing " \
+           "at startup. (default: ./vm.paused.<pid>)")                       \
+                                                                             \
+@@ -3197,5 +3206,3 @@
+ RUNTIME_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
+ 
+ RUNTIME_OS_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/handles.cpp openjdk/hotspot/src/share/vm/runtime/handles.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/handles.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/handles.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)handles.cpp	1.110 07/05/05 17:06:42 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/handles.hpp openjdk/hotspot/src/share/vm/runtime/handles.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/handles.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/handles.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)handles.hpp	1.120 07/05/05 17:06:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -349,4 +346,3 @@
+   ~ResetNoHandleMark() {}
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/handles.inline.hpp openjdk/hotspot/src/share/vm/runtime/handles.inline.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/handles.inline.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/handles.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)handles.inline.hpp	1.28 07/05/05 17:06:48 JVM"
+-#endif
+ /*
+  * Copyright 1998-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/hpi.cpp openjdk/hotspot/src/share/vm/runtime/hpi.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/hpi.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/hpi.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)hpi.cpp	1.18 07/05/17 16:05:48 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/hpi.hpp openjdk/hotspot/src/share/vm/runtime/hpi.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/hpi.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/hpi.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)hpi.hpp	1.22 07/05/05 17:06:48 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/icache.cpp openjdk/hotspot/src/share/vm/runtime/icache.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/icache.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/icache.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)icache.cpp	1.23 07/05/05 17:06:49 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/icache.hpp openjdk/hotspot/src/share/vm/runtime/icache.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/icache.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/icache.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)icache.hpp	1.18 07/05/05 17:06:44 JVM"
+-#endif
+ /*
+  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/init.cpp openjdk/hotspot/src/share/vm/runtime/init.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/init.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/init.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)init.cpp	1.122 07/05/23 10:54:05 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -85,6 +82,7 @@
+ 
+ 
+ jint init_globals() {  
++  HandleMark hm;
+   management_init();
+   vtune_init();
+   bytecodes_init();
+@@ -107,7 +105,9 @@
+   universe2_init();  // dependent on codeCache_init and stubRoutines_init
+   referenceProcessor_init();
+   jni_handles_init();
++#ifndef VM_STRUCTS_KERNEL
+   vmStructs_init();
++#endif // VM_STRUCTS_KERNEL
+ 
+   vtableStubs_init();
+   InlineCacheBuffer_init();
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/init.hpp openjdk/hotspot/src/share/vm/runtime/init.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/init.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/init.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)init.hpp	1.19 07/05/05 17:06:49 JVM"
+-#endif
+ /*
+  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/interfaceSupport.cpp openjdk/hotspot/src/share/vm/runtime/interfaceSupport.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/interfaceSupport.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/interfaceSupport.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)interfaceSupport.cpp	1.91 07/05/05 17:06:50 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -270,4 +267,3 @@
+   }
+ #endif
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/interfaceSupport.hpp openjdk/hotspot/src/share/vm/runtime/interfaceSupport.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/interfaceSupport.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/interfaceSupport.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)interfaceSupport.hpp	1.176 07/05/17 16:05:52 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/javaCalls.cpp openjdk/hotspot/src/share/vm/runtime/javaCalls.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/javaCalls.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/javaCalls.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)javaCalls.cpp	1.220 07/05/05 17:06:51 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/javaCalls.hpp openjdk/hotspot/src/share/vm/runtime/javaCalls.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/javaCalls.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/javaCalls.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)javaCalls.hpp	1.81 07/05/05 17:06:47 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -196,4 +193,3 @@
+   // Low-level interface
+   static void call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/java.cpp openjdk/hotspot/src/share/vm/runtime/java.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/java.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/java.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)java.cpp	1.221 07/05/29 09:44:26 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -144,13 +141,6 @@
+     RuntimeHistogram->print();
+   }
+ 
+-  if (CountVMLocks) {
+-    extern Histogram *MutexHistogram;
+-    extern Histogram *MutexContentionHistogram;
+-    MutexHistogram->print();
+-    MutexContentionHistogram->print();
+-  }
+-
+   if (CountJNICalls) {
+     extern Histogram *JNIHistogram;
+     JNIHistogram->print();
+@@ -438,6 +428,7 @@
+   // Always call even when there are not JVMTI environments yet, since environments
+   // may be attached late and JVMTI must track phases of VM execution
+   JvmtiExport::post_vm_death();
++  Threads::shutdown_vm_agents();
+ 
+   // Terminate the signal thread
+   // Note: we don't wait until it actually dies.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp openjdk/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)javaFrameAnchor.hpp	1.16 07/05/05 17:06:50 JVM"
+-#endif
+ /*
+  * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -44,7 +41,7 @@
+ friend class JavaThread;
+ friend class frame;
+ friend class VMStructs;
+-friend class cInterpreter;
++friend class BytecodeInterpreter;
+ friend class JavaCallWrapper;
+ 
+  private:
+@@ -88,4 +85,3 @@
+   static ByteSize last_Java_pc_offset()          { return byte_offset_of(JavaFrameAnchor, _last_Java_pc); }
+ 
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/java.hpp openjdk/hotspot/src/share/vm/runtime/java.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/java.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/java.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)java.hpp	1.36 07/05/05 17:06:49 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -72,6 +69,7 @@
+   static bool is_jdk14x_version()           { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 4; }
+   static bool is_jdk15x_version()           { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 5; }
+   static bool is_jdk16x_version()           { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 6; }
++  static bool is_jdk17x_version()           { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 7; }
+ 
+   static bool supports_thread_park_blocker() { return _version_info.thread_park_blocker; }
+ 
+@@ -87,9 +85,16 @@
+   }
+   static bool is_gte_jdk16x_version() {
+     // Keep the semantics of this that the version number is >= 1.6
++    assert(is_jdk_version_initialized(), "Not initialized");
+     return _jdk_version >= 6;
+   }
+ 
++  static bool is_gte_jdk17x_version() {
++    // Keep the semantics of this that the version number is >= 1.7
++    assert(is_jdk_version_initialized(), "Not initialized");
++    return _jdk_version >= 7;
++  }
++
+   static bool is_jdk_version_initialized() {
+     return _jdk_version > 0;
+   }
+@@ -116,5 +121,3 @@
+     _version_info.jdk_version = (1 << 24) | (5 << 16);
+   }
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/jfieldIDWorkaround.hpp openjdk/hotspot/src/share/vm/runtime/jfieldIDWorkaround.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/jfieldIDWorkaround.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/jfieldIDWorkaround.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jfieldIDWorkaround.hpp	1.11 07/05/05 17:06:51 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/jniHandles.cpp openjdk/hotspot/src/share/vm/runtime/jniHandles.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/jniHandles.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/jniHandles.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jniHandles.cpp	1.64 07/05/17 16:06:13 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/jniHandles.hpp openjdk/hotspot/src/share/vm/runtime/jniHandles.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/jniHandles.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/jniHandles.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jniHandles.hpp	1.54 07/05/17 16:06:14 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -213,5 +210,3 @@
+     *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
+   }
+ }
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/jniPeriodicChecker.cpp openjdk/hotspot/src/share/vm/runtime/jniPeriodicChecker.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/jniPeriodicChecker.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/jniPeriodicChecker.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jniPeriodicChecker.cpp	1.4 07/05/05 17:06:51 JVM"
+-#endif
+ /*
+  * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/jniPeriodicChecker.hpp openjdk/hotspot/src/share/vm/runtime/jniPeriodicChecker.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/jniPeriodicChecker.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/jniPeriodicChecker.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jniPeriodicChecker.hpp	1.4 07/05/05 17:06:51 JVM"
+-#endif
+ /*
+  * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/memprofiler.cpp openjdk/hotspot/src/share/vm/runtime/memprofiler.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/memprofiler.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/memprofiler.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)memprofiler.cpp	1.24 07/05/05 17:06:52 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/memprofiler.hpp openjdk/hotspot/src/share/vm/runtime/memprofiler.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/memprofiler.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/memprofiler.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)memprofiler.hpp	1.17 07/05/05 17:06:52 JVM"
+-#endif
+ /*
+  * Copyright 1998 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/monitorChunk.cpp openjdk/hotspot/src/share/vm/runtime/monitorChunk.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/monitorChunk.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/monitorChunk.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)monitorChunk.cpp	1.19 07/05/05 17:06:52 JVM"
+-#endif
+ /*
+  * Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -45,4 +42,3 @@
+     at(index)->oops_do(f);
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/monitorChunk.hpp openjdk/hotspot/src/share/vm/runtime/monitorChunk.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/monitorChunk.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/monitorChunk.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)monitorChunk.hpp	1.19 07/05/05 17:06:52 JVM"
+-#endif
+ /*
+  * Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/mutex.cpp openjdk/hotspot/src/share/vm/runtime/mutex.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/mutex.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/mutex.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,4 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)mutex.cpp	1.60 07/05/05 17:06:43 JVM"
+-#endif
++
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -28,63 +26,808 @@
+ # include "incls/_precompiled.incl"
+ # include "incls/_mutex.cpp.incl"
+ 
+-#ifdef ASSERT
+-Histogram* MutexHistogram;
+-static volatile jint MutexHistogram_lock = 0;
+-Histogram* MutexContentionHistogram;
+-static volatile jint MutexContentionHistogram_lock = 0;
++// o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
++//
++// Native Monitor-Mutex locking - theory of operations
++//
++// * Native Monitors are completely unrelated to Java-level monitors,
++//   although the "back-end" slow-path implementations share a common lineage.
++//   See objectMonitor:: in synchronizer.cpp.
++//   Native Monitors do *not* support nesting or recursion but otherwise
++//   they're basically Hoare-flavor monitors.
++//
++// * A thread acquires ownership of a Monitor/Mutex by CASing the LockByte
++//   in the _LockWord from zero to non-zero.  Note that the _Owner field
++//   is advisory and is used only to verify that the thread calling unlock()
++//   is indeed the last thread to have acquired the lock.
++//
++// * Contending threads "push" themselves onto the front of the contention
++//   queue -- called the cxq -- with CAS and then spin/park.
++//   The _LockWord contains the LockByte as well as the pointer to the head
++//   of the cxq.  Colocating the LockByte with the cxq precludes certain races.
++//
++// * Using a separately addressable LockByte allows for CAS:MEMBAR or CAS:0
++//   idioms.  We currently use MEMBAR in the uncontended unlock() path, as
++//   MEMBAR often has less latency than CAS.  If warranted, we could switch to
++//   a CAS:0 mode, using timers to close the resultant race, as is done
++//   with Java Monitors in synchronizer.cpp.
++//
++//   See the following for a discussion of the relative cost of atomics (CAS)
++//   MEMBAR, and ways to eliminate such instructions from the common-case paths:
++//   -- http://blogs.sun.com/dave/entry/biased_locking_in_hotspot
++//   -- http://blogs.sun.com/dave/resource/MustangSync.pdf
++//   -- http://blogs.sun.com/dave/resource/synchronization-public2.pdf
++//   -- synchronizer.cpp
++//
++// * Overall goals - desiderata
++//   1. Minimize context switching
++//   2. Minimize lock migration
++//   3. Minimize CPI -- affinity and locality
++//   4. Minimize the execution of high-latency instructions such as CAS or MEMBAR
++//   5. Minimize outer lock hold times
++//   6. Behave gracefully on a loaded system
++//
++// * Thread flow and list residency:
++//
++//   Contention queue --> EntryList --> OnDeck --> Owner --> !Owner
++//   [..resident on monitor list..]
++//   [...........contending..................]
++//
++//   -- The contention queue (cxq) contains recently-arrived threads (RATs).
++//      Threads on the cxq eventually drain into the EntryList.
++//   -- Invariant: a thread appears on at most one list -- cxq, EntryList
++//      or WaitSet -- at any one time.
++//   -- For a given monitor there can be at most one "OnDeck" thread at any
++//      given time but if needbe this particular invariant could be relaxed.
++//
++// * The WaitSet and EntryList linked lists are composed of ParkEvents.
++//   I use ParkEvent instead of threads as ParkEvents are immortal and
++//   type-stable, meaning we can safely unpark() a possibly stale
++//   list element in the unlock()-path.  (That's benign).
++//
++// * Succession policy - providing for progress:
++//
++//   As necessary, the unlock()ing thread identifies, unlinks, and unparks
++//   an "heir presumptive" tentative successor thread from the EntryList.
++//   This becomes the so-called "OnDeck" thread, of which there can be only
++//   one at any given time for a given monitor.  The wakee will recontend
++//   for ownership of monitor.
++//
++//   Succession is provided for by a policy of competitive handoff.
++//   The exiting thread does _not_ grant or pass ownership to the
++//   successor thread.  (This is also referred to as "handoff" succession").
++//   Instead the exiting thread releases ownership and possibly wakes
++//   a successor, so the successor can (re)compete for ownership of the lock.
++//
++//   Competitive handoff provides excellent overall throughput at the expense
++//   of short-term fairness.  If fairness is a concern then one remedy might
++//   be to add an AcquireCounter field to the monitor.  After a thread acquires
++//   the lock it will decrement the AcquireCounter field.  When the count
++//   reaches 0 the thread would reset the AcquireCounter variable, abdicate
++//   the lock directly to some thread on the EntryList, and then move itself to the
++//   tail of the EntryList.
++//
++//   But in practice most threads engage or otherwise participate in resource
++//   bounded producer-consumer relationships, so lock domination is not usually
++//   a practical concern.  Recall too, that in general it's easier to construct
++//   a fair lock from a fast lock, but not vice-versa.
++//
++// * The cxq can have multiple concurrent "pushers" but only one concurrent
++//   detaching thread.  This mechanism is immune from the ABA corruption.
++//   More precisely, the CAS-based "push" onto cxq is ABA-oblivious.
++//   We use OnDeck as a pseudo-lock to enforce the at-most-one detaching
++//   thread constraint.
++//
++// * Taken together, the cxq and the EntryList constitute or form a
++//   single logical queue of threads stalled trying to acquire the lock.
++//   We use two distinct lists to reduce heat on the list ends.
++//   Threads in lock() enqueue onto cxq while threads in unlock() will
++//   dequeue from the EntryList.  (c.f. Michael Scott's "2Q" algorithm).
++//   A key desideratum is to minimize queue & monitor metadata manipulation
++//   that occurs while holding the "outer" monitor lock -- that is, we want to
++//   minimize monitor lock holds times.
++//
++//   The EntryList is ordered by the prevailing queue discipline and
++//   can be organized in any convenient fashion, such as a doubly-linked list or
++//   a circular doubly-linked list.  If we need a priority queue then something akin
++//   to Solaris' sleepq would work nicely.  Viz.,
++//   -- http://agg.eng/ws/on10_nightly/source/usr/src/uts/common/os/sleepq.c.
++//   -- http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/os/sleepq.c
++//   Queue discipline is enforced at ::unlock() time, when the unlocking thread
++//   drains the cxq into the EntryList, and orders or reorders the threads on the
++//   EntryList accordingly.
++//
++//   Barring "lock barging", this mechanism provides fair cyclic ordering,
++//   somewhat similar to an elevator-scan.
++//
++// * OnDeck
++//   --  For a given monitor there can be at most one OnDeck thread at any given
++//       instant.  The OnDeck thread is contending for the lock, but has been
++//       unlinked from the EntryList and cxq by some previous unlock() operations.
++//       Once a thread has been designated the OnDeck thread it will remain so
++//       until it manages to acquire the lock -- being OnDeck is a stable property.
++//   --  Threads on the EntryList or cxq are _not allowed to attempt lock acquisition.
++//   --  OnDeck also serves as an "inner lock" as follows.  Threads in unlock() will, after
++//       having cleared the LockByte and dropped the outer lock,  attempt to "trylock"
++//       OnDeck by CASing the field from null to non-null.  If successful, that thread
++//       is then responsible for progress and succession and can use CAS to detach and
++//       drain the cxq into the EntryList.  By convention, only this thread, the holder of
++//       the OnDeck inner lock, can manipulate the EntryList or detach and drain the
++//       RATs on the cxq into the EntryList.  This avoids ABA corruption on the cxq as
++//       we allow multiple concurrent "push" operations but restrict detach concurrency
++//       to at most one thread.  Having selected and detached a successor, the thread then
++//       changes the OnDeck to refer to that successor, and then unparks the successor.
++//       That successor will eventually acquire the lock and clear OnDeck.  Beware
++//       that the OnDeck usage as a lock is asymmetric.  A thread in unlock() transiently
++//       "acquires" OnDeck, performs queue manipulations, passes OnDeck to some successor,
++//       and then the successor eventually "drops" OnDeck.  Note that there's never
++//       any sense of contention on the inner lock, however.  Threads never contend
++//       or wait for the inner lock.
++//   --  OnDeck provides for futile wakeup throttling a described in section 3.3 of
++//       See http://www.usenix.org/events/jvm01/full_papers/dice/dice.pdf
++//       In a sense, OnDeck subsumes the ObjectMonitor _Succ and ObjectWaiter
++//       TState fields found in Java-level objectMonitors.  (See synchronizer.cpp).
++//
++// * Waiting threads reside on the WaitSet list -- wait() puts
++//   the caller onto the WaitSet.  Notify() or notifyAll() simply
++//   transfers threads from the WaitSet to either the EntryList or cxq.
++//   Subsequent unlock() operations will eventually unpark the notifyee.
++//   Unparking a notifee in notify() proper is inefficient - if we were to do so
++//   it's likely the notifyee would simply impale itself on the lock held
++//   by the notifier.
++//
++// * The mechanism is obstruction-free in that if the holder of the transient
++//   OnDeck lock in unlock() is preempted or otherwise stalls, other threads
++//   can still acquire and release the outer lock and continue to make progress.
++//   At worst, waking of already blocked contending threads may be delayed,
++//   but nothing worse.  (We only use "trylock" operations on the inner OnDeck
++//   lock).
++//
++// * Note that thread-local storage must be initialized before a thread
++//   uses Native monitors or mutexes.  The native monitor-mutex subsystem
++//   depends on Thread::current().
++//
++// * The monitor synchronization subsystem avoids the use of native
++//   synchronization primitives except for the narrow platform-specific
++//   park-unpark abstraction.  See the comments in os_solaris.cpp regarding
++//   the semantics of park-unpark.  Put another way, this monitor implementation
++//   depends only on atomic operations and park-unpark.  The monitor subsystem
++//   manages all RUNNING->BLOCKED and BLOCKED->READY transitions while the
++//   underlying OS manages the READY<->RUN transitions.
++//
++// * The memory consistency model provide by lock()-unlock() is at least as
++//   strong or stronger than the Java Memory model defined by JSR-133.
++//   That is, we guarantee at least entry consistency, if not stronger.
++//   See http://g.oswego.edu/dl/jmm/cookbook.html.
++//
++// * Thread:: currently contains a set of purpose-specific ParkEvents:
++//   _MutexEvent, _ParkEvent, etc.  A better approach might be to do away with
++//   the purpose-specific ParkEvents and instead implement a general per-thread
++//   stack of available ParkEvents which we could provision on-demand.  The
++//   stack acts as a local cache to avoid excessive calls to ParkEvent::Allocate()
++//   and ::Release().  A thread would simply pop an element from the local stack before it
++//   enqueued or park()ed.  When the contention was over the thread would
++//   push the no-longer-needed ParkEvent back onto its stack.
++//
++// * A slightly reduced form of ILock() and IUnlock() have been partially
++//   model-checked (Murphi) for safety and progress at T=1,2,3 and 4.
++//   It'd be interesting to see if TLA/TLC could be useful as well.
++//
++// * Mutex-Monitor is a low-level "leaf" subsystem.  That is, the monitor
++//   code should never call other code in the JVM that might itself need to
++//   acquire monitors or mutexes.  That's true *except* in the case of the
++//   ThreadBlockInVM state transition wrappers.  The ThreadBlockInVM DTOR handles
++//   mutator reentry (ingress) by checking for a pending safepoint in which case it will
++//   call SafepointSynchronize::block(), which in turn may call Safepoint_lock->lock(), etc.
++//   In that particular case a call to lock() for a given Monitor can end up recursively
++//   calling lock() on another monitor.   While distasteful, this is largely benign
++//   as the calls come from jacket that wraps lock(), and not from deep within lock() itself.
++//
++//   It's unfortunate that native mutexes and thread state transitions were convolved.
++//   They're really separate concerns and should have remained that way.  Melding
++//   them together was facile -- a bit too facile.   The current implementation badly
++//   conflates the two concerns.
++//
++// * TODO-FIXME:
++//
++//   -- Add DTRACE probes for contended acquire, contended acquired, contended unlock
++//      We should also add DTRACE probes in the ParkEvent subsystem for
++//      Park-entry, Park-exit, and Unpark.
++//
++//   -- We have an excess of mutex-like constructs in the JVM, namely:
++//      1. objectMonitors for Java-level synchronization (synchronizer.cpp)
++//      2. low-level muxAcquire and muxRelease
++//      3. low-level spinAcquire and spinRelease
++//      4. native Mutex:: and Monitor::
++//      5. jvm_raw_lock() and _unlock()
++//      6. JVMTI raw monitors -- distinct from (5) despite having a confusingly
++//         similar name.
++//
++// o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
++
++
++// CASPTR() uses the canonical argument order that dominates in the literature.
++// Our internal cmpxchg_ptr() uses a bastardized ordering to accommodate Sun .il templates.
++
++#define CASPTR(a,c,s) intptr_t(Atomic::cmpxchg_ptr ((void *)(s),(void *)(a),(void *)(c)))
++#define UNS(x) (uintptr_t(x))
++#define TRACE(m) { static volatile int ctr = 0 ; int x = ++ctr ; if ((x & (x-1))==0) { ::printf ("%d:%s\n", x, #m); ::fflush(stdout); }}
++
++// Simplistic low-quality Marsaglia SHIFT-XOR RNG.
++// Bijective except for the trailing mask operation.
++// Useful for spin loops as the compiler can't optimize it away.
++
++static inline jint MarsagliaXORV (jint x) {
++  if (x == 0) x = 1|os::random() ;
++  x ^= x << 6;
++  x ^= ((unsigned)x) >> 21;
++  x ^= x << 7 ;
++  return x & 0x7FFFFFFF ;
++}
+ 
+-MutexHistogramElement::MutexHistogramElement(const char* elementName) {
+-  _name = elementName;
+-  uintx count = 0;
++static inline jint MarsagliaXOR (jint * const a) {
++  jint x = *a ;
++  if (x == 0) x = UNS(a)|1 ;
++  x ^= x << 6;
++  x ^= ((unsigned)x) >> 21;
++  x ^= x << 7 ;
++  *a = x ;
++  return x & 0x7FFFFFFF ;
++}
+ 
+-  while (Atomic::cmpxchg(1, &MutexHistogram_lock, 0) != 0) {
+-    while (OrderAccess::load_acquire(&MutexHistogram_lock) != 0) {
+-      count +=1;
+-      if ( (WarnOnStalledSpinLock > 0)
+-        && (count % WarnOnStalledSpinLock == 0)) {
+-        warning("MutexHistogram_lock seems to be stalled");
+-      }
+-    }
++static int Stall (int its) {
++  static volatile jint rv = 1 ;
++  volatile int OnFrame = 0 ;
++  jint v = rv ^ UNS(OnFrame) ;
++  while (--its >= 0) {
++    v = MarsagliaXORV (v) ;
++  }
++  // Make this impossible for the compiler to optimize away,
++  // but (mostly) avoid W coherency sharing on MP systems.
++  if (v == 0x12345) rv = v ;
++  return v ;
++}
++
++int Monitor::TryLock () {
++  intptr_t v = _LockWord.FullWord ;
++  for (;;) {
++    if ((v & _LBIT) != 0) return 0 ;
++    const intptr_t u = CASPTR (&_LockWord, v, v|_LBIT) ;
++    if (v == u) return 1 ;
++    v = u ;
+   }
++}
+ 
+-  if (MutexHistogram == NULL) {
+-    MutexHistogram = new Histogram("VM Mutex Lock Attempt Counts",200);
++int Monitor::TryFast () {
++  // Optimistic fast-path form ...
++  // Fast-path attempt for the common uncontended case.
++  // Avoid RTS->RTO $ coherence upgrade on typical SMP systems.
++  intptr_t v = CASPTR (&_LockWord, 0, _LBIT) ;  // agro ...
++  if (v == 0) return 1 ;
++
++  for (;;) {
++    if ((v & _LBIT) != 0) return 0 ;
++    const intptr_t u = CASPTR (&_LockWord, v, v|_LBIT) ;
++    if (v == u) return 1 ;
++    v = u ;
+   }
++}
+ 
+-  MutexHistogram->add_element(this);
+-  Atomic::dec(&MutexHistogram_lock);
++int Monitor::ILocked () {
++  const intptr_t w = _LockWord.FullWord & 0xFF ;
++  assert (w == 0 || w == _LBIT, "invariant") ;
++  return w == _LBIT ;
+ }
+ 
++// Polite TATAS spinlock with exponential backoff - bounded spin.
++// Ideally we'd use processor cycles, time or vtime to control
++// the loop, but we currently use iterations.
++// All the constants within were derived empirically but work over
++// over the spectrum of J2SE reference platforms.
++// On Niagara-class systems the back-off is unnecessary but
++// is relatively harmless.  (At worst it'll slightly retard
++// acquisition times).  The back-off is critical for older SMP systems
++// where constant fetching of the LockWord would otherwise impair
++// scalability.
++//
++// Clamp spinning at approximately 1/2 of a context-switch round-trip.
++// See synchronizer.cpp for details and rationale.
++
++int Monitor::TrySpin (Thread * const Self) {
++  if (TryLock())    return 1 ;
++  if (!os::is_MP()) return 0 ;
++
++  int Probes  = 0 ;
++  int Delay   = 0 ;
++  int Steps   = 0 ;
++  int SpinMax = NativeMonitorSpinLimit ;
++  int flgs    = NativeMonitorFlags ;
++  for (;;) {
++    intptr_t v = _LockWord.FullWord;
++    if ((v & _LBIT) == 0) {
++      if (CASPTR (&_LockWord, v, v|_LBIT) == v) {
++        return 1 ;
++      }
++      continue ;
++    }
++
++    if ((flgs & 8) == 0) {
++      SpinPause () ;
++    }
++
++    // Periodically increase Delay -- variable Delay form
++    // conceptually: delay *= 1 + 1/Exponent
++    ++ Probes;
++    if (Probes > SpinMax) return 0 ;
++
++    if ((Probes & 0x7) == 0) {
++      Delay = ((Delay << 1)|1) & 0x7FF ;
++      // CONSIDER: Delay += 1 + (Delay/4); Delay &= 0x7FF ;
++    }
++
++    if (flgs & 2) continue ;
++
++    // Consider checking _owner's schedctl state, if OFFPROC abort spin.
++    // If the owner is OFFPROC then it's unlike that the lock will be dropped
++    // in a timely fashion, which suggests that spinning would not be fruitful
++    // or profitable.
++
++    // Stall for "Delay" time units - iterations in the current implementation.
++    // Avoid generating coherency traffic while stalled.
++    // Possible ways to delay:
++    //   PAUSE, SLEEP, MEMBAR #sync, MEMBAR #halt,
++    //   wr %g0,%asi, gethrtime, rdstick, rdtick, rdtsc, etc. ...
++    // Note that on Niagara-class systems we want to minimize STs in the
++    // spin loop.  N1 and brethren write-around the L1$ over the xbar into the L2$.
++    // Furthermore, they don't have a W$ like traditional SPARC processors.
++    // We currently use a Marsaglia Shift-Xor RNG loop.
++    Steps += Delay ;
++    if (Self != NULL) {
++      jint rv = Self->rng[0] ;
++      for (int k = Delay ; --k >= 0; ) {
++        rv = MarsagliaXORV (rv) ;
++        if ((flgs & 4) == 0 && SafepointSynchronize::do_call_back()) return 0 ;
++      }
++      Self->rng[0] = rv ;
++    } else {
++      Stall (Delay) ;
++    }
++  }
++}
+ 
+-MutexContentionHistogramElement::MutexContentionHistogramElement(const char* elementName) {
+-  _name = elementName;
+-  uintx count = 0;
++static int ParkCommon (ParkEvent * ev, jlong timo) {
++  // Diagnostic support - periodically unwedge blocked threads
++  intx nmt = NativeMonitorTimeout ;
++  if (nmt > 0 && (nmt < timo || timo <= 0)) {
++     timo = nmt ;
++  }
++  int err = OS_OK ;
++  if (0 == timo) {
++    ev->park() ;
++  } else {
++    err = ev->park(timo) ;
++  }
++  return err ;
++}
+ 
+-  while (Atomic::cmpxchg(1, &MutexContentionHistogram_lock, 0) != 0) {
+-    while (OrderAccess::load_acquire(&MutexContentionHistogram_lock) != 0) {
+-      count +=1;
+-      if ( (WarnOnStalledSpinLock > 0)
+-        && (count % WarnOnStalledSpinLock == 0)) {
+-        warning("MutexContentionHistogram_lock seems to be stalled");
++inline int Monitor::AcquireOrPush (ParkEvent * ESelf) {
++  intptr_t v = _LockWord.FullWord ;
++  for (;;) {
++    if ((v & _LBIT) == 0) {
++      const intptr_t u = CASPTR (&_LockWord, v, v|_LBIT) ;
++      if (u == v) return 1 ;        // indicate acquired
++      v = u ;
++    } else {
++      // Anticipate success ...
++      ESelf->ListNext = (ParkEvent *) (v & ~_LBIT) ;
++      const intptr_t u = CASPTR (&_LockWord, v, intptr_t(ESelf)|_LBIT) ;
++      if (u == v) return 0 ;        // indicate pushed onto cxq
++      v = u ;
+       }
++    // Interference - LockWord change - just retry
+     }
++}
++
++// ILock and IWait are the lowest level primitive internal blocking
++// synchronization functions.  The callers of IWait and ILock must have
++// performed any needed state transitions beforehand.
++// IWait and ILock may directly call park() without any concern for thread state.
++// Note that ILock and IWait do *not* access _owner.
++// _owner is a higher-level logical concept.
++
++void Monitor::ILock (Thread * Self) {
++  assert (_OnDeck != Self->_MutexEvent, "invariant") ;
++
++  if (TryFast()) {
++ Exeunt:
++    assert (ILocked(), "invariant") ;
++    return ;
++  }
++
++  ParkEvent * const ESelf = Self->_MutexEvent ;
++  assert (_OnDeck != ESelf, "invariant") ;
++
++  // As an optimization, spinners could conditionally try to set ONDECK to _LBIT
++  // Synchronizer.cpp uses a similar optimization.
++  if (TrySpin (Self)) goto Exeunt ;
++
++  // Slow-path - the lock is contended.
++  // Either Enqueue Self on cxq or acquire the outer lock.
++  // LockWord encoding = (cxq,LOCKBYTE)
++  ESelf->reset() ;
++  OrderAccess::fence() ;
++
++  // Optional optimization ... try barging on the inner lock
++  if ((NativeMonitorFlags & 32) && CASPTR (&_OnDeck, NULL, UNS(Self)) == 0) {
++    goto OnDeck_LOOP ;
++  }
++
++  if (AcquireOrPush (ESelf)) goto Exeunt ;
++
++  // At any given time there is at most one ondeck thread.
++  // ondeck implies not resident on cxq and not resident on EntryList
++  // Only the OnDeck thread can try to acquire -- contended for -- the lock.
++  // CONSIDER: use Self->OnDeck instead of m->OnDeck.
++  // Deschedule Self so that others may run.
++  while (_OnDeck != ESelf) {
++    ParkCommon (ESelf, 0) ;
++  }
++
++  // Self is now in the ONDECK position and will remain so until it
++  // manages to acquire the lock.
++ OnDeck_LOOP:
++  for (;;) {
++    assert (_OnDeck == ESelf, "invariant") ;
++    if (TrySpin (Self)) break ;
++    // CONSIDER: if ESelf->TryPark() && TryLock() break ...
++    // It's probably wise to spin only if we *actually* blocked
++    // CONSIDER: check the lockbyte, if it remains set then
++    // preemptively drain the cxq into the EntryList.
++    // The best place and time to perform queue operations -- lock metadata --
++    // is _before having acquired the outer lock, while waiting for the lock to drop.
++    ParkCommon (ESelf, 0) ;
++  }
++
++  assert (_OnDeck == ESelf, "invariant") ;
++  _OnDeck = NULL ;
++
++  // Note that we current drop the inner lock (clear OnDeck) in the slow-path
++  // epilog immediately after having acquired the outer lock.
++  // But instead we could consider the following optimizations:
++  // A. Shift or defer dropping the inner lock until the subsequent IUnlock() operation.
++  //    This might avoid potential reacquisition of the inner lock in IUlock().
++  // B. While still holding the inner lock, attempt to opportunistically select
++  //    and unlink the next ONDECK thread from the EntryList.
++  //    If successful, set ONDECK to refer to that thread, otherwise clear ONDECK.
++  //    It's critical that the select-and-unlink operation run in constant-time as
++  //    it executes when holding the outer lock and may artificially increase the
++  //    effective length of the critical section.
++  // Note that (A) and (B) are tantamount to succession by direct handoff for
++  // the inner lock.
++  goto Exeunt ;
++}
++
++void Monitor::IUnlock (bool RelaxAssert) {
++  assert (ILocked(), "invariant") ;
++  _LockWord.Bytes[_LSBINDEX] = 0 ;       // drop outer lock
++  OrderAccess::storeload ();
++  ParkEvent * const w = _OnDeck ;
++  assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ;
++  if (w != NULL) {
++    // Either we have a valid ondeck thread or ondeck is transiently "locked"
++    // by some exiting thread as it arranges for succession.  The LSBit of
++    // OnDeck allows us to discriminate two cases.  If the latter, the
++    // responsibility for progress and succession lies with that other thread.
++    // For good performance, we also depend on the fact that redundant unpark()
++    // operations are cheap.  That is, repeated Unpark()ing of the ONDECK thread
++    // is inexpensive.  This approach provides implicit futile wakeup throttling.
++    // Note that the referent "w" might be stale with respect to the lock.
++    // In that case the following unpark() is harmless and the worst that'll happen
++    // is a spurious return from a park() operation.  Critically, if "w" _is stale,
++    // then progress is known to have occurred as that means the thread associated
++    // with "w" acquired the lock.  In that case this thread need take no further
++    // action to guarantee progress.
++    if ((UNS(w) & _LBIT) == 0) w->unpark() ;
++    return ;
++  }
++
++  intptr_t cxq = _LockWord.FullWord ;
++  if (((cxq & ~_LBIT)|UNS(_EntryList)) == 0) {
++    return ;      // normal fast-path exit - cxq and EntryList both empty
++  }
++  if (cxq & _LBIT) {
++    // Optional optimization ...
++    // Some other thread acquired the lock in the window since this
++    // thread released it.  Succession is now that thread's responsibility.
++    return ;
++  }
++
++ Succession:
++  // Slow-path exit - this thread must ensure succession and progress.
++  // OnDeck serves as lock to protect cxq and EntryList.
++  // Only the holder of OnDeck can manipulate EntryList or detach the RATs from cxq.
++  // Avoid ABA - allow multiple concurrent producers (enqueue via push-CAS)
++  // but only one concurrent consumer (detacher of RATs).
++  // Consider protecting this critical section with schedctl on Solaris.
++  // Unlike a normal lock, however, the exiting thread "locks" OnDeck,
++  // picks a successor and marks that thread as OnDeck.  That successor
++  // thread will then clear OnDeck once it eventually acquires the outer lock.
++  if (CASPTR (&_OnDeck, NULL, _LBIT) != UNS(NULL)) {
++    return ;
++  }
++
++  ParkEvent * List = _EntryList ;
++  if (List != NULL) {
++    // Transfer the head of the EntryList to the OnDeck position.
++    // Once OnDeck, a thread stays OnDeck until it acquires the lock.
++    // For a given lock there is at most OnDeck thread at any one instant.
++   WakeOne:
++    assert (List == _EntryList, "invariant") ;
++    ParkEvent * const w = List ;
++    assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ;
++    _EntryList = w->ListNext ;
++    // as a diagnostic measure consider setting w->_ListNext = BAD
++    assert (UNS(_OnDeck) == _LBIT, "invariant") ;
++    _OnDeck = w ;           // pass OnDeck to w.
++                            // w will clear OnDeck once it acquires the outer lock
++
++    // Another optional optimization ...
++    // For heavily contended locks it's not uncommon that some other
++    // thread acquired the lock while this thread was arranging succession.
++    // Try to defer the unpark() operation - Delegate the responsibility
++    // for unpark()ing the OnDeck thread to the current or subsequent owners
++    // That is, the new owner is responsible for unparking the OnDeck thread.
++    OrderAccess::storeload() ;
++    cxq = _LockWord.FullWord ;
++    if (cxq & _LBIT) return ;
++
++    w->unpark() ;
++    return ;
++  }
++
++  cxq = _LockWord.FullWord ;
++  if ((cxq & ~_LBIT) != 0) {
++    // The EntryList is empty but the cxq is populated.
++    // drain RATs from cxq into EntryList
++    // Detach RATs segment with CAS and then merge into EntryList
++    for (;;) {
++      // optional optimization - if locked, the owner is responsible for succession
++      if (cxq & _LBIT) goto Punt ;
++      const intptr_t vfy = CASPTR (&_LockWord, cxq, cxq & _LBIT) ;
++      if (vfy == cxq) break ;
++      cxq = vfy ;
++      // Interference - LockWord changed - Just retry
++      // We can see concurrent interference from contending threads
++      // pushing themselves onto the cxq or from lock-unlock operations.
++      // From the perspective of this thread, EntryList is stable and
++      // the cxq is prepend-only -- the head is volatile but the interior
++      // of the cxq is stable.  In theory if we encounter interference from threads
++      // pushing onto cxq we could simply break off the original cxq suffix and
++      // move that segment to the EntryList, avoiding a 2nd or multiple CAS attempts
++      // on the high-traffic LockWord variable.   For instance lets say the cxq is "ABCD"
++      // when we first fetch cxq above.  Between the fetch -- where we observed "A"
++      // -- and CAS -- where we attempt to CAS null over A -- "PQR" arrive,
++      // yielding cxq = "PQRABCD".  In this case we could simply set A.ListNext
++      // null, leaving cxq = "PQRA" and transfer the "BCD" segment to the EntryList.
++      // Note too, that it's safe for this thread to traverse the cxq
++      // without taking any special concurrency precautions.
++    }
++
++    // We don't currently reorder the cxq segment as we move it onto
++    // the EntryList, but it might make sense to reverse the order
++    // or perhaps sort by thread priority.  See the comments in
++    // synchronizer.cpp objectMonitor::exit().
++    assert (_EntryList == NULL, "invariant") ;
++    _EntryList = List = (ParkEvent *)(cxq & ~_LBIT) ;
++    assert (List != NULL, "invariant") ;
++    goto WakeOne ;
++  }
++
++  // cxq|EntryList is empty.
++  // w == NULL implies that cxq|EntryList == NULL in the past.
++  // Possible race - rare inopportune interleaving.
++  // A thread could have added itself to cxq since this thread previously checked.
++  // Detect and recover by refetching cxq.
++ Punt:
++  assert (UNS(_OnDeck) == _LBIT, "invariant") ;
++  _OnDeck = NULL ;            // Release inner lock.
++  OrderAccess::storeload();   // Dekker duality - pivot point
++
++  // Resample LockWord/cxq to recover from possible race.
++  // For instance, while this thread T1 held OnDeck, some other thread T2 might
++  // acquire the outer lock.  Another thread T3 might try to acquire the outer
++  // lock, but encounter contention and enqueue itself on cxq.  T2 then drops the
++  // outer lock, but skips succession as this thread T1 still holds OnDeck.
++  // T1 is and remains responsible for ensuring succession of T3.
++  //
++  // Note that we don't need to recheck EntryList, just cxq.
++  // If threads moved onto EntryList since we dropped OnDeck
++  // that implies some other thread forced succession.
++  cxq = _LockWord.FullWord ;
++  if ((cxq & ~_LBIT) != 0 && (cxq & _LBIT) == 0) {
++    goto Succession ;         // potential race -- re-run succession
+   }
++  return ;
++}
+ 
+-  if (MutexContentionHistogram == NULL) {
+-    MutexContentionHistogram = new Histogram("VM Mutex Lock Contention Count",200);
++bool Monitor::notify() {
++  assert (_owner == Thread::current(), "invariant") ;
++  assert (ILocked(), "invariant") ;
++  if (_WaitSet == NULL) return true ;
++  NotifyCount ++ ;
++
++  // Transfer one thread from the WaitSet to the EntryList or cxq.
++  // Currently we just unlink the head of the WaitSet and prepend to the cxq.
++  // And of course we could just unlink it and unpark it, too, but
++  // in that case it'd likely impale itself on the reentry.
++  Thread::muxAcquire (_WaitLock, "notify:WaitLock") ;
++  ParkEvent * nfy = _WaitSet ;
++  if (nfy != NULL) {                  // DCL idiom
++    _WaitSet = nfy->ListNext ;
++    assert (nfy->Notified == 0, "invariant") ;
++    // push nfy onto the cxq
++    for (;;) {
++      const intptr_t v = _LockWord.FullWord ;
++      assert ((v & 0xFF) == _LBIT, "invariant") ;
++      nfy->ListNext = (ParkEvent *)(v & ~_LBIT);
++      if (CASPTR (&_LockWord, v, UNS(nfy)|_LBIT) == v) break;
++      // interference - _LockWord changed -- just retry
++    }
++    // Note that setting Notified before pushing nfy onto the cxq is
++    // also legal and safe, but the safety properties are much more
++    // subtle, so for the sake of code stewardship ...
++    OrderAccess::fence() ;
++    nfy->Notified = 1;
++  }
++  Thread::muxRelease (_WaitLock) ;
++  if (nfy != NULL && (NativeMonitorFlags & 16)) {
++    // Experimental code ... light up the wakee in the hope that this thread (the owner)
++    // will drop the lock just about the time the wakee comes ONPROC.
++    nfy->unpark() ;
+   }
++  assert (ILocked(), "invariant") ;
++  return true ;
++}
+ 
+-  MutexContentionHistogram->add_element(this);
+-  Atomic::dec(&MutexContentionHistogram_lock);
++// Currently notifyAll() transfers the waiters one-at-a-time from the waitset
++// to the cxq.  This could be done more efficiently with a single bulk en-mass transfer,
++// but in practice notifyAll() for large #s of threads is rare and not time-critical.
++// Beware too, that we invert the order of the waiters.  Lets say that the
++// waitset is "ABCD" and the cxq is "XYZ".  After a notifyAll() the waitset
++// will be empty and the cxq will be "DCBAXYZ".  This is benign, of course.
++
++bool Monitor::notify_all() {
++  assert (_owner == Thread::current(), "invariant") ;
++  assert (ILocked(), "invariant") ;
++  while (_WaitSet != NULL) notify() ;
++  return true ;
+ }
+ 
+-#endif
++int Monitor::IWait (Thread * Self, jlong timo) {
++  assert (ILocked(), "invariant") ;
+ 
++  // Phases:
++  // 1. Enqueue Self on WaitSet - currently prepend
++  // 2. unlock - drop the outer lock
++  // 3. wait for either notification or timeout
++  // 4. lock - reentry - reacquire the outer lock
++
++  ParkEvent * const ESelf = Self->_MutexEvent ;
++  ESelf->Notified = 0 ;
++  ESelf->reset() ;
++  OrderAccess::fence() ;
++
++  // Add Self to WaitSet
++  // Ideally only the holder of the outer lock would manipulate the WaitSet -
++  // That is, the outer lock would implicitly protect the WaitSet.
++  // But if a thread in wait() encounters a timeout it will need to dequeue itself
++  // from the WaitSet _before it becomes the owner of the lock.  We need to dequeue
++  // as the ParkEvent -- which serves as a proxy for the thread -- can't reside
++  // on both the WaitSet and the EntryList|cxq at the same time..  That is, a thread
++  // on the WaitSet can't be allowed to compete for the lock until it has managed to
++  // unlink its ParkEvent from WaitSet.  Thus the need for WaitLock.
++  // Contention on the WaitLock is minimal.
++  //
++  // Another viable approach would be add another ParkEvent, "WaitEvent" to the
++  // thread class.  The WaitSet would be composed of WaitEvents.  Only the
++  // owner of the outer lock would manipulate the WaitSet.  A thread in wait()
++  // could then compete for the outer lock, and then, if necessary, unlink itself
++  // from the WaitSet only after having acquired the outer lock.  More precisely,
++  // there would be no WaitLock.  A thread in in wait() would enqueue its WaitEvent
++  // on the WaitSet; release the outer lock; wait for either notification or timeout;
++  // reacquire the inner lock; and then, if needed, unlink itself from the WaitSet.
++  //
++  // Alternatively, a 2nd set of list link fields in the ParkEvent might suffice.
++  // One set would be for the WaitSet and one for the EntryList.
++  // We could also deconstruct the ParkEvent into a "pure" event and add a
++  // new immortal/TSM "ListElement" class that referred to ParkEvents.
++  // In that case we could have one ListElement on the WaitSet and another
++  // on the EntryList, with both referring to the same pure Event.
++
++  Thread::muxAcquire (_WaitLock, "wait:WaitLock:Add") ;
++  ESelf->ListNext = _WaitSet ;
++  _WaitSet = ESelf ;
++  Thread::muxRelease (_WaitLock) ;
++
++  // Release the outer lock
++  // We call IUnlock (RelaxAssert=true) as a thread T1 might
++  // enqueue itself on the WaitSet, call IUnlock(), drop the lock,
++  // and then stall before it can attempt to wake a successor.
++  // Some other thread T2 acquires the lock, and calls notify(), moving
++  // T1 from the WaitSet to the cxq.  T2 then drops the lock.  T1 resumes,
++  // and then finds *itself* on the cxq.  During the course of a normal
++  // IUnlock() call a thread should _never find itself on the EntryList
++  // or cxq, but in the case of wait() it's possible.
++  // See synchronizer.cpp objectMonitor::wait().
++  IUnlock (true) ;
++
++  // Wait for either notification or timeout
++  // Beware that in some circumstances we might propagate
++  // spurious wakeups back to the caller.
++
++  for (;;) {
++    if (ESelf->Notified) break ;
++    int err = ParkCommon (ESelf, timo) ;
++    if (err == OS_TIMEOUT || (NativeMonitorFlags & 1)) break ;
++  }
++
++  // Prepare for reentry - if necessary, remove ESelf from WaitSet
++  // ESelf can be:
++  // 1. Still on the WaitSet.  This can happen if we exited the loop by timeout.
++  // 2. On the cxq or EntryList
++  // 3. Not resident on cxq, EntryList or WaitSet, but in the OnDeck position.
++
++  OrderAccess::fence() ;
++  int WasOnWaitSet = 0 ;
++  if (ESelf->Notified == 0) {
++    Thread::muxAcquire (_WaitLock, "wait:WaitLock:remove") ;
++    if (ESelf->Notified == 0) {     // DCL idiom
++      assert (_OnDeck != ESelf, "invariant") ;   // can't be both OnDeck and on WaitSet
++      // ESelf is resident on the WaitSet -- unlink it.
++      // A doubly-linked list would be better here so we can unlink in constant-time.
++      // We have to unlink before we potentially recontend as ESelf might otherwise
++      // end up on the cxq|EntryList -- it can't be on two lists at once.
++      ParkEvent * p = _WaitSet ;
++      ParkEvent * q = NULL ;            // classic q chases p
++      while (p != NULL && p != ESelf) {
++        q = p ;
++        p = p->ListNext ;
++      }
++      assert (p == ESelf, "invariant") ;
++      if (p == _WaitSet) {      // found at head
++        assert (q == NULL, "invariant") ;
++        _WaitSet = p->ListNext ;
++      } else {                  // found in interior
++        assert (q->ListNext == p, "invariant") ;
++        q->ListNext = p->ListNext ;
++      }
++      WasOnWaitSet = 1 ;        // We were *not* notified but instead encountered timeout
++    }
++    Thread::muxRelease (_WaitLock) ;
++  }
++
++  // Reentry phase - reacquire the lock
++  if (WasOnWaitSet) {
++    // ESelf was previously on the WaitSet but we just unlinked it above
++    // because of a timeout.  ESelf is not resident on any list and is not OnDeck
++    assert (_OnDeck != ESelf, "invariant") ;
++    ILock (Self) ;
++  } else {
++    // A prior notify() operation moved ESelf from the WaitSet to the cxq.
++    // ESelf is now on the cxq, EntryList or at the OnDeck position.
++    // The following fragment is extracted from Monitor::ILock()
++    for (;;) {
++      if (_OnDeck == ESelf && TrySpin(Self)) break ;
++      ParkCommon (ESelf, 0) ;
++    }
++    assert (_OnDeck == ESelf, "invariant") ;
++    _OnDeck = NULL ;
++  }
++
++  assert (ILocked(), "invariant") ;
++  return WasOnWaitSet != 0 ;        // return true IFF timeout
++}
+ 
+-// This needs to be an invalid return from Thread::current; NULL is checked
+-// for as invalid in its implementation. _owner == INVALID_THREAD, means that
+-// the lock is unlocked.
+ 
+ // ON THE VMTHREAD SNEAKING PAST HELD LOCKS:
+ // In particular, there are certain types of global lock that may be held
+@@ -92,181 +835,351 @@
+ // written the _owner field. These locks may be sneakily acquired by the
+ // VM thread during a safepoint to avoid deadlocks. Alternatively, one should
+ // identify all such locks, and ensure that Java threads never block at
+-// safepoints while holding them (_no_safepopint_check_flag). While it
++// safepoints while holding them (_no_safepoint_check_flag). While it
+ // seems as though this could increase the time to reach a safepoint
+ // (or at least increase the mean, if not the variance), the latter
+ // approach might make for a cleaner, more maintainable JVM design.
++//
++// Sneaking is vile and reprehensible and should be excised at the 1st
++// opportunity.  It's possible that the need for sneaking could be obviated
++// as follows.  Currently, a thread might (a) while TBIVM, call pthread_mutex_lock
++// or ILock() thus acquiring the "physical" lock underlying Monitor/Mutex.
++// (b) stall at the TBIVM exit point as a safepoint is in effect.  Critically,
++// it'll stall at the TBIVM reentry state transition after having acquired the
++// underlying lock, but before having set _owner and having entered the actual
++// critical section.  The lock-sneaking facility leverages that fact and allowed the
++// VM thread to logically acquire locks that had already be physically locked by mutators
++// but where mutators were known blocked by the reentry thread state transition.
++//
++// If we were to modify the Monitor-Mutex so that TBIVM state transitions tightly
++// wrapped calls to park(), then we could likely do away with sneaking.  We'd
++// decouple lock acquisition and parking.  The critical invariant  to eliminating
++// sneaking is to ensure that we never "physically" acquire the lock while TBIVM.
++// An easy way to accomplish this is to wrap the park calls in a narrow TBIVM jacket.
++// One difficulty with this approach is that the TBIVM wrapper could recurse and
++// call lock() deep from within a lock() call, while the MutexEvent was already enqueued.
++// Using a stack (N=2 at minimum) of ParkEvents would take care of that problem.
++//
++// But of course the proper ultimate approach is to avoid schemes that require explicit
++// sneaking or dependence on any any clever invariants or subtle implementation properties
++// of Mutex-Monitor and instead directly address the underlying design flaw.
+ 
+-Thread* Mutex::INVALID_THREAD = (Thread*)NULL;
+-
+-void Mutex::lock(Thread *thread) { 
+-
++void Monitor::lock (Thread * Self) {
+ #ifdef CHECK_UNHANDLED_OOPS
+   // Clear unhandled oops so we get a crash right away.  Only clear for non-vm
+   // or GC threads.
+-  if (thread->is_Java_thread()) {
+-    thread->clear_unhandled_oops();
++  if (Self->is_Java_thread()) {
++    Self->clear_unhandled_oops();
+   }
+ #endif // CHECK_UNHANDLED_OOPS
+ 
+-  debug_only(check_prelock_state(thread));
+-  // assert(!thread->is_inside_signal_handler(), "don't lock inside signal handler");
++  debug_only(check_prelock_state(Self));
++  assert (_owner != Self              , "invariant") ;
++  assert (_OnDeck != Self->_MutexEvent, "invariant") ;
++
++  if (TryFast()) {
++ Exeunt:
++    assert (ILocked(), "invariant") ;
++    assert (owner() == NULL, "invariant");
++    set_owner (Self);
++    return ;
++  }
+ 
+-#ifdef ASSERT
+-  // Keep track of how many time access lock
+-  if (CountVMLocks) _histogram->increment_count();  
+-#endif
++  // The lock is contended ...
+ 
+-  // lock_implementation is a os-specific method
+-  if (lock_implementation()) {
+-    // Success, we now own the lock
+-  } else {    
+-#ifdef ASSERT
+-  // Keep track of how many times we fail 
+-  if (CountVMLocks) _contend_histogram->increment_count();  
+-#endif
+-    bool can_sneak = thread->is_VM_thread() &&
+-                     SafepointSynchronize::is_at_safepoint();
+-    if (can_sneak && _owner == INVALID_THREAD) {        
++  bool can_sneak = Self->is_VM_thread() && SafepointSynchronize::is_at_safepoint();
++  if (can_sneak && _owner == NULL) {
+       // a java thread has locked the lock but has not entered the
+       // critical region -- let's just pretend we've locked the lock
+-      // and go on.  we note this with _suppress_signal so we can also
++    // and go on.  we note this with _snuck so we can also
+       // pretend to unlock when the time comes.
+-      _suppress_signal = true;
+-    } else {
+-      check_block_state(thread);
+-      if (!thread->is_Java_thread()) {
+-	wait_for_lock_implementation();
+-      } else {	
+-	debug_only(assert(rank() > Mutex::special, 
+-	  "Potential deadlock with special or lesser rank mutex"));
+-	wait_for_lock_blocking_implementation((JavaThread*)thread);
+-      }
++    _snuck = true;
++    goto Exeunt ;
+     }
++
++  // Try a brief spin to avoid passing thru thread state transition ...
++  if (TrySpin (Self)) goto Exeunt ;
++
++  check_block_state(Self);
++  if (Self->is_Java_thread()) {
++    // Horribile dictu - we suffer through a state transition
++    assert(rank() > Mutex::special, "Potential deadlock with special or lesser rank mutex");
++    ThreadBlockInVM tbivm ((JavaThread *) Self) ;
++    ILock (Self) ;
++  } else {
++    // Mirabile dictu
++    ILock (Self) ;
+   }
++  goto Exeunt ;
++}
++
++void Monitor::lock() {
++  this->lock(Thread::current());
++}
++
++// Lock without safepoint check - a degenerate variant of lock().
++// Should ONLY be used by safepoint code and other code
++// that is guaranteed not to block while running inside the VM. If this is called with
++// thread state set to be in VM, the safepoint synchronization code will deadlock!
+ 
+-  assert(owner() == Mutex::INVALID_THREAD, "Mutex lock count and owner are inconsistent");
+-  set_owner(thread);
+-  trace("locks");  
++void Monitor::lock_without_safepoint_check (Thread * Self) {
++  assert (_owner != Self, "invariant") ;
++  ILock (Self) ;
++  assert (_owner == NULL, "invariant");
++  set_owner (Self);
+ }
+ 
+-void Mutex::lock() {
+-  Thread* thread = Thread::current();    
+-  this->lock(thread);
++void Monitor::lock_without_safepoint_check () {
++  lock_without_safepoint_check (Thread::current()) ;
+ }
+ 
+-// Returns true if thread succeceed in grabbing the lock, otherwise false.
+-bool Mutex::try_lock() {
+-  Thread* thread    = Thread::current();
+-  debug_only(check_prelock_state(thread));
++
++// Returns true if thread succeceed [sic] in grabbing the lock, otherwise false.
++
++bool Monitor::try_lock() {
++  Thread * const Self = Thread::current();
++  debug_only(check_prelock_state(Self));
+   // assert(!thread->is_inside_signal_handler(), "don't lock inside signal handler");
+ 
+-#ifdef ASSERT
+-  // Keep track of how many time access lock
+-  if (CountVMLocks) _histogram->increment_count();  
+-#endif
+-  // Special case, where all Java threads are stopped. The count is not -1, but the owner
+-  // is not yet set. In that case the VM thread can safely grab the lock.
+-  bool can_sneak = thread->is_VM_thread() &&
+-                   SafepointSynchronize::is_at_safepoint();
+-  if (can_sneak && _owner == INVALID_THREAD) {
+-    set_owner(thread); // Do not need to be atomic, since we are at a safepoint
+-    _suppress_signal = true;
++  // Special case, where all Java threads are stopped.
++  // The lock may have been acquired but _owner is not yet set.
++  // In that case the VM thread can safely grab the lock.
++  // It strikes me this should appear _after the TryLock() fails, below.
++  bool can_sneak = Self->is_VM_thread() && SafepointSynchronize::is_at_safepoint();
++  if (can_sneak && _owner == NULL) {
++    set_owner(Self); // Do not need to be atomic, since we are at a safepoint
++    _snuck = true;
+     return true;
+   }
+ 
+-  // The try_lock_implementation is platform-specific
+-  if (try_lock_implementation()) {
++  if (TryLock()) {
+     // We got the lock        
+-    assert(owner() == Mutex::INVALID_THREAD, "Mutex lock count and owner are inconsistent");
+-    set_owner(thread);
+-    trace("try_locks");
++    assert (_owner == NULL, "invariant");
++    set_owner (Self);
+     return true;
+-  } else {
+-#ifdef ASSERT
+-  // Keep track of how many times we fail 
+-  if (CountVMLocks) _contend_histogram->increment_count();  
+-#endif
++  }
+     return false;
++}
++
++void Monitor::unlock() {
++  assert (_owner  == Thread::current(), "invariant") ;
++  assert (_OnDeck != Thread::current()->_MutexEvent , "invariant") ;
++  set_owner (NULL) ;
++  if (_snuck) {
++    assert(SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread(), "sneak");
++    _snuck = false;
++    return ;
+   }
++  IUnlock (false) ;
+ }
+ 
+-// Lock without safepoint check. Should ONLY be used by safepoint code and other code
+-// that is guaranteed not to block while running inside the VM. If this is called with
+-// thread state set to be in VM, the safepoint synchronization code will deadlock!
++// Yet another degenerate version of Monitor::lock() or lock_without_safepoint_check()
++// jvm_raw_lock() and _unlock() can be called by non-Java threads via JVM_RawMonitorEnter.
++//
++// There's no expectation that JVM_RawMonitors will interoperate properly with the native
++// Mutex-Monitor constructs.  We happen to implement JVM_RawMonitors in terms of
++// native Mutex-Monitors simply as a matter of convenience.  A simple abstraction layer
++// over a pthread_mutex_t would work equally as well, but require more platform-specific
++// code -- a "PlatformMutex".  Alternatively, a simply layer over muxAcquire-muxRelease
++// would work too.
++//
++// Since the caller might be a foreign thread, we don't necessarily have a Thread.MutexEvent
++// instance available.  Instead, we transiently allocate a ParkEvent on-demand if
++// we encounter contention.  That ParkEvent remains associated with the thread
++// until it manages to acquire the lock, at which time we return the ParkEvent
++// to the global ParkEvent free list.  This is correct and suffices for our purposes.
++//
++// Beware that the original jvm_raw_unlock() had a "_snuck" test but that
++// jvm_raw_lock() didn't have the corresponding test.  I suspect that's an
++// oversight, but I've replicated the original suspect logic in the new code ...
++
++void Monitor::jvm_raw_lock() {
++  assert(rank() == native, "invariant");
++
++  if (TryLock()) {
++ Exeunt:
++    assert (ILocked(), "invariant") ;
++    assert (_owner == NULL, "invariant");
++    // This can potentially be called by non-java Threads. Thus, the ThreadLocalStorage
++    // might return NULL. Don't call set_owner since it will break on an NULL owner
++    // Consider installing a non-null "ANON" distinguished value instead of just NULL.
++    _owner = ThreadLocalStorage::thread();
++    return ;
++  }
+ 
+-void Mutex::lock_without_safepoint_check() {
+-#ifdef ASSERT
+-  // Keep track of how many time access lock
+-  if (CountVMLocks) _histogram->increment_count();  
+-#endif
+-  Thread* thread = Thread::current();
+-// #ifdef ASSERT
+-//   if (thread) {
+-//     assert(!thread->is_inside_signal_handler(), "don't lock inside signal handler");
+-//   }
+-// #endif
+-
+-  // lock_implementation is platform specific
+-  if (lock_implementation()) {
+-    // Success, we now own the lock
++  if (TrySpin(NULL)) goto Exeunt ;
++
++  // slow-path - apparent contention
++  // Allocate a ParkEvent for transient use.
++  // The ParkEvent remains associated with this thread until
++  // the time the thread manages to acquire the lock.
++  ParkEvent * const ESelf = ParkEvent::Allocate(NULL) ;
++  ESelf->reset() ;
++  OrderAccess::storeload() ;
++
++  // Either Enqueue Self on cxq or acquire the outer lock.
++  if (AcquireOrPush (ESelf)) {
++    ParkEvent::Release (ESelf) ;      // surrender the ParkEvent
++    goto Exeunt ;
++  }
++
++  // At any given time there is at most one ondeck thread.
++  // ondeck implies not resident on cxq and not resident on EntryList
++  // Only the OnDeck thread can try to acquire -- contended for -- the lock.
++  // CONSIDER: use Self->OnDeck instead of m->OnDeck.
++  for (;;) {
++    if (_OnDeck == ESelf && TrySpin(NULL)) break ;
++    ParkCommon (ESelf, 0) ;
++  }
++
++  assert (_OnDeck == ESelf, "invariant") ;
++  _OnDeck = NULL ;
++  ParkEvent::Release (ESelf) ;      // surrender the ParkEvent
++  goto Exeunt ;
++}
++
++void Monitor::jvm_raw_unlock() {
++  // Nearly the same as Monitor::unlock() ...
++  // directly set _owner instead of using set_owner(null)
++  _owner = NULL ;
++  if (_snuck) {         // ???
++    assert(SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread(), "sneak");
++    _snuck = false;
++    return ;
++  }
++  IUnlock(false) ;
++}
++
++bool Monitor::wait(bool no_safepoint_check, long timeout, bool as_suspend_equivalent) {
++  Thread * const Self = Thread::current() ;
++  assert (_owner == Self, "invariant") ;
++  assert (ILocked(), "invariant") ;
++
++  // as_suspend_equivalent logically implies !no_safepoint_check
++  guarantee (!as_suspend_equivalent || !no_safepoint_check, "invariant") ;
++  // !no_safepoint_check logically implies java_thread
++  guarantee (no_safepoint_check || Self->is_Java_thread(), "invariant") ;
++
++  #ifdef ASSERT
++    Monitor * least = get_least_ranked_lock_besides_this(Self->owned_locks());
++    assert(least != this, "Specification of get_least_... call above");
++    if (least != NULL && least->rank() <= special) {
++      tty->print("Attempting to wait on monitor %s/%d while holding"
++                 " lock %s/%d -- possible deadlock",
++                 name(), rank(), least->name(), least->rank());
++      assert(false, "Shouldn't block(wait) while holding a lock of rank special");
++    }
++  #endif // ASSERT
++
++  int wait_status ;
++  // conceptually set the owner to NULL in anticipation of
++  // abdicating the lock in wait
++  set_owner(NULL);
++  if (no_safepoint_check) {
++    wait_status = IWait (Self, timeout) ;
+   } else {    
+-#ifdef ASSERT
+-    // Keep track of how many times we fail 
+-    if (CountVMLocks) _contend_histogram->increment_count();  
+-#endif
+-    wait_for_lock_implementation();
++    assert (Self->is_Java_thread(), "invariant") ;
++    JavaThread *jt = (JavaThread *)Self;
++
++    // Enter safepoint region - ornate and Rococo ...
++    ThreadBlockInVM tbivm(jt);
++    OSThreadWaitState osts(Self->osthread(), false /* not Object.wait() */);
++
++    if (as_suspend_equivalent) {
++      jt->set_suspend_equivalent();
++      // cleared by handle_special_suspend_equivalent_condition() or
++      // java_suspend_self()
++    }
++
++    wait_status = IWait (Self, timeout) ;
++
++    // were we externally suspended while we were waiting?
++    if (as_suspend_equivalent && jt->handle_special_suspend_equivalent_condition()) {
++      // Our event wait has finished and we own the lock, but
++      // while we were waiting another thread suspended us. We don't
++      // want to hold the lock while suspended because that
++      // would surprise the thread that suspended us.
++      assert (ILocked(), "invariant") ;
++      IUnlock (true) ;
++      jt->java_suspend_self();
++      ILock (Self) ;
++      assert (ILocked(), "invariant") ;
++    }
+   }
+ 
+-  assert(_owner == INVALID_THREAD, "Mutex lock count and owner are inconsistent");
+-  set_owner(thread);
++  // Conceptually reestablish ownership of the lock.
++  // The "real" lock -- the LockByte -- was reacquired by IWait().
++  assert (ILocked(), "invariant") ;
++  assert (_owner == NULL, "invariant") ;
++  set_owner (Self) ;
++  return wait_status != 0 ;          // return true IFF timeout
+ }
+ 
++Monitor::~Monitor() {
++  assert ((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "") ;
++}
++
++void Monitor::ClearMonitor (Monitor * m) {
++  m->_owner             = NULL ;
++  m->_snuck             = false ;
++  m->_name              = "UNKNOWN" ;
++  m->_LockWord.FullWord = 0 ;
++  m->_EntryList         = NULL ;
++  m->_OnDeck            = NULL ;
++  m->_WaitSet           = NULL ;
++  m->_WaitLock[0]       = 0 ;
++}
+ 
+-// Can be called by non-Java threads (JVM_RawMonitorEnter)
+-void Mutex::jvm_raw_lock() {
++Monitor::Monitor() { ClearMonitor(this); }
++
++Monitor::Monitor (int Rank, const char * name, bool allow_vm_block) {
++  ClearMonitor (this) ;
+ #ifdef ASSERT
+-  // Keep track of how many time access lock
+-  if (CountVMLocks) _histogram->increment_count();  
++  _allow_vm_block  = allow_vm_block;
++  _rank            = Rank ;
+ #endif
+-  assert(rank() == native, "must be called by non-VM locks");
+-  if (lock_implementation()) {
+-    // Success, we now own the lock
+-  } else {    
++}
++
++Mutex::~Mutex() {
++  assert ((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "") ;
++}
++
++Mutex::Mutex (int Rank, const char * name, bool allow_vm_block) {
++  ClearMonitor ((Monitor *) this) ;
+ #ifdef ASSERT
+-    // Keep track of how many times we fail 
+-    if (CountVMLocks) _contend_histogram->increment_count();  
++ _allow_vm_block   = allow_vm_block;
++ _rank             = Rank ;
+ #endif
+-    wait_for_lock_implementation();
+-  }
+-  assert(_owner == INVALID_THREAD, "Mutex lock count and owner are inconsistent");
+-  // This can potentially be called by non-java Threads. Thus, the ThreadLocalStorage
+-  // might return NULL. Don't call set_owner since it will break on an NULL
+-  // owner
+-  _owner = ThreadLocalStorage::thread();
+ }
+ 
+-bool Mutex::owned_by_self() const { 
++bool Monitor::owned_by_self() const {
+   bool ret = _owner == Thread::current(); 
+-  assert(_lock_count>=0 || !ret, "lock count must by >=0 for a locked mutex");
++  assert (!ret || _LockWord.Bytes[_LSBINDEX] != 0, "invariant") ;
+   return ret;
+ }
+ 
+-void Mutex::print_on_error(outputStream* st) const {
++void Monitor::print_on_error(outputStream* st) const {
+   st->print("[" PTR_FORMAT, this);
+-  st->print("/" PTR_FORMAT, _lock_event);
+   st->print("] %s", _name);
+   st->print(" - owner thread: " PTR_FORMAT, _owner);
+ }
+ 
++
++
++
+ // ----------------------------------------------------------------------------------
+ // Non-product code
+ 
++#ifndef PRODUCT
++void Monitor::print_on(outputStream* st) const {
++  st->print_cr("Mutex: [0x%lx/0x%lx] %s - owner: 0x%lx", this, _LockWord.FullWord, _name, _owner);
++}
++#endif
+ 
+ #ifndef PRODUCT
+ #ifdef ASSERT
+-Mutex* Mutex::get_least_ranked_lock(Mutex* locks) {
+-  Mutex *res, *tmp;
++Monitor * Monitor::get_least_ranked_lock(Monitor * locks) {
++  Monitor *res, *tmp;
+   for (res = tmp = locks; tmp != NULL; tmp = tmp->next()) {
+     if (tmp->rank() < res->rank()) {
+       res = tmp;
+@@ -285,8 +1198,8 @@
+   return res;
+ }
+ 
+-Mutex* Mutex::get_least_ranked_lock_besides_this(Mutex* locks) {
+-  Mutex *res, *tmp;
++Monitor* Monitor::get_least_ranked_lock_besides_this(Monitor* locks) {
++  Monitor *res, *tmp;
+   for (res = NULL, tmp = locks; tmp != NULL; tmp = tmp->next()) {
+     if (tmp != this && (res == NULL || tmp->rank() < res->rank())) {
+       res = tmp;
+@@ -306,7 +1219,7 @@
+ }
+ 
+ 
+-bool Mutex::contains(Mutex* locks, Mutex* lock) {
++bool Monitor::contains(Monitor* locks, Monitor * lock) {
+   for (; locks != NULL; locks = locks->next()) {
+     if (locks == lock)
+       return true;
+@@ -315,7 +1228,12 @@
+ }
+ #endif
+ 
+-void Mutex::set_owner_implementation(Thread *new_owner) {  
++// Called immediately after lock acquisition or release as a diagnostic
++// to track the lock-set of the thread and test for rank violations that
++// might indicate exposure to deadlock.
++// Rather like an EventListener for _owner (:>).
++
++void Monitor::set_owner_implementation(Thread *new_owner) {
+   // This function is solely responsible for maintaining
+   // and checking the invariant that threads and locks
+   // are in a 1/N relation, with some some locks unowned.
+@@ -326,17 +1244,17 @@
+   // owner to another--it must be owned by NULL as an
+   // intermediate state.
+ 
+-  if (new_owner != INVALID_THREAD) {
++  if (new_owner != NULL) {
+     // the thread is acquiring this lock
+  
+     assert(new_owner == Thread::current(), "Should I be doing this?");
+-    assert(_owner == INVALID_THREAD, "setting the owner thread of an already owned mutex");
++    assert(_owner == NULL, "setting the owner thread of an already owned mutex");
+     _owner = new_owner; // set the owner
+ 
+     // link "this" into the owned locks list
+ 
+     #ifdef ASSERT  // Thread::_owned_locks is under the same ifdef
+-      Mutex* locks = get_least_ranked_lock(new_owner->owned_locks());
++      Monitor* locks = get_least_ranked_lock(new_owner->owned_locks());
+                     // Mutex::set_owner_implementation is a friend of Thread
+ 
+       assert(this->rank() >= 0, "bad lock rank");
+@@ -379,13 +1297,13 @@
+     Thread* old_owner = _owner;
+     debug_only(_last_owner = old_owner);
+     
+-    assert(old_owner != INVALID_THREAD, "removing the owner thread of an unowned mutex");
++    assert(old_owner != NULL, "removing the owner thread of an unowned mutex");
+     assert(old_owner == Thread::current(), "removing the owner thread of an unowned mutex");
+ 
+-    _owner = INVALID_THREAD; // set the owner
++    _owner = NULL; // set the owner
+ 
+     #ifdef ASSERT
+-      Mutex *locks = old_owner->owned_locks();
++      Monitor *locks = old_owner->owned_locks();
+ 
+       if (LogMultipleMutexLocking && locks != this) {
+         Events::log("thread " INTPTR_FORMAT " unlocks %s, still owns %s", old_owner, this->name(), locks->name());
+@@ -393,7 +1311,7 @@
+   
+       // remove "this" from the owned locks list
+   
+-      Mutex *prev = NULL;
++      Monitor *prev = NULL;
+       bool found = false;
+       for (; locks != NULL; prev = locks, locks = locks->next()) {
+         if (locks == this) {
+@@ -414,8 +1332,7 @@
+ 
+ 
+ // Factored out common sanity checks for locking mutex'es. Used by lock() and try_lock()
+-void Mutex::check_prelock_state(Thread *thread) {
+-  assert(_lock_count >= -1, "sanity check");  
++void Monitor::check_prelock_state(Thread *thread) {
+   assert((!thread->is_Java_thread() || ((JavaThread *)thread)->thread_state() == _thread_in_vm) 
+          || rank() == Mutex::special, "wrong thread state for using locks");
+   if (StrictSafepointChecks) { 
+@@ -427,7 +1344,7 @@
+   }
+ }
+ 
+-void Mutex::check_block_state(Thread *thread) {  
++void Monitor::check_block_state(Thread *thread) {
+   if (!_allow_vm_block && thread->is_VM_thread()) {
+     warning("VM thread blocked on lock");
+     print();
+@@ -436,8 +1353,4 @@
+   assert(_owner != thread, "deadlock: blocking on monitor owned by current thread");    
+ }
+ 
+-
+-void Mutex::trace(const char* operation) {
+-}
+-
+ #endif // PRODUCT
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/mutex.hpp openjdk/hotspot/src/share/vm/runtime/mutex.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/mutex.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/mutex.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)mutex.hpp	1.68 07/05/05 17:06:50 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -25,49 +22,71 @@
+  *  
+  */
+ 
+-#ifdef  ASSERT
+-class MutexHistogramElement : public HistogramElement {
+-  public:
+-   MutexHistogramElement(const char* elementname);
+-};
+-
+-class MutexContentionHistogramElement : public HistogramElement {
+-  public:
+-   MutexContentionHistogramElement(const char* elementname);
+-};
+-
+-
+-#endif
+-
+-// A simple Mutex for VM locking using OS primitives.  Note that
+-// Mutex locking is NOT guaranteed to interoperate with the fast
+-// object locking, which is intentional: it reduces reliance on the
+-// fast locking mechanism as it is developed and tuned, and gives us
+-// a way out of all the recursive locking rat-holes that appear when
+-// we try to use a single locking mechanism.
+-//
+-// Implementation adapted from WIN32 Q&A by Jeffery Richter
+-// (implementation should be moved into platform specific file)
++// The SplitWord construct allows us to colocate the contention queue
++// (cxq) with the lock-byte.  The queue elements are ParkEvents, which are
++// always aligned on 256-byte addresses - the least significant byte of
++// a ParkEvent is always 0.  Colocating the lock-byte with the queue
++// allows us to easily avoid what would otherwise be a race in lock()
++// if we were to use two completely separate fields for the contention queue
++// and the lock indicator.  Specifically, colocation renders us immune
++// from the race where a thread might enqueue itself in the lock() slow-path
++// immediately after the lock holder drops the outer lock in the unlock()
++// fast-path.
+ //
++// Colocation allows us to use a fast-path unlock() form that uses
++// A MEMBAR instead of a CAS.  MEMBAR has lower local latency than CAS
++// on many platforms.
+ //
+-//                NOTE WELL!!
++// See:
++// +  http://blogs.sun.com/dave/entry/biased_locking_in_hotspot
++// +  http://blogs.sun.com/dave/resource/synchronization-public2.pdf
+ //
++// Note that we're *not* using word-tearing the classic sense.
++// The lock() fast-path will CAS the lockword and the unlock()
++// fast-path will store into the lock-byte colocated within the lockword.
++// We depend on the fact that all our reference platforms have
++// coherent and atomic byte accesses.  More precisely, byte stores
++// interoperate in a safe, sane, and expected manner with respect to
++// CAS, ST and LDs to the full-word containing the byte.
++// If you're porting HotSpot to a platform where that isn't the case
++// then you'll want change the unlock() fast path from:
++//    STB;MEMBAR #storeload; LDN
++// to a full-word CAS of the lockword.
++
++
++union SplitWord {   // full-word with separately addressable LSB
++  volatile intptr_t FullWord ;
++  volatile void * Address ;
++  volatile jbyte Bytes [sizeof(intptr_t)] ;
++} ;
++
++// Endian-ness ... index of least-significant byte in SplitWord.Bytes[]
++#ifdef AMD64        // little
++ #define _LSBINDEX 0
++#else
++#if IA32            // little
++ #define _LSBINDEX 0
++#else
++#ifdef SPARC        // big
++ #define _LSBINDEX (sizeof(intptr_t)-1)
++#else
++ #error "unknown architecture"
++#endif
++#endif
++#endif
++
++class ParkEvent ;
++
+ // See orderAccess.hpp.  We assume throughout the VM that mutex lock and
+ // try_lock do fence-lock-acquire, and that unlock does a release-unlock,
+ // *in that order*.  If their implementations change such that these
+ // assumptions are violated, a whole lot of code will break.
+ 
+-class Mutex : public CHeapObj {
+- private:
+-  // The following methods are machine-specific, and defined in mutex_<os>.inline.hpp or mutex_<os>.cpp
+-  bool lock_implementation();
+-  bool try_lock_implementation();
+-  void wait_for_lock_implementation();
+-  void wait_for_lock_blocking_implementation(JavaThread *thread);
++class Monitor : public CHeapObj {
+ 
+  public:
+-  // A special lock: Is a lock where you are guarantteed not to block while you are holding it, i.e., no
+-  // vm operation can happen, taking other locks, etc. 
++  // A special lock: Is a lock where you are guaranteed not to block while you are
++  // holding it, i.e., no vm operation can happen, taking other locks, etc.
+   // NOTE: It is critical that the rank 'special' be the lowest (earliest)
+   // (except for "event"?) for the deadlock dection to work correctly.
+   // The rank native is only for use in Mutex's created by JVM_RawMonitorCreate,
+@@ -91,37 +110,42 @@
+        native      = max_nonleaf    +   1
+   };
+ 
+- protected:     
+-  // Fields
+-  jint              _lock_count; 
+-  void*             _lock_event;  
+-  volatile bool     _suppress_signal;    // Used for sneaky locking
+-  Thread* volatile  _owner;              // The owner of the lock
+-  const char* _name;                     // Name of mutex  
+-#ifdef ASSERT
+-  MutexHistogramElement *_histogram;
+-  MutexContentionHistogramElement *_contend_histogram;
+-#endif
++  // The WaitSet and EntryList linked lists are composed of ParkEvents.
++  // I use ParkEvent instead of threads as ParkEvents are immortal and
++  // type-stable, meaning we can safely unpark() a possibly stale
++  // list element in the unlock()-path.
++
++ protected:                              // Monitor-Mutex metadata
++  SplitWord _LockWord ;                  // Contention queue (cxq) colocated with Lock-byte
++  enum LockWordBits { _LBIT=1 } ;
++  Thread * volatile _owner;              // The owner of the lock
++                                         // Consider sequestering _owner on its own $line
++                                         // to aid future synchronization mechanisms.
++  ParkEvent * volatile _EntryList ;      // List of threads waiting for entry
++  ParkEvent * volatile _OnDeck ;         // heir-presumptive
++  volatile intptr_t _WaitLock [1] ;      // Protects _WaitSet
++  ParkEvent * volatile  _WaitSet ;       // LL of ParkEvents
++  volatile bool     _snuck;              // Used for sneaky locking (evil).
++  const char * _name;                    // Name of mutex
++  int NotifyCount ;                      // diagnostic assist
++  double pad [8] ;                       // avoid false sharing
+ 
+   // Debugging fields for naming, deadlock detection, etc. (some only used in debug mode)
+ #ifndef PRODUCT
+   bool      _allow_vm_block;
+   debug_only(int _rank;)     	   // rank (to avoid/detect potential deadlocks)
+-  debug_only(Mutex* _next;)        // Used by a Thread to link up owned locks    
++  debug_only(Monitor * _next;)           // Used by a Thread to link up owned locks
+   debug_only(Thread* _last_owner;) // the last thread to own the lock    
+-  debug_only(static bool contains(Mutex* locks, Mutex* lock);)
+-  debug_only(static Mutex* get_least_ranked_lock(Mutex* locks);)
+-  debug_only(Mutex* get_least_ranked_lock_besides_this(Mutex* locks);)
++  debug_only(static bool contains(Monitor * locks, Monitor * lock);)
++  debug_only(static Monitor * get_least_ranked_lock(Monitor * locks);)
++  debug_only(Monitor * get_least_ranked_lock_besides_this(Monitor * locks);)
+ #endif
+   
+   void set_owner_implementation(Thread* owner)                        PRODUCT_RETURN;
+-  void trace                   (const char* operation)                PRODUCT_RETURN;
+   void check_prelock_state     (Thread* thread)                       PRODUCT_RETURN;
+   void check_block_state       (Thread* thread)                       PRODUCT_RETURN;
+ 
+   // platform-dependent support code can go here (in os_<os_family>.cpp)
+-  friend class MutexImplementation;
+-  friend class RawMonitor;
+  public:
+   enum {
+     _no_safepoint_check_flag    = true,
+@@ -129,19 +153,52 @@
+     _as_suspend_equivalent_flag = true
+   };	
+ 
+-  Mutex(int rank, const char *name, bool allow_vm_block = !_allow_vm_block_flag);
+-  ~Mutex();
++  enum WaitResults {
++    CONDVAR_EVENT,         // Wait returned because of condition variable notification
++    INTERRUPT_EVENT,       // Wait returned because waiting thread was interrupted
++    NUMBER_WAIT_RESULTS
++  };
++
++ private:
++   int  TrySpin (Thread * Self) ;
++   int  TryLock () ;
++   int  TryFast () ;
++   int  AcquireOrPush (ParkEvent * ev) ;
++   void IUnlock (bool RelaxAssert) ;
++   void ILock (Thread * Self) ;
++   int  IWait (Thread * Self, jlong timo);
++   int  ILocked () ;
++
++ protected:
++   static void ClearMonitor (Monitor * m) ;
++   Monitor() ;
++
++ public:
++  Monitor(int rank, const char *name, bool allow_vm_block=false);
++  ~Monitor();
++
++  // Wait until monitor is notified (or times out).
++  // Defaults are to make safepoint checks, wait time is forever (i.e.,
++  // zero), and not a suspend-equivalent condition. Returns true if wait
++  // times out; otherwise returns false.
++  bool wait(bool no_safepoint_check = !_no_safepoint_check_flag,
++            long timeout = 0,
++            bool as_suspend_equivalent = !_as_suspend_equivalent_flag);
++  bool notify();
++  bool notify_all();
++
+   
+   void lock(); // prints out warning if VM thread blocks 
+   void lock(Thread *thread); // overloaded with current thread
+   void unlock();
+-  bool is_locked() const                     { return _owner != INVALID_THREAD; }
++  bool is_locked() const                     { return _owner != NULL; }
+ 
+   bool try_lock(); // Like lock(), but unblocking. It returns false instead
+ 
+   // Lock without safepoint check. Should ONLY be used by safepoint code and other code
+   // that is guaranteed not to block while running inside the VM.
+   void lock_without_safepoint_check();    
++  void lock_without_safepoint_check (Thread * Self) ;
+ 
+   // Current owner - not not MT-safe. Can only be used to guarantee that
+   // the current running thread owns the lock
+@@ -162,52 +219,56 @@
+     debug_only(int    rank() const          { return _rank; })
+     bool   allow_vm_block()                 { return _allow_vm_block; }
+     
+-    debug_only(Mutex *next()  const         { return _next; }) 
+-    debug_only(void   set_next(Mutex *next) { _next = next; })       
++    debug_only(Monitor *next()  const         { return _next; })
++    debug_only(void   set_next(Monitor *next) { _next = next; })
+   #endif
+   
+   void set_owner(Thread* owner) {
+   #ifndef PRODUCT
+     set_owner_implementation(owner);
+-    debug_only(void verify_mutex_rank(Thread* thr));
++    debug_only(void verify_Monitor(Thread* thr));
+   #else  
+     _owner = owner;
+   #endif
+   }
+ 
+-  static Thread* INVALID_THREAD; // Value of _owner when unowned. (i.e., lock is unlocked)
+ };
+ 
++// Normally we'd expect Monitor to extend Mutex in the sense that a monitor
++// constructed from pthreads primitives might extend a mutex by adding
++// a condvar and some extra metadata.  In fact this was the case until J2SE7.
++//
++// Currently, however, the base object is a monitor.  Monitor contains all the
++// logic for wait(), notify(), etc.   Mutex extends monitor and restricts the
++// visiblity of wait(), notify(), and notify_all().
++//
++// Another viable alternative would have been to have Monitor extend Mutex and
++// implement all the normal mutex and wait()-notify() logic in Mutex base class.
++// The wait()-notify() facility would be exposed via special protected member functions
++// (e.g., _Wait() and _Notify()) in Mutex.  Monitor would extend Mutex and expose wait()
++// as a call to _Wait().  That is, the public wait() would be a wrapper for the protected
++// _Wait().
++//
++// An even better alternative is to simply eliminate Mutex:: and use Monitor:: instead.
++// After all, monitors are sufficient for Java-level synchronization.   At one point in time
++// there may have been some benefit to having distinct mutexes and monitors, but that time
++// has past.
++//
++// The Mutex/Monitor design parallels that of Java-monitors, being based on
++// thread-specific park-unpark platform-specific primitives.
+ 
+-// A Monitor is a Mutex with a built in condition variable. It allows a thread, to
+-// temporarily to give up the lock and wait on the lock, until it is notified.
+-class Monitor : public Mutex {
+- protected:
+-  void* _event; 	// Manual-reset event for notifications
+-  long _counter;	// Current number of notifications
+-  long _waiters;	// Number of threads waiting for notification
+-  long _tickets;	// Number of waiters to be notified
+-
+-  enum WaitResults {
+-    CONDVAR_EVENT,         // Wait returned because of condition variable notification
+-    INTERRUPT_EVENT,       // Wait returned because waiting thread was interrupted
+-    NUMBER_WAIT_RESULTS
+-  };
+ 
+-  friend class RawMonitor;
++class Mutex : public Monitor {      // degenerate Monitor
+  public:
+-  Monitor(int rank, const char *name, bool allow_vm_block=false);
+-  ~Monitor();
+-
+-  // Wait until monitor is notified (or times out).
+-  // Defaults are to make safepoint checks, wait time is forever (i.e.,
+-  // zero), and not a suspend-equivalent condition. Returns true if wait
+-  // times out; otherwise returns false.
+-  bool wait(bool no_safepoint_check = !_no_safepoint_check_flag,
+-            long timeout = 0,
+-            bool as_suspend_equivalent = !_as_suspend_equivalent_flag);
+-  bool notify();
+-  bool notify_all();
++   Mutex (int rank, const char *name, bool allow_vm_block=false);
++   ~Mutex () ;
++ private:
++   bool notify ()    { ShouldNotReachHere(); return false; }
++   bool notify_all() { ShouldNotReachHere(); return false; }
++   bool wait (bool no_safepoint_check, long timeout, bool as_suspend_equivalent) {
++     ShouldNotReachHere() ;
++     return false ;
++   }
+ };
+ 
+ /*
+@@ -218,12 +279,12 @@
+  * 6271289 --
+  * To avoid errors where an os thread expires but the JavaThread still
+  * exists, Parkers are immortal (type-stable) and are recycled across 
+- * new threads.  This parallels the Event and ParkEvent implementation.
+- * Because park-unpark alow spurious wakeups it is harmless if an
++ * new threads.  This parallels the ParkEvent implementation.
++ * Because park-unpark allow spurious wakeups it is harmless if an
+  * unpark call unparks a new thread using the old Parker reference.  
+  *
+  * In the future we'll want to think about eliminating Parker and using
+- * ParkEvent instead.  There's consider duplication between the two
++ * ParkEvent instead.  There's considerable duplication between the two
+  * services.  
+  *
+  */
+@@ -255,4 +316,3 @@
+   static Parker * volatile FreeList ;
+   static volatile int ListLock ;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/mutexLocker.cpp openjdk/hotspot/src/share/vm/runtime/mutexLocker.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/mutexLocker.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/mutexLocker.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)mutexLocker.cpp	1.178 07/06/19 03:54:19 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -28,7 +25,13 @@
+ #include "incls/_precompiled.incl"
+ #include "incls/_mutexLocker.cpp.incl"
+ 
+-// Mutexes used in the VM (see comment in mutexLocker.hpp)
++// Mutexes used in the VM (see comment in mutexLocker.hpp):
++//
++// Note that the following pointers are effectively final -- after having been
++// set at JVM startup-time, they should never be subsequently mutated.
++// Instead of using pointers to malloc()ed monitors and mutexes we should consider
++// eliminating the indirection and using instances instead.
++// Consider using GCC's __read_mostly.
+ 
+ Mutex*   Patching_lock                = NULL;
+ Monitor* SystemDictionary_lock        = NULL;
+@@ -105,11 +108,11 @@
+ Monitor* LowMemory_lock               = NULL;
+ 
+ #define MAX_NUM_MUTEX 128
+-static Mutex* _mutex_array[MAX_NUM_MUTEX];
++static Monitor * _mutex_array[MAX_NUM_MUTEX];
+ static int _num_mutex;
+ 
+ #ifdef ASSERT
+-void assert_locked_or_safepoint(const Mutex* lock) {
++void assert_locked_or_safepoint(const Monitor * lock) {
+   // check if this thread owns the lock (common case)
+   if (IgnoreLockingAssertions) return;
+   assert(lock != NULL, "Need non-NULL lock");
+@@ -123,7 +126,7 @@
+ }
+ 
+ // a stronger assertion than the above
+-void assert_lock_strong(const Mutex* lock) {
++void assert_lock_strong(const Monitor * lock) {
+   if (IgnoreLockingAssertions) return;
+   assert(lock != NULL, "Need non-NULL lock");
+   if (lock->owned_by_self()) return;
+@@ -232,7 +235,7 @@
+ 
+ }
+ 
+-GCMutexLocker::GCMutexLocker(Mutex* mutex) {
++GCMutexLocker::GCMutexLocker(Monitor * mutex) {
+   if (SafepointSynchronize::is_at_safepoint()) {
+     _locked = false;
+   } else {
+@@ -249,7 +252,7 @@
+   bool none = true;
+   for (int i = 0; i < _num_mutex; i++) {
+      // see if it has an owner
+-     if (_mutex_array[i]->owner() != Mutex::INVALID_THREAD) {
++     if (_mutex_array[i]->owner() != NULL) {
+        if (none) {
+           // print format used by Mutex::print_on_error()
+           st->print_cr(" ([mutex/lock_event])");
+@@ -261,4 +264,3 @@
+   }
+   if (none) st->print_cr("None");
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/mutexLocker.hpp openjdk/hotspot/src/share/vm/runtime/mutexLocker.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/mutexLocker.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/mutexLocker.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)mutexLocker.hpp	1.150 07/06/19 03:54:12 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -122,9 +119,9 @@
+ 
+ class MutexLocker: StackObj {
+  private:
+-  Mutex* _mutex;
++  Monitor * _mutex;
+  public:
+-  MutexLocker(Mutex* mutex) {
++  MutexLocker(Monitor * mutex) {
+     assert(mutex->rank() != Mutex::special,
+       "Special ranked mutex should only use MutexLockerEx");
+     _mutex = mutex;
+@@ -132,7 +129,7 @@
+   }
+ 
+   // Overloaded constructor passing current thread
+-  MutexLocker(Mutex* mutex, Thread *thread) {
++  MutexLocker(Monitor * mutex, Thread *thread) {
+     assert(mutex->rank() != Mutex::special,
+       "Special ranked mutex should only use MutexLockerEx");
+     _mutex = mutex;
+@@ -147,8 +144,8 @@
+ 
+ // for debugging: check that we're already owning this lock (or are at a safepoint)
+ #ifdef ASSERT
+-void assert_locked_or_safepoint(const Mutex* lock);
+-void assert_lock_strong(const Mutex* lock);
++void assert_locked_or_safepoint(const Monitor * lock);
++void assert_lock_strong(const Monitor * lock);
+ #else
+ #define assert_locked_or_safepoint(lock)
+ #define assert_lock_strong(lock)
+@@ -163,9 +160,9 @@
+ 
+ class MutexLockerEx: public StackObj {
+  private:
+-  Mutex* _mutex;
++  Monitor * _mutex;
+  public:
+-  MutexLockerEx(Mutex* mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) {
++  MutexLockerEx(Monitor * mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) {
+     _mutex = mutex;
+     if (_mutex != NULL) {
+       assert(mutex->rank() > Mutex::special || no_safepoint_check,
+@@ -190,7 +187,7 @@
+ 
+ class MonitorLockerEx: public MutexLockerEx {
+  private:
+-  Monitor* _monitor;
++  Monitor * _monitor;
+  public:
+   MonitorLockerEx(Monitor* monitor,
+                   bool no_safepoint_check = !Mutex::_no_safepoint_check_flag):
+@@ -242,10 +239,10 @@
+ 
+ class GCMutexLocker: public StackObj {
+ private:
+-  Mutex* _mutex;
++  Monitor * _mutex;
+   bool _locked;
+ public:
+-  GCMutexLocker(Mutex* mutex);
++  GCMutexLocker(Monitor * mutex);
+   ~GCMutexLocker() { if (_locked) _mutex->unlock(); }
+ };
+ 
+@@ -256,10 +253,10 @@
+ 
+ class MutexUnlocker: StackObj {
+  private:
+-  Mutex* _mutex;
++  Monitor * _mutex;
+ 
+  public:
+-  MutexUnlocker(Mutex* mutex) {
++  MutexUnlocker(Monitor * mutex) {
+     _mutex = mutex;
+     _mutex->unlock();
+   }
+@@ -274,11 +271,11 @@
+ 
+ class MutexUnlockerEx: StackObj {
+  private:
+-  Mutex* _mutex;
++  Monitor * _mutex;
+   bool _no_safepoint_check;
+ 
+  public:
+-  MutexUnlockerEx(Mutex* mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) {
++  MutexUnlockerEx(Monitor * mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) {
+     _mutex = mutex;
+     _no_safepoint_check = no_safepoint_check;
+     _mutex->unlock();
+@@ -305,10 +302,10 @@
+ //
+ class VerifyMutexLocker: StackObj {
+  private:
+-  Mutex* _mutex;
++  Monitor * _mutex;
+   bool   _reentrant;
+  public:
+-  VerifyMutexLocker(Mutex* mutex) {
++  VerifyMutexLocker(Monitor * mutex) {
+     _mutex     = mutex;
+     _reentrant = mutex->owned_by_self();
+     if (!_reentrant) {
+@@ -326,4 +323,3 @@
+ };
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/objectMonitor.hpp openjdk/hotspot/src/share/vm/runtime/objectMonitor.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/objectMonitor.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/objectMonitor.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)objectMonitor.hpp	1.41 07/05/17 16:06:18 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -159,7 +156,6 @@
+  private:
+   friend class ObjectSynchronizer;
+   friend class ObjectWaiter;
+-  friend class RawMonitor;
+   friend class VMStructs;
+ 
+   // WARNING: this must be the very first word of ObjectMonitor
+@@ -210,7 +206,3 @@
+   intptr_t StatA, StatsB ; 
+ 
+ };
+-
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/objectMonitor.inline.hpp openjdk/hotspot/src/share/vm/runtime/objectMonitor.inline.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/objectMonitor.inline.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/objectMonitor.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)objectMonitor.inline.hpp	1.24 07/05/05 17:06:52 JVM"
+-#endif
+ /*
+  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/orderAccess.cpp openjdk/hotspot/src/share/vm/runtime/orderAccess.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/orderAccess.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/orderAccess.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)orderAccess.cpp	1.9 07/05/05 17:06:53 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/orderAccess.hpp openjdk/hotspot/src/share/vm/runtime/orderAccess.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/orderAccess.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/orderAccess.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)orderAccess.hpp	1.11 07/05/05 17:06:52 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/os.cpp openjdk/hotspot/src/share/vm/runtime/os.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/os.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/os.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)os.cpp	1.183 07/06/19 03:53:14 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -39,6 +36,8 @@
+ volatile jlong    os::_global_time        = 0;
+ volatile int      os::_global_time_lock   = 0;
+ bool              os::_use_global_time    = false;
++size_t            os::_page_sizes[os::page_sizes_max];
++
+ #ifndef PRODUCT
+ int os::num_mallocs = 0;            // # of calls to malloc/realloc
+ size_t os::alloc_bytes = 0;         // # of bytes allocated
+@@ -1013,7 +1012,7 @@
+   // handler or a println uses at least 8k stack of VM and native code
+   // respectively.
+   const int framesize_in_bytes =
+-    AbstractInterpreter::size_top_interpreter_activation(method()) * wordSize;
++    Interpreter::size_top_interpreter_activation(method()) * wordSize;
+   int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages) 
+                       * vm_page_size()) + framesize_in_bytes;
+   // The very lower end of the stack
+@@ -1021,6 +1020,46 @@
+   return (sp > (stack_limit + reserved_area));
+ }
+ 
++size_t os::page_size_for_region(size_t region_min_size, size_t region_max_size,
++                                uint min_pages)
++{
++  assert(min_pages > 0, "sanity");
++  if (UseLargePages) {
++    const size_t max_page_size = region_max_size / min_pages;
++
++    for (unsigned int i = 0; _page_sizes[i] != 0; ++i) {
++      const size_t sz = _page_sizes[i];
++      const size_t mask = sz - 1;
++      if ((region_min_size & mask) == 0 && (region_max_size & mask) == 0) {
++        // The largest page size with no fragmentation.
++        return sz;
++      }
++
++      if (sz <= max_page_size) {
++        // The largest page size that satisfies the min_pages requirement.
++        return sz;
++      }
++    }
++  }
++
++  return vm_page_size();
++}
++
++#ifndef PRODUCT
++void os::trace_page_sizes(const char* str, const size_t region_min_size,
++                          const size_t region_max_size, const size_t page_size,
++                          const char* base, const size_t size)
++{
++  if (TracePageSizes) {
++    tty->print_cr("%s:  min=" SIZE_FORMAT " max=" SIZE_FORMAT
++                  " pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT
++                  " size=" SIZE_FORMAT,
++                  str, region_min_size, region_max_size,
++                  page_size, base, size);
++  }
++}
++#endif  // #ifndef PRODUCT
++
+ // This is the working definition of a server class machine:
+ // >= 2 physical CPU's and >=2GB of memory, with some fuzz 
+ // because the graphics memory (?) sometimes masks physical memory.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/os.hpp openjdk/hotspot/src/share/vm/runtime/os.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/os.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/os.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)os.hpp	1.220 07/06/19 03:53:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -63,6 +60,8 @@
+ 
+ class os: AllStatic {
+  private:
++  enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel)
++
+   static OSThread*          _starting_thread;
+   static address            _polling_page;
+   static volatile int32_t * _mem_serialize_page;
+@@ -70,6 +69,13 @@
+   static volatile jlong     _global_time;
+   static volatile int       _global_time_lock;
+   static bool               _use_global_time;
++  static size_t             _page_sizes[page_sizes_max];
++
++  static void init_page_sizes(size_t default_page_size) {
++    _page_sizes[0] = default_page_size;
++    _page_sizes[1] = 0; // sentinel
++  }
++
+  public:
+ 
+   static void init(void);			// Called before command line parsing
+@@ -155,9 +161,38 @@
+   static bool stack_shadow_pages_available(Thread *thread, methodHandle method);
+ 
+   // OS interface to Virtual Memory
++
++  // Return the default page size.
+   static int    vm_page_size();
++
++  // Return the page size to use for a region of memory.  The min_pages argument
++  // is a hint intended to limit fragmentation; it says the returned page size
++  // should be <= region_max_size / min_pages.  Because min_pages is a hint,
++  // this routine may return a size larger than region_max_size / min_pages.
++  //
++  // The current implementation ignores min_pages if a larger page size is an
++  // exact multiple of both region_min_size and region_max_size.  This allows
++  // larger pages to be used when doing so would not cause fragmentation; in
++  // particular, a single page can be used when region_min_size ==
++  // region_max_size == a supported page size.
++  static size_t page_size_for_region(size_t region_min_size,
++                                     size_t region_max_size,
++                                     uint min_pages);
++
++  // Method for tracing page sizes returned by the above method; enabled by
++  // TracePageSizes.  The region_{min,max}_size parameters should be the values
++  // passed to page_size_for_region() and page_size should be the result of that
++  // call.  The (optional) base and size parameters should come from the
++  // ReservedSpace base() and size() methods.
++  static void trace_page_sizes(const char* str, const size_t region_min_size,
++                               const size_t region_max_size,
++                               const size_t page_size,
++                               const char* base = NULL,
++                               const size_t size = 0) PRODUCT_RETURN;
++
+   static int    vm_allocation_granularity();
+-  static char*  reserve_memory(size_t bytes, char* addr = 0);
++  static char*  reserve_memory(size_t bytes, char* addr = 0,
++                               size_t alignment_hint = 0);
+   static char*  attempt_reserve_memory_at(size_t bytes, char* addr);
+   static void   split_reserved_memory(char *base, size_t size,
+                                       size_t split, bool realloc);
+@@ -292,7 +327,15 @@
+   static int naked_sleep();
+   static void infinite_sleep(); // never returns, use with CAUTION
+   static void yield();        // Yields to all threads with same priority
+-  static void NakedYield () ; 
++  enum YieldResult {
++    YIELD_SWITCHED = 1,         // caller descheduled, other ready threads exist & ran
++    YIELD_NONEREADY = 0,        // No other runnable/ready threads.
++                                // platform-specific yield return immediately
++    YIELD_UNKNOWN = -1          // Unknown: platform doesn't support _SWITCHED or _NONEREADY
++    // YIELD_SWITCHED and YIELD_NONREADY imply the platform supports a "strong"
++    // yield that can be used in lieu of blocking.
++  } ;
++  static YieldResult NakedYield () ;
+   static void yield_all(int attempts = 0); // Yields to all other threads including lower priority
+   static void loop_breaker(int attempts);  // called from within tight loops to possibly influence time-sharing
+   static OSReturn set_priority(Thread* thread, ThreadPriority priority);
+@@ -316,6 +359,9 @@
+   static int message_box(const char* title, const char* message);
+   static char* do_you_want_to_debug(const char* message);
+ 
++  // run cmd in a separate process and return its exit code; or -1 on failures
++  static int fork_and_exec(char *cmd);
++
+   // Set file to send error reports.
+   static void set_error_file(const char *logfile);
+ 
+@@ -548,5 +594,3 @@
+ extern "C" int SpinPause () ; 
+ extern "C" int SafeFetch32 (int * adr, int errValue) ; 
+ extern "C" intptr_t SafeFetchN (intptr_t * adr, intptr_t errValue) ; 
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/osThread.cpp openjdk/hotspot/src/share/vm/runtime/osThread.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/osThread.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/osThread.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)osThread.cpp	1.29 07/05/05 17:06:53 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -56,4 +53,3 @@
+     default:                      st->print("unknown state %d", _state); break;
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/osThread.hpp openjdk/hotspot/src/share/vm/runtime/osThread.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/osThread.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/osThread.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)osThread.hpp	1.40 07/05/05 17:06:53 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/perfData.cpp openjdk/hotspot/src/share/vm/runtime/perfData.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/perfData.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/perfData.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)perfData.cpp	1.22 07/05/05 17:06:52 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/perfData.hpp openjdk/hotspot/src/share/vm/runtime/perfData.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/perfData.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/perfData.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)perfData.hpp	1.24 07/05/05 17:06:54 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/perfMemory.cpp openjdk/hotspot/src/share/vm/runtime/perfMemory.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/perfMemory.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/perfMemory.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)perfMemory.cpp	1.27 07/05/05 17:06:53 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -227,7 +224,7 @@
+ char* PerfMemory::get_perfdata_file_path() {
+   char* dest_file = NULL; 
+  
+-  if (PerfDataSaveFile[0] != '\0') {
++  if (PerfDataSaveFile != NULL) {
+     // dest_file_name stores the validated file name if file_name
+     // contains %p which will be replaced by pid.
+     dest_file = NEW_C_HEAP_ARRAY(char, JVM_MAXPATHLEN);
+@@ -249,4 +246,3 @@
+    
+   return dest_file;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/perfMemory.hpp openjdk/hotspot/src/share/vm/runtime/perfMemory.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/perfMemory.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/perfMemory.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)perfMemory.hpp	1.23 07/05/05 17:06:54 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/prefetch.hpp openjdk/hotspot/src/share/vm/runtime/prefetch.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/prefetch.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/prefetch.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)prefetch.hpp	1.9 07/05/05 17:06:53 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/reflectionCompat.hpp openjdk/hotspot/src/share/vm/runtime/reflectionCompat.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/reflectionCompat.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/reflectionCompat.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)reflectionCompat.hpp	1.14 07/05/05 17:06:54 JVM"
+-#endif
+ /*
+  * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/reflection.cpp openjdk/hotspot/src/share/vm/runtime/reflection.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/reflection.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/reflection.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)reflection.cpp	1.178 07/05/23 10:54:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -298,7 +295,7 @@
+ 
+ oop Reflection:: basic_type_arrayklass_to_mirror(klassOop basic_type_arrayklass, TRAPS) {
+   BasicType type = typeArrayKlass::cast(basic_type_arrayklass)->element_type();
+-  return SystemDictionary::java_mirror(type);
++  return Universe::java_mirror(type);
+ }
+ 
+ 
+@@ -625,7 +622,7 @@
+   // Basic types
+   BasicType type = vmSymbols::signature_type(signature());
+   if (type != T_OBJECT) {
+-    return Handle(THREAD, SystemDictionary::java_mirror(type));
++    return Handle(THREAD, Universe::java_mirror(type));
+   }
+ 
+   oop loader = instanceKlass::cast(k())->class_loader();
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/reflection.hpp openjdk/hotspot/src/share/vm/runtime/reflection.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/reflection.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/reflection.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)reflection.hpp	1.46 07/05/05 17:06:54 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -163,4 +160,3 @@
+ #endif /* SUPPORT_OLD_REFLECTION */
+ 
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/reflectionUtils.cpp openjdk/hotspot/src/share/vm/runtime/reflectionUtils.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/reflectionUtils.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/reflectionUtils.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)reflectionUtils.cpp	1.15 07/05/05 17:06:54 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/reflectionUtils.hpp openjdk/hotspot/src/share/vm/runtime/reflectionUtils.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/reflectionUtils.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/reflectionUtils.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)reflectionUtils.hpp	1.16 07/05/05 17:06:54 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/registerMap.hpp openjdk/hotspot/src/share/vm/runtime/registerMap.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/registerMap.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/registerMap.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)registerMap.hpp	1.16 07/05/05 17:06:54 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/relocator.cpp openjdk/hotspot/src/share/vm/runtime/relocator.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/relocator.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/relocator.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)relocator.cpp	1.40 07/05/05 17:06:54 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/relocator.hpp openjdk/hotspot/src/share/vm/runtime/relocator.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/relocator.hpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/relocator.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)relocator.hpp	1.27 07/05/05 17:06:54 JVM"
+-#endif
+ /*
+  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -119,4 +116,3 @@
+       _listener->relocated(bci, delta, new_code_length); 
+   }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/rframe.cpp openjdk/hotspot/src/share/vm/runtime/rframe.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/rframe.cpp	2008-08-28 10:23:16.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/rframe.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)rframe.cpp	1.41 07/05/05 17:06:52 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -171,4 +168,3 @@
+ void DeoptimizedRFrame::print() {
+   RFrame::print("deopt.");
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/rframe.hpp openjdk/hotspot/src/share/vm/runtime/rframe.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/rframe.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/rframe.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)rframe.hpp	1.23 07/05/05 17:06:49 JVM"
+-#endif
+ /*
+  * Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -118,5 +115,3 @@
+  public:
+   void print();
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/safepoint.cpp openjdk/hotspot/src/share/vm/runtime/safepoint.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/safepoint.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/safepoint.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)safepoint.cpp	1.305 07/05/29 09:44:27 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -37,6 +34,7 @@
+ volatile int SafepointSynchronize::_safepoint_counter = 0;
+ static volatile int PageArmed = 0 ;        // safepoint polling page is RO|RW vs PROT_NONE
+ static volatile int TryingToBlock = 0 ;    // proximate value -- for advisory use only
++static bool timeout_error_printed = false;
+ 
+ // Roll all threads forward to a safepoint and suspend them all
+ void SafepointSynchronize::begin() {   
+@@ -81,8 +79,7 @@
+   // Save the starting time, so that it can be compared to see if this has taken
+   // too long to complete.
+   jlong safepoint_limit_time;
+-  static bool timeout_error_printed = false;
+-  
++  timeout_error_printed = false;
+   
+   // Begin the process of bringing the system to a safepoint.
+   // Java threads can be in several different states and are
+@@ -129,7 +126,7 @@
+   }
+ 
+   // Make interpreter safepoint aware
+-  AbstractInterpreter::notice_safepoints(); 
++  Interpreter::notice_safepoints();
+ 
+   if (UseCompilerSafepoints && DeferPollingPageLoopCount < 0) { 
+     // Make polling safepoint aware
+@@ -148,7 +145,7 @@
+ #endif // ASSERT
+ 
+   if (SafepointTimeout)
+-    safepoint_limit_time = os::javaTimeMillis() + (jlong)SafepointTimeoutDelay;
++    safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS;
+ 
+   // Iterate through all threads until it have been determined how to stop them all at a safepoint  
+   unsigned int iterations = 0;
+@@ -172,36 +169,15 @@
+       }
+     }
+ 
+-    if (PrintSafepointStatistics && iterations == 0) {
++    if ( (PrintSafepointStatistics || (PrintSafepointStatisticsTimeout > 0))
++         && iterations == 0) {
+       begin_statistics(nof_threads, still_running);
+     }
+ 
+     if (still_running > 0) {
+       // Check for if it takes to long
+-      if (SafepointTimeout && safepoint_limit_time < os::javaTimeMillis()) {
+-        if (!timeout_error_printed) {
+-          timeout_error_printed = true;
+-          // Print out the thread IDs which didn't reach the safepoint
+-          // for debugging purposes (useful when there are lots of
+-          // threads in the debugger)
+-          tty->print_cr("# SafepointSynchronize::begin: Fatal error:");
+-          tty->print_cr("# SafepointSynchronize::begin: Timed out while attempting to reach a safepoint.");
+-          tty->print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:");
+-          for(JavaThread *cur = Threads::first(); cur; cur = cur->next()) {
+-            ThreadSafepointState *cur_state = cur->safepoint_state();
+-            if (cur_state->is_running()) {         
+-              tty->print("# ");
+-              cur_state->print();
+-              cur->osthread()->print();
+-              tty->print_cr("");
+-            }
+-          }
+-          tty->print_cr("# SafepointSynchronize::begin: (End of list)");
+-        }
+-
+-        if (DieOnSafepointTimeout) {
+-          fatal("Safepoint Timeout");
+-        }
++      if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
++        print_safepoint_timeout(_spinning_timeout);
+       }
+ 
+       // Spin to avoid context switching.  
+@@ -294,35 +270,11 @@
+       Safepoint_lock->wait(true);  // true, means with no safepoint checks
+     } else {
+       // Compute remaining time
+-      jlong remaining_time = safepoint_limit_time - os::javaTimeMillis();
++      jlong remaining_time = safepoint_limit_time - os::javaTimeNanos();
+ 
+       // If there is no remaining time, then there is an error
+-      if (remaining_time < 0 || Safepoint_lock->wait(true, remaining_time)) {
+-        if (!timeout_error_printed) {
+-          timeout_error_printed = true;
+-          // Print out the thread IDs which didn't reach the safepoint
+-          // for debugging purposes (useful when there are lots of
+-          // threads in the debugger)
+-          tty->print_cr("# SafepointSynchronize::begin: Fatal error:");
+-          tty->print_cr("# SafepointSynchronize::begin: Timed out while waiting for all threads to stop.");
+-          tty->print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:");
+-          for(JavaThread *cur = Threads::first(); cur; cur = cur->next()) {
+-            ThreadSafepointState *cur_state = cur->safepoint_state();
+-            if (cur_state->type() == ThreadSafepointState::_call_back) {
+-              if (!cur_state->has_called_back()) {
+-                tty->print("# ");
+-                cur_state->print();
+-                cur->osthread()->print();
+-                tty->print_cr("");
+-              }
+-            }
+-          }
+-          tty->print_cr("# SafepointSynchronize::begin: (End of list)");
+-        }
+-
+-        if (DieOnSafepointTimeout) {
+-          fatal("Safepoint Timeout");
+-        }
++      if (remaining_time < 0 || Safepoint_lock->wait(true, remaining_time / MICROUNITS)) {
++        print_safepoint_timeout(_blocking_timeout);
+       }
+     }
+   }               
+@@ -330,10 +282,12 @@
+ 
+ #ifndef PRODUCT
+   if (SafepointTimeout) {
+-    jlong current_time = os::javaTimeMillis();
++    jlong current_time = os::javaTimeNanos();
+     if (safepoint_limit_time < current_time) {
+-      tty->print_cr("# SafepointSynchronize: Finished after %.4f seconds",
+-        0.001 * ((double)current_time - (double)safepoint_limit_time + (double)SafepointTimeoutDelay) );
++      tty->print_cr("# SafepointSynchronize: Finished after "
++                    INT64_FORMAT_W(6) " ms",
++                    ((current_time - safepoint_limit_time) / MICROUNITS +
++                     SafepointTimeoutDelay));
+     }
+   }
+ #endif
+@@ -397,7 +351,7 @@
+   }
+ 
+   // Remove safepoint check from interpreter
+-  AbstractInterpreter::ignore_safepoints();
++  Interpreter::ignore_safepoints();
+ 
+   {
+     MutexLocker mu(Safepoint_lock);
+@@ -739,6 +693,51 @@
+   // print_me(sp,stack_copy,was_oops);
+ }
+ 
++
++void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason) {
++  if (!timeout_error_printed) {
++    timeout_error_printed = true;
++    // Print out the thread infor which didn't reach the safepoint for debugging
++    // purposes (useful when there are lots of threads in the debugger).
++    tty->print_cr("");
++    tty->print_cr("# SafepointSynchronize::begin: Timeout detected:");
++    if (reason ==  _spinning_timeout) {
++      tty->print_cr("# SafepointSynchronize::begin: Timed out while spinning to reach a safepoint.");
++    } else if (reason == _blocking_timeout) {
++      tty->print_cr("# SafepointSynchronize::begin: Timed out while waiting for threads to stop.");
++    }
++
++    tty->print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:");
++    ThreadSafepointState *cur_state;
++    ResourceMark rm;
++    for(JavaThread *cur_thread = Threads::first(); cur_thread;
++        cur_thread = cur_thread->next()) {
++      cur_state = cur_thread->safepoint_state();
++
++      if (cur_thread->thread_state() != _thread_blocked &&
++          ((reason == _spinning_timeout && cur_state->is_running()) ||
++           (reason == _blocking_timeout && !cur_state->has_called_back()))) {
++        tty->print("# ");
++        cur_thread->print();
++        tty->print_cr("");
++      }
++    }
++    tty->print_cr("# SafepointSynchronize::begin: (End of list)");
++  }
++
++  // To debug the long safepoint, specify both DieOnSafepointTimeout &
++  // ShowMessageBoxOnError.
++  if (DieOnSafepointTimeout) {
++    char msg[1024];
++    VM_Operation *op = VMThread::vm_operation();
++    sprintf(msg, "Safepoint sync time longer than %d ms detected when executing %s.",
++            SafepointTimeoutDelay,
++            op != NULL ? op->name() : "no vm operation");
++    fatal(msg);
++  }
++}
++
++
+ // -------------------------------------------------------------------------------------------------------
+ // Implementation of ThreadSafepointState 
+ 
+@@ -968,8 +967,11 @@
+ static jlong  last_safepoint_start_time = 0;
+ static jlong  sync_end_time = 0;  
+ static bool   need_to_track_page_armed_status = false;
++static bool   init_done = false;
++
++void SafepointSynchronize::deferred_initialize_stat() {
++  if (init_done) return;
+ 
+-void SafepointSynchronize::initialize_stat() {
+   if (PrintSafepointStatisticsCount <= 0) {
+     fatal("Wrong PrintSafepointStatisticsCount");
+   }
+@@ -1005,9 +1007,12 @@
+   }
+  
+   tty->print_cr("page_trap_count");
++
++  init_done = true;
+ }
+ 
+ void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) {
++  deferred_initialize_stat();
+   
+   SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
+ 
+@@ -1140,8 +1145,7 @@
+ // print_statistics to print out the rest of the sampling.  Then
+ // it tries to summarize the sampling.
+ void SafepointSynchronize::print_stat_on_exit() {
+-  assert(Thread::current()->is_VM_thread(), 
+-         "print_stat_on_exit not called on VMThread");
++  if (_safepoint_stats == NULL) return;
+ 
+   SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
+   
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/safepoint.hpp openjdk/hotspot/src/share/vm/runtime/safepoint.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/safepoint.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/safepoint.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)safepoint.hpp	1.103 07/05/26 16:02:40 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -62,6 +59,11 @@
+       _other_thread = 2
+   };
+ 
++  enum SafepointTimeoutReason {
++    _spinning_timeout = 0,
++    _blocking_timeout = 1
++  };
++
+   typedef struct { 
+     int    _vmop_type;                         // type of VM operation triggers the safepoint
+     int    _nof_total_threads;                 // total number of Java threads
+@@ -107,6 +109,10 @@
+   inline static void inc_page_trap_count() {
+     Atomic::inc(&_safepoint_stats[_cur_stat_index]._nof_threads_hit_page_trap);
+   }
++
++  // For debug long safepoint
++  static void print_safepoint_timeout(SafepointTimeoutReason timeout_reason);
++
+ public:
+ 
+   // Main entry points
+@@ -142,7 +148,7 @@
+   static void print_state()                                PRODUCT_RETURN;
+   static void safepoint_msg(const char* format, ...)       PRODUCT_RETURN;
+   
+-  static void initialize_stat();
++  static void deferred_initialize_stat();
+   static void print_stat_on_exit();
+   inline static void inc_vmop_coalesced_count() { _coalesced_vmop_count++; }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sharedRuntime.cpp openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/sharedRuntime.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)sharedRuntime.cpp	1.382 07/07/19 12:19:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -470,11 +467,6 @@
+   throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_AbstractMethodError());
+ JRT_END
+ 
+-JRT_ENTRY(void, SharedRuntime::throw_IncompatibleClassChangeError(JavaThread* thread))
+-  // These errors occur only at call sites
+-  throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_IncompatibleClassChangeError(), "vtable stub");
+-JRT_END
+-
+ JRT_ENTRY(void, SharedRuntime::throw_ArithmeticException(JavaThread* thread))
+   throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArithmeticException(), "/ by zero");
+ JRT_END
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sharedRuntime.hpp openjdk/hotspot/src/share/vm/runtime/sharedRuntime.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/sharedRuntime.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/sharedRuntime.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)sharedRuntime.hpp	1.157 07/07/19 12:19:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -107,7 +104,6 @@
+     STACK_OVERFLOW
+   };
+   static void    throw_AbstractMethodError(JavaThread* thread);
+-  static void    throw_IncompatibleClassChangeError(JavaThread* thread);
+   static void    throw_ArithmeticException(JavaThread* thread);
+   static void    throw_NullPointerException(JavaThread* thread);
+   static void    throw_NullPointerException_at_call(JavaThread* thread);
+@@ -130,6 +126,7 @@
+   }
+ 
+ #ifdef COMPILER2
++  static void generate_uncommon_trap_blob(void);
+   static UncommonTrapBlob* uncommon_trap_blob()                  { return _uncommon_trap_blob; }
+ #endif // COMPILER2
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp openjdk/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)sharedRuntimeTrans.cpp	1.8 07/05/05 17:06:54 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp openjdk/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)sharedRuntimeTrig.cpp	1.16 07/05/05 17:06:55 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/signature.cpp openjdk/hotspot/src/share/vm/runtime/signature.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/signature.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/signature.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)signature.cpp	1.43 07/05/05 17:06:56 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/signature.hpp openjdk/hotspot/src/share/vm/runtime/signature.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/signature.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/signature.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)signature.hpp	1.50 07/05/05 17:06:56 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stackValueCollection.cpp openjdk/hotspot/src/share/vm/runtime/stackValueCollection.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/stackValueCollection.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/stackValueCollection.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)stackValueCollection.cpp	1.18 07/05/05 17:06:53 JVM"
+-#endif
+ /*
+  * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stackValueCollection.hpp openjdk/hotspot/src/share/vm/runtime/stackValueCollection.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/stackValueCollection.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/stackValueCollection.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)stackValueCollection.hpp	1.14 07/05/05 17:06:58 JVM"
+-#endif
+ /*
+  * Copyright 2001-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stackValue.cpp openjdk/hotspot/src/share/vm/runtime/stackValue.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/stackValue.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/stackValue.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)stackValue.cpp	1.27 07/05/05 17:06:58 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -28,6 +25,136 @@
+ # include "incls/_precompiled.incl"
+ # include "incls/_stackValue.cpp.incl"
+ 
++StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv) {
++  if (sv->is_location()) {
++    // Stack or register value
++    Location loc = ((LocationValue *)sv)->location();
++
++#ifdef SPARC
++    // %%%%% Callee-save floats will NOT be working on a Sparc until we
++    // handle the case of a 2 floats in a single double register.
++    assert( !(loc.is_register() && loc.type() == Location::float_in_dbl), "Sparc does not handle callee-save floats yet" );
++#endif // SPARC
++
++    // First find address of value
++
++    address value_addr = loc.is_register()
++      // Value was in a callee-save register
++      ? reg_map->location(VMRegImpl::as_VMReg(loc.register_number()))
++      // Else value was directly saved on the stack. The frame's original stack pointer,
++      // before any extension by its callee (due to Compiler1 linkage on SPARC), must be used.
++      : ((address)fr->unextended_sp()) + loc.stack_offset();
++
++    // Then package it right depending on type
++    // Note: the transfer of the data is thru a union that contains
++    // an intptr_t. This is because an interpreter stack slot is
++    // really an intptr_t. The use of a union containing an intptr_t
++    // ensures that on a 64 bit platform we have proper alignment
++    // and that we store the value where the interpreter will expect
++    // to find it (i.e. proper endian). Similarly on a 32bit platform
++    // using the intptr_t ensures that when a value is larger than
++    // a stack slot (jlong/jdouble) that we capture the proper part
++    // of the value for the stack slot in question.
++    //
++    switch( loc.type() ) {
++    case Location::float_in_dbl: { // Holds a float in a double register?
++      // The callee has no clue whether the register holds a float,
++      // double or is unused.  He always saves a double.  Here we know
++      // a double was saved, but we only want a float back.  Narrow the
++      // saved double to the float that the JVM wants.
++      assert( loc.is_register(), "floats always saved to stack in 1 word" );
++      union { intptr_t p; jfloat jf; } value;
++      value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
++      value.jf = (jfloat) *(jdouble*) value_addr;
++      return new StackValue(value.p); // 64-bit high half is stack junk
++    }
++    case Location::int_in_long: { // Holds an int in a long register?
++      // The callee has no clue whether the register holds an int,
++      // long or is unused.  He always saves a long.  Here we know
++      // a long was saved, but we only want an int back.  Narrow the
++      // saved long to the int that the JVM wants.
++      assert( loc.is_register(), "ints always saved to stack in 1 word" );
++      union { intptr_t p; jint ji;} value;
++      value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
++      value.ji = (jint) *(jlong*) value_addr;
++      return new StackValue(value.p); // 64-bit high half is stack junk
++    }
++#ifdef _LP64
++    case Location::dbl:
++      // Double value in an aligned adjacent pair
++      return new StackValue(*(intptr_t*)value_addr);
++    case Location::lng:
++      // Long   value in an aligned adjacent pair
++      return new StackValue(*(intptr_t*)value_addr);
++#endif
++    case Location::oop: {
++      Handle h(*(oop *)value_addr); // Wrap a handle around the oop
++      return new StackValue(h);
++    }
++    case Location::addr: {
++      ShouldNotReachHere(); // both C1 and C2 now inline jsrs
++    }
++    case Location::normal: {
++      // Just copy all other bits straight through
++      union { intptr_t p; jint ji;} value;
++      value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
++      value.ji = *(jint*)value_addr;
++      return new StackValue(value.p);
++    }
++    case Location::invalid:
++      return new StackValue();
++    default:
++      ShouldNotReachHere();
++    }
++
++  } else if (sv->is_constant_int()) {
++    // Constant int: treat same as register int.
++    union { intptr_t p; jint ji;} value;
++    value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
++    value.ji = (jint)((ConstantIntValue*)sv)->value();
++    return new StackValue(value.p);
++  } else if (sv->is_constant_oop()) {
++    // constant oop
++    return new StackValue(((ConstantOopReadValue *)sv)->value());
++#ifdef _LP64
++  } else if (sv->is_constant_double()) {
++    // Constant double in a single stack slot
++    union { intptr_t p; double d; } value;
++    value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
++    value.d = ((ConstantDoubleValue *)sv)->value();
++    return new StackValue(value.p);
++  } else if (sv->is_constant_long()) {
++    // Constant long in a single stack slot
++    union { intptr_t p; jlong jl; } value;
++    value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
++    value.jl = ((ConstantLongValue *)sv)->value();
++    return new StackValue(value.p);
++#endif
++  } else if (sv->is_object()) {
++    return new StackValue(((ObjectValue *)sv)->value());
++  }
++
++  // Unknown ScopeValue type
++  ShouldNotReachHere();
++  return new StackValue((intptr_t) 0);   // dummy
++}
++
++
++BasicLock* StackValue::resolve_monitor_lock(const frame* fr, Location location) {
++  assert(location.is_stack(), "for now we only look at the stack");
++  int word_offset = location.stack_offset() / wordSize;
++  // (stack picture)
++  // high: [     ]  word_offset + 1
++  // low   [     ]  word_offset
++  //
++  // sp->  [     ]  0
++  // the word_offset is the distance from the stack pointer to the lowest address
++  // The frame's original stack pointer, before any extension by its callee
++  // (due to Compiler1 linkage on SPARC), must be used.
++  return (BasicLock*) (fr->unextended_sp() + word_offset);
++}
++
++
+ #ifndef PRODUCT
+ 
+ void StackValue::print_on(outputStream* st) const {
+@@ -51,4 +178,3 @@
+ }
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stackValue.hpp openjdk/hotspot/src/share/vm/runtime/stackValue.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/stackValue.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/stackValue.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)stackValue.hpp	1.36 07/05/05 17:06:58 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -93,10 +90,12 @@
+     }
+   }
+ 
++  static StackValue* create_stack_value(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv);
++  static BasicLock*  resolve_monitor_lock(const frame* fr, Location location);
++
+ #ifndef PRODUCT
+  public:
+   // Printing
+   void print_on(outputStream* st) const;
+ #endif
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/statSampler.cpp openjdk/hotspot/src/share/vm/runtime/statSampler.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/statSampler.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/statSampler.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)statSampler.cpp	1.24 07/05/05 17:06:58 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -360,4 +357,3 @@
+ 
+   StatSampler::destroy();
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/statSampler.hpp openjdk/hotspot/src/share/vm/runtime/statSampler.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/statSampler.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/statSampler.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)statSampler.hpp	1.12 07/05/05 17:06:58 JVM"
+-#endif
+ /*
+  * Copyright 2001-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp openjdk/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)stubCodeGenerator.cpp	1.30 07/05/17 16:06:31 JVM"
+-#endif
+ /*
+  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -146,4 +143,3 @@
+     JvmtiExport::post_dynamic_code_generated(_cdesc->name(), _cdesc->begin(), _cdesc->end());
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp openjdk/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)stubCodeGenerator.hpp	1.25 07/05/17 16:06:33 JVM"
+-#endif
+ /*
+  * Copyright 1997-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -121,4 +118,3 @@
+   ~StubCodeMark();
+ 
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stubRoutines.cpp openjdk/hotspot/src/share/vm/runtime/stubRoutines.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/stubRoutines.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/stubRoutines.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)stubRoutines.cpp	1.115 07/07/19 12:19:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -43,7 +40,6 @@
+ address StubRoutines::_catch_exception_entry                    = NULL;
+ address StubRoutines::_forward_exception_entry                  = NULL;
+ address StubRoutines::_throw_AbstractMethodError_entry          = NULL;
+-address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL;
+ address StubRoutines::_throw_ArithmeticException_entry          = NULL;
+ address StubRoutines::_throw_NullPointerException_entry         = NULL;
+ address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stubRoutines.hpp openjdk/hotspot/src/share/vm/runtime/stubRoutines.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/stubRoutines.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/stubRoutines.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)stubRoutines.hpp	1.118 07/07/19 12:19:07 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -87,7 +84,6 @@
+   static address _forward_exception_entry;
+   static address _catch_exception_entry;
+   static address _throw_AbstractMethodError_entry;
+-  static address _throw_IncompatibleClassChangeError_entry;
+   static address _throw_ArithmeticException_entry;
+   static address _throw_NullPointerException_entry;
+   static address _throw_NullPointerException_at_call_entry;
+@@ -188,7 +184,6 @@
+   static address forward_exception_entry()                 { return _forward_exception_entry; }
+   // Implicit exceptions
+   static address throw_AbstractMethodError_entry()         { return _throw_AbstractMethodError_entry; }
+-  static address throw_IncompatibleClassChangeError_entry(){ return _throw_IncompatibleClassChangeError_entry; }
+   static address throw_ArithmeticException_entry()         { return _throw_ArithmeticException_entry; }
+   static address throw_NullPointerException_entry()        { return _throw_NullPointerException_entry; }
+   static address throw_NullPointerException_at_call_entry(){ return _throw_NullPointerException_at_call_entry; }
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sweeper.cpp openjdk/hotspot/src/share/vm/runtime/sweeper.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/sweeper.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/sweeper.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)sweeper.cpp	1.39 07/05/05 17:06:50 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sweeper.hpp openjdk/hotspot/src/share/vm/runtime/sweeper.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/sweeper.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/sweeper.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)sweeper.hpp	1.26 07/05/05 17:06:59 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/synchronizer.cpp openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/synchronizer.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)synchronizer.cpp	1.110 07/05/26 16:19:45 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -119,6 +116,7 @@
+   volatile int  _notified ;    
+   volatile TStates TState ; 
+   Sorted        _Sorted ;           // List placement disposition
++  bool          _active ;           // Contention monitoring is enabled
+  public:
+   ObjectWaiter(Thread* thread) {
+     _next     = NULL;
+@@ -127,8 +125,19 @@
+     TState    = TS_RUN ; 
+     _thread   = thread;
+     _event    = thread->_ParkEvent ; 
++    _active   = false;
+     assert (_event != NULL, "invariant") ; 
+   }
++
++  void wait_reenter_begin(ObjectMonitor *mon) {
++    JavaThread *jt = (JavaThread *)this->_thread;
++    _active = JavaThreadBlockedOnMonitorEnterState::wait_reenter_begin(jt, mon);
++  }
++
++  void wait_reenter_end(ObjectMonitor *mon) {
++    JavaThread *jt = (JavaThread *)this->_thread;
++    JavaThreadBlockedOnMonitorEnterState::wait_reenter_end(jt, _active);
++  }
+ };
+ 
+ enum ManifestConstants { 
+@@ -180,7 +189,7 @@
+ 
+ // Tunables ...
+ // The knob* variables are effectively final.  Once set they should
+-// never be modified hence.
++// never be modified hence.  Consider using __read_mostly with GCC.
+ 
+ static int Knob_LogSpins           = 0 ;       // enable jvmstat tally for spins
+ static int Knob_HandOff            = 0 ;      
+@@ -322,7 +331,7 @@
+     // Typically the displaced header will be 0 (recursive stack lock) or 
+     // unused_mark.  Naively we'd like to assert that the displaced mark
+     // value is either 0, neutral, or 3.  But with the advent of the
+-    // the store-before-CAS avoidance in fast_lock/compiler_lock_object
++    // store-before-CAS avoidance in fast_lock/compiler_lock_object
+     // we can find any flavor mark in the displaced mark.
+   }
+ // [RGV] The next line appears to do nothing!
+@@ -450,7 +459,7 @@
+ 
+ typedef volatile int SpinLockT ; 
+ 
+-static void SpinAcquire (volatile int * adr, const char * LockName) {
++void Thread::SpinAcquire (volatile int * adr, const char * LockName) {
+   if (Atomic::cmpxchg (1, adr, 0) == 0) {
+      return ;   // normal fast-path return
+   }
+@@ -464,6 +473,8 @@
+         ++ctr ; 
+         if ((ctr & 0xFFF) == 0 || !os::is_MP()) { 
+            if (Yields > 5) { 
++             // Consider using a simple NakedSleep() instead.
++             // Then SpinAcquire could be called by non-JVM threads
+              Thread::current()->_ParkEvent->park(1) ; 
+            } else { 
+              os::NakedYield() ; 
+@@ -477,7 +488,7 @@
+   }
+ }
+ 
+-static void SpinRelease (volatile int * adr) {
++void Thread::SpinRelease (volatile int * adr) {
+   assert (*adr != 0, "invariant") ; 
+   OrderAccess::fence() ;      // guarantee at least release consistency. 
+   // Roach-motel semantics.
+@@ -494,12 +505,15 @@
+ //    The remainder of the word points to the head of a singly-linked list
+ //    of threads blocked on the lock.  
+ //
+-// *  users of muxAcquire and muxRelease must be careful with regards to
+-//    consuming unpark() "permits".  This is particularly true when 
+-//    muxAcquire-muxRelease are used as part of the implementation of 
+-//    the sync subsystem.  A safe rule of thumb is that a thread should never
+-//    call muxAcquire() if it's enqueued (cxq, EntryList, WaitList, etc) and 
+-//    will subsequently park().  The park() operation in muxAcquire() could
++// *  The current implementation of muxAcquire-muxRelease uses its own
++//    dedicated Thread._MuxEvent instance.  If we're interested in
++//    minimizing the peak number of extant ParkEvent instances then
++//    we could eliminate _MuxEvent and "borrow" _ParkEvent as long
++//    as certain invariants were satisfied.  Specifically, care would need
++//    to be taken with regards to consuming unpark() "permits".
++//    A safe rule of thumb is that a thread would never call muxAcquire()
++//    if it's enqueued (cxq, EntryList, WaitList, etc) and will subsequently
++//    park().  Otherwise the _ParkEvent park() operation in muxAcquire() could
+ //    consume an unpark() permit intended for monitorenter, for instance. 
+ //    One way around this would be to widen the restricted-range semaphore
+ //    implemented in park().  Another alternative would be to provide
+@@ -507,9 +521,9 @@
+ //    instance would be dedicated to muxAcquire-muxRelease, for instance.
+ //
+ // *  Usage:
+-//    -- only as leaf locks
+-//    -- for short-term locks only, as blocking MuxAcquire() does _not perform
+-//       a state transition.  
++//    -- Only as leaf locks
++//    -- for short-term locking only as muxAcquire does not perform
++//       thread state transitions.
+ // 
+ // Alternatives:
+ // *  We could implement muxAcquire and muxRelease with MCS or CLH locks 
+@@ -531,12 +545,13 @@
+ //    to provide the usual futile-wakeup optimization.  
+ //    See RTStt for details.  
+ // *  Consider schedctl.sc_nopreempt to cover the critical section.
++//
+ 
+ 
+ typedef volatile intptr_t MutexT ;      // Mux Lock-word
+ enum MuxBits { LOCKBIT = 1 } ; 
+  
+-static void ATTR muxAcquire (volatile intptr_t * Lock, const char * LockName) {
++void Thread::muxAcquire (volatile intptr_t * Lock, const char * LockName) {
+   intptr_t w = Atomic::cmpxchg_ptr (LOCKBIT, Lock, 0) ; 
+   if (w == 0) return ; 
+   if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { 
+@@ -544,10 +559,9 @@
+   }
+ 
+   TEVENT (muxAcquire - Contention) ; 
+-  ParkEvent * Self = Thread::current()->_ParkEvent ; 
++  ParkEvent * const Self = Thread::current()->_MuxEvent ;
+   assert ((intptr_t(Self) & LOCKBIT) == 0, "invariant") ; 
+   for (;;) { 
+-     intptr_t w ; 
+      int its = (os::is_MP() ? 100 : 0) + 1 ; 
+ 
+      // Optional spin phase: spin-then-park strategy
+@@ -567,6 +581,7 @@
+         w = *Lock ; 
+         if ((w & LOCKBIT) == 0) { 
+             if (Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { 
++                Self->OnList = 0 ;   // hygiene - allows stronger asserts
+                 return ; 
+             }
+             continue ;      // Interference -- *Lock changed -- Just retry
+@@ -582,17 +597,79 @@
+   }
+ }
+ 
++void Thread::muxAcquireW (volatile intptr_t * Lock, ParkEvent * ev) {
++  intptr_t w = Atomic::cmpxchg_ptr (LOCKBIT, Lock, 0) ;
++  if (w == 0) return ;
++  if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
++    return ;
++  }
++
++  TEVENT (muxAcquire - Contention) ;
++  ParkEvent * ReleaseAfter = NULL ;
++  if (ev == NULL) {
++    ev = ReleaseAfter = ParkEvent::Allocate (NULL) ;
++  }
++  assert ((intptr_t(ev) & LOCKBIT) == 0, "invariant") ;
++  for (;;) {
++    guarantee (ev->OnList == 0, "invariant") ;
++    int its = (os::is_MP() ? 100 : 0) + 1 ;
++
++    // Optional spin phase: spin-then-park strategy
++    while (--its >= 0) {
++      w = *Lock ;
++      if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
++        if (ReleaseAfter != NULL) {
++          ParkEvent::Release (ReleaseAfter) ;
++        }
++        return ;
++      }
++    }
++
++    ev->reset() ;
++    ev->OnList = intptr_t(Lock) ;
++    // The following fence() isn't _strictly necessary as the subsequent
++    // CAS() both serializes execution and ratifies the fetched *Lock value.
++    OrderAccess::fence();
++    for (;;) {
++      w = *Lock ;
++      if ((w & LOCKBIT) == 0) {
++        if (Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
++          ev->OnList = 0 ;
++          // We call ::Release while holding the outer lock, thus
++          // artificially lengthening the critical section.
++          // Consider deferring the ::Release() until the subsequent unlock(),
++          // after we've dropped the outer lock.
++          if (ReleaseAfter != NULL) {
++            ParkEvent::Release (ReleaseAfter) ;
++          }
++          return ;
++        }
++        continue ;      // Interference -- *Lock changed -- Just retry
++      }
++      assert (w & LOCKBIT, "invariant") ;
++      ev->ListNext = (ParkEvent *) (w & ~LOCKBIT );
++      if (Atomic::cmpxchg_ptr (intptr_t(ev)|LOCKBIT, Lock, w) == w) break ;
++    }
++
++    while (ev->OnList != 0) {
++      ev->park() ;
++    }
++  }
++}
++
+ // Release() must extract a successor from the list and then wake that thread.
+ // It can "pop" the front of the list or use a detach-modify-reattach (DMR) scheme 
+ // similar to that used by ParkEvent::Allocate() and ::Release().  DMR-based
+-// Release() would (A) CAS() or swap() null to *Lock, releasing the lock and 
+-// detaching the list.  (B) Extract a successor from the private list "in-hand" 
+-// (C) attempt to CAS() the residual back into *Lock over null.  If there were any 
+-// newly arrived threads and the CAS() would fail.  In that case Release() would 
+-// detach the RATs, re-merge the list in-hand with the RATs and repeat as needed.  
+-// Alternately, Release() can detach and extract a successor, put then pass the
+-// residual list to the wakee.  The wakee must reattach and remerge before it
+-// competes for the lock.  
++// Release() would :
++// (A) CAS() or swap() null to *Lock, releasing the lock and detaching the list.
++// (B) Extract a successor from the private list "in-hand"
++// (C) attempt to CAS() the residual back into *Lock over null.
++//     If there were any newly arrived threads and the CAS() would fail.
++//     In that case Release() would detach the RATs, re-merge the list in-hand
++//     with the RATs and repeat as needed.  Alternately, Release() might
++//     detach and extract a successor, but then pass the residual list to the wakee.
++//     The wakee would be responsible for reattaching and remerging before it
++//     competed for the lock.
+ //
+ // Both "pop" and DMR are immune from ABA corruption -- there can be
+ // multiple concurrent pushers, but only one popper or detacher.  
+@@ -600,9 +677,9 @@
+ // but tends to provide excellent throughput as hot threads remain hot. 
+ // (We wake recently run threads first).  
+ 
+-static void ATTR muxRelease (volatile intptr_t * Lock)  {
++void Thread::muxRelease (volatile intptr_t * Lock)  {
+    for (;;) { 
+-     intptr_t w = Atomic::cmpxchg_ptr (0, Lock, LOCKBIT) ; 
++    const intptr_t w = Atomic::cmpxchg_ptr (0, Lock, LOCKBIT) ;
+      assert (w & LOCKBIT, "invariant") ; 
+      if (w == LOCKBIT) return ; 
+      ParkEvent * List = (ParkEvent *) (w & ~LOCKBIT) ; 
+@@ -705,7 +782,7 @@
+             // Reprovision the thread's omFreeList.  
+             // Use bulk transfers to reduce the allocation rate and heat
+             // on various locks.
+-            muxAcquire (&ListLock, "omAlloc") ;  
++            Thread::muxAcquire (&ListLock, "omAlloc") ;
+             for (int i = Self->omFreeProvision; --i >= 0 && gFreeList != NULL; ) {
+                 ObjectMonitor * take = gFreeList ;
+                 gFreeList = take->FreeNext ;
+@@ -714,7 +791,7 @@
+                 take->Recycle() ;
+                 omRelease (Self, take) ;
+             }
+-            muxRelease (&ListLock) ;  
++            Thread::muxRelease (&ListLock) ;
+             Self->omFreeProvision += 1 + (Self->omFreeProvision/2) ;
+             if (Self->omFreeProvision > MAXPRIVATE ) Self->omFreeProvision = MAXPRIVATE ;
+             TEVENT (omFirst - reprovision) ;
+@@ -758,7 +835,7 @@
+ 
+         // Acquire the ListLock to manipulate BlockList and FreeList.
+         // An Oyama-Taura-Yonezawa scheme might be more efficient. 
+-        muxAcquire (&ListLock, "omAlloc [2]") ; 
++        Thread::muxAcquire (&ListLock, "omAlloc [2]") ;
+ 
+         // Add the new block to the list of extant blocks (gBlockList). 
+         // The very first objectMonitor in a block is reserved and dedicated.
+@@ -769,7 +846,7 @@
+         // Add the new string of objectMonitors to the global free list
+         temp[_BLOCKSIZE - 1].FreeNext = gFreeList ; 
+         gFreeList = temp + 1;
+-        muxRelease (&ListLock) ; 
++        Thread::muxRelease (&ListLock) ;
+         TEVENT (Allocate block of monitors) ; 
+     }
+ }
+@@ -826,10 +903,10 @@
+     }
+ 
+     guarantee (Tail != NULL && List != NULL, "invariant") ; 
+-    muxAcquire (&ListLock, "omFlush") ; 
++    Thread::muxAcquire (&ListLock, "omFlush") ;
+     Tail->FreeNext = gFreeList ;
+     gFreeList = List ;
+-    muxRelease (&ListLock) ; 
++    Thread::muxRelease (&ListLock) ;
+     TEVENT (omFlush) ; 
+ }
+ 
+@@ -907,7 +984,7 @@
+          int YieldThenBlock = 0 ; 
+          assert (ix >= 0 && ix < NINFLATIONLOCKS, "invariant") ; 
+          assert ((NINFLATIONLOCKS & (NINFLATIONLOCKS-1)) == 0, "invariant") ; 
+-         muxAcquire (InflationLocks + ix, "InflationLock") ; 
++         Thread::muxAcquire (InflationLocks + ix, "InflationLock") ;
+          while (obj->mark() == markOopDesc::INFLATING()) {
+            // Beware: NakedYield() is advisory and has almost no effect on some platforms
+            // so we periodically call Self->_ParkEvent->park(1).
+@@ -918,7 +995,7 @@
+               os::NakedYield() ; 
+            }
+          }
+-         muxRelease (InflationLocks + ix ) ; 
++         Thread::muxRelease (InflationLocks + ix ) ;
+          TEVENT (Inflate: INFLATING - yield/park) ; 
+        }
+     } else { 
+@@ -958,7 +1035,7 @@
+       // Only that thread can complete inflation -- other threads must wait.  
+       // The INFLATING value is transient. 
+       // Currently, we spin/yield/park and poll the markword, waiting for inflation to finish.  
+-      // We could always eliminate polling by parking the thread on some auxilliary list.
++      // We could always eliminate polling by parking the thread on some auxiliary list.
+       if (mark == markOopDesc::INFLATING()) {
+          TEVENT (Inflate: spin while INFLATING) ; 
+          ReadStableMark(object) ; 
+@@ -969,7 +1046,7 @@
+       // Could be stack-locked either by this thread or by some other thread.
+       // 
+       // Note that we allocate the objectmonitor speculatively, _before_ attempting 
+-      // to install INFLATING into the mark word.  We orginally installed INFLATING, 
++      // to install INFLATING into the mark word.  We originally installed INFLATING,
+       // allocated the objectmonitor, and then finally STed the address of the 
+       // objectmonitor into the mark.  This was correct, but artificially lengthened
+       // the interval in which INFLATED appeared in the mark, thus increasing 
+@@ -1022,7 +1099,7 @@
+           // will then spin, waiting for the 0 value to disappear.   Put another way, 
+           // the 0 causes the owner to stall if the owner happens to try to
+           // drop the lock (restoring the header from the basiclock to the object) 
+-          // while inflation is in-progess.  This protocol avoids races that might 
++          // while inflation is in-progress.  This protocol avoids races that might
+           // would otherwise permit hashCode values to change or "flicker" for an object.  
+           // Critically, while object->mark is 0 mark->displaced_mark_helper() is stable.
+           // 0 serves as a "BUSY" inflate-in-progress indicator.  
+@@ -1204,7 +1281,7 @@
+   }
+ 
+ #if 0
+-  // The following optimization isn't particulary useful.  
++  // The following optimization isn't particularly useful.
+   if (mark->has_monitor() && mark->monitor()->is_entered(THREAD)) { 
+     lock->set_displaced_header (NULL) ; 
+     return ; 
+@@ -1625,9 +1702,9 @@
+   assert(THREAD == JavaThread::current(), "must be current Java thread");
+   No_Safepoint_Verifier nsv ;       
+   ReleaseJavaMonitorsClosure rjmc(THREAD);
+-  muxAcquire(&ListLock, "release_monitors_owned_by_thread");
++  Thread::muxAcquire(&ListLock, "release_monitors_owned_by_thread");
+   ObjectSynchronizer::monitors_iterate(&rjmc);
+-  muxRelease(&ListLock);
++  Thread::muxRelease(&ListLock);
+   THREAD->clear_pending_exception();
+ }
+ 
+@@ -1769,10 +1846,10 @@
+      guarantee (FreeTail != NULL && nScavenged > 0, "invariant") ; 
+      assert (FreeTail->FreeNext == NULL, "invariant") ; 
+      // constant-time list splice - prepend scavenged segment to gFreeList
+-     muxAcquire (&ListLock, "scavenge - return") ;  
++     Thread::muxAcquire (&ListLock, "scavenge - return") ;
+      FreeTail->FreeNext = gFreeList ; 
+      gFreeList = FreeHead ; 
+-     muxRelease (&ListLock) ; 
++     Thread::muxRelease (&ListLock) ;
+   } 
+ 
+   if (_sync_Deflations != NULL) _sync_Deflations->inc(nScavenged) ; 
+@@ -2161,7 +2238,7 @@
+ // "rings" or oscillates between spinning and not spinning.  This happens
+ // when spinning is just on the cusp of profitability, however, so the 
+ // situation is not dire.  The state is benign -- there's no need to add 
+-// hysterisis control to damp the transition rate between spinning and 
++// hysteresis control to damp the transition rate between spinning and
+ // not spinning.
+ //
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@@ -2209,7 +2286,7 @@
+ //    (that is, loadavg() << #cpus), we can instead suppress futile
+ //    wakeup throttling, or even wake more than one successor at exit-time.
+ //    The net effect is largely equivalent to spinning.  In both cases,
+-//    contenting threads go ONPROC and opportunistically attempt to acquire
++//    contending threads go ONPROC and opportunistically attempt to acquire
+ //    the lock, decreasing lock handover latency at the expense of wasted
+ //    cycles and context switching. 
+ //
+@@ -2249,7 +2326,7 @@
+ //    for extended periods on the ready queue.  
+ //
+ // *  While spinning try to use the otherwise wasted time to help the VM make
+-//    progess:
++//    progress:
+ //  
+ //    -- YieldTo() the owner, if the owner is OFFPROC but ready
+ //       Done our remaining quantum directly to the ready thread.
+@@ -2280,7 +2357,7 @@
+ //    as the default spin state after inflation is aggressive (optimistic)
+ //    and tends toward spinning.  So in the worst case for a lock where
+ //    spinning is not profitable we may spin unnecessarily for a brief
+-//    period.  But then again, if a lock is contented it'll tend not to deflate\
++//    period.  But then again, if a lock is contended it'll tend not to deflate
+ //    in the first place.
+ 
+ 
+@@ -2397,7 +2474,7 @@
+       // This is useful on classic SMP systems, but is of less utility on 
+       // N1-style CMT platforms. 
+       // 
+-      // Trade-off: lock acquistion latency vs coherency bandwidth.
++      // Trade-off: lock acquisition latency vs coherency bandwidth.
+       // Lock hold times are typically short.  A histogram
+       // of successful spin attempts shows that we usually acquire
+       // the lock early in the spin.  That suggests we want to 
+@@ -2601,7 +2678,7 @@
+ // * Invariant: A thread appears on at most one monitor list --
+ //   cxq, EntryList or WaitSet -- at any one time.
+ //
+-// * Contenting threads "push" themselves onto the cxq with CAS 
++// * Contending threads "push" themselves onto the cxq with CAS
+ //   and then spin/park.
+ //
+ // * After a contending thread eventually acquires the lock it must
+@@ -2689,7 +2766,7 @@
+ //   by the notifier.  
+ //
+ // * An interesting alternative is to encode cxq as (List,LockByte) where
+-//   the LockByte is 0 iff the monitor is owned.  _owner is simply an auxilliary
++//   the LockByte is 0 iff the monitor is owned.  _owner is simply an auxiliary
+ //   variable, like _recursions, in the scheme.  The threads or Events that form
+ //   the list would have to be aligned in 256-byte addresses.  A thread would
+ //   try to acquire the lock or enqueue itself with CAS, but exiting threads
+@@ -2962,7 +3039,7 @@
+ //     Given that, we'd call HSSEC after having returned from park(), 
+ //     but before attempting to acquire the monitor.  This is only a 
+ //     partial solution.  It avoids calling HSSEC while holding the 
+-//     monitor (good), but it still increases successor reacquistion latency --
++//     monitor (good), but it still increases successor reacquisition latency --
+ //     the interval between unparking a successor and the time the successor
+ //     resumes and retries the lock.  See ReenterI(), which defers state transitions.  
+ //     If we use this technique we can also avoid EnterI()-exit() loop
+@@ -3278,7 +3355,7 @@
+    // * Consider: set Wakee->UnparkTime = timeNow()
+    //   When the thread wakes up it'll compute (timeNow() - Self->UnparkTime()).
+    //   By measuring recent ONPROC latency we can approximate the
+-   //   the system load.  In turn, we can feed that information back
++   //   system load.  In turn, we can feed that information back
+    //   into the spinning & succession policies.  
+    //   (ONPROC latency correlates strongly with load).  
+    //
+@@ -3300,7 +3377,7 @@
+ // ~~~~~~
+ // Note that the collector can't reclaim the objectMonitor or deflate
+ // the object out from underneath the thread calling ::exit() as the
+-// the thread calling ::exit() never transitions to a stable state.
++// thread calling ::exit() never transitions to a stable state.
+ // This inhibits GC, which in turn inhibits asynchronous (and 
+ // inopportune) reclamation of "this".  
+ //
+@@ -3308,7 +3385,7 @@
+ // There's one exception to the claim above, however.  EnterI() can call
+ // exit() to drop a lock if the acquirer has been externally suspended.
+ // In that case exit() is called with _thread_state as _thread_blocked,
+-// but the monitor's _count field is > 0, which inhibits reclaimation.  
++// but the monitor's _count field is > 0, which inhibits reclamation.
+ //
+ // 1-0 exit
+ // ~~~~~~~~
+@@ -3455,7 +3532,7 @@
+          // I'd like to write one of the following:
+          // A.  OrderAccess::release() ; _owner = NULL 
+          // B.  OrderAccess::loadstore(); OrderAccess::storestore(); _owner = NULL;
+-         // Unfortunatey OrderAccess::release() and OrderAccess::loadstore() both
++         // Unfortunately OrderAccess::release() and OrderAccess::loadstore() both
+          // store into a _dummy variable.  That store is not needed, but can result
+          // in massive wasteful coherency traffic on classic SMP systems.  
+          // Instead, I use release_store(), which is implemented as just a simple
+@@ -3495,14 +3572,14 @@
+          // (Note that we'd need to make the post-drop spin short, but no
+          // shorter than the worst-case round-trip cache-line migration time.
+          // The dropped lock needs to become visible to the spinner, and then
+-         // the acquistion of the lock by the spinner must become visible to
++         // the acquisition of the lock by the spinner must become visible to
+          // the exiting thread).  
+          // 
+ 
+          // It appears that an heir-presumptive (successor) must be made ready.
+          // Only the current lock owner can manipulate the EntryList or
+          // drain _cxq, so we need to reacquire the lock.  If we fail
+-         // to reaquire the lock the responsibility for ensuring succession
++         // to reacquire the lock the responsibility for ensuring succession
+          // falls to the new owner.  
+          // 
+          if (Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) != NULL) {
+@@ -3523,7 +3600,7 @@
+             // in the fast-exit path raced an entering thread in the slow-enter
+             // path.  
+             // We have two choices:
+-            // A.  Try to reaquire the lock. 
++            // A.  Try to reacquire the lock.
+             //     If the CAS() fails return immediately, otherwise
+             //     we either restart/rerun the exit operation, or simply
+             //     fall-through into the code below which wakes a successor.
+@@ -3657,7 +3734,7 @@
+           // notify() operation moves T1 from O's waitset to O's EntryList. T2 then
+           // release the lock "O".  T2 resumes immediately after the ST of null into
+           // _owner, above.  T2 notices that the EntryList is populated, so it
+-          // reaquires the lock and then finds itself on the EntryList.  
++          // reacquires the lock and then finds itself on the EntryList.
+           // Given all that, we have to tolerate the circumstance where "w" is 
+           // associated with Self.        
+           assert (w->TState == ObjectWaiter::TS_ENTER, "invariant") ; 
+@@ -3828,9 +3905,9 @@
+    // returns because of a timeout of interrupt.  Contention is exceptionally rare
+    // so we use a simple spin-lock instead of a heavier-weight blocking lock.  
+ 
+-   SpinAcquire (&_WaitSetLock, "WaitSet - add") ; 
++   Thread::SpinAcquire (&_WaitSetLock, "WaitSet - add") ;
+    AddWaiter (&node) ; 
+-   SpinRelease (&_WaitSetLock) ; 
++   Thread::SpinRelease (&_WaitSetLock) ;
+ 
+    if ((SyncFlags & 4) == 0) { 
+       _Responsible = NULL ; 
+@@ -3909,13 +3986,13 @@
+      // That is, we fail toward safety.
+ 
+      if (node.TState == ObjectWaiter::TS_WAIT) { 
+-         SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ; 
++         Thread::SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ;
+          if (node.TState == ObjectWaiter::TS_WAIT) { 
+             DequeueSpecificWaiter (&node) ;       // unlink from WaitSet
+             assert(node._notified == 0, "invariant");
+             node.TState = ObjectWaiter::TS_RUN ; 
+          }
+-         SpinRelease (&_WaitSetLock) ; 
++         Thread::SpinRelease (&_WaitSetLock) ;
+      }
+ 
+      // The thread is now either on off-list (TS_RUN), 
+@@ -3936,9 +4013,7 @@
+ 
+      // post monitor waited event.  Note that this is past-tense, we are done waiting.
+      if (JvmtiExport::should_post_monitor_waited()) {
+-        JvmtiExport::post_monitor_waited(jt, this, (ret == OS_TIMEOUT) ? true : false);
+-        // Just to err on the conservative side ...
+-        if (_succ == Self) _succ = NULL ; 
++       JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT);
+      }
+      OrderAccess::fence() ; 
+ 
+@@ -3952,7 +4027,7 @@
+      } else {
+          guarantee (v == ObjectWaiter::TS_ENTER || v == ObjectWaiter::TS_CXQ, "invariant") ; 
+          ReenterI (Self, &node) ; 
+-         node.TState = ObjectWaiter::TS_RUN ; 
++         node.wait_reenter_end(this);
+      }
+ 
+      // Self has reacquired the lock.  
+@@ -4009,7 +4084,7 @@
+ 
+   int Policy = Knob_MoveNotifyee ; 
+ 
+-  SpinAcquire (&_WaitSetLock, "WaitSet - notify") ; 
++  Thread::SpinAcquire (&_WaitSetLock, "WaitSet - notify") ;
+   ObjectWaiter * iterator = DequeueWaiter() ; 
+   if (iterator != NULL) { 
+      TEVENT (Notify1 - Transfer) ; 
+@@ -4099,6 +4174,10 @@
+         ev->unpark() ; 
+      }
+ 
++     if (Policy < 4) {
++       iterator->wait_reenter_begin(this);
++     }
++
+      // _WaitSetLock protects the wait queue, not the EntryList.  We could
+      // move the add-to-EntryList operation, above, outside the critical section
+      // protected by _WaitSetLock.  In practice that's not useful.  With the 
+@@ -4108,13 +4187,14 @@
+      // critical section.
+   }
+ 
+-  SpinRelease (&_WaitSetLock) ; 
++  Thread::SpinRelease (&_WaitSetLock) ;
+ 
+   if (iterator != NULL && ObjectSynchronizer::_sync_Notifications != NULL) { 
+      ObjectSynchronizer::_sync_Notifications->inc() ; 
+   }
+ }
+ 
++
+ void ObjectMonitor::notifyAll(TRAPS) {
+   CHECK_OWNER();
+   ObjectWaiter* iterator;
+@@ -4126,7 +4206,7 @@
+ 
+   int Policy = Knob_MoveNotifyee ; 
+   int Tally = 0 ; 
+-  SpinAcquire (&_WaitSetLock, "WaitSet - notifyall") ; 
++  Thread::SpinAcquire (&_WaitSetLock, "WaitSet - notifyall") ;
+   
+   for (;;) {
+      iterator = DequeueWaiter () ; 
+@@ -4223,6 +4303,9 @@
+         ev->unpark() ; 
+      }
+ 
++     if (Policy < 4) {
++       iterator->wait_reenter_begin(this);
++     }
+ 
+      // _WaitSetLock protects the wait queue, not the EntryList.  We could
+      // move the add-to-EntryList operation, above, outside the critical section
+@@ -4233,7 +4316,7 @@
+      // critical section.
+   }
+ 
+-  SpinRelease (&_WaitSetLock) ; 
++  Thread::SpinRelease (&_WaitSetLock) ;
+ 
+   if (Tally != 0 && ObjectSynchronizer::_sync_Notifications != NULL) { 
+      ObjectSynchronizer::_sync_Notifications->inc(Tally) ; 
+@@ -4631,6 +4714,3 @@
+ }
+ 
+ #endif
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/synchronizer.hpp openjdk/hotspot/src/share/vm/runtime/synchronizer.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/synchronizer.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/synchronizer.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)synchronizer.hpp	1.71 07/05/26 16:04:34 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/task.cpp openjdk/hotspot/src/share/vm/runtime/task.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/task.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/task.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)task.cpp	1.27 07/05/05 17:06:59 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/task.hpp openjdk/hotspot/src/share/vm/runtime/task.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/task.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/task.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)task.hpp	1.23 07/05/05 17:06:59 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/thread.cpp openjdk/hotspot/src/share/vm/runtime/thread.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/thread.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/thread.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)thread.cpp	1.809 07/06/01 01:36:09 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -146,7 +143,7 @@
+   _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true);
+   _suspend_flags = 0;
+ 
+-  // thread-specific hashCode stream generator state. 
++  // thread-specific hashCode stream generator state - Marsaglia shift-xor form
+   _hashStateX = os::random() ; 
+   _hashStateY = 842502087 ; 
+   _hashStateZ = 0x8767 ;    // (int)(3579807591LL & 0xffff) ; 
+@@ -156,7 +153,18 @@
+   _schedctl = NULL ; 
+   _Stalled  = 0 ; 
+   _TypeTag  = 0x2BAD ; 
++
++  // Many of the following fields are effectively final - immutable
++  // Note that nascent threads can't use the Native Monitor-Mutex
++  // construct until the _MutexEvent is initialized ...
++  // CONSIDER: instead of using a fixed set of purpose-dedicated ParkEvents
++  // we might instead use a stack of ParkEvents that we could provision on-demand.
++  // The stack would act as a cache to avoid calls to ParkEvent::Allocate()
++  // and ::Release()
+   _ParkEvent = ParkEvent::Allocate (this) ; 
++  _SleepEvent  = ParkEvent::Allocate (this) ;
++  _MutexEvent  = ParkEvent::Allocate (this) ;
++  _MuxEvent    = ParkEvent::Allocate (this) ;
+ 
+ #ifdef CHECK_UNHANDLED_OOPS
+   if (CheckUnhandledOops) {
+@@ -208,11 +216,12 @@
+   delete last_handle_mark();
+   assert(last_handle_mark() == NULL, "check we have reached the end");
+ 
+-  // It's possible we can encounter a null _ParkEvent in stillborn threads.
+-  if (_ParkEvent != NULL) {
+-     ParkEvent::Release (_ParkEvent) ; 
+-     _ParkEvent = NULL ; 
+-  }
++  // It's possible we can encounter a null _ParkEvent, etc., in stillborn threads.
++  // We NULL out the fields for good hygiene.
++  ParkEvent::Release (_ParkEvent)   ; _ParkEvent   = NULL ;
++  ParkEvent::Release (_SleepEvent)  ; _SleepEvent  = NULL ;
++  ParkEvent::Release (_MutexEvent)  ; _MutexEvent  = NULL ;
++  ParkEvent::Release (_MuxEvent)    ; _MuxEvent    = NULL ;
+ 
+   delete handle_area();
+ 
+@@ -714,7 +723,7 @@
+ 
+ #ifdef ASSERT
+ void Thread::print_owned_locks_on(outputStream* st) const {  
+-  Mutex *cur = _owned_locks;
++  Monitor *cur = _owned_locks;
+   if (cur == NULL) {
+     st->print(" (no locks) ");
+   } else {
+@@ -729,7 +738,7 @@
+ static int ref_use_count  = 0;
+ 
+ bool Thread::owns_locks_but_compiled_lock() const {
+-  for(Mutex *cur = _owned_locks; cur; cur = cur->next()) {
++  for(Monitor *cur = _owned_locks; cur; cur = cur->next()) {
+     if (cur != Compile_lock) return true;
+   }
+   return false;
+@@ -756,7 +765,7 @@
+         && !Universe::is_bootstrapping()) {
+       // Make sure we do not hold any locks that the VM thread also uses.
+       // This could potentially lead to deadlocks      
+-      for(Mutex *cur = _owned_locks; cur; cur = cur->next()) {
++      for(Monitor *cur = _owned_locks; cur; cur = cur->next()) {
+         // Threads_lock is special, since the safepoint synchronization will not start before this is
+         // acquired. Hence, a JavaThread cannot be holding it at a safepoint. So is VMOperationRequest_lock,
+         // since it is used to transfer control between JavaThreads and the VMThread
+@@ -2709,6 +2718,10 @@
+   _task  = NULL;
+   _queue = queue;
+   _counters = counters;
++
++#ifndef PRODUCT
++  _ideal_graph_printer = NULL;
++#endif
+ }
+ 
+ 
+@@ -2834,8 +2847,6 @@
+   // crash Linux VM, see notes in os_linux.cpp.
+   main_thread->create_stack_guard_pages();
+ 
+-  HandleMark hm;
+-
+   // Initialize Java-Leve synchronization subsystem
+   ObjectSynchronizer::Initialize() ; 
+ 
+@@ -2847,6 +2858,8 @@
+     return status;
+   }
+ 
++  HandleMark hm;
++
+   { MutexLocker mu(Threads_lock);
+     Threads::add(main_thread);
+   }
+@@ -3096,6 +3109,28 @@
+       // Try to load the agent from the standard dll directory
+       hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), name);
+       library = hpi::dll_load(buffer, ebuf, sizeof ebuf);
++#ifdef KERNEL
++      // Download instrument dll
++      if (library == NULL && strcmp(name, "instrument") == 0) {
++        char *props = Arguments::get_kernel_properties();
++        char *home  = Arguments::get_java_home();
++        const char *fmt   = "%s/bin/java %s -Dkernel.background.download=false"
++                      " sun.jkernel.DownloadManager -download client_jvm";
++        int length = strlen(props) + strlen(home) + strlen(fmt) + 1;
++        char *cmd = AllocateHeap(length);
++        jio_snprintf(cmd, length, fmt, home, props);
++        int status = os::fork_and_exec(cmd);
++        FreeHeap(props);
++        FreeHeap(cmd);
++        if (status == -1) {
++          warning(cmd);
++          vm_exit_during_initialization("fork_and_exec failed: %s",
++                                         strerror(errno));
++        }
++        // when this comes back the instrument.dll should be where it belongs.
++        library = hpi::dll_load(buffer, ebuf, sizeof ebuf);
++      }
++#endif // KERNEL
+       if (library == NULL) { // Try the local directory
+         char ns[1] = {0};
+         hpi::dll_build_name(buffer, sizeof(buffer), ns, name);
+@@ -3180,6 +3215,33 @@
+   JvmtiExport::enter_primordial_phase();
+ }
+ 
++extern "C" {
++  typedef void (JNICALL *Agent_OnUnload_t)(JavaVM *);
++}
++
++void Threads::shutdown_vm_agents() {
++  // Send any Agent_OnUnload notifications
++  const char *on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS;
++  extern struct JavaVM_ main_vm;
++  for (AgentLibrary* agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
++
++    // Find the Agent_OnUnload function.
++    for (uint symbol_index = 0; symbol_index < ARRAY_SIZE(on_unload_symbols); symbol_index++) {
++      Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t,
++               hpi::dll_lookup(agent->os_lib(), on_unload_symbols[symbol_index]));
++
++      // Invoke the Agent_OnUnload function
++      if (unload_entry != NULL) {
++        JavaThread* thread = JavaThread::current();
++        ThreadToNativeFromVM ttn(thread);
++        HandleMark hm(thread);
++        (*unload_entry)(&main_vm);
++        break;
++      }
++    }
++  }
++}
++
+ // Called for after the VM is initialized for -Xrun libraries which have not been converted to agent libraries
+ // Invokes JVM_OnLoad
+ void Threads::create_vm_init_libraries() {
+@@ -3322,6 +3384,11 @@
+     VMThread::destroy();
+   }
+ 
++  // clean up ideal graph printers
++#if defined(COMPILER2) && !defined(PRODUCT)
++  IdealGraphPrinter::clean_up();
++#endif
++
+   // Now, all Java threads are gone except daemon threads. Daemon threads
+   // running Java code or in VM are stopped by the Safepoint. However,
+   // daemon threads executing native code are still running.  But they
+@@ -3690,11 +3757,12 @@
+ 
+ // Lifecycle management for TSM ParkEvents.
+ // ParkEvents are type-stable (TSM). 
++// In our particular implementation they happen to be immortal.
+ // 
+ // We manage concurrency on the FreeList with a CAS-based
+ // detach-modify-reattach idiom that avoids the ABA problems
+ // that would otherwise be present in a simple CAS-based
+-// push-pop implementation. 
++// push-pop implementation.   (push-one and pop-all)
+ //
+ // Caveat: Allocate() and Release() may be called from threads
+ // other than the thread associated with the Event!
+@@ -3714,7 +3782,7 @@
+ ParkEvent * volatile ParkEvent::FreeList = NULL ; 
+ 
+ ParkEvent * ParkEvent::Allocate (Thread * t) { 
+-  guarantee (t != NULL, "invariant") ; 
++  // In rare cases -- JVM_RawMonitor* operations -- we can find t == null.
+   ParkEvent * ev ; 
+ 
+   // Start by trying to recycle an existing but unassociated
+@@ -3722,7 +3790,7 @@
+   for (;;) { 
+     ev = FreeList ; 
+     if (ev == NULL) break ; 
+-    // 1: Detach
++    // 1: Detach - sequester or privatize the list
+     // Tantamount to ev = Swap (&FreeList, NULL)
+     if (Atomic::cmpxchg_ptr (NULL, &FreeList, ev) != ev) {
+        continue ; 
+@@ -3757,40 +3825,58 @@
+     guarantee (ev->AssociatedWith == NULL, "invariant") ; 
+   } else {
+     // Do this the hard way -- materialize a new ParkEvent.
+-    // In rare cases an allocating thread might detach
+-    // a long list -- installing null into FreeList --and 
+-    // then stall.  Another thread calling Allocate() would see 
+-    // FreeList == null and then invoke the ctor.  In this case we 
+-    // end up with more ParkEvents in circulation than we need, but 
+-    // the race is rare and the outcome is benign.  
+-    // Ideally, the # of extant ParkEvents is equal to the
+-    // maximum # of threads that existed at any one time.
+-    // Because of the race mentioned above, segments of the
+-    // freelist can be transiently inaccessible.  At worst
+-    // we may end up with the # of ParkEvents in circulation
+-    // slightly above the ideal.  
++    // In rare cases an allocating thread might detach a long list --
++    // installing null into FreeList -- and then stall or be obstructed.
++    // A 2nd thread calling Allocate() would see FreeList == null.
++    // The list held privately by the 1st thread is unavailable to the 2nd thread.
++    // In that case the 2nd thread would have to materialize a new ParkEvent,
++    // even though free ParkEvents existed in the system.  In this case we end up
++    // with more ParkEvents in circulation than we need, but the race is
++    // rare and the outcome is benign.  Ideally, the # of extant ParkEvents
++    // is equal to the maximum # of threads that existed at any one time.
++    // Because of the race mentioned above, segments of the freelist
++    // can be transiently inaccessible.  At worst we may end up with the
++    // # of ParkEvents in circulation slightly above the ideal.
++    // Note that if we didn't have the TSM/immortal constraint, then
++    // when reattaching, above, we could trim the list.
+     ev = new ParkEvent () ; 
++    guarantee ((intptr_t(ev) & 0xFF) == 0, "invariant") ;
+   }
++  ev->reset() ;                     // courtesy to caller
+   ev->AssociatedWith = t ;          // Associate ev with t
+   ev->FreeNext       = NULL ; 
+   return ev ; 
+ }
+ 
+-
+-
+ void ParkEvent::Release (ParkEvent * ev) {
+   if (ev == NULL) return ; 
+-  guarantee (ev->AssociatedWith != NULL, "invariant") ; 
+   guarantee (ev->FreeNext == NULL      , "invariant") ; 
+   ev->AssociatedWith = NULL ; 
+   for (;;) { 
+     // Push ev onto FreeList
++    // The mechanism is "half" lock-free.
+     ParkEvent * List = FreeList ; 
+     ev->FreeNext = List ; 
+     if (Atomic::cmpxchg_ptr (ev, &FreeList, List) == List) break ; 
+   }
+ }
+ 
++// Override operator new and delete so we can ensure that the
++// least significant byte of ParkEvent addresses is 0.
++// Beware that excessive address alignment is undesirable
++// as it can result in D$ index usage imbalance as
++// well as bank access imbalance on Niagara-like platforms,
++// although Niagara's hash function should help.
++
++void * ParkEvent::operator new (size_t sz) {
++  return (void *) ((intptr_t (CHeapObj::operator new (sz + 256)) + 256) & -256) ;
++}
++
++void ParkEvent::operator delete (void * a) {
++  // ParkEvents are type-stable and immortal ...
++  ShouldNotReachHere();
++}
++
+ 
+ // 6399321 As a temporary measure we copied & modified the ParkEvent::
+ // allocate() and release() code for use by Parkers.  The Parker:: forms
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/threadCritical.hpp openjdk/hotspot/src/share/vm/runtime/threadCritical.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/threadCritical.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/threadCritical.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)threadCritical.hpp	1.13 07/05/05 17:07:00 JVM"
+-#endif
+ /*
+  * Copyright 2001-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -54,5 +51,3 @@
+   ThreadCritical();
+   ~ThreadCritical();
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/thread.hpp openjdk/hotspot/src/share/vm/runtime/thread.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/thread.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/thread.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)thread.hpp	1.453 07/07/05 17:14:54 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -32,6 +29,7 @@
+ class JvmtiGetLoadedClassesClosure;
+ class ThreadStatistics;
+ class ConcurrentLocksDump;
++class ParkEvent ;
+ 
+ class ciEnv;
+ class CompileThread;
+@@ -39,7 +37,6 @@
+ class CompileTask;
+ class CompileQueue;
+ class CompilerCounters;
+-class RawMonitor;
+ class vframeArray;
+ 
+ class DeoptResourceMark;
+@@ -47,6 +44,7 @@
+ 
+ class GCTaskQueue;
+ class ThreadClosure;
++class IdealGraphPrinter;
+ 
+ // Class hierarchy
+ // - Thread
+@@ -458,15 +456,16 @@
+ #ifdef ASSERT
+  private:
+   // Deadlock detection support for Mutex locks. List of locks own by thread.
+-  Mutex *_owned_locks;
++  Monitor *_owned_locks;
+   // Mutex::set_owner_implementation is the only place where _owned_locks is modified,
+   // thus the friendship
+   friend class Mutex;
++  friend class Monitor;
+ 
+  public:  
+   void print_owned_locks_on(outputStream* st) const;
+   void print_owned_locks() const		 { print_owned_locks_on(tty);	 }
+-  Mutex* owned_locks() const			 { return _owned_locks;          }
++  Monitor * owned_locks() const                  { return _owned_locks;          }
+   bool owns_locks() const                        { return owned_locks() != NULL; }  
+   bool owns_locks_but_compiled_lock() const;
+ 
+@@ -511,17 +510,34 @@
+  public:
+   volatile intptr_t _Stalled ; 
+   volatile int _TypeTag ; 
+-  class ParkEvent * _ParkEvent ; 
++  ParkEvent * _ParkEvent ;                     // for synchronized()
++  ParkEvent * _SleepEvent ;                    // for Thread.sleep
++  ParkEvent * _MutexEvent ;                    // for native internal Mutex/Monitor
++  ParkEvent * _MuxEvent ;                      // for low-level muxAcquire-muxRelease
++  int NativeSyncRecursion ;                    // diagnostic
++
+   volatile int _OnTrap ;                       // Resume-at IP delta
+-  int _hashStateW ; 
+-  int _hashStateX ;                            // thread-specific hashCode generator state
+-  int _hashStateY ; 
+-  int _hashStateZ ; 
++  jint _hashStateW ;                           // Marsaglia Shift-XOR thread-local RNG
++  jint _hashStateX ;                           // thread-specific hashCode generator state
++  jint _hashStateY ;
++  jint _hashStateZ ;
+   void * _schedctl ; 
+-  intptr_t _ScratchA, _ScratchB ;              // Scratch locations for fast-path sync code
+ 
++  intptr_t _ScratchA, _ScratchB ;              // Scratch locations for fast-path sync code
+   static ByteSize ScratchA_offset()            { return byte_offset_of(Thread, _ScratchA ); }
+   static ByteSize ScratchB_offset()            { return byte_offset_of(Thread, _ScratchB ); }
++
++  volatile jint rng [4] ;                      // RNG for spin loop
++
++  // Low-level leaf-lock primitives used to implement synchronization
++  // and native monitor-mutex infrastructure.
++  // Not for general synchronization use.
++  static void SpinAcquire (volatile int * Lock, const char * Name) ;
++  static void SpinRelease (volatile int * Lock) ;
++  static void muxAcquire  (volatile intptr_t * Lock, const char * Name) ;
++  static void muxAcquireW (volatile intptr_t * Lock, ParkEvent * ev) ;
++  static void muxRelease  (volatile intptr_t * Lock) ;
++
+ };
+ 
+ // Inline implementation of Thread::current()
+@@ -1513,6 +1529,14 @@
+     _log = log;
+   }
+ 
++#ifndef PRODUCT
++private:
++  IdealGraphPrinter *_ideal_graph_printer;
++public:
++  IdealGraphPrinter *ideal_graph_printer()                       { return _ideal_graph_printer; }
++  void set_ideal_graph_printer(IdealGraphPrinter *n)             { _ideal_graph_printer = n; }
++#endif
++
+   // Get/set the thread's current task
+   CompileTask*  task()                           { return _task; }
+   void          set_task(CompileTask* task)      { _task = task; }
+@@ -1548,6 +1572,7 @@
+   static void convert_vm_init_libraries_to_agents();
+   static void create_vm_init_libraries();
+   static void create_vm_init_agents();
++  static void shutdown_vm_agents();
+   static bool destroy_vm();
+   // Supported VM versions via JNI
+   // Includes JNI_VERSION_1_1
+@@ -1658,15 +1683,16 @@
+ // unpark threads. 
+ //
+ // The base-class, PlatformEvent, is platform-specific while the ParkEvent is
+-// platform-independent.  PlatformEvent provides park(), unpark(), etc.  
++// platform-independent.  PlatformEvent provides park(), unpark(), etc., and
++// is abstract -- that is, a PlatformEvent should never be instantiated except
++// as part of a ParkEvent.
+ // Equivalently we could have defined a platform-independent base-class that 
+ // exported Allocate(), Release(), etc.  The platform-specific class would extend 
+ // that base-class, adding park(), unpark(), etc.  
+ //
+-// A word of caution: The JVM uses 3 very similar constructs:
++// A word of caution: The JVM uses 2 very similar constructs:
+ // 1. ParkEvent are used for Java-level "monitor" synchronization.
+ // 2. Parkers are used by JSR166-JUC park-unpark. 
+-// 3. interrupt_event() is used for threads blocked in Thread.sleep().
+ //
+ // We'll want to eventually merge these redundant facilities and use ParkEvent.
+ 
+@@ -1680,16 +1706,18 @@
+     intptr_t RawThreadIdentity ;        // LWPID etc
+     volatile int Incarnation ;
+ 
++    // diagnostic : keep track of last thread to wake this thread.
++    // this is useful for construction of dependency graphs.
++    void * LastWaker ;
++
+   public:
+-    // MCS-CLH list linkage
++    // MCS-CLH list linkage and Native Mutex/Monitor
+     ParkEvent * volatile ListNext ; 
+     ParkEvent * volatile ListPrev ; 
+     volatile intptr_t OnList ; 
+     volatile int TState ; 
+-
+-    // diagnostic : keep track of last thread to wake this thread.
+-    // this is useful for construction of dependency graphs.
+-    void * LastWaker ; 
++    volatile int Notified ;             // for native monitor construct
++    volatile int IsWaiting ;            // Enqueued on WaitSet
+    
+ 
+   private:
+@@ -1712,11 +1740,18 @@
+        ListPrev       = NULL ; 
+        OnList         = 0 ; 
+        TState         = 0 ; 
++       Notified       = 0 ;
++       IsWaiting      = 0 ;
+     }
+ 
++    // We use placement-new to force ParkEvent instances to be
++    // aligned on 256-byte address boundaries.  This ensures that the least
++    // significant byte of a ParkEvent address is always 0.
++
++    void * operator new (size_t sz) ;
++    void operator delete (void * a) ;
++
+   public:
+     static ParkEvent * Allocate (Thread * t) ; 
+     static void Release (ParkEvent * e) ; 
+ } ; 
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/threadLocalStorage.cpp openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/threadLocalStorage.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)threadLocalStorage.cpp	1.46 07/05/05 17:07:00 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -50,4 +47,3 @@
+   set_thread_index(os::allocate_thread_local_storage());
+   generate_code_for_get_thread();
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/threadLocalStorage.hpp openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/threadLocalStorage.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)threadLocalStorage.hpp	1.45 07/05/05 17:07:00 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -63,4 +60,3 @@
+   static void pd_invalidate_all();
+   
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/timer.cpp openjdk/hotspot/src/share/vm/runtime/timer.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/timer.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/timer.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)timer.cpp	1.33 07/05/05 17:06:59 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/timer.hpp openjdk/hotspot/src/share/vm/runtime/timer.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/timer.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/timer.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)timer.hpp	1.36 07/05/05 17:06:59 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/unhandledOops.cpp openjdk/hotspot/src/share/vm/runtime/unhandledOops.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/unhandledOops.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/unhandledOops.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)unhandledOops.cpp	1.11 07/05/05 17:07:00 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/unhandledOops.hpp openjdk/hotspot/src/share/vm/runtime/unhandledOops.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/unhandledOops.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/unhandledOops.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)unhandledOops.hpp	1.7 07/05/05 17:07:01 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframeArray.cpp openjdk/hotspot/src/share/vm/runtime/vframeArray.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/vframeArray.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vframeArray.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vframeArray.cpp	1.144 07/06/08 15:21:45 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -141,9 +138,6 @@
+ 					 frame* caller,
+ 					 bool is_top_frame,
+ 					 int exec_mode) {
+-#if  defined(CC_INTERP) && !defined(IA64)
+-  ShouldNotReachHere();
+-#else
+   JavaThread* thread = (JavaThread*) Thread::current();
+ 
+   // Look at bci and decide on bcp and continuation pc
+@@ -169,7 +163,7 @@
+   // For Compiler2, there should be no pending exception when deoptimizing at monitorenter
+   // because there is no safepoint at the null pointer check (it is either handled explicitly
+   // or prior to the monitorenter) and asynchronous exceptions are not made "pending" by the
+-  // runtime interface for the slow case (see JRT_ENTRY_NO_ASYNC).  If an asynchronous 
++  // runtime interface for the slow case (see JRT_ENTRY_FOR_MONITORENTER).  If an asynchronous
+   // exception was processed, the bytecode pointer would have to be extended one bytecode beyond
+   // the monitorenter to place it in the proper exception range.
+   //
+@@ -373,6 +367,7 @@
+ 
+ #ifndef PRODUCT
+   if (TraceDeoptimization && Verbose) {
++    ttyLocker ttyl;
+     tty->print_cr("[%d Interpreted Frame]", ++unpack_counter);
+     iframe()->print_on(tty);
+     RegisterMap map(thread);
+@@ -403,7 +398,6 @@
+ 
+   _locals = _expressions = NULL;
+ 
+-#endif /* !CC_INTERP */
+ }
+ 
+ int vframeArrayElement::on_stack_size(int callee_parameters,
+@@ -527,11 +521,6 @@
+     caller_frame = *element(index)->iframe();
+   }
+ 
+-#ifdef CC_INTERP
+-#ifndef IA64
+-  ShouldNotReachHere();
+-#endif
+-#endif
+ 
+   deallocate_monitor_chunks();
+ }
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframeArray.hpp openjdk/hotspot/src/share/vm/runtime/vframeArray.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/vframeArray.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vframeArray.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vframeArray.hpp	1.77 07/05/05 17:07:01 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -202,4 +199,3 @@
+ #endif
+   
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframe.cpp openjdk/hotspot/src/share/vm/runtime/vframe.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/vframe.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vframe.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vframe.cpp	1.162 07/05/17 16:07:02 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -547,7 +544,8 @@
+ void javaVFrame::print_value() const {
+   methodOop  m = method();
+   klassOop   k = m->method_holder();
+-  tty->print_cr("frame( sp=" INTPTR_FORMAT ", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT ")", _fr.sp(), _fr.fp(), _fr.pc());
++  tty->print_cr("frame( sp=" INTPTR_FORMAT ", unextended_sp=" INTPTR_FORMAT ", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT ")",
++                _fr.sp(),  _fr.unextended_sp(), _fr.fp(), _fr.pc());
+   tty->print("%s.%s", Klass::cast(k)->internal_name(), m->name()->as_C_string());
+ 
+   if (!m->is_native()) {
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframe_hp.cpp openjdk/hotspot/src/share/vm/runtime/vframe_hp.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/vframe_hp.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vframe_hp.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vframe_hp.cpp	1.158 07/05/05 17:07:02 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -163,130 +160,17 @@
+   return result;
+ }
+ 
+-StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const {
+-  if (sv->is_location()) {
+-    // Stack or register value
+-    Location loc = ((LocationValue *)sv)->location();
+-
+-#ifdef SPARC
+-    // %%%%% Callee-save floats will NOT be working on a Sparc until we
+-    // handle the case of a 2 floats in a single double register.
+-    assert( !(loc.is_register() && loc.type() == Location::float_in_dbl), "Sparc does not handle callee-save floats yet" );
+-#endif // SPARC
+-
+-    // First find address of value
+-
+-    address value_addr = loc.is_register()
+-      // Value was in a callee-save register
+-      ? register_map()->location(VMRegImpl::as_VMReg(loc.register_number()))
+-      // Else value was directly saved on the stack. The frame's original stack pointer,
+-      // before any extension by its callee (due to Compiler1 linkage on SPARC), must be used.
+-      : ((address)_fr.unextended_sp()) + loc.stack_offset();
+-
+-    // Then package it right depending on type
+-    // Note: the transfer of the data is thru a union that contains
+-    // an intptr_t. This is because an interpreter stack slot is
+-    // really an intptr_t. The use of a union containing an intptr_t
+-    // ensures that on a 64 bit platform we have proper alignment
+-    // and that we store the value where the interpreter will expect
+-    // to find it (i.e. proper endian). Similarly on a 32bit platform
+-    // using the intptr_t ensures that when a value is larger than
+-    // a stack slot (jlong/jdouble) that we capture the proper part
+-    // of the value for the stack slot in question.
+-    //
+-    switch( loc.type() ) {
+-    case Location::float_in_dbl: { // Holds a float in a double register?
+-      // The callee has no clue whether the register holds a float,
+-      // double or is unused.  He always saves a double.  Here we know
+-      // a double was saved, but we only want a float back.  Narrow the
+-      // saved double to the float that the JVM wants.
+-      assert( loc.is_register(), "floats always saved to stack in 1 word" );
+-      union { intptr_t p; jfloat jf; } value;
+-      value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
+-      value.jf = (jfloat) *(jdouble*) value_addr;
+-      return new StackValue(value.p); // 64-bit high half is stack junk
+-    }
+-    case Location::int_in_long: { // Holds an int in a long register?
+-      // The callee has no clue whether the register holds an int,
+-      // long or is unused.  He always saves a long.  Here we know
+-      // a long was saved, but we only want an int back.  Narrow the
+-      // saved long to the int that the JVM wants.
+-      assert( loc.is_register(), "ints always saved to stack in 1 word" );
+-      union { intptr_t p; jint ji;} value;
+-      value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
+-      value.ji = (jint) *(jlong*) value_addr;
+-      return new StackValue(value.p); // 64-bit high half is stack junk
+-    }
+-#ifdef _LP64
+-    case Location::dbl:
+-      // Double value in an aligned adjacent pair
+-      return new StackValue(*(intptr_t*)value_addr);
+-    case Location::lng:
+-      // Long   value in an aligned adjacent pair
+-      return new StackValue(*(intptr_t*)value_addr);
+-#endif
+-    case Location::oop: {
+-      Handle h(*(oop *)value_addr); // Wrap a handle around the oop
+-      return new StackValue(h);
+-    }
+-    case Location::addr: {
+-      ShouldNotReachHere(); // both C1 and C2 now inline jsrs
+-    }
+-    case Location::normal: {
+-      // Just copy all other bits straight through
+-      union { intptr_t p; jint ji;} value;
+-      value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
+-      value.ji = *(jint*)value_addr;
+-      return new StackValue(value.p);
+-    }
+-    case Location::invalid:
+-      return new StackValue();
+-    default:
+-      ShouldNotReachHere();
+-    }
+ 
+-  } else if (sv->is_constant_int()) {
+-    // Constant int: treat same as register int.
+-    union { intptr_t p; jint ji;} value;
+-    value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
+-    value.ji = (jint)((ConstantIntValue*)sv)->value();
+-    return new StackValue(value.p); 
+-  } else if (sv->is_constant_oop()) {
+-    // constant oop        
+-    return new StackValue(((ConstantOopReadValue *)sv)->value());
+-#ifdef _LP64
+-  } else if (sv->is_constant_double()) {
+-    // Constant double in a single stack slot
+-    union { intptr_t p; double d; } value;
+-    value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
+-    value.d = ((ConstantDoubleValue *)sv)->value();
+-    return new StackValue(value.p);
+-  } else if (sv->is_constant_long()) {
+-    // Constant long in a single stack slot
+-    union { intptr_t p; jlong jl; } value;
+-    value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
+-    value.jl = ((ConstantLongValue *)sv)->value();
+-    return new StackValue(value.p);
+-#endif
+-  }
++// The implementation of the following two methods was factorized into the
++// class StackValue because it is also used from within deoptimization.cpp for
++// rematerialization and relocking of non-escaping objects.
+ 
+-  // Unknown ScopeValue type
+-  ShouldNotReachHere();    
+-  return new StackValue((intptr_t) 0);   // dummy  
++StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const {
++  return StackValue::create_stack_value(&_fr, register_map(), sv);
+ }
+ 
+ BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const {
+-  assert(location.is_stack(), "for now we only look at the stack");
+-  int word_offset = location.stack_offset() / wordSize;
+-  // (stack picture)
+-  // high: [     ]  word_offset + 1
+-  // low   [     ]  word_offset
+-  //       
+-  // sp->  [     ]  0
+-  // the word_offset is the distance from the stack pointer to the lowest address
+-  // The frame's original stack pointer, before any extension by its callee
+-  // (due to Compiler1 linkage on SPARC), must be used.
+-  return (BasicLock*) (fr().unextended_sp() + word_offset);
++  return StackValue::resolve_monitor_lock(&_fr, location);
+ }
+ 
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframe_hp.hpp openjdk/hotspot/src/share/vm/runtime/vframe_hp.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/vframe_hp.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vframe_hp.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vframe_hp.hpp	1.54 07/05/05 17:07:01 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframe.hpp openjdk/hotspot/src/share/vm/runtime/vframe.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/vframe.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vframe.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vframe.hpp	1.89 07/05/17 16:07:04 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/virtualspace.cpp openjdk/hotspot/src/share/vm/runtime/virtualspace.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/virtualspace.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/virtualspace.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)virtualspace.cpp	1.62 07/05/05 17:07:03 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -34,21 +31,156 @@
+   initialize(size, 0, false, NULL);
+ }
+ 
+-ReservedSpace::ReservedSpace(size_t size, size_t forced_base_alignment,
++ReservedSpace::ReservedSpace(size_t size, size_t alignment,
+                              bool large, char* requested_address) {
+-  initialize(size, forced_base_alignment, large, requested_address);
++  initialize(size, alignment, large, requested_address);
+ }
+ 
+-void ReservedSpace::initialize(size_t size, size_t forced_base_alignment,
+-                               bool large, char* requested_address) {
++char *
++ReservedSpace::align_reserved_region(char* addr, const size_t len,
++                                     const size_t prefix_size,
++                                     const size_t prefix_align,
++                                     const size_t suffix_size,
++                                     const size_t suffix_align)
++{
++  assert(addr != NULL, "sanity");
++  const size_t required_size = prefix_size + suffix_size;
++  assert(len >= required_size, "len too small");
++
++  const size_t s = size_t(addr);
++  const size_t beg_ofs = s + prefix_size & suffix_align - 1;
++  const size_t beg_delta = beg_ofs == 0 ? 0 : suffix_align - beg_ofs;
++
++  if (len < beg_delta + required_size) {
++     return NULL; // Cannot do proper alignment.
++  }
++  const size_t end_delta = len - (beg_delta + required_size);
++
++  if (beg_delta != 0) {
++    os::release_memory(addr, beg_delta);
++  }
++
++  if (end_delta != 0) {
++    char* release_addr = (char*) (s + beg_delta + required_size);
++    os::release_memory(release_addr, end_delta);
++  }
++
++  return (char*) (s + beg_delta);
++}
++
++char* ReservedSpace::reserve_and_align(const size_t reserve_size,
++                                       const size_t prefix_size,
++                                       const size_t prefix_align,
++                                       const size_t suffix_size,
++                                       const size_t suffix_align)
++{
++  assert(reserve_size > prefix_size + suffix_size, "should not be here");
++
++  char* raw_addr = os::reserve_memory(reserve_size, NULL, prefix_align);
++  if (raw_addr == NULL) return NULL;
++
++  char* result = align_reserved_region(raw_addr, reserve_size, prefix_size,
++                                       prefix_align, suffix_size,
++                                       suffix_align);
++  if (result == NULL && !os::release_memory(raw_addr, reserve_size)) {
++    fatal("os::release_memory failed");
++  }
++
++#ifdef ASSERT
++  if (result != NULL) {
++    const size_t raw = size_t(raw_addr);
++    const size_t res = size_t(result);
++    assert(res >= raw, "alignment decreased start addr");
++    assert(res + prefix_size + suffix_size <= raw + reserve_size,
++           "alignment increased end addr");
++    assert((res & prefix_align - 1) == 0, "bad alignment of prefix");
++    assert((res + prefix_size & suffix_align - 1) == 0,
++           "bad alignment of suffix");
++  }
++#endif
++
++  return result;
++}
++
++ReservedSpace::ReservedSpace(const size_t prefix_size,
++                             const size_t prefix_align,
++                             const size_t suffix_size,
++                             const size_t suffix_align)
++{
++  assert(prefix_size != 0, "sanity");
++  assert(prefix_align != 0, "sanity");
++  assert(suffix_size != 0, "sanity");
++  assert(suffix_align != 0, "sanity");
++  assert((prefix_size & prefix_align - 1) == 0,
++    "prefix_size not divisible by prefix_align");
++  assert((suffix_size & suffix_align - 1) == 0,
++    "suffix_size not divisible by suffix_align");
++  assert((suffix_align & prefix_align - 1) == 0,
++    "suffix_align not divisible by prefix_align");
++
++  // On systems where the entire region has to be reserved and committed up
++  // front, the compound alignment normally done by this method is unnecessary.
++  const bool try_reserve_special = UseLargePages &&
++    prefix_align == os::large_page_size();
++  if (!os::can_commit_large_page_memory() && try_reserve_special) {
++    initialize(prefix_size + suffix_size, prefix_align, true);
++    return;
++  }
+ 
+-  assert(size % os::vm_allocation_granularity() == 0,
+-         "size not allocation aligned");
+-  assert((forced_base_alignment % os::vm_allocation_granularity()) == 0,
+-         "size not allocation aligned");
+   _base = NULL;
+   _size = 0;
++  _alignment = 0;
+   _special = false;
++
++  // Optimistically try to reserve the exact size needed.
++  const size_t size = prefix_size + suffix_size;
++  char* addr = os::reserve_memory(size, NULL, prefix_align);
++  if (addr == NULL) return;
++
++  // Check whether the result has the needed alignment (unlikely unless
++  // prefix_align == suffix_align).
++  const size_t ofs = size_t(addr) + prefix_size & suffix_align - 1;
++  if (ofs != 0) {
++    // Wrong alignment.  Release, allocate more space and do manual alignment.
++    //
++    // On most operating systems, another allocation with a somewhat larger size
++    // will return an address "close to" that of the previous allocation.  The
++    // result is often the same address (if the kernel hands out virtual
++    // addresses from low to high), or an address that is offset by the increase
++    // in size.  Exploit that to minimize the amount of extra space requested.
++    if (!os::release_memory(addr, size)) {
++      fatal("os::release_memory failed");
++    }
++
++    const size_t extra = MAX2(ofs, suffix_align - ofs);
++    addr = reserve_and_align(size + extra, prefix_size, prefix_align,
++                             suffix_size, suffix_align);
++    if (addr == NULL) {
++      // Try an even larger region.  If this fails, address space is exhausted.
++      addr = reserve_and_align(size + suffix_align, prefix_size,
++                               prefix_align, suffix_size, suffix_align);
++    }
++  }
++
++  _base = addr;
++  _size = size;
++  _alignment = prefix_align;
++}
++
++void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
++                               char* requested_address) {
++  const size_t granularity = os::vm_allocation_granularity();
++  assert((size & granularity - 1) == 0,
++         "size not aligned to os::vm_allocation_granularity()");
++  assert((alignment & granularity - 1) == 0,
++         "alignment not aligned to os::vm_allocation_granularity()");
++  assert(alignment == 0 || is_power_of_2((intptr_t)alignment),
++         "not a power of 2");
++
++  _base = NULL;
++  _size = 0;
++  _special = false;
++  _alignment = 0;
+   if (size == 0) {
+     return;
+   }
+@@ -68,8 +200,8 @@
+     
+     if (base != NULL) {
+       // Check alignment constraints
+-      if (forced_base_alignment > 0) {
+-        assert((uintptr_t) base % forced_base_alignment == 0, 
++      if (alignment > 0) {
++        assert((uintptr_t) base % alignment == 0,
+                "Large pages returned a non-aligned address"); 
+       }
+       _special = true;
+@@ -90,23 +222,23 @@
+     if (requested_address != 0) {
+       base = os::attempt_reserve_memory_at(size, requested_address);
+     } else {
+-      base = os::reserve_memory(size, NULL);
++      base = os::reserve_memory(size, NULL, alignment);
+     }
+ 
+     if (base == NULL) return;
+ 
+     // Check alignment constraints
+-    if (forced_base_alignment > 0 && ((uintptr_t) base % forced_base_alignment != 0)) {
++    if (alignment > 0 && ((size_t)base & alignment - 1) != 0) {
+       // Base not aligned, retry
+       if (!os::release_memory(base, size)) fatal("os::release_memory failed");
+       // Reserve size large enough to do manual alignment and
+       // increase size to a multiple of the desired alignment
+-      size = align_size_up(size, forced_base_alignment);
+-      size_t extra_size = size + forced_base_alignment;
+-      char* extra_base = os::reserve_memory(extra_size);
++      size = align_size_up(size, alignment);
++      size_t extra_size = size + alignment;
++      char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
+       if (extra_base == NULL) return;
+       // Do manual alignement
+-      base = (char*) align_size_up((uintptr_t) extra_base, forced_base_alignment);
++      base = (char*) align_size_up((uintptr_t) extra_base, alignment);
+       assert(base >= extra_base, "just checking");
+       // Release unused areas
+       size_t unused_bottom_size = base - extra_base;
+@@ -126,6 +258,8 @@
+   // Done
+   _base = base;
+   _size = size;
++  _alignment = MAX2(alignment, (size_t) os::vm_page_size());
++
+   assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base,
+ 	 "area must be distinguisable from marks for mark-sweep");
+   assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size],
+@@ -133,29 +267,33 @@
+ }
+ 
+ 
+-ReservedSpace::ReservedSpace(char* base, size_t size, bool special) {
++ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment,
++                             bool special) {
+   assert((size % os::vm_allocation_granularity()) == 0,
+          "size not allocation aligned");
+   _base = base;
+   _size = size;
++  _alignment = alignment;
+   _special = special;
+ }
+ 
+ 
+-ReservedSpace ReservedSpace::first_part(size_t partition_size,
++ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment,
+                                         bool split, bool realloc) {
+   assert(partition_size <= size(), "partition failed");
+   if (split) {
+     os::split_reserved_memory(_base, _size, partition_size, realloc);
+   }
+-  ReservedSpace result(base(), partition_size, special());
++  ReservedSpace result(base(), partition_size, alignment, special());
+   return result;
+ }
+ 
+ 
+-ReservedSpace ReservedSpace::last_part(size_t partition_size) {
++ReservedSpace
++ReservedSpace::last_part(size_t partition_size, size_t alignment) {
+   assert(partition_size <= size(), "partition failed");
+-  ReservedSpace result(base() + partition_size, size() - partition_size, special());
++  ReservedSpace result(base() + partition_size, size() - partition_size,
++                       alignment, special());
+   return result;
+ }
+ 
+@@ -235,11 +373,7 @@
+   // No attempt is made to force large page alignment at the very top and 
+   // bottom of the space if they are not aligned so already. 
+   _lower_alignment  = os::vm_page_size();
+-  if (UseLargePages && rs.size() >= os::large_page_size()) {
+-    _middle_alignment = os::large_page_size();
+-  } else {
+-    _middle_alignment = os::vm_page_size();
+-  }
++  _middle_alignment = os::page_size_for_region(rs.size(), rs.size(), 1);
+   _upper_alignment  = os::vm_page_size();
+ 
+   // End of each region
+@@ -568,4 +702,3 @@
+ }
+ 
+ #endif
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/virtualspace.hpp openjdk/hotspot/src/share/vm/runtime/virtualspace.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/virtualspace.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/virtualspace.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)virtualspace.hpp	1.41 07/05/05 17:07:02 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -32,31 +29,62 @@
+  private:
+   char*  _base;
+   size_t _size;
++  size_t _alignment;
+   bool   _special;
+ 
+   // ReservedSpace
+-  ReservedSpace(char* base, size_t size, bool large);
+-  void initialize(size_t size, size_t forced_base_alignment,
+-                  bool large,  char* requested_address = NULL);
++  ReservedSpace(char* base, size_t size, size_t alignment, bool special);
++  void initialize(size_t size, size_t alignment, bool large,
++                  char* requested_address = NULL);
++
++  // Release parts of an already-reserved memory region [addr, addr + len) to
++  // get a new region that has "compound alignment."  Return the start of the
++  // resulting region, or NULL on failure.
++  //
++  // The region is logically divided into a prefix and a suffix.  The prefix
++  // starts at the result address, which is aligned to prefix_align.  The suffix
++  // starts at result address + prefix_size, which is aligned to suffix_align.
++  // The total size of the result region is size prefix_size + suffix_size.
++  char* align_reserved_region(char* addr, const size_t len,
++                              const size_t prefix_size,
++                              const size_t prefix_align,
++                              const size_t suffix_size,
++                              const size_t suffix_align);
++
++  // Reserve memory, call align_reserved_region() to alignment it and return the
++  // result.
++  char* reserve_and_align(const size_t reserve_size,
++                          const size_t prefix_size,
++                          const size_t prefix_align,
++                          const size_t suffix_size,
++                          const size_t suffix_align);
+ 
+  public:
+   // Constructor
+   ReservedSpace(size_t size);
+-  ReservedSpace(size_t size, size_t forced_base_alignment,
+-                bool large, char* requested_address = NULL);
++  ReservedSpace(size_t size, size_t alignment, bool large,
++                char* requested_address = NULL);
++  ReservedSpace(const size_t prefix_size, const size_t prefix_align,
++                const size_t suffix_size, const size_t suffix_align);
+ 
+   // Accessors
+-  char*  base()   { return _base;   }
+-  size_t size()   { return _size;   }
+-  bool   special(){ return _special;}
++  char*  base()      const { return _base;      }
++  size_t size()      const { return _size;      }
++  size_t alignment() const { return _alignment; }
++  bool   special()   const { return _special;   }
+ 
+-  bool is_reserved() { return _base != NULL; }
++  bool is_reserved() const { return _base != NULL; }
+   void release();
+ 
+   // Splitting
+-  ReservedSpace first_part(size_t partition_size,
++  ReservedSpace first_part(size_t partition_size, size_t alignment,
++                           bool split = false, bool realloc = true);
++  ReservedSpace last_part (size_t partition_size, size_t alignment);
++
++  // These simply call the above using the default alignment.
++  inline ReservedSpace first_part(size_t partition_size,
+                            bool split = false, bool realloc = true);
+-  ReservedSpace last_part (size_t partition_size);
++  inline ReservedSpace last_part (size_t partition_size);
+ 
+   // Alignment
+   static size_t page_align_size_up(size_t size);
+@@ -65,6 +93,16 @@
+   static size_t allocation_align_size_down(size_t size);
+ };
+ 
++ReservedSpace
++ReservedSpace::first_part(size_t partition_size, bool split, bool realloc)
++{
++  return first_part(partition_size, alignment(), split, realloc);
++}
++
++ReservedSpace ReservedSpace::last_part(size_t partition_size)
++{
++  return last_part(partition_size, alignment());
++}
+ 
+ // VirtualSpace is data structure for committing a previously reserved address range in smaller chunks.
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vm_operations.cpp openjdk/hotspot/src/share/vm/runtime/vm_operations.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/vm_operations.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vm_operations.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vm_operations.cpp	1.192 07/05/23 10:54:18 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vm_operations.hpp openjdk/hotspot/src/share/vm/runtime/vm_operations.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/vm_operations.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vm_operations.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vm_operations.hpp	1.130 07/05/23 10:54:21 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vmStructs.cpp openjdk/hotspot/src/share/vm/runtime/vmStructs.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/vmStructs.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vmStructs.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vmStructs.cpp	1.186 07/08/20 18:05:45 JVM"
+-#endif
+ /*
+  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -244,6 +241,7 @@
+      static_field(Universe,                    _constantPoolCacheKlassObj,                    klassOop)                              \
+      static_field(Universe,                    _compiledICHolderKlassObj,                     klassOop)                              \
+      static_field(Universe,                    _systemObjArrayKlassObj,                       klassOop)                              \
++     static_field(Universe,                    _mirrors[0],                                   oop)                                  \
+      static_field(Universe,                    _main_thread_group,                            oop)                                   \
+      static_field(Universe,                    _system_thread_group,                          oop)                                   \
+      static_field(Universe,                    _the_empty_byte_array,                         typeArrayOop)                          \
+@@ -289,11 +287,12 @@
+   nonstatic_field(CardGeneration,              _rs,                                           GenRemSet*)                            \
+   nonstatic_field(CardGeneration,              _bts,                                          BlockOffsetSharedArray*)               \
+                                                                                                                                      \
+-  nonstatic_field(CardTableModRefBS,           _whole_heap,                                   MemRegion)                             \
++  nonstatic_field(CardTableModRefBS,           _whole_heap,                                   const MemRegion)                       \
++  nonstatic_field(CardTableModRefBS,           _guard_index,                                  const size_t)                          \
++  nonstatic_field(CardTableModRefBS,           _last_valid_index,                             const size_t)                          \
++  nonstatic_field(CardTableModRefBS,           _page_size,                                    const size_t)                          \
++  nonstatic_field(CardTableModRefBS,           _byte_map_size,                                const size_t)                          \
+   nonstatic_field(CardTableModRefBS,           _byte_map,                                     jbyte*)                                \
+-  nonstatic_field(CardTableModRefBS,           _byte_map_size,                                size_t)                                \
+-  nonstatic_field(CardTableModRefBS,           _last_valid_index,                             size_t)                                \
+-  nonstatic_field(CardTableModRefBS,           _guard_index,                                  size_t)                                \
+   nonstatic_field(CardTableModRefBS,           _cur_covered_regions,                          int)                                   \
+   nonstatic_field(CardTableModRefBS,           _covered,                                      MemRegion*)                            \
+   nonstatic_field(CardTableModRefBS,           _committed,                                    MemRegion*)                            \
+@@ -488,7 +487,6 @@
+       static_field(SystemDictionary,            _vector_klass,                                 klassOop)                             \
+       static_field(SystemDictionary,            _hashtable_klass,                              klassOop)                             \
+       static_field(SystemDictionary,            _box_klasses[0],                               klassOop)                             \
+-      static_field(SystemDictionary,            _mirrors[0],                                   oop)                                  \
+       static_field(SystemDictionary,            _java_system_loader,                           oop)                                  \
+                                                                                                                                      \
+   /*******************/                                                                                                              \
+@@ -1007,6 +1005,7 @@
+   declare_toplevel_type(GenerationSpec)                                   \
+   declare_toplevel_type(HeapWord)                                         \
+   declare_toplevel_type(MemRegion)                                        \
++  declare_toplevel_type(const MemRegion)                                  \
+   declare_toplevel_type(PermanentGenerationSpec)                          \
+   declare_toplevel_type(ThreadLocalAllocBuffer)                           \
+   declare_toplevel_type(VirtualSpace)                                     \
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vmStructs.hpp openjdk/hotspot/src/share/vm/runtime/vmStructs.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/vmStructs.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vmStructs.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vmStructs.hpp	1.13 07/05/05 17:07:02 JVM"
+-#endif
+ /*
+  * Copyright 2000-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vmThread.cpp openjdk/hotspot/src/share/vm/runtime/vmThread.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/vmThread.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vmThread.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vmThread.cpp	1.91 07/05/23 10:54:15 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -204,11 +201,6 @@
+                  PerfDataManager::create_counter(SUN_THREADS, "vmOperationTime",
+                                                  PerfData::U_Ticks, CHECK);
+   }
+-
+-  // Initialize safepoint intrumentation buffer etc.
+-  if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0){
+-    SafepointSynchronize::initialize_stat();
+-  }
+ }
+ 
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vmThread.hpp openjdk/hotspot/src/share/vm/runtime/vmThread.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/vmThread.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vmThread.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vmThread.hpp	1.40 07/05/05 17:07:03 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -149,5 +146,3 @@
+   // Pointer to single-instance of VM thread
+   static VMThread*     _vm_thread;
+ };
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vm_version.cpp openjdk/hotspot/src/share/vm/runtime/vm_version.cpp
+--- openjdk6/hotspot/src/share/vm/runtime/vm_version.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vm_version.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vm_version.cpp	1.57 07/08/20 18:10:11 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -89,12 +86,16 @@
+   #define VMLP ""
+ #endif
+ 
++#ifdef KERNEL
++  #define VMTYPE "Kernel"
++#else // KERNEL
+ #ifdef TIERED
+   #define VMTYPE "Server"
+ #else
+   #define VMTYPE COMPILER1_PRESENT("Client")   \
+                  COMPILER2_PRESENT("Server")   
+ #endif // TIERED
++#endif // KERNEL
+ 
+ #ifndef HOTSPOT_VM_DISTRO
+   #error HOTSPOT_VM_DISTRO must be defined
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vm_version.hpp openjdk/hotspot/src/share/vm/runtime/vm_version.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/vm_version.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vm_version.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vm_version.hpp	1.27 07/08/08 19:44:04 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -66,5 +63,10 @@
+   static unsigned int logical_processors_per_package() {
+     return _logical_processors_per_package;
+   }
+-};
+ 
++  // Number of page sizes efficiently supported by the hardware.  Most chips now
++  // support two sizes, thus this default implementation.  Processor-specific
++  // subclasses should define new versions to hide this one as needed.  Note
++  // that the O/S may support more sizes, but at most this many are used.
++  static uint page_size_count() { return 2; }
++};
+diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vtune.hpp openjdk/hotspot/src/share/vm/runtime/vtune.hpp
+--- openjdk6/hotspot/src/share/vm/runtime/vtune.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/runtime/vtune.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vtune.hpp	1.20 07/05/05 17:07:01 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -56,4 +53,3 @@
+    VTuneClassLoadMarker() { VTune::start_class_load(); }
+   ~VTuneClassLoadMarker() { VTune::end_class_load(); }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/services/attachListener.cpp openjdk/hotspot/src/share/vm/services/attachListener.cpp
+--- openjdk6/hotspot/src/share/vm/services/attachListener.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/attachListener.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)attachListener.cpp	1.22 07/05/05 17:07:04 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -140,6 +137,7 @@
+   return JNI_OK;
+ }
+ 
++#ifndef SERVICES_KERNEL   // Heap dumping not supported
+ // Implementation of "dumpheap" command.
+ // 
+ // Input arguments :-
+@@ -180,6 +178,7 @@
+   }
+   return JNI_OK;
+ }
++#endif // SERVICES_KERNEL
+ 
+ // Implementation of "inspectheap" command
+ //
+@@ -326,7 +325,9 @@
+ static AttachOperationFunctionInfo funcs[] = {
+   { "agentProperties", 	get_agent_properties },
+   { "datadump",         data_dump },
++#ifndef SERVICES_KERNEL
+   { "dumpheap",         dump_heap },
++#endif  // SERVICES_KERNEL
+   { "load",             JvmtiExport::load_agent_library },
+   { "properties",       get_system_properties },
+   { "threaddump",	thread_dump },
+diff -ruNb openjdk6/hotspot/src/share/vm/services/attachListener.hpp openjdk/hotspot/src/share/vm/services/attachListener.hpp
+--- openjdk6/hotspot/src/share/vm/services/attachListener.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/attachListener.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)attachListener.hpp	1.11 07/05/05 17:07:04 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -34,6 +31,7 @@
+ // complets the result value and any result data is returned to the client
+ // tool.
+ 
++#ifndef SERVICES_KERNEL
+ 
+ class AttachOperation;
+ 
+@@ -43,25 +41,31 @@
+   const char* name;
+   AttachOperationFunction func;
+ };
++#endif // SERVICES_KERNEL
+ 
+ class AttachListener: AllStatic {
+- private:
+-  static volatile bool _initialized;
+-
+  public:
+-  static void init();
+-  static bool is_initialized()			{ return _initialized; }
+-  static void set_initialized()                 { _initialized = true; }
+-  static void abort();
++  static void init()  KERNEL_RETURN;
++  static void abort() KERNEL_RETURN;
+ 
+   // invoke to perform clean-up tasks when all clients detach
+-  static void detachall();
++  static void detachall() KERNEL_RETURN;
+ 
+   // indicates if the Attach Listener needs to be created at startup
+-  static bool init_at_startup();
++  static bool init_at_startup() KERNEL_RETURN_(return false;);
+ 
+   // indicates if we have a trigger to start the Attach Listener
+-  static bool is_init_trigger();
++  static bool is_init_trigger() KERNEL_RETURN_(return false;);
++
++#ifdef SERVICES_KERNEL
++  static bool is_attach_supported()             { return false; }
++#else // SERVICES_KERNEL
++ private:
++  static volatile bool _initialized;
++
++ public:
++  static bool is_initialized()                  { return _initialized; }
++  static void set_initialized()                 { _initialized = true; }
+ 
+   // indicates if this VM supports attach-on-demand
+   static bool is_attach_supported()             { return !DisableAttachMechanism; }
+@@ -83,8 +87,10 @@
+ 
+   // dequeue the next operation
+   static AttachOperation* dequeue();
++#endif // SERVICES_KERNEL
+ };
+ 
++#ifndef SERVICES_KERNEL
+ class AttachOperation: public CHeapObj {
+  public:
+   enum {
+@@ -138,6 +144,4 @@
+   // complete operation by sending result code and any result data to the client
+   virtual void complete(jint result, bufferedStream* result_stream) = 0;
+ };
+-
+-
+-
++#endif // SERVICES_KERNEL
+diff -ruNb openjdk6/hotspot/src/share/vm/services/classLoadingService.cpp openjdk/hotspot/src/share/vm/services/classLoadingService.cpp
+--- openjdk6/hotspot/src/share/vm/services/classLoadingService.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/classLoadingService.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)classLoadingService.cpp	1.15 07/05/05 17:07:04 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/classLoadingService.hpp openjdk/hotspot/src/share/vm/services/classLoadingService.hpp
+--- openjdk6/hotspot/src/share/vm/services/classLoadingService.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/classLoadingService.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)classLoadingService.hpp	1.10 07/05/05 17:07:05 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -136,4 +133,3 @@
+     _loaded_classes->append(h);
+   }
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/services/dtraceAttacher.cpp openjdk/hotspot/src/share/vm/services/dtraceAttacher.cpp
+--- openjdk6/hotspot/src/share/vm/services/dtraceAttacher.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/dtraceAttacher.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)dtraceAttacher.cpp	1.8 07/05/23 10:54:23 JVM" 
+-#endif
+ /*
+  * Copyright 2006-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/dtraceAttacher.hpp openjdk/hotspot/src/share/vm/services/dtraceAttacher.hpp
+--- openjdk6/hotspot/src/share/vm/services/dtraceAttacher.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/dtraceAttacher.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)dtraceAttacher.hpp	1.5 07/05/05 17:07:05 JVM"
+-#endif
+ /*
+  * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -45,4 +42,3 @@
+   // set ExtendedDTraceProbes flag
+   static void set_extended_dprobes(bool value);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/services/heapDumper.cpp openjdk/hotspot/src/share/vm/services/heapDumper.cpp
+--- openjdk6/hotspot/src/share/vm/services/heapDumper.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/heapDumper.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)heapDumper.cpp	1.20 07/05/29 09:44:30 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -1257,9 +1254,10 @@
+ }
+ 
+ // The VM operation that performs the heap dump
+-class VM_HeapDumper : public VM_Operation {
++class VM_HeapDumper : public VM_GC_Operation {
+  private:
+   DumpWriter* _writer;
++  bool _gc_before_heap_dump;
+   bool _is_segmented_dump; 
+   jlong _dump_start;
+ 
+@@ -1270,6 +1268,8 @@
+   jlong dump_start() const                      { return _dump_start; }
+   void set_dump_start(jlong pos);
+ 
++  bool skip_operation() const;
++
+   // writes a HPROF_LOAD_CLASS record
+   static void do_load_class(klassOop k);
+ 
+@@ -1296,8 +1296,12 @@
+   void end_of_dump();
+   
+  public:
+-  VM_HeapDumper(DumpWriter* writer){
++  VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump) :
++    VM_GC_Operation(0 /* total collections,      dummy, ignored */,
++                    0 /* total full collections, dummy, ignored */,
++                    gc_before_heap_dump) {
+     _writer = writer;
++    _gc_before_heap_dump = gc_before_heap_dump;
+     _is_segmented_dump = false; 
+     _dump_start = (jlong)-1;
+   }
+@@ -1308,6 +1312,10 @@
+   void doit();
+ };
+ 
++bool VM_HeapDumper::skip_operation() const {
++  return false;
++}
++
+ // sets the dump starting position
+ void VM_HeapDumper::set_dump_start(jlong pos) {
+   _dump_start = pos;
+@@ -1550,8 +1558,15 @@
+ // roots.
+ 
+ void VM_HeapDumper::doit() {
+-  // need to ensure that we can iterate over the heap
+-  Universe::heap()->ensure_parsability(false);  // no need to retire TLABs
++
++  HandleMark hm;
++  CollectedHeap* ch = Universe::heap();
++  if (_gc_before_heap_dump) {
++    ch->collect_as_vm_thread(GCCause::_heap_dump);
++  } else {
++    // make the heap parsable (no need to retire TLABs)
++    ch->ensure_parsability(false);
++  }
+ 
+   // Write the file header - use 1.0.2 for large heaps, otherwise 1.0.1
+   size_t used;
+@@ -1653,13 +1668,8 @@
+     return -1; 
+   }
+ 
+-  // Do a full GC before heap dump
+-  if (_gc_before_heap_dump) {
+-    Universe::heap()->collect(GCCause::_heap_dump);
+-  }
+   // generate the dump
+-  MutexLocker ml(Heap_lock);
+-  VM_HeapDumper dumper(&writer);
++  VM_HeapDumper dumper(&writer, _gc_before_heap_dump);
+   VMThread::execute(&dumper);
+ 
+   // close dump file and record any error that the writer may have encountered
+@@ -1714,3 +1724,50 @@
+     assert(_error != NULL, "allocation failure");
+   }
+ }
++
++
++// Called by error reporting
++void HeapDumper::dump_heap() {
++  static char path[JVM_MAXPATHLEN];
++
++  // The dump file defaults to java_pid<pid>.hprof in the current working
++  // directory. HeapDumpPath=<file> can be used to specify an alternative
++  // dump file name or a directory where dump file is created.
++  bool use_default_filename = true;
++  if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {
++    path[0] = '\0'; // HeapDumpPath=<file> not specified
++  } else {
++    assert(strlen(HeapDumpPath) < sizeof(path), "HeapDumpPath too long");
++    strcpy(path, HeapDumpPath);
++    // check if the path is a directory (must exist)
++    DIR* dir = os::opendir(path);
++    if (dir == NULL) {
++      use_default_filename = false;
++    } else {
++      // HeapDumpPath specified a directory. We append a file separator
++      // (if needed).
++      os::closedir(dir);
++      size_t fs_len = strlen(os::file_separator());
++      if (strlen(path) >= fs_len) {
++        char* end = path;
++        end += (strlen(path) - fs_len);
++        if (strcmp(end, os::file_separator()) != 0) {
++          assert(strlen(path) + strlen(os::file_separator()) < sizeof(path),
++            "HeapDumpPath too long");
++          strcat(path, os::file_separator());
++        }
++      }
++    }
++  }
++  // If HeapDumpPath wasn't a file name then we append the default name
++  if (use_default_filename) {
++    char fn[32];
++    sprintf(fn, "java_pid%d.hprof", os::current_process_id());
++    assert(strlen(path) + strlen(fn) < sizeof(path), "HeapDumpPath too long");
++    strcat(path, fn);
++  }
++
++  HeapDumper dumper(false /* no GC before heap dump */,
++                    true  /* send to tty */);
++  dumper.dump(path);
++}
+diff -ruNb openjdk6/hotspot/src/share/vm/services/heapDumper.hpp openjdk/hotspot/src/share/vm/services/heapDumper.hpp
+--- openjdk6/hotspot/src/share/vm/services/heapDumper.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/heapDumper.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,8 +1,5 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)heapDumper.hpp	1.8 07/05/05 17:07:05 JVM"
+-#endif
+ /*
+- * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2005-2007 Sun Microsystems, Inc.  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
+@@ -25,7 +22,6 @@
+  *  
+  */
+ 
+-
+ // HeapDumper is used to dump the java heap to file in HPROF binary format:
+ //
+ //  { HeapDumper dumper(true /* full GC before heap dump */);
+@@ -68,5 +64,6 @@
+ 
+   // returns error message (resource allocated), or NULL if no error
+   char* error_as_C_string() const;
+-};
+ 
++  static void dump_heap()    KERNEL_RETURN;
++};
+diff -ruNb openjdk6/hotspot/src/share/vm/services/jmm.h openjdk/hotspot/src/share/vm/services/jmm.h
+--- openjdk6/hotspot/src/share/vm/services/jmm.h	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/jmm.h	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jmm.h	1.36 07/05/05 17:07:04 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -288,4 +285,3 @@
+ #endif /* __cplusplus */
+ 
+ #endif /* !_JAVA_JMM_H_ */
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/services/lowMemoryDetector.cpp openjdk/hotspot/src/share/vm/services/lowMemoryDetector.cpp
+--- openjdk6/hotspot/src/share/vm/services/lowMemoryDetector.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/lowMemoryDetector.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)lowMemoryDetector.cpp	1.28 07/05/05 17:07:04 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/lowMemoryDetector.hpp openjdk/hotspot/src/share/vm/services/lowMemoryDetector.hpp
+--- openjdk6/hotspot/src/share/vm/services/lowMemoryDetector.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/lowMemoryDetector.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)lowMemoryDetector.hpp	1.22 07/05/05 17:07:05 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/management.cpp openjdk/hotspot/src/share/vm/services/management.cpp
+--- openjdk6/hotspot/src/share/vm/services/management.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/management.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)management.cpp	1.82 07/05/05 17:07:05 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -40,7 +37,7 @@
+ klassOop Management::_garbageCollectorMXBean_klass = NULL;
+ klassOop Management::_managementFactory_klass = NULL;
+ 
+-jmmOptionalSupport Management::_optional_support;
++jmmOptionalSupport Management::_optional_support = {0};
+ TimeStamp Management::_stamp;
+ 
+ void management_init() {
+@@ -83,7 +80,10 @@
+   }
+   _optional_support.isBootClassPathSupported = 1;
+   _optional_support.isObjectMonitorUsageSupported = 1;
++#ifndef SERVICES_KERNEL
++  // This depends on the heap inspector
+   _optional_support.isSynchronizerUsageSupported = 1;
++#endif // SERVICES_KERNEL
+ }
+ 
+ void Management::initialize(TRAPS) {
+@@ -1186,11 +1186,12 @@
+ 
+   typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids));
+   int num_threads = (ta != NULL ? ta->length() : 0);
+-  ThreadDumpResult dump_result(num_threads);
+-
+-  if (ta != NULL) {
+     typeArrayHandle ids_ah(THREAD, ta);
+ 
++  ThreadDumpResult dump_result(num_threads);  // can safepoint
++
++  if (ids_ah() != NULL) {
++
+     // validate the thread id array
+     validate_thread_id_array(ids_ah, CHECK_NULL);
+ 
+@@ -1943,6 +1944,7 @@
+ 
+ // Dump heap - Returns 0 if succeeds.
+ JVM_ENTRY(jint, jmm_DumpHeap0(JNIEnv *env, jstring outputfile, jboolean live))
++#ifndef SERVICES_KERNEL
+   ResourceMark rm(THREAD);
+   oop on = JNIHandles::resolve_external_guard(outputfile);
+   if (on == NULL) {
+@@ -1959,8 +1961,10 @@
+     const char* errmsg = dumper.error_as_C_string();
+     THROW_MSG_(vmSymbols::java_io_IOException(), errmsg, -1);
+   }
+-
+   return 0;
++#else  // SERVICES_KERNEL
++  return -1;
++#endif // SERVICES_KERNEL
+ JVM_END
+ 
+ jlong Management::ticks_to_ms(jlong ticks) {
+diff -ruNb openjdk6/hotspot/src/share/vm/services/management.hpp openjdk/hotspot/src/share/vm/services/management.hpp
+--- openjdk6/hotspot/src/share/vm/services/management.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/management.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)management.hpp	1.23 07/05/05 17:07:05 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryManager.cpp openjdk/hotspot/src/share/vm/services/memoryManager.cpp
+--- openjdk6/hotspot/src/share/vm/services/memoryManager.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/memoryManager.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)memoryManager.cpp	1.28 07/05/05 17:07:05 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryManager.hpp openjdk/hotspot/src/share/vm/services/memoryManager.hpp
+--- openjdk6/hotspot/src/share/vm/services/memoryManager.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/memoryManager.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)memoryManager.hpp	1.15 07/05/05 17:07:05 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryPool.cpp openjdk/hotspot/src/share/vm/services/memoryPool.cpp
+--- openjdk6/hotspot/src/share/vm/services/memoryPool.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/memoryPool.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)memoryPool.cpp	1.35 07/05/29 09:44:30 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryPool.hpp openjdk/hotspot/src/share/vm/services/memoryPool.hpp
+--- openjdk6/hotspot/src/share/vm/services/memoryPool.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/memoryPool.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)memoryPool.hpp	1.25 07/05/29 09:44:30 JVM"
+-#endif
+ /*
+  * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryService.cpp openjdk/hotspot/src/share/vm/services/memoryService.cpp
+--- openjdk6/hotspot/src/share/vm/services/memoryService.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/memoryService.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)memoryService.cpp	1.35 07/05/29 09:44:30 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryService.hpp openjdk/hotspot/src/share/vm/services/memoryService.hpp
+--- openjdk6/hotspot/src/share/vm/services/memoryService.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/memoryService.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)memoryService.hpp	1.16 07/05/05 17:07:05 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryUsage.hpp openjdk/hotspot/src/share/vm/services/memoryUsage.hpp
+--- openjdk6/hotspot/src/share/vm/services/memoryUsage.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/memoryUsage.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)memoryUsage.hpp	1.12 07/05/05 17:07:06 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/psMemoryPool.cpp openjdk/hotspot/src/share/vm/services/psMemoryPool.cpp
+--- openjdk6/hotspot/src/share/vm/services/psMemoryPool.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/psMemoryPool.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)psMemoryPool.cpp	1.1 07/05/01 16:48:51 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/psMemoryPool.hpp openjdk/hotspot/src/share/vm/services/psMemoryPool.hpp
+--- openjdk6/hotspot/src/share/vm/services/psMemoryPool.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/psMemoryPool.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)psMemoryPool.hpp	1.1 07/05/01 16:48:51 JVM"
+-#endif
+ /*
+  * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/runtimeService.cpp openjdk/hotspot/src/share/vm/services/runtimeService.cpp
+--- openjdk6/hotspot/src/share/vm/services/runtimeService.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/runtimeService.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)runtimeService.cpp	1.16 07/05/05 17:07:06 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -97,6 +94,9 @@
+     memset((void*) capabilities, '0', len);
+     capabilities[len-1] = '\0';
+     capabilities[0] = AttachListener::is_attach_supported() ? '1' : '0';
++#ifdef KERNEL
++    capabilities[1] = '1';
++#endif // KERNEL
+     PerfDataManager::create_string_constant(SUN_RT, "jvmCapabilities",
+                                             capabilities, CHECK);
+   }
+diff -ruNb openjdk6/hotspot/src/share/vm/services/runtimeService.hpp openjdk/hotspot/src/share/vm/services/runtimeService.hpp
+--- openjdk6/hotspot/src/share/vm/services/runtimeService.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/runtimeService.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)runtimeService.hpp	1.10 07/05/05 17:07:06 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/serviceUtil.hpp openjdk/hotspot/src/share/vm/services/serviceUtil.hpp
+--- openjdk6/hotspot/src/share/vm/services/serviceUtil.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/serviceUtil.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)serviceUtil.hpp	1.8 07/05/05 17:07:06 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/threadService.cpp openjdk/hotspot/src/share/vm/services/threadService.cpp
+--- openjdk6/hotspot/src/share/vm/services/threadService.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/threadService.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)threadService.cpp	1.54 07/05/17 16:07:12 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/services/threadService.hpp openjdk/hotspot/src/share/vm/services/threadService.hpp
+--- openjdk6/hotspot/src/share/vm/services/threadService.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/services/threadService.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)threadService.hpp	1.41 07/05/05 17:07:06 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -385,16 +382,21 @@
+ 
+   void save_old_state(JavaThread* java_thread) {
+     _java_thread  = java_thread;
+-    _is_alive = (_java_thread != NULL) && (_java_thread->threadObj() != NULL);
++    _is_alive = is_alive(java_thread);
+     if (is_alive()) {
+       _old_state = java_lang_Thread::get_thread_status(_java_thread->threadObj());
+     }
+   }
+ 
+  public:
++  static void set_thread_status(JavaThread* java_thread,
++                                java_lang_Thread::ThreadStatus state) {
++    java_lang_Thread::set_thread_status(java_thread->threadObj(), state);
++  }
++
+   void set_thread_status(java_lang_Thread::ThreadStatus state) {
+     if (is_alive()) {
+-      java_lang_Thread::set_thread_status(_java_thread->threadObj(), state);
++      set_thread_status(_java_thread, state);
+     }
+   }
+     
+@@ -411,6 +413,11 @@
+   ~JavaThreadStatusChanger() {
+     set_thread_status(_old_state);
+   }
++
++  static bool is_alive(JavaThread* java_thread) {
++    return java_thread != NULL && java_thread->threadObj() != NULL;
++  }
++
+   bool is_alive() {
+     return _is_alive;
+   }
+@@ -479,7 +486,37 @@
+  private:
+   ThreadStatistics* _stat; 
+   bool _active;
++
++  static bool contended_enter_begin(JavaThread *java_thread) {
++    set_thread_status(java_thread, java_lang_Thread::BLOCKED_ON_MONITOR_ENTER);
++    ThreadStatistics* stat = java_thread->get_thread_stat();
++    stat->contended_enter();
++    bool active = ThreadService::is_thread_monitoring_contention();
++    if (active) {
++      stat->contended_enter_begin();
++    }
++    return active;
++  }
++
+  public:
++  // java_thread is waiting thread being blocked on monitor reenter.
++  // Current thread is the notifying thread which holds the monitor.
++  static bool wait_reenter_begin(JavaThread *java_thread, ObjectMonitor *obj_m) {
++    assert((java_thread != NULL), "Java thread should not be null here");
++    bool active  = false;
++    if (is_alive(java_thread) && ServiceUtil::visible_oop((oop)obj_m->object())) {
++      active = contended_enter_begin(java_thread);
++    }
++    return active;
++  }
++
++  static void wait_reenter_end(JavaThread *java_thread, bool active) {
++    if (active) {
++      java_thread->get_thread_stat()->contended_enter_end();
++    }
++    set_thread_status(java_thread, java_lang_Thread::RUNNABLE);
++  }
++
+   JavaThreadBlockedOnMonitorEnterState(JavaThread *java_thread, ObjectMonitor *obj_m) :
+     JavaThreadStatusChanger(java_thread) {
+     assert((java_thread != NULL), "Java thread should not be null here");
+@@ -487,16 +524,10 @@
+     // enter done for external java world objects and it is contended. All other cases
+     // like for vm internal objects and for external objects which are not contended
+     // thread status is not changed and contended enter stat is not collected.
++    _active = false;
+     if (is_alive() && ServiceUtil::visible_oop((oop)obj_m->object()) && obj_m->contentions() > 0) {
+-      set_thread_status(java_lang_Thread::BLOCKED_ON_MONITOR_ENTER);
+       _stat = java_thread->get_thread_stat();
+-      _stat->contended_enter();
+-      _active = ThreadService::is_thread_monitoring_contention();
+-      if (_active) {
+-        _stat->contended_enter_begin();
+-      }
+-    } else {
+-      _active = false;
++      _active = contended_enter_begin(java_thread);
+     } 
+   }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/accessFlags.cpp openjdk/hotspot/src/share/vm/utilities/accessFlags.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/accessFlags.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/accessFlags.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)accessFlags.cpp	1.25 07/05/05 17:07:07 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/accessFlags.hpp openjdk/hotspot/src/share/vm/utilities/accessFlags.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/accessFlags.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/accessFlags.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)accessFlags.hpp	1.68 07/05/05 17:07:07 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/array.cpp openjdk/hotspot/src/share/vm/utilities/array.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/array.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/array.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)array.cpp	1.20 07/05/05 17:07:07 JVM"
+-#endif
+ /*
+  * Copyright 2000-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/array.hpp openjdk/hotspot/src/share/vm/utilities/array.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/array.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/array.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)array.hpp	1.15 07/05/05 17:07:07 JVM"
+-#endif
+ /*
+  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/bitMap.cpp openjdk/hotspot/src/share/vm/utilities/bitMap.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/bitMap.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/bitMap.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)bitMap.cpp	1.48 07/05/05 17:07:07 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/bitMap.hpp openjdk/hotspot/src/share/vm/utilities/bitMap.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/bitMap.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/bitMap.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)bitMap.hpp	1.45 07/05/05 17:07:06 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -116,6 +113,10 @@
+   }
+ 
+  public:
++
++  // Constructs a bitmap with no map, and size 0.
++  BitMap() : _map(NULL), _size(0) {}
++
+   // Construction
+   BitMap(idx_t* map, idx_t size_in_bits);
+ 
+@@ -393,4 +394,3 @@
+     }
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/bitMap.inline.hpp openjdk/hotspot/src/share/vm/utilities/bitMap.inline.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/bitMap.inline.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/bitMap.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)bitMap.inline.hpp	1.8 07/05/05 17:07:07 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/constantTag.cpp openjdk/hotspot/src/share/vm/utilities/constantTag.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/constantTag.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/constantTag.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)constantTag.cpp	1.21 07/05/05 17:07:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-1999 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/constantTag.hpp openjdk/hotspot/src/share/vm/utilities/constantTag.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/constantTag.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/constantTag.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)constantTag.hpp	1.28 07/05/05 17:07:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -87,4 +84,3 @@
+     
+   void print_on(outputStream* st) const PRODUCT_RETURN;
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/copy.hpp openjdk/hotspot/src/share/vm/utilities/copy.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/copy.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/copy.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)copy.hpp	1.15 07/05/17 16:07:14 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/debug.cpp openjdk/hotspot/src/share/vm/utilities/debug.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/debug.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/debug.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)debug.cpp	1.180 07/05/05 17:07:08 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -252,7 +249,6 @@
+ 
+ void report_java_out_of_memory(const char* message) {
+   static jint out_of_memory_reported = 0;
+-  static char path[JVM_MAXPATHLEN];
+ 
+   // A number of threads may attempt to report OutOfMemoryError at around the 
+   // same time. To avoid dumping the heap or executing the data collection
+@@ -262,47 +258,7 @@
+     // create heap dump before OnOutOfMemoryError commands are executed
+     if (HeapDumpOnOutOfMemoryError) {
+       tty->print_cr("java.lang.OutOfMemoryError: %s", message);
+-
+-      // The dump file defaults to java_pid<pid>.hprof in the current working
+-      // directory. HeapDumpPath=<file> can be used to specify an alternative
+-      // dump file name or a directory where dump file is created.    
+-      bool use_default_filename = true;
+-      if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {
+-        path[0] = '\0'; // HeapDumpPath=<file> not specified
+-      } else {
+-        assert(strlen(HeapDumpPath) < sizeof(path), "HeapDumpPath too long");
+-        strcpy(path, HeapDumpPath);
+-	// check if the path is a directory (must exist)
+-        DIR* dir = os::opendir(path);        
+-	if (dir == NULL) {	  
+-	  use_default_filename = false; 
+-	} else {
+-	  // HeapDumpPath specified a directory. We append a file separator
+-	  // (if needed).
+-	  os::closedir(dir);
+-	  size_t fs_len = strlen(os::file_separator());
+-	  if (strlen(path) >= fs_len) {
+-	    char* end = path;
+-	    end += (strlen(path) - fs_len);
+-	    if (strcmp(end, os::file_separator()) != 0) {
+-              assert(strlen(path) + strlen(os::file_separator()) < sizeof(path), 
+-	        "HeapDumpPath too long");
+-	      strcat(path, os::file_separator());
+-	    }
+-	  }
+-	}     
+-      }
+-      // If HeapDumpPath wasn't a file name then we append the default name
+-      if (use_default_filename) {
+-        char fn[32];
+-	sprintf(fn, "java_pid%d.hprof", os::current_process_id());
+-	assert(strlen(path) + strlen(fn) < sizeof(path), "HeapDumpPath too long");
+-	strcat(path, fn);
+-      }
+-
+-      HeapDumper dumper(false /* no GC before heap dump */,
+-                        true  /* send to tty */);
+-      dumper.dump(path);
++      HeapDumper::dump_heap();
+     }
+ 
+     if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
+@@ -978,4 +934,3 @@
+ #endif
+ 
+ #endif // PRODUCT
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/debug.hpp openjdk/hotspot/src/share/vm/utilities/debug.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/debug.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/debug.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)debug.hpp	1.50 07/05/05 17:07:07 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/defaultStream.hpp openjdk/hotspot/src/share/vm/utilities/defaultStream.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/defaultStream.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/defaultStream.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)defaultStream.hpp	1.13 07/05/05 17:07:08 JVM"
+-#endif
+ /*
+  * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/dtrace.hpp openjdk/hotspot/src/share/vm/utilities/dtrace.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/dtrace.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/dtrace.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)dtrace.hpp	1.11 07/05/05 17:07:08 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -126,4 +123,3 @@
+   HS_DTRACE_PROBE_N(provider,name,((uintptr_t)a0,(uintptr_t)a1,(uintptr_t)a2,\
+     (uintptr_t)a3,(uintptr_t)a4,(uintptr_t)a5,(uintptr_t)a6,(uintptr_t)a7,\
+     (uintptr_t)a8,(uintptr_t)a9))
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/events.cpp openjdk/hotspot/src/share/vm/utilities/events.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/events.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/events.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)events.cpp	1.40 07/05/05 17:07:07 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -250,4 +247,3 @@
+ int print_all_events(outputStream *st) { return 0; }
+ 
+ #endif // PRODUCT
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/events.hpp openjdk/hotspot/src/share/vm/utilities/events.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/events.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/events.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)events.hpp	1.22 07/05/05 17:07:09 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -65,4 +62,3 @@
+ };
+ 
+ int print_all_events(outputStream *st);
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/exceptions.cpp openjdk/hotspot/src/share/vm/utilities/exceptions.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/exceptions.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/exceptions.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)exceptions.cpp	1.99 07/05/05 17:07:09 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -376,14 +373,14 @@
+ #ifndef PRODUCT
+ // caller frees value_string if necessary
+ void Exceptions::debug_check_abort(const char *value_string) {
+-  if (AbortVMOnException[0] != '\0' && value_string != NULL &&
++  if (AbortVMOnException != NULL && value_string != NULL &&
+       strstr(value_string, AbortVMOnException)) {
+     fatal1("Saw %s, aborting", value_string);
+   }
+ }
+ 
+ void Exceptions::debug_check_abort(Handle exception) {
+-  if (AbortVMOnException[0] != '\0') {
++  if (AbortVMOnException != NULL) {
+     ResourceMark rm;
+     debug_check_abort(instanceKlass::cast(exception()->klass())->external_name());
+   }
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/exceptions.hpp openjdk/hotspot/src/share/vm/utilities/exceptions.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/exceptions.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/exceptions.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)exceptions.hpp	1.51 07/05/05 17:07:09 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -276,5 +273,3 @@
+ // exceptions.
+ 
+ #define EXCEPTION_MARK                           Thread* THREAD; ExceptionMark __em(THREAD);
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/globalDefinitions.cpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/globalDefinitions.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)globalDefinitions.cpp	1.48 07/05/05 17:07:09 JVM"
+-#endif
+ /*
+  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)globalDefinitions_gcc.hpp	1.47 07/05/05 17:07:10 JVM"
+-#endif
+ /*
+  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -276,4 +273,3 @@
+ # undef offsetof
+ #endif
+ #define offsetof(klass,field) offset_of(klass,field)
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/globalDefinitions.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/globalDefinitions.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)globalDefinitions.hpp	1.217 07/05/23 10:54:27 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)globalDefinitions_sparcWorks.hpp	1.80 07/05/05 17:07:10 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)globalDefinitions_visCPP.hpp	1.68 07/05/05 17:07:10 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/growableArray.cpp openjdk/hotspot/src/share/vm/utilities/growableArray.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/growableArray.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/growableArray.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)growableArray.cpp	1.37 07/05/05 17:07:10 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -54,4 +51,3 @@
+     return _arena->Amalloc(elementSize * _max);
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/growableArray.hpp openjdk/hotspot/src/share/vm/utilities/growableArray.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/growableArray.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/growableArray.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)growableArray.hpp	1.55 07/05/05 17:07:09 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/hashtable.cpp openjdk/hotspot/src/share/vm/utilities/hashtable.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/hashtable.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/hashtable.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)hashtable.cpp	1.13 07/05/05 17:07:10 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/hashtable.hpp openjdk/hotspot/src/share/vm/utilities/hashtable.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/hashtable.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/hashtable.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)hashtable.hpp	1.14 07/05/05 17:07:10 JVM"
+-#endif
+ /*
+  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/hashtable.inline.hpp openjdk/hotspot/src/share/vm/utilities/hashtable.inline.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/hashtable.inline.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/hashtable.inline.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)hashtable.inline.hpp	1.9 07/05/05 17:07:10 JVM"
+-#endif
+ /*
+  * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/histogram.cpp openjdk/hotspot/src/share/vm/utilities/histogram.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/histogram.cpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/histogram.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)histogram.cpp	1.21 07/05/05 17:07:09 JVM"
+-#endif
+ /*
+  * Copyright 1998-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/histogram.hpp openjdk/hotspot/src/share/vm/utilities/histogram.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/histogram.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/histogram.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)histogram.hpp	1.17 07/05/05 17:07:11 JVM"
+-#endif
+ /*
+  * Copyright 1998-2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/macros.hpp openjdk/hotspot/src/share/vm/utilities/macros.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/macros.hpp	2008-08-28 10:23:17.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/macros.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)macros.hpp	1.41 07/05/29 09:44:30 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -38,6 +35,21 @@
+ #ifdef KERNEL
+ #define COMPILER1
+ #define SERIALGC
++
++#define JVMTI_KERNEL
++#define FPROF_KERNEL
++#define VM_STRUCTS_KERNEL
++#define JNICHECK_KERNEL
++#define SERVICES_KERNEL
++
++#define KERNEL_RETURN        {}
++#define KERNEL_RETURN_(code) { code }
++
++#else  // KERNEL
++
++#define KERNEL_RETURN        /* next token must be ; */
++#define KERNEL_RETURN_(code) /* next token must be ; */
++
+ #endif // KERNEL
+ 
+ // COMPILER1 variant
+@@ -81,6 +93,14 @@
+ #define NOT_CHECK_UNHANDLED_OOPS(code)  code
+ #endif // CHECK_UNHANDLED_OOPS
+ 
++#ifdef CC_INTERP
++#define CC_INTERP_ONLY(code) code
++#define NOT_CC_INTERP(code)
++#else
++#define CC_INTERP_ONLY(code)
++#define NOT_CC_INTERP(code) code
++#endif // CC_INTERP
++
+ #ifdef ASSERT
+ #define DEBUG_ONLY(code) code
+ #define NOT_DEBUG(code)
+@@ -159,4 +179,3 @@
+ #define FIX_THIS(code) report_assertion_failure("FIX_THIS",__FILE__, __LINE__, "")
+ 
+ #define define_pd_global(type, name, value) const type pd_##name = value;
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/ostream.cpp openjdk/hotspot/src/share/vm/utilities/ostream.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/ostream.cpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/ostream.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)ostream.cpp	1.78 07/06/08 23:17:46 JVM"
+-#endif
+ /*
+  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -358,7 +355,7 @@
+ 
+ void defaultStream::init_log() {
+   // %%% Need a MutexLocker?
+-  const char* log_name = strlen(LogFile) > 0 ? LogFile : "hotspot.log";
++  const char* log_name = LogFile != NULL ? LogFile : "hotspot.log";
+   char buf[O_BUFLEN*2];
+   const char* try_name = make_log_name(log_name, NULL, buf);
+   fileStream* file = new(ResourceObj::C_HEAP) fileStream(try_name);
+@@ -762,6 +759,7 @@
+   }
+   memcpy(buffer + buffer_pos, s, len);
+   buffer_pos += len;
++  update_position(s, len);
+ }
+                                                                                                 
+ char* bufferedStream::as_string() {
+@@ -777,3 +775,76 @@
+   }
+ }
+ 
++#ifndef PRODUCT
++
++#if defined(SOLARIS) || defined(LINUX)
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#endif
++
++// Network access
++networkStream::networkStream() {
++
++  _socket = -1;
++
++  hpi::initialize_socket_library();
++
++  int result = hpi::socket(AF_INET, SOCK_STREAM, 0);
++  if (result <= 0) {
++    assert(false, "Socket could not be created!");
++  } else {
++    _socket = result;
++  }
++}
++
++int networkStream::read(char *buf, size_t len) {
++  return hpi::recv(_socket, buf, (int)len, 0);
++}
++
++void networkStream::flush() {
++  if (size() != 0) {
++    hpi::send(_socket, (char *)base(), (int)size(), 0);
++  }
++  reset();
++}
++
++networkStream::~networkStream() {
++  close();
++}
++
++void networkStream::close() {
++  if (_socket != -1) {
++    flush();
++    hpi::socket_close(_socket);
++    _socket = -1;
++  }
++}
++
++bool networkStream::connect(const char *ip, short port) {
++
++  struct sockaddr_in server;
++  server.sin_family = AF_INET;
++  server.sin_port = htons(port);
++
++  server.sin_addr.s_addr = inet_addr(ip);
++  if (server.sin_addr.s_addr == (unsigned long)-1) {
++#ifdef _WINDOWS
++    struct hostent* host = hpi::get_host_by_name((char*)ip);
++#else
++    struct hostent* host = gethostbyname(ip);
++#endif
++    if (host != NULL) {
++      memcpy(&server.sin_addr, host->h_addr_list[0], host->h_length);
++    } else {
++      return false;
++    }
++  }
++
++
++  int result = hpi::connect(_socket, (struct sockaddr*)&server, sizeof(struct sockaddr_in));
++  return (result >= 0);
++}
++
++#endif
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/ostream.hpp openjdk/hotspot/src/share/vm/utilities/ostream.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/ostream.hpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/ostream.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)ostream.hpp	1.43 07/06/08 23:18:20 JVM"
+-#endif
+ /*
+  * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -222,3 +219,23 @@
+ };
+ 
+ #define O_BUFLEN 2000   // max size of output of individual print() methods
++
++#ifndef PRODUCT
++
++class networkStream : public bufferedStream {
++
++  private:
++    int _socket;
++
++  public:
++    networkStream();
++    ~networkStream();
++
++    bool connect(const char *host, short port);
++    bool is_open() const { return _socket != -1; }
++    int read(char *buf, size_t len);
++    void close();
++    virtual void flush();
++};
++
++#endif
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/preserveException.cpp openjdk/hotspot/src/share/vm/utilities/preserveException.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/preserveException.cpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/preserveException.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)preserveException.cpp	1.21 07/05/05 17:07:11 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/preserveException.hpp openjdk/hotspot/src/share/vm/utilities/preserveException.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/preserveException.hpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/preserveException.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)preserveException.hpp	1.20 07/05/05 17:07:11 JVM"
+-#endif
+ /*
+  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/sizes.cpp openjdk/hotspot/src/share/vm/utilities/sizes.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/sizes.cpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/sizes.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)sizes.cpp	1.11 07/05/05 17:07:10 JVM"
+-#endif
+ /*
+  * Copyright 2000 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/sizes.hpp openjdk/hotspot/src/share/vm/utilities/sizes.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/sizes.hpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/sizes.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)sizes.hpp	1.19 07/05/05 17:07:08 JVM"
+-#endif
+ /*
+  * Copyright 2000-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -145,4 +142,3 @@
+ // Use the following #define to get C++ field member offsets
+ 
+ #define byte_offset_of(klass,field)   in_ByteSize((int)offset_of(klass, field))
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/taskqueue.cpp openjdk/hotspot/src/share/vm/utilities/taskqueue.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/taskqueue.cpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/taskqueue.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)taskqueue.cpp	1.25 07/05/05 17:07:10 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -54,8 +51,7 @@
+ ParallelTaskTerminator(int n_threads, TaskQueueSetSuper* queue_set) :
+   _n_threads(n_threads),
+   _queue_set(queue_set), 
+-  _offered_termination(0), _terminated(0),
+-  _term_monitor(Mutex::leaf+1, "ParTaskTerm", true) {}
++  _offered_termination(0) {}
+ 
+ bool ParallelTaskTerminator::peek_in_queue_set() {
+   return _queue_set->peek();
+@@ -111,519 +107,6 @@
+   }
+ }
+ 
+-OopTaskQueue::OopTaskQueue() : TaskQueueSuper() {
+-  assert(sizeof(Age) == sizeof(jint), "Depends on this.");
+-}
+-
+-void OopTaskQueue::initialize() {
+-  _elems = NEW_C_HEAP_ARRAY(Task, n());
+-  guarantee(_elems != NULL, "Allocation failed.");
+-}
+-
+-bool OopTaskQueue::push_slow(Task t, juint dirty_n_elems) {
+-  if (dirty_n_elems == n() - 1) {
+-    // Actually means 0, so do the push.
+-    juint localBot = _bottom;
+-    _elems[localBot] = t;
+-    _bottom = increment_index(localBot);
+-    return true;
+-  } else
+-    return false;
+-}
+-
+-bool OopTaskQueue::
+-pop_local_slow(juint localBot, Age oldAge) {
+-  // This queue was observed to contain exactly one element; either this
+-  // thread will claim it, or a competing "pop_global".  In either case,
+-  // the queue will be logically empty afterwards.  Create a new Age value
+-  // that represents the empty queue for the given value of "_bottom".  (We 
+-  // must also increment "tag" because of the case where "bottom == 1",
+-  // "top == 0".  A pop_global could read the queue element in that case,
+-  // then have the owner thread do a pop followed by another push.  Without
+-  // the incrementing of "tag", the pop_global's CAS could succeed,
+-  // allowing it to believe it has claimed the stale element.)
+-  Age newAge;
+-  newAge._top = localBot;
+-  newAge._tag = oldAge.tag() + 1;
+-  // Perhaps a competing pop_global has already incremented "top", in which 
+-  // case it wins the element.
+-  if (localBot == oldAge.top()) {
+-    Age tempAge;
+-    // No competing pop_global has yet incremented "top"; we'll try to
+-    // install new_age, thus claiming the element.
+-    assert(sizeof(Age) == sizeof(jint) && sizeof(jint) == sizeof(juint),
+-	   "Assumption about CAS unit.");
+-    *(jint*)&tempAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
+-    if (tempAge == oldAge) {
+-      // We win.
+-      assert(dirty_size(localBot, get_top()) != n() - 1,
+-	     "Shouldn't be possible...");
+-      return true;
+-    }
+-  }
+-  // We fail; a completing pop_global gets the element.  But the queue is
+-  // empty (and top is greater than bottom.)  Fix this representation of
+-  // the empty queue to become the canonical one.
+-  set_age(newAge);
+-  assert(dirty_size(localBot, get_top()) != n() - 1,
+-	 "Shouldn't be possible...");
+-  return false;
+-}
+-
+-bool OopTaskQueue::pop_global(Task& t) {
+-  Age newAge;
+-  Age oldAge = get_age();
+-  juint localBot = _bottom;
+-  juint n_elems = size(localBot, oldAge.top());
+-  if (n_elems == 0) {
+-    return false;
+-  }
+-  t = _elems[oldAge.top()];
+-  newAge = oldAge;
+-  newAge._top = increment_index(newAge.top());
+-  if ( newAge._top == 0 ) newAge._tag++;
+-  Age resAge;
+-  *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
+-  // Note that using "_bottom" here might fail, since a pop_local might
+-  // have decremented it.
+-  assert(dirty_size(localBot, newAge._top) != n() - 1,
+-	 "Shouldn't be possible...");
+-  return (resAge == oldAge);
+-}
+-
+-OopTaskQueue::~OopTaskQueue() {
+-  FREE_C_HEAP_ARRAY(Task, _elems);
+-}
+-
+-OopStarTaskQueue::OopStarTaskQueue() : TaskQueueSuper() {
+-  assert(sizeof(Age) == sizeof(jint), "Depends on this.");
+-}
+-
+-void OopStarTaskQueue::initialize() {
+-  _elems = NEW_C_HEAP_ARRAY(StarTask, n());
+-  guarantee(_elems != NULL, "Allocation failed.");
+-}
+-
+-bool OopStarTaskQueue::push_slow(StarTask t, juint dirty_n_elems) {
+-  if (dirty_n_elems == n() - 1) {
+-    // Actually means 0, so do the push.
+-    juint localBot = _bottom;
+-    _elems[localBot] = t;
+-    _bottom = increment_index(localBot);
+-    return true;
+-  } else
+-    return false;
+-}
+-
+-bool OopStarTaskQueue::
+-pop_local_slow(juint localBot, Age oldAge) {
+-  // This queue was observed to contain exactly one element; either this
+-  // thread will claim it, or a competing "pop_global".  In either case,
+-  // the queue will be logically empty afterwards.  Create a new Age value
+-  // that represents the empty queue for the given value of "_bottom".  (We 
+-  // must also increment "tag" because of the case where "bottom == 1",
+-  // "top == 0".  A pop_global could read the queue element in that case,
+-  // then have the owner thread do a pop followed by another push.  Without
+-  // the incrementing of "tag", the pop_global's CAS could succeed,
+-  // allowing it to believe it has claimed the stale element.)
+-  Age newAge;
+-  newAge._top = localBot;
+-  newAge._tag = oldAge.tag() + 1;
+-  // Perhaps a competing pop_global has already incremented "top", in which 
+-  // case it wins the element.
+-  if (localBot == oldAge.top()) {
+-    Age tempAge;
+-    // No competing pop_global has yet incremented "top"; we'll try to
+-    // install new_age, thus claiming the element.
+-    assert(sizeof(Age) == sizeof(jint) && sizeof(jint) == sizeof(juint),
+-	   "Assumption about CAS unit.");
+-    *(jint*)&tempAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
+-    if (tempAge == oldAge) {
+-      // We win.
+-      assert(dirty_size(localBot, get_top()) != n() - 1,
+-	     "Shouldn't be possible...");
+-      return true;
+-    }
+-  }
+-  // We fail; a completing pop_global gets the element.  But the queue is
+-  // empty (and top is greater than bottom.)  Fix this representation of
+-  // the empty queue to become the canonical one.
+-  set_age(newAge);
+-  assert(dirty_size(localBot, get_top()) != n() - 1,
+-	 "Shouldn't be possible...");
+-  return false;
+-}
+-
+-bool OopStarTaskQueue::pop_global(StarTask& t) {
+-  Age newAge;
+-  Age oldAge = get_age();
+-  juint localBot = _bottom;
+-  juint n_elems = size(localBot, oldAge.top());
+-  if (n_elems == 0) {
+-    return false;
+-  }
+-  t = _elems[oldAge.top()];
+-  newAge = oldAge;
+-  newAge._top = increment_index(newAge.top());
+-  if ( newAge._top == 0 ) newAge._tag++;
+-  Age resAge;
+-  *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
+-  // Note that using "_bottom" here might fail, since a pop_local might
+-  // have decremented it.
+-  assert(dirty_size(localBot, newAge._top) != n() - 1,
+-	 "Shouldn't be possible...");
+-  return (resAge == oldAge);
+-}
+-
+-OopStarTaskQueue::~OopStarTaskQueue() {
+-  FREE_C_HEAP_ARRAY(Task, _elems);
+-}
+-
+-// GenTaskQueue is an exact clone of OopTaskQueue.  See
+-// header file for questions about why GenTaskQueue exists.
+-
+-GenTaskQueue::GenTaskQueue() : TaskQueueSuper() {
+-  assert(sizeof(Age) == sizeof(jint), "Depends on this.");
+-}
+-
+-void GenTaskQueue::initialize() {
+-  _elems = NEW_C_HEAP_ARRAY(GenTask, n());
+-  guarantee(_elems != NULL, "Allocation failed.");
+-}
+-
+-bool GenTaskQueue::push_slow(GenTask t, juint dirty_n_elems) {
+-  if (dirty_n_elems == n() - 1) {
+-    // Actually means 0, so do the push.
+-    juint localBot = _bottom;
+-    _elems[localBot] = t;
+-    _bottom = increment_index(localBot);
+-    return true;
+-  } else
+-    return false;
+-}
+-
+-bool GenTaskQueue::
+-pop_local_slow(juint localBot, Age oldAge) {
+-  // This queue was observed to contain exactly one element; either this
+-  // thread will claim it, or a competing "pop_global".  In either case,
+-  // the queue will be logically empty afterwards.  Create a new Age value
+-  // that represents the empty queue for the given value of "_bottom".  (We 
+-  // must also increment "tag" because of the case where "bottom == 1",
+-  // "top == 0".  A pop_global could read the queue element in that case,
+-  // then have the owner thread do a pop followed by another push.  Without
+-  // the incrementing of "tag", the pop_global's CAS could succeed,
+-  // allowing it to believe it has claimed the stale element.)
+-  Age newAge;
+-  newAge._top = localBot;
+-  newAge._tag = oldAge.tag() + 1;
+-  // Perhaps a competing pop_global has already incremented "top", in which 
+-  // case it wins the element.
+-  if (localBot == oldAge.top()) {
+-    Age tempAge;
+-    // No competing pop_global has yet incremented "top"; we'll try to
+-    // install new_age, thus claiming the element.
+-    assert(sizeof(Age) == sizeof(jint) && sizeof(jint) == sizeof(juint),
+-	   "Assumption about CAS unit.");
+-    *(jint*)&tempAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
+-    if (tempAge == oldAge) {
+-      // We win.
+-      assert(dirty_size(localBot, get_top()) != n() - 1,
+-	     "Shouldn't be possible...");
+-      return true;
+-    }
+-  }
+-  // We fail; a completing pop_global gets the element.  But the queue is
+-  // empty (and top is greater than bottom.)  Fix this representation of
+-  // the empty queue to become the canonical one.
+-  set_age(newAge);
+-  assert(dirty_size(localBot, get_top()) != n() - 1,
+-	 "Shouldn't be possible...");
+-  return false;
+-}
+-
+-bool GenTaskQueue::pop_global(GenTask& t) {
+-  Age newAge;
+-  Age oldAge = get_age();
+-  juint localBot = _bottom;
+-  juint n_elems = size(localBot, oldAge.top());
+-  if (n_elems == 0) {
+-    return false;
+-  }
+-  t = _elems[oldAge.top()];
+-  newAge = oldAge;
+-  newAge._top = increment_index(newAge.top());
+-  if ( newAge._top == 0 ) newAge._tag++;
+-  Age resAge;
+-  *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
+-  // Note that using "_bottom" here might fail, since a pop_local might
+-  // have decremented it.
+-  assert(dirty_size(localBot, newAge._top) != n() - 1,
+-	 "Shouldn't be possible...");
+-  return (resAge == oldAge);
+-}
+-
+-GenTaskQueue::~GenTaskQueue() {
+-  FREE_C_HEAP_ARRAY(GenTask, _elems);
+-}
+-// End of GenTaskQueue clone
+-
+-void OopTaskQueueSet::register_queue(int i, OopTaskQueue* q) {
+-  assert(0 <= i && i < _n, "index out of range.");
+-  _queues[i] = q;
+-}
+-
+-OopTaskQueue* OopTaskQueueSet::queue(int i) {
+-  return _queues[i];
+-}
+-
+-bool OopTaskQueueSet::steal(int queue_num, int* seed, Task& t) {
+-  for (int i = 0; i < 2 * _n; i++)
+-    if (steal_best_of_2(queue_num, seed, t))
+-      return true;
+-  return false;
+-}
+-
+-bool OopTaskQueueSet::steal_best_of_all(int queue_num, int* seed, Task& t) {
+-  if (_n > 2) {
+-    int best_k;
+-    jint best_sz = 0;
+-    for (int k = 0; k < _n; k++) {
+-      if (k == queue_num) continue;
+-      jint sz = _queues[k]->size();
+-      if (sz > best_sz) {
+-	best_sz = sz;
+-	best_k = k;
+-      }
+-    }
+-    return best_sz > 0 && _queues[best_k]->pop_global(t);
+-  } else if (_n == 2) {
+-    // Just try the other one.
+-    int k = (queue_num + 1) % 2;
+-    return _queues[k]->pop_global(t);
+-  } else {
+-    assert(_n == 1, "can't be zero.");
+-    return false;
+-  }
+-}
+-
+-bool OopTaskQueueSet::steal_1_random(int queue_num, int* seed, Task& t) {
+-  if (_n > 2) {
+-    int k = queue_num;
+-    while (k == queue_num) k = randomParkAndMiller(seed) % _n;
+-    return _queues[2]->pop_global(t);
+-  } else if (_n == 2) {
+-    // Just try the other one.
+-    int k = (queue_num + 1) % 2;
+-    return _queues[k]->pop_global(t);
+-  } else {
+-    assert(_n == 1, "can't be zero.");
+-    return false;
+-  }
+-}
+-
+-bool OopTaskQueueSet::steal_best_of_2(int queue_num, int* seed, Task& t) {
+-  if (_n > 2) {
+-    int k1 = queue_num;
+-    while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n;
+-    int k2 = queue_num;
+-    while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n;
+-    // Sample both and try the larger.
+-    juint sz1 = _queues[k1]->size();
+-    juint sz2 = _queues[k2]->size();
+-    if (sz2 > sz1) return _queues[k2]->pop_global(t);
+-    else return _queues[k1]->pop_global(t);
+-  } else if (_n == 2) {
+-    // Just try the other one.
+-    int k = (queue_num + 1) % 2;
+-    return _queues[k]->pop_global(t);
+-  } else {
+-    assert(_n == 1, "can't be zero.");
+-    return false;
+-  }
+-}
+-
+-bool OopTaskQueueSet::peek() {
+-  // Try all the queues.
+-  for (int j = 0; j < _n; j++) {
+-    if (_queues[j]->peek())
+-      return true;
+-  }
+-  return false;
+-}
+-
+-void OopStarTaskQueueSet::register_queue(int i, OopStarTaskQueue* q) {
+-  assert(0 <= i && i < _n, "index out of range.");
+-  _queues[i] = q;
+-}
+-
+-OopStarTaskQueue* OopStarTaskQueueSet::queue(int i) {
+-  return _queues[i];
+-}
+-
+-bool OopStarTaskQueueSet::steal(int queue_num, int* seed, StarTask& t) {
+-  for (int i = 0; i < 2 * _n; i++)
+-    if (steal_best_of_2(queue_num, seed, t))
+-      return true;
+-  return false;
+-}
+-
+-bool OopStarTaskQueueSet::steal_best_of_all(int queue_num, int* seed,
+-					    StarTask& t) {
+-  if (_n > 2) {
+-    int best_k;
+-    jint best_sz = 0;
+-    for (int k = 0; k < _n; k++) {
+-      if (k == queue_num) continue;
+-      jint sz = _queues[k]->size();
+-      if (sz > best_sz) {
+-	best_sz = sz;
+-	best_k = k;
+-      }
+-    }
+-    return best_sz > 0 && _queues[best_k]->pop_global(t);
+-  } else if (_n == 2) {
+-    // Just try the other one.
+-    int k = (queue_num + 1) % 2;
+-    return _queues[k]->pop_global(t);
+-  } else {
+-    assert(_n == 1, "can't be zero.");
+-    return false;
+-  }
+-}
+-
+-bool OopStarTaskQueueSet::steal_1_random(int queue_num, int* seed,
+-					 StarTask& t) {
+-  if (_n > 2) {
+-    int k = queue_num;
+-    while (k == queue_num) k = randomParkAndMiller(seed) % _n;
+-    return _queues[2]->pop_global(t);
+-  } else if (_n == 2) {
+-    // Just try the other one.
+-    int k = (queue_num + 1) % 2;
+-    return _queues[k]->pop_global(t);
+-  } else {
+-    assert(_n == 1, "can't be zero.");
+-    return false;
+-  }
+-}
+-
+-bool OopStarTaskQueueSet::steal_best_of_2(int queue_num, int* seed,
+-					  StarTask& t) {
+-  if (_n > 2) {
+-    int k1 = queue_num;
+-    while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n;
+-    int k2 = queue_num;
+-    while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n;
+-    // Sample both and try the larger.
+-    juint sz1 = _queues[k1]->size();
+-    juint sz2 = _queues[k2]->size();
+-    if (sz2 > sz1) return _queues[k2]->pop_global(t);
+-    else return _queues[k1]->pop_global(t);
+-  } else if (_n == 2) {
+-    // Just try the other one.
+-    int k = (queue_num + 1) % 2;
+-    return _queues[k]->pop_global(t);
+-  } else {
+-    assert(_n == 1, "can't be zero.");
+-    return false;
+-  }
+-}
+-
+-bool OopStarTaskQueueSet::peek() {
+-  // Try all the queues.
+-  for (int j = 0; j < _n; j++) {
+-    if (_queues[j]->peek())
+-      return true;
+-  }
+-  return false;
+-}
+-
+-// Clone of OopTaskQueueSet for GenTask
+-void GenTaskQueueSet::register_queue(int i, GenTaskQueue* q) {
+-  assert(0 <= i && i < _n, "index out of range.");
+-  _queues[i] = q;
+-}
+-
+-GenTaskQueue* GenTaskQueueSet::queue(int i) {
+-  return _queues[i];
+-}
+-
+-bool GenTaskQueueSet::steal(int queue_num, int* seed, GenTask& t) {
+-  for (int i = 0; i < 2 * _n; i++)
+-    if (steal_best_of_all(queue_num, seed, t))
+-      return true;
+-  return false;
+-}
+-
+-bool GenTaskQueueSet::steal_best_of_all(int queue_num, int* seed, GenTask& t) {
+-  if (_n > 2) {
+-    int best_k;
+-    jint best_sz = 0;
+-    for (int k = 0; k < _n; k++) {
+-      if (k == queue_num) continue;
+-      jint sz = _queues[k]->size();
+-      if (sz > best_sz) {
+-	best_sz = sz;
+-	best_k = k;
+-      }
+-    }
+-    return best_sz > 0 && _queues[best_k]->pop_global(t);
+-  } else if (_n == 2) {
+-    // Just try the other one.
+-    int k = (queue_num + 1) % 2;
+-    return _queues[k]->pop_global(t);
+-  } else {
+-    assert(_n == 1, "can't be zero.");
+-    return false;
+-  }
+-}
+-
+-bool GenTaskQueueSet::steal_1_random(int queue_num, int* seed, GenTask& t) {
+-  if (_n > 2) {
+-    int k = queue_num;
+-    while (k == queue_num) k = randomParkAndMiller(seed) % _n;
+-    return _queues[2]->pop_global(t);
+-  } else if (_n == 2) {
+-    // Just try the other one.
+-    int k = (queue_num + 1) % 2;
+-    return _queues[k]->pop_global(t);
+-  } else {
+-    assert(_n == 1, "can't be zero.");
+-    return false;
+-  }
+-}
+-
+-bool GenTaskQueueSet::steal_best_of_2(int queue_num, int* seed, GenTask& t) {
+-  if (_n > 2) {
+-    int k1 = queue_num;
+-    while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n;
+-    int k2 = queue_num;
+-    while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n;
+-    // Sample both and try the larger.
+-    juint sz1 = _queues[k1]->size();
+-    juint sz2 = _queues[k2]->size();
+-    if (sz2 > sz1) return _queues[k2]->pop_global(t);
+-    else return _queues[k1]->pop_global(t);
+-  } else if (_n == 2) {
+-    // Just try the other one.
+-    int k = (queue_num + 1) % 2;
+-    return _queues[k]->pop_global(t);
+-  } else {
+-    assert(_n == 1, "can't be zero.");
+-    return false;
+-  }
+-}
+-
+-bool GenTaskQueueSet::peek() {
+-  // Try all the queues.
+-  for (int j = 0; j < _n; j++) {
+-    if (_queues[j]->peek())
+-      return true;
+-  }
+-  return false;
+-}
+-// End clone of OopTaskQueueSet for GenTask
+-
+ bool ChunkTaskQueueWithOverflow::is_empty() {
+   return (_chunk_queue.size() == 0) &&
+ 	 (_overflow_stack->length() == 0);
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/taskqueue.hpp openjdk/hotspot/src/share/vm/utilities/taskqueue.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/taskqueue.hpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/taskqueue.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)taskqueue.hpp	1.38 07/05/05 17:07:10 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -26,8 +23,6 @@
+  */
+ 
+ class TaskQueueSuper: public CHeapObj {
+-  friend class ChunkTaskQueue;
+-
+ protected:
+   // The first free element after the last one pushed (mod _n).
+   // (For now we'll assume only 32-bit CAS).
+@@ -131,115 +126,129 @@
+ 
+ };
+ 
+-typedef oop Task;
+-class OopTaskQueue: public TaskQueueSuper {
+-private:
+-  // Slow paths for push, pop_local.  (pop_global has no fast path.)
+-  bool push_slow(Task t, juint dirty_n_elems);
+-  bool pop_local_slow(juint localBot, Age oldAge);
+-
+-public:
+-  // Initializes the queue to empty.
+-  OopTaskQueue();
+-
+-  void initialize();
+-
+-  // Push the task "t" on the queue.  Returns "false" iff the queue is
+-  // full.
+-  inline bool push(Task t);
+-
+-  // If succeeds in claiming a task (from the 'local' end, that is, the
+-  // most recently pushed task), returns "true" and sets "t" to that task.
+-  // Otherwise, the queue is empty and returns false.
+-  inline bool pop_local(Task& t);
+-
+-  // If succeeds in claiming a task (from the 'global' end, that is, the
+-  // least recently pushed task), returns "true" and sets "t" to that task.
+-  // Otherwise, the queue is empty and returns false.
+-  bool pop_global(Task& t);
+-
+-  // Delete any resource associated with the queue.
+-  ~OopTaskQueue();
+-
+-private:
+-  // Element array.
+-  volatile Task* _elems;
+-
+-};
+-
+-typedef oop* StarTask;
+-class OopStarTaskQueue: public TaskQueueSuper {
++template<class E> class GenericTaskQueue: public TaskQueueSuper {
+ private:
+   // Slow paths for push, pop_local.  (pop_global has no fast path.)
+-  bool push_slow(StarTask t, juint dirty_n_elems);
++  bool push_slow(E t, juint dirty_n_elems);
+   bool pop_local_slow(juint localBot, Age oldAge);
+ 
+ public:
+   // Initializes the queue to empty.
+-  OopStarTaskQueue();
++  GenericTaskQueue();
+ 
+   void initialize();
+ 
+   // Push the task "t" on the queue.  Returns "false" iff the queue is
+   // full.
+-  inline bool push(StarTask t);
++  inline bool push(E t);
+ 
+   // If succeeds in claiming a task (from the 'local' end, that is, the
+   // most recently pushed task), returns "true" and sets "t" to that task.
+   // Otherwise, the queue is empty and returns false.
+-  inline bool pop_local(StarTask& t);
++  inline bool pop_local(E& t);
+ 
+   // If succeeds in claiming a task (from the 'global' end, that is, the
+   // least recently pushed task), returns "true" and sets "t" to that task.
+   // Otherwise, the queue is empty and returns false.
+-  bool pop_global(StarTask& t);
++  bool pop_global(E& t);
+ 
+   // Delete any resource associated with the queue.
+-  ~OopStarTaskQueue();
++  ~GenericTaskQueue();
+ 
+ private:
+   // Element array.
+-  volatile StarTask* _elems;
+-
++  volatile E* _elems;
+ };
+ 
+-// Clone of OopTaskQueue with GenTask instead of Task
+-typedef size_t GenTask;  // Generic task
+-class GenTaskQueue: public TaskQueueSuper {
+-private:
+-  // Slow paths for push, pop_local.  (pop_global has no fast path.)
+-  bool push_slow(GenTask t, juint dirty_n_elems);
+-  bool pop_local_slow(juint localBot, Age oldAge);
+-
+-public:
+-  // Initializes the queue to empty.
+-  GenTaskQueue();
+-
+-  void initialize();
+-
+-  // Push the task "t" on the queue.  Returns "false" iff the queue is
+-  // full.
+-  inline bool push(GenTask t);
++template<class E>
++GenericTaskQueue<E>::GenericTaskQueue():TaskQueueSuper() {
++  assert(sizeof(Age) == sizeof(jint), "Depends on this.");
++}
+ 
+-  // If succeeds in claiming a task (from the 'local' end, that is, the
+-  // most recently pushed task), returns "true" and sets "t" to that task.
+-  // Otherwise, the queue is empty and returns false.
+-  inline bool pop_local(GenTask& t);
++template<class E>
++void GenericTaskQueue<E>::initialize() {
++  _elems = NEW_C_HEAP_ARRAY(E, n());
++  guarantee(_elems != NULL, "Allocation failed.");
++}
+ 
+-  // If succeeds in claiming a task (from the 'global' end, that is, the
+-  // least recently pushed task), returns "true" and sets "t" to that task.
+-  // Otherwise, the queue is empty and returns false.
+-  bool pop_global(GenTask& t);
++template<class E>
++bool GenericTaskQueue<E>::push_slow(E t, juint dirty_n_elems) {
++  if (dirty_n_elems == n() - 1) {
++    // Actually means 0, so do the push.
++    juint localBot = _bottom;
++    _elems[localBot] = t;
++    _bottom = increment_index(localBot);
++    return true;
++  } else
++    return false;
++}
+ 
+-  // Delete any resource associated with the queue.
+-  ~GenTaskQueue();
++template<class E>
++bool GenericTaskQueue<E>::
++pop_local_slow(juint localBot, Age oldAge) {
++  // This queue was observed to contain exactly one element; either this
++  // thread will claim it, or a competing "pop_global".  In either case,
++  // the queue will be logically empty afterwards.  Create a new Age value
++  // that represents the empty queue for the given value of "_bottom".  (We
++  // must also increment "tag" because of the case where "bottom == 1",
++  // "top == 0".  A pop_global could read the queue element in that case,
++  // then have the owner thread do a pop followed by another push.  Without
++  // the incrementing of "tag", the pop_global's CAS could succeed,
++  // allowing it to believe it has claimed the stale element.)
++  Age newAge;
++  newAge._top = localBot;
++  newAge._tag = oldAge.tag() + 1;
++  // Perhaps a competing pop_global has already incremented "top", in which
++  // case it wins the element.
++  if (localBot == oldAge.top()) {
++    Age tempAge;
++    // No competing pop_global has yet incremented "top"; we'll try to
++    // install new_age, thus claiming the element.
++    assert(sizeof(Age) == sizeof(jint) && sizeof(jint) == sizeof(juint),
++           "Assumption about CAS unit.");
++    *(jint*)&tempAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
++    if (tempAge == oldAge) {
++      // We win.
++      assert(dirty_size(localBot, get_top()) != n() - 1,
++             "Shouldn't be possible...");
++      return true;
++    }
++  }
++  // We fail; a completing pop_global gets the element.  But the queue is
++  // empty (and top is greater than bottom.)  Fix this representation of
++  // the empty queue to become the canonical one.
++  set_age(newAge);
++  assert(dirty_size(localBot, get_top()) != n() - 1,
++         "Shouldn't be possible...");
++  return false;
++}
+ 
+-private:
+-  // Element array.
+-  volatile GenTask* _elems;
++template<class E>
++bool GenericTaskQueue<E>::pop_global(E& t) {
++  Age newAge;
++  Age oldAge = get_age();
++  juint localBot = _bottom;
++  juint n_elems = size(localBot, oldAge.top());
++  if (n_elems == 0) {
++    return false;
++  }
++  t = _elems[oldAge.top()];
++  newAge = oldAge;
++  newAge._top = increment_index(newAge.top());
++  if ( newAge._top == 0 ) newAge._tag++;
++  Age resAge;
++  *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
++  // Note that using "_bottom" here might fail, since a pop_local might
++  // have decremented it.
++  assert(dirty_size(localBot, newAge._top) != n() - 1,
++         "Shouldn't be possible...");
++  return (resAge == oldAge);
++}
+ 
+-};
+-// End clone of OopTaskQueue with GenTask instead of Task
++template<class E>
++GenericTaskQueue<E>::~GenericTaskQueue() {
++  FREE_C_HEAP_ARRAY(E, _elems);
++}
+ 
+ // Inherits the typedef of "Task" from above.
+ class TaskQueueSetSuper: public CHeapObj {
+@@ -250,100 +259,129 @@
+   virtual bool peek() = 0;
+ };
+ 
+-class OopTaskQueueSet: public TaskQueueSetSuper {
++template<class E> class GenericTaskQueueSet: public TaskQueueSetSuper {
+ private:
+   int _n;
+-  OopTaskQueue** _queues;
++  GenericTaskQueue<E>** _queues;
+ 
+-  bool steal_1_random(int queue_num, int* seed, Task& t);
+-  bool steal_best_of_2(int queue_num, int* seed, Task& t);
+-  bool steal_best_of_all(int queue_num, int* seed, Task& t);
+ public:
+-  OopTaskQueueSet(int n) : _n(n) {
+-    typedef OopTaskQueue* OopTaskQueuePtr;
+-    _queues = NEW_C_HEAP_ARRAY(OopTaskQueuePtr, n);
++  GenericTaskQueueSet(int n) : _n(n) {
++    typedef GenericTaskQueue<E>* GenericTaskQueuePtr;
++    _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n);
+     guarantee(_queues != NULL, "Allocation failure.");
+-    for (int i = 0; i < n; i++) _queues[i] = NULL;
++    for (int i = 0; i < n; i++) {
++      _queues[i] = NULL;
+   }
+-
+-  void register_queue(int i, OopTaskQueue* q);
+-
+-  OopTaskQueue* queue(int n);
+-
+-  // The thread with queue number "queue_num" (and whose random number seed 
+-  // is at "seed") is trying to steal a task from some other queue.  (It
+-  // may try several queues, according to some configuration parameter.)
+-  // If some steal succeeds, returns "true" and sets "t" the stolen task,
+-  // otherwise returns false.
+-  bool steal(int queue_num, int* seed, Task& t);
+-
+-  bool peek();
+-};
+-
+-class OopStarTaskQueueSet: public TaskQueueSetSuper {
+-private:
+-  int _n;
+-  OopStarTaskQueue** _queues;
+-
+-  bool steal_1_random(int queue_num, int* seed, StarTask& t);
+-  bool steal_best_of_2(int queue_num, int* seed, StarTask& t);
+-  bool steal_best_of_all(int queue_num, int* seed, StarTask& t);
+-public:
+-  OopStarTaskQueueSet(int n) : _n(n) {
+-    typedef OopStarTaskQueue* OopStarTaskQueuePtr;
+-    _queues = NEW_C_HEAP_ARRAY(OopStarTaskQueuePtr, n);
+-    guarantee(_queues != NULL, "Allocation failure.");
+-    for (int i = 0; i < n; i++) _queues[i] = NULL;
+   }
+ 
+-  void register_queue(int i, OopStarTaskQueue* q);
++  bool steal_1_random(int queue_num, int* seed, E& t);
++  bool steal_best_of_2(int queue_num, int* seed, E& t);
++  bool steal_best_of_all(int queue_num, int* seed, E& t);
++
++  void register_queue(int i, GenericTaskQueue<E>* q);
+ 
+-  OopStarTaskQueue* queue(int n);
++  GenericTaskQueue<E>* queue(int n);
+ 
+   // The thread with queue number "queue_num" (and whose random number seed 
+   // is at "seed") is trying to steal a task from some other queue.  (It
+   // may try several queues, according to some configuration parameter.)
+   // If some steal succeeds, returns "true" and sets "t" the stolen task,
+   // otherwise returns false.
+-  bool steal(int queue_num, int* seed, StarTask& t);
++  bool steal(int queue_num, int* seed, E& t);
+ 
+   bool peek();
+ };
+ 
+-// Clone of OopTaskQueueSet for GenTask
+-class GenTaskQueueSet: public TaskQueueSetSuper {
+-  friend class ChunkTaskQueueSet;
++template<class E>
++void GenericTaskQueueSet<E>::register_queue(int i, GenericTaskQueue<E>* q) {
++  assert(0 <= i && i < _n, "index out of range.");
++  _queues[i] = q;
++}
+ 
+-private:
+-  int _n;
+-  GenTaskQueue** _queues;
++template<class E>
++GenericTaskQueue<E>* GenericTaskQueueSet<E>::queue(int i) {
++  return _queues[i];
++}
+ 
+-protected:
+-  bool steal_1_random(int queue_num, int* seed, GenTask& t);
+-  bool steal_best_of_2(int queue_num, int* seed, GenTask& t);
+-  bool steal_best_of_all(int queue_num, int* seed, GenTask& t);
+-public:
+-  GenTaskQueueSet(int n) : _n(n) {
+-    typedef GenTaskQueue* GenTaskQueuePtr;
+-    _queues = NEW_C_HEAP_ARRAY(GenTaskQueuePtr, n);
+-    guarantee(_queues != NULL, "Allocation failure.");
+-    for (int i = 0; i < n; i++) _queues[i] = NULL;
+-  }
++template<class E>
++bool GenericTaskQueueSet<E>::steal(int queue_num, int* seed, E& t) {
++  for (int i = 0; i < 2 * _n; i++)
++    if (steal_best_of_2(queue_num, seed, t))
++      return true;
++  return false;
++}
+ 
+-  void register_queue(int i, GenTaskQueue* q);
++template<class E>
++bool GenericTaskQueueSet<E>::steal_best_of_all(int queue_num, int* seed, E& t) {
++  if (_n > 2) {
++    int best_k;
++    jint best_sz = 0;
++    for (int k = 0; k < _n; k++) {
++      if (k == queue_num) continue;
++      jint sz = _queues[k]->size();
++      if (sz > best_sz) {
++        best_sz = sz;
++        best_k = k;
++      }
++    }
++    return best_sz > 0 && _queues[best_k]->pop_global(t);
++  } else if (_n == 2) {
++    // Just try the other one.
++    int k = (queue_num + 1) % 2;
++    return _queues[k]->pop_global(t);
++  } else {
++    assert(_n == 1, "can't be zero.");
++    return false;
++  }
++}
+ 
+-  GenTaskQueue* queue(int n);
++template<class E>
++bool GenericTaskQueueSet<E>::steal_1_random(int queue_num, int* seed, E& t) {
++  if (_n > 2) {
++    int k = queue_num;
++    while (k == queue_num) k = randomParkAndMiller(seed) % _n;
++    return _queues[2]->pop_global(t);
++  } else if (_n == 2) {
++    // Just try the other one.
++    int k = (queue_num + 1) % 2;
++    return _queues[k]->pop_global(t);
++  } else {
++    assert(_n == 1, "can't be zero.");
++    return false;
++  }
++}
+ 
+-  // The thread with queue number "queue_num" (and whose random number seed 
+-  // is at "seed") is trying to steal a task from some other queue.  (It
+-  // may try several queues, according to some configuration parameter.)
+-  // If some steal succeeds, returns "true" and sets "t" the stolen task,
+-  // otherwise returns false.
+-  bool steal(int queue_num, int* seed, GenTask& t);
++template<class E>
++bool GenericTaskQueueSet<E>::steal_best_of_2(int queue_num, int* seed, E& t) {
++  if (_n > 2) {
++    int k1 = queue_num;
++    while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n;
++    int k2 = queue_num;
++    while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n;
++    // Sample both and try the larger.
++    juint sz1 = _queues[k1]->size();
++    juint sz2 = _queues[k2]->size();
++    if (sz2 > sz1) return _queues[k2]->pop_global(t);
++    else return _queues[k1]->pop_global(t);
++  } else if (_n == 2) {
++    // Just try the other one.
++    int k = (queue_num + 1) % 2;
++    return _queues[k]->pop_global(t);
++  } else {
++    assert(_n == 1, "can't be zero.");
++    return false;
++  }
++}
+ 
+-  bool peek();
+-};
+-// End clone of OopTaskQueueSet for GenTask
++template<class E>
++bool GenericTaskQueueSet<E>::peek() {
++  // Try all the queues.
++  for (int j = 0; j < _n; j++) {
++    if (_queues[j]->peek())
++      return true;
++  }
++  return false;
++}
+ 
+ // A class to aid in the termination of a set of parallel tasks using
+ // TaskQueueSet's for work stealing.
+@@ -353,8 +391,6 @@
+   int _n_threads;
+   TaskQueueSetSuper* _queue_set;
+   jint _offered_termination;
+-  jint _terminated;
+-  Monitor _term_monitor;
+ 
+   bool peek_in_queue_set();
+ protected:
+@@ -383,7 +419,7 @@
+ 
+ #define SIMPLE_STACK 0
+ 
+-inline bool OopTaskQueue::push(Task t) {
++template<class E> inline bool GenericTaskQueue<E>::push(E t) {
+ #if SIMPLE_STACK
+   juint localBot = _bottom;
+   if (_bottom < max_elems()) {
+@@ -410,7 +446,7 @@
+ #endif
+ }
+ 
+-inline bool OopTaskQueue::pop_local(Task& t) {
++template<class E> inline bool GenericTaskQueue<E>::pop_local(E& t) {
+ #if SIMPLE_STACK
+   juint localBot = _bottom;
+   assert(localBot > 0, "precondition.");
+@@ -450,167 +486,21 @@
+ #endif
+ }
+ 
+-inline bool OopStarTaskQueue::push(StarTask t) {
+-#if SIMPLE_STACK
+-  juint localBot = _bottom;
+-  if (_bottom < max_elems()) {
+-    _elems[localBot] = t;
+-    _bottom = localBot + 1;
+-    return true;
+-  } else {
+-    return false;
+-  }
+-#else
+-  juint localBot = _bottom;
+-  assert((localBot >= 0) && (localBot < n()), "_bottom out of range.");
+-  jushort top = get_top();
+-  juint dirty_n_elems = dirty_size(localBot, top);
+-  assert((dirty_n_elems >= 0) && (dirty_n_elems < n()),
+-	 "n_elems out of range.");
+-  if (dirty_n_elems < max_elems()) {
+-    _elems[localBot] = t;
+-    _bottom = increment_index(localBot);
+-    return true;
+-  } else {
+-    return push_slow(t, dirty_n_elems);
+-  }
+-#endif
+-}
+-
+-inline bool OopStarTaskQueue::pop_local(StarTask& t) {
+-#if SIMPLE_STACK
+-  juint localBot = _bottom;
+-  assert(localBot > 0, "precondition.");
+-  localBot--;
+-  t = _elems[localBot];
+-  _bottom = localBot;
+-  return true;
+-#else
+-  juint localBot = _bottom;
+-  // This value cannot be n-1.  That can only occur as a result of
+-  // the assignment to bottom in this method.  If it does, this method
+-  // resets the size( to 0 before the next call (which is sequential,
+-  // since this is pop_local.)
+-  juint dirty_n_elems = dirty_size(localBot, get_top());
+-  assert(dirty_n_elems != n() - 1, "Shouldn't be possible...");
+-  if (dirty_n_elems == 0) return false;
+-  localBot = decrement_index(localBot);
+-  _bottom = localBot;
+-  // This is necessary to prevent any read below from being reordered
+-  // before the store just above.
+-  OrderAccess::fence();
+-  t = _elems[localBot];
+-  // This is a second read of "age"; the "size()" above is the first.
+-  // If there's still at least one element in the queue, based on the
+-  // "_bottom" and "age" we've read, then there can be no interference with 
+-  // a "pop_global" operation, and we're done.
+-  juint tp = get_top();
+-  if (size(localBot, tp) > 0) {
+-    assert(dirty_size(localBot, tp) != n() - 1,
+-	   "Shouldn't be possible...");
+-    return true;
+-  } else {
+-    // Otherwise, the queue contained exactly one element; we take the slow
+-    // path.
+-    return pop_local_slow(localBot, get_age());
+-  }
+-#endif
+-}
+-
+-// Clone of OopTaskQueue for GenTask
+-
+-inline bool GenTaskQueue::push(GenTask t) {
+-#if SIMPLE_STACK
+-  juint localBot = _bottom;
+-  if (_bottom < max_elems()) {
+-    _elems[localBot] = t;
+-    _bottom = localBot + 1;
+-    return true;
+-  } else {
+-    return false;
+-  }
+-#else
+-  juint localBot = _bottom;
+-  assert((localBot >= 0) && (localBot < n()), "_bottom out of range.");
+-  jushort top = get_top();
+-  juint dirty_n_elems = dirty_size(localBot, top);
+-  assert((dirty_n_elems >= 0) && (dirty_n_elems < n()),
+-	 "n_elems out of range.");
+-  if (dirty_n_elems < max_elems()) {
+-    _elems[localBot] = t;
+-    _bottom = increment_index(localBot);
+-    return true;
+-  } else {
+-    return push_slow(t, dirty_n_elems);
+-  }
+-#endif
+-}
++typedef oop Task;
++typedef GenericTaskQueue<Task>         OopTaskQueue;
++typedef GenericTaskQueueSet<Task>      OopTaskQueueSet;
+ 
+-inline bool GenTaskQueue::pop_local(GenTask& t) {
+-#if SIMPLE_STACK
+-  juint localBot = _bottom;
+-  assert(localBot > 0, "precondition.");
+-  localBot--;
+-  t = _elems[localBot];
+-  _bottom = localBot;
+-  return true;
+-#else
+-  juint localBot = _bottom;
+-  // This value cannot be n-1.  That can only occur as a result of
+-  // the assignment to bottom in this method.  If it does, this method
+-  // resets the size( to 0 before the next call (which is sequential,
+-  // since this is pop_local.)
+-  juint dirty_n_elems = dirty_size(localBot, get_top());
+-  assert(dirty_n_elems != n() - 1, "Shouldn't be possible...");
+-  if (dirty_n_elems == 0) return false;
+-  localBot = decrement_index(localBot);
+-  _bottom = localBot;
+-  // This is necessary to prevent any read below from being reordered
+-  // before the store just above.
+-  OrderAccess::fence();
+-  t = _elems[localBot];
+-  // This is a second read of "age"; the "size()" above is the first.
+-  // If there's still at least one element in the queue, based on the
+-  // "_bottom" and "age" we've read, then there can be no interference with 
+-  // a "pop_global" operation, and we're done.
+-  juint tp = get_top();
+-  if (size(localBot, tp) > 0) {
+-    assert(dirty_size(localBot, tp) != n() - 1,
+-	   "Shouldn't be possible...");
+-    return true;
+-  } else {
+-    // Otherwise, the queue contained exactly one element; we take the slow
+-    // path.
+-    return pop_local_slow(localBot, get_age());
+-  }
+-#endif
+-}
+-// End clone of OopTaskQueue for GenTask
++typedef oop* StarTask;
++typedef GenericTaskQueue<StarTask>     OopStarTaskQueue;
++typedef GenericTaskQueueSet<StarTask>  OopStarTaskQueueSet;
+ 
+ typedef size_t ChunkTask;  // index for chunk
+-
+-class ChunkTaskQueue: public CHeapObj {
+-private:
+-  GenTaskQueue	_chunk_queue;
+-
+- public:
+-  ChunkTaskQueue() {};
+-  ~ChunkTaskQueue() {};
+-
+-  bool push_slow(ChunkTask t, juint dirty_n_elems);
+-  bool pop_local_slow(juint localBot, TaskQueueSuper::Age oldAge);
+-
+-  inline void initialize() { _chunk_queue.initialize(); }
+-  inline bool push(ChunkTask t) { return _chunk_queue.push((GenTask) t); }
+-  inline bool pop_local(ChunkTask& t) { return _chunk_queue.pop_local((GenTask&) t); }
+-  bool pop_global(ChunkTask& t) { return _chunk_queue.pop_global((GenTask&) t); }  
+-  juint size() { return _chunk_queue.size(); }
+-};
++typedef GenericTaskQueue<ChunkTask>    ChunkTaskQueue;
++typedef GenericTaskQueueSet<ChunkTask> ChunkTaskQueueSet;
+ 
+ class ChunkTaskQueueWithOverflow: public CHeapObj {
+-  friend class ChunkTaskQueueSet;
+  protected:
+-  GenTaskQueue	              _chunk_queue;
++  ChunkTaskQueue              _chunk_queue;
+   GrowableArray<ChunkTask>*   _overflow_stack;
+ 
+  public:
+@@ -629,50 +519,7 @@
+   bool stealable_is_empty();
+   bool overflow_is_empty();
+   juint stealable_size() { return _chunk_queue.size(); }
++  ChunkTaskQueue* task_queue() { return &_chunk_queue; }
+ };
+ 
+-class ChunkTaskQueueSet: public CHeapObj {
+-private:
+-  GenTaskQueueSet _task_queue_set;
+-
+-  bool steal_1_random(int queue_num, int* seed, GenTask& t) {
+-    return _task_queue_set.steal_1_random(queue_num, seed, t);
+-  }
+-  bool steal_best_of_2(int queue_num, int* seed, GenTask& t) {
+-    return _task_queue_set.steal_best_of_2(queue_num, seed, t);
+-  }
+-  bool steal_best_of_all(int queue_num, int* seed, GenTask& t) {
+-    return _task_queue_set.steal_best_of_all(queue_num, seed, t);
+-  }
+-public:
+-  ChunkTaskQueueSet(int n) : _task_queue_set(n) {}
+-
+ #define USE_ChunkTaskQueueWithOverflow
+-  void register_queue(int i, GenTaskQueue* q) {
+-    _task_queue_set.register_queue(i, q);
+-  }
+-
+-  void register_queue(int i, ChunkTaskQueueWithOverflow* q) {
+-    register_queue(i, &q->_chunk_queue);
+-  }
+-
+-  ChunkTaskQueue* queue(int n) { 
+-    return (ChunkTaskQueue*) _task_queue_set.queue(n); 
+-  }
+-
+-  GenTaskQueueSet* task_queue_set() { return &_task_queue_set; }
+-
+-  // The thread with queue number "queue_num" (and whose random number seed 
+-  // is at "seed") is trying to steal a task from some other queue.  (It
+-  // may try several queues, according to some configuration parameter.)
+-  // If some steal succeeds, returns "true" and sets "t" the stolen task,
+-  // otherwise returns false.
+-  bool steal(int queue_num, int* seed, GenTask& t) {
+-    return _task_queue_set.steal(queue_num, seed, t);
+-  }
+-
+-  bool peek() {
+-    return _task_queue_set.peek();
+-  }
+-};
+-// End clone of OopTaskQueueSet for GenTask
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/top.hpp openjdk/hotspot/src/share/vm/utilities/top.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/top.hpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/top.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)top.hpp	1.16 07/05/05 17:07:11 JVM"
+-#endif
+ /*
+  * Copyright 1997 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/utf8.cpp openjdk/hotspot/src/share/vm/utilities/utf8.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/utf8.cpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/utf8.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)utf8.cpp	1.30 07/05/05 17:07:07 JVM"
+-#endif
+ /*
+  * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -245,6 +242,3 @@
+   }
+   *utf8_buffer = '\0';
+ }
+-
+-
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/utf8.hpp openjdk/hotspot/src/share/vm/utilities/utf8.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/utf8.hpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/utf8.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)utf8.hpp	1.22 07/05/05 17:07:11 JVM"
+-#endif
+ /*
+  * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/vmError.cpp openjdk/hotspot/src/share/vm/utilities/vmError.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/vmError.cpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/vmError.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vmError.cpp	1.31 07/05/23 10:54:29 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -728,7 +725,7 @@
+       // open log file
+       int fd = -1;
+ 
+-      if (strlen(ErrorFile) > 0) {
++      if (ErrorFile != NULL) {
+         bool copy_ok = 
+           Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer));
+         if (copy_ok) {
+@@ -802,7 +799,7 @@
+       out.print_raw   (cmd);
+       out.print_raw_cr("\" ..."); 
+ 
+-      fork_and_exec(cmd);
++      os::fork_and_exec(cmd);
+     }
+ 
+     // done with OnError
+@@ -865,7 +862,7 @@
+ #endif
+     tty->print_cr("\"%s\"...", cmd);
+ 
+-    _err->fork_and_exec(cmd);
++    os::fork_and_exec(cmd);
+   }
+ }
+ 
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/vmError.hpp openjdk/hotspot/src/share/vm/utilities/vmError.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/vmError.hpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/vmError.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)vmError.hpp	1.17 07/05/05 17:07:11 JVM"
+-#endif
+ /*
+  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -63,9 +60,6 @@
+   // used by reporting about OOM
+   size_t       _size;
+ 
+-  // run cmd in a separate process and return its exit code; or -1 on failures
+-  int fork_and_exec(char* cmd);
+-
+   // set signal handlers on Solaris/Linux or the default exception filter
+   // on Windows, to handle recursive crashes.
+   void reset_signal_handlers();
+@@ -107,4 +101,3 @@
+   // signal was not changed by error reporter
+   static address get_resetted_sighandler(int sig);
+ };
+-
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/workgroup.cpp openjdk/hotspot/src/share/vm/utilities/workgroup.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/workgroup.cpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/workgroup.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)workgroup.cpp	1.36 07/05/05 17:07:11 JVM"
+-#endif
+ /*
+  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/workgroup.hpp openjdk/hotspot/src/share/vm/utilities/workgroup.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/workgroup.hpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/workgroup.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)workgroup.hpp	1.22 07/05/05 17:07:11 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/xmlstream.cpp openjdk/hotspot/src/share/vm/utilities/xmlstream.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/xmlstream.cpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/xmlstream.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)xmlstream.cpp	1.17 07/05/05 17:07:12 JVM"
+-#endif
+ /*
+  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/xmlstream.hpp openjdk/hotspot/src/share/vm/utilities/xmlstream.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/xmlstream.hpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/xmlstream.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)xmlstream.hpp	1.12 07/05/05 17:07:11 JVM"
+-#endif
+ /*
+  * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp openjdk/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp
+--- openjdk6/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)yieldingWorkgroup.cpp	1.11 07/05/05 17:07:11 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp openjdk/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp
+--- openjdk6/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp	2008-08-28 10:23:18.000000000 +0200
++++ openjdk/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp	2007-12-14 08:57:03.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)yieldingWorkgroup.hpp	1.10 07/05/05 17:07:12 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/launcher/java_md.c openjdk/hotspot/src/os/linux/launcher/java_md.c
+--- openjdk6/hotspot/src/os/linux/launcher/java_md.c	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/launcher/java_md.c	2007-12-14 08:57:02.000000000 +0100
+@@ -671,11 +671,11 @@
+ 
+     char *p;
+ 
+-    snprintf(jvmpath, jvmpathsize, GetExecname());
++    snprintf(jvmpath, jvmpathsize, "%s", GetExecname());
+     p = strrchr(jvmpath, '/');
+     if (p) {
+        /* replace executable name with libjvm.so */
+-       snprintf(p + 1, jvmpathsize - (p + 1 - jvmpath), JVM_DLL);
++       snprintf(p + 1, jvmpathsize - (p + 1 - jvmpath), "%s", JVM_DLL);
+     } else {
+        /* this case shouldn't happen */
+        snprintf(jvmpath, jvmpathsize, "%s", JVM_DLL);
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/attachListener_linux.cpp openjdk/hotspot/src/os/linux/vm/attachListener_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/attachListener_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/attachListener_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)attachListener_linux.cpp	1.14 07/05/05 17:04:34 JVM"
+-#endif
+ /*
+  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/c1_globals_linux.hpp openjdk/hotspot/src/os/linux/vm/c1_globals_linux.hpp
+--- openjdk6/hotspot/src/os/linux/vm/c1_globals_linux.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/c1_globals_linux.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c1_globals_linux.hpp	1.12 07/05/05 17:04:35 JVM"
+-#endif
+ /*
+  * Copyright 2000-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/c2_globals_linux.hpp openjdk/hotspot/src/os/linux/vm/c2_globals_linux.hpp
+--- openjdk6/hotspot/src/os/linux/vm/c2_globals_linux.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/c2_globals_linux.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)c2_globals_linux.hpp	1.12 07/05/05 17:04:35 JVM"
+-#endif
+ /*
+  * Copyright 2000-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/chaitin_linux.cpp openjdk/hotspot/src/os/linux/vm/chaitin_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/chaitin_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/chaitin_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)chaitin_linux.cpp	1.11 07/05/05 17:04:35 JVM"
+-#endif
+ /*
+  * Copyright 1999-2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/globals_linux.hpp openjdk/hotspot/src/os/linux/vm/globals_linux.hpp
+--- openjdk6/hotspot/src/os/linux/vm/globals_linux.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/globals_linux.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)globals_linux.hpp	1.12 07/05/05 17:04:35 JVM"
+-#endif
+ /*
+  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/hpi_linux.cpp openjdk/hotspot/src/os/linux/vm/hpi_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/hpi_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/hpi_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)hpi_linux.cpp	1.16 07/05/05 17:04:35 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/hpi_linux.hpp openjdk/hotspot/src/os/linux/vm/hpi_linux.hpp
+--- openjdk6/hotspot/src/os/linux/vm/hpi_linux.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/hpi_linux.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)hpi_linux.hpp	1.18 07/05/05 17:04:34 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/interfaceSupport_linux.hpp openjdk/hotspot/src/os/linux/vm/interfaceSupport_linux.hpp
+--- openjdk6/hotspot/src/os/linux/vm/interfaceSupport_linux.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/interfaceSupport_linux.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)interfaceSupport_linux.hpp	1.6 07/05/05 17:04:35 JVM"
+-#endif
+ /*
+  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -30,4 +27,3 @@
+ static inline void serialize_memory(JavaThread *thread) {
+   os::write_memory_serialize_page(thread);
+ }
+-
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/jsig.c openjdk/hotspot/src/os/linux/vm/jsig.c
+--- openjdk6/hotspot/src/os/linux/vm/jsig.c	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/jsig.c	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jsig.c	1.12 07/05/05 17:04:34 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/jvm_linux.cpp openjdk/hotspot/src/os/linux/vm/jvm_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/jvm_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/jvm_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)jvm_linux.cpp	1.22 08/06/16 14:15:16 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -135,7 +132,7 @@
+ */
+ 
+ struct siglabel {
+-  const char *name;
++  char *name;
+   int   number;
+ };
+ 
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/jvm_linux.h openjdk/hotspot/src/os/linux/vm/jvm_linux.h
+--- openjdk6/hotspot/src/os/linux/vm/jvm_linux.h	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/jvm_linux.h	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)jvm_linux.h	1.15 07/05/05 17:04:35 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/mutex_linux.cpp openjdk/hotspot/src/os/linux/vm/mutex_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/mutex_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/mutex_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,8 +1,5 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)mutex_linux.cpp	1.48 07/05/29 11:38:16 JVM"
+-#endif
+ /*
+- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright (c) 2007 Sun Microsystems, Inc.  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
+@@ -30,470 +27,3 @@
+ 
+ // put OS-includes here
+ # include <signal.h>
+-
+-// Implementation of Mutex
+-
+-// A simple Mutex for VM locking: it is not guaranteed to interoperate with
+-// the fast object locking, so exclusively use Mutex locking or exclusively
+-// use fast object locking.
+-
+-Mutex::Mutex(int rank, const char *name, bool allow_vm_block)
+-  debug_only( : _rank(rank) )
+-{
+-  _lock_event     = new os::Linux::Event;
+-  _suppress_signal = false;
+-  _owner          = INVALID_THREAD;
+-  _name           = name;
+-
+-#ifdef ASSERT
+-  if (CountVMLocks) {
+-    _histogram         = new MutexHistogramElement(name);
+-    _contend_histogram = new MutexContentionHistogramElement(name);
+-  }
+-#endif
+-
+-#ifndef PRODUCT
+-  _lock_count     = -1; // unused in solaris
+-  _allow_vm_block = allow_vm_block;
+-  debug_only(_next = NULL;)
+-  debug_only(_last_owner = INVALID_THREAD;)
+-#endif
+-}
+-
+-
+-Mutex::~Mutex() {  
+-  os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event;
+-
+-  assert(_owner == INVALID_THREAD, "Owned Mutex being deleted");
+-  assert(_lock_count == -1, "Mutex being deleted with non -1 lock count");
+-  delete _Lock_Event;
+-}
+-
+-
+-void Mutex::unlock() {
+-  os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event;
+-
+-  assert(_owner == Thread::current(), "Mutex not being unlocked by owner");
+-
+-  set_owner(INVALID_THREAD);
+-
+-  if (_suppress_signal) {
+-    assert(SafepointSynchronize::is_at_safepoint() &&
+-           Thread::current()->is_VM_thread(), "can't sneak");
+-    _suppress_signal = false;
+-  }
+-  else {
+-    assert(_lock_count >= 0, "Mutex being unlocked without positive lock count");
+-    debug_only(_lock_count--;)
+-    _Lock_Event->unlock();
+-  }
+-}
+-
+-
+-// Can be called by non-Java threads (JVM_RawMonitorExit)
+-void Mutex::jvm_raw_unlock() {
+-  os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event;
+-  // Do not call set_owner, as this would break.
+-  _owner = INVALID_THREAD;
+-  if (_suppress_signal) {
+-    assert(SafepointSynchronize::is_at_safepoint() &&
+-           Thread::current()->is_VM_thread(), "can't sneak");
+-    _suppress_signal = false;
+-  }
+-  else {
+-    debug_only(_lock_count--;)
+-    _Lock_Event->unlock();
+-  }
+-}
+-
+-
+-void Mutex::wait_for_lock_blocking_implementation(JavaThread *thread) {
+-  ThreadBlockInVM tbivm(thread);
+-
+-  wait_for_lock_implementation();
+-}
+-
+-
+-#ifndef PRODUCT
+-void Mutex::print_on(outputStream* st) const {
+-  os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event;
+-
+-  st->print_cr("Mutex: [0x%x/0x%x] %s - owner: 0x%x", this, _Lock_Event, _name, _owner);
+-}
+-#endif
+-
+-
+-//
+-// Monitor
+-//
+-
+-
+-Monitor::Monitor(int rank, const char *name, bool allow_vm_block) : Mutex(rank, name, allow_vm_block) {
+-  _event   = NULL;		
+-  _counter = 0;
+-  _tickets = 0;
+-  _waiters = 0;
+-}
+-
+-
+-Monitor::~Monitor() {
+-}  
+-
+-
+-bool Monitor::wait(bool no_safepoint_check, long timeout,
+-                   bool as_suspend_equivalent) {
+-  os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event;
+-  Thread* thread = Thread::current();
+-
+-  assert(_owner != INVALID_THREAD, "Wait on unknown thread");
+-  assert(_owner == thread, "Wait on Monitor not by owner");
+-
+-  // The design rule for use of mutexes of rank special or less is
+-  // that we are guaranteed not to block while holding such mutexes.
+-  // Here we verify that the least ranked mutex that we hold,
+-  // modulo the mutex we are about to relinquish, satisfies that
+-  // constraint, since we are about to block in a wait.
+-  #ifdef ASSERT
+-    Mutex* least = get_least_ranked_lock_besides_this(thread->owned_locks());
+-    assert(least != this, "Specification of get_least_... call above");
+-    if (least != NULL && least->rank() <= special) {
+-      tty->print("Attempting to wait on monitor %s/%d while holding"
+-                 " lock %s/%d -- possible deadlock",
+-                 name(), rank(), least->name(), least->rank());
+-      assert(false,
+-             "Shouldn't block(wait) while holding a lock of rank special");
+-    }
+-  #endif // ASSERT
+-
+-  long c = _counter;
+-
+-  #ifdef ASSERT
+-    // Don't catch signals while blocked; let the running threads have the signals.
+-    // (This allows a debugger to break into the running thread.)
+-    sigset_t oldsigs;
+-    sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals();
+-    pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
+-  #endif
+-
+-  _waiters++;
+-  // Loop until condition variable is signaled.  Tickets will
+-  // reflect the number of threads which have been notified. The counter
+-  // field is used to make sure we don't respond to notifications that
+-  // have occurred *before* we started waiting, and is incremented each
+-  // time the condition variable is signaled.
+-  // Use a ticket scheme to guard against spurious wakeups.
+-  int wait_status;
+-
+-  while (true) {
+-
+-    if (no_safepoint_check) {
+-
+-      // conceptually set the owner to INVALID_THREAD in anticipation of yielding the lock in wait
+-      set_owner(Mutex::INVALID_THREAD);
+-
+-      // (SafepointTimeout is not implemented)
+-      if(timeout == 0) {
+-	wait_status = _Lock_Event->wait();
+-      }
+-      else {
+-	wait_status = _Lock_Event->timedwait(timeout);
+-      }
+-    } else {
+-      JavaThread *jt = (JavaThread *)thread;
+-
+-      // conceptually set the owner to INVALID_THREAD in anticipation of yielding the lock in wait
+-      set_owner(Mutex::INVALID_THREAD);
+-
+-      // Enter safepoint region
+-      ThreadBlockInVM tbivm(jt);
+-      OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
+-
+-      if (as_suspend_equivalent) {
+-        jt->set_suspend_equivalent();
+-        // cleared by handle_special_suspend_equivalent_condition() or
+-        // java_suspend_self()
+-      }
+-
+-      if(timeout == 0) {
+-	wait_status = _Lock_Event->wait();
+-      }
+-      else {
+-	wait_status = _Lock_Event->timedwait(timeout);
+-      }
+-
+-      // were we externally suspended while we were waiting?
+-      if (as_suspend_equivalent &&
+-          jt->handle_special_suspend_equivalent_condition()) {
+-        //
+-        // Our event wait has finished and we own the _Lock_Event, but
+-        // while we were waiting another thread suspended us. We don't
+-        // want to hold the _Lock_Event while suspended because that
+-        // would surprise the thread that suspended us.
+-        //
+-        _Lock_Event->unlock();
+-        jt->java_suspend_self();
+-        _Lock_Event->lock();
+-      }
+-    } // if no_safepoint_check
+-
+-    // conceptually reaquire the lock (the actual Linux lock is already reacquired after waiting)
+-    set_owner(thread);
+-
+-    // We get to this point if either:
+-    // a) a notify has been executed by some other thread and woke us up
+-    // b) a signal has been delivered to this thread and terminated wait
+-    // c) the above two events happened while we were waiting - that is a signal
+-    //    was delivered while notify was executed by some other thread.
+-
+-    // Handle cases a) and c) here. We consume one ticket even in case c) when notify
+-    // and a signal arrive together
+-    if (_tickets != 0 && _counter != c) {
+-      break;
+-    }
+-    
+-    // If wait was interrupted by a signal or timeout, do not use up a ticket
+-    if (wait_status == EINTR || wait_status == ETIME || wait_status == ETIMEDOUT) {
+-      ++_tickets;		// will be decremented again below
+-      break;
+-    }
+-
+-
+-  }
+-  _waiters--;
+-  _tickets--;
+-
+-#ifdef ASSERT
+-  pthread_sigmask(SIG_SETMASK, &oldsigs, NULL);
+-#endif
+-   
+-  // return true if timed out
+-  return (wait_status == ETIME || wait_status == ETIMEDOUT);
+-}
+-
+-
+-// Notify a single thread waiting on this condition variable
+-bool Monitor::notify() {
+-  os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event;
+-
+-  assert(_owner != INVALID_THREAD, "notify on unknown thread");
+-  assert(_owner == Thread::current(), "notify on Monitor not by owner");
+-
+-  if (_waiters > _tickets) {
+-    
+-    _Lock_Event->signal();
+-    
+-    _tickets++;
+-    _counter++;
+-  }
+-
+-  return true;
+-
+-}
+-
+-
+-// Notify all threads waiting on this ConditionVariable
+-bool Monitor::notify_all() {
+-  os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event;
+-
+-  assert(_owner != INVALID_THREAD, "notify on unknown thread");
+-  assert(_owner == Thread::current(), "notify on Monitor not by owner");
+-
+-  if (_waiters > 0) {
+-
+-    _Lock_Event->broadcast();
+-
+-    _tickets = _waiters;
+-    _counter++;
+-  }
+-
+-  return true;
+-}
+-
+-// JSR166
+-// -------------------------------------------------------
+-
+-/*
+- * The solaris and linux implementations of park/unpark are fairly
+- * conservative for now, but can be improved. They currently use a
+- * mutex/condvar pair, plus a a count. 
+- * Park decrements count if > 0, else does a condvar wait.  Unpark
+- * sets count to 1 and signals condvar.  Only one thread ever waits 
+- * on the condvar. Contention seen when trying to park implies that someone 
+- * is unparking you, so don't wait. And spurious returns are fine, so there 
+- * is no need to track notifications.
+- */
+-
+-#define NANOSECS_PER_SEC 1000000000
+-#define NANOSECS_PER_MILLISEC 1000000
+-#define MAX_SECS 100000000
+-/*
+- * This code is common to linux and solaris and will be moved to a
+- * common place in dolphin.
+- *
+- * The passed in time value is either a relative time in nanoseconds
+- * or an absolute time in milliseconds. Either way it has to be unpacked
+- * into suitable seconds and nanoseconds components and stored in the
+- * given timespec structure. 
+- * Given time is a 64-bit value and the time_t used in the timespec is only 
+- * a signed-32-bit value (except on 64-bit Linux) we have to watch for
+- * overflow if times way in the future are given. Further on Solaris versions
+- * prior to 10 there is a restriction (see cond_timedwait) that the specified
+- * number of seconds, in abstime, is less than current_time  + 100,000,000.
+- * As it will be 28 years before "now + 100000000" will overflow we can
+- * ignore overflow and just impose a hard-limit on seconds using the value
+- * of "now + 100,000,000". This places a limit on the timeout of about 3.17
+- * years from "now".
+- */
+-static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
+-  assert (time > 0, "convertTime");
+-
+-  struct timeval now;
+-  int status = gettimeofday(&now, NULL);
+-  assert(status == 0, "gettimeofday");
+-
+-  time_t max_secs = now.tv_sec + MAX_SECS;
+-
+-  if (isAbsolute) {
+-    jlong secs = time / 1000;
+-    if (secs > max_secs) {
+-      absTime->tv_sec = max_secs;
+-    }
+-    else {
+-      absTime->tv_sec = secs;
+-    }
+-    absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;   
+-  }
+-  else {
+-    jlong secs = time / NANOSECS_PER_SEC;
+-    if (secs >= MAX_SECS) {
+-      absTime->tv_sec = max_secs;
+-      absTime->tv_nsec = 0;
+-    }
+-    else {
+-      absTime->tv_sec = now.tv_sec + secs;
+-      absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
+-      if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
+-        absTime->tv_nsec -= NANOSECS_PER_SEC;
+-        ++absTime->tv_sec; // note: this must be <= max_secs
+-      }
+-    }
+-  }
+-  assert(absTime->tv_sec >= 0, "tv_sec < 0");
+-  assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
+-  assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
+-  assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
+-}
+-
+-void Parker::park(bool isAbsolute, jlong time) {
+-  // Optional fast-path check:
+-  // Return immediately if a permit is available.
+-  if (_counter > 0) { 
+-      _counter = 0 ;  
+-      return ;  
+-  }
+-
+-  Thread* thread = Thread::current();
+-  assert(thread->is_Java_thread(), "Must be JavaThread");
+-  JavaThread *jt = (JavaThread *)thread;
+-
+-  // Optional optimization -- avoid state transitions if there's an interrupt pending.
+-  // Check interrupt before trying to wait
+-  if (Thread::is_interrupted(thread, false)) {
+-    return;
+-  }
+-
+-  // Next, demultiplex/decode time arguments
+-  timespec absTime;
+-  if (time < 0) { // don't wait at all
+-    return; 
+-  }
+-  if (time > 0) {
+-    unpackTime(&absTime, isAbsolute, time);
+-  }
+-
+-
+-  // Enter safepoint region
+-  // Beware of deadlocks such as 6317397. 
+-  // The per-thread Parker:: mutex is a classic leaf-lock.
+-  // In particular a thread must never block on the Threads_lock while
+-  // holding the Parker:: mutex.  If safepoints are pending both the
+-  // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.  
+-  ThreadBlockInVM tbivm(jt);
+-
+-  // Don't wait if cannot get lock since interference arises from
+-  // unblocking.  Also. check interrupt before trying wait
+-  if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) {
+-    return;
+-  }
+-
+-  int status ; 
+-  if (_counter > 0)  { // no wait needed
+-    _counter = 0;
+-    status = pthread_mutex_unlock(_mutex);
+-    assert (status == 0, "invariant") ; 
+-    return;
+-  }
+-
+-#ifdef ASSERT
+-  // Don't catch signals while blocked; let the running threads have the signals.
+-  // (This allows a debugger to break into the running thread.)
+-  sigset_t oldsigs;
+-  sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals();
+-  pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
+-#endif
+-  
+-  OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
+-  jt->set_suspend_equivalent();
+-  // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
+-  
+-  if (time == 0) {
+-    status = pthread_cond_wait (_cond, _mutex) ; 
+-  } else {
+-    status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ; 
+-    if (status != 0 && WorkAroundNPTLTimedWaitHang) { 
+-      pthread_cond_destroy (_cond) ; 
+-      pthread_cond_init    (_cond, NULL); 
+-    }
+-  }
+-  assert_status(status == 0 || status == EINTR || 
+-                status == ETIME || status == ETIMEDOUT, 
+-                status, "cond_timedwait");
+-
+-#ifdef ASSERT
+-  pthread_sigmask(SIG_SETMASK, &oldsigs, NULL);
+-#endif
+-
+-  _counter = 0 ; 
+-  status = pthread_mutex_unlock(_mutex) ;
+-  assert_status(status == 0, status, "invariant") ; 
+-  // If externally suspended while waiting, re-suspend
+-  if (jt->handle_special_suspend_equivalent_condition()) {
+-    jt->java_suspend_self();
+-  }
+-
+-}
+-
+-void Parker::unpark() {
+-  int s, status ; 
+-  status = pthread_mutex_lock(_mutex);
+-  assert (status == 0, "invariant") ; 
+-  s = _counter;
+-  _counter = 1;
+-  if (s < 1) { 
+-     if (WorkAroundNPTLTimedWaitHang) { 
+-        status = pthread_cond_signal (_cond) ; 
+-        assert (status == 0, "invariant") ; 
+-        status = pthread_mutex_unlock(_mutex);
+-        assert (status == 0, "invariant") ; 
+-     } else {
+-        status = pthread_mutex_unlock(_mutex);
+-        assert (status == 0, "invariant") ; 
+-        status = pthread_cond_signal (_cond) ; 
+-        assert (status == 0, "invariant") ; 
+-     }
+-  } else {
+-    pthread_mutex_unlock(_mutex);
+-    assert (status == 0, "invariant") ; 
+-  }
+-}
+-
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/mutex_linux.inline.hpp openjdk/hotspot/src/os/linux/vm/mutex_linux.inline.hpp
+--- openjdk6/hotspot/src/os/linux/vm/mutex_linux.inline.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/mutex_linux.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)mutex_linux.inline.hpp	1.12 07/05/05 17:04:36 JVM"
+-#endif
+ /*
+  * Copyright 1999-2002 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -25,26 +22,6 @@
+  *  
+  */
+ 
+-inline bool Mutex::lock_implementation() {
+-  int status = ((os::Linux::Event*)_lock_event)->trylock();
+-  if (status != 0) { 
+-    debug_only(_lock_count++); 
+-    return true; 
+-  } 
+-  return false;
+-}
+-
+-inline bool Mutex::try_lock_implementation() {
+-  // Same on Linux.
+-  return lock_implementation();
+-}
+-
+-
+-inline void Mutex::wait_for_lock_implementation() {
+-  assert(!owned_by_self(), "deadlock");
+-  ((os::Linux::Event*)_lock_event)->lock();
+-  debug_only(_lock_count++;)
+-}
+ 
+ // Reconciliation History
+ // mutex_solaris.inline.hpp	1.5 99/06/22 16:38:49
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.cpp openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)objectMonitor_linux.cpp	1.69 07/05/05 17:04:36 JVM"
+-#endif
+ 
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+@@ -25,4 +22,3 @@
+  * have any questions.
+  *  
+  */
+-
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.hpp openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.hpp
+--- openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)objectMonitor_linux.hpp	1.18 07/05/05 17:04:36 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -26,4 +23,3 @@
+  */
+ 
+  private:
+-
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.inline.hpp openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.inline.hpp
+--- openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.inline.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)objectMonitor_linux.inline.hpp	1.14 07/05/05 17:04:36 JVM"
+-#endif
+ /*
+  * Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -24,4 +21,3 @@
+  * have any questions.
+  *  
+  */
+-
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/os_linux.cpp openjdk/hotspot/src/os/linux/vm/os_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/os_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)os_linux.cpp	1.258 08/06/16 14:16:05 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -78,8 +75,8 @@
+ bool os::Linux::_is_floating_stack = false;
+ bool os::Linux::_is_NPTL = false;
+ bool os::Linux::_supports_fast_thread_cpu_time = false;
+-const char * os::Linux::_glibc_version = NULL;
+-const char * os::Linux::_libpthread_version = NULL;
++char * os::Linux::_glibc_version = NULL;
++char * os::Linux::_libpthread_version = NULL;
+ 
+ static jlong initial_time_count=0;
+ 
+@@ -202,7 +199,7 @@
+ // the system call returns 1.  This causes the VM to act as if it is
+ // a single processor and elide locking (see is_MP() call).
+ static bool unsafe_chroot_detected = false;
+-static const char *unstable_chroot_error = "/proc file system not found.\n"
++static char *unstable_chroot_error = "/proc file system not found.\n"
+                     "Java may be unstable running multithreaded in a chroot "
+                     "environment on Linux when /proc filesystem is not mounted.";
+ 
+@@ -536,18 +533,20 @@
+ 
+      // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
+      // us "NPTL-0.29" even we are running with LinuxThreads. Check if this
+-     // is the case. Also, LinuxThreads has a hard limit on max number of 
+-     // threads. So sysconf(_SC_THREAD_THREADS_MAX) will return a positive 
+-     // value.On the other hand, NPTL does not have such a limit, sysconf()
+-     // will return -1 and errno is not changed. Check if it is really NPTL.
++     // is the case:
+      if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 &&
+-         strstr(str, "NPTL") &&
+-         sysconf(_SC_THREAD_THREADS_MAX) > 0) {
++         strstr(str, "NPTL")) {
++        // LinuxThreads has a hard limit on max number of threads. So
++        // sysconf(_SC_THREAD_THREADS_MAX) will return a positive value.
++        // On the other hand, NPTL does not have such a limit, sysconf()
++        // will return -1 and errno is not changed. Check if it is really
++        // NPTL:
++        if (sysconf(_SC_THREAD_THREADS_MAX) > 0) {
+        free(str);
+-       os::Linux::set_libpthread_version("linuxthreads");
+-     } else {
+-       os::Linux::set_libpthread_version(str);
++           str = "linuxthreads";
++        }
+      }
++     os::Linux::set_libpthread_version(str);
+   } else {
+     // glibc before 2.3.2 only has LinuxThreads.
+     os::Linux::set_libpthread_version("linuxthreads");
+@@ -2292,7 +2291,8 @@
+   return ::munmap(addr, size) == 0;
+ }
+ 
+-char* os::reserve_memory(size_t bytes, char* requested_addr) {
++char* os::reserve_memory(size_t bytes, char* requested_addr,
++                         size_t alignment_hint) {
+   return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
+ }
+ 
+@@ -2378,6 +2378,13 @@
+     }
+   }
+ 
++  const size_t default_page_size = (size_t)Linux::page_size();
++  if (_large_page_size > default_page_size) {
++    _page_sizes[0] = _large_page_size;
++    _page_sizes[1] = default_page_size;
++    _page_sizes[2] = 0;
++  }
++
+   // Large page support is available on 2.6 or newer kernel, some vendors
+   // (e.g. Redhat) have backported it to their 2.4 based distributions.
+   // We optimistically assume the support is available. If later it turns out
+@@ -2567,12 +2574,11 @@
+ int os::sleep(Thread* thread, jlong millis, bool interruptible) {
+   assert(thread == Thread::current(),  "thread consistency check");
+ 
+-  if (interruptible) {
+-    OSThread* osthread = thread->osthread();
+-    Linux::Event* event = (Linux::Event*) osthread->interrupt_event();
+-    event->reset() ; 
++  ParkEvent * const slp = thread->_SleepEvent ;
++  slp->reset() ;
+     OrderAccess::fence() ; 
+ 
++  if (interruptible) {
+     jlong prevtime = javaTimeNanos();
+ 
+     for (;;) {
+@@ -2606,7 +2612,7 @@
+         // cleared by handle_special_suspend_equivalent_condition() or
+         // java_suspend_self() via check_and_wait_while_suspended()
+ 
+-        event->park(millis);
++        slp->park(millis);
+ 
+         // were we externally suspended while we were waiting?
+         jt->check_and_wait_while_suspended();
+@@ -2614,11 +2620,27 @@
+     }
+   } else {
+     OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
+-    Linux::Event event;
+-    event.lock();
+-    int rslt = event.timedwait(millis);
+-    event.unlock();
+-    return rslt;
++    jlong prevtime = javaTimeNanos();
++
++    for (;;) {
++      // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
++      // the 1st iteration ...
++      jlong newtime = javaTimeNanos();
++
++      if (newtime - prevtime < 0) {
++        // time moving backwards, should only happen if no monotonic clock
++        // not a guarantee() because JVM should not abort on kernel/glibc bugs
++        assert(!Linux::supports_monotonic_clock(), "time moving backwards");
++      } else {
++        millis -= (newtime - prevtime) / NANOSECS_PER_MILLISECS;
++      }
++
++      if(millis <= 0) break ;
++
++      prevtime = newtime;
++      slp->park(millis);
++    }
++    return OS_OK ;
+   }
+ }
+ 
+@@ -2643,7 +2665,7 @@
+   sched_yield();
+ }
+ 
+-void os::NakedYield() { sched_yield(); } 
++os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;}
+ 
+ void os::yield_all(int attempts) {
+   // Yields to all threads, including threads with lower priorities
+@@ -2914,13 +2936,13 @@
+   OSThread* osthread = thread->osthread();
+ 
+   if (!osthread->interrupted()) {
+-    Linux::Event* event = (Linux::Event*) osthread->interrupt_event();
+     osthread->set_interrupted(true);
+     // More than one thread can get here with the same value of osthread,
+     // resulting in multiple notifications.  We do, however, want the store
+     // to interrupted() to be visible to other threads before we execute unpark().
+     OrderAccess::fence();
+-    event->unpark();
++    ParkEvent * const slp = thread->_SleepEvent ;
++    if (slp != NULL) slp->unpark() ;
+   }
+ 
+   // For JSR166. Unpark even if interrupt status already was set
+@@ -2941,9 +2963,8 @@
+   bool interrupted = osthread->interrupted();
+ 
+   if (interrupted && clear_interrupted) {
+-    Linux::Event* event = (Linux::Event*) osthread->interrupt_event();
+     osthread->set_interrupted(false);
+-    event->reset();
++    // consider thread->_SleepEvent->reset() ... optional optimization
+   }
+ 
+   return interrupted;
+@@ -3437,10 +3458,10 @@
+   ThreadCritical::initialize();
+ 
+   Linux::set_page_size(sysconf(_SC_PAGESIZE));
+-
+   if (Linux::page_size() == -1) {
+     fatal1("os_linux.cpp: os::init: sysconf failed (%s)", strerror(errno));
+   }
++  init_page_sizes((size_t) Linux::page_size());
+ 
+   Linux::initialize_system_info();
+ 
+@@ -4029,26 +4050,6 @@
+   }
+ }
+ 
+-#ifndef PRODUCT
+-void os::Linux::Event::verify() {
+-  guarantee(!Universe::is_fully_initialized() ||
+-            !Universe::heap()->is_in_reserved((oop)this),
+-            "Mutex must be in C heap only.");
+-}
+-
+-void os::Linux::OSMutex::verify() {
+-  guarantee(!Universe::is_fully_initialized() || 
+-    	    !Universe::heap()->is_in_reserved((oop)this), 
+-    	    "OSMutex must be in C heap only.");
+-}
+-
+-void os::Linux::OSMutex::verify_locked() {
+-  pthread_t my_id = pthread_self();
+-  assert(_is_owned, "OSMutex should be locked");
+-  assert(pthread_equal(_owner, my_id), "OSMutex should be locked by me");
+-}
+-#endif
+-
+ extern "C" {
+ 
+ /**
+@@ -4146,6 +4147,42 @@
+ // It may be possible to refine (4) by checking the kernel and NTPL verisons
+ // and only enabling the work-around for vulnerable environments. 
+ 
++// utility to compute the abstime argument to timedwait:
++// millis is the relative timeout time
++// abstime will be the absolute timeout time
++// TODO: replace compute_abstime() with unpackTime()
++
++static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
++  if (millis < 0)  millis = 0;
++  struct timeval now;
++  int status = gettimeofday(&now, NULL);
++  assert(status == 0, "gettimeofday");
++  jlong seconds = millis / 1000;
++  millis %= 1000;
++  if (seconds > 50000000) { // see man cond_timedwait(3T)
++    seconds = 50000000;
++  }
++  abstime->tv_sec = now.tv_sec  + seconds;
++  long       usec = now.tv_usec + millis * 1000;
++  if (usec >= 1000000) {
++    abstime->tv_sec += 1;
++    usec -= 1000000;
++  }
++  abstime->tv_nsec = usec * 1000;
++  return abstime;
++}
++
++
++// Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
++// Conceptually TryPark() should be equivalent to park(0).
++
++int os::PlatformEvent::TryPark() {
++  for (;;) {
++    const int v = _Event ;
++    guarantee ((v == 0) || (v == 1), "invariant") ;
++    if (Atomic::cmpxchg (0, &_Event, v) == v) return v  ;
++  }
++}
+ 
+ void os::PlatformEvent::park() {       // AKA "down()"
+   // Invariant: Only the thread associated with the Event/PlatformEvent
+@@ -4195,7 +4232,7 @@
+   // We do this the hard way, by blocking the thread.
+   // Consider enforcing a minimum timeout value.  
+   struct timespec abst;
+-  os::Linux::Event::compute_abstime(&abst, millis);
++  compute_abstime(&abst, millis);
+ 
+   int ret = OS_TIMEOUT;
+   int status = pthread_mutex_lock(_mutex);
+@@ -4282,3 +4319,276 @@
+   // simply re-test the condition and re-park itself.  
+ }
+ 
++
++// JSR166
++// -------------------------------------------------------
++
++/*
++ * The solaris and linux implementations of park/unpark are fairly
++ * conservative for now, but can be improved. They currently use a
++ * mutex/condvar pair, plus a a count.
++ * Park decrements count if > 0, else does a condvar wait.  Unpark
++ * sets count to 1 and signals condvar.  Only one thread ever waits
++ * on the condvar. Contention seen when trying to park implies that someone
++ * is unparking you, so don't wait. And spurious returns are fine, so there
++ * is no need to track notifications.
++ */
++
++
++#define NANOSECS_PER_SEC 1000000000
++#define NANOSECS_PER_MILLISEC 1000000
++#define MAX_SECS 100000000
++/*
++ * This code is common to linux and solaris and will be moved to a
++ * common place in dolphin.
++ *
++ * The passed in time value is either a relative time in nanoseconds
++ * or an absolute time in milliseconds. Either way it has to be unpacked
++ * into suitable seconds and nanoseconds components and stored in the
++ * given timespec structure.
++ * Given time is a 64-bit value and the time_t used in the timespec is only
++ * a signed-32-bit value (except on 64-bit Linux) we have to watch for
++ * overflow if times way in the future are given. Further on Solaris versions
++ * prior to 10 there is a restriction (see cond_timedwait) that the specified
++ * number of seconds, in abstime, is less than current_time  + 100,000,000.
++ * As it will be 28 years before "now + 100000000" will overflow we can
++ * ignore overflow and just impose a hard-limit on seconds using the value
++ * of "now + 100,000,000". This places a limit on the timeout of about 3.17
++ * years from "now".
++ */
++
++static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
++  assert (time > 0, "convertTime");
++
++  struct timeval now;
++  int status = gettimeofday(&now, NULL);
++  assert(status == 0, "gettimeofday");
++
++  time_t max_secs = now.tv_sec + MAX_SECS;
++
++  if (isAbsolute) {
++    jlong secs = time / 1000;
++    if (secs > max_secs) {
++      absTime->tv_sec = max_secs;
++    }
++    else {
++      absTime->tv_sec = secs;
++    }
++    absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
++  }
++  else {
++    jlong secs = time / NANOSECS_PER_SEC;
++    if (secs >= MAX_SECS) {
++      absTime->tv_sec = max_secs;
++      absTime->tv_nsec = 0;
++    }
++    else {
++      absTime->tv_sec = now.tv_sec + secs;
++      absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
++      if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
++        absTime->tv_nsec -= NANOSECS_PER_SEC;
++        ++absTime->tv_sec; // note: this must be <= max_secs
++      }
++    }
++  }
++  assert(absTime->tv_sec >= 0, "tv_sec < 0");
++  assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
++  assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
++  assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
++}
++
++void Parker::park(bool isAbsolute, jlong time) {
++  // Optional fast-path check:
++  // Return immediately if a permit is available.
++  if (_counter > 0) {
++      _counter = 0 ;
++      return ;
++  }
++
++  Thread* thread = Thread::current();
++  assert(thread->is_Java_thread(), "Must be JavaThread");
++  JavaThread *jt = (JavaThread *)thread;
++
++  // Optional optimization -- avoid state transitions if there's an interrupt pending.
++  // Check interrupt before trying to wait
++  if (Thread::is_interrupted(thread, false)) {
++    return;
++  }
++
++  // Next, demultiplex/decode time arguments
++  timespec absTime;
++  if (time < 0) { // don't wait at all
++    return;
++  }
++  if (time > 0) {
++    unpackTime(&absTime, isAbsolute, time);
++  }
++
++
++  // Enter safepoint region
++  // Beware of deadlocks such as 6317397.
++  // The per-thread Parker:: mutex is a classic leaf-lock.
++  // In particular a thread must never block on the Threads_lock while
++  // holding the Parker:: mutex.  If safepoints are pending both the
++  // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
++  ThreadBlockInVM tbivm(jt);
++
++  // Don't wait if cannot get lock since interference arises from
++  // unblocking.  Also. check interrupt before trying wait
++  if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) {
++    return;
++  }
++
++  int status ;
++  if (_counter > 0)  { // no wait needed
++    _counter = 0;
++    status = pthread_mutex_unlock(_mutex);
++    assert (status == 0, "invariant") ;
++    return;
++  }
++
++#ifdef ASSERT
++  // Don't catch signals while blocked; let the running threads have the signals.
++  // (This allows a debugger to break into the running thread.)
++  sigset_t oldsigs;
++  sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals();
++  pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
++#endif
++
++  OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
++  jt->set_suspend_equivalent();
++  // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
++
++  if (time == 0) {
++    status = pthread_cond_wait (_cond, _mutex) ;
++  } else {
++    status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ;
++    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
++      pthread_cond_destroy (_cond) ;
++      pthread_cond_init    (_cond, NULL);
++    }
++  }
++  assert_status(status == 0 || status == EINTR ||
++                status == ETIME || status == ETIMEDOUT,
++                status, "cond_timedwait");
++
++#ifdef ASSERT
++  pthread_sigmask(SIG_SETMASK, &oldsigs, NULL);
++#endif
++
++  _counter = 0 ;
++  status = pthread_mutex_unlock(_mutex) ;
++  assert_status(status == 0, status, "invariant") ;
++  // If externally suspended while waiting, re-suspend
++  if (jt->handle_special_suspend_equivalent_condition()) {
++    jt->java_suspend_self();
++  }
++
++}
++
++void Parker::unpark() {
++  int s, status ;
++  status = pthread_mutex_lock(_mutex);
++  assert (status == 0, "invariant") ;
++  s = _counter;
++  _counter = 1;
++  if (s < 1) {
++     if (WorkAroundNPTLTimedWaitHang) {
++        status = pthread_cond_signal (_cond) ;
++        assert (status == 0, "invariant") ;
++        status = pthread_mutex_unlock(_mutex);
++        assert (status == 0, "invariant") ;
++     } else {
++        status = pthread_mutex_unlock(_mutex);
++        assert (status == 0, "invariant") ;
++        status = pthread_cond_signal (_cond) ;
++        assert (status == 0, "invariant") ;
++     }
++  } else {
++    pthread_mutex_unlock(_mutex);
++    assert (status == 0, "invariant") ;
++  }
++}
++
++
++extern char** environ;
++
++#ifndef __NR_fork
++#define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57)
++#endif
++
++#ifndef __NR_execve
++#define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59)
++#endif
++
++// Run the specified command in a separate process. Return its exit value,
++// or -1 on failure (e.g. can't fork a new process).
++// Unlike system(), this function can be called from signal handler. It
++// doesn't block SIGINT et al.
++int os::fork_and_exec(char* cmd) {
++  char * argv[4];
++  argv[0] = "sh";
++  argv[1] = "-c";
++  argv[2] = cmd;
++  argv[3] = NULL;
++
++  // fork() in LinuxThreads/NPTL is not async-safe. It needs to run
++  // pthread_atfork handlers and reset pthread library. All we need is a
++  // separate process to execve. Make a direct syscall to fork process.
++  // On IA64 there's no fork syscall, we have to use fork() and hope for
++  // the best...
++  pid_t pid = NOT_IA64(syscall(__NR_fork);)
++              IA64_ONLY(fork();)
++
++  if (pid < 0) {
++    // fork failed
++    return -1;
++
++  } else if (pid == 0) {
++    // child process
++
++    // execve() in LinuxThreads will call pthread_kill_other_threads_np()
++    // first to kill every thread on the thread list. Because this list is
++    // not reset by fork() (see notes above), execve() will instead kill
++    // every thread in the parent process. We know this is the only thread
++    // in the new process, so make a system call directly.
++    // IA64 should use normal execve() from glibc to match the glibc fork()
++    // above.
++    NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
++    IA64_ONLY(execve("/bin/sh", argv, environ);)
++
++    // execve failed
++    _exit(-1);
++
++  } else  {
++    // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
++    // care about the actual exit code, for now.
++
++    int status;
++
++    // Wait for the child process to exit.  This returns immediately if
++    // the child has already exited. */
++    while (waitpid(pid, &status, 0) < 0) {
++        switch (errno) {
++        case ECHILD: return 0;
++        case EINTR: break;
++        default: return -1;
++        }
++    }
++
++    if (WIFEXITED(status)) {
++       // The child exited normally; get its exit code.
++       return WEXITSTATUS(status);
++    } else if (WIFSIGNALED(status)) {
++       // The child exited because of a signal
++       // The best value to return is 0x80 + signal number,
++       // because that is what all Unix shells do, and because
++       // it allows callers to distinguish between process exit and
++       // process death by signal.
++       return 0x80 + WTERMSIG(status);
++    } else {
++       // Unknown exit code; pass it through
++       return status;
++    }
++  }
++}
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/os_linux.hpp openjdk/hotspot/src/os/linux/vm/os_linux.hpp
+--- openjdk6/hotspot/src/os/linux/vm/os_linux.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/os_linux.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)os_linux.hpp	1.71 08/06/16 14:16:05 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -55,8 +52,8 @@
+   static address   _initial_thread_stack_bottom;
+   static uintptr_t _initial_thread_stack_size;
+ 
+-  static const char *_glibc_version;
+-  static const char *_libpthread_version;
++  static char *_glibc_version;
++  static char *_libpthread_version;
+ 
+   static bool _is_floating_stack;
+   static bool _is_NPTL;
+@@ -73,8 +70,8 @@
+   static julong physical_memory() { return _physical_memory; }
+   static void initialize_system_info();
+ 
+-  static void set_glibc_version(const char *s)      { _glibc_version = s; }
+-  static void set_libpthread_version(const char *s) { _libpthread_version = s; }
++  static void set_glibc_version(char *s)      { _glibc_version = s; }
++  static void set_libpthread_version(char *s) { _libpthread_version = s; }
+ 
+   static bool supports_variable_stack_size();
+ 
+@@ -134,8 +131,8 @@
+   static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
+ 
+   // GNU libc and libpthread version strings
+-  static const char *glibc_version()          { return _glibc_version; }
+-  static const char *libpthread_version()     { return _libpthread_version; }
++  static char *glibc_version()                { return _glibc_version; }
++  static char *libpthread_version()           { return _libpthread_version; }
+ 
+   // NPTL or LinuxThreads?
+   static bool is_LinuxThreads()               { return !_is_NPTL; }
+@@ -192,252 +189,6 @@
+   // LinuxThreads work-around for 6292965
+   static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
+ 
+-  // An event is a condition variable with associated mutex.
+-  // (A cond_t is only usable in combination with a mutex_t.)
+-  class Event : public CHeapObj {
+-   private:
+-    volatile int    _count;
+-    volatile int _nParked ; 
+-    double cachePad [4] ; 
+-    pthread_mutex_t _mutex[1];
+-    pthread_cond_t  _cond[1];
+-
+-   public:
+-    Event * FreeNext ;                  // TSM free list linkage
+-    int Immortal ;                         
+-    
+-   public:
+-    Event() {
+-      verify();
+-      int status;
+-      status = pthread_cond_init(_cond, NULL);
+-      assert_status(status == 0, status, "cond_init");
+-      status = pthread_mutex_init(_mutex, NULL);
+-      assert_status(status == 0, status, "mutex_init");
+-      _count = 0;
+-      _nParked = 0 ; 
+-      FreeNext = NULL ; 
+-      Immortal = 0 ; 
+-    }
+-    ~Event() {
+-      int status;
+-      guarantee (Immortal == 0, "invariant") ; 
+-      guarantee (_nParked == 0, "invariant") ; 
+-      status = pthread_cond_destroy(_cond);
+-      assert_status(status == 0, status, "cond_destroy");
+-      status = pthread_mutex_destroy(_mutex);
+-      assert_status(status == 0, status, "mutex_destroy");
+-    }
+-    // hook to check for mutex corruption:
+-    void verify() PRODUCT_RETURN;
+-    // for use in critical sections:
+-    void lock() {
+-      verify();
+-      int status = pthread_mutex_lock(_mutex);
+-      assert_status(status == 0, status,  "mutex_lock");
+-    }
+-    bool trylock() {
+-      verify();
+-      int status = pthread_mutex_trylock(_mutex);
+-      if (status == EBUSY) {
+-	return false;
+-      }
+-      assert_status(status == 0, status, "mutex_lock");
+-      return true;
+-    }
+-    void unlock() {
+-      verify();
+-      int status = pthread_mutex_unlock(_mutex);
+-      assert_status(status == 0, status, "mutex_unlock");
+-    }
+-    int timedwait(timespec* abstime) {
+-      verify();
+-      ++_nParked ; 
+-      int status = safe_cond_timedwait(_cond, _mutex, abstime);
+-      --_nParked ; 
+-      if (status != 0 && _nParked == 0 && WorkAroundNPTLTimedWaitHang) {
+-         // Beware: if the condvar is currupted by the NPTL bug but we have
+-         // multiple threads parked in timedwait() -- as can happen with
+-         // Monitor::wait() -- then we don't have much recourse.  
+-         // Reinitializing the condvar would likely orphan the other waiters.  
+-         pthread_cond_destroy (_cond) ; 
+-         pthread_cond_init (_cond, NULL) ; 
+-      }
+-      assert_status(status == 0 || status == EINTR || 
+-		    status == ETIME || status == ETIMEDOUT, 
+-		    status, "cond_timedwait");
+-      return status;
+-    }
+-    int timedwait(jlong millis) {
+-      timespec abst;
+-      Event::compute_abstime(&abst, millis);
+-      return timedwait(&abst);
+-    }
+-    int wait() {
+-      verify();
+-      ++_nParked ; 
+-      int status = pthread_cond_wait(_cond, _mutex);
+-      --_nParked ; 
+-      // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
+-      // Treat this the same as if the wait was interrupted
+-      if(status == ETIME) {
+-	status = EINTR;
+-      }
+-      assert_status(status == 0 || status == EINTR, status, "cond_wait");
+-      return status;
+-    }
+-    void signal() {
+-      verify();
+-      int status = pthread_cond_signal(_cond);
+-      assert_status(status == 0, status, "cond_signal");
+-    }
+-    void broadcast() {
+-      verify();
+-      int status = pthread_cond_broadcast(_cond);
+-      assert_status(status == 0, status, "cond_broadcast");
+-    }
+-
+-    // TODO-FIXME: eliminate park, unpark and reset as well as interrupt_event().
+-    // Convert from interrupt_interrupt() to Self->ParkEvent. 
+-
+-    // functions used to support monitor and interrupt
+-    // Note: park() may wake up spuriously. Use it in a loop.
+-    void park() {
+-      verify();
+-      lock();
+-      while (_count <= 0) {
+-        wait();
+-      }
+-      _count = 0;
+-      unlock();
+-    }
+-
+-    int park(jlong millis) {
+-      verify();
+-      int ret = OS_TIMEOUT;
+-      lock();
+-      if (_count <= 0) {
+-        timedwait(millis);
+-      }
+-      if (_count > 0) {
+-        _count = 0;
+-        ret = OS_OK;
+-      }
+-      unlock();
+-      return ret;
+-    }
+-
+-    void unpark() {
+-      verify();
+-      lock();
+-      int AnyWaiters = _nParked - _count ; 
+-      _count = 1;
+-      // Refer to the comments in os_solaris.hpp
+-      // Try to avoid the call to signal(), and, if possible, 
+-      // call signal() after dropping the lock.  
+-      if (AnyWaiters > 0) { 
+-         if (Immortal && WorkAroundNPTLTimedWaitHang == 0) { 
+-            unlock(); signal(); 
+-         } else { 
+-            signal(); unlock();
+-         }
+-      } else { 
+-         unlock(); 
+-      }
+-    }
+-
+-    void reset() {
+-     verify();
+-     assert (_nParked == 0, "invariant") ; 
+-     _count = 0;
+-    }
+-
+-    // utility to compute the abstime argument to timedwait:
+-    static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
+-      // millis is the relative timeout time
+-      // abstime will be the absolute timeout time
+-      if (millis < 0)  millis = 0;
+-      struct timeval now;
+-      int status = gettimeofday(&now, NULL);
+-      assert(status == 0, "gettimeofday");
+-      jlong seconds = millis / 1000;
+-      millis %= 1000;
+-      if (seconds > 50000000) { // see man cond_timedwait(3T)
+-        seconds = 50000000;
+-      }
+-      abstime->tv_sec = now.tv_sec  + seconds;
+-      long       usec = now.tv_usec + millis * 1000;
+-      if (usec >= 1000000) {
+-        abstime->tv_sec += 1;
+-        usec -= 1000000;
+-      }
+-      abstime->tv_nsec = usec * 1000;
+-      return abstime;
+-    }
+-  };
+-
+-  // An OSMutex is an abstraction used in the implementation of
+-  // ObjectMonitor; needed to abstract over the different thread
+-  // libraries' mutexes on Solaris.
+-  class OSMutex : public CHeapObj {
+-   private:
+-    #ifndef PRODUCT
+-    debug_only(volatile pthread_t _owner;)
+-    debug_only(volatile bool      _is_owned;)
+-    #endif
+-    pthread_mutex_t _mutex[1];
+-
+-   public:
+-    OSMutex() {
+-      verify();
+-      int status = pthread_mutex_init(_mutex, NULL);
+-      assert_status(status == 0, status, "pthread_mutex_init");
+-      #ifndef PRODUCT
+-      debug_only(_is_owned = false;)
+-      #endif
+-    }
+-    ~OSMutex() {
+-      int status = pthread_mutex_destroy(_mutex);
+-      assert_status(status == 0, status, "pthread_mutex_destroy");
+-    }
+-    // for use in critical sections:
+-    void lock() {
+-      verify();
+-      int status = pthread_mutex_lock(_mutex);
+-      assert_status(status == 0, status, "pthread_mutex_lock");
+-      #ifndef PRODUCT
+-      assert(_is_owned == false, "mutex_lock should not have had owner");
+-      debug_only(_owner = pthread_self();)
+-      debug_only(_is_owned = true;)
+-      #endif
+-    }
+-    bool trylock() {
+-      verify();
+-      int status = pthread_mutex_trylock(_mutex);
+-      if (status == EBUSY)
+-	return false;
+-      assert_status(status == 0, status, "pthread_mutex_trylock");
+-      #ifndef PRODUCT
+-      debug_only(_owner = pthread_self();)
+-      debug_only(_is_owned = true;)
+-      #endif
+-      return true;
+-    }
+-    void unlock() {
+-      verify();
+-      #ifndef PRODUCT
+-      debug_only(pthread_t my_id = pthread_self();)
+-      assert(pthread_equal(_owner, my_id), "mutex_unlock");
+-      debug_only(_is_owned = false;)
+-      #endif
+-      int status = pthread_mutex_unlock(_mutex);
+-      assert_status(status == 0, status, "pthread_mutex_unlock");
+-    }
+-
+-    // hook to check for mutex corruption:
+-    void verify() PRODUCT_RETURN;
+-    void verify_locked() PRODUCT_RETURN;
+-  };
+ 
+   // Linux suspend/resume support - this helper is a shadow of its former
+   // self now that low-level suspension is barely used, and old workarounds
+@@ -511,6 +262,7 @@
+     int  fired() { return _Event; } 
+     void park () ; 
+     void unpark () ;
++    int  TryPark () ;
+     int  park (jlong millis) ;
+     void SetAssociation (Thread * a) { _Assoc = a ; } 
+ } ;
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/os_linux.inline.hpp openjdk/hotspot/src/os/linux/vm/os_linux.inline.hpp
+--- openjdk6/hotspot/src/os/linux/vm/os_linux.inline.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/os_linux.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)os_linux.inline.hpp	1.30 07/05/05 17:04:36 JVM"
+-#endif
+ /*
+  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/os_share_linux.hpp openjdk/hotspot/src/os/linux/vm/os_share_linux.hpp
+--- openjdk6/hotspot/src/os/linux/vm/os_share_linux.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/os_share_linux.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)os_share_linux.hpp	1.11 07/05/05 17:04:36 JVM"
+-#endif
+ /*
+  * Copyright 1999-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/osThread_linux.cpp openjdk/hotspot/src/os/linux/vm/osThread_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/osThread_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/osThread_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)osThread_linux.cpp	1.24 07/05/05 17:04:36 JVM"
+-#endif
+ /*
+  * Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -29,17 +26,6 @@
+ # include "incls/_osThread_linux.cpp.incl"
+ 
+ 
+-// Events associated with threads via "interrupt_event" must
+-// reside in a TSM (type-stable memory) pool.  
+-// The relationship between the interrupt_event and a thread
+-// must be stable for the lifetime of the thread.  
+-//
+-// A slightly better implementation would be to subclass Event
+-// with a "TSMEvent" that added the FreeNext field.  
+- 
+-static os::Linux::Event * EventFreeList = NULL ;     
+-static pthread_mutex_t EventFreeLock = PTHREAD_MUTEX_INITIALIZER ;
+- 
+ void OSThread::pd_initialize() {
+   assert(this != NULL, "check");
+   _thread_id        = 0;
+@@ -51,37 +37,10 @@
+ 
+   sigemptyset(&_caller_sigmask);
+ 
+-  // Try to allocate an Event from the TSM list, otherwise
+-  // instantiate a new Event.
+-  pthread_mutex_lock (&EventFreeLock) ;
+-  os::Linux::Event * ie = EventFreeList ;
+-  if (ie != NULL) {
+-     guarantee (ie->Immortal, "invariant") ;
+-     EventFreeList = ie->FreeNext ;
+-  }
+-  pthread_mutex_unlock (&EventFreeLock) ;
+-  if (ie == NULL) {
+-     ie = new os::Linux::Event();
+-  } else { 
+-     ie->reset () ;
+-  }
+-  ie->FreeNext = (os::Linux::Event *) 0xBAD ;
+-  ie->Immortal = 1 ;
+-  _interrupt_event = ie ;
+-
+   _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true);
+   assert(_startThread_lock !=NULL, "check");
+ }
+ 
+ void OSThread::pd_destroy() {
+-  os::Linux::Event * ie = _interrupt_event ;
+-  _interrupt_event = NULL ;
+-  guarantee (ie != NULL, "invariant") ;
+-  guarantee (ie->Immortal, "invariant") ;
+-  pthread_mutex_lock (&EventFreeLock) ;
+-  ie->FreeNext = EventFreeList ;
+-  EventFreeList = ie ;
+-  pthread_mutex_unlock (&EventFreeLock) ;
+-
+   delete _startThread_lock;
+ }
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/osThread_linux.hpp openjdk/hotspot/src/os/linux/vm/osThread_linux.hpp
+--- openjdk6/hotspot/src/os/linux/vm/osThread_linux.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/osThread_linux.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)osThread_linux.hpp	1.37 07/05/05 17:04:36 JVM"
+-#endif
+ /*
+  * Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -121,25 +118,11 @@
+   void set_alt_sig_stack(address val)     { _alt_sig_stack = val; }
+   address alt_sig_stack(void)             { return _alt_sig_stack; }
+ 
+-  // ***************************************************************
+-  // The interrupt_event is used to implement java.lang.Thread.interrupt,
+-  // which on Linux can interrupt sleep and ObjectMonitor::wait().
+-  // ***************************************************************
+-
+ private:
+-
+-  os::Linux::Event* _interrupt_event;
+   Monitor* _startThread_lock;     // sync parent and child in thread creation
+ 
+ public:
+ 
+-  os::Linux::Event* interrupt_event() const {
+-    return _interrupt_event;
+-  }
+-  void set_interrupt_event(os::Linux::Event* ptr) {
+-    _interrupt_event = ptr;
+-  }
+-
+   Monitor* startThread_lock() const {
+     return _startThread_lock;
+   }
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/perfMemory_linux.cpp openjdk/hotspot/src/os/linux/vm/perfMemory_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/perfMemory_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/perfMemory_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)perfMemory_linux.cpp	1.30 07/05/05 17:04:35 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -942,7 +939,7 @@
+   // to the specified file name no matter whether PerfDataSaveToFile is specified
+   // or not. In other word, -XX:PerfDataSaveFile=.. overrides flag 
+   // -XX:+PerfDataSaveToFile.
+-  if (PerfDataSaveToFile || PerfDataSaveFile[0] != '\0') {
++  if (PerfDataSaveToFile || PerfDataSaveFile != NULL) {
+     save_memory_to_file(start(), capacity());
+   }
+ 
+@@ -1012,4 +1009,3 @@
+ char* PerfMemory::backing_store_filename() {
+   return backing_store_file_name;
+ }
+-
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/stubRoutines_linux.cpp openjdk/hotspot/src/os/linux/vm/stubRoutines_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/stubRoutines_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/stubRoutines_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)stubRoutines_linux.cpp	1.10 07/05/05 17:04:36 JVM"
+-#endif
+ /*
+  * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/threadCritical_linux.cpp openjdk/hotspot/src/os/linux/vm/threadCritical_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/threadCritical_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/threadCritical_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)threadCritical_linux.cpp	1.16 07/05/05 17:04:37 JVM"
+-#endif
+ /*
+  * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -67,4 +64,3 @@
+     guarantee(ret == 0, "fatal error with pthread_mutex_unlock()");
+   }
+ }
+-
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/thread_linux.inline.hpp openjdk/hotspot/src/os/linux/vm/thread_linux.inline.hpp
+--- openjdk6/hotspot/src/os/linux/vm/thread_linux.inline.hpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/thread_linux.inline.hpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_HDR
+-#pragma ident "@(#)thread_linux.inline.hpp	1.10 07/05/05 17:04:37 JVM"
+-#endif
+ /*
+  * Copyright 2002-2003 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/vmError_linux.cpp openjdk/hotspot/src/os/linux/vm/vmError_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/vmError_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/vmError_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vmError_linux.cpp	1.14 08/06/17 09:14:15 JVM"
+-#endif
+ /*
+  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -34,84 +31,6 @@
+ #include <unistd.h>
+ #include <signal.h>
+ 
+-extern char** environ;
+-
+-#ifndef __NR_fork
+-#define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57)
+-#endif
+-
+-#ifndef __NR_execve
+-#define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59)
+-#endif
+-
+-// Run the specified command in a separate process. Return its exit value,
+-// or -1 on failure (e.g. can't fork a new process).
+-// Unlike system(), this function can be called from signal handler. It
+-// doesn't block SIGINT et al.
+-int VMError::fork_and_exec(char* cmd) {
+-  const char * argv[4] = {"sh", "-c", cmd, NULL};
+-
+-  // fork() in LinuxThreads/NPTL is not async-safe. It needs to run 
+-  // pthread_atfork handlers and reset pthread library. All we need is a 
+-  // separate process to execve. Make a direct syscall to fork process.
+-  // On IA64 there's no fork syscall, we have to use fork() and hope for
+-  // the best...
+-  pid_t pid = NOT_IA64(syscall(__NR_fork);) 
+-              IA64_ONLY(fork();)
+-
+-  if (pid < 0) {
+-    // fork failed
+-    return -1;
+-
+-  } else if (pid == 0) {
+-    // child process
+-
+-    // execve() in LinuxThreads will call pthread_kill_other_threads_np() 
+-    // first to kill every thread on the thread list. Because this list is 
+-    // not reset by fork() (see notes above), execve() will instead kill 
+-    // every thread in the parent process. We know this is the only thread 
+-    // in the new process, so make a system call directly.
+-    // IA64 should use normal execve() from glibc to match the glibc fork() 
+-    // above.
+-    NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
+-    IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
+-
+-    // execve failed
+-    _exit(-1);
+-
+-  } else  {
+-    // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
+-    // care about the actual exit code, for now.
+-   
+-    int status;
+-
+-    // Wait for the child process to exit.  This returns immediately if
+-    // the child has already exited. */
+-    while (waitpid(pid, &status, 0) < 0) {
+-        switch (errno) {
+-        case ECHILD: return 0;
+-        case EINTR: break;
+-        default: return -1;
+-        }
+-    }
+-
+-    if (WIFEXITED(status)) {
+-       // The child exited normally; get its exit code.
+-       return WEXITSTATUS(status);
+-    } else if (WIFSIGNALED(status)) {
+-       // The child exited because of a signal
+-       // The best value to return is 0x80 + signal number,
+-       // because that is what all Unix shells do, and because
+-       // it allows callers to distinguish between process exit and
+-       // process death by signal.
+-       return 0x80 + WTERMSIG(status);
+-    } else {
+-       // Unknown exit code; pass it through
+-       return status;
+-    }
+-  }
+-}
+-
+ void VMError::show_message_box(char *buf, int buflen) {
+   bool yes;
+   do {
+@@ -135,7 +54,8 @@
+       jio_snprintf(buf, buflen, "gdb /proc/%d/exe %d", 
+                    os::current_process_id(), os::current_process_id());
+ 
+-      fork_and_exec(buf);
++      os::fork_and_exec(buf);
++      yes = false;
+     }
+   } while (yes);
+ }
+diff -ruNb openjdk6/hotspot/src/os/linux/vm/vtune_linux.cpp openjdk/hotspot/src/os/linux/vm/vtune_linux.cpp
+--- openjdk6/hotspot/src/os/linux/vm/vtune_linux.cpp	2008-08-28 10:23:05.000000000 +0200
++++ openjdk/hotspot/src/os/linux/vm/vtune_linux.cpp	2007-12-14 08:57:02.000000000 +0100
+@@ -1,6 +1,3 @@
+-#ifdef USE_PRAGMA_IDENT_SRC
+-#pragma ident "@(#)vtune_linux.cpp	1.12 07/05/05 17:04:35 JVM"
+-#endif
+ /*
+  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.