changeset 4599:0b55a78c6be5

Merge
author bharadwaj
date Fri, 26 Apr 2013 10:52:26 -0700
parents 57ac6a688ae6 a5c95fcf7cb7
children fd49109d0d88
files agent/doc/c2replay.html src/os/windows/vm/os_windows.cpp src/share/vm/runtime/vmStructs.cpp
diffstat 28 files changed, 794 insertions(+), 144 deletions(-) [+]
line wrap: on
line diff
--- a/agent/doc/c2replay.html	Fri Apr 26 00:40:22 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-<html>
-<head>
-<title>
-C2 Replay
-</title>
-</head>
-<body>
-
-<h1>C2 compiler replay</h1>
-<p>
-The C2 compiler replay is a function to repeat the compiling process from a crashed java process in compiled method<br>
-This function only exists in debug version of VM
-</p>
-<h2>Usage</h2>
-<pre> 
-First, use SA to attach to the core file, if suceeded, do
-       clhsdb>dumpreplaydata <address> | -a | <thread_id> [> replay.txt]
-       create file replay.txt, address is address of Method, or nmethod(CodeBlob)
-       clhsdb>buildreplayjars [all | boot | app]
-       create files:
-         all:
-           app.jar, boot.jar
-         boot:
-           boot.jar
-         app:
-           app.jar
-       exit SA now.
-Second, use the obtained replay text file, replay.txt and jar files, app.jar and boot.jar, using debug version of java
-       java -Xbootclasspath/p:boot.jar -cp app.jar -XX:ReplayDataFile=<datafile> -XX:+ReplayCompiles ....
-       This will replay the compiling process.
-
-       With ReplayCompiles, the replay will recompile all the methods in app.jar, and in boot.jar to emulate the process in java app.
-
-notes:
-       1) Most time, we don't need the boot.jar which is the classes loaded from JDK. It will be only modified when an agent(JVMDI) is running and modifies the classes.
-       2) If encounter error as "<flag>" not found, that means the SA is using a VMStructs which is different from the one with corefile. In this case, SA has a utility tool vmstructsdump which is located at agent/src/os/<os>/proc/<os_platform>
-
-       Use this tool to dump VM type library:
-       vmstructsdump libjvm.so > <type_name>.db
-
-       set env SA_TYPEDB=<type_name>.db (refer different shell for set envs)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/doc/cireplay.html	Fri Apr 26 10:52:26 2013 -0700
@@ -0,0 +1,41 @@
+<html>
+<head>
+<title>
+Replay
+</title>
+</head>
+<body>
+
+<h1>Compiler replay</h1>
+<p>
+The compiler replay is a function to repeat the compiling process from a crashed java process in compiled method<br>
+This function only exists in debug version of VM
+</p>
+<h2>Usage</h2>
+<pre>
+First, use SA to attach to the core file, if succeeded, do
+       hsdb&gt; dumpreplaydata &lt;address&gt; | -a | &lt;thread_id&gt; [&gt; replay.txt]
+       create file replay.txt, address is address of Method, or nmethod(CodeBlob)
+       hsdb&gt; buildreplayjars [all | boot | app]
+       create files:
+         all:
+           app.jar, boot.jar
+         boot:
+           boot.jar
+         app:
+           app.jar
+       exit SA now.
+Second, use the obtained replay text file, replay.txt and jar files, app.jar and boot.jar, using debug version of java
+       java -Xbootclasspath/p:boot.jar -cp app.jar -XX:ReplayDataFile=&lt;datafile&gt; -XX:+ReplayCompiles ....
+       This will replay the compiling process.
+
+       With ReplayCompiles, the replay will recompile all the methods in app.jar, and in boot.jar to emulate the process in java app.
+
+notes:
+       1) Most time, we don't need the boot.jar which is the classes loaded from JDK. It will be only modified when an agent(JVMDI) is running and modifies the classes.
+       2) If encounter error as "&lt;flag&gt;" not found, that means the SA is using a VMStructs which is different from the one with corefile. In this case, SA has a utility tool vmstructsdump which is located at agent/src/os/&lt;os&gt;/proc/&lt;os_platform&gt;
+
+       Use this tool to dump VM type library:
+       vmstructsdump libjvm.so &gt; &lt;type_name&gt;.db
+
+       set env SA_TYPEDB=&lt;type_name&gt;.db (refer different shell for set envs)
--- a/agent/doc/clhsdb.html	Fri Apr 26 00:40:22 2013 -0700
+++ b/agent/doc/clhsdb.html	Fri Apr 26 10:52:26 2013 -0700
@@ -15,7 +15,7 @@
 <p>
 There is also JavaScript based SA command line interface called <a href="jsdb.html">jsdb</a>.
 But, CLHSDB supports Unix shell-like (or dbx/gdb-like) command line interface with
-support for output redirection/appending (familiar >, >>), command history and so on.
+support for output redirection/appending (familiar &gt;, &gt;&gt;), command history and so on.
 Each CLHSDB command can have zero or more arguments and optionally end with output redirection
 (or append) to a file. Commands may be stored in a file and run using <b>source</b> command.
 <b>help</b> command prints usage message for all supported commands (or a specific command)
@@ -49,7 +49,7 @@
   dumpheap [ file ] <font color="red">dump heap in hprof binary format</font>
   dumpideal -a | id <font color="red">dump ideal graph like debug flag -XX:+PrintIdeal</font>
   dumpilt -a | id <font color="red">dump inline tree for C2 compilation</font>
-  dumpreplaydata <address> | -a | <thread_id> [>replay.txt] <font color="red">dump replay data into a file</font>
+  dumpreplaydata &lt;address&gt; | -a | &lt;thread_id&gt; [&gt;replay.txt] <font color="red">dump replay data into a file</font>
   echo [ true | false ] <font color="red">turn on/off command echo mode</font>
   examine [ address/count ] | [ address,address] <font color="red">show contents of memory from given address</font>
   field [ type [ name fieldtype isStatic offset address ] ] <font color="red">print info about a field of HotSpot type</font>
@@ -96,11 +96,11 @@
 
 <h3>JavaScript integration</h3>
 
-<p>Few CLHSDB commands are already implemented in JavaScript. It is possible to extend CLHSDB command set 
+<p>Few CLHSDB commands are already implemented in JavaScript. It is possible to extend CLHSDB command set
 by implementing more commands in a JavaScript file and by loading it by <b>jsload</b> command. <b>jseval</b>
 command may be used to evaluate arbitrary JavaScript expression from a string. Any JavaScript function
 may be exposed as a CLHSDB command by registering it using JavaScript <b><code>registerCommand</code></b>
-function. This function accepts command name, usage and name of the JavaScript implementation function 
+function. This function accepts command name, usage and name of the JavaScript implementation function
 as arguments.
 </p>
 
@@ -127,11 +127,11 @@
 </code>
 </pre>
 
-<h3>C2 Compilation Replay</h3>
+<h3>Compilation Replay</h3>
 <p>
 When a java process crashes in compiled method, usually a core file is saved.
-The C2 replay function can reproduce the compiling process in the core.
-<a href="c2replay.html">c2replay.html</a>
+The replay function can reproduce the compiling process in the core.
+<a href="cireplay.html">cireplay.html</a>
 
 </body>
 </html>
--- a/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java	Fri Apr 26 00:40:22 2013 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java	Fri Apr 26 10:52:26 2013 -0700
@@ -93,10 +93,11 @@
     CompileTask task = task();
     Method method = task.method();
     int entryBci = task.osrBci();
+    int compLevel = task.compLevel();
     Klass holder = method.getMethodHolder();
     out.println("compile " + holder.getName().asString() + " " +
                 OopUtilities.escapeString(method.getName().asString()) + " " +
                 method.getSignature().asString() + " " +
-                entryBci);
+                entryBci + " " + compLevel);
   }
 }
--- a/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Fri Apr 26 00:40:22 2013 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Fri Apr 26 10:52:26 2013 -0700
@@ -78,6 +78,8 @@
       current sweep traversal index. */
   private static CIntegerField stackTraversalMarkField;
 
+  private static CIntegerField compLevelField;
+
   static {
     VM.registerVMInitializedObserver(new Observer() {
         public void update(Observable o, Object data) {
@@ -113,7 +115,7 @@
     osrEntryPointField          = type.getAddressField("_osr_entry_point");
     lockCountField              = type.getJIntField("_lock_count");
     stackTraversalMarkField     = type.getCIntegerField("_stack_traversal_mark");
-
+    compLevelField              = type.getCIntegerField("_comp_level");
     pcDescSize = db.lookupType("PcDesc").getSize();
   }
 
@@ -530,7 +532,7 @@
     out.println("compile " + holder.getName().asString() + " " +
                 OopUtilities.escapeString(method.getName().asString()) + " " +
                 method.getSignature().asString() + " " +
-                getEntryBCI());
+                getEntryBCI() + " " + getCompLevel());
 
   }
 
@@ -551,4 +553,5 @@
   private int getHandlerTableOffset() { return (int) handlerTableOffsetField.getValue(addr); }
   private int getNulChkTableOffset()  { return (int) nulChkTableOffsetField .getValue(addr); }
   private int getNMethodEndOffset()   { return (int) nmethodEndOffsetField  .getValue(addr); }
+  private int getCompLevel()          { return (int) compLevelField         .getValue(addr); }
 }
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/CompileTask.java	Fri Apr 26 00:40:22 2013 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/CompileTask.java	Fri Apr 26 10:52:26 2013 -0700
@@ -46,10 +46,12 @@
     Type type      = db.lookupType("CompileTask");
     methodField = type.getAddressField("_method");
     osrBciField = new CIntField(type.getCIntegerField("_osr_bci"), 0);
+    compLevelField = new CIntField(type.getCIntegerField("_comp_level"), 0);
   }
 
   private static AddressField methodField;
   private static CIntField osrBciField;
+  private static CIntField compLevelField;
 
   public CompileTask(Address addr) {
     super(addr);
@@ -63,4 +65,8 @@
   public int osrBci() {
     return (int)osrBciField.getValue(getAddress());
   }
+
+  public int compLevel() {
+      return (int)compLevelField.getValue(getAddress());
+  }
 }
--- a/src/os/bsd/vm/os_bsd.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/os/bsd/vm/os_bsd.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -1230,10 +1230,6 @@
   return retval;
 }
 
-const char* os::get_current_directory(char *buf, int buflen) {
-  return getcwd(buf, buflen);
-}
-
 // check if addr is inside libjvm.so
 bool os::address_is_in_vm(address addr) {
   static address libjvm_base_addr;
--- a/src/os/linux/vm/os_linux.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/os/linux/vm/os_linux.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -1662,10 +1662,6 @@
   return retval;
 }
 
-const char* os::get_current_directory(char *buf, int buflen) {
-  return getcwd(buf, buflen);
-}
-
 // check if addr is inside libjvm.so
 bool os::address_is_in_vm(address addr) {
   static address libjvm_base_addr;
--- a/src/os/posix/vm/os_posix.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/os/posix/vm/os_posix.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -251,3 +251,11 @@
   return true;
 #endif
 }
+
+const char* os::get_current_directory(char *buf, size_t buflen) {
+  return getcwd(buf, buflen);
+}
+
+FILE* os::open(int fd, const char* mode) {
+  return ::fdopen(fd, mode);
+}
--- a/src/os/solaris/vm/os_solaris.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/os/solaris/vm/os_solaris.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -1915,10 +1915,6 @@
   return retval;
 }
 
-const char* os::get_current_directory(char *buf, int buflen) {
-  return getcwd(buf, buflen);
-}
-
 // check if addr is inside libjvm.so
 bool os::address_is_in_vm(address addr) {
   static address libjvm_base_addr;
--- a/src/os/windows/vm/os_windows.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/os/windows/vm/os_windows.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -1221,8 +1221,10 @@
 
 // Needs to be in os specific directory because windows requires another
 // header file <direct.h>
-const char* os::get_current_directory(char *buf, int buflen) {
-  return _getcwd(buf, buflen);
+const char* os::get_current_directory(char *buf, size_t buflen) {
+  int n = static_cast<int>(buflen);
+  if (buflen > INT_MAX)  n = INT_MAX;
+  return _getcwd(buf, n);
 }
 
 //-----------------------------------------------------------
@@ -4098,6 +4100,10 @@
   return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode);
 }
 
+FILE* os::open(int fd, const char* mode) {
+  return ::_fdopen(fd, mode);
+}
+
 // Is a (classpath) directory empty?
 bool os::dir_is_empty(const char* path) {
   WIN32_FIND_DATA fd;
--- a/src/share/vm/ci/ciEnv.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/ci/ciEnv.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -1149,23 +1149,9 @@
   record_method_not_compilable("out of memory");
 }
 
-fileStream* ciEnv::_replay_data_stream = NULL;
-
-void ciEnv::dump_replay_data() {
+void ciEnv::dump_replay_data(outputStream* out) {
   VM_ENTRY_MARK;
   MutexLocker ml(Compile_lock);
-  if (_replay_data_stream == NULL) {
-    _replay_data_stream = new (ResourceObj::C_HEAP, mtCompiler) fileStream(ReplayDataFile);
-    if (_replay_data_stream == NULL) {
-      fatal(err_msg("Can't open %s for replay data", ReplayDataFile));
-    }
-  }
-  dump_replay_data(_replay_data_stream);
-}
-
-
-void ciEnv::dump_replay_data(outputStream* out) {
-  ASSERT_IN_VM;
   ResourceMark rm;
 #if INCLUDE_JVMTI
   out->print_cr("JvmtiExport can_access_local_variables %d",     _jvmti_can_access_local_variables);
@@ -1178,13 +1164,15 @@
   for (int i = 0; i < objects->length(); i++) {
     objects->at(i)->dump_replay_data(out);
   }
-  Method* method = task()->method();
-  int entry_bci = task()->osr_bci();
+  CompileTask* task = this->task();
+  Method* method = task->method();
+  int entry_bci = task->osr_bci();
+  int comp_level = task->comp_level();
   // Klass holder = method->method_holder();
-  out->print_cr("compile %s %s %s %d",
+  out->print_cr("compile %s %s %s %d %d",
                 method->klass_name()->as_quoted_ascii(),
                 method->name()->as_quoted_ascii(),
                 method->signature()->as_quoted_ascii(),
-                entry_bci);
+                entry_bci, comp_level);
   out->flush();
 }
--- a/src/share/vm/ci/ciEnv.hpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/ci/ciEnv.hpp	Fri Apr 26 10:52:26 2013 -0700
@@ -46,8 +46,6 @@
   friend class CompileBroker;
   friend class Dependencies;  // for get_object, during logging
 
-  static fileStream* _replay_data_stream;
-
 private:
   Arena*           _arena;       // Alias for _ciEnv_arena except in init_shared_objects()
   Arena            _ciEnv_arena;
@@ -451,10 +449,6 @@
   // RedefineClasses support
   void metadata_do(void f(Metadata*)) { _factory->metadata_do(f); }
 
-  // Dump the compilation replay data for this ciEnv to
-  // ReplayDataFile, creating the file if needed.
-  void  dump_replay_data();
-
   // Dump the compilation replay data for the ciEnv to the stream.
   void dump_replay_data(outputStream* out);
 };
--- a/src/share/vm/ci/ciMethod.hpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/ci/ciMethod.hpp	Fri Apr 26 10:52:26 2013 -0700
@@ -196,7 +196,6 @@
   // Analysis and profiling.
   //
   // Usage note: liveness_at_bci and init_vars should be wrapped in ResourceMarks.
-  bool          uses_monitors() const            { return _uses_monitors; } // this one should go away, it has a misleading name
   bool          has_monitor_bytecodes() const    { return _uses_monitors; }
   bool          has_balanced_monitors();
 
--- a/src/share/vm/ci/ciReplay.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/ci/ciReplay.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -89,7 +89,7 @@
     loader = Handle(thread, SystemDictionary::java_system_loader());
     stream = fopen(filename, "rt");
     if (stream == NULL) {
-      fprintf(stderr, "Can't open replay file %s\n", filename);
+      fprintf(stderr, "ERROR: Can't open replay file %s\n", filename);
     }
     buffer_length = 32;
     buffer = NEW_RESOURCE_ARRAY(char, buffer_length);
@@ -327,7 +327,6 @@
         if (had_error()) {
           tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
           tty->print_cr("%s", buffer);
-          assert(false, "error");
           return;
         }
         pos = 0;
@@ -370,11 +369,47 @@
     }
   }
 
-  // compile <klass> <name> <signature> <entry_bci>
+  // validation of comp_level
+  bool is_valid_comp_level(int comp_level) {
+    const int msg_len = 256;
+    char* msg = NULL;
+    if (!is_compile(comp_level)) {
+      msg = NEW_RESOURCE_ARRAY(char, msg_len);
+      jio_snprintf(msg, msg_len, "%d isn't compilation level", comp_level);
+    } else if (!TieredCompilation && (comp_level != CompLevel_highest_tier)) {
+      msg = NEW_RESOURCE_ARRAY(char, msg_len);
+      switch (comp_level) {
+        case CompLevel_simple:
+          jio_snprintf(msg, msg_len, "compilation level %d requires Client VM or TieredCompilation", comp_level);
+          break;
+        case CompLevel_full_optimization:
+          jio_snprintf(msg, msg_len, "compilation level %d requires Server VM", comp_level);
+          break;
+        default:
+          jio_snprintf(msg, msg_len, "compilation level %d requires TieredCompilation", comp_level);
+      }
+    }
+    if (msg != NULL) {
+      report_error(msg);
+      return false;
+    }
+    return true;
+  }
+
+  // compile <klass> <name> <signature> <entry_bci> <comp_level>
   void process_compile(TRAPS) {
     // methodHandle method;
     Method* method = parse_method(CHECK);
     int entry_bci = parse_int("entry_bci");
+    const char* comp_level_label = "comp_level";
+    int comp_level = parse_int(comp_level_label);
+    // old version w/o comp_level
+    if (had_error() && (error_message() == comp_level_label)) {
+      comp_level = CompLevel_full_optimization;
+    }
+    if (!is_valid_comp_level(comp_level)) {
+      return;
+    }
     Klass* k = method->method_holder();
     ((InstanceKlass*)k)->initialize(THREAD);
     if (HAS_PENDING_EXCEPTION) {
@@ -389,12 +424,12 @@
       }
     }
     // Make sure the existence of a prior compile doesn't stop this one
-    nmethod* nm = (entry_bci != InvocationEntryBci) ? method->lookup_osr_nmethod_for(entry_bci, CompLevel_full_optimization, true) : method->code();
+    nmethod* nm = (entry_bci != InvocationEntryBci) ? method->lookup_osr_nmethod_for(entry_bci, comp_level, true) : method->code();
     if (nm != NULL) {
       nm->make_not_entrant();
     }
     replay_state = this;
-    CompileBroker::compile_method(method, entry_bci, CompLevel_full_optimization,
+    CompileBroker::compile_method(method, entry_bci, comp_level,
                                   methodHandle(), 0, "replay", THREAD);
     replay_state = NULL;
     reset();
@@ -551,7 +586,7 @@
           if (parsed_two_word == i) continue;
 
         default:
-          ShouldNotReachHere();
+          fatal(err_msg_res("Unexpected tag: %d", cp->tag_at(i).value()));
           break;
       }
 
@@ -819,6 +854,11 @@
     ReplaySuppressInitializers = 1;
   }
 
+  if (FLAG_IS_DEFAULT(ReplayDataFile)) {
+    tty->print_cr("ERROR: no compiler replay data file specified (use -XX:ReplayDataFile=replay_pid12345.txt).");
+    return 1;
+  }
+
   // Load and parse the replay data
   CompileReplay rp(ReplayDataFile, THREAD);
   int exit_code = 0;
--- a/src/share/vm/compiler/compileBroker.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/compiler/compileBroker.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -1842,6 +1842,8 @@
         }
       }
     }
+    // simulate crash during compilation
+    assert(task->compile_id() != CICrashAt, "just as planned");
   }
   pop_jni_handle_block();
 
--- a/src/share/vm/prims/whitebox.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/prims/whitebox.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -436,9 +436,29 @@
       instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass());
       Handle loader(ikh->class_loader());
       if (loader.is_null()) {
+        ResourceMark rm;
         ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
-        jint result = env->RegisterNatives(wbclass, methods, sizeof(methods)/sizeof(methods[0]));
-        if (result == 0) {
+        bool result = true;
+        //  one by one registration natives for exception catching
+        jclass exceptionKlass = env->FindClass(vmSymbols::java_lang_NoSuchMethodError()->as_C_string());
+        for (int i = 0, n = sizeof(methods) / sizeof(methods[0]); i < n; ++i) {
+          if (env->RegisterNatives(wbclass, methods + i, 1) != 0) {
+            result = false;
+            if (env->ExceptionCheck() && env->IsInstanceOf(env->ExceptionOccurred(), exceptionKlass)) {
+              // j.l.NoSuchMethodError is thrown when a method can't be found or a method is not native
+              // ignoring the exception
+              tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s", methods[i].name, methods[i].signature);
+              env->ExceptionClear();
+            } else {
+              // register is failed w/o exception or w/ unexpected exception
+              tty->print_cr("Warning: unexpected error on register of sun.hotspot.WhiteBox::%s%s. All methods will be unregistered", methods[i].name, methods[i].signature);
+              env->UnregisterNatives(wbclass);
+              break;
+            }
+          }
+        }
+
+        if (result) {
           WhiteBox::set_used();
         }
       }
--- a/src/share/vm/runtime/globals.hpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/runtime/globals.hpp	Fri Apr 26 10:52:26 2013 -0700
@@ -3223,8 +3223,9 @@
   develop(bool, ReplayCompiles, false,                                      \
           "Enable replay of compilations from ReplayDataFile")              \
                                                                             \
-  develop(ccstr, ReplayDataFile, "replay.txt",                              \
-          "file containing compilation replay information")                 \
+  product(ccstr, ReplayDataFile, NULL,                                      \
+          "File containing compilation replay information"                  \
+          "[default: ./replay_pid%p.log] (%p replaced with pid)")           \
                                                                             \
   develop(intx, ReplaySuppressInitializers, 2,                              \
           "Controls handling of class initialization during replay"         \
@@ -3237,8 +3238,8 @@
   develop(bool, ReplayIgnoreInitErrors, false,                              \
           "Ignore exceptions thrown during initialization for replay")      \
                                                                             \
-  develop(bool, DumpReplayDataOnError, true,                                \
-          "record replay data for crashing compiler threads")               \
+  product(bool, DumpReplayDataOnError, true,                                \
+          "Record replay data for crashing compiler threads")               \
                                                                             \
   product(bool, CICompilerCountPerCPU, false,                               \
           "1 compiler thread for log(N CPUs)")                              \
@@ -3247,7 +3248,9 @@
           "Fire OutOfMemoryErrors throughout CI for testing the compiler "  \
           "(non-negative value throws OOM after this many CI accesses "     \
           "in each compile)")                                               \
-                                                                            \
+  notproduct(intx, CICrashAt, -1,                                           \
+          "id of compilation to trigger assert in compiler thread for "     \
+          "the purpose of testing, e.g. generation of replay data")         \
   notproduct(bool, CIObjectFactoryVerify, false,                            \
           "enable potentially expensive verification in ciObjectFactory")   \
                                                                             \
--- a/src/share/vm/runtime/os.hpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/runtime/os.hpp	Fri Apr 26 10:52:26 2013 -0700
@@ -454,6 +454,7 @@
   // File i/o operations
   static const int default_file_open_flags();
   static int open(const char *path, int oflag, int mode);
+  static FILE* open(int fd, const char* mode);
   static int close(int fd);
   static jlong lseek(int fd, jlong offset, int whence);
   static char* native_path(char *path);
@@ -477,7 +478,7 @@
   static const char*    dll_file_extension();
 
   static const char*    get_temp_directory();
-  static const char*    get_current_directory(char *buf, int buflen);
+  static const char*    get_current_directory(char *buf, size_t buflen);
 
   // Builds a platform-specific full library path given a ld path and lib name
   // Returns true if buffer contains full path to existing file, false otherwise
--- a/src/share/vm/runtime/sharedRuntime.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -1316,12 +1316,6 @@
   assert(stub_frame.is_runtime_frame(), "sanity check");
   frame caller_frame = stub_frame.sender(&reg_map);
 
-  // MethodHandle invokes don't have a CompiledIC and should always
-  // simply redispatch to the callee_target.
-  address   sender_pc = caller_frame.pc();
-  CodeBlob* sender_cb = caller_frame.cb();
-  nmethod*  sender_nm = sender_cb->as_nmethod_or_null();
-
   if (caller_frame.is_interpreted_frame() ||
       caller_frame.is_entry_frame()) {
     Method* callee = thread->callee_target();
--- a/src/share/vm/runtime/vmStructs.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/runtime/vmStructs.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -828,6 +828,7 @@
   nonstatic_field(nmethod,             _lock_count,                                   jint)                                  \
   nonstatic_field(nmethod,             _stack_traversal_mark,                         long)                                  \
   nonstatic_field(nmethod,             _compile_id,                                   int)                                   \
+  nonstatic_field(nmethod,             _comp_level,                                   int)                                   \
   nonstatic_field(nmethod,             _exception_cache,                              ExceptionCache*)                       \
   nonstatic_field(nmethod,             _marked_for_deoptimization,                    bool)                                  \
                                                                                                                              \
--- a/src/share/vm/utilities/ostream.hpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/utilities/ostream.hpp	Fri Apr 26 10:52:26 2013 -0700
@@ -196,7 +196,7 @@
   fileStream() { _file = NULL; _need_close = false; }
   fileStream(const char* file_name);
   fileStream(const char* file_name, const char* opentype);
-  fileStream(FILE* file) { _file = file; _need_close = false; }
+  fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; }
   ~fileStream();
   bool is_open() const { return _file != NULL; }
   void set_need_close(bool b) { _need_close = b;}
--- a/src/share/vm/utilities/vmError.cpp	Fri Apr 26 00:40:22 2013 -0700
+++ b/src/share/vm/utilities/vmError.cpp	Fri Apr 26 10:52:26 2013 -0700
@@ -796,6 +796,56 @@
 VMError* volatile VMError::first_error = NULL;
 volatile jlong VMError::first_error_tid = -1;
 
+/** Expand a pattern into a buffer starting at pos and open a file using constructed path */
+static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) {
+  int fd = -1;
+  if (Arguments::copy_expand_pid(pattern, strlen(pattern), &buf[pos], buflen - pos)) {
+    fd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  }
+  return fd;
+}
+
+/**
+ * Construct file name for a log file and return it's file descriptor.
+ * Name and location depends on pattern, default_pattern params and access
+ * permissions.
+ */
+static int prepare_log_file(const char* pattern, const char* default_pattern, char* buf, size_t buflen) {
+  int fd = -1;
+
+  // If possible, use specified pattern to construct log file name
+  if (pattern != NULL) {
+    fd = expand_and_open(pattern, buf, buflen, 0);
+  }
+
+  // Either user didn't specify, or the user's location failed,
+  // so use the default name in the current directory
+  if (fd == -1) {
+    const char* cwd = os::get_current_directory(buf, buflen);
+    if (cwd != NULL) {
+      size_t pos = strlen(cwd);
+      int fsep_len = jio_snprintf(&buf[pos], buflen-pos, "%s", os::file_separator());
+      pos += fsep_len;
+      if (fsep_len > 0) {
+        fd = expand_and_open(default_pattern, buf, buflen, pos);
+      }
+    }
+  }
+
+   // try temp directory if it exists.
+   if (fd == -1) {
+     const char* tmpdir = os::get_temp_directory();
+     if (tmpdir != NULL && strlen(tmpdir) > 0) {
+       int pos = jio_snprintf(buf, buflen, "%s%s", tmpdir, os::file_separator());
+       if (pos > 0) {
+         fd = expand_and_open(default_pattern, buf, buflen, pos);
+       }
+     }
+   }
+
+  return fd;
+}
+
 void VMError::report_and_die() {
   // Don't allocate large buffer on stack
   static char buffer[O_BUFLEN];
@@ -905,36 +955,7 @@
     // see if log file is already open
     if (!log.is_open()) {
       // open log file
-      int fd = -1;
-
-      if (ErrorFile != NULL) {
-        bool copy_ok =
-          Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer));
-        if (copy_ok) {
-          fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
-        }
-      }
-
-      if (fd == -1) {
-        const char *cwd = os::get_current_directory(buffer, sizeof(buffer));
-        size_t len = strlen(cwd);
-        // either user didn't specify, or the user's location failed,
-        // so use the default name in the current directory
-        jio_snprintf(&buffer[len], sizeof(buffer)-len, "%shs_err_pid%u.log",
-                     os::file_separator(), os::current_process_id());
-        fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
-      }
-
-      if (fd == -1) {
-        const char * tmpdir = os::get_temp_directory();
-        // try temp directory if it exists.
-        if (tmpdir != NULL && tmpdir[0] != '\0') {
-          jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log",
-                       tmpdir, os::file_separator(), os::current_process_id());
-          fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
-        }
-      }
-
+      int fd = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer));
       if (fd != -1) {
         out.print_raw("# An error report file with more information is saved as:\n# ");
         out.print_raw_cr(buffer);
@@ -958,7 +979,7 @@
     // Run error reporting to determine whether or not to report the crash.
     if (!transmit_report_done && should_report_bug(first_error->_id)) {
       transmit_report_done = true;
-      FILE* hs_err = ::fdopen(log.fd(), "r");
+      FILE* hs_err = os::open(log.fd(), "r");
       if (NULL != hs_err) {
         ErrorReporter er;
         er.call(hs_err, buffer, O_BUFLEN);
@@ -1008,7 +1029,19 @@
     skip_replay = true;
     ciEnv* env = ciEnv::current();
     if (env != NULL) {
-      env->dump_replay_data();
+      int fd = prepare_log_file(ReplayDataFile, "replay_pid%p.log", buffer, sizeof(buffer));
+      if (fd != -1) {
+        FILE* replay_data_file = os::open(fd, "w");
+        if (replay_data_file != NULL) {
+          fileStream replay_data_stream(replay_data_file, /*need_close=*/true);
+          env->dump_replay_data(&replay_data_stream);
+          out.print_raw("#\n# Compiler replay data is saved as:\n# ");
+          out.print_raw_cr(buffer);
+        } else {
+          out.print_raw("#\n# Can't open file to dump replay data. Error: ");
+          out.print_raw_cr(strerror(os::get_last_error()));
+        }
+      }
     }
   }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/ciReplay/TestSA.sh	Fri Apr 26 10:52:26 2013 -0700
@@ -0,0 +1,92 @@
+#!/bin/sh
+# 
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+# 
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+# 
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+# 
+# 
+
+##
+## @test
+## @bug 8011675
+## @summary testing of ciReplay with using generated by SA replay.txt 
+## @author igor.ignatyev@oracle.com
+## @run shell TestSA.sh
+##
+
+if [ "${TESTSRC}" = "" ]
+then
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
+fi
+echo "TESTSRC=${TESTSRC}"
+
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
+
+. ${TESTSRC}/common.sh
+
+generate_replay
+
+${MV} ${replay_data} replay_vm.txt    
+
+if [ -z "${core_file}" -o ! -r "${core_file}" ]
+then
+    # skip test if MacOS host isn't configured for core dumping
+    if [ "$OS" = "Darwin" ]
+    then
+        if [ ! -d "/cores" ]
+        then
+            echo TEST SKIPPED: \'/cores\' dir doens\'t exist
+            exit 0
+        fi
+        if [ ! -w "/cores" ]
+        then
+            echo TEST SKIPPED: \'/cores\' dir exists but is not writable
+            exit 0
+        fi
+    fi
+    test_fail 2 "CHECK :: CORE GENERATION" "core wasn't generated on $OS"
+fi
+
+echo "dumpreplaydata -a > ${replay_data}" | \
+        ${JAVA} ${TESTVMOPTS} \
+        -cp ${TESTJAVA}${FS}lib${FS}sa-jdi.jar \
+        sun.jvm.hotspot.CLHSDB  ${JAVA} ${core_file}
+
+if [ ! -s ${replay_data} ]
+then
+    test_fail 1 "CHECK :: REPLAY DATA GENERATION" \
+        "replay data wasn't generated by SA"
+fi
+
+diff --brief ${replay_data} replay_vm.txt
+if [ $? -ne 0 ]
+then
+    echo WARNING: replay.txt from SA != replay.txt from VM
+fi
+
+common_tests 10 
+${VM_TYPE}_tests 20
+
+cleanup
+
+echo TEST PASSED
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/ciReplay/TestVM.sh	Fri Apr 26 10:52:26 2013 -0700
@@ -0,0 +1,86 @@
+#!/bin/sh
+# 
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+# 
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+# 
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+# 
+# 
+
+##
+## @test
+## @bug 8011675
+## @summary testing of ciReplay with using generated by VM replay.txt 
+## @author igor.ignatyev@oracle.com
+## @run shell TestVM.sh
+##
+
+if [ "${TESTSRC}" = "" ]
+then
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
+fi
+echo "TESTSRC=${TESTSRC}"
+
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
+
+. ${TESTSRC}/common.sh
+
+generate_replay
+
+if [ ! -s ${replay_data} ]
+then
+    test_fail 1 "CHECK :: REPLAY DATA GENERATION" \
+        "replay data wasn't generated by VM"
+fi
+
+common_tests 10
+${VM_TYPE}_tests 20
+
+cleanup
+
+if [ $is_tiered -eq 1 ]
+then
+    stop_level=1
+    while [ $stop_level -le $server_level ]
+    do
+        generate_replay "-XX:TieredStopAtLevel=$stop_level"
+        if [ ! -s ${replay_data} ]
+        then
+            test_fail `expr $stop_level + 30` \
+                    "TIERED LEVEL $stop_level :: REPLAY DATA GENERATION" \
+                    "replay data wasn't generated by VM with stop_level=$stop_level"
+        fi
+        level=`grep "^compile " $replay_data | awk '{print $6}'`
+        if [ $level -gt $stop_level ]
+        then
+            test_fail `expr $stop_level + 40` \
+                    "TIERED LEVEL $stop_level :: COMP_LEVEL VERIFICATION" \
+                    "comp_level in replay[$level] is greater than stop_level[$stop_level]"
+        fi
+        positive_test `expr $stop_level + 50` "TIERED LEVEL $stop_level :: REPLAY" \
+                "-XX:TieredStopAtLevel=$stop_level"
+        stop_level=`expr $stop_level + 1`
+    done
+    cleanup
+fi
+
+echo TEST PASSED
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/ciReplay/TestVM_no_comp_level.sh	Fri Apr 26 10:52:26 2013 -0700
@@ -0,0 +1,74 @@
+#!/bin/sh
+# 
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+# 
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+# 
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+# 
+# 
+
+##
+## @test
+## @bug 8011675
+## @summary testing of ciReplay with using generated by VM replay.txt w/o comp_level
+## @author igor.ignatyev@oracle.com
+## @run shell TestVM_no_comp_level.sh
+##
+
+if [ "${TESTSRC}" = "" ]
+then
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
+fi
+echo "TESTSRC=${TESTSRC}"
+
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
+
+. ${TESTSRC}/common.sh
+
+generate_replay
+
+if [ ! -s ${replay_data} ]
+then
+    test_fail 1 "CHECK :: REPLAY DATA GENERATION" \
+            "replay data wasn't generated by VM"
+fi
+
+${CP} ${replay_data} replay_vm.txt
+
+sed 's/^\(compile *[^ ][^ ]* *[^ ][^ ]* [^ ][^ ]* [^ ][^ ]*\).*$/\1/' \
+        replay_vm.txt > ${replay_data}
+
+if [ $client_available -eq 1 ]
+then
+    # tiered is unavailable in client vm, so results w/ flags will be the same as w/o flags
+    negative_test 10 "CLIENT" -client
+fi
+
+if [ $server_available -eq 1 ]
+then
+    positive_test 21 "SERVER :: NON-TIERED" -XX:-TieredCompilation -server
+    positive_test 22 "SERVER :: TIERED" -XX:+TieredCompilation -server
+fi
+
+cleanup
+
+echo TEST PASSED
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/ciReplay/common.sh	Fri Apr 26 10:52:26 2013 -0700
@@ -0,0 +1,253 @@
+#!/bin/sh
+# 
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+# 
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+# 
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+# 
+# 
+
+# $1 - error code
+# $2 - test name
+# $3,.. - decription
+test_fail() {
+    error=$1
+    shift
+    name=$1
+    shift
+    echo "TEST [$name] FAILED:"
+    echo "$@"
+    exit $error
+}
+
+# $@ - additional vm opts
+start_test() {
+    # disable core dump on *nix
+    ulimit -S -c 0
+    # disable core dump on windows
+    VMOPTS="$@ -XX:-CreateMinidumpOnCrash"
+    cmd="${JAVA} ${VMOPTS} -XX:+ReplayCompiles -XX:ReplayDataFile=${replay_data}"
+    echo $cmd
+    $cmd
+    return $?
+}
+
+# $1 - error_code
+# $2 - test name
+# $3,.. - additional vm opts
+positive_test() {
+    error=$1
+    shift
+    name=$1
+    shift
+    VMOPTS="${TESTVMOPTS} $@"
+    echo "POSITIVE TEST [$name]"
+    start_test ${VMOPTS}
+    exit_code=$?
+    if [ ${exit_code} -ne 0 ]
+    then
+        test_fail $error "$name" "exit_code[${exit_code}] != 0 during replay "\
+                "w/ vmopts: ${VMOPTS}"
+    fi
+}
+
+# $1 - error_code
+# $2 - test name
+# $2,.. - additional vm opts
+negative_test() {
+    error=$1
+    shift
+    name=$1
+    shift
+    VMOPTS="${TESTVMOPTS} $@"
+    echo "NEGATIVE TEST [$name]"
+    start_test ${VMOPTS}
+    exit_code=$?
+    if [ ${exit_code} -eq 0 ]
+    then
+        test_fail $error "$name" "exit_code[${exit_code}] == 0 during replay "\
+                "w/ vmopts: ${VMOPTS}"
+    fi
+}
+
+# $1 - initial error_code
+common_tests() {
+    positive_test $1 "COMMON :: THE SAME FLAGS"
+    positive_test `expr $1 + 1` "COMMON :: TIERED" -XX:+TieredCompilation
+}
+
+# $1 - initial error_code
+# $2 - non-tiered comp_level 
+nontiered_tests() {
+    level=`grep "^compile " $replay_data | awk '{print $6}'`
+    # is level available in non-tiere
+    if [ "$level" -eq $2 ]
+    then
+        positive_test $1 "NON-TIERED :: AVAILABLE COMP_LEVEL" \
+                -XX:-TieredCompilation
+    else
+        negative_test `expr $1 + 1` "NON-TIERED :: UNAVAILABLE COMP_LEVEL" \
+        negative_test `expr $1 + 1` "NON-TIERED :: UNAVAILABLE COMP_LEVEL" \
+                -XX:-TieredCompilation
+    fi
+}
+
+# $1 - initial error_code
+client_tests() {
+    # testing in opposite VM
+    if [ $server_available -eq 1 ]
+    then
+        negative_test $1 "SERVER :: NON-TIERED" -XX:-TieredCompilation \
+                -server
+        positive_test `expr $1 + 1` "SERVER :: TIERED" -XX:+TieredCompilation \
+                -server
+    fi
+    nontiered_tests `expr $1 + 2` $client_level 
+}
+
+# $1 - initial error_code
+server_tests() {
+    # testing in opposite VM
+    if [ $client_available -eq 1 ]
+    then
+        # tiered is unavailable in client vm, so results w/ flags will be the same as w/o flags
+        negative_test $1 "CLIENT" -client
+    fi
+    nontiered_tests `expr $1 + 2` $server_level
+}
+
+cleanup() {
+    ${RM} -f core*
+    ${RM} -f replay*.txt
+    ${RM} -f hs_err_pid*.log
+    ${RM} -f test_core
+    ${RM} -f test_replay.txt
+}
+
+JAVA=${TESTJAVA}${FS}bin${FS}java
+
+replay_data=test_replay.txt
+
+${JAVA} ${TESTVMOPTS} -Xinternalversion 2>&1 | grep debug
+
+# Only test fastdebug 
+if [ $? -ne 0 ]
+then
+    echo TEST SKIPPED: product build
+    exit 0
+fi
+
+is_int=`${JAVA} ${TESTVMOPTS} -version 2>&1 | grep -c "interpreted mode"`
+# Not applicable for Xint
+if [ $is_int -ne 0 ]
+then
+    echo TEST SKIPPED: interpreted mode
+    exit 0
+fi
+
+cleanup
+
+client_available=`${JAVA} ${TESTVMOPTS} -client -Xinternalversion 2>&1 | \
+        grep -c Client`
+server_available=`${JAVA} ${TESTVMOPTS} -server -Xinternalversion 2>&1 | \
+        grep -c Server`
+is_tiered=`${JAVA} ${TESTVMOPTS} -XX:+PrintFlagsFinal -version | \
+        grep TieredCompilation | \
+        grep -c true`
+# CompLevel_simple -- C1
+client_level=1
+# CompLevel_full_optimization -- C2 or Shark 
+server_level=4
+
+echo "client_available=$client_available"
+echo "server_available=$server_available"
+echo "is_tiered=$is_tiered"
+
+# crash vm in compiler thread with generation replay data and 'small' dump-file
+# $@ - additional vm opts
+generate_replay() {
+    # enable core dump
+    ulimit -c unlimited
+
+    cmd="${JAVA} ${TESTVMOPTS} $@ \
+            -Xms8m \
+            -Xmx32m \
+            -XX:MetaspaceSize=4m \
+            -XX:MaxMetaspaceSize=16m \
+            -XX:InitialCodeCacheSize=512k \
+            -XX:ReservedCodeCacheSize=4m \
+            -XX:ThreadStackSize=512 \
+            -XX:VMThreadStackSize=512 \
+            -XX:CompilerThreadStackSize=512 \
+            -XX:ParallelGCThreads=1 \
+            -XX:CICompilerCount=1 \
+            -Xcomp \
+            -XX:CICrashAt=1 \
+            -XX:+CreateMinidumpOnCrash \
+            -XX:+DumpReplayDataOnError \
+            -XX:ReplayDataFile=${replay_data} \
+            -version"
+    echo GENERATION OF REPLAY.TXT:
+    echo $cmd
+
+    ${cmd} 2>&1 > crash.out
+    
+    core_locations=`grep -i core crash.out | grep "location:" | \
+            sed -e 's/.*location: //'`
+    rm crash.out 
+    # processing core locations for *nix
+    if [ $OS != "windows" ]
+    then
+        # remove 'or' between '/core.<pid>' and 'core'
+        core_locations=`echo $core_locations | \
+                sed -e 's/\([^ ]*\) or \([^ ]*\)/\1 \2/'`
+        # add <core_path>/core.<pid> core.<pid>
+        core=`echo $core_locations | awk '{print $1}'`
+        dir=`dirname $core`
+        core=`basename $core`
+        if [ -n ${core} ]
+        then
+            core_locations="$core_locations $dir${FS}$core"
+        fi
+        core=`echo $core_locations | awk '{print $2}'`
+        if [ -n ${core} ]
+        then
+            core_locations="$core_locations $dir${FS}$core"
+        fi
+    fi
+
+    echo "LOOKING FOR CORE IN ${core_locations}"
+    for core in $core_locations
+    do
+        if [ -r "$core" ]
+        then
+            core_file=$core
+        fi
+    done
+
+    # core-file was found
+    if [ -n "$core_file" ]
+    then
+        ${MV} "${core_file}" test_core
+        core_file=test_core
+    fi
+
+    ${RM} -f hs_err_pid*.log
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sanity/WhiteBox.java	Fri Apr 26 10:52:26 2013 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test WhiteBox
+ * @bug 8011675
+ * @summary verify that whitebox can be used even if not all functions are declared in java-part
+ * @author igor.ignatyev@oracle.com
+ * @library /testlibrary
+ * @compile WhiteBox.java
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI sun.hotspot.WhiteBox
+ * @clean sun.hotspot.WhiteBox
+ */
+
+package sun.hotspot;
+
+public class WhiteBox {
+    private static native void registerNatives();
+    static { registerNatives(); }
+    public native int notExistedMethod();
+    public native int getHeapOopSize();
+    public static void main(String[] args) {
+        WhiteBox wb = new WhiteBox();
+        if (wb.getHeapOopSize() < 0) {
+            throw new Error("wb.getHeapOopSize() < 0");
+        }
+        boolean catched = false;
+        try {
+            wb.notExistedMethod();
+        } catch (UnsatisfiedLinkError e) {
+            catched = true;
+        }
+        if (!catched) {
+            throw new Error("wb.notExistedMethod() was invoked");
+        }
+    }
+}