changeset 4554:124ca22437b1

Merge
author chegar
date Fri, 12 Apr 2013 10:14:42 +0100
parents 511e334ee345 (diff) 3d641132f83b (current diff)
children 6c560f9ebb3e
files src/share/vm/opto/library_call.cpp
diffstat 296 files changed, 8623 insertions(+), 4373 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Feb 26 16:16:54 2013 -0800
+++ b/.hgtags	Fri Apr 12 10:14:42 2013 +0100
@@ -325,3 +325,10 @@
 65b797426a3bec6e91b64085a0cfb94adadb634a jdk8-b81
 0631ebcc45f05c73b09a56c2586685af1f781c1d hs25-b23
 3db4ab0e12f437fe374817de346b2b0c6b4a5b31 jdk8-b82
+e3a41fc0234895eba4f272b984f7dacff495f8eb hs25-b24
+1c8db54ee9f315e20d6d5d9bf0b5c10349e9d301 jdk8-b83
+8d0f263a370c5f3e61791bb06054560804117288 hs25-b25
+af788b85010ebabbc1e8f52c6766e08c7a95cf99 jdk8-b84
+a947f40fb536e5b9e0aa210cf26abb430f80887a hs25-b26
+42fe530cd478744a4d12a0cbf803f0fc804bab1a jdk8-b85
+09b0d3e9ba6cdf7da07d4010d2d1df14596f6864 hs25-b27
--- a/agent/src/os/bsd/MacosxDebuggerLocal.m	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/os/bsd/MacosxDebuggerLocal.m	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -40,12 +40,34 @@
 #import <errno.h>
 #import <sys/types.h>
 #import <sys/ptrace.h>
+#include "libproc_impl.h"
 
-jboolean debug = JNI_FALSE;
+#define UNSUPPORTED_ARCH "Unsupported architecture!"
+
+#if defined(x86_64) && !defined(amd64)
+#define amd64 1
+#endif
+
+#if amd64
+#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
+#else
+#error UNSUPPORTED_ARCH
+#endif
 
 static jfieldID symbolicatorID = 0; // set in _init0
 static jfieldID taskID = 0; // set in _init0
 
+static jfieldID p_ps_prochandle_ID = 0;
+static jfieldID loadObjectList_ID = 0;
+static jmethodID listAdd_ID = 0;
+
+static jmethodID createClosestSymbol_ID = 0;
+static jmethodID createLoadObject_ID = 0;
+static jmethodID getJavaThreadsInfo_ID = 0;
+
+// indicator if thread id (lwpid_t) was set
+static bool _threads_filled = false;
+
 static void putSymbolicator(JNIEnv *env, jobject this_obj, id symbolicator) {
   (*env)->SetLongField(env, this_obj, symbolicatorID, (jlong)(intptr_t)symbolicator);
 }
@@ -76,6 +98,11 @@
   (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
 }
 
+static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
+  jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);
+  return (struct ps_prochandle*)(intptr_t)ptr;
+}
+
 #if defined(__i386__)
     #define hsdb_thread_state_t     x86_thread_state32_t
     #define hsdb_float_state_t      x86_float_state32_t
@@ -91,7 +118,7 @@
     #define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT
     #define HSDB_FLOAT_STATE_COUNT  x86_FLOAT_STATE64_COUNT
 #else
-    #error "Unsupported architecture"
+    #error UNSUPPORTED_ARCH
 #endif
 
 /*
@@ -104,6 +131,66 @@
   symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J");
   taskID = (*env)->GetFieldID(env, cls, "task", "J");
   CHECK_EXCEPTION;
+
+  // for core file
+  p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J");
+  CHECK_EXCEPTION;
+  loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;");
+  CHECK_EXCEPTION;
+
+  // methods we use
+  createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol",
+                    "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
+  CHECK_EXCEPTION;
+  createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject",
+                    "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");
+  CHECK_EXCEPTION;
+
+  // java.util.List method we call
+  jclass listClass = (*env)->FindClass(env, "java/util/List");
+  CHECK_EXCEPTION;
+  listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");
+  CHECK_EXCEPTION;
+  getJavaThreadsInfo_ID = (*env)->GetMethodID(env, cls, "getJavaThreadsInfo",
+                                                     "()[J");
+  CHECK_EXCEPTION;
+
+  init_libproc(getenv("LIBSAPROC_DEBUG") != NULL);
+}
+
+JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize
+  (JNIEnv *env, jclass cls)
+{
+#ifdef _LP64
+  return 8;
+#else
+  #error UNSUPPORTED_ARCH
+#endif
+}
+
+/** called by Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0 */
+jlong lookupByNameIncore(
+  JNIEnv *env, struct ps_prochandle *ph, jobject this_obj, jstring objectName, jstring symbolName)
+{
+  const char *objectName_cstr, *symbolName_cstr;
+  jlong addr;
+  jboolean isCopy;
+  objectName_cstr = NULL;
+  if (objectName != NULL) {
+    objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy);
+    CHECK_EXCEPTION_(0);
+  }
+  symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy);
+  CHECK_EXCEPTION_(0);
+
+  print_debug("look for %s \n", symbolName_cstr);
+  addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr);
+
+  if (objectName_cstr != NULL) {
+    (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr);
+  }
+  (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr);
+  return addr;
 }
 
 /*
@@ -116,14 +203,17 @@
   JNIEnv *env, jobject this_obj, 
   jstring objectName, jstring symbolName) 
 {
+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+  if (ph->core != NULL) {
+    return lookupByNameIncore(env, ph, this_obj, objectName, symbolName);
+  }
+
   jlong address = 0;
 
 JNF_COCOA_ENTER(env);
   NSString *symbolNameString = JNFJavaToNSString(env, symbolName);
 
-  if (debug) {
-    printf("lookupInProcess called for %s\n", [symbolNameString UTF8String]);
-  }
+  print_debug("lookupInProcess called for %s\n", [symbolNameString UTF8String]);
 
   id symbolicator = getSymbolicator(env, this_obj);
   if (symbolicator != nil) {
@@ -131,9 +221,7 @@
     address = (jlong) dynamicCall(symbolicator, @selector(addressForSymbol:), symbolNameString);
   }
 
-  if (debug) {
-    printf("address of symbol %s = %llx\n", [symbolNameString UTF8String], address);
-  }
+  print_debug("address of symbol %s = %llx\n", [symbolNameString UTF8String], address);
 JNF_COCOA_EXIT(env);
 
   return address;
@@ -141,6 +229,42 @@
 
 /*
  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    lookupByAddress0
+ * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
+ */
+JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0
+  (JNIEnv *env, jobject this_obj, jlong addr) {
+  uintptr_t offset;
+  const char* sym = NULL;
+
+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+  sym = symbol_for_pc(ph, (uintptr_t) addr, &offset);
+  if (sym == NULL) return 0;
+  return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID,
+                          (*env)->NewStringUTF(env, sym), (jlong)offset);
+}
+
+/** called from Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0 */
+jbyteArray readBytesFromCore(
+  JNIEnv *env, struct ps_prochandle *ph, jobject this_obj, jlong addr, jlong numBytes)
+{
+  jboolean isCopy;
+  jbyteArray array;
+  jbyte *bufPtr;
+  ps_err_e err;
+
+  array = (*env)->NewByteArray(env, numBytes);
+  CHECK_EXCEPTION_(0);
+  bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy);
+  CHECK_EXCEPTION_(0);
+
+  err = ps_pread(ph, (psaddr_t) (uintptr_t)addr, bufPtr, numBytes);
+  (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0);
+  return (err == PS_OK)? array : 0;
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
  * Method:    readBytesFromProcess0
  * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
  */
@@ -149,12 +273,15 @@
   JNIEnv *env, jobject this_obj, 
   jlong addr, jlong numBytes) 
 {
-  if (debug) printf("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes);
+  print_debug("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes);
 
   // must allocate storage instead of using former parameter buf
-  jboolean isCopy;
   jbyteArray array;
-  jbyte *bufPtr;
+
+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+  if (ph->core != NULL) {
+    return readBytesFromCore(env, ph, this_obj, addr, numBytes);
+  }
 
   array = (*env)->NewByteArray(env, numBytes);
   CHECK_EXCEPTION_(0);
@@ -189,7 +316,7 @@
     // assume all failures are unmapped pages
   }
 
-  if (debug) fprintf(stderr, "%ld pages\n", pageCount);
+  print_debug("%ld pages\n", pageCount);
 	
   remaining = numBytes;
 	
@@ -207,7 +334,7 @@
     }
 
     if (mapped[i]) {
-      if (debug) fprintf(stderr, "page %d mapped (len %ld start %ld)\n", i, len, start);
+      print_debug("page %d mapped (len %ld start %ld)\n", i, len, start);
       (*env)->SetByteArrayRegion(env, array, 0, len, ((jbyte *) pages[i] + start));
       vm_deallocate(mach_task_self(), pages[i], vm_page_size);
     }
@@ -220,6 +347,115 @@
   return array;
 }
 
+/** Only used for core file reading, set thread_id for threads which is got after core file parsed.
+  * Thread context is available in Mach-O core file but thread id is not. We can get thread id
+  * from Threads which store all java threads information when they are created. Here we can identify
+  * them as java threads by checking if a thread's rsp or rbp within a java thread's stack.
+  * Note Macosx uses unique_thread_id which is different from other platforms though printed ids
+  * are still pthread id. Function BsdDebuggerLocal.getJavaThreadsInfo returns an array of long
+  * integers to host all java threads' id, stack_start, stack_end as:
+  * [uid0, stack_start0, stack_end0, uid1, stack_start1, stack_end1, ...]
+  *
+  * The work cannot be done at init0 since Threads is not available yet(VM not initialized yet). 
+  * This function should be called only once if succeeded
+  */ 
+bool fill_java_threads(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
+  int n = 0, i = 0, j;
+  struct reg regs;
+  
+  jlongArray thrinfos = (*env)->CallObjectMethod(env, this_obj, getJavaThreadsInfo_ID);
+  CHECK_EXCEPTION_(false);
+  int len = (int)(*env)->GetArrayLength(env, thrinfos);
+  uint64_t* cinfos = (uint64_t *)(*env)->GetLongArrayElements(env, thrinfos, NULL);
+  CHECK_EXCEPTION_(false); 
+  n = get_num_threads(ph);
+  print_debug("fill_java_threads called, num_of_thread = %d\n", n);
+  for (i = 0; i < n; i++) {
+    if (!get_nth_lwp_regs(ph, i, &regs)) {
+      print_debug("Could not get regs of thread %d, already set!\n", i);
+      return false;
+    }
+    for (j = 0; j < len; j += 3) {
+      lwpid_t  uid = cinfos[j];
+      uint64_t beg = cinfos[j + 1];
+      uint64_t end = cinfos[j + 2]; 
+      if ((regs.r_rsp < end && regs.r_rsp >= beg) ||
+          (regs.r_rbp < end && regs.r_rbp >= beg)) {
+        set_lwp_id(ph, i, uid);
+        break;
+      }
+    }
+  }
+  (*env)->ReleaseLongArrayElements(env, thrinfos, (jlong*)cinfos, 0);
+  CHECK_EXCEPTION_(false);
+  return true;
+}
+
+/* For core file only, called from
+ * Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0
+ */
+jlongArray getThreadIntegerRegisterSetFromCore(JNIEnv *env, jobject this_obj, long lwp_id) {
+  if (!_threads_filled)  {
+    if (!fill_java_threads(env, this_obj, get_proc_handle(env, this_obj))) {
+      throw_new_debugger_exception(env, "Failed to fill in threads");
+      return 0;
+    } else {
+      _threads_filled = true;
+    }
+  }
+
+  struct reg gregs;
+  jboolean isCopy;
+  jlongArray array;
+  jlong *regs;
+
+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+  if (get_lwp_regs(ph, lwp_id, &gregs) != true) {
+    THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0);
+  }
+
+#undef NPRGREG
+#undef REG_INDEX
+#if amd64
+#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
+
+  array = (*env)->NewLongArray(env, NPRGREG);
+  CHECK_EXCEPTION_(0);
+  regs = (*env)->GetLongArrayElements(env, array, &isCopy);
+
+  regs[REG_INDEX(R15)] = gregs.r_r15;
+  regs[REG_INDEX(R14)] = gregs.r_r14;
+  regs[REG_INDEX(R13)] = gregs.r_r13;
+  regs[REG_INDEX(R12)] = gregs.r_r12;
+  regs[REG_INDEX(RBP)] = gregs.r_rbp;
+  regs[REG_INDEX(RBX)] = gregs.r_rbx;
+  regs[REG_INDEX(R11)] = gregs.r_r11;
+  regs[REG_INDEX(R10)] = gregs.r_r10;
+  regs[REG_INDEX(R9)]  = gregs.r_r9;
+  regs[REG_INDEX(R8)]  = gregs.r_r8;
+  regs[REG_INDEX(RAX)] = gregs.r_rax;
+  regs[REG_INDEX(RCX)] = gregs.r_rcx;
+  regs[REG_INDEX(RDX)] = gregs.r_rdx;
+  regs[REG_INDEX(RSI)] = gregs.r_rsi;
+  regs[REG_INDEX(RDI)] = gregs.r_rdi;
+  regs[REG_INDEX(RIP)] = gregs.r_rip;
+  regs[REG_INDEX(CS)]  = gregs.r_cs;
+  regs[REG_INDEX(RSP)] = gregs.r_rsp;
+  regs[REG_INDEX(SS)]  = gregs.r_ss;
+  regs[REG_INDEX(FSBASE)] = 0;
+  regs[REG_INDEX(GSBASE)] = 0;
+  regs[REG_INDEX(DS)] = gregs.r_ds;
+  regs[REG_INDEX(ES)] = gregs.r_es;
+  regs[REG_INDEX(FS)] = gregs.r_fs;
+  regs[REG_INDEX(GS)] = gregs.r_gs;
+  regs[REG_INDEX(TRAPNO)] = gregs.r_trapno;
+  regs[REG_INDEX(RFL)]    = gregs.r_rflags;
+
+#endif /* amd64 */
+  (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
+  return array;
+}
 
 /*
  * Lookup the thread_t that corresponds to the given thread_id.
@@ -232,9 +468,7 @@
  */
 thread_t
 lookupThreadFromThreadId(task_t task, jlong thread_id) {
-  if (debug) {
-    printf("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id);
-  }
+  print_debug("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id);
   
   thread_array_t thread_list = NULL;
   mach_msg_type_number_t thread_list_count = 0;
@@ -244,9 +478,7 @@
   // get the list of all the send rights
   kern_return_t result = task_threads(task, &thread_list, &thread_list_count);
   if (result != KERN_SUCCESS) {
-    if (debug) {
-      printf("task_threads returned 0x%x\n", result);
-    }
+    print_debug("task_threads returned 0x%x\n", result);
     return 0;
   }
   
@@ -257,9 +489,7 @@
     // get the THREAD_IDENTIFIER_INFO for the send right
     result = thread_info(thread_list[i], THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count);
     if (result != KERN_SUCCESS) {
-      if (debug) {
-        printf("thread_info returned 0x%x\n", result);
-      }
+      print_debug("thread_info returned 0x%x\n", result);
       break;
     }
     
@@ -288,15 +518,17 @@
   JNIEnv *env, jobject this_obj, 
   jlong thread_id) 
 {
-  if (debug)
-    printf("getThreadRegisterSet0 called\n");
+  print_debug("getThreadRegisterSet0 called\n");
+
+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+  if (ph->core != NULL) {
+    return getThreadIntegerRegisterSetFromCore(env, this_obj, thread_id);
+  }
 
   kern_return_t result;
   thread_t tid;
   mach_msg_type_number_t count = HSDB_THREAD_STATE_COUNT;
   hsdb_thread_state_t state;
-  unsigned int *r;
-  int i;
   jlongArray registerArray;
   jlong *primitiveArray;
   task_t gTask = getTask(env, this_obj);
@@ -306,97 +538,56 @@
   result = thread_get_state(tid, HSDB_THREAD_STATE, (thread_state_t)&state, &count);
 
   if (result != KERN_SUCCESS) {
-    if (debug)
-      printf("getregs: thread_get_state(%d) failed (%d)\n", tid, result);
+    print_error("getregs: thread_get_state(%d) failed (%d)\n", tid, result);
     return NULL;
   }
 
-  // 40 32-bit registers on ppc, 16 on x86. 
-  // Output order is the same as the order in the ppc_thread_state/i386_thread_state struct.
-#if defined(__i386__)
-	r = (unsigned int *)&state;
-	registerArray = (*env)->NewLongArray(env, 8);
-	primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL);
-	primitiveArray[0] = r[0];  // eax
-	primitiveArray[1] = r[2];  // ecx
-	primitiveArray[2] = r[3];  // edx
-	primitiveArray[3] = r[1];  // ebx
-	primitiveArray[4] = r[7];  // esp
-	primitiveArray[5] = r[6];  // ebp
-	primitiveArray[6] = r[5];  // esi
-	primitiveArray[7] = r[4];  // edi
-	(*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0);
-#elif defined(__x86_64__)
-	/* From AMD64ThreadContext.java
-	   public static final int R15 = 0;
-	   public static final int R14 = 1;
-	   public static final int R13 = 2;
-	   public static final int R12 = 3;
-	   public static final int R11 = 4;
-	   public static final int R10 = 5;
-	   public static final int R9  = 6;
-	   public static final int R8  = 7;
-	   public static final int RDI = 8;
-	   public static final int RSI = 9;
-	   public static final int RBP = 10;
-	   public static final int RBX = 11;
-	   public static final int RDX = 12;
-	   public static final int RCX = 13;
-	   public static final int RAX = 14;
-	   public static final int TRAPNO = 15;
-	   public static final int ERR = 16;
-	   public static final int RIP = 17;
-	   public static final int CS = 18;
-	   public static final int RFL = 19;
-	   public static final int RSP = 20;
-	   public static final int SS = 21;
-	   public static final int FS = 22;
-	   public static final int GS = 23;
-	   public static final int ES = 24;
-	   public static final int DS = 25;
-	   public static final int FSBASE = 26;
-	   public static final int GSBASE = 27;
-	 */
-	// 64 bit
-	if (debug) printf("Getting threads for a 64-bit process\n");
-	registerArray = (*env)->NewLongArray(env, 28);
-	primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL);
+#if amd64
+#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
+#undef REG_INDEX
+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
+
+  // 64 bit
+  print_debug("Getting threads for a 64-bit process\n");
+  registerArray = (*env)->NewLongArray(env, NPRGREG);
+  CHECK_EXCEPTION_(0);
+  primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL);
 
-	primitiveArray[0] = state.__r15;
-	primitiveArray[1] = state.__r14;
-	primitiveArray[2] = state.__r13;
-	primitiveArray[3] = state.__r12;
-	primitiveArray[4] = state.__r11;
-	primitiveArray[5] = state.__r10;
-	primitiveArray[6] = state.__r9;
-	primitiveArray[7] = state.__r8;
-	primitiveArray[8] = state.__rdi;
-	primitiveArray[9] = state.__rsi;
-	primitiveArray[10] = state.__rbp;
-	primitiveArray[11] = state.__rbx;
-	primitiveArray[12] = state.__rdx;
-	primitiveArray[13] = state.__rcx;
-	primitiveArray[14] = state.__rax;
-	primitiveArray[15] = 0;             // trapno ?
-	primitiveArray[16] = 0;             // err ?
-	primitiveArray[17] = state.__rip;
-	primitiveArray[18] = state.__cs;
-	primitiveArray[19] = state.__rflags;
-	primitiveArray[20] = state.__rsp;
-	primitiveArray[21] = 0;            // We don't have SS
-	primitiveArray[22] = state.__fs;
-	primitiveArray[23] = state.__gs;
-	primitiveArray[24] = 0;
-	primitiveArray[25] = 0;
-	primitiveArray[26] = 0;
-	primitiveArray[27] = 0;
+  primitiveArray[REG_INDEX(R15)] = state.__r15;
+  primitiveArray[REG_INDEX(R14)] = state.__r14;
+  primitiveArray[REG_INDEX(R13)] = state.__r13;
+  primitiveArray[REG_INDEX(R12)] = state.__r12;
+  primitiveArray[REG_INDEX(R11)] = state.__r11;
+  primitiveArray[REG_INDEX(R10)] = state.__r10;
+  primitiveArray[REG_INDEX(R9)]  = state.__r9;
+  primitiveArray[REG_INDEX(R8)]  = state.__r8;
+  primitiveArray[REG_INDEX(RDI)] = state.__rdi;
+  primitiveArray[REG_INDEX(RSI)] = state.__rsi;
+  primitiveArray[REG_INDEX(RBP)] = state.__rbp;
+  primitiveArray[REG_INDEX(RBX)] = state.__rbx;
+  primitiveArray[REG_INDEX(RDX)] = state.__rdx;
+  primitiveArray[REG_INDEX(RCX)] = state.__rcx;
+  primitiveArray[REG_INDEX(RAX)] = state.__rax;
+  primitiveArray[REG_INDEX(TRAPNO)] = 0;            // trapno, not used
+  primitiveArray[REG_INDEX(ERR)]    = 0;            // err, not used 
+  primitiveArray[REG_INDEX(RIP)] = state.__rip;
+  primitiveArray[REG_INDEX(CS)]  = state.__cs;
+  primitiveArray[REG_INDEX(RFL)] = state.__rflags;
+  primitiveArray[REG_INDEX(RSP)] = state.__rsp;
+  primitiveArray[REG_INDEX(SS)] = 0;                // We don't have SS
+  primitiveArray[REG_INDEX(FS)] = state.__fs;
+  primitiveArray[REG_INDEX(GS)] = state.__gs;
+  primitiveArray[REG_INDEX(ES)] = 0;
+  primitiveArray[REG_INDEX(DS)] = 0;
+  primitiveArray[REG_INDEX(FSBASE)] = 0;
+  primitiveArray[REG_INDEX(GSBASE)] = 0;
+  print_debug("set registers\n");
 
-	if (debug) printf("set registers\n");
+  (*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0);
 
-	(*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0);
 #else
-#error Unsupported architecture
-#endif
+#error UNSUPPORTED_ARCH
+#endif /* amd64 */
 
   return registerArray;
 }
@@ -410,8 +601,7 @@
 Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0(
   JNIEnv *env, jobject this_obj, jint tid) 
 {
-  if (debug)
-    printf("translateTID0 called on tid = 0x%x\n", (int)tid);
+  print_debug("translateTID0 called on tid = 0x%x\n", (int)tid);
 
   kern_return_t result;
   thread_t foreign_tid, usable_tid;
@@ -426,8 +616,7 @@
   if (result != KERN_SUCCESS)
     return -1;
     
-  if (debug)
-    printf("translateTID0: 0x%x -> 0x%x\n", foreign_tid, usable_tid);
+  print_debug("translateTID0: 0x%x -> 0x%x\n", foreign_tid, usable_tid);
     
   return (jint) usable_tid;
 }
@@ -437,7 +626,7 @@
   // pass the signal to the process so we don't swallow it
   int res;
   if ((res = ptrace(PT_CONTINUE, pid, (caddr_t)1, signal)) < 0) {
-    fprintf(stderr, "attach: ptrace(PT_CONTINUE, %d) failed with %d\n", pid, res);
+    print_error("attach: ptrace(PT_CONTINUE, %d) failed with %d\n", pid, res);
     return false;
   }
   return true;
@@ -461,11 +650,11 @@
           return true;
         }
         if (!ptrace_continue(pid, WSTOPSIG(status))) {
-          fprintf(stderr, "attach: Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
+          print_error("attach: Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
           return false;
         }
       } else {
-        fprintf(stderr, "attach: waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
+        print_error("attach: waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
         return false;
       }
     } else {
@@ -474,13 +663,13 @@
           continue;
           break;
         case ECHILD:
-          fprintf(stderr, "attach: waitpid() failed. Child process pid (%d) does not exist \n", pid);
+          print_error("attach: waitpid() failed. Child process pid (%d) does not exist \n", pid);
           break;
         case EINVAL:
-          fprintf(stderr, "attach: waitpid() failed. Invalid options argument.\n");
+          print_error("attach: waitpid() failed. Invalid options argument.\n");
           break;
         default:
-          fprintf(stderr, "attach: waitpid() failed. Unexpected error %d\n",errno);
+          print_error("attach: waitpid() failed. Unexpected error %d\n",errno);
           break;
       }
       return false;
@@ -492,7 +681,7 @@
 static bool ptrace_attach(pid_t pid) {
   int res;
   if ((res = ptrace(PT_ATTACH, pid, 0, 0)) < 0) {
-    fprintf(stderr, "ptrace(PT_ATTACH, %d) failed with %d\n", pid, res);
+    print_error("ptrace(PT_ATTACH, %d) failed with %d\n", pid, res);
     return false;
   } else {
     return ptrace_waitpid(pid);
@@ -504,23 +693,19 @@
  * Method:    attach0
  * Signature: (I)V
  */
-JNIEXPORT void JNICALL 
+JNIEXPORT void JNICALL
 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I(
-  JNIEnv *env, jobject this_obj, jint jpid) 
+  JNIEnv *env, jobject this_obj, jint jpid)
 {
+  print_debug("attach0 called for jpid=%d\n", (int)jpid);
+
 JNF_COCOA_ENTER(env);
-  if (getenv("JAVA_SAPROC_DEBUG") != NULL)
-    debug = JNI_TRUE;
-  else
-    debug = JNI_FALSE;
-  if (debug) printf("attach0 called for jpid=%d\n", (int)jpid);
-  
-  // get the task from the pid
+
   kern_return_t result;
   task_t gTask = 0;
   result = task_for_pid(mach_task_self(), jpid, &gTask);
   if (result != KERN_SUCCESS) {
-    fprintf(stderr, "attach: task_for_pid(%d) failed (%d)\n", (int)jpid, result);
+    print_error("attach: task_for_pid(%d) failed (%d)\n", (int)jpid, result);
     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
   }
   putTask(env, this_obj, gTask);
@@ -550,18 +735,79 @@
 JNF_COCOA_EXIT(env);
 }
 
+/** For core file, 
+    called from Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2 */
+static void fillLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
+  int n = 0, i = 0;
+
+  // add load objects
+  n = get_num_libs(ph);
+  for (i = 0; i < n; i++) {
+     uintptr_t base;
+     const char* name;
+     jobject loadObject;
+     jobject loadObjectList;
+
+     base = get_lib_base(ph, i);
+     name = get_lib_name(ph, i);
+     loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID,
+                                   (*env)->NewStringUTF(env, name), (jlong)0, (jlong)base);
+     CHECK_EXCEPTION;
+     loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID);
+     CHECK_EXCEPTION;
+     (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);
+     CHECK_EXCEPTION;
+  }
+}
+
+/*
+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
+ * Method:    attach0
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2(
+  JNIEnv *env, jobject this_obj, jstring execName, jstring coreName)
+{
+  const char *execName_cstr;
+  const char *coreName_cstr;
+  jboolean isCopy;
+  struct ps_prochandle* ph;
+
+  execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy);
+  CHECK_EXCEPTION;
+  coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
+  CHECK_EXCEPTION;
+
+  print_debug("attach: %s %s\n", execName_cstr, coreName_cstr);
+
+  if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
+    (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
+    (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
+    THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
+  }
+  (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
+  (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
+  (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
+  fillLoadObjects(env, this_obj, ph);
+}
+
 /*
  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
  * Method:    detach0
  * Signature: ()V
  */
-JNIEXPORT void JNICALL 
+JNIEXPORT void JNICALL
 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0(
-  JNIEnv *env, jobject this_obj) 
+  JNIEnv *env, jobject this_obj)
 {
+  print_debug("detach0 called\n");
+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+  if (ph != NULL && ph->core != NULL) {
+     Prelease(ph);
+     return;
+  }
 JNF_COCOA_ENTER(env);
-  if (debug) printf("detach0 called\n");
-
   task_t gTask = getTask(env, this_obj);
 
   // detach from the ptraced process causing it to resume execution
@@ -569,15 +815,15 @@
   kern_return_t k_res;
   k_res = pid_for_task(gTask, &pid);
   if (k_res != KERN_SUCCESS) {
-    fprintf(stderr, "detach: pid_for_task(%d) failed (%d)\n", pid, k_res);
+    print_error("detach: pid_for_task(%d) failed (%d)\n", pid, k_res);
   }
   else {
     int res = ptrace(PT_DETACH, pid, 0, 0);
     if (res < 0) {
-      fprintf(stderr, "detach: ptrace(PT_DETACH, %d) failed (%d)\n", pid, res);
+      print_error("detach: ptrace(PT_DETACH, %d) failed (%d)\n", pid, res);
     }
   }
-  
+
   mach_port_deallocate(mach_task_self(), gTask);
   id symbolicator = getSymbolicator(env, this_obj);
   if (symbolicator != nil) {
@@ -585,170 +831,3 @@
   }
 JNF_COCOA_EXIT(env);
 }
-
-/*
- * Class:     sun_jvm_hotspot_asm_Disassembler
- * Method:    load_library
- * Signature: (Ljava/lang/String;)L
- */
-JNIEXPORT jlong JNICALL
-Java_sun_jvm_hotspot_asm_Disassembler_load_1library(
-  JNIEnv * env, 
-  jclass disclass,
-  jstring jrepath_s,
-  jstring libname_s) 
-{
-  uintptr_t func = 0;
-  const char* error_message = NULL;
-  const char* java_home;
-  jboolean isCopy;
-  uintptr_t *handle = NULL;
-
-  const char * jrepath = (*env)->GetStringUTFChars(env, jrepath_s, &isCopy); // like $JAVA_HOME/jre/lib/sparc/
-  const char * libname = (*env)->GetStringUTFChars(env, libname_s, &isCopy);
-  char buffer[128];
-
-  /* Load the hsdis library */
-  void* hsdis_handle;
-  hsdis_handle = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL);
-  if (hsdis_handle == NULL) {
-    snprintf(buffer, sizeof(buffer), "%s%s", jrepath, libname);
-    hsdis_handle = dlopen(buffer, RTLD_LAZY | RTLD_GLOBAL);
-  }
-  if (hsdis_handle != NULL) {
-    func = (uintptr_t)dlsym(hsdis_handle, "decode_instructions_virtual");
-  }
-  if (func == 0) {
-    error_message = dlerror();
-    fprintf(stderr, "%s\n", error_message);
-  }
-
-  (*env)->ReleaseStringUTFChars(env, libname_s, libname);
-  (*env)->ReleaseStringUTFChars(env, jrepath_s, jrepath);
-
-  if (func == 0) {
-    /* Couldn't find entry point.  error_message should contain some
-     * platform dependent error message.
-     */
-    THROW_NEW_DEBUGGER_EXCEPTION_(error_message, (jlong)func);
-  }
-  return (jlong)func;
-}
-
-/* signature of decode_instructions_virtual from hsdis.h */
-typedef void* (*decode_func)(uintptr_t start_va, uintptr_t end_va,
-                             unsigned char* start, uintptr_t length,
-                             void* (*event_callback)(void*, const char*, void*),
-                             void* event_stream,
-                             int (*printf_callback)(void*, const char*, ...),
-                             void* printf_stream,
-                             const char* options);
-
-/* container for call back state when decoding instructions */
-typedef struct {
-  JNIEnv* env;
-  jobject dis;
-  jobject visitor;
-  jmethodID handle_event;
-  jmethodID raw_print;
-  char buffer[4096];
-} decode_env;
-
-
-/* event callback binding to Disassembler.handleEvent */
-static void* event_to_env(void* env_pv, const char* event, void* arg) {
-  decode_env* denv = (decode_env*)env_pv;
-  JNIEnv* env = denv->env;
-  jstring event_string = (*env)->NewStringUTF(env, event);
-  jlong result = (*env)->CallLongMethod(env, denv->dis, denv->handle_event, denv->visitor,
-                                        event_string, (jlong) (uintptr_t)arg);
-  /* ignore exceptions for now */
-  CHECK_EXCEPTION_CLEAR_((void *)0);
-  return (void*)(uintptr_t)result;
-}
-
-/* printing callback binding to Disassembler.rawPrint */
-static int printf_to_env(void* env_pv, const char* format, ...) {
-  jstring output;
-  va_list ap;
-  int cnt;
-  decode_env* denv = (decode_env*)env_pv;
-  JNIEnv* env = denv->env;
-  size_t flen = strlen(format);
-  const char* raw = NULL;
-
-  if (flen == 0)  return 0;
-  if (flen < 2 ||
-      strchr(format, '%') == NULL) {
-    raw = format;
-  } else if (format[0] == '%' && format[1] == '%' &&
-             strchr(format+2, '%') == NULL) {
-    // happens a lot on machines with names like %foo
-    flen--;
-    raw = format+1;
-  }
-  if (raw != NULL) {
-    jstring output = (*env)->NewStringUTF(env, raw);
-    (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output);
-    CHECK_EXCEPTION_CLEAR;
-    return (int) flen;
-  }
-  va_start(ap, format);
-  cnt = vsnprintf(denv->buffer, sizeof(denv->buffer), format, ap);
-  va_end(ap);
-
-  output = (*env)->NewStringUTF(env, denv->buffer);
-  (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output);
-  CHECK_EXCEPTION_CLEAR;
-  return cnt;
-}
-
-/*
- * Class:     sun_jvm_hotspot_asm_Disassembler
- * Method:    decode
- * Signature: (Lsun/jvm/hotspot/asm/InstructionVisitor;J[BLjava/lang/String;J)V
- */
-JNIEXPORT void JNICALL
-Java_sun_jvm_hotspot_asm_Disassembler_decode(
-   JNIEnv * env,
-   jobject dis,
-   jobject visitor,
-   jlong startPc,
-   jbyteArray code,
-   jstring options_s,
-   jlong decode_instructions_virtual) 
-{
-  jboolean isCopy;
-  jbyte* start = (*env)->GetByteArrayElements(env, code, &isCopy);
-  jbyte* end = start + (*env)->GetArrayLength(env, code);
-  const char * options = (*env)->GetStringUTFChars(env, options_s, &isCopy);
-  jclass disclass = (*env)->GetObjectClass(env, dis);
-
-  decode_env denv;
-  denv.env = env;
-  denv.dis = dis;
-  denv.visitor = visitor;
-
-  /* find Disassembler.handleEvent callback */
-  denv.handle_event = (*env)->GetMethodID(env, disclass, "handleEvent",
-                                          "(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;J)J");
-  CHECK_EXCEPTION_CLEAR_VOID
-
-  /* find Disassembler.rawPrint callback */
-  denv.raw_print = (*env)->GetMethodID(env, disclass, "rawPrint",
-                                       "(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;)V");
-  CHECK_EXCEPTION_CLEAR_VOID
-
-  /* decode the buffer */
-  (*(decode_func)(uintptr_t)decode_instructions_virtual)(startPc,
-                                                         startPc + end - start,
-                                                         (unsigned char*)start,
-                                                         end - start,
-                                                         &event_to_env,  (void*) &denv,
-                                                         &printf_to_env, (void*) &denv,
-                                                         options);
-
-  /* cleanup */
-  (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT);
-  (*env)->ReleaseStringUTFChars(env, options_s, options);
-}
--- a/agent/src/os/bsd/Makefile	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/os/bsd/Makefile	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 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
@@ -22,34 +22,60 @@
 #  
 #
 
-ARCH := $(shell if ([ `uname -m` = "ia64" ])  ; then echo ia64 ; elif ([ `uname -m` = "amd64" ]) ; then echo amd64; elif ([ `uname -m` = "sparc64" ]) ; then echo sparc; else echo i386 ; fi )
+ARCH := $(shell if ([ `uname -m` = "ia64" ])  ; then echo ia64 ; elif ([ `uname -m` = "amd64" ]) ; then echo amd64; elif ([ `uname -m` = "x86_64" ]) ; then echo amd64; elif ([ `uname -m` = "sparc64" ]) ; then echo sparc; else echo i386 ; fi )
+
+OS       := $(shell uname -s)
+
 GCC      = gcc
 
 JAVAH    = ${JAVA_HOME}/bin/javah
 
+ifneq ($(OS), Darwin)
 SOURCES  = salibelf.c   \
         symtab.c        \
 	libproc_impl.c  \
 	ps_proc.c       \
 	ps_core.c       \
 	BsdDebuggerLocal.c
-
-INCLUDES = -I${JAVA_HOME}/include -I${JAVA_HOME}/include/$(shell uname -s | tr "[:upper:]" "[:lower:]")
-
-OBJS     = $(SOURCES:.c=.o)
+OBJS    = $(SOURCES:.c=.o)
+OBJSPLUS = $(OBJS) sadis.o
+LIBSA = $(ARCH)/libsaproc.so
 
 LIBS     = -lutil -lthread_db
 
-CFLAGS   = -c -fPIC -g -Wall -D_ALLBSD_SOURCE -D_GNU_SOURCE -D$(ARCH) $(INCLUDES)
+else
 
-LIBSA = $(ARCH)/libsaproc.so
+SOURCES  = symtab.c     \
+	libproc_impl.c  \
+	ps_core.c
+OBJS    = $(SOURCES:.c=.o)
+OBJSPLUS = MacosxDebuggerLocal.o sadis.o $(OBJS)
+EXTINCLUDE = -I/System/Library/Frameworks/JavaVM.framework/Headers -I.
+EXTCFLAGS = -m64 -D__APPLE__ -framework JavaNativeFoundation
+FOUNDATIONFLAGS = -framework Foundation -F/System/Library/Frameworks/JavaVM.framework/Frameworks -framework JavaNativeFoundation -framework Security -framework CoreFoundation
+LIBSA = $(ARCH)/libsaproc.dylib
+endif   # Darwin
+
+INCLUDES = -I${JAVA_HOME}/include -I${JAVA_HOME}/include/$(shell uname -s | tr "[:upper:]" "[:lower:]") $(EXTINCLUDE)
+
+
+
+CFLAGS   = -c -fPIC -g -Wall -D_ALLBSD_SOURCE -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) $(EXTCFLAGS)
+
+
 
 all: $(LIBSA)
 
-BsdDebuggerLocal.o: BsdDebuggerLocal.c
-	$(JAVAH) -jni -classpath ../../../../../build/bsd-i586/hotspot/outputdir/bsd_i486_compiler2/generated/saclasses  \
+MacosxDebuggerLocal.o: MacosxDebuggerLocal.m
+	echo "OS="$(OS)
+	$(JAVAH) -jni -classpath ../../../build/classes  \
 		sun.jvm.hotspot.debugger.x86.X86ThreadContext \
 		sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
+	$(GCC) $(CFLAGS) $(FOUNDATIONFLAGS) $<
+
+sadis.o: ../../share/native/sadis.c
+	$(JAVAH) -jni -classpath ../../../build/classes \
+		sun.jvm.hotspot.asm.Disassembler
 	$(GCC) $(CFLAGS) $<
 
 .c.obj:
@@ -59,9 +85,9 @@
   LFLAGS_LIBSA = -Xlinker --version-script=mapfile
 endif
 
-$(LIBSA): $(OBJS) mapfile
+$(LIBSA): $(OBJSPLUS) mapfile 
 	if [ ! -d $(ARCH) ] ; then mkdir $(ARCH) ; fi
-	$(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(OBJS) $(LIBS)
+	$(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(FOUNDATIONFLAGS) $(OBJSPLUS) $(LIBS) $(SALIBS)
 
 test.o: $(LIBSA) test.c
 	$(GCC) -c -o test.o -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) test.c
@@ -71,7 +97,6 @@
 
 clean:
 	rm -f $(LIBSA)
-	rm -f $(OBJS)
+	rm -f *.o
 	rm -f test.o
 	-rmdir $(ARCH)
-
--- a/agent/src/os/bsd/libproc.h	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/os/bsd/libproc.h	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -27,9 +27,38 @@
 
 #include <unistd.h>
 #include <stdint.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+
+#ifdef __APPLE__
+typedef enum ps_err_e {
+  PS_OK, PS_ERR, PS_BADPID, PS_BADLID,
+  PS_BADADDR, PS_NOSYM, PS_NOFREGS
+} ps_err_e;
+
+#ifndef psaddr_t
+#define psaddr_t uintptr_t
+#endif
+
+#ifndef bool
+typedef int bool;
+#define true  1
+#define false 0
+#endif  // bool
+
+#ifndef lwpid_t
+#define lwpid_t uintptr_t
+#endif
+
+#include <mach/thread_status.h>
+#else   // __APPLE__
+#include <elf.h>
+#include <link.h>
 #include <machine/reg.h>
 #include <proc_service.h>
-
 #if defined(sparc) || defined(sparcv9)
 /*
   If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64
@@ -44,6 +73,14 @@
 
 #endif //sparc or sparcv9
 
+// This C bool type must be int for compatibility with BSD calls and
+// it would be a mistake to equivalence it to C++ bool on many platforms
+typedef int bool;
+#define true  1
+#define false 0
+
+#endif // __APPLE__
+
 /************************************************************************************
 
 0. This is very minimal subset of Solaris libproc just enough for current application.
@@ -72,13 +109,7 @@
 
 *************************************************************************************/
 
-// This C bool type must be int for compatibility with BSD calls and
-// it would be a mistake to equivalence it to C++ bool on many platforms
-
-typedef int bool;
-#define true  1
-#define false 0
-
+struct reg;
 struct ps_prochandle;
 
 // attach to a process
--- a/agent/src/os/bsd/libproc_impl.c	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/os/bsd/libproc_impl.c	Fri Apr 12 10:14:42 2013 +0100
@@ -21,12 +21,6 @@
  * questions.
  *
  */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <thread_db.h>
 #include "libproc_impl.h"
 
 static const char* alt_root = NULL;
@@ -34,61 +28,65 @@
 
 #define SA_ALTROOT "SA_ALTROOT"
 
+off_t ltell(int fd) {
+  return lseek(fd, 0, SEEK_CUR);
+}
+
 static void init_alt_root() {
-   if (alt_root_len == -1) {
-      alt_root = getenv(SA_ALTROOT);
-      if (alt_root) {
-         alt_root_len = strlen(alt_root);
-      } else {
-         alt_root_len = 0;
-      }
-   }
+  if (alt_root_len == -1) {
+    alt_root = getenv(SA_ALTROOT);
+    if (alt_root) {
+      alt_root_len = strlen(alt_root);
+    } else {
+      alt_root_len = 0;
+    }
+  }
 }
 
 int pathmap_open(const char* name) {
-   int fd;
-   char alt_path[PATH_MAX + 1];
+  int fd;
+  char alt_path[PATH_MAX + 1];
+
+  init_alt_root();
 
-   init_alt_root();
-   fd = open(name, O_RDONLY);
-   if (fd >= 0) {
+  if (alt_root_len > 0) {
+    strcpy(alt_path, alt_root);
+    strcat(alt_path, name);
+    fd = open(alt_path, O_RDONLY);
+    if (fd >= 0) {
+      print_debug("path %s substituted for %s\n", alt_path, name);
       return fd;
-   }
+    }
 
-   if (alt_root_len > 0) {
+    if (strrchr(name, '/')) {
       strcpy(alt_path, alt_root);
-      strcat(alt_path, name);
+      strcat(alt_path, strrchr(name, '/'));
       fd = open(alt_path, O_RDONLY);
       if (fd >= 0) {
-         print_debug("path %s substituted for %s\n", alt_path, name);
-         return fd;
+        print_debug("path %s substituted for %s\n", alt_path, name);
+        return fd;
       }
-
-      if (strrchr(name, '/')) {
-         strcpy(alt_path, alt_root);
-         strcat(alt_path, strrchr(name, '/'));
-         fd = open(alt_path, O_RDONLY);
-         if (fd >= 0) {
-            print_debug("path %s substituted for %s\n", alt_path, name);
-            return fd;
-         }
-      }
-   }
-
-   return -1;
+    }
+  } else {
+    fd = open(name, O_RDONLY);
+    if (fd >= 0) {
+      return fd;
+    }
+  }
+  return -1;
 }
 
 static bool _libsaproc_debug;
 
 void print_debug(const char* format,...) {
-   if (_libsaproc_debug) {
-     va_list alist;
+  if (_libsaproc_debug) {
+    va_list alist;
 
-     va_start(alist, format);
-     fputs("libsaproc DEBUG: ", stderr);
-     vfprintf(stderr, format, alist);
-     va_end(alist);
-   }
+    va_start(alist, format);
+    fputs("libsaproc DEBUG: ", stderr);
+    vfprintf(stderr, format, alist);
+    va_end(alist);
+  }
 }
 
 void print_error(const char* format,...) {
@@ -100,172 +98,235 @@
 }
 
 bool is_debug() {
-   return _libsaproc_debug;
+  return _libsaproc_debug;
 }
 
+#ifdef __APPLE__
+// get arch offset in file
+bool get_arch_off(int fd, cpu_type_t cputype, off_t *offset) {
+  struct fat_header fatheader;
+  struct fat_arch fatarch;
+  off_t img_start = 0;
+
+  off_t pos = ltell(fd);
+  if (read(fd, (void *)&fatheader, sizeof(struct fat_header)) != sizeof(struct fat_header)) {
+    return false;
+  }
+  if (fatheader.magic == FAT_CIGAM) {
+    int i;
+    for (i = 0; i < ntohl(fatheader.nfat_arch); i++) {
+      if (read(fd, (void *)&fatarch, sizeof(struct fat_arch)) != sizeof(struct fat_arch)) {
+        return false;
+      }
+      if (ntohl(fatarch.cputype) == cputype) {
+        print_debug("fat offset=%x\n", ntohl(fatarch.offset));
+        img_start = ntohl(fatarch.offset);
+        break;
+      }
+    }
+    if (img_start == 0) {
+      return false;
+    }
+  }
+  lseek(fd, pos, SEEK_SET);
+  *offset = img_start;
+  return true;
+}
+
+bool is_macho_file(int fd) {
+  mach_header_64 fhdr;
+  off_t x86_64_off;
+
+  if (fd < 0) {
+    print_debug("Invalid file handle passed to is_macho_file\n");
+    return false;
+  }
+
+  off_t pos = ltell(fd);
+  // check fat header
+  if (!get_arch_off(fd, CPU_TYPE_X86_64, &x86_64_off)) {
+    print_debug("failed to get fat header\n");
+    return false;
+  }
+  lseek(fd, x86_64_off, SEEK_SET);
+  if (read(fd, (void *)&fhdr, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
+     return false;
+  }
+  lseek(fd, pos, SEEK_SET);               // restore
+  print_debug("fhdr.magic %x\n", fhdr.magic);
+  return (fhdr.magic == MH_MAGIC_64 || fhdr.magic == MH_CIGAM_64);
+}
+
+#endif //__APPLE__
+
 // initialize libproc
 bool init_libproc(bool debug) {
-   // init debug mode
    _libsaproc_debug = debug;
-
+#ifndef __APPLE__
    // initialize the thread_db library
    if (td_init() != TD_OK) {
      print_debug("libthread_db's td_init failed\n");
      return false;
    }
-
+#endif // __APPLE__
    return true;
 }
 
-static void destroy_lib_info(struct ps_prochandle* ph) {
-   lib_info* lib = ph->libs;
-   while (lib) {
-     lib_info *next = lib->next;
-     if (lib->symtab) {
-        destroy_symtab(lib->symtab);
-     }
-     free(lib);
-     lib = next;
-   }
+void destroy_lib_info(struct ps_prochandle* ph) {
+  lib_info* lib = ph->libs;
+  while (lib) {
+    lib_info* next = lib->next;
+    if (lib->symtab) {
+      destroy_symtab(lib->symtab);
+    }
+    free(lib);
+    lib = next;
+  }
 }
 
-static void destroy_thread_info(struct ps_prochandle* ph) {
-   thread_info* thr = ph->threads;
-   while (thr) {
-     thread_info *next = thr->next;
-     free(thr);
-     thr = next;
-   }
+void destroy_thread_info(struct ps_prochandle* ph) {
+  sa_thread_info* thr = ph->threads;
+  while (thr) {
+    sa_thread_info* n = thr->next;
+    free(thr);
+    thr = n;
+  }
 }
 
 // ps_prochandle cleanup
-
-// ps_prochandle cleanup
 void Prelease(struct ps_prochandle* ph) {
-   // do the "derived class" clean-up first
-   ph->ops->release(ph);
-   destroy_lib_info(ph);
-   destroy_thread_info(ph);
-   free(ph);
+  // do the "derived class" clean-up first
+  ph->ops->release(ph);
+  destroy_lib_info(ph);
+  destroy_thread_info(ph);
+  free(ph);
 }
 
 lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base) {
-   return add_lib_info_fd(ph, libname, -1, base);
+  return add_lib_info_fd(ph, libname, -1, base);
 }
 
 lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) {
    lib_info* newlib;
+  print_debug("add_lib_info_fd %s\n", libname);
 
-   if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) {
-      print_debug("can't allocate memory for lib_info\n");
-      return NULL;
-   }
-
-   strncpy(newlib->name, libname, sizeof(newlib->name));
-   newlib->base = base;
+  if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) {
+    print_debug("can't allocate memory for lib_info\n");
+    return NULL;
+  }
 
-   if (fd == -1) {
-      if ( (newlib->fd = pathmap_open(newlib->name)) < 0) {
-         print_debug("can't open shared object %s\n", newlib->name);
-         free(newlib);
-         return NULL;
-      }
-   } else {
-      newlib->fd = fd;
-   }
+  strncpy(newlib->name, libname, sizeof(newlib->name));
+  newlib->base = base;
 
-   // check whether we have got an ELF file. /proc/<pid>/map
-   // gives out all file mappings and not just shared objects
-   if (is_elf_file(newlib->fd) == false) {
-      close(newlib->fd);
+  if (fd == -1) {
+    if ( (newlib->fd = pathmap_open(newlib->name)) < 0) {
+      print_debug("can't open shared object %s\n", newlib->name);
       free(newlib);
       return NULL;
-   }
-
-   newlib->symtab = build_symtab(newlib->fd);
-   if (newlib->symtab == NULL) {
-      print_debug("symbol table build failed for %s\n", newlib->name);
-   }
-   else {
-      print_debug("built symbol table for %s\n", newlib->name);
-   }
+    }
+  } else {
+    newlib->fd = fd;
+  }
 
-   // even if symbol table building fails, we add the lib_info.
-   // This is because we may need to read from the ELF file for core file
-   // address read functionality. lookup_symbol checks for NULL symtab.
-   if (ph->libs) {
-      ph->lib_tail->next = newlib;
-      ph->lib_tail = newlib;
-   }  else {
-      ph->libs = ph->lib_tail = newlib;
-   }
-   ph->num_libs++;
+#ifdef __APPLE__
+  // check whether we have got an Macho file.
+  if (is_macho_file(newlib->fd) == false) {
+    close(newlib->fd);
+    free(newlib);
+    print_debug("not a mach-o file\n");
+    return NULL;
+  }
+#else
+  // check whether we have got an ELF file. /proc/<pid>/map
+  // gives out all file mappings and not just shared objects
+  if (is_elf_file(newlib->fd) == false) {
+    close(newlib->fd);
+    free(newlib);
+    return NULL;
+  }
+#endif // __APPLE__
 
-   return newlib;
+  newlib->symtab = build_symtab(newlib->fd);
+  if (newlib->symtab == NULL) {
+    print_debug("symbol table build failed for %s\n", newlib->name);
+  } else {
+    print_debug("built symbol table for %s\n", newlib->name);
+  }
+
+  // even if symbol table building fails, we add the lib_info.
+  // This is because we may need to read from the ELF file or MachO file for core file
+  // address read functionality. lookup_symbol checks for NULL symtab.
+  if (ph->libs) {
+    ph->lib_tail->next = newlib;
+    ph->lib_tail = newlib;
+  }  else {
+    ph->libs = ph->lib_tail = newlib;
+  }
+  ph->num_libs++;
+  return newlib;
 }
 
 // lookup for a specific symbol
 uintptr_t lookup_symbol(struct ps_prochandle* ph,  const char* object_name,
                        const char* sym_name) {
-   // ignore object_name. search in all libraries
-   // FIXME: what should we do with object_name?? The library names are obtained
-   // by parsing /proc/<pid>/maps, which may not be the same as object_name.
-   // What we need is a utility to map object_name to real file name, something
-   // dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For
-   // now, we just ignore object_name and do a global search for the symbol.
+  // ignore object_name. search in all libraries
+  // FIXME: what should we do with object_name?? The library names are obtained
+  // by parsing /proc/<pid>/maps, which may not be the same as object_name.
+  // What we need is a utility to map object_name to real file name, something
+  // dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For
+  // now, we just ignore object_name and do a global search for the symbol.
 
-   lib_info* lib = ph->libs;
-   while (lib) {
-      if (lib->symtab) {
-         uintptr_t res = search_symbol(lib->symtab, lib->base, sym_name, NULL);
-         if (res) return res;
-      }
-      lib = lib->next;
-   }
+  lib_info* lib = ph->libs;
+  while (lib) {
+    if (lib->symtab) {
+      uintptr_t res = search_symbol(lib->symtab, lib->base, sym_name, NULL);
+      if (res) return res;
+    }
+    lib = lib->next;
+  }
 
-   print_debug("lookup failed for symbol '%s' in obj '%s'\n",
+  print_debug("lookup failed for symbol '%s' in obj '%s'\n",
                           sym_name, object_name);
-   return (uintptr_t) NULL;
+  return (uintptr_t) NULL;
 }
 
-
 const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset) {
-   const char* res = NULL;
-   lib_info* lib = ph->libs;
-   while (lib) {
-      if (lib->symtab && addr >= lib->base) {
-         res = nearest_symbol(lib->symtab, addr - lib->base, poffset);
-         if (res) return res;
-      }
-      lib = lib->next;
-   }
-   return NULL;
+  const char* res = NULL;
+  lib_info* lib = ph->libs;
+  while (lib) {
+    if (lib->symtab && addr >= lib->base) {
+      res = nearest_symbol(lib->symtab, addr - lib->base, poffset);
+      if (res) return res;
+    }
+    lib = lib->next;
+  }
+  return NULL;
 }
 
 // add a thread to ps_prochandle
-thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
-   thread_info* newthr;
-   if ( (newthr = (thread_info*) calloc(1, sizeof(thread_info))) == NULL) {
-      print_debug("can't allocate memory for thread_info\n");
-      return NULL;
-   }
+sa_thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
+  sa_thread_info* newthr;
+  if ( (newthr = (sa_thread_info*) calloc(1, sizeof(sa_thread_info))) == NULL) {
+    print_debug("can't allocate memory for thread_info\n");
+    return NULL;
+  }
 
-   // initialize thread info
-   newthr->pthread_id = pthread_id;
-   newthr->lwp_id = lwp_id;
+  // initialize thread info
+  newthr->pthread_id = pthread_id;
+  newthr->lwp_id = lwp_id;
 
-   // add new thread to the list
-   newthr->next = ph->threads;
-   ph->threads = newthr;
-   ph->num_threads++;
-   return newthr;
+  // add new thread to the list
+  newthr->next = ph->threads;
+  ph->threads = newthr;
+  ph->num_threads++;
+  return newthr;
 }
 
-
+#ifndef __APPLE__
 // struct used for client data from thread_db callback
 struct thread_db_client_data {
-   struct ps_prochandle* ph;
-   thread_info_callback callback;
+  struct ps_prochandle* ph;
+  thread_info_callback callback;
 };
 
 // callback function for libthread_db
@@ -314,6 +375,7 @@
   return true;
 }
 
+#endif // __APPLE__
 
 // get number of threads
 int get_num_threads(struct ps_prochandle* ph) {
@@ -322,18 +384,54 @@
 
 // get lwp_id of n'th thread
 lwpid_t get_lwp_id(struct ps_prochandle* ph, int index) {
-   int count = 0;
-   thread_info* thr = ph->threads;
-   while (thr) {
-      if (count == index) {
-         return thr->lwp_id;
-      }
-      count++;
-      thr = thr->next;
-   }
-   return -1;
+  int count = 0;
+  sa_thread_info* thr = ph->threads;
+  while (thr) {
+    if (count == index) {
+      return thr->lwp_id;
+    }
+    count++;
+    thr = thr->next;
+  }
+  return 0;
 }
 
+#ifdef __APPLE__
+// set lwp_id of n'th thread
+bool set_lwp_id(struct ps_prochandle* ph, int index, lwpid_t lwpid) {
+  int count = 0;
+  sa_thread_info* thr = ph->threads;
+  while (thr) {
+    if (count == index) {
+      thr->lwp_id = lwpid;
+      return true;
+    }
+    count++;
+    thr = thr->next;
+  }
+  return false;
+}
+
+// get regs of n-th thread, only used in fillThreads the first time called
+bool get_nth_lwp_regs(struct ps_prochandle* ph, int index, struct reg* regs) {
+  int count = 0;
+  sa_thread_info* thr = ph->threads;
+  while (thr) {
+    if (count == index) {
+      break;
+    }
+    count++;
+    thr = thr->next;
+  }
+  if (thr != NULL) {
+    memcpy(regs, &thr->regs, sizeof(struct reg));
+    return true;
+  }
+  return false;
+}
+
+#endif // __APPLE__
+
 // get regs for a given lwp
 bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs) {
   return ph->ops->get_lwp_regs(ph, lwp_id, regs);
@@ -341,35 +439,35 @@
 
 // get number of shared objects
 int get_num_libs(struct ps_prochandle* ph) {
-   return ph->num_libs;
+  return ph->num_libs;
 }
 
 // get name of n'th solib
 const char* get_lib_name(struct ps_prochandle* ph, int index) {
-   int count = 0;
-   lib_info* lib = ph->libs;
-   while (lib) {
-      if (count == index) {
-         return lib->name;
-      }
-      count++;
-      lib = lib->next;
-   }
-   return NULL;
+  int count = 0;
+  lib_info* lib = ph->libs;
+  while (lib) {
+    if (count == index) {
+      return lib->name;
+    }
+    count++;
+    lib = lib->next;
+  }
+  return NULL;
 }
 
 // get base address of a lib
 uintptr_t get_lib_base(struct ps_prochandle* ph, int index) {
-   int count = 0;
-   lib_info* lib = ph->libs;
-   while (lib) {
-      if (count == index) {
-         return lib->base;
-      }
-      count++;
-      lib = lib->next;
-   }
-   return (uintptr_t)NULL;
+  int count = 0;
+  lib_info* lib = ph->libs;
+  while (lib) {
+    if (count == index) {
+      return lib->base;
+    }
+    count++;
+    lib = lib->next;
+  }
+  return (uintptr_t)NULL;
 }
 
 bool find_lib(struct ps_prochandle* ph, const char *lib_name) {
@@ -425,6 +523,7 @@
   va_end(alist);
 }
 
+#ifndef __APPLE__
 // ------------------------------------------------------------------------
 // Functions below this point are not yet implemented. They are here only
 // to make the linker happy.
@@ -458,3 +557,4 @@
   print_debug("ps_pcontinue not implemented\n");
   return PS_OK;
 }
+#endif // __APPLE__
--- a/agent/src/os/bsd/libproc_impl.h	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/os/bsd/libproc_impl.h	Fri Apr 12 10:14:42 2013 +0100
@@ -30,6 +30,60 @@
 #include "libproc.h"
 #include "symtab.h"
 
+#ifdef __APPLE__
+#include <inttypes.h>     // for PRIx64, 32, ...
+#include <pthread.h>
+#include <mach-o/loader.h>
+#include <mach-o/nlist.h>
+#include <mach-o/fat.h>
+
+#ifndef register_t
+#define register_t uint64_t
+#endif
+
+/*** registers copied from bsd/amd64 */
+typedef struct reg {
+  register_t      r_r15;
+  register_t      r_r14;
+  register_t      r_r13;
+  register_t      r_r12;
+  register_t      r_r11;
+  register_t      r_r10;
+  register_t      r_r9;
+  register_t      r_r8;
+  register_t      r_rdi;
+  register_t      r_rsi;
+  register_t      r_rbp;
+  register_t      r_rbx;
+  register_t      r_rdx;
+  register_t      r_rcx;
+  register_t      r_rax;
+  uint32_t        r_trapno;      // not used
+  uint16_t        r_fs;
+  uint16_t        r_gs;
+  uint32_t        r_err;         // not used
+  uint16_t        r_es;          // not used
+  uint16_t        r_ds;          // not used
+  register_t      r_rip;
+  register_t      r_cs;
+  register_t      r_rflags;
+  register_t      r_rsp;
+  register_t      r_ss;          // not used
+} reg;
+
+// convenient defs
+typedef struct mach_header_64 mach_header_64;
+typedef struct load_command load_command;
+typedef struct segment_command_64 segment_command_64;
+typedef struct thread_command thread_command;
+typedef struct dylib_command dylib_command;
+typedef struct symtab_command symtab_command;
+typedef struct nlist_64 nlist_64;
+#else
+#include <thread_db.h>
+#include "salibelf.h"
+#endif //  __APPLE__
+
 // data structures in this file mimic those of Solaris 8.0 - libproc's Pcontrol.h
 
 #define BUF_SIZE     (PATH_MAX + NAME_MAX + 1)
@@ -44,12 +98,12 @@
 } lib_info;
 
 // list of threads
-typedef struct thread_info {
-   lwpid_t                  lwp_id;
-   pthread_t                pthread_id; // not used cores, always -1
+typedef struct sa_thread_info {
+   lwpid_t                  lwp_id;     // same as pthread_t
+   pthread_t                pthread_id; //
    struct reg               regs;       // not for process, core uses for caching regset
-   struct thread_info*      next;
-} thread_info;
+   struct sa_thread_info*   next;
+} sa_thread_info;
 
 // list of virtual memory maps
 typedef struct map_info {
@@ -91,6 +145,7 @@
    // part of the class sharing workaround
    map_info*          class_share_maps;// class share maps in a linked list
    map_info**         map_array; // sorted (by vaddr) array of map_info pointers
+   char               exec_path[4096];  // file name java
 };
 
 struct ps_prochandle {
@@ -100,12 +155,11 @@
    lib_info*          libs;      // head of lib list
    lib_info*          lib_tail;  // tail of lib list - to append at the end
    int                num_threads;
-   thread_info*       threads;   // head of thread list
+   sa_thread_info*    threads;   // head of thread list
    struct core_data*  core;      // data only used for core dumps, NULL for process
 };
 
 int pathmap_open(const char* name);
-
 void print_debug(const char* format,...);
 void print_error(const char* format,...);
 bool is_debug();
@@ -122,10 +176,45 @@
 lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd,
                           uintptr_t base);
 
-// adds a new thread to threads list, returns NULL on failure
-thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id);
-
+sa_thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id);
 // a test for ELF signature without using libelf
+
+#ifdef __APPLE__
+// a test for Mach-O signature
+bool is_macho_file(int fd);
+// skip fat head to get image start offset of cpu_type_t
+// return false if any error happens, else value in offset.
+bool get_arch_off(int fd, cpu_type_t cputype, off_t *offset);
+#else
 bool is_elf_file(int fd);
+#endif // __APPLE__
+
+lwpid_t get_lwp_id(struct ps_prochandle* ph, int index);
+bool set_lwp_id(struct ps_prochandle* ph, int index, lwpid_t lwpid);
+bool get_nth_lwp_regs(struct ps_prochandle* ph, int index, struct reg* regs);
+
+// ps_pglobal_lookup() looks up the symbol sym_name in the symbol table
+// of the load object object_name in the target process identified by ph.
+// It returns the symbol's value as an address in the target process in
+// *sym_addr.
 
+ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
+                    const char *sym_name, psaddr_t *sym_addr);
+
+// read "size" bytes info "buf" from address "addr"
+ps_err_e ps_pread(struct ps_prochandle *ph, psaddr_t  addr,
+                  void *buf, size_t size);
+
+// write "size" bytes of data to debuggee at address "addr"
+ps_err_e ps_pwrite(struct ps_prochandle *ph, psaddr_t addr,
+                   const void *buf, size_t size);
+
+// fill in ptrace_lwpinfo for lid
+ps_err_e ps_linfo(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo);
+
+// needed for when libthread_db is compiled with TD_DEBUG defined
+void ps_plog (const char *format, ...);
+
+// untility, tells the position in file
+off_t ltell(int fd);
 #endif //_LIBPROC_IMPL_H_
--- a/agent/src/os/bsd/ps_core.c	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/os/bsd/ps_core.c	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -28,10 +28,11 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stddef.h>
-#include <elf.h>
-#include <link.h>
 #include "libproc_impl.h"
-#include "salibelf.h"
+
+#ifdef __APPLE__
+#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
+#endif
 
 // This file has the libproc implementation to read core files.
 // For live processes, refer to ps_proc.c. Portions of this is adapted
@@ -41,156 +42,158 @@
 // ps_prochandle cleanup helper functions
 
 // close all file descriptors
-static void close_elf_files(struct ps_prochandle* ph) {
-   lib_info* lib = NULL;
+static void close_files(struct ps_prochandle* ph) {
+  lib_info* lib = NULL;
+  // close core file descriptor
+  if (ph->core->core_fd >= 0)
+    close(ph->core->core_fd);
 
-   // close core file descriptor
-   if (ph->core->core_fd >= 0)
-     close(ph->core->core_fd);
+  // close exec file descriptor
+  if (ph->core->exec_fd >= 0)
+    close(ph->core->exec_fd);
 
-   // close exec file descriptor
-   if (ph->core->exec_fd >= 0)
-     close(ph->core->exec_fd);
+  // close interp file descriptor
+  if (ph->core->interp_fd >= 0)
+    close(ph->core->interp_fd);
 
-   // close interp file descriptor
-   if (ph->core->interp_fd >= 0)
-     close(ph->core->interp_fd);
-
-   // close class share archive file
-   if (ph->core->classes_jsa_fd >= 0)
-     close(ph->core->classes_jsa_fd);
+  // close class share archive file
+  if (ph->core->classes_jsa_fd >= 0)
+    close(ph->core->classes_jsa_fd);
 
-   // close all library file descriptors
-   lib = ph->libs;
-   while (lib) {
-      int fd = lib->fd;
-      if (fd >= 0 && fd != ph->core->exec_fd) close(fd);
-      lib = lib->next;
-   }
+  // close all library file descriptors
+  lib = ph->libs;
+  while (lib) {
+    int fd = lib->fd;
+    if (fd >= 0 && fd != ph->core->exec_fd) {
+      close(fd);
+    }
+    lib = lib->next;
+  }
 }
 
 // clean all map_info stuff
 static void destroy_map_info(struct ps_prochandle* ph) {
   map_info* map = ph->core->maps;
   while (map) {
-     map_info* next = map->next;
-     free(map);
-     map = next;
+    map_info* next = map->next;
+    free(map);
+    map = next;
   }
 
   if (ph->core->map_array) {
-     free(ph->core->map_array);
+    free(ph->core->map_array);
   }
 
   // Part of the class sharing workaround
   map = ph->core->class_share_maps;
   while (map) {
-     map_info* next = map->next;
-     free(map);
-     map = next;
+    map_info* next = map->next;
+    free(map);
+    map = next;
   }
 }
 
 // ps_prochandle operations
 static void core_release(struct ps_prochandle* ph) {
-   if (ph->core) {
-      close_elf_files(ph);
-      destroy_map_info(ph);
-      free(ph->core);
-   }
+  if (ph->core) {
+    close_files(ph);
+    destroy_map_info(ph);
+    free(ph->core);
+  }
 }
 
 static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
-   map_info* map;
-   if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
-      print_debug("can't allocate memory for map_info\n");
-      return NULL;
-   }
+  map_info* map;
+  if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
+    print_debug("can't allocate memory for map_info\n");
+    return NULL;
+  }
 
-   // initialize map
-   map->fd     = fd;
-   map->offset = offset;
-   map->vaddr  = vaddr;
-   map->memsz  = memsz;
-   return map;
+  // initialize map
+  map->fd     = fd;
+  map->offset = offset;
+  map->vaddr  = vaddr;
+  map->memsz  = memsz;
+  return map;
 }
 
 // add map info with given fd, offset, vaddr and memsz
 static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
                              uintptr_t vaddr, size_t memsz) {
-   map_info* map;
-   if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
-      return NULL;
-   }
+  map_info* map;
+  if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
+    return NULL;
+  }
 
-   // add this to map list
-   map->next  = ph->core->maps;
-   ph->core->maps   = map;
-   ph->core->num_maps++;
+  // add this to map list
+  map->next  = ph->core->maps;
+  ph->core->maps   = map;
+  ph->core->num_maps++;
 
-   return map;
+  return map;
 }
 
 // Part of the class sharing workaround
 static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
                              uintptr_t vaddr, size_t memsz) {
-   map_info* map;
-   if ((map = allocate_init_map(ph->core->classes_jsa_fd,
-                                offset, vaddr, memsz)) == NULL) {
-      return NULL;
-   }
+  map_info* map;
+  if ((map = allocate_init_map(ph->core->classes_jsa_fd,
+                               offset, vaddr, memsz)) == NULL) {
+    return NULL;
+  }
 
-   map->next = ph->core->class_share_maps;
-   ph->core->class_share_maps = map;
-   return map;
+  map->next = ph->core->class_share_maps;
+  ph->core->class_share_maps = map;
+  return map;
 }
 
 // Return the map_info for the given virtual address.  We keep a sorted
 // array of pointers in ph->map_array, so we can binary search.
 static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
 {
-   int mid, lo = 0, hi = ph->core->num_maps - 1;
-   map_info *mp;
+  int mid, lo = 0, hi = ph->core->num_maps - 1;
+  map_info *mp;
 
-   while (hi - lo > 1) {
-     mid = (lo + hi) / 2;
-      if (addr >= ph->core->map_array[mid]->vaddr)
-         lo = mid;
-      else
-         hi = mid;
-   }
+  while (hi - lo > 1) {
+    mid = (lo + hi) / 2;
+    if (addr >= ph->core->map_array[mid]->vaddr) {
+      lo = mid;
+    } else {
+      hi = mid;
+    }
+  }
 
-   if (addr < ph->core->map_array[hi]->vaddr)
-      mp = ph->core->map_array[lo];
-   else
-      mp = ph->core->map_array[hi];
+  if (addr < ph->core->map_array[hi]->vaddr) {
+    mp = ph->core->map_array[lo];
+  } else {
+    mp = ph->core->map_array[hi];
+  }
 
-   if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz)
-      return (mp);
+  if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
+    return (mp);
+  }
 
 
-   // Part of the class sharing workaround
-   // Unfortunately, we have no way of detecting -Xshare state.
-   // Check out the share maps atlast, if we don't find anywhere.
-   // This is done this way so to avoid reading share pages
-   // ahead of other normal maps. For eg. with -Xshare:off we don't
-   // want to prefer class sharing data to data from core.
-   mp = ph->core->class_share_maps;
-   if (mp) {
-      print_debug("can't locate map_info at 0x%lx, trying class share maps\n",
-             addr);
-   }
-   while (mp) {
-      if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
-         print_debug("located map_info at 0x%lx from class share maps\n",
-                  addr);
-         return (mp);
-      }
-      mp = mp->next;
-   }
+  // Part of the class sharing workaround
+  // Unfortunately, we have no way of detecting -Xshare state.
+  // Check out the share maps atlast, if we don't find anywhere.
+  // This is done this way so to avoid reading share pages
+  // ahead of other normal maps. For eg. with -Xshare:off we don't
+  // want to prefer class sharing data to data from core.
+  mp = ph->core->class_share_maps;
+  if (mp) {
+    print_debug("can't locate map_info at 0x%lx, trying class share maps\n", addr);
+  }
+  while (mp) {
+    if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
+      print_debug("located map_info at 0x%lx from class share maps\n", addr);
+      return (mp);
+    }
+    mp = mp->next;
+  }
 
-   print_debug("can't locate map_info at 0x%lx\n", addr);
-   return (NULL);
+  print_debug("can't locate map_info at 0x%lx\n", addr);
+  return (NULL);
 }
 
 //---------------------------------------------------------------
@@ -239,157 +242,171 @@
 };
 
 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
-   jboolean i;
-   if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
-      *pvalue = i;
-      return true;
-   } else {
-      return false;
-   }
+  jboolean i;
+  if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
+    *pvalue = i;
+    return true;
+  } else {
+    return false;
+  }
 }
 
 static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
-   uintptr_t uip;
-   if (ps_pread(ph, (psaddr_t) addr, &uip, sizeof(uip)) == PS_OK) {
-      *pvalue = uip;
-      return true;
-   } else {
-      return false;
-   }
+  uintptr_t uip;
+  if (ps_pread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
+    *pvalue = uip;
+    return true;
+  } else {
+    return false;
+  }
 }
 
 // used to read strings from debuggee
 static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
-   size_t i = 0;
-   char  c = ' ';
+  size_t i = 0;
+  char  c = ' ';
 
-   while (c != '\0') {
-     if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK)
-         return false;
-      if (i < size - 1)
-         buf[i] = c;
-      else // smaller buffer
-         return false;
-      i++; addr++;
-   }
-
-   buf[i] = '\0';
-   return true;
+  while (c != '\0') {
+    if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK) {
+      return false;
+    }
+    if (i < size - 1) {
+      buf[i] = c;
+    } else {
+      // smaller buffer
+      return false;
+    }
+    i++; addr++;
+  }
+  buf[i] = '\0';
+  return true;
 }
 
+#ifdef __APPLE__
+#define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
+// mangled name of Arguments::SharedArchivePath
+#define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
+#else
 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
 // mangled name of Arguments::SharedArchivePath
-#define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
+#define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
+#endif // __APPLE_
 
 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
-   lib_info* lib = ph->libs;
-   while (lib != NULL) {
-      // we are iterating over shared objects from the core dump. look for
-      // libjvm[_g].so.
-      const char *jvm_name = 0;
-      if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
-          (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0) {
-         char classes_jsa[PATH_MAX];
-         struct FileMapHeader header;
-         size_t n = 0;
-         int fd = -1, m = 0;
-         uintptr_t base = 0, useSharedSpacesAddr = 0;
-         uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
-         jboolean useSharedSpaces = 0;
-
-         memset(classes_jsa, 0, sizeof(classes_jsa));
-         jvm_name = lib->name;
-         useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
-         if (useSharedSpacesAddr == 0) {
-            print_debug("can't lookup 'UseSharedSpaces' flag\n");
-            return false;
-         }
+  int m;
+  size_t n;
+  lib_info* lib = ph->libs;
+  while (lib != NULL) {
+    // we are iterating over shared objects from the core dump. look for
+    // libjvm[_g].so.
+    const char *jvm_name = 0;
+#ifdef __APPLE__
+    if ((jvm_name = strstr(lib->name, "/libjvm.dylib")) != 0 ||
+        (jvm_name = strstr(lib->name, "/libjvm_g.dylib")) != 0)
+#else
+    if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
+        (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0)
+#endif // __APPLE__
+    {
+      char classes_jsa[PATH_MAX];
+      struct FileMapHeader header;
+      int fd = -1;
+      uintptr_t base = 0, useSharedSpacesAddr = 0;
+      uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
+      jboolean useSharedSpaces = 0;
 
-         // Hotspot vm types are not exported to build this library. So
-         // using equivalent type jboolean to read the value of
-         // UseSharedSpaces which is same as hotspot type "bool".
-         if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
-            print_debug("can't read the value of 'UseSharedSpaces' flag\n");
-            return false;
-         }
+      memset(classes_jsa, 0, sizeof(classes_jsa));
+      jvm_name = lib->name;
+      useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
+      if (useSharedSpacesAddr == 0) {
+        print_debug("can't lookup 'UseSharedSpaces' flag\n");
+        return false;
+      }
 
-         if ((int)useSharedSpaces == 0) {
-            print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
-            return true;
-         }
+      // Hotspot vm types are not exported to build this library. So
+      // using equivalent type jboolean to read the value of
+      // UseSharedSpaces which is same as hotspot type "bool".
+      if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
+        print_debug("can't read the value of 'UseSharedSpaces' flag\n");
+        return false;
+      }
 
-         sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
-         if (sharedArchivePathAddrAddr == 0) {
-            print_debug("can't lookup shared archive path symbol\n");
-            return false;
-         }
+      if ((int)useSharedSpaces == 0) {
+        print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
+        return true;
+      }
 
-         if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
-            print_debug("can't read shared archive path pointer\n");
-            return false;
-         }
+      sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
+      if (sharedArchivePathAddrAddr == 0) {
+        print_debug("can't lookup shared archive path symbol\n");
+        return false;
+      }
 
-         if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
-            print_debug("can't read shared archive path value\n");
-            return false;
-         }
+      if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
+        print_debug("can't read shared archive path pointer\n");
+        return false;
+      }
 
-         print_debug("looking for %s\n", classes_jsa);
-         // open the class sharing archive file
-         fd = pathmap_open(classes_jsa);
-         if (fd < 0) {
-            print_debug("can't open %s!\n", classes_jsa);
-            ph->core->classes_jsa_fd = -1;
-            return false;
-         } else {
-            print_debug("opened %s\n", classes_jsa);
-         }
+      if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
+        print_debug("can't read shared archive path value\n");
+        return false;
+      }
 
-         // read FileMapHeader from the file
-         memset(&header, 0, sizeof(struct FileMapHeader));
-         if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
-              != sizeof(struct FileMapHeader)) {
-            print_debug("can't read shared archive file map header from %s\n", classes_jsa);
-            close(fd);
-            return false;
-         }
+      print_debug("looking for %s\n", classes_jsa);
+      // open the class sharing archive file
+      fd = pathmap_open(classes_jsa);
+      if (fd < 0) {
+        print_debug("can't open %s!\n", classes_jsa);
+        ph->core->classes_jsa_fd = -1;
+        return false;
+      } else {
+        print_debug("opened %s\n", classes_jsa);
+      }
 
-         // check file magic
-         if (header._magic != 0xf00baba2) {
-            print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
-                        classes_jsa, header._magic);
-            close(fd);
-            return false;
-         }
+      // read FileMapHeader from the file
+      memset(&header, 0, sizeof(struct FileMapHeader));
+      if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
+           != sizeof(struct FileMapHeader)) {
+        print_debug("can't read shared archive file map header from %s\n", classes_jsa);
+        close(fd);
+        return false;
+      }
 
-         // check version
-         if (header._version != CURRENT_ARCHIVE_VERSION) {
-            print_debug("%s has wrong shared archive file version %d, expecting %d\n",
-                        classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
-            close(fd);
-            return false;
-         }
+      // check file magic
+      if (header._magic != 0xf00baba2) {
+        print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
+                     classes_jsa, header._magic);
+        close(fd);
+        return false;
+      }
+
+      // check version
+      if (header._version != CURRENT_ARCHIVE_VERSION) {
+        print_debug("%s has wrong shared archive file version %d, expecting %d\n",
+                     classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
+        close(fd);
+        return false;
+      }
 
-         ph->core->classes_jsa_fd = fd;
-         // add read-only maps from classes[_g].jsa to the list of maps
-         for (m = 0; m < NUM_SHARED_MAPS; m++) {
-            if (header._space[m]._read_only) {
-               base = (uintptr_t) header._space[m]._base;
-               // no need to worry about the fractional pages at-the-end.
-               // possible fractional pages are handled by core_read_data.
-               add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
-                         base, (size_t) header._space[m]._used);
-               print_debug("added a share archive map at 0x%lx\n", base);
-            }
-         }
-         return true;
+      ph->core->classes_jsa_fd = fd;
+      // add read-only maps from classes[_g].jsa to the list of maps
+      for (m = 0; m < NUM_SHARED_MAPS; m++) {
+        if (header._space[m]._read_only) {
+          base = (uintptr_t) header._space[m]._base;
+          // no need to worry about the fractional pages at-the-end.
+          // possible fractional pages are handled by core_read_data.
+          add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
+                                   base, (size_t) header._space[m]._used);
+          print_debug("added a share archive map at 0x%lx\n", base);
+        }
       }
-      lib = lib->next;
-   }
-   return true;
+      return true;
+    }
+    lib = lib->next;
+  }
+  return true;
 }
 
-
 //---------------------------------------------------------------------------
 // functions to handle map_info
 
@@ -397,54 +414,57 @@
 // callback for sorting the array of map_info pointers.
 static int core_cmp_mapping(const void *lhsp, const void *rhsp)
 {
-   const map_info *lhs = *((const map_info **)lhsp);
-   const map_info *rhs = *((const map_info **)rhsp);
+  const map_info *lhs = *((const map_info **)lhsp);
+  const map_info *rhs = *((const map_info **)rhsp);
 
-   if (lhs->vaddr == rhs->vaddr)
-      return (0);
+  if (lhs->vaddr == rhs->vaddr) {
+    return (0);
+  }
 
-   return (lhs->vaddr < rhs->vaddr ? -1 : 1);
+  return (lhs->vaddr < rhs->vaddr ? -1 : 1);
 }
 
 // we sort map_info by starting virtual address so that we can do
 // binary search to read from an address.
 static bool sort_map_array(struct ps_prochandle* ph) {
-   size_t num_maps = ph->core->num_maps;
-   map_info* map = ph->core->maps;
-   int i = 0;
+  size_t num_maps = ph->core->num_maps;
+  map_info* map = ph->core->maps;
+  int i = 0;
 
-   // allocate map_array
-   map_info** array;
-   if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
-      print_debug("can't allocate memory for map array\n");
-      return false;
-   }
+  // allocate map_array
+  map_info** array;
+  if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
+     print_debug("can't allocate memory for map array\n");
+     return false;
+  }
 
-   // add maps to array
-   while (map) {
-      array[i] = map;
-      i++;
-      map = map->next;
-   }
+  // add maps to array
+  while (map) {
+    array[i] = map;
+    i++;
+    map = map->next;
+  }
 
-   // sort is called twice. If this is second time, clear map array
-   if (ph->core->map_array) free(ph->core->map_array);
-   ph->core->map_array = array;
-   // sort the map_info array by base virtual address.
-   qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
-            core_cmp_mapping);
+  // sort is called twice. If this is second time, clear map array
+  if (ph->core->map_array) {
+    free(ph->core->map_array);
+  }
+  ph->core->map_array = array;
+  // sort the map_info array by base virtual address.
+  qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
+           core_cmp_mapping);
 
-   // print map
-   if (is_debug()) {
-      int j = 0;
-      print_debug("---- sorted virtual address map ----\n");
-      for (j = 0; j < ph->core->num_maps; j++) {
-        print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
-                                         ph->core->map_array[j]->memsz);
-      }
-   }
+  // print map
+  if (is_debug()) {
+    int j = 0;
+    print_debug("---- sorted virtual address map ----\n");
+    for (j = 0; j < ph->core->num_maps; j++) {
+      print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
+                                       ph->core->map_array[j]->memsz);
+    }
+  }
 
-   return true;
+  return true;
 }
 
 #ifndef MIN
@@ -461,16 +481,18 @@
       off_t off;
       int fd;
 
-      if (mp == NULL)
+      if (mp == NULL) {
          break;  /* No mapping for this address */
+      }
 
       fd = mp->fd;
       mapoff = addr - mp->vaddr;
       len = MIN(resid, mp->memsz - mapoff);
       off = mp->offset + mapoff;
 
-      if ((len = pread(fd, buf, len, off)) <= 0)
+      if ((len = pread(fd, buf, len, off)) <= 0) {
          break;
+      }
 
       resid -= len;
       addr += len;
@@ -507,8 +529,8 @@
 
 static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
                           struct reg* regs) {
-   // for core we have cached the lwp regs from NOTE section
-   thread_info* thr = ph->threads;
+   // for core we have cached the lwp regs after segment parsed
+   sa_thread_info* thr = ph->threads;
    while (thr) {
      if (thr->lwp_id == lwp_id) {
        memcpy(regs, &thr->regs, sizeof(struct reg));
@@ -519,7 +541,7 @@
    return false;
 }
 
-static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
+static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t id, void *info) {
    print_debug("core_get_lwp_info not implemented\n");
    return false;
 }
@@ -532,12 +554,451 @@
    .get_lwp_info= core_get_lwp_info
 };
 
-// read regs and create thread from NT_PRSTATUS entries from core file
+// from this point, mainly two blocks divided by def __APPLE__
+// one for Macosx, the other for regular Bsd
+
+#ifdef __APPLE__
+
+void print_thread(sa_thread_info *threadinfo) {
+  print_debug("thread added: %d\n", threadinfo->lwp_id);
+  print_debug("registers:\n");
+  print_debug("  r_r15: 0x%" PRIx64 "\n", threadinfo->regs.r_r15);
+  print_debug("  r_r14: 0x%" PRIx64 "\n", threadinfo->regs.r_r14);
+  print_debug("  r_r13: 0x%" PRIx64 "\n", threadinfo->regs.r_r13);
+  print_debug("  r_r12: 0x%" PRIx64 "\n", threadinfo->regs.r_r12);
+  print_debug("  r_r11: 0x%" PRIx64 "\n", threadinfo->regs.r_r11);
+  print_debug("  r_r10: 0x%" PRIx64 "\n", threadinfo->regs.r_r10);
+  print_debug("  r_r9:  0x%" PRIx64 "\n", threadinfo->regs.r_r9);
+  print_debug("  r_r8:  0x%" PRIx64 "\n", threadinfo->regs.r_r8);
+  print_debug("  r_rdi: 0x%" PRIx64 "\n", threadinfo->regs.r_rdi);
+  print_debug("  r_rsi: 0x%" PRIx64 "\n", threadinfo->regs.r_rsi);
+  print_debug("  r_rbp: 0x%" PRIx64 "\n", threadinfo->regs.r_rbp);
+  print_debug("  r_rbx: 0x%" PRIx64 "\n", threadinfo->regs.r_rbx);
+  print_debug("  r_rdx: 0x%" PRIx64 "\n", threadinfo->regs.r_rdx);
+  print_debug("  r_rcx: 0x%" PRIx64 "\n", threadinfo->regs.r_rcx);
+  print_debug("  r_rax: 0x%" PRIx64 "\n", threadinfo->regs.r_rax);
+  print_debug("  r_fs:  0x%" PRIx32 "\n", threadinfo->regs.r_fs);
+  print_debug("  r_gs:  0x%" PRIx32 "\n", threadinfo->regs.r_gs);
+  print_debug("  r_rip  0x%" PRIx64 "\n", threadinfo->regs.r_rip);
+  print_debug("  r_cs:  0x%" PRIx64 "\n", threadinfo->regs.r_cs);
+  print_debug("  r_rsp: 0x%" PRIx64 "\n", threadinfo->regs.r_rsp);
+  print_debug("  r_rflags: 0x%" PRIx64 "\n", threadinfo->regs.r_rflags);
+}
+
+// read all segments64 commands from core file
+// read all thread commands from core file
+static bool read_core_segments(struct ps_prochandle* ph) {
+  int i = 0;
+  int num_threads = 0;
+  int fd = ph->core->core_fd;
+  off_t offset = 0;
+  mach_header_64      fhead;
+  load_command        lcmd;
+  segment_command_64  segcmd;
+  // thread_command      thrcmd;
+
+  lseek(fd, offset, SEEK_SET);
+  if(read(fd, (void *)&fhead, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
+     goto err;
+  }
+  print_debug("total commands: %d\n", fhead.ncmds);
+  offset += sizeof(mach_header_64);
+  for (i = 0; i < fhead.ncmds; i++) {
+    lseek(fd, offset, SEEK_SET);
+    if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) {
+      goto err;
+    }
+    offset += lcmd.cmdsize;    // next command position
+    if (lcmd.cmd == LC_SEGMENT_64) {
+      lseek(fd, -sizeof(load_command), SEEK_CUR);
+      if (read(fd, (void *)&segcmd, sizeof(segment_command_64)) != sizeof(segment_command_64)) {
+        print_debug("failed to read LC_SEGMENT_64 i = %d!\n", i);
+        goto err;
+      }
+      if (add_map_info(ph, fd, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize) == NULL) {
+        print_debug("Failed to add map_info at i = %d\n", i);
+        goto err;
+      }
+      print_debug("segment added: %" PRIu64 " 0x%" PRIx64 " %d\n",
+                   segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize);
+    } else if (lcmd.cmd == LC_THREAD || lcmd.cmd == LC_UNIXTHREAD) {
+      typedef struct thread_fc {
+        uint32_t  flavor;
+        uint32_t  count;
+      } thread_fc;
+      thread_fc fc;
+      uint32_t size = sizeof(load_command);
+      while (size < lcmd.cmdsize) {
+        if (read(fd, (void *)&fc, sizeof(thread_fc)) != sizeof(thread_fc)) {
+          printf("Reading flavor, count failed.\n");
+          goto err;
+        }
+        size += sizeof(thread_fc);
+        if (fc.flavor == x86_THREAD_STATE) {
+          x86_thread_state_t thrstate;
+          if (read(fd, (void *)&thrstate, sizeof(x86_thread_state_t)) != sizeof(x86_thread_state_t)) {
+            printf("Reading flavor, count failed.\n");
+            goto err;
+          }
+          size += sizeof(x86_thread_state_t);
+          // create thread info list, update lwp_id later
+          sa_thread_info* newthr = add_thread_info(ph, (pthread_t) -1, (lwpid_t) num_threads++);
+          if (newthr == NULL) {
+            printf("create thread_info failed\n");
+            goto err;
+          }
+
+          // note __DARWIN_UNIX03 depengs on other definitions
+#if __DARWIN_UNIX03
+#define get_register_v(regst, regname) \
+  regst.uts.ts64.__##regname
+#else
+#define get_register_v(regst, regname) \
+  regst.uts.ts64.##regname
+#endif // __DARWIN_UNIX03
+          newthr->regs.r_rax = get_register_v(thrstate, rax);
+          newthr->regs.r_rbx = get_register_v(thrstate, rbx);
+          newthr->regs.r_rcx = get_register_v(thrstate, rcx);
+          newthr->regs.r_rdx = get_register_v(thrstate, rdx);
+          newthr->regs.r_rdi = get_register_v(thrstate, rdi);
+          newthr->regs.r_rsi = get_register_v(thrstate, rsi);
+          newthr->regs.r_rbp = get_register_v(thrstate, rbp);
+          newthr->regs.r_rsp = get_register_v(thrstate, rsp);
+          newthr->regs.r_r8  = get_register_v(thrstate, r8);
+          newthr->regs.r_r9  = get_register_v(thrstate, r9);
+          newthr->regs.r_r10 = get_register_v(thrstate, r10);
+          newthr->regs.r_r11 = get_register_v(thrstate, r11);
+          newthr->regs.r_r12 = get_register_v(thrstate, r12);
+          newthr->regs.r_r13 = get_register_v(thrstate, r13);
+          newthr->regs.r_r14 = get_register_v(thrstate, r14);
+          newthr->regs.r_r15 = get_register_v(thrstate, r15);
+          newthr->regs.r_rip = get_register_v(thrstate, rip);
+          newthr->regs.r_rflags = get_register_v(thrstate, rflags);
+          newthr->regs.r_cs  = get_register_v(thrstate, cs);
+          newthr->regs.r_fs  = get_register_v(thrstate, fs);
+          newthr->regs.r_gs  = get_register_v(thrstate, gs);
+          print_thread(newthr);
+        } else if (fc.flavor == x86_FLOAT_STATE) {
+          x86_float_state_t flstate;
+          if (read(fd, (void *)&flstate, sizeof(x86_float_state_t)) != sizeof(x86_float_state_t)) {
+            print_debug("Reading flavor, count failed.\n");
+            goto err;
+          }
+          size += sizeof(x86_float_state_t);
+        } else if (fc.flavor == x86_EXCEPTION_STATE) {
+          x86_exception_state_t excpstate;
+          if (read(fd, (void *)&excpstate, sizeof(x86_exception_state_t)) != sizeof(x86_exception_state_t)) {
+            printf("Reading flavor, count failed.\n");
+            goto err;
+          }
+          size += sizeof(x86_exception_state_t);
+        }
+      }
+    }
+  }
+  return true;
+err:
+  return false;
+}
+
+/**local function **/
+bool exists(const char *fname)
+{
+  int fd;
+  if ((fd = open(fname, O_RDONLY)) > 0) {
+    close(fd);
+    return true;
+  }
+  return false;
+}
+
+// we check: 1. lib
+//           2. lib/server
+//           3. jre/lib
+//           4. jre/lib/server
+// from: 1. exe path
+//       2. JAVA_HOME
+//       3. DYLD_LIBRARY_PATH
+static bool get_real_path(struct ps_prochandle* ph, char *rpath) {
+  /** check if they exist in JAVA ***/
+  char* execname = ph->core->exec_path;
+  char  filepath[4096];
+  char* filename = strrchr(rpath, '/');               // like /libjvm.dylib
+  if (filename == NULL) {
+    return false;
+  }
+
+  char* posbin = strstr(execname, "/bin/java");
+  if (posbin != NULL) {
+    memcpy(filepath, execname, posbin - execname);    // not include trailing '/'
+    filepath[posbin - execname] = '\0';
+  } else {
+    char* java_home = getenv("JAVA_HOME");
+    if (java_home != NULL) {
+      strcpy(filepath, java_home);
+    } else {
+      char* dyldpath = getenv("DYLD_LIBRARY_PATH");
+      char* dypath = strtok(dyldpath, ":");
+      while (dypath != NULL) {
+        strcpy(filepath, dypath);
+        strcat(filepath, filename);
+        if (exists(filepath)) {
+           strcpy(rpath, filepath);
+           return true;
+        }
+        dypath = strtok(dyldpath, ":");
+      }
+      // not found
+      return false;
+    }
+  }
+  // for exec and java_home, jdkpath now is filepath
+  size_t filepath_base_size = strlen(filepath);
+
+  // first try /lib/ and /lib/server
+  strcat(filepath, "/lib");
+  strcat(filepath, filename);
+  if (exists(filepath)) {
+    strcpy(rpath, filepath);
+    return true;
+  }
+  char* pos = strstr(filepath, filename);    // like /libjvm.dylib
+  *pos = '\0';
+  strcat(filepath, "/server");
+  strcat(filepath, filename);
+  if (exists(filepath)) {
+    strcpy(rpath, filepath);
+    return true;
+  }
+
+  // then try /jre/lib/ and /jre/lib/server
+  filepath[filepath_base_size] = '\0';
+  strcat(filepath, "/jre/lib");
+  strcat(filepath, filename);
+  if (exists(filepath)) {
+    strcpy(rpath, filepath);
+    return true;
+  }
+  pos = strstr(filepath, filename);
+  *pos = '\0';
+  strcat(filepath, "/server");
+  strcat(filepath, filename);
+  if (exists(filepath)) {
+    strcpy(rpath, filepath);
+    return true;
+  }
+
+  return false;
+}
+
+static bool read_shared_lib_info(struct ps_prochandle* ph) {
+  static int pagesize = 0;
+  int fd = ph->core->core_fd;
+  int i = 0, j;
+  uint32_t  v;
+  mach_header_64 header;        // used to check if a file header in segment
+  load_command lcmd;
+  dylib_command dylibcmd;
+
+  char name[BUF_SIZE];  // use to store name
+
+  if (pagesize == 0) {
+    pagesize = getpagesize();
+    print_debug("page size is %d\n", pagesize);
+  }
+  for (j = 0; j < ph->core->num_maps; j++) {
+    map_info *iter = ph->core->map_array[j];   // head
+    off_t fpos = iter->offset;
+    if (iter->fd != fd) {
+      // only search core file!
+      continue;
+    }
+    print_debug("map_info %d: vmaddr = 0x%016" PRIx64 "  fileoff = %" PRIu64 "  vmsize = %" PRIu64 "\n",
+                           j, iter->vaddr, iter->offset, iter->memsz);
+    lseek(fd, fpos, SEEK_SET);
+    // we assume .dylib loaded at segment address --- which is true for JVM libraries
+    // multiple files may be loaded in one segment.
+    // if first word is not a magic word, means this segment does not contain lib file.
+    if (read(fd, (void *)&v, sizeof(uint32_t)) == sizeof(uint32_t)) {
+      if (v != MH_MAGIC_64) {
+        continue;
+      }
+    } else {
+      // may be encountered last map, which is not readable
+      continue;
+    }
+    while (ltell(fd) - iter->offset < iter->memsz) {
+      lseek(fd, fpos, SEEK_SET);
+      if (read(fd, (void *)&v, sizeof(uint32_t)) != sizeof(uint32_t)) {
+        break;
+      }
+      if (v != MH_MAGIC_64) {
+        fpos = (ltell(fd) + pagesize -1)/pagesize * pagesize;
+        continue;
+      }
+      lseek(fd, -sizeof(uint32_t), SEEK_CUR);
+      // this is the file begining to core file.
+      if (read(fd, (void *)&header, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
+        goto err;
+      }
+      fpos = ltell(fd);
+
+      // found a mach-o file in this segment
+      for (i = 0; i < header.ncmds; i++) {
+        // read commands in this "file"
+        // LC_ID_DYLIB is the file itself for a .dylib
+        lseek(fd, fpos, SEEK_SET);
+        if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) {
+          return false;   // error
+        }
+        fpos += lcmd.cmdsize;  // next command position
+        // make sure still within seg size.
+        if (fpos  - lcmd.cmdsize - iter->offset > iter->memsz) {
+          print_debug("Warning: out of segement limit: %ld \n", fpos  - lcmd.cmdsize - iter->offset);
+          break;  // no need to iterate all commands
+        }
+        if (lcmd.cmd == LC_ID_DYLIB) {
+          lseek(fd, -sizeof(load_command), SEEK_CUR);
+          if (read(fd, (void *)&dylibcmd, sizeof(dylib_command)) != sizeof(dylib_command)) {
+            return false;
+          }
+          /**** name stored at dylib_command.dylib.name.offset, is a C string  */
+          lseek(fd, dylibcmd.dylib.name.offset - sizeof(dylib_command), SEEK_CUR);
+          int j = 0;
+          while (j < BUF_SIZE) {
+            read(fd, (void *)(name + j), sizeof(char));
+            if (name[j] == '\0') break;
+            j++;
+          }
+          print_debug("%s\n", name);
+          // changed name from @rpath/xxxx.dylib to real path
+          if (strrchr(name, '@')) {
+            get_real_path(ph, name);
+            print_debug("get_real_path returned: %s\n", name);
+          }
+          add_lib_info(ph, name, iter->vaddr);
+          break;
+        }
+      }
+      // done with the file, advanced to next page to search more files
+      fpos = (ltell(fd) + pagesize - 1) / pagesize * pagesize;
+    }
+  }
+  return true;
+err:
+  return false;
+}
+
+bool read_macho64_header(int fd, mach_header_64* core_header) {
+  bool is_macho = false;
+  if (fd < 0) return false;
+  off_t pos = ltell(fd);
+  lseek(fd, 0, SEEK_SET);
+  if (read(fd, (void *)core_header, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
+    is_macho = false;
+  } else {
+    is_macho = (core_header->magic ==  MH_MAGIC_64 || core_header->magic ==  MH_CIGAM_64);
+  }
+  lseek(fd, pos, SEEK_SET);
+  return is_macho;
+}
+
+// the one and only one exposed stuff from this file
+struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
+  mach_header_64 core_header;
+  mach_header_64 exec_header;
+
+  struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
+  if (ph == NULL) {
+    print_debug("cant allocate ps_prochandle\n");
+    return NULL;
+  }
+
+  if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
+    free(ph);
+    print_debug("can't allocate ps_prochandle\n");
+    return NULL;
+  }
+
+  // initialize ph
+  ph->ops = &core_ops;
+  ph->core->core_fd   = -1;
+  ph->core->exec_fd   = -1;
+  ph->core->interp_fd = -1;
+
+  print_debug("exec: %s   core: %s", exec_file, core_file);
+
+  strncpy(ph->core->exec_path, exec_file, sizeof(ph->core->exec_path));
+
+  // open the core file
+  if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
+    print_error("can't open core file\n");
+    goto err;
+  }
+
+  // read core file header
+  if (read_macho64_header(ph->core->core_fd, &core_header) != true || core_header.filetype != MH_CORE) {
+    print_debug("core file is not a valid Mach-O file\n");
+    goto err;
+  }
+
+  if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
+    print_error("can't open executable file\n");
+    goto err;
+  }
+
+  if (read_macho64_header(ph->core->exec_fd, &exec_header) != true ||
+                          exec_header.filetype != MH_EXECUTE) {
+    print_error("executable file is not a valid Mach-O file\n");
+    goto err;
+  }
+
+  // process core file segments
+  if (read_core_segments(ph) != true) {
+    print_error("failed to read core segments\n");
+    goto err;
+  }
+
+  // allocate and sort maps into map_array, we need to do this
+  // here because read_shared_lib_info needs to read from debuggee
+  // address space
+  if (sort_map_array(ph) != true) {
+    print_error("failed to sort segment map array\n");
+    goto err;
+  }
+
+  if (read_shared_lib_info(ph) != true) {
+    print_error("failed to read libraries\n");
+    goto err;
+  }
+
+  // sort again because we have added more mappings from shared objects
+  if (sort_map_array(ph) != true) {
+    print_error("failed to sort segment map array\n");
+    goto err;
+  }
+
+  if (init_classsharing_workaround(ph) != true) {
+    print_error("failed to workaround classshareing\n");
+    goto err;
+  }
+
+  print_debug("Leave Pgrab_core\n");
+  return ph;
+
+err:
+  Prelease(ph);
+  return NULL;
+}
+
+#else // __APPLE__ (none macosx)
+
+// read regs and create thread from core file
 static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size_t nbytes) {
    // we have to read prstatus_t from buf
    // assert(nbytes == sizeof(prstaus_t), "size mismatch on prstatus_t");
    prstatus_t* prstat = (prstatus_t*) buf;
-   thread_info* newthr;
+   sa_thread_info* newthr;
    print_debug("got integer regset for lwp %d\n", prstat->pr_pid);
    // we set pthread_t to -1 for core dump
    if((newthr = add_thread_info(ph, (pthread_t) -1,  prstat->pr_pid)) == NULL)
@@ -632,8 +1093,9 @@
                                    notep->n_type, notep->n_descsz);
 
       if (notep->n_type == NT_PRSTATUS) {
-         if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true)
+         if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
             return false;
+         }
       }
       p = descdata + ROUNDUP(notep->n_descsz, 4);
    }
@@ -681,7 +1143,9 @@
     for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
       switch (core_php->p_type) {
          case PT_NOTE:
-            if (core_handle_note(ph, core_php) != true) goto err;
+            if (core_handle_note(ph, core_php) != true) {
+              goto err;
+            }
             break;
 
          case PT_LOAD: {
@@ -800,7 +1264,6 @@
    return false;
 }
 
-
 #define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug,  r_map)
 #define LD_BASE_OFFSET        offsetof(struct r_debug,  r_ldbase)
 #define LINK_MAP_ADDR_OFFSET  offsetof(struct link_map, l_addr)
@@ -810,213 +1273,218 @@
 // read shared library info from runtime linker's data structures.
 // This work is done by librtlb_db in Solaris
 static bool read_shared_lib_info(struct ps_prochandle* ph) {
-   uintptr_t addr = ph->core->dynamic_addr;
-   uintptr_t debug_base;
-   uintptr_t first_link_map_addr;
-   uintptr_t ld_base_addr;
-   uintptr_t link_map_addr;
-   uintptr_t lib_base_diff;
-   uintptr_t lib_base;
-   uintptr_t lib_name_addr;
-   char lib_name[BUF_SIZE];
-   ELF_DYN dyn;
-   ELF_EHDR elf_ehdr;
-   int lib_fd;
+  uintptr_t addr = ph->core->dynamic_addr;
+  uintptr_t debug_base;
+  uintptr_t first_link_map_addr;
+  uintptr_t ld_base_addr;
+  uintptr_t link_map_addr;
+  uintptr_t lib_base_diff;
+  uintptr_t lib_base;
+  uintptr_t lib_name_addr;
+  char lib_name[BUF_SIZE];
+  ELF_DYN dyn;
+  ELF_EHDR elf_ehdr;
+  int lib_fd;
 
-   // _DYNAMIC has information of the form
-   //         [tag] [data] [tag] [data] .....
-   // Both tag and data are pointer sized.
-   // We look for dynamic info with DT_DEBUG. This has shared object info.
-   // refer to struct r_debug in link.h
+  // _DYNAMIC has information of the form
+  //         [tag] [data] [tag] [data] .....
+  // Both tag and data are pointer sized.
+  // We look for dynamic info with DT_DEBUG. This has shared object info.
+  // refer to struct r_debug in link.h
 
-   dyn.d_tag = DT_NULL;
-   while (dyn.d_tag != DT_DEBUG) {
-      if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
-         print_debug("can't read debug info from _DYNAMIC\n");
-         return false;
-      }
-      addr += sizeof(ELF_DYN);
-   }
+  dyn.d_tag = DT_NULL;
+  while (dyn.d_tag != DT_DEBUG) {
+    if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
+      print_debug("can't read debug info from _DYNAMIC\n");
+      return false;
+    }
+    addr += sizeof(ELF_DYN);
+  }
 
-   // we have got Dyn entry with DT_DEBUG
-   debug_base = dyn.d_un.d_ptr;
-   // at debug_base we have struct r_debug. This has first link map in r_map field
-   if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
-                 &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
-      print_debug("can't read first link map address\n");
-      return false;
-   }
+  // we have got Dyn entry with DT_DEBUG
+  debug_base = dyn.d_un.d_ptr;
+  // at debug_base we have struct r_debug. This has first link map in r_map field
+  if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
+                  &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
+    print_debug("can't read first link map address\n");
+    return false;
+  }
 
-   // read ld_base address from struct r_debug
-   // XXX: There is no r_ldbase member on BSD
-/*
-   if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
-                 sizeof(uintptr_t)) != PS_OK) {
-      print_debug("can't read ld base address\n");
-      return false;
-   }
-   ph->core->ld_base_addr = ld_base_addr;
-*/
-   ph->core->ld_base_addr = 0;
+  // read ld_base address from struct r_debug
+  // XXX: There is no r_ldbase member on BSD
+  /*
+  if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
+                  sizeof(uintptr_t)) != PS_OK) {
+    print_debug("can't read ld base address\n");
+    return false;
+  }
+  ph->core->ld_base_addr = ld_base_addr;
+  */
+  ph->core->ld_base_addr = 0;
 
-   print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
+  print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
 
-   // now read segments from interp (i.e ld-elf.so.1)
-   if (read_interp_segments(ph) != true)
-      return false;
+  // now read segments from interp (i.e ld-elf.so.1)
+  if (read_interp_segments(ph) != true)
+    return false;
 
-   // after adding interpreter (ld.so) mappings sort again
-   if (sort_map_array(ph) != true)
-      return false;
+  // after adding interpreter (ld.so) mappings sort again
+  if (sort_map_array(ph) != true)
+    return false;
 
-   print_debug("first link map is at 0x%lx\n", first_link_map_addr);
+  print_debug("first link map is at 0x%lx\n", first_link_map_addr);
 
-   link_map_addr = first_link_map_addr;
-   while (link_map_addr != 0) {
-      // read library base address of the .so. Note that even though <sys/link.h> calls
-      // link_map->l_addr as "base address",  this is * not * really base virtual
-      // address of the shared object. This is actually the difference b/w the virtual
-      // address mentioned in shared object and the actual virtual base where runtime
-      // linker loaded it. We use "base diff" in read_lib_segments call below.
+  link_map_addr = first_link_map_addr;
+  while (link_map_addr != 0) {
+    // read library base address of the .so. Note that even though <sys/link.h> calls
+    // link_map->l_addr as "base address",  this is * not * really base virtual
+    // address of the shared object. This is actually the difference b/w the virtual
+    // address mentioned in shared object and the actual virtual base where runtime
+    // linker loaded it. We use "base diff" in read_lib_segments call below.
 
-      if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET,
-                   &lib_base_diff, sizeof(uintptr_t)) != PS_OK) {
-         print_debug("can't read shared object base address diff\n");
-         return false;
-      }
+    if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET,
+                 &lib_base_diff, sizeof(uintptr_t)) != PS_OK) {
+      print_debug("can't read shared object base address diff\n");
+      return false;
+    }
 
-      // read address of the name
-      if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET,
-                    &lib_name_addr, sizeof(uintptr_t)) != PS_OK) {
-         print_debug("can't read address of shared object name\n");
-         return false;
-      }
+    // read address of the name
+    if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET,
+                  &lib_name_addr, sizeof(uintptr_t)) != PS_OK) {
+      print_debug("can't read address of shared object name\n");
+      return false;
+    }
 
-      // read name of the shared object
-      if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) {
-         print_debug("can't read shared object name\n");
-         return false;
-      }
+    // read name of the shared object
+    if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) {
+      print_debug("can't read shared object name\n");
+      return false;
+    }
 
-      if (lib_name[0] != '\0') {
-         // ignore empty lib names
-         lib_fd = pathmap_open(lib_name);
+    if (lib_name[0] != '\0') {
+      // ignore empty lib names
+      lib_fd = pathmap_open(lib_name);
 
-         if (lib_fd < 0) {
-            print_debug("can't open shared object %s\n", lib_name);
-            // continue with other libraries...
-         } else {
-            if (read_elf_header(lib_fd, &elf_ehdr)) {
-               lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
-               print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
-                           lib_name, lib_base, lib_base_diff);
-               // while adding library mappings we need to use "base difference".
-               if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
-                  print_debug("can't read shared object's segments\n");
-                  close(lib_fd);
-                  return false;
-               }
-               add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
-               // Map info is added for the library (lib_name) so
-               // we need to re-sort it before calling the p_pdread.
-               if (sort_map_array(ph) != true)
-                  return false;
-            } else {
-               print_debug("can't read ELF header for shared object %s\n", lib_name);
-               close(lib_fd);
-               // continue with other libraries...
-            }
-         }
+      if (lib_fd < 0) {
+        print_debug("can't open shared object %s\n", lib_name);
+        // continue with other libraries...
+      } else {
+        if (read_elf_header(lib_fd, &elf_ehdr)) {
+          lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
+          print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
+                       lib_name, lib_base, lib_base_diff);
+          // while adding library mappings we need to use "base difference".
+          if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
+            print_debug("can't read shared object's segments\n");
+            close(lib_fd);
+            return false;
+          }
+          add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
+          // Map info is added for the library (lib_name) so
+          // we need to re-sort it before calling the p_pdread.
+          if (sort_map_array(ph) != true)
+            return false;
+        } else {
+          print_debug("can't read ELF header for shared object %s\n", lib_name);
+          close(lib_fd);
+          // continue with other libraries...
+        }
       }
+    }
 
-      // read next link_map address
-      if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
-                        &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
-         print_debug("can't read next link in link_map\n");
-         return false;
-      }
-   }
+    // read next link_map address
+    if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
+                 &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
+      print_debug("can't read next link in link_map\n");
+      return false;
+    }
+  }
 
-   return true;
+  return true;
 }
 
 // the one and only one exposed stuff from this file
 struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
-   ELF_EHDR core_ehdr;
-   ELF_EHDR exec_ehdr;
+  ELF_EHDR core_ehdr;
+  ELF_EHDR exec_ehdr;
 
-   struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
-   if (ph == NULL) {
-      print_debug("can't allocate ps_prochandle\n");
-      return NULL;
-   }
+  struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
+  if (ph == NULL) {
+    print_debug("cant allocate ps_prochandle\n");
+    return NULL;
+  }
 
-   if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
-      free(ph);
-      print_debug("can't allocate ps_prochandle\n");
-      return NULL;
-   }
+  if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
+    free(ph);
+    print_debug("can't allocate ps_prochandle\n");
+    return NULL;
+  }
 
-   // initialize ph
-   ph->ops = &core_ops;
-   ph->core->core_fd   = -1;
-   ph->core->exec_fd   = -1;
-   ph->core->interp_fd = -1;
+  // initialize ph
+  ph->ops = &core_ops;
+  ph->core->core_fd   = -1;
+  ph->core->exec_fd   = -1;
+  ph->core->interp_fd = -1;
+
+  print_debug("exec: %s   core: %s", exec_file, core_file);
 
-   // open the core file
-   if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
-      print_debug("can't open core file\n");
-      goto err;
-   }
+  // open the core file
+  if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
+    print_debug("can't open core file\n");
+    goto err;
+  }
 
-   // read core file ELF header
-   if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
-      print_debug("core file is not a valid ELF ET_CORE file\n");
-      goto err;
-   }
+  // read core file ELF header
+  if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
+    print_debug("core file is not a valid ELF ET_CORE file\n");
+    goto err;
+  }
 
-   if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
-      print_debug("can't open executable file\n");
-      goto err;
-   }
+  if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
+    print_debug("can't open executable file\n");
+    goto err;
+  }
 
-   if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
-      print_debug("executable file is not a valid ELF ET_EXEC file\n");
-      goto err;
-   }
+  if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
+     print_debug("executable file is not a valid ELF ET_EXEC file\n");
+     goto err;
+  }
 
-   // process core file segments
-   if (read_core_segments(ph, &core_ehdr) != true)
-      goto err;
+  // process core file segments
+  if (read_core_segments(ph, &core_ehdr) != true)
+     goto err;
 
-   // process exec file segments
-   if (read_exec_segments(ph, &exec_ehdr) != true)
-      goto err;
+  // process exec file segments
+  if (read_exec_segments(ph, &exec_ehdr) != true)
+     goto err;
 
-   // exec file is also treated like a shared object for symbol search
-   if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
-                       (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
-      goto err;
+  // exec file is also treated like a shared object for symbol search
+  if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
+                      (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
+     goto err;
 
-   // allocate and sort maps into map_array, we need to do this
-   // here because read_shared_lib_info needs to read from debuggee
-   // address space
-   if (sort_map_array(ph) != true)
-      goto err;
+  // allocate and sort maps into map_array, we need to do this
+  // here because read_shared_lib_info needs to read from debuggee
+  // address space
+  if (sort_map_array(ph) != true)
+    goto err;
 
-   if (read_shared_lib_info(ph) != true)
-      goto err;
+  if (read_shared_lib_info(ph) != true)
+    goto err;
 
-   // sort again because we have added more mappings from shared objects
-   if (sort_map_array(ph) != true)
-      goto err;
+  // sort again because we have added more mappings from shared objects
+  if (sort_map_array(ph) != true)
+    goto err;
 
-   if (init_classsharing_workaround(ph) != true)
-      goto err;
+  if (init_classsharing_workaround(ph) != true)
+    goto err;
 
-   return ph;
+  print_debug("Leave Pgrab_core\n");
+  return ph;
 
 err:
-   Prelease(ph);
-   return NULL;
+  Prelease(ph);
+  return NULL;
 }
+
+#endif // __APPLE__
--- a/agent/src/os/bsd/symtab.c	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/os/bsd/symtab.c	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -28,32 +28,182 @@
 #include <string.h>
 #include <db.h>
 #include <fcntl.h>
+
+#include "libproc_impl.h"
 #include "symtab.h"
+#ifndef __APPLE__
 #include "salibelf.h"
+#endif // __APPLE__
 
 
 // ----------------------------------------------------
 // functions for symbol lookups
 // ----------------------------------------------------
 
+typedef struct symtab_symbol {
+  char *name;                // name like __ZThread_...
+  uintptr_t offset;          // to loaded address
+  uintptr_t size;            // size strlen
+} symtab_symbol;
+
+typedef struct symtab {
+  char *strs;                // all symbols "__symbol1__'\0'__symbol2__...."
+  size_t num_symbols;
+  DB* hash_table;
+  symtab_symbol* symbols;
+} symtab_t;
+
+#ifdef __APPLE__
+
+void build_search_table(symtab_t *symtab) {
+  int i;
+  for (i = 0; i < symtab->num_symbols; i++) {
+    DBT key, value;
+    key.data = symtab->symbols[i].name;
+    key.size = strlen(key.data) + 1;
+    value.data = &(symtab->symbols[i]);
+    value.size = sizeof(symtab_symbol);
+    (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0);
+
+    // check result
+    if (is_debug()) {
+      DBT rkey, rvalue;
+      char* tmp = (char *)malloc(strlen(symtab->symbols[i].name) + 1);
+      strcpy(tmp, symtab->symbols[i].name);
+      rkey.data = tmp;
+      rkey.size = strlen(tmp) + 1;
+      (*symtab->hash_table->get)(symtab->hash_table, &rkey, &rvalue, 0);
+      // we may get a copy back so compare contents
+      symtab_symbol *res = (symtab_symbol *)rvalue.data;
+      if (strcmp(res->name, symtab->symbols[i].name)  ||
+          res->offset != symtab->symbols[i].offset    ||
+          res->size != symtab->symbols[i].size) {
+        print_debug("error to get hash_table value!\n");
+      }
+      free(tmp);
+    }
+  }
+}
+
+// read symbol table from given fd.
+struct symtab* build_symtab(int fd) {
+  symtab_t* symtab = NULL;
+  int i;
+  mach_header_64 header;
+  off_t image_start;
+
+  if (!get_arch_off(fd, CPU_TYPE_X86_64, &image_start)) {
+    print_debug("failed in get fat header\n");
+    return NULL;
+  }
+  lseek(fd, image_start, SEEK_SET);
+  if (read(fd, (void *)&header, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
+    print_debug("reading header failed!\n");
+    return NULL;
+  }
+  // header
+  if (header.magic != MH_MAGIC_64) {
+    print_debug("not a valid .dylib file\n");
+    return NULL;
+  }
+
+  load_command lcmd;
+  symtab_command symtabcmd;
+  nlist_64 lentry;
+
+  bool lcsymtab_exist = false;
+
+  long filepos = ltell(fd);
+  for (i = 0; i < header.ncmds; i++) {
+    lseek(fd, filepos, SEEK_SET);
+    if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) {
+      print_debug("read load_command failed for file\n");
+      return NULL;
+    }
+    filepos += lcmd.cmdsize;  // next command position
+    if (lcmd.cmd == LC_SYMTAB) {
+      lseek(fd, -sizeof(load_command), SEEK_CUR);
+      lcsymtab_exist = true;
+      break;
+    }
+  }
+  if (!lcsymtab_exist) {
+    print_debug("No symtab command found!\n");
+    return NULL;
+  }
+  if (read(fd, (void *)&symtabcmd, sizeof(symtab_command)) != sizeof(symtab_command)) {
+    print_debug("read symtab_command failed for file");
+    return NULL;
+  }
+  symtab = (symtab_t *)malloc(sizeof(symtab_t));
+  if (symtab == NULL) {
+    print_debug("out of memory: allocating symtab\n");
+    return NULL;
+  }
+
+  // create hash table, we use berkeley db to
+  // manipulate the hash table.
+  symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL);
+  if (symtab->hash_table == NULL)
+    goto quit;
+
+  symtab->num_symbols = symtabcmd.nsyms;
+  symtab->symbols = (symtab_symbol *)malloc(sizeof(symtab_symbol) * symtab->num_symbols);
+  symtab->strs    = (char *)malloc(sizeof(char) * symtabcmd.strsize);
+  if (symtab->symbols == NULL || symtab->strs == NULL) {
+     print_debug("out of memory: allocating symtab.symbol or symtab.strs\n");
+     goto quit;
+  }
+  lseek(fd, image_start + symtabcmd.symoff, SEEK_SET);
+  for (i = 0; i < symtab->num_symbols; i++) {
+    if (read(fd, (void *)&lentry, sizeof(nlist_64)) != sizeof(nlist_64)) {
+      print_debug("read nlist_64 failed at %i\n", i);
+      goto quit;
+    }
+    symtab->symbols[i].offset = lentry.n_value;
+    symtab->symbols[i].size  = lentry.n_un.n_strx;        // index
+  }
+
+  // string table
+  lseek(fd, image_start + symtabcmd.stroff, SEEK_SET);
+  int size = read(fd, (void *)(symtab->strs), symtabcmd.strsize * sizeof(char));
+  if (size != symtabcmd.strsize * sizeof(char)) {
+     print_debug("reading string table failed\n");
+     goto quit;
+  }
+
+  for (i = 0; i < symtab->num_symbols; i++) {
+    symtab->symbols[i].name = symtab->strs + symtab->symbols[i].size;
+    if (i > 0) {
+      // fix size
+      symtab->symbols[i - 1].size = symtab->symbols[i].size - symtab->symbols[i - 1].size;
+      print_debug("%s size = %d\n", symtab->symbols[i - 1].name, symtab->symbols[i - 1].size);
+
+    }
+
+    if (i == symtab->num_symbols - 1) {
+      // last index
+      symtab->symbols[i].size =
+            symtabcmd.strsize - symtab->symbols[i].size;
+      print_debug("%s size = %d\n", symtab->symbols[i].name, symtab->symbols[i].size);
+    }
+  }
+
+  // build a hashtable for fast query
+  build_search_table(symtab);
+  return symtab;
+quit:
+  if (symtab) destroy_symtab(symtab);
+  return NULL;
+}
+
+#else // __APPLE__
+
 struct elf_section {
   ELF_SHDR   *c_shdr;
   void       *c_data;
 };
 
-struct elf_symbol {
-  char *name;
-  uintptr_t offset;
-  uintptr_t size;
-};
-
-typedef struct symtab {
-  char *strs;
-  size_t num_symbols;
-  struct elf_symbol *symbols;
-  DB* hash_table;
-} symtab_t;
-
 // read symbol table from given fd.
 struct symtab* build_symtab(int fd) {
   ELF_EHDR ehdr;
@@ -176,7 +326,7 @@
         key.data = sym_name;
         key.size = strlen(sym_name) + 1;
         value.data = &(symtab->symbols[j]);
-        value.size = sizeof(void *);
+        value.size = sizeof(symtab_symbol);
         (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0);
       }
     }
@@ -201,30 +351,29 @@
   return symtab;
 }
 
-void destroy_symtab(struct symtab* symtab) {
+#endif // __APPLE__
+
+void destroy_symtab(symtab_t* symtab) {
   if (!symtab) return;
-  if (symtab->strs) free(symtab->strs);
-  if (symtab->symbols) free(symtab->symbols);
-  if (symtab->hash_table) {
-    (*symtab->hash_table->close)(symtab->hash_table);
-  }
+  free(symtab->strs);
+  free(symtab->symbols);
   free(symtab);
 }
 
-uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
-                      const char *sym_name, int *sym_size) {
+uintptr_t search_symbol(struct symtab* symtab, uintptr_t base, const char *sym_name, int *sym_size) {
   DBT key, value;
   int ret;
 
   // library does not have symbol table
-  if (!symtab || !symtab->hash_table)
+  if (!symtab || !symtab->hash_table) {
      return 0;
+  }
 
   key.data = (char*)(uintptr_t)sym_name;
   key.size = strlen(sym_name) + 1;
   ret = (*symtab->hash_table->get)(symtab->hash_table, &key, &value, 0);
   if (ret == 0) {
-    struct elf_symbol *sym = value.data;
+    symtab_symbol *sym = value.data;
     uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset);
     if (sym_size) *sym_size = sym->size;
     return rslt;
@@ -238,7 +387,7 @@
   int n = 0;
   if (!symtab) return NULL;
   for (; n < symtab->num_symbols; n++) {
-    struct elf_symbol* sym = &(symtab->symbols[n]);
+    symtab_symbol* sym = &(symtab->symbols[n]);
     if (sym->name != NULL &&
       offset >= sym->offset && offset < sym->offset + sym->size) {
       if (poffset) *poffset = (offset - sym->offset);
--- a/agent/src/os/bsd/symtab.h	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/os/bsd/symtab.h	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -27,11 +27,11 @@
 
 #include <stdint.h>
 
-// interface to manage ELF symbol tables
+// interface to manage ELF or MachO symbol tables
 
 struct symtab;
 
-// build symbol table for a given ELF file descriptor
+// build symbol table for a given ELF or MachO file escriptor
 struct symtab* build_symtab(int fd);
 
 // destroy the symbol table
--- a/agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -34,11 +34,18 @@
   public BsdVtblAccess(SymbolLookup symbolLookup,
                          String[] dllNames) {
     super(symbolLookup, dllNames);
-
-    if (symbolLookup.lookup("libjvm.so", "__vt_10JavaThread") != null ||
-        symbolLookup.lookup("libjvm_g.so", "__vt_10JavaThread") != null) {
+    boolean oldVT = false;
+    boolean isDarwin = dllNames[0].lastIndexOf(".dylib") != -1;
+    String vtJavaThread = isDarwin ? "_vt_10JavaThread" : "__vt_10JavaThread";
+    for (String dllName : dllNames) {
+       if (symbolLookup.lookup(dllName, vtJavaThread) != null) {
+         oldVT = true;
+         break;
+       }
+    }
+    if (oldVT) {
        // old C++ ABI
-       vt = "__vt_";
+       vt = isDarwin ? "_vt_" :  "__vt_";
     } else {
        // new C++ ABI
        vt = "_ZTV";
--- a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java	Fri Apr 12 10:14:42 2013 +0100
@@ -24,36 +24,81 @@
 
 package sun.jvm.hotspot;
 
-import java.io.*;
-import java.math.*;
-import java.util.*;
-import java.util.regex.*;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
-import sun.jvm.hotspot.types.Type;
-import sun.jvm.hotspot.types.Field;
-import sun.jvm.hotspot.HotSpotTypeDataBase;
-import sun.jvm.hotspot.types.basic.BasicType;
-import sun.jvm.hotspot.types.basic.BasicTypeDataBase;
-import sun.jvm.hotspot.types.CIntegerType;
-import sun.jvm.hotspot.code.*;
-import sun.jvm.hotspot.compiler.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.interpreter.*;
-import sun.jvm.hotspot.memory.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.opto.*;
-import sun.jvm.hotspot.ci.*;
-import sun.jvm.hotspot.asm.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.utilities.*;
-import sun.jvm.hotspot.utilities.soql.*;
-import sun.jvm.hotspot.ui.classbrowser.*;
-import sun.jvm.hotspot.ui.tree.*;
-import sun.jvm.hotspot.tools.*;
+import sun.jvm.hotspot.ci.ciEnv;
+import sun.jvm.hotspot.code.CodeBlob;
+import sun.jvm.hotspot.code.CodeCacheVisitor;
+import sun.jvm.hotspot.code.NMethod;
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.debugger.OopHandle;
+import sun.jvm.hotspot.memory.SymbolTable;
+import sun.jvm.hotspot.memory.SystemDictionary;
+import sun.jvm.hotspot.memory.Universe;
+import sun.jvm.hotspot.oops.DefaultHeapVisitor;
+import sun.jvm.hotspot.oops.HeapVisitor;
+import sun.jvm.hotspot.oops.InstanceKlass;
+import sun.jvm.hotspot.oops.Klass;
+import sun.jvm.hotspot.oops.Metadata;
+import sun.jvm.hotspot.oops.Method;
+import sun.jvm.hotspot.oops.MethodData;
+import sun.jvm.hotspot.oops.Oop;
+import sun.jvm.hotspot.oops.RawHeapVisitor;
+import sun.jvm.hotspot.oops.Symbol;
+import sun.jvm.hotspot.oops.UnknownOopException;
+import sun.jvm.hotspot.opto.Compile;
+import sun.jvm.hotspot.opto.InlineTree;
+import sun.jvm.hotspot.runtime.CompiledVFrame;
+import sun.jvm.hotspot.runtime.CompilerThread;
+import sun.jvm.hotspot.runtime.JavaThread;
+import sun.jvm.hotspot.runtime.JavaVFrame;
+import sun.jvm.hotspot.runtime.Threads;
+import sun.jvm.hotspot.runtime.VM;
 import sun.jvm.hotspot.tools.ObjectHistogram;
+import sun.jvm.hotspot.tools.PMap;
+import sun.jvm.hotspot.tools.PStack;
 import sun.jvm.hotspot.tools.StackTrace;
 import sun.jvm.hotspot.tools.jcore.ClassDump;
 import sun.jvm.hotspot.tools.jcore.ClassFilter;
+import sun.jvm.hotspot.types.CIntegerType;
+import sun.jvm.hotspot.types.Field;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.basic.BasicType;
+import sun.jvm.hotspot.ui.classbrowser.HTMLGenerator;
+import sun.jvm.hotspot.ui.tree.CTypeTreeNodeAdapter;
+import sun.jvm.hotspot.ui.tree.OopTreeNodeAdapter;
+import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
+import sun.jvm.hotspot.utilities.AddressOps;
+import sun.jvm.hotspot.utilities.Assert;
+import sun.jvm.hotspot.utilities.HeapProgressThunk;
+import sun.jvm.hotspot.utilities.LivenessPathElement;
+import sun.jvm.hotspot.utilities.MethodArray;
+import sun.jvm.hotspot.utilities.ObjectReader;
+import sun.jvm.hotspot.utilities.PointerFinder;
+import sun.jvm.hotspot.utilities.PointerLocation;
+import sun.jvm.hotspot.utilities.ReversePtrs;
+import sun.jvm.hotspot.utilities.ReversePtrsAnalysis;
+import sun.jvm.hotspot.utilities.RobustOopDeterminator;
+import sun.jvm.hotspot.utilities.SystemDictionaryHelper;
+import sun.jvm.hotspot.utilities.soql.JSJavaFactory;
+import sun.jvm.hotspot.utilities.soql.JSJavaFactoryImpl;
+import sun.jvm.hotspot.utilities.soql.JSJavaScriptEngine;
 
 public class CommandProcessor {
     public abstract static class DebuggerInterface {
@@ -1132,6 +1177,10 @@
                     Klass klass = null;
                     if (t.countTokens() == 1) {
                         klass = SystemDictionaryHelper.findInstanceKlass(t.nextToken());
+                        if (klass == null) {
+                            out.println("No such type.");
+                            return;
+                        }
                     }
                     while (base != null && base.lessThan(end)) {
                         long step = stride;
@@ -1517,7 +1566,7 @@
                         ByteArrayOutputStream bos = new ByteArrayOutputStream();
                         thread.printThreadIDOn(new PrintStream(bos));
                         if (all || bos.toString().equals(name)) {
-                            out.println(bos.toString() + " = " + thread.getAddress());
+                            out.println("Thread " + bos.toString() + " Address: " + thread.getAddress());
                             HTMLGenerator gen = new HTMLGenerator(false);
                             try {
                                 out.println(gen.genHTMLForJavaStackTrace(thread));
@@ -1546,7 +1595,7 @@
                         ByteArrayOutputStream bos = new ByteArrayOutputStream();
                         thread.printThreadIDOn(new PrintStream(bos));
                         if (all || bos.toString().equals(name)) {
-                            out.println(bos.toString() + " = " + thread.getAddress());
+                            out.println("Thread " + bos.toString() + " Address " + thread.getAddress());
                             if (!all) return;
                         }
                     }
--- a/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -311,6 +311,8 @@
                 setupDebuggerLinux();
             } else if (os.equals("bsd")) {
                 setupDebuggerBsd();
+            } else if (os.equals("darwin")) {
+                setupDebuggerDarwin();
             } else {
                 // Add support for more operating systems here
                 throw new DebuggerException("Operating system " + os + " not yet supported");
@@ -370,6 +372,10 @@
                 db = new HotSpotTypeDataBase(machDesc,
                 new BsdVtblAccess(debugger, jvmLibNames),
                 debugger, jvmLibNames);
+            } else if (os.equals("darwin")) {
+                db = new HotSpotTypeDataBase(machDesc,
+                new BsdVtblAccess(debugger, jvmLibNames),
+                debugger, jvmLibNames);
             } else {
                 throw new DebuggerException("OS \"" + os + "\" not yet supported (no VtblAccess yet)");
             }
@@ -459,6 +465,8 @@
             setupJVMLibNamesLinux();
         } else if (os.equals("bsd")) {
             setupJVMLibNamesBsd();
+        } else if (os.equals("darwin")) {
+            setupJVMLibNamesDarwin();
         } else {
             throw new RuntimeException("Unknown OS type");
         }
@@ -567,6 +575,29 @@
         jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so" };
     }
 
+    //
+    // Darwin
+    //
+
+    private void setupDebuggerDarwin() {
+        setupJVMLibNamesDarwin();
+
+        if (cpu.equals("amd64") || cpu.equals("x86_64")) {
+            machDesc = new MachineDescriptionAMD64();
+        } else {
+            throw new DebuggerException("Darwin only supported on x86_64. Current arch: " + cpu);
+        }
+
+        BsdDebuggerLocal dbg = new BsdDebuggerLocal(machDesc, !isServer);
+        debugger = dbg;
+
+        attachDebugger();
+    }
+
+    private void setupJVMLibNamesDarwin() {
+        jvmLibNames = new String[] { "libjvm.dylib", "libjvm_g.dylib" };
+    }
+
     /** Convenience routine which should be called by per-platform
       debugger setup. Should not be called when startupMode is
       REMOTE_MODE. */
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -31,6 +31,9 @@
 import sun.jvm.hotspot.debugger.x86.*;
 import sun.jvm.hotspot.debugger.cdbg.*;
 import sun.jvm.hotspot.utilities.*;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.Threads;
+import sun.jvm.hotspot.runtime.JavaThread;
 import java.lang.reflect.*;
 
 /** <P> An implementation of the JVMDebugger interface. The basic debug
@@ -51,10 +54,11 @@
 public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
     private boolean useGCC32ABI;
     private boolean attached;
-    private long    p_ps_prochandle; // native debugger handle
-    private long    symbolicator; // macosx symbolicator handle
-    private long    task; // macosx task handle
+    private long    p_ps_prochandle;      // native debugger handle
+    private long    symbolicator;         // macosx symbolicator handle
+    private long    task;                 // macosx task handle
     private boolean isCore;
+    private boolean isDarwin;             // variant for bsd
 
     // CDebugger support
     private BsdCDebugger cdbg;
@@ -208,6 +212,7 @@
             }
         }
 
+        isDarwin = getOS().equals("darwin");
         workerThread = new BsdDebuggerLocalWorkerThread(this);
         workerThread.start();
     }
@@ -240,8 +245,11 @@
 
     /* called from attach methods */
     private void findABIVersion() throws DebuggerException {
-        if (lookupByName0("libjvm.so", "__vt_10JavaThread") != 0 ||
-            lookupByName0("libjvm_g.so", "__vt_10JavaThread") != 0) {
+        String libjvmName = isDarwin ? "libjvm.dylib" : "libjvm.so";
+        String libjvm_gName = isDarwin? "libjvm_g.dylib" : "libjvm_g.so";
+        String javaThreadVt = isDarwin ? "_vt_10JavaThread" : "__vt_10JavaThread";
+        if (lookupByName0(libjvmName, javaThreadVt) != 0 ||
+            lookupByName0(libjvm_gName, javaThreadVt) != 0) {
             // old C++ ABI
             useGCC32ABI = false;
         } else {
@@ -360,7 +368,8 @@
         }
 
         if (isCore) {
-            long addr = lookupByName0(objectName, symbol);
+            // MacOSX symbol with "_" as leading
+            long addr = lookupByName0(objectName, isDarwin ? "_" + symbol : symbol);
             return (addr == 0)? null : new BsdAddress(this, handleGCC32ABI(addr, symbol));
         } else {
             class LookupByNameTask implements WorkerThreadTask {
@@ -403,12 +412,12 @@
     public ThreadProxy getThreadForIdentifierAddress(Address threadIdAddr, Address uniqueThreadIdAddr) {
         return new BsdThread(this, threadIdAddr, uniqueThreadIdAddr);
     }
+
     @Override
     public ThreadProxy getThreadForIdentifierAddress(Address addr) {
         throw new RuntimeException("unimplemented");
     }
 
-
     /** From the ThreadAccess interface via Debugger and JVMDebugger */
     public ThreadProxy getThreadForThreadId(long id) {
         return new BsdThread(this, id);
@@ -601,6 +610,33 @@
         throw new DebuggerException("Unimplemented");
     }
 
+    /** this functions used for core file reading and called from native attach0,
+        it returns an array of long integers as
+        [thread_id, stack_start, stack_end, thread_id, stack_start, stack_end, ....] for
+        all java threads recorded in Threads. Also adds the ThreadProxy to threadList */
+    public long[] getJavaThreadsInfo() {
+        requireAttach();
+        Threads threads = VM.getVM().getThreads();
+        int len = threads.getNumberOfThreads();
+        long[] result = new long[len * 3];    // triple
+        JavaThread t = threads.first();
+        long beg, end;
+        int i = 0;
+        while (t != null) {
+            end = t.getStackBaseValue();
+            beg = end - t.getStackSize();
+            BsdThread bsdt = (BsdThread)t.getThreadProxy();
+            long uid = bsdt.getUniqueThreadId();
+            if (threadList != null) threadList.add(bsdt);
+            result[i] = uid;
+            result[i + 1] = beg;
+            result[i + 2] = end;
+            t = t.next();
+            i += 3;
+        }
+        return result;
+    }
+
     static {
         System.loadLibrary("saproc");
         init0();
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -44,7 +44,8 @@
 
     BsdThread(BsdDebugger debugger, long id) {
         this.debugger = debugger;
-        this.thread_id = (int) id;
+        // use unique_thread_id to identify thread
+        this.unique_thread_id = id;
     }
 
     public boolean equals(Object obj) {
@@ -52,7 +53,7 @@
             return false;
         }
 
-        return (((BsdThread) obj).thread_id == thread_id);
+        return (((BsdThread) obj).unique_thread_id == unique_thread_id);
     }
 
     public int hashCode() {
@@ -80,4 +81,9 @@
       throws IllegalThreadStateException, DebuggerException {
         throw new DebuggerException("Unimplemented");
     }
+
+    /** this is not interface function, used in core file to get unique thread id on Macosx*/
+    public long getUniqueThreadId() {
+        return unique_thread_id;
+    }
 }
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java	Fri Apr 12 10:14:42 2013 +0100
@@ -572,9 +572,14 @@
       DTFWHome = sysRoot + File.separator + ".." + File.separator +
           "Program Files" + File.separator + "Debugging Tools For Windows";
       searchList.add(DTFWHome);
-      searchList.add(DTFWHome + " (x86)");
-      searchList.add(DTFWHome + " (x64)");
 
+      // Only add the search path for the current CPU architecture:
+      String cpu = PlatformInfo.getCPU();
+      if (cpu.equals("x86")) {
+          searchList.add(DTFWHome + " (x86)");
+      } else if (cpu.equals("amd64")) {
+          searchList.add(DTFWHome + " (x64)");
+      }
       // The last place to search is the system directory:
       searchList.add(sysRoot + File.separator + "system32");
     }
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -148,7 +148,7 @@
     if (doVMFields) {
       visitor.doCInt(mark, true);
       if (VM.getVM().isCompressedKlassPointersEnabled()) {
-        throw new InternalError("unimplemented");
+        visitor.doMetadata(compressedKlass, true);
       } else {
         visitor.doMetadata(klass, true);
       }
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -320,6 +320,10 @@
     return stackBaseField.getValue(addr);
   }
 
+  public long getStackBaseValue() {
+    return VM.getVM().getAddressValue(getStackBase());
+  }
+
   public long getStackSize() {
     return stackSizeField.getValue(addr);
   }
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -42,6 +42,7 @@
 public class Threads {
     private static JavaThreadFactory threadFactory;
     private static AddressField      threadListField;
+    private static CIntegerField     numOfThreadsField;
     private static VirtualConstructor virtualConstructor;
     private static JavaThreadPDAccess access;
 
@@ -57,6 +58,7 @@
         Type type = db.lookupType("Threads");
 
         threadListField = type.getAddressField("_thread_list");
+        numOfThreadsField = type.getCIntegerField("_number_of_threads");
 
         // Instantiate appropriate platform-specific JavaThreadFactory
         String os  = VM.getVM().getOS();
@@ -102,6 +104,10 @@
             } else if (cpu.equals("amd64") || cpu.equals("x86_64")) {
                 access = new BsdAMD64JavaThreadPDAccess();
             }
+        } else if (os.equals("darwin")) {
+            if (cpu.equals("amd64") || cpu.equals("x86_64")) {
+                access = new BsdAMD64JavaThreadPDAccess();
+            }
         }
 
         if (access == null) {
@@ -144,6 +150,10 @@
         return createJavaThreadWrapper(threadAddr);
     }
 
+    public int getNumberOfThreads() {
+        return (int) numOfThreadsField.getValue();
+    }
+
     /** Routine for instantiating appropriately-typed wrapper for a
       JavaThread. Currently needs to be public for OopUtilities to
       access it. */
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -32,6 +32,7 @@
 import sun.jvm.hotspot.debugger.cdbg.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.utilities.PlatformInfo;
 
 public class PStack extends Tool {
     // in non-verbose mode, Method*s are not printed in java frames
@@ -54,6 +55,11 @@
    }
 
    public void run(PrintStream out, Debugger dbg) {
+      if (PlatformInfo.getOS().equals("darwin")) {
+        out.println("Not available on Darwin");
+        return;
+      }
+
       CDebugger cdbg = dbg.getCDebugger();
       if (cdbg != null) {
          ConcurrentLocksPrinter concLocksPrinter = null;
--- a/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java	Fri Apr 12 10:14:42 2013 +0100
@@ -24,10 +24,15 @@
 
 package sun.jvm.hotspot.types.basic;
 
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.types.*;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.debugger.MachineDescription;
 import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
 
 /** <P> This is a basic implementation of the TypeDataBase interface.
     It allows an external type database builder to add types to be
@@ -150,7 +155,7 @@
     return VM.getVM().getOopSize();
   }
 
-  static HashMap typeToVtbl = new HashMap();
+  HashMap typeToVtbl = new HashMap();
 
   private Address vtblForType(Type type) {
     Address vtblAddr = (Address)typeToVtbl.get(type);
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -43,8 +43,8 @@
       return "bsd";
     } else if (os.equals("OpenBSD")) {
       return "bsd";
-    } else if (os.equals("Darwin") || os.contains("OS X")) {
-      return "bsd";
+    } else if (os.contains("Darwin") || os.contains("OS X")) {
+      return "darwin";
     } else if (os.startsWith("Windows")) {
       return "win32";
     } else {
--- a/agent/src/share/native/sadis.c	Tue Feb 26 16:16:54 2013 -0800
+++ b/agent/src/share/native/sadis.c	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -48,7 +48,10 @@
 
 #include <string.h>
 #include <dlfcn.h>
+
+#ifndef __APPLE__
 #include <link.h>
+#endif
 
 #endif
 
@@ -109,9 +112,7 @@
                                                                            jstring libname_s) {
   uintptr_t func = 0;
   const char* error_message = NULL;
-  const char* java_home;
   jboolean isCopy;
-  uintptr_t *handle = NULL;
 
   const char * jrepath = (*env)->GetStringUTFChars(env, jrepath_s, &isCopy); // like $JAVA_HOME/jre/lib/sparc/
   const char * libname = (*env)->GetStringUTFChars(env, libname_s, &isCopy);
@@ -167,7 +168,8 @@
                              void* event_stream,
                              int (*printf_callback)(void*, const char*, ...),
                              void* printf_stream,
-                             const char* options);
+                             const char* options,
+                             int newline);
 
 /* container for call back state when decoding instructions */
 typedef struct {
@@ -281,7 +283,7 @@
                                                          end - start,
                                                          &event_to_env,  (void*) &denv,
                                                          &printf_to_env, (void*) &denv,
-                                                         options);
+                                                         options, 0 /* newline */);
 
   /* cleanup */
   (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT);
--- a/make/Makefile	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/Makefile	Fri Apr 12 10:14:42 2013 +0100
@@ -532,6 +532,39 @@
 	 $(TAR) -cf - *) | \
 	 ($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -)
 
+
+# Testing the built JVM
+RUN_JVM=JAVA_HOME=$(JDK_IMPORT_PATH) $(JDK_IMPORT_PATH)/bin/java -d$(ARCH_DATA_MODEL) -Dsun.java.launcher=gamma
+generic_test:
+	@$(ECHO) "Running with: $(ALTJVM_DIR)"
+	@$(RUN_JVM) -XXaltjvm=$(ALTJVM_DIR) -Xinternalversion
+	@$(RUN_JVM) -XXaltjvm=$(ALTJVM_DIR) -showversion -help
+
+# C2 test targets
+test_product test_optimized test_fastdebug test_jvmg:
+	@$(MAKE) generic_test ALTJVM_DIR="$(C2_DIR)/$(@:test_%=%)"
+
+# C1 test targets
+test_product1 test_optimized1 test_fastdebug1 test_jvmg1:
+  ifeq ($(ARCH_DATA_MODEL), 32)
+	@$(MAKE) generic_test ALTJVM_DIR="$(C1_DIR)/$(@:test_%1=%)"
+  else
+	@$(ECHO) "No compiler1 ($(@:test_%=%)) for ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)"
+  endif
+
+# Zero test targets
+test_productzero test_optimizedzero test_fastdebugzero test_jvmgzero:
+	@$(MAKE) generic_test ALTJVM_DIR="$(ZERO_DIR)/$(@:test_%zero=%)"
+
+# Shark test targets
+test_productshark test_optimizedshark test_fastdebugshark test_jvmgshark:
+	@$(MAKE) generic_test ALTJVM_DIR="$(SHARK_DIR)/$(@:test_%shark=%)"
+
+# Minimal1 test targets
+test_productminimal1 test_optimizedminimal1 test_fastdebugminimal1 test_jvmgminimal1:
+	@$(MAKE) generic_test ALTJVM_DIR="$(MINIMAL1_DIR)/$(@:test_%minimal1=%)"
+
+
 test_jdk:
   ifeq ($(JVM_VARIANT_CLIENT), true)
 	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -client -Xinternalversion
--- a/make/bsd/Makefile	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/bsd/Makefile	Fri Apr 12 10:14:42 2013 +0100
@@ -299,63 +299,42 @@
 
 $(TARGETS_C2):  $(SUBDIRS_C2)
 	cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_TIERED):  $(SUBDIRS_TIERED)
 	cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_C1):  $(SUBDIRS_C1)
 	cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_CORE):  $(SUBDIRS_CORE)
 	cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_ZERO):  $(SUBDIRS_ZERO)
 	cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_SHARK):  $(SUBDIRS_SHARK)
 	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_MINIMAL1):  $(SUBDIRS_MINIMAL1)
 	cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && $(MAKE) $(MFLAGS) install
 endif
--- a/make/bsd/build.sh	Tue Feb 26 16:16:54 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) 1999, 2008, 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.
-#  
-#
-
-# Make sure the variable JAVA_HOME is set before running this script.
-
-set -u
-
-
-if [ $# != 2 ]; then 
-    echo "Usage : $0 Build_Options Location"
-    echo "Build Options : debug or optimized or basicdebug or basic or clean"
-    echo "Location : specify any workspace which has gamma sources"
-    exit 1
-fi
-
-# Just in case:
-case ${JAVA_HOME} in
-/*) true;;
-?*) JAVA_HOME=`( cd $JAVA_HOME; pwd )`;;
-esac
-
-case `uname -m` in
-  i386|i486|i586|i686)
-    mach=i386
-    ;;
-  *)
-    echo "Unsupported machine: " `uname -m`
-    exit 1
-    ;;
-esac
-
-if [ "${JAVA_HOME}" = ""  -o  ! -d "${JAVA_HOME}" -o ! -d ${JAVA_HOME}/jre/lib/${mach} ]; then
-    echo "JAVA_HOME needs to be set to a valid JDK path"
-    echo "ksh : export JAVA_HOME=/net/tetrasparc/export/gobi/JDK1.2_fcs_V/bsd"
-    echo "csh : setenv JAVA_HOME /net/tetrasparc/export/gobi/JDK1.2_fcs_V/bsd"
-    exit 1
-fi
-
-
-LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/`uname -p`:\
-${JAVA_HOME}/jre/lib/`uname -p`/native_threads:${LD_LIBRARY_PATH-.}
-
-# This is necessary as long as we are using the old launcher
-# with the new distribution format:
-CLASSPATH=${JAVA_HOME}/jre/lib/rt.jar:${CLASSPATH-.}
-
-
-for gm in gmake gnumake
-do
-  if [ "${GNUMAKE-}" != "" ]; then break; fi
-  ($gm --version >/dev/null) 2>/dev/null && GNUMAKE=$gm
-done
-: ${GNUMAKE:?'Cannot locate the gnumake program.  Stop.'}
-
-
-echo "### ENVIRONMENT SETTINGS:"
-export JAVA_HOME		; echo "JAVA_HOME=$JAVA_HOME"
-export LD_LIBRARY_PATH		; echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
-export CLASSPATH		; echo "CLASSPATH=$CLASSPATH"
-export GNUMAKE			; echo "GNUMAKE=$GNUMAKE"
-echo "###"
-
-Build_Options=$1
-Location=$2
-
-case ${Location} in
-/*) true;;
-?*) Location=`(cd ${Location}; pwd)`;;
-esac
-
-echo \
-${GNUMAKE} -f ${Location}/make/bsd/Makefile $Build_Options GAMMADIR=${Location}
-${GNUMAKE} -f ${Location}/make/bsd/Makefile $Build_Options GAMMADIR=${Location}
--- a/make/bsd/makefiles/buildtree.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/bsd/makefiles/buildtree.make	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 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
@@ -50,7 +50,6 @@
 # jvmti.make	- generate JVMTI bindings from the spec (JSR-163)
 # sa.make	- generate SA jar file and natives
 # env.[ck]sh	- environment settings
-# test_gamma	- script to run the Queens program
 # 
 # The makefiles are split this way so that "make foo" will run faster by not
 # having to read the dependency files for the vm.
@@ -67,9 +66,6 @@
 # 'gmake MAKE_VERBOSE=y' or 'gmake QUIETLY=' gives all the gory details.
 QUIETLY$(MAKE_VERBOSE)	= @
 
-# For now, until the compiler is less wobbly:
-TESTFLAGS	= -Xbatch -showversion
-
 ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
 else
@@ -135,7 +131,7 @@
 # dtrace.make is used on BSD versions that implement Dtrace (like MacOS X)
 BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make \
 	jvmti.make sa.make dtrace.make \
-        env.sh env.csh jdkpath.sh .dbxrc test_gamma
+        env.sh env.csh jdkpath.sh
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -194,6 +190,17 @@
 # literal "$(GAMMADIR)/" suitable for inclusion in a Makefile.  
 gamma-path=$(subst $(GAMMADIR),\$$(GAMMADIR),$(call $(1),$(HS_COMMON_SRC)/$(2)))
 
+# This bit is needed to enable local rebuilds.
+# Unless the makefile itself sets LP64, any environmental
+# setting of LP64 will interfere with the build.
+LP64_SETTING/32 = LP64 = \#empty
+LP64_SETTING/64 = LP64 = 1
+
+DATA_MODE/i486 = 32
+DATA_MODE/amd64 = 64
+
+DATA_MODE = $(DATA_MODE/$(BUILDARCH))
+
 flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
@@ -216,6 +223,7 @@
 	echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \
 	echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \
 	echo "OPENJDK = $(OPENJDK)"; \
+	echo "$(LP64_SETTING/$(DATA_MODE))"; \
 	echo; \
 	echo "# Used for platform dispatching"; \
 	echo "TARGET_DEFINES  = -DTARGET_OS_FAMILY_\$$(Platform_os_family)"; \
@@ -352,7 +360,7 @@
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	$(BUILDTREE_COMMENT); \
-	[ -n "$$JAVA_HOME" ] && { echo ": \$${JAVA_HOME:=$${JAVA_HOME}}"; }; \
+	{ echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \
 	{ \
 	echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
 	} | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
@@ -364,8 +372,7 @@
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	$(BUILDTREE_COMMENT); \
-	[ -n "$$JAVA_HOME" ] && \
-	{ echo "if (! \$$?JAVA_HOME) setenv JAVA_HOME \"$$JAVA_HOME\""; }; \
+	{ echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \
 	sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
 	) > $@
 
@@ -376,119 +383,6 @@
 	echo "JDK=${JAVA_HOME}"; \
 	) > $@	   
 
-.dbxrc:  $(BUILDTREE_MAKE)
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	echo "echo '# Loading $(PLATFORM_DIR)/$(TARGET)/.dbxrc'"; \
-	echo "if [ -f \"\$${HOTSPOT_DBXWARE}\" ]"; \
-	echo "then"; \
-	echo "	source \"\$${HOTSPOT_DBXWARE}\""; \
-	echo "elif [ -f \"\$$HOME/.dbxrc\" ]"; \
-	echo "then"; \
-	echo "	source \"\$$HOME/.dbxrc\""; \
-	echo "fi"; \
-	) > $@
-
-# Skip the test for product builds (which only work when installed in a JDK), to
-# avoid exiting with an error and causing make to halt.
-NO_TEST_MSG	= \
-	echo "$@:  skipping the test--this build must be tested in a JDK."
-
-NO_JAVA_HOME_MSG	= \
-	echo "JAVA_HOME must be set to run this test."
-
-DATA_MODE = $(DATA_MODE/$(BUILDARCH))
-JAVA_FLAG = $(JAVA_FLAG/$(DATA_MODE))
-
-DATA_MODE/i486    = 32
-DATA_MODE/sparc   = 32
-DATA_MODE/sparcv9 = 64
-DATA_MODE/amd64   = 64
-DATA_MODE/ia64    = 64
-DATA_MODE/zero    = $(ARCH_DATA_MODEL)
-
-JAVA_FLAG/32 = -d32
-JAVA_FLAG/64 = -d64
-
-WRONG_DATA_MODE_MSG = \
-	echo "JAVA_HOME must point to a $(DATA_MODE)-bit OpenJDK."
-
-CROSS_COMPILING_MSG = \
-	echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run."
-
-test_gamma:  $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	echo "#!/bin/sh"; \
-	echo ""; \
-	$(BUILDTREE_COMMENT); \
-	echo ""; \
-	echo "# Include environment settings for gamma run"; \
-	echo ""; \
-	echo ". ./env.sh"; \
-	echo ""; \
-	echo "# Do not run gamma test for cross compiles"; \
-	echo ""; \
-	echo "if [ -n \"$(CROSS_COMPILE_ARCH)\" ]; then "; \
-	echo "  $(CROSS_COMPILING_MSG)"; \
-	echo "  exit 0"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Make sure JAVA_HOME is set as it is required for gamma"; \
-	echo ""; \
-	echo "if [ -z \"\$${JAVA_HOME}\" ]; then "; \
-	echo "  $(NO_JAVA_HOME_MSG)"; \
-	echo "  exit 0"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Check JAVA_HOME version to be used for the test"; \
-	echo ""; \
-	echo "\$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion > /dev/null 2>&1"; \
-	echo "if [ \$$? -ne 0 ]; then "; \
-	echo "  $(WRONG_DATA_MODE_MSG)"; \
-	echo "  exit 0"; \
-	echo "fi"; \
-	echo ""; \
-	echo "GAMMA_PROG=gamma"; \
-	echo ""; \
-	echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
-	echo "  # Ensure architecture for gamma and JAVA_HOME is the same."; \
-	echo "  # NOTE: gamma assumes the OpenJDK directory layout."; \
-	echo ""; \
-	echo "  GAMMA_ARCH=\"\`file \$${GAMMA_PROG} | awk '{print \$$NF}'\`\""; \
-	echo "  JVM_LIB=\"\$${JAVA_HOME}/jre/lib/libjava.$(LIBRARY_SUFFIX)\""; \
-	echo "  if [ ! -f \$${JVM_LIB} ]; then"; \
-	echo "    JVM_LIB=\"\$${JAVA_HOME}/jre/lib/$${LIBARCH}/libjava.$(LIBRARY_SUFFIX)\""; \
-	echo "  fi"; \
-	echo "  if [ ! -f \$${JVM_LIB} ] || [ -z \"\`file \$${JVM_LIB} | grep \$${GAMMA_ARCH}\`\" ]; then "; \
-	echo "    $(WRONG_DATA_MODE_MSG)"; \
-	echo "    exit 0"; \
-	echo "  fi"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Compile Queens program for test"; \
-	echo ""; \
-	echo "rm -f Queens.class"; \
-	echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \
-	echo ""; \
-	echo "# Set library path solely for gamma launcher test run"; \
-	echo ""; \
-	echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
-	echo "export LD_LIBRARY_PATH"; \
-	echo "unset LD_LIBRARY_PATH_32"; \
-	echo "unset LD_LIBRARY_PATH_64"; \
-	echo ""; \
-	echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
-	echo "  DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/native_threads:\$${JAVA_HOME}/jre/lib:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
-	echo "  export DYLD_LIBRARY_PATH"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Use the gamma launcher and JAVA_HOME to run the test"; \
-	echo ""; \
-	echo "./\$${GAMMA_PROG} $(TESTFLAGS) Queens < /dev/null"; \
-	) > $@
-	$(QUIETLY) chmod +x $@
-
 FORCE:
 
 .PHONY:  all FORCE
--- a/make/bsd/makefiles/mapfile-vers-debug	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/bsd/makefiles/mapfile-vers-debug	Fri Apr 12 10:14:42 2013 +0100
@@ -135,6 +135,7 @@
                 JVM_GetEnclosingMethodInfo;
                 JVM_GetFieldAnnotations;
                 JVM_GetFieldIxModifiers;
+                JVM_GetFieldTypeAnnotations;
                 JVM_GetHostName;
                 JVM_GetInheritedAccessControlContext;
                 JVM_GetInterfaceVersion;
@@ -156,6 +157,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameterAnnotations;
                 JVM_GetMethodParameters;
+                JVM_GetMethodTypeAnnotations;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetSockName;
--- a/make/bsd/makefiles/mapfile-vers-product	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/bsd/makefiles/mapfile-vers-product	Fri Apr 12 10:14:42 2013 +0100
@@ -135,6 +135,7 @@
                 JVM_GetEnclosingMethodInfo;
                 JVM_GetFieldAnnotations;
                 JVM_GetFieldIxModifiers;
+                JVM_GetFieldTypeAnnotations;
                 JVM_GetHostName;
                 JVM_GetInheritedAccessControlContext;
                 JVM_GetInterfaceVersion;
@@ -156,6 +157,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameterAnnotations;
                 JVM_GetMethodParameters;
+                JVM_GetMethodTypeAnnotations;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetSockName;
--- a/make/bsd/makefiles/saproc.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/bsd/makefiles/saproc.make	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 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
@@ -24,7 +24,7 @@
 
 # Rules to build serviceability agent library, used by vm.make
 
-# libsaproc.so: serviceability agent
+# libsaproc.so(dylib): serviceability agent
 SAPROC   = saproc
 
 ifeq ($(OS_VENDOR), Darwin)
@@ -37,7 +37,7 @@
 
 SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family)
 
-NON_STUB_SASRCFILES = $(SASRCDIR)/salibelf.c                 \
+BSD_NON_STUB_SASRCFILES = $(SASRCDIR)/salibelf.c             \
                       $(SASRCDIR)/symtab.c                   \
                       $(SASRCDIR)/libproc_impl.c             \
                       $(SASRCDIR)/ps_proc.c                  \
@@ -45,13 +45,19 @@
                       $(SASRCDIR)/BsdDebuggerLocal.c         \
                       $(AGENT_DIR)/src/share/native/sadis.c
 
+DARWIN_NON_STUB_SASRCFILES = $(SASRCDIR)/symtab.c            \
+                      $(SASRCDIR)/libproc_impl.c             \
+                      $(SASRCDIR)/ps_core.c                  \
+                      $(SASRCDIR)/MacosxDebuggerLocal.m      \
+                      $(AGENT_DIR)/src/share/native/sadis.c
+
 ifeq ($(OS_VENDOR), FreeBSD)
-  SASRCFILES = $(NON_STUB_SASRCFILES)
+  SASRCFILES = $(BSD_NON_STUB_SASRCFILES)
   SALIBS = -lutil -lthread_db
   SAARCH = $(ARCHFLAG)
 else
   ifeq ($(OS_VENDOR), Darwin)
-    SASRCFILES = $(SASRCDIR)/MacosxDebuggerLocal.m
+    SASRCFILES = $(DARWIN_NON_STUB_SASRCFILES)
     SALIBS = -g -framework Foundation -F/System/Library/Frameworks/JavaVM.framework/Frameworks -framework JavaNativeFoundation -framework Security -framework CoreFoundation
     #objc compiler blows up on -march=i586, perhaps it should not be included in the macosx intel 32-bit C++ compiles?
     SAARCH = $(subst -march=i586,,$(ARCHFLAG))
@@ -102,7 +108,7 @@
 	fi
 	@echo Making SA debugger back-end...
 	$(QUIETLY) $(CC) -D$(BUILDARCH) -D_GNU_SOURCE                   \
-                   $(SYMFLAG) $(SAARCH) $(SHARED_FLAG) $(PICFLAG)     \
+	           $(SYMFLAG) $(SAARCH) $(SHARED_FLAG) $(PICFLAG)       \
 	           -I$(SASRCDIR)                                        \
 	           -I$(GENERATED)                                       \
 	           $(BOOT_JAVA_INCLUDES)                                \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/build.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,92 @@
+#! /bin/sh
+#
+# Copyright (c) 1998, 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.
+#  
+#
+
+# Make sure the variable JAVA_HOME is set before running this script.
+
+set -u
+
+
+if [ $# -lt 1 ]; then 
+    echo "Usage : $0 BuildTarget [LP64=1] [BuildOptions]"
+    echo "               Server VM | Client VM"
+    echo "BuildTarget :  debug     | debug1"
+    echo "               fastdebug | fastdebug1"
+    echo "               jvmg      | jvmg1"
+    echo "               optimized | optimized1"
+    echo "               profiled  | profiled1"
+    echo "               product   | product1"
+    exit 1
+fi
+
+if [ "${JAVA_HOME-}" = ""  -o  ! -d "${JAVA_HOME-}" -o ! -d ${JAVA_HOME-}/jre/lib/ ]; then
+    echo "JAVA_HOME needs to be set to a valid JDK path"
+    echo "JAVA_HOME: ${JAVA_HOME-}"
+    exit 1
+fi
+
+# Just in case:
+JAVA_HOME=`( cd $JAVA_HOME; pwd )`
+
+if [ "${ALT_BOOTDIR-}" = ""  -o  ! -d "${ALT_BOOTDIR-}" -o ! -d ${ALT_BOOTDIR-}/jre/lib/ ]; then
+    ALT_BOOTDIR=${JAVA_HOME}
+fi
+
+# build in current directory by default
+if [ "${ALT_OUTPUTDIR-}" = ""  -o  ! -d "${ALT_OUTPUTDIR-}" ]; then
+    ALT_OUTPUTDIR=`(pwd)`
+fi
+
+HOTSPOT_SRC=`(dirname $0)`/..
+HOTSPOT_SRC=`(cd ${HOTSPOT_SRC}; pwd)`
+
+for gm in gmake gnumake
+do
+  if [ "${GNUMAKE-}" != "" ]; then break; fi
+  ($gm --version >/dev/null) 2>/dev/null && GNUMAKE=$gm
+done
+: ${GNUMAKE:?'Cannot locate the gnumake program.  Stop.'}
+
+# quiet build by default
+Quiet="MAKE_VERBOSE="
+
+# no debug info by default
+NoDebugInfo="ENABLE_FULL_DEBUG_SYMBOLS="
+
+LANG=C
+
+echo "### ENVIRONMENT SETTINGS:"
+export HOTSPOT_SRC		; echo "HOTSPOT_SRC=$HOTSPOT_SRC"
+export JAVA_HOME		; echo "JAVA_HOME=$JAVA_HOME"
+export ALT_BOOTDIR		; echo "ALT_BOOTDIR=$ALT_BOOTDIR"
+export ALT_OUTPUTDIR		; echo "ALT_OUTPUTDIR=$ALT_OUTPUTDIR"
+export GNUMAKE			; echo "GNUMAKE=$GNUMAKE"
+export LANG			; echo "LANG=$LANG"
+echo "###"
+
+BuildOptions="$Quiet $NoDebugInfo $*"
+
+echo \
+${GNUMAKE} -f ${HOTSPOT_SRC}/make/Makefile $BuildOptions GAMMADIR=${HOTSPOT_SRC}
+${GNUMAKE} -f ${HOTSPOT_SRC}/make/Makefile $BuildOptions GAMMADIR=${HOTSPOT_SRC}
--- a/make/defs.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/defs.make	Fri Apr 12 10:14:42 2013 +0100
@@ -302,7 +302,7 @@
 endif
 
 # Required make macro settings for all platforms
-MAKE_ARGS += JAVA_HOME=$(ABS_BOOTDIR)
+MAKE_ARGS += BOOTDIR=$(ABS_BOOTDIR)
 MAKE_ARGS += OUTPUTDIR=$(ABS_OUTPUTDIR)
 MAKE_ARGS += GAMMADIR=$(ABS_GAMMADIR)
 MAKE_ARGS += MAKE_VERBOSE=$(MAKE_VERBOSE)
@@ -337,9 +337,6 @@
 EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h
 EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h
 
-# By default, run Queens test after building
-TEST_IN_BUILD ?= true
-
 ifndef JAVASE_EMBEDDED
 EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jfr.h
 endif
--- a/make/excludeSrc.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/excludeSrc.make	Fri Apr 12 10:14:42 2013 +0100
@@ -28,7 +28,8 @@
       Src_Files_EXCLUDE += jvmtiGetLoadedClasses.cpp forte.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \
 	jvmtiImpl.cpp jvmtiManageCapabilities.cpp jvmtiRawMonitor.cpp jvmtiUtil.cpp jvmtiTrace.cpp \
 	jvmtiCodeBlobEvents.cpp jvmtiEnv.cpp jvmtiRedefineClasses.cpp jvmtiEnvBase.cpp jvmtiEnvThreadState.cpp \
-	jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp
+	jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp \
+	jvmtiClassFileReconstituter.cpp
 endif
 
 ifeq ($(INCLUDE_FPROF), false)
--- a/make/hotspot_version	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/hotspot_version	Fri Apr 12 10:14:42 2013 +0100
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=25
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=23
+HS_BUILD_NUMBER=27
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
--- a/make/jprt.properties	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/jprt.properties	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -97,15 +97,18 @@
 jprt.my.linux.ppcsflt.jdk7u8=${jprt.my.linux.ppcsflt.jdk7}
 jprt.my.linux.ppcsflt=${jprt.my.linux.ppcsflt.${jprt.tools.default.release}}
 
-jprt.my.linux.armvfp.jdk8=linux_armvfp_2.6
-jprt.my.linux.armvfp.jdk7=linux_armvfp_2.6
-jprt.my.linux.armvfp.jdk7u8=${jprt.my.linux.armvfp.jdk7}
-jprt.my.linux.armvfp=${jprt.my.linux.armvfp.${jprt.tools.default.release}}
+jprt.my.linux.armvfpsflt.jdk8=linux_armvfpsflt_2.6
+jprt.my.linux.armvfpsflt=${jprt.my.linux.armvfpsflt.${jprt.tools.default.release}}
+
+jprt.my.linux.armvfphflt.jdk8=linux_armvfphflt_2.6
+jprt.my.linux.armvfphflt=${jprt.my.linux.armvfphflt.${jprt.tools.default.release}}
 
-jprt.my.linux.armv6.jdk8=linux_armv6_2.6
-jprt.my.linux.armv6.jdk7=linux_armv6_2.6
-jprt.my.linux.armv6.jdk7u8=${jprt.my.linux.armv6.jdk7}
-jprt.my.linux.armv6=${jprt.my.linux.armv6.${jprt.tools.default.release}}
+# The ARM GP vfp-sflt build is not currently supported
+#jprt.my.linux.armvs.jdk8=linux_armvs_2.6
+#jprt.my.linux.armvs=${jprt.my.linux.armvs.${jprt.tools.default.release}}
+
+jprt.my.linux.armvh.jdk8=linux_armvh_2.6
+jprt.my.linux.armvh=${jprt.my.linux.armvh.${jprt.tools.default.release}}
 
 jprt.my.linux.armsflt.jdk8=linux_armsflt_2.6
 jprt.my.linux.armsflt.jdk7=linux_armsflt_2.6
@@ -139,7 +142,7 @@
     ${jprt.my.macosx.x64}-{product|fastdebug|debug}, \
     ${jprt.my.windows.i586}-{product|fastdebug|debug}, \
     ${jprt.my.windows.x64}-{product|fastdebug|debug}, \
-    ${jprt.my.linux.armv6}-{product|fastdebug}
+    ${jprt.my.linux.armvh}-{product|fastdebug}
 
 jprt.build.targets.open= \
     ${jprt.my.solaris.i586}-{productOpen}, \
@@ -151,7 +154,8 @@
     ${jprt.my.linux.ppc}-{productEmb|fastdebugEmb}, \
     ${jprt.my.linux.ppcv2}-{productEmb|fastdebugEmb}, \
     ${jprt.my.linux.ppcsflt}-{productEmb|fastdebugEmb}, \
-    ${jprt.my.linux.armvfp}-{productEmb|fastdebugEmb}, \
+    ${jprt.my.linux.armvfpsflt}-{productEmb|fastdebugEmb}, \
+    ${jprt.my.linux.armvfphflt}-{productEmb|fastdebugEmb}, \
     ${jprt.my.linux.armsflt}-{productEmb|fastdebugEmb}
 
 jprt.build.targets.all=${jprt.build.targets.standard}, \
--- a/make/linux/Makefile	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/linux/Makefile	Fri Apr 12 10:14:42 2013 +0100
@@ -300,63 +300,42 @@
 
 $(TARGETS_C2):  $(SUBDIRS_C2)
 	cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_TIERED):  $(SUBDIRS_TIERED)
 	cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_C1):  $(SUBDIRS_C1)
 	cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_CORE):  $(SUBDIRS_CORE)
 	cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_ZERO):  $(SUBDIRS_ZERO)
 	cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_SHARK):  $(SUBDIRS_SHARK)
 	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_MINIMAL1):  $(SUBDIRS_MINIMAL1)
 	cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && $(MAKE) $(MFLAGS) install
 endif
--- a/make/linux/build.sh	Tue Feb 26 16:16:54 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) 1999, 2011, 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.
-#  
-#
-
-# Make sure the variable JAVA_HOME is set before running this script.
-
-set -u
-
-
-if [ $# != 2 ]; then 
-    echo "Usage : $0 Build_Options Location"
-    echo "Build Options : debug or optimized or basicdebug or basic or clean"
-    echo "Location : specify any workspace which has gamma sources"
-    exit 1
-fi
-
-# Just in case:
-case ${JAVA_HOME} in
-/*) true;;
-?*) JAVA_HOME=`( cd $JAVA_HOME; pwd )`;;
-esac
-
-case `uname -m` in
-  i386|i486|i586|i686)
-    mach=i386
-    ;;
-  x86_64)
-    mach=amd64
-    ;;
-  *)
-    echo "Unsupported machine: " `uname -m`
-    exit 1
-    ;;
-esac
-
-if [ "${JAVA_HOME}" = ""  -o  ! -d "${JAVA_HOME}" -o ! -d ${JAVA_HOME}/jre/lib/${mach} ]; then
-    echo "JAVA_HOME needs to be set to a valid JDK path"
-    echo "ksh : export JAVA_HOME=/net/tetrasparc/export/gobi/JDK1.2_fcs_V/linux"
-    echo "csh : setenv JAVA_HOME /net/tetrasparc/export/gobi/JDK1.2_fcs_V/linux"
-    exit 1
-fi
-
-
-LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/`uname -p`:\
-${JAVA_HOME}/jre/lib/`uname -p`/native_threads:${LD_LIBRARY_PATH-.}
-
-# This is necessary as long as we are using the old launcher
-# with the new distribution format:
-CLASSPATH=${JAVA_HOME}/jre/lib/rt.jar:${CLASSPATH-.}
-
-
-for gm in gmake gnumake
-do
-  if [ "${GNUMAKE-}" != "" ]; then break; fi
-  ($gm --version >/dev/null) 2>/dev/null && GNUMAKE=$gm
-done
-: ${GNUMAKE:?'Cannot locate the gnumake program.  Stop.'}
-
-
-echo "### ENVIRONMENT SETTINGS:"
-export JAVA_HOME		; echo "JAVA_HOME=$JAVA_HOME"
-export LD_LIBRARY_PATH		; echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
-export CLASSPATH		; echo "CLASSPATH=$CLASSPATH"
-export GNUMAKE			; echo "GNUMAKE=$GNUMAKE"
-echo "###"
-
-Build_Options=$1
-Location=$2
-
-case ${Location} in
-/*) true;;
-?*) Location=`(cd ${Location}; pwd)`;;
-esac
-
-echo \
-${GNUMAKE} -f ${Location}/make/linux/Makefile $Build_Options GAMMADIR=${Location}
-${GNUMAKE} -f ${Location}/make/linux/Makefile $Build_Options GAMMADIR=${Location}
--- a/make/linux/makefiles/buildtree.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/linux/makefiles/buildtree.make	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 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
@@ -50,7 +50,6 @@
 # jvmti.make	- generate JVMTI bindings from the spec (JSR-163)
 # sa.make	- generate SA jar file and natives
 # env.[ck]sh	- environment settings
-# test_gamma	- script to run the Queens program
 # 
 # The makefiles are split this way so that "make foo" will run faster by not
 # having to read the dependency files for the vm.
@@ -64,9 +63,6 @@
 # 'gmake MAKE_VERBOSE=y' or 'gmake QUIETLY=' gives all the gory details.
 QUIETLY$(MAKE_VERBOSE)	= @
 
-# For now, until the compiler is less wobbly:
-TESTFLAGS	= -Xbatch -showversion
-
 ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
 else
@@ -128,7 +124,7 @@
 BUILDTREE_MAKE	= $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
 
 BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
-        env.sh env.csh jdkpath.sh .dbxrc test_gamma
+        env.sh env.csh jdkpath.sh
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -187,6 +183,19 @@
 # literal "$(GAMMADIR)/" suitable for inclusion in a Makefile.  
 gamma-path=$(subst $(GAMMADIR),\$$(GAMMADIR),$(call $(1),$(HS_COMMON_SRC)/$(2)))
 
+# This bit is needed to enable local rebuilds.
+# Unless the makefile itself sets LP64, any environmental
+# setting of LP64 will interfere with the build.
+LP64_SETTING/32 = LP64 = \#empty
+LP64_SETTING/64 = LP64 = 1
+
+DATA_MODE/i486 = 32
+DATA_MODE/sparc = 32
+DATA_MODE/sparcv9 = 64
+DATA_MODE/amd64 = 64
+
+DATA_MODE = $(DATA_MODE/$(BUILDARCH))
+
 flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
@@ -209,6 +218,7 @@
 	echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \
 	echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \
 	echo "OPENJDK = $(OPENJDK)"; \
+	echo "$(LP64_SETTING/$(DATA_MODE))"; \
 	echo; \
 	echo "# Used for platform dispatching"; \
 	echo "TARGET_DEFINES  = -DTARGET_OS_FAMILY_\$$(Platform_os_family)"; \
@@ -345,7 +355,7 @@
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	$(BUILDTREE_COMMENT); \
-	[ -n "$$JAVA_HOME" ] && { echo ": \$${JAVA_HOME:=$${JAVA_HOME}}"; }; \
+	{ echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \
 	{ \
 	echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
 	} | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
@@ -357,8 +367,7 @@
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	$(BUILDTREE_COMMENT); \
-	[ -n "$$JAVA_HOME" ] && \
-	{ echo "if (! \$$?JAVA_HOME) setenv JAVA_HOME \"$$JAVA_HOME\""; }; \
+	{ echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \
 	sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
 	) > $@
 
@@ -369,119 +378,6 @@
 	echo "JDK=${JAVA_HOME}"; \
 	) > $@	   
 
-.dbxrc:  $(BUILDTREE_MAKE)
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	echo "echo '# Loading $(PLATFORM_DIR)/$(TARGET)/.dbxrc'"; \
-	echo "if [ -f \"\$${HOTSPOT_DBXWARE}\" ]"; \
-	echo "then"; \
-	echo "	source \"\$${HOTSPOT_DBXWARE}\""; \
-	echo "elif [ -f \"\$$HOME/.dbxrc\" ]"; \
-	echo "then"; \
-	echo "	source \"\$$HOME/.dbxrc\""; \
-	echo "fi"; \
-	) > $@
-
-# Skip the test for product builds (which only work when installed in a JDK), to
-# avoid exiting with an error and causing make to halt.
-NO_TEST_MSG	= \
-	echo "$@:  skipping the test--this build must be tested in a JDK."
-
-NO_JAVA_HOME_MSG	= \
-	echo "JAVA_HOME must be set to run this test."
-
-DATA_MODE = $(DATA_MODE/$(BUILDARCH))
-JAVA_FLAG = $(JAVA_FLAG/$(DATA_MODE))
-
-DATA_MODE/i486    = 32
-DATA_MODE/sparc   = 32
-DATA_MODE/sparcv9 = 64
-DATA_MODE/amd64   = 64
-DATA_MODE/ia64    = 64
-DATA_MODE/zero    = $(ARCH_DATA_MODEL)
-
-JAVA_FLAG/32 = -d32
-JAVA_FLAG/64 = -d64
-
-WRONG_DATA_MODE_MSG = \
-	echo "JAVA_HOME must point to a $(DATA_MODE)-bit OpenJDK."
-
-CROSS_COMPILING_MSG = \
-	echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run."
-
-test_gamma:  $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	echo "#!/bin/sh"; \
-	echo ""; \
-	$(BUILDTREE_COMMENT); \
-	echo ""; \
-	echo "# Include environment settings for gamma run"; \
-	echo ""; \
-	echo ". ./env.sh"; \
-	echo ""; \
-	echo "# Do not run gamma test for cross compiles"; \
-	echo ""; \
-	echo "if [ -n \"$(CROSS_COMPILE_ARCH)\" ]; then "; \
-	echo "  $(CROSS_COMPILING_MSG)"; \
-	echo "  exit 0"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Make sure JAVA_HOME is set as it is required for gamma"; \
-	echo ""; \
-	echo "if [ -z \"\$${JAVA_HOME}\" ]; then "; \
-	echo "  $(NO_JAVA_HOME_MSG)"; \
-	echo "  exit 0"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Check JAVA_HOME version to be used for the test"; \
-	echo ""; \
-	echo "\$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion > /dev/null 2>&1"; \
-	echo "if [ \$$? -ne 0 ]; then "; \
-	echo "  $(WRONG_DATA_MODE_MSG)"; \
-	echo "  exit 0"; \
-	echo "fi"; \
-	echo ""; \
-	echo "GAMMA_PROG=gamma"; \
-	echo ""; \
-	echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
-	echo "  # Ensure architecture for gamma and JAVA_HOME is the same."; \
-	echo "  # NOTE: gamma assumes the OpenJDK directory layout."; \
-	echo ""; \
-	echo "  GAMMA_ARCH=\"\`file \$${GAMMA_PROG} | awk '{print \$$NF}'\`\""; \
-	echo "  JVM_LIB=\"\$${JAVA_HOME}/jre/lib/libjava.$(LIBRARY_SUFFIX)\""; \
-	echo "  if [ ! -f \$${JVM_LIB} ]; then"; \
-	echo "    JVM_LIB=\"\$${JAVA_HOME}/jre/lib/$${LIBARCH}/libjava.$(LIBRARY_SUFFIX)\""; \
-	echo "  fi"; \
-	echo "  if [ ! -f \$${JVM_LIB} ] || [ -z \"\`file \$${JVM_LIB} | grep \$${GAMMA_ARCH}\`\" ]; then "; \
-	echo "    $(WRONG_DATA_MODE_MSG)"; \
-	echo "    exit 0"; \
-	echo "  fi"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Compile Queens program for test"; \
-	echo ""; \
-	echo "rm -f Queens.class"; \
-	echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \
-	echo ""; \
-	echo "# Set library path solely for gamma launcher test run"; \
-	echo ""; \
-	echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
-	echo "export LD_LIBRARY_PATH"; \
-	echo "unset LD_LIBRARY_PATH_32"; \
-	echo "unset LD_LIBRARY_PATH_64"; \
-	echo ""; \
-	echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
-	echo "  DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/native_threads:\$${JAVA_HOME}/jre/lib:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
-	echo "  export DYLD_LIBRARY_PATH"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Use the gamma launcher and JAVA_HOME to run the test"; \
-	echo ""; \
-	echo "./\$${GAMMA_PROG} $(TESTFLAGS) Queens < /dev/null"; \
-	) > $@
-	$(QUIETLY) chmod +x $@
-
 FORCE:
 
 .PHONY:  all FORCE
--- a/make/linux/makefiles/gcc.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/linux/makefiles/gcc.make	Fri Apr 12 10:14:42 2013 +0100
@@ -126,14 +126,12 @@
 # Compiler warnings are treated as errors
 WARNINGS_ARE_ERRORS = -Werror
 
-# Except for a few acceptable ones
+WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function
+
 # Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
-# conversions which might affect the values. To avoid that, we need to turn
-# it off explicitly. 
-ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
-WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef
-else
-WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
+# conversions which might affect the values. Only enable it in earlier versions.
+ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
+WARNING_FLAGS += -Wconversion
 endif
 
 CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
--- a/make/linux/makefiles/mapfile-vers-debug	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/linux/makefiles/mapfile-vers-debug	Fri Apr 12 10:14:42 2013 +0100
@@ -131,6 +131,7 @@
                 JVM_GetEnclosingMethodInfo;
                 JVM_GetFieldAnnotations;
                 JVM_GetFieldIxModifiers;
+                JVM_GetFieldTypeAnnotations;
                 JVM_GetHostName;
                 JVM_GetInheritedAccessControlContext;
                 JVM_GetInterfaceVersion;
@@ -152,6 +153,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameterAnnotations;
                 JVM_GetMethodParameters;
+                JVM_GetMethodTypeAnnotations;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetSockName;
--- a/make/linux/makefiles/mapfile-vers-product	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/linux/makefiles/mapfile-vers-product	Fri Apr 12 10:14:42 2013 +0100
@@ -131,6 +131,7 @@
                 JVM_GetEnclosingMethodInfo;
                 JVM_GetFieldAnnotations;
                 JVM_GetFieldIxModifiers;
+                JVM_GetFieldTypeAnnotations;
                 JVM_GetHostName;
                 JVM_GetInheritedAccessControlContext;
                 JVM_GetInterfaceVersion;
@@ -152,6 +153,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameterAnnotations;
                 JVM_GetMethodParameters;
+                JVM_GetMethodTypeAnnotations;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetSockName;
--- a/make/solaris/Makefile	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/solaris/Makefile	Fri Apr 12 10:14:42 2013 +0100
@@ -231,36 +231,24 @@
 
 $(TARGETS_C2):  $(SUBDIRS_C2)
 	cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_TIERED):  $(SUBDIRS_TIERED)
 	cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_C1):  $(SUBDIRS_C1)
 	cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) install
 endif
 
 $(TARGETS_CORE):  $(SUBDIRS_CORE)
 	cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS)
-ifeq ($(TEST_IN_BUILD),true)
-	cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && ./test_gamma
-endif
 ifdef INSTALL
 	cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install
 endif
--- a/make/solaris/build.sh	Tue Feb 26 16:16:54 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) 1998, 2008, 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.
-#  
-#
-
-# Make sure the variable JAVA_HOME is set before running this script.
-
-set -u
-
-
-usage() {
-    (
-        echo "Usage : $0 [-sb | -sbfast] config ws_path"
-        echo ""
-        echo "Where:"
-        echo "    -sb     ::= enable source browser info generation for"
-        echo "                all configs during compilation"
-        echo ""
-        echo "    -sbfast ::= enable source browser info generation for"
-        echo "                all configs without compilation"
-        echo ""
-        echo "    config  ::= debug     | debug1     | debugcore"
-        echo "                fastdebug | fastdebug1 | fastdebugcore"
-        echo "                jvmg      | jvmg1      | jvmgcore"
-        echo "                optimized | optimized1 | optimizedcore"
-        echo "                profiled  | profiled1  | profiledcore"
-        echo "                product   | product1   | productcore"
-        echo ""
-        echo "    ws_path ::= path to HotSpot workspace"
-    ) >&2
-    exit 1
-}
-
-# extract possible options
-options=""
-if [ $# -gt 2 ]; then 
-    case "$1" in
-    -sb)
-	options="CFLAGS_BROWSE=-xsb"
-	shift
-	;;
-    -sbfast)
-	options="CFLAGS_BROWSE=-xsbfast"
-	shift
-	;;
-    *)
-	echo "Unknown option: '$1'" >&2
-	usage
-	;;
-    esac
-fi
-
-# should be just two args left at this point
-if [ $# != 2 ]; then 
-    usage
-fi
-
-# Just in case:
-case ${JAVA_HOME} in
-/*) true;;
-?*) JAVA_HOME=`( cd $JAVA_HOME; pwd )`;;
-esac
-
-if [ "${JAVA_HOME}" = ""  -o  ! -d "${JAVA_HOME}" -o ! -d ${JAVA_HOME}/jre/lib/`uname -p` ]; then
-    echo "JAVA_HOME needs to be set to a valid JDK path"
-    echo "ksh : export JAVA_HOME=/net/tetrasparc/export/gobi/JDK1.2_fcs_V/solaris"
-    echo "csh : setenv JAVA_HOME /net/tetrasparc/export/gobi/JDK1.2_fcs_V/solaris"
-    exit 1
-fi
-
-
-LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/`uname -p`:\
-${JAVA_HOME}/jre/lib/`uname -p`/native_threads:${LD_LIBRARY_PATH-.}
-
-# This is necessary as long as we are using the old launcher
-# with the new distribution format:
-CLASSPATH=${JAVA_HOME}/jre/lib/rt.jar:${CLASSPATH-.}
-
-
-for gm in gmake gnumake
-do
-  if [ "${GNUMAKE-}" != "" ]; then break; fi
-  ($gm --version >/dev/null) 2>/dev/null && GNUMAKE=$gm
-done
-: ${GNUMAKE:?'Cannot locate the gnumake program.  Stop.'}
-
-
-echo "### ENVIRONMENT SETTINGS:"
-export JAVA_HOME		; echo "JAVA_HOME=$JAVA_HOME"
-export LD_LIBRARY_PATH		; echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
-export CLASSPATH		; echo "CLASSPATH=$CLASSPATH"
-export GNUMAKE			; echo "GNUMAKE=$GNUMAKE"
-echo "###"
-
-config=$1
-ws_path=$2
-
-case ${ws_path} in
-/*) true;;
-?*) ws_path=`(cd ${ws_path}; pwd)`;;
-esac
-
-echo \
-${GNUMAKE} -f ${ws_path}/make/solaris/Makefile \
-    $config GAMMADIR=${ws_path} $options
-${GNUMAKE} -f ${ws_path}/make/solaris/Makefile \
-    $config GAMMADIR=${ws_path} $options
--- a/make/solaris/makefiles/buildtree.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/solaris/makefiles/buildtree.make	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 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
@@ -50,21 +50,19 @@
 # jvmti.make	- generate JVMTI bindings from the spec (JSR-163)
 # sa.make	- generate SA jar file and natives
 # env.[ck]sh	- environment settings
-# test_gamma	- script to run the Queens program
 # 
 # The makefiles are split this way so that "make foo" will run faster by not
 # having to read the dependency files for the vm.
 
 -include $(SPEC)
 include $(GAMMADIR)/make/scm.make
+include $(GAMMADIR)/make/defs.make
 include $(GAMMADIR)/make/altsrc.make
 
+
 # 'gmake MAKE_VERBOSE=y' or 'gmake QUIETLY=' gives all the gory details.
 QUIETLY$(MAKE_VERBOSE)	= @
 
-# For now, until the compiler is less wobbly:
-TESTFLAGS	= -Xbatch -Xmx32m -showversion
-
 ### maye ARCH_XXX instead?
 ifdef USE_GCC
 PLATFORM_FILE	= $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).gcc
@@ -119,7 +117,7 @@
 BUILDTREE_MAKE	= $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
 
 BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
-        env.sh env.csh jdkpath.sh .dbxrc test_gamma
+        env.sh env.csh jdkpath.sh
 
 BUILDTREE_VARS	= GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
 	ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -178,6 +176,19 @@
 # literal "$(GAMMADIR)/" suitable for inclusion in a Makefile.  
 gamma-path=$(subst $(GAMMADIR),\$$(GAMMADIR),$(call $(1),$(HS_COMMON_SRC)/$(2)))
 
+# This bit is needed to enable local rebuilds.
+# Unless the makefile itself sets LP64, any environmental
+# setting of LP64 will interfere with the build.
+LP64_SETTING/32 = LP64 = \#empty
+LP64_SETTING/64 = LP64 = 1
+
+DATA_MODE/i486 = 32
+DATA_MODE/sparc = 32
+DATA_MODE/sparcv9 = 64
+DATA_MODE/amd64 = 64
+
+DATA_MODE = $(DATA_MODE/$(BUILDARCH))
+
 flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
@@ -334,7 +345,7 @@
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	$(BUILDTREE_COMMENT); \
-	[ -n "$$JAVA_HOME" ] && { echo ": \$${JAVA_HOME:=$${JAVA_HOME}}"; }; \
+	{ echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \
 	{ \
 	echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
 	} | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
@@ -346,8 +357,7 @@
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	$(BUILDTREE_COMMENT); \
-	[ -n "$$JAVA_HOME" ] && \
-	{ echo "if (! \$$?JAVA_HOME) setenv JAVA_HOME \"$$JAVA_HOME\""; }; \
+	{ echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \
 	sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
 	) > $@
 
@@ -358,124 +368,6 @@
 	echo "JDK=${JAVA_HOME}"; \
 	) > $@	   
 
-.dbxrc:  $(BUILDTREE_MAKE)
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	echo "echo '# Loading $(PLATFORM_DIR)/$(TARGET)/.dbxrc'"; \
-	echo "if [ -f \"\$${HOTSPOT_DBXWARE}\" ]"; \
-	echo "then"; \
-	echo "	source \"\$${HOTSPOT_DBXWARE}\""; \
-	echo "elif [ -f \"\$$HOME/.dbxrc\" ]"; \
-	echo "then"; \
-	echo "	source \"\$$HOME/.dbxrc\""; \
-	echo "fi"; \
-	) > $@
-
-# Skip the test for product builds (which only work when installed in a JDK), to
-# avoid exiting with an error and causing make to halt.
-NO_TEST_MSG	= \
-	echo "$@:  skipping the test--this build must be tested in a JDK."
-
-NO_JAVA_HOME_MSG	= \
-	echo "JAVA_HOME must be set to run this test."
-
-DATA_MODE = $(DATA_MODE/$(BUILDARCH))
-JAVA_FLAG = $(JAVA_FLAG/$(DATA_MODE))
-
-DATA_MODE/i486    = 32
-DATA_MODE/sparc   = 32
-DATA_MODE/sparcv9 = 64
-DATA_MODE/amd64   = 64
-DATA_MODE/ia64    = 64
-
-# This bit is needed to enable local rebuilds.
-# Unless the makefile itself sets LP64, any environmental
-# setting of LP64 will interfere with the build.
-LP64_SETTING/32 = LP64 = \#empty
-LP64_SETTING/64 = LP64 = 1
-
-JAVA_FLAG/32 = -d32
-JAVA_FLAG/64 = -d64
-
-WRONG_DATA_MODE_MSG = \
-	echo "JAVA_HOME must point to a $(DATA_MODE)-bit OpenJDK."
-
-CROSS_COMPILING_MSG = \
-	echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run."
-
-test_gamma:  $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
-	@echo Creating $@ ...
-	$(QUIETLY) ( \
-	echo "#!/bin/sh"; \
-	echo ""; \
-	$(BUILDTREE_COMMENT); \
-	echo ""; \
-	echo "# Include environment settings for gamma run"; \
-	echo ""; \
-	echo ". ./env.sh"; \
-	echo ""; \
-	echo "# Do not run gamma test for cross compiles"; \
-	echo ""; \
-	echo "if [ -n \"$(CROSS_COMPILE_ARCH)\" ]; then "; \
-	echo "  $(CROSS_COMPILING_MSG)"; \
-	echo "  exit 0"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Make sure JAVA_HOME is set as it is required for gamma"; \
-	echo ""; \
-	echo "if [ -z \"\$${JAVA_HOME}\" ]; then "; \
-	echo "  $(NO_JAVA_HOME_MSG)"; \
-	echo "  exit 0"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Check JAVA_HOME version to be used for the test"; \
-	echo ""; \
-	echo "\$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion > /dev/null 2>&1"; \
-	echo "if [ \$$? -ne 0 ]; then "; \
-	echo "  $(WRONG_DATA_MODE_MSG)"; \
-	echo "  exit 0"; \
-	echo "fi"; \
-	echo ""; \
-	echo "GAMMA_PROG=gamma"; \
-	echo ""; \
-	echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
-	echo "  # Ensure architecture for gamma and JAVA_HOME is the same."; \
-	echo "  # NOTE: gamma assumes the OpenJDK directory layout."; \
-	echo ""; \
-	echo "  GAMMA_ARCH=\"\`file \$${GAMMA_PROG} | awk '{print \$$NF}'\`\""; \
-	echo "  JVM_LIB=\"\$${JAVA_HOME}/jre/lib/libjava.$(LIBRARY_SUFFIX)\""; \
-	echo "  if [ ! -f \$${JVM_LIB} ]; then"; \
-	echo "    JVM_LIB=\"\$${JAVA_HOME}/jre/lib/$${LIBARCH}/libjava.$(LIBRARY_SUFFIX)\""; \
-	echo "  fi"; \
-	echo "  if [ ! -f \$${JVM_LIB} ] || [ -z \"\`file \$${JVM_LIB} | grep \$${GAMMA_ARCH}\`\" ]; then "; \
-	echo "    $(WRONG_DATA_MODE_MSG)"; \
-	echo "    exit 0"; \
-	echo "  fi"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Compile Queens program for test"; \
-	echo ""; \
-	echo "rm -f Queens.class"; \
-	echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \
-	echo ""; \
-	echo "# Set library path solely for gamma launcher test run"; \
-	echo ""; \
-	echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
-	echo "export LD_LIBRARY_PATH"; \
-	echo "unset LD_LIBRARY_PATH_32"; \
-	echo "unset LD_LIBRARY_PATH_64"; \
-	echo ""; \
-	echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \
-	echo "  DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/native_threads:\$${JAVA_HOME}/jre/lib:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
-	echo "  export DYLD_LIBRARY_PATH"; \
-	echo "fi"; \
-	echo ""; \
-	echo "# Use the gamma launcher and JAVA_HOME to run the test"; \
-	echo ""; \
-	echo "./\$${GAMMA_PROG} $(TESTFLAGS) Queens < /dev/null"; \
-	) > $@
-	$(QUIETLY) chmod +x $@
-
 FORCE:
 
 .PHONY:  all FORCE
--- a/make/solaris/makefiles/mapfile-vers	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/solaris/makefiles/mapfile-vers	Fri Apr 12 10:14:42 2013 +0100
@@ -131,6 +131,7 @@
                 JVM_GetEnclosingMethodInfo;
                 JVM_GetFieldAnnotations;
                 JVM_GetFieldIxModifiers;
+                JVM_GetFieldTypeAnnotations;
                 JVM_GetHostName;
                 JVM_GetInheritedAccessControlContext;
                 JVM_GetInterfaceVersion;
@@ -152,6 +153,7 @@
                 JVM_GetMethodIxSignatureUTF;
                 JVM_GetMethodParameterAnnotations;
                 JVM_GetMethodParameters;
+                JVM_GetMethodTypeAnnotations;
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetSockName;
--- a/make/test/Queens.java	Tue Feb 26 16:16:54 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2006, 2008, 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.
- *
- */
-
-import java.util.*;
-
-// Copyright 1996, Animorphic Systems
-// gri 28 Aug 92 / 15 Jan 93 / 8 Dec 95
-
-class Queens {
-
-  static void try_i(boolean a[], boolean b[], boolean c[], int x[], int i) {
-    int adj = 7;
-
-    for (int j = 1; j <= 8; j++) {
-      if (b[j] && a[i+j] && c[adj+i-j]) {
-        x[i] = j;
-        b[j] = false;
-        a[i+j] = false;
-        c[adj+i-j] = false;
-        if (i < 8) try_i(a, b, c, x, i+1);
-        else print(x);
-        b[j] = true;
-        a[i+j] = true;
-        c[adj+i-j] = true;
-      }
-    }
-  }
-
-  public static void main(String s[]) {
-    boolean a[] = new boolean[16+1];
-    boolean b[] = new boolean[ 8+1];
-    boolean c[] = new boolean[14+1];
-    int     x[] = new int[8+1];
-    int adj = 7;
-
-    for (int i = -7; i <= 16; i++) {
-      if (i >= 1 && i <= 8) b[i]     = true;
-      if (i >= 2)           a[i]     = true;
-      if (i <= 7)           c[adj+i] = true;
-    }
-
-    x[0] = 0; // solution counter
-
-    try_i(a, b, c, x, 1);
-  }
-
-  static void print(int x[]) {
-    // first correct solution: A1 B5 C8 D6 E3 F7 G2 H4
-
-    char LF = (char)0xA;
-    char CR = (char)0xD;
-
-    x[0]++;
-    if (x[0] < 10)
-        System.out.print(" ");
-    System.out.print(x[0] + ". ");
-    for (int i = 1; i <= 8; i++) {
-      char p = (char)('A' + i - 1);
-      System.out.print(p);
-      System.out.print (x[i] + " ");
-    }
-    System.out.println();
-  }
-
-};
--- a/make/windows/build.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/windows/build.make	Fri Apr 12 10:14:42 2013 +0100
@@ -110,8 +110,6 @@
 !endif
 !elseif "$(Variant)" == "tiered"
 VARIANT_TEXT=Tiered
-!elseif "$(Variant)" == "kernel"
-VARIANT_TEXT=Kernel
 !endif
 
 #########################################################################
@@ -305,9 +303,9 @@
 checks: checkVariant checkWorkSpace checkSA
 
 checkVariant:
-	@ if "$(Variant)"=="" echo Need to specify "Variant=[tiered|compiler2|compiler1|kernel|core]" && false
-	@ if "$(Variant)" NEQ "tiered" if "$(Variant)" NEQ "compiler2" if "$(Variant)" NEQ "compiler1" if "$(Variant)" NEQ "kernel" if "$(Variant)" NEQ "core" \
-          echo Need to specify "Variant=[tiered|compiler2|compiler1|kernel|core]" && false
+	@ if "$(Variant)"=="" echo Need to specify "Variant=[tiered|compiler2|compiler1|core]" && false
+	@ if "$(Variant)" NEQ "tiered" if "$(Variant)" NEQ "compiler2" if "$(Variant)" NEQ "compiler1" if "$(Variant)" NEQ "core" \
+          echo Need to specify "Variant=[tiered|compiler2|compiler1|core]" && false
 
 checkWorkSpace:
 	@ if "$(WorkSpace)"=="" echo Need to specify "WorkSpace=..." && false
--- a/make/windows/create.bat	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/windows/create.bat	Fri Apr 12 10:14:42 2013 +0100
@@ -148,7 +148,7 @@
 
 REM This is now safe to do.
 :copyfiles
-for /D %%i in (compiler1, compiler2, tiered, core, kernel) do (
+for /D %%i in (compiler1, compiler2, tiered, core) do (
 if NOT EXIST %HotSpotBuildSpace%\%%i\generated mkdir %HotSpotBuildSpace%\%%i\generated
 copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\generated > NUL
 )
@@ -156,7 +156,7 @@
 REM force regneration of ProjectFile
 if exist %ProjectFile% del %ProjectFile%
 
-for /D %%i in (compiler1, compiler2, tiered, core, kernel) do (
+for /D %%i in (compiler1, compiler2, tiered, core) do (
 echo -- %%i --
 echo # Generated file!                                                        >    %HotSpotBuildSpace%\%%i\local.make
 echo # Changing a variable below and then deleting %ProjectFile% will cause  >>    %HotSpotBuildSpace%\%%i\local.make
--- a/make/windows/makefiles/compile.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/windows/makefiles/compile.make	Fri Apr 12 10:14:42 2013 +0100
@@ -221,13 +221,6 @@
 !endif
 !endif
 
-# Compile for space above time.
-!if "$(Variant)" == "kernel"
-PRODUCT_OPT_OPTION   = /O1 /Oy-
-FASTDEBUG_OPT_OPTION = /O1 /Oy-
-DEBUG_OPT_OPTION     = /Od
-!endif
-
 # If NO_OPTIMIZATIONS is defined in the environment, turn everything off
 !ifdef NO_OPTIMIZATIONS
 PRODUCT_OPT_OPTION   = $(DEBUG_OPT_OPTION)
--- a/make/windows/makefiles/product.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/windows/makefiles/product.make	Fri Apr 12 10:14:42 2013 +0100
@@ -51,13 +51,6 @@
 # Force resources to be rebuilt every time
 $(Res_Files): FORCE
 
-# Kernel doesn't need exported vtbl symbols.
-!if "$(Variant)" == "kernel"
-$(AOUT): $(Res_Files) $(Obj_Files)
-	$(LD) @<<
-  $(LD_FLAGS) /out:$@ /implib:$*.lib $(Obj_Files) $(Res_Files)
-<<
-!else
 vm.def: $(Obj_Files)
 	sh $(WorkSpace)/make/windows/build_vm_def.sh
 
@@ -65,7 +58,6 @@
 	$(LD) @<<
   $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
 <<
-!endif
 !if "$(MT)" != ""
 # The previous link command created a .manifest file that we want to
 # insert into the linked artifact so we do not need to track it
--- a/make/windows/makefiles/vm.make	Tue Feb 26 16:16:54 2013 -0800
+++ b/make/windows/makefiles/vm.make	Fri Apr 12 10:14:42 2013 +0100
@@ -89,12 +89,8 @@
 # AsyncGetCallTrace is not supported on IA64 yet
 AGCT_EXPORT=
 !else
-!if "$(Variant)" == "kernel"
-AGCT_EXPORT=
-!else
 AGCT_EXPORT=/export:AsyncGetCallTrace
 !endif
-!endif
 
 # If you modify exports below please do the corresponding changes in
 # src/share/tools/ProjectCreator/WinGammaPlatformVC7.java
--- a/make/windows/projectfiles/kernel/Makefile	Tue Feb 26 16:16:54 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#
-# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#   
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#   
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#  
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#   
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#  
-#
-
-!include ../local.make
-
-!include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile
--- a/make/windows/projectfiles/kernel/vm.def	Tue Feb 26 16:16:54 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-;
-; This .DEF file is a placeholder for one which is automatically
-; generated during the build process. See
-; make\windows\build_vm_def.sh and
-; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
-; options).
-;
--- a/make/windows/projectfiles/kernel/vm.dsw	Tue Feb 26 16:16:54 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "vm"=.\vm.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
--- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -51,6 +51,16 @@
 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
 
+  if (_info->deoptimize_on_exception()) {
+    address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
+    __ call(a, relocInfo::runtime_call_type);
+    __ delayed()->nop();
+    ce->add_call_info_here(_info);
+    ce->verify_oop_map(_info);
+    debug_only(__ should_not_reach_here());
+    return;
+  }
+
   if (_index->is_register()) {
     __ mov(_index->as_register(), G4);
   } else {
@@ -64,11 +74,22 @@
   __ delayed()->nop();
   ce->add_call_info_here(_info);
   ce->verify_oop_map(_info);
-#ifdef ASSERT
-  __ should_not_reach_here();
-#endif
+  debug_only(__ should_not_reach_here());
+}
+
+PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) {
+  _info = new CodeEmitInfo(info);
 }
 
+void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
+  __ call(a, relocInfo::runtime_call_type);
+  __ delayed()->nop();
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
+  debug_only(__ should_not_reach_here());
+}
 
 void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
@@ -99,10 +120,17 @@
 
 
 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
+  address a;
+  if (_info->deoptimize_on_exception()) {
+    // Deoptimize, do not throw the exception, because it is probably wrong to do it here.
+    a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
+  } else {
+    a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id);
+  }
+
   ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
   __ bind(_entry);
-  __ call(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id),
-          relocInfo::runtime_call_type);
+  __ call(a, relocInfo::runtime_call_type);
   __ delayed()->nop();
   ce->add_call_info_here(_info);
   ce->verify_oop_map(_info);
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -3361,6 +3361,45 @@
   __ mov(G2_thread, result_reg->as_register());
 }
 
+#ifdef ASSERT
+// emit run-time assertion
+void LIR_Assembler::emit_assert(LIR_OpAssert* op) {
+  assert(op->code() == lir_assert, "must be");
+
+  if (op->in_opr1()->is_valid()) {
+    assert(op->in_opr2()->is_valid(), "both operands must be valid");
+    comp_op(op->condition(), op->in_opr1(), op->in_opr2(), op);
+  } else {
+    assert(op->in_opr2()->is_illegal(), "both operands must be illegal");
+    assert(op->condition() == lir_cond_always, "no other conditions allowed");
+  }
+
+  Label ok;
+  if (op->condition() != lir_cond_always) {
+    Assembler::Condition acond;
+    switch (op->condition()) {
+      case lir_cond_equal:        acond = Assembler::equal;                break;
+      case lir_cond_notEqual:     acond = Assembler::notEqual;             break;
+      case lir_cond_less:         acond = Assembler::less;                 break;
+      case lir_cond_lessEqual:    acond = Assembler::lessEqual;            break;
+      case lir_cond_greaterEqual: acond = Assembler::greaterEqual;         break;
+      case lir_cond_greater:      acond = Assembler::greater;              break;
+      case lir_cond_aboveEqual:   acond = Assembler::greaterEqualUnsigned; break;
+      case lir_cond_belowEqual:   acond = Assembler::lessEqualUnsigned;    break;
+      default:                         ShouldNotReachHere();
+    };
+    __ br(acond, false, Assembler::pt, ok);
+    __ delayed()->nop();
+  }
+  if (op->halt()) {
+    const char* str = __ code_string(op->msg());
+    __ stop(str);
+  } else {
+    breakpoint();
+  }
+  __ bind(ok);
+}
+#endif
 
 void LIR_Assembler::peephole(LIR_List* lir) {
   LIR_OpList* inst = lir->instructions_list();
--- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -324,7 +324,7 @@
 
 void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
   assert(x->is_pinned(),"");
-  bool needs_range_check = true;
+  bool needs_range_check = x->compute_needs_range_check();
   bool use_length = x->length() != NULL;
   bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT;
   bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL ||
@@ -339,12 +339,9 @@
   array.load_item();
   index.load_nonconstant();
 
-  if (use_length) {
-    needs_range_check = x->compute_needs_range_check();
-    if (needs_range_check) {
-      length.set_instruction(x->length());
-      length.load_item();
-    }
+  if (use_length && needs_range_check) {
+    length.set_instruction(x->length());
+    length.load_item();
   }
   if (needs_store_check) {
     value.load_item();
--- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -987,6 +987,25 @@
       break;
 #endif // INCLUDE_ALL_GCS
 
+    case predicate_failed_trap_id:
+      {
+        __ set_info("predicate_failed_trap", dont_gc_arguments);
+        OopMap* oop_map = save_live_registers(sasm);
+
+        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
+
+        oop_maps = new OopMapSet();
+        oop_maps->add_gc_map(call_offset, oop_map);
+
+        DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
+        assert(deopt_blob != NULL, "deoptimization blob must have been created");
+        restore_live_registers(sasm);
+        __ restore();
+        __ br(Assembler::always, false, Assembler::pt, deopt_blob->unpack_with_reexecution(), relocInfo::runtime_call_type);
+        __ delayed()->nop();
+      }
+      break;
+
     default:
       { __ set_info("unimplemented entry", dont_gc_arguments);
         __ save_frame(0);
--- a/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1385,13 +1385,13 @@
   }
 #endif
 
-  int len = strlen(file) + strlen(msg) + 1 + 4;
-  sprintf(buffer, "%d", line);
-  len += strlen(buffer);
-  sprintf(buffer, " at offset %d ", offset());
-  len += strlen(buffer);
-  char * real_msg = new char[len];
-  sprintf(real_msg, "%s%s(%s:%d)", msg, buffer, file, line);
+  const char* real_msg = NULL;
+  {
+    ResourceMark rm;
+    stringStream ss;
+    ss.print("%s at offset %d (%s:%d)", msg, offset(), file, line);
+    real_msg = code_string(ss.as_string());
+  }
 
   // Call indirectly to solve generation ordering problem
   AddressLiteral a(StubRoutines::verify_oop_subroutine_entry_address());
@@ -1423,13 +1423,13 @@
   // plausibility check for oops
   if (!VerifyOops) return;
 
-  char buffer[64];
-  sprintf(buffer, "%d", line);
-  int len = strlen(file) + strlen(msg) + 1 + 4 + strlen(buffer);
-  sprintf(buffer, " at SP+%d ", addr.disp());
-  len += strlen(buffer);
-  char * real_msg = new char[len];
-  sprintf(real_msg, "%s at SP+%d (%s:%d)", msg, addr.disp(), file, line);
+  const char* real_msg = NULL;
+  {
+    ResourceMark rm;
+    stringStream ss;
+    ss.print("%s at SP+%d (%s:%d)", msg, addr.disp(), file, line);
+    real_msg = code_string(ss.as_string());
+  }
 
   // Call indirectly to solve generation ordering problem
   AddressLiteral a(StubRoutines::verify_oop_subroutine_entry_address());
@@ -1622,9 +1622,13 @@
   // in order to run automated test scripts on the VM
   // Use the flag ShowMessageBoxOnError
 
-  char* b = new char[1024];
-  sprintf(b, "untested: %s", what);
-
+  const char* b = NULL;
+  {
+    ResourceMark rm;
+    stringStream ss;
+    ss.print("untested: %s", what);
+    b = code_string(ss.as_string());
+  }
   if (ShowMessageBoxOnError) { STOP(b); }
   else                       { warn(b); }
 }
--- a/src/cpu/x86/vm/assembler_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -214,14 +214,6 @@
   return enc;
 }
 
-static int encode(XMMRegister r) {
-  int enc = r->encoding();
-  if (enc >= 8) {
-    enc -= 8;
-  }
-  return enc;
-}
-
 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
   assert(dst->has_byte_register(), "must have byte register");
   assert(isByte(op1) && isByte(op2), "wrong opcode");
--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -101,6 +101,15 @@
 
 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
+  if (_info->deoptimize_on_exception()) {
+    address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
+    __ call(RuntimeAddress(a));
+    ce->add_call_info_here(_info);
+    ce->verify_oop_map(_info);
+    debug_only(__ should_not_reach_here());
+    return;
+  }
+
   // pass the array index on stack because all registers must be preserved
   if (_index->is_cpu_register()) {
     ce->store_parameter(_index->as_register(), 0);
@@ -115,9 +124,22 @@
   }
   __ call(RuntimeAddress(Runtime1::entry_for(stub_id)));
   ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
   debug_only(__ should_not_reach_here());
 }
 
+PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) {
+  _info = new CodeEmitInfo(info);
+}
+
+void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
+  __ call(RuntimeAddress(a));
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
+  debug_only(__ should_not_reach_here());
+}
 
 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
   if (_offset != -1) {
@@ -414,10 +436,19 @@
 
 
 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
+  address a;
+  if (_info->deoptimize_on_exception()) {
+    // Deoptimize, do not throw the exception, because it is probably wrong to do it here.
+    a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
+  } else {
+    a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id);
+  }
+
   ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
   __ bind(_entry);
-  __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id)));
+  __ call(RuntimeAddress(a));
   ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
   debug_only(__ should_not_reach_here());
 }
 
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -3755,6 +3755,44 @@
   }
 }
 
+#ifdef ASSERT
+// emit run-time assertion
+void LIR_Assembler::emit_assert(LIR_OpAssert* op) {
+  assert(op->code() == lir_assert, "must be");
+
+  if (op->in_opr1()->is_valid()) {
+    assert(op->in_opr2()->is_valid(), "both operands must be valid");
+    comp_op(op->condition(), op->in_opr1(), op->in_opr2(), op);
+  } else {
+    assert(op->in_opr2()->is_illegal(), "both operands must be illegal");
+    assert(op->condition() == lir_cond_always, "no other conditions allowed");
+  }
+
+  Label ok;
+  if (op->condition() != lir_cond_always) {
+    Assembler::Condition acond = Assembler::zero;
+    switch (op->condition()) {
+      case lir_cond_equal:        acond = Assembler::equal;       break;
+      case lir_cond_notEqual:     acond = Assembler::notEqual;    break;
+      case lir_cond_less:         acond = Assembler::less;        break;
+      case lir_cond_lessEqual:    acond = Assembler::lessEqual;   break;
+      case lir_cond_greaterEqual: acond = Assembler::greaterEqual;break;
+      case lir_cond_greater:      acond = Assembler::greater;     break;
+      case lir_cond_belowEqual:   acond = Assembler::belowEqual;  break;
+      case lir_cond_aboveEqual:   acond = Assembler::aboveEqual;  break;
+      default:                    ShouldNotReachHere();
+    }
+    __ jcc(acond, ok);
+  }
+  if (op->halt()) {
+    const char* str = __ code_string(op->msg());
+    __ stop(str);
+  } else {
+    breakpoint();
+  }
+  __ bind(ok);
+}
+#endif
 
 void LIR_Assembler::membar() {
   // QQQ sparc TSO uses this,
--- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -263,7 +263,7 @@
 
 void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
   assert(x->is_pinned(),"");
-  bool needs_range_check = true;
+  bool needs_range_check = x->compute_needs_range_check();
   bool use_length = x->length() != NULL;
   bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT;
   bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL ||
@@ -278,12 +278,10 @@
   array.load_item();
   index.load_nonconstant();
 
-  if (use_length) {
-    needs_range_check = x->compute_needs_range_check();
-    if (needs_range_check) {
-      length.set_instruction(x->length());
-      length.load_item();
-    }
+  if (use_length && needs_range_check) {
+    length.set_instruction(x->length());
+    length.load_item();
+
   }
   if (needs_store_check) {
     value.load_item();
--- a/src/cpu/x86/vm/c1_LinearScan_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/c1_LinearScan_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -675,7 +675,8 @@
   switch (op2->code()) {
     case lir_cmp:
     case lir_cmp_fd2i:
-    case lir_ucmp_fd2i: {
+    case lir_ucmp_fd2i:
+    case lir_assert: {
       assert(left->is_fpu_register(), "invalid LIR");
       assert(right->is_fpu_register(), "invalid LIR");
 
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1807,6 +1807,24 @@
       break;
 #endif // INCLUDE_ALL_GCS
 
+    case predicate_failed_trap_id:
+      {
+        StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
+
+        OopMap* map = save_live_registers(sasm, 1);
+
+        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
+        oop_maps = new OopMapSet();
+        oop_maps->add_gc_map(call_offset, map);
+        restore_live_registers(sasm);
+        __ leave();
+        DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
+        assert(deopt_blob != NULL, "deoptimization blob must have been created");
+
+        __ jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
+      }
+      break;
+
     default:
       { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments);
         __ movptr(rax, (int)id);
--- a/src/cpu/x86/vm/cppInterpreter_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1299,25 +1299,8 @@
   __ push(rdx);
 #endif // _LP64
 
-  // Either restore the MXCSR register after returning from the JNI Call
-  // or verify that it wasn't changed.
-  if (VM_Version::supports_sse()) {
-    if (RestoreMXCSROnJNICalls) {
-      __ ldmxcsr(ExternalAddress(StubRoutines::addr_mxcsr_std()));
-    }
-    else if (CheckJNICalls ) {
-      __ call(RuntimeAddress(StubRoutines::x86::verify_mxcsr_entry()));
-    }
-  }
-
-#ifndef _LP64
-  // Either restore the x87 floating pointer control word after returning
-  // from the JNI call or verify that it wasn't changed.
-  if (CheckJNICalls) {
-    __ call(RuntimeAddress(StubRoutines::x86::verify_fpu_cntrl_wrd_entry()));
-  }
-#endif // _LP64
-
+  // Verify or restore cpu control state after JNI call
+  __ restore_cpu_control_state_after_jni();
 
   // change thread state
   __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans);
--- a/src/cpu/x86/vm/frame_x86.inline.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/frame_x86.inline.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -295,14 +295,18 @@
   return true;
 }
 
-
+inline oop frame::saved_oop_result(RegisterMap* map) const {
+  oop* result_adr = (oop *)map->location(rax->as_VMReg());
+  guarantee(result_adr != NULL, "bad register save location");
 
-inline oop frame::saved_oop_result(RegisterMap* map) const       {
-  return *((oop*) map->location(rax->as_VMReg()));
+  return (*result_adr);
 }
 
 inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
-  *((oop*) map->location(rax->as_VMReg())) = obj;
+  oop* result_adr = (oop *)map->location(rax->as_VMReg());
+  guarantee(result_adr != NULL, "bad register save location");
+
+  *result_adr = obj;
 }
 
 #endif // CPU_X86_VM_FRAME_X86_INLINE_HPP
--- a/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/macroAssembler_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -4262,8 +4262,13 @@
   if (!VerifyOops) return;
 
   // Pass register number to verify_oop_subroutine
-  char* b = new char[strlen(s) + 50];
-  sprintf(b, "verify_oop: %s: %s", reg->name(), s);
+  const char* b = NULL;
+  {
+    ResourceMark rm;
+    stringStream ss;
+    ss.print("verify_oop: %s: %s", reg->name(), s);
+    b = code_string(ss.as_string());
+  }
   BLOCK_COMMENT("verify_oop {");
 #ifdef _LP64
   push(rscratch1);                    // save r10, trashed by movptr()
@@ -4297,9 +4302,14 @@
   { Label L;
     testptr(tmp, tmp);
     if (WizardMode) {
+      const char* buf = NULL;
+      {
+        ResourceMark rm;
+        stringStream ss;
+        ss.print("DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
+        buf = code_string(ss.as_string());
+      }
       jcc(Assembler::notZero, L);
-      char* buf = new char[40];
-      sprintf(buf, "DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
       STOP(buf);
     } else {
       jccb(Assembler::notZero, L);
@@ -4343,9 +4353,13 @@
 
   // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord);
   // Pass register number to verify_oop_subroutine
-  char* b = new char[strlen(s) + 50];
-  sprintf(b, "verify_oop_addr: %s", s);
-
+  const char* b = NULL;
+  {
+    ResourceMark rm;
+    stringStream ss;
+    ss.print("verify_oop_addr: %s", s);
+    b = code_string(ss.as_string());
+  }
 #ifdef _LP64
   push(rscratch1);                    // save r10, trashed by movptr()
 #endif
@@ -4751,6 +4765,31 @@
   pop_CPU_state();
 }
 
+void MacroAssembler::restore_cpu_control_state_after_jni() {
+  // Either restore the MXCSR register after returning from the JNI Call
+  // or verify that it wasn't changed (with -Xcheck:jni flag).
+  if (VM_Version::supports_sse()) {
+    if (RestoreMXCSROnJNICalls) {
+      ldmxcsr(ExternalAddress(StubRoutines::addr_mxcsr_std()));
+    } else if (CheckJNICalls) {
+      call(RuntimeAddress(StubRoutines::x86::verify_mxcsr_entry()));
+    }
+  }
+  if (VM_Version::supports_avx()) {
+    // Clear upper bits of YMM registers to avoid SSE <-> AVX transition penalty.
+    vzeroupper();
+  }
+
+#ifndef _LP64
+  // Either restore the x87 floating pointer control word after returning
+  // from the JNI call or verify that it wasn't changed.
+  if (CheckJNICalls) {
+    call(RuntimeAddress(StubRoutines::x86::verify_fpu_cntrl_wrd_entry()));
+  }
+#endif // _LP64
+}
+
+
 void MacroAssembler::load_klass(Register dst, Register src) {
 #ifdef _LP64
   if (UseCompressedKlassPointers) {
@@ -5745,6 +5784,8 @@
     addptr(result, stride2);
     subl(cnt2, stride2);
     jccb(Assembler::notZero, COMPARE_WIDE_VECTORS_LOOP);
+    // clean upper bits of YMM registers
+    vzeroupper();
 
     // compare wide vectors tail
     bind(COMPARE_WIDE_TAIL);
@@ -5758,6 +5799,8 @@
 
     // Identifies the mismatching (higher or lower)16-bytes in the 32-byte vectors.
     bind(VECTOR_NOT_EQUAL);
+    // clean upper bits of YMM registers
+    vzeroupper();
     lea(str1, Address(str1, result, scale));
     lea(str2, Address(str2, result, scale));
     jmp(COMPARE_16_CHARS);
@@ -6014,6 +6057,10 @@
 
   // That's it
   bind(DONE);
+  if (UseAVX >= 2) {
+    // clean upper bits of YMM registers
+    vzeroupper();
+  }
 }
 
 void MacroAssembler::generate_fill(BasicType t, bool aligned,
@@ -6143,6 +6190,10 @@
         vmovdqu(Address(to, 0), xtmp);
         addptr(to, 32);
         subl(count, 8 << shift);
+
+        BIND(L_check_fill_8_bytes);
+        // clean upper bits of YMM registers
+        vzeroupper();
       } else {
         // Fill 32-byte chunks
         pshufd(xtmp, xtmp, 0);
@@ -6166,8 +6217,9 @@
         addptr(to, 32);
         subl(count, 8 << shift);
         jcc(Assembler::greaterEqual, L_fill_32_bytes_loop);
+
+        BIND(L_check_fill_8_bytes);
       }
-      BIND(L_check_fill_8_bytes);
       addl(count, 8 << shift);
       jccb(Assembler::zero, L_exit);
       jmpb(L_fill_8_bytes);
@@ -6302,6 +6354,10 @@
     jccb(Assembler::lessEqual, L_copy_16_chars);
 
     bind(L_copy_16_chars_exit);
+    if (UseAVX >= 2) {
+      // clean upper bits of YMM registers
+      vzeroupper();
+    }
     subptr(len, 8);
     jccb(Assembler::greater, L_copy_8_chars_exit);
 
--- a/src/cpu/x86/vm/macroAssembler_x86.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/macroAssembler_x86.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -582,6 +582,9 @@
   // only if +VerifyFPU
   void verify_FPU(int stack_depth, const char* s = "illegal FPU state");
 
+  // Verify or restore cpu control state after JNI call
+  void restore_cpu_control_state_after_jni();
+
   // prints msg, dumps registers and stops execution
   void stop(const char* msg);
 
--- a/src/cpu/x86/vm/methodHandles_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -41,11 +41,6 @@
 
 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
 
-// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
-static RegisterOrConstant constant(int value) {
-  return RegisterOrConstant(value);
-}
-
 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg) {
   if (VerifyMethodHandles)
     verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class),
--- a/src/cpu/x86/vm/relocInfo_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/relocInfo_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -145,12 +145,9 @@
   assert(which == Assembler::disp32_operand ||
          which == Assembler::call32_operand ||
          which == Assembler::imm_operand, "format unpacks ok");
-  if (which != Assembler::imm_operand) {
-    // The "address" in the code is a displacement can't return it as
-    // and address* since it is really a jint*
-    ShouldNotReachHere();
-    return NULL;
-  }
+  // The "address" in the code is a displacement can't return it as
+  // and address* since it is really a jint*
+  guarantee(which == Assembler::imm_operand, "must be immediate operand");
 #else
   assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok");
 #endif // AMD64
--- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -2065,6 +2065,9 @@
 
   __ call(RuntimeAddress(native_func));
 
+  // Verify or restore cpu control state after JNI call
+  __ restore_cpu_control_state_after_jni();
+
   // WARNING - on Windows Java Natives use pascal calling convention and pop the
   // arguments off of the stack. We could just re-adjust the stack pointer here
   // and continue to do SP relative addressing but we instead switch to FP
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -2315,16 +2315,8 @@
 
   __ call(RuntimeAddress(native_func));
 
-    // Either restore the MXCSR register after returning from the JNI Call
-    // or verify that it wasn't changed.
-    if (RestoreMXCSROnJNICalls) {
-      __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std()));
-
-    }
-    else if (CheckJNICalls ) {
-      __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::verify_mxcsr_entry())));
-    }
-
+  // Verify or restore cpu control state after JNI call
+  __ restore_cpu_control_state_after_jni();
 
   // Unpack native results.
   switch (ret_type) {
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -835,6 +835,11 @@
   __ BIND(L_copy_64_bytes);
     __ subl(qword_count, 8);
     __ jcc(Assembler::greaterEqual, L_copy_64_bytes_loop);
+
+    if (UseUnalignedLoadStores && (UseAVX >= 2)) {
+      // clean upper bits of YMM registers
+      __ vzeroupper();
+    }
     __ addl(qword_count, 8);
     __ jccb(Assembler::zero, L_exit);
     //
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1331,6 +1331,10 @@
       }
       __ addptr(qword_count, 4);
       __ BIND(L_end);
+      if (UseAVX >= 2) {
+        // clean upper bits of YMM registers
+        __ vzeroupper();
+      }
     } else {
       // Copy 32-bytes per iteration
       __ BIND(L_loop);
@@ -1404,6 +1408,10 @@
       }
       __ subptr(qword_count, 4);
       __ BIND(L_end);
+      if (UseAVX >= 2) {
+        // clean upper bits of YMM registers
+        __ vzeroupper();
+      }
     } else {
       // Copy 32-bytes per iteration
       __ BIND(L_loop);
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1080,22 +1080,8 @@
 
   // result potentially in rdx:rax or ST0
 
-  // Either restore the MXCSR register after returning from the JNI Call
-  // or verify that it wasn't changed.
-  if (VM_Version::supports_sse()) {
-    if (RestoreMXCSROnJNICalls) {
-      __ ldmxcsr(ExternalAddress(StubRoutines::addr_mxcsr_std()));
-    }
-    else if (CheckJNICalls ) {
-      __ call(RuntimeAddress(StubRoutines::x86::verify_mxcsr_entry()));
-    }
-  }
-
-  // Either restore the x87 floating pointer control word after returning
-  // from the JNI call or verify that it wasn't changed.
-  if (CheckJNICalls) {
-    __ call(RuntimeAddress(StubRoutines::x86::verify_fpu_cntrl_wrd_entry()));
-  }
+  // Verify or restore cpu control state after JNI call
+  __ restore_cpu_control_state_after_jni();
 
   // save potential result in ST(0) & rdx:rax
   // (if result handler is the T_FLOAT or T_DOUBLE handler, result must be in ST0 -
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1079,15 +1079,8 @@
   __ call(rax);
   // result potentially in rax or xmm0
 
-  // Depending on runtime options, either restore the MXCSR
-  // register after returning from the JNI Call or verify that
-  // it wasn't changed during -Xcheck:jni.
-  if (RestoreMXCSROnJNICalls) {
-    __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std()));
-  }
-  else if (CheckJNICalls) {
-    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::verify_mxcsr_entry())));
-  }
+  // Verify or restore cpu control state after JNI call
+  __ restore_cpu_control_state_after_jni();
 
   // NOTE: The order of these pushes is known to frame::interpreter_frame_result
   // in order to extract the result of a method call. If the order of these
--- a/src/cpu/x86/vm/x86_32.ad	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/x86_32.ad	Fri Apr 12 10:14:42 2013 +0100
@@ -228,10 +228,16 @@
 static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000));
 
 // Offset hacking within calls.
-static int pre_call_FPU_size() {
-  if (Compile::current()->in_24_bit_fp_mode())
-    return 6; // fldcw
-  return 0;
+static int pre_call_resets_size() {
+  int size = 0;
+  Compile* C = Compile::current();
+  if (C->in_24_bit_fp_mode()) {
+    size += 6; // fldcw
+  }
+  if (C->max_vector_size() > 16) {
+    size += 3; // vzeroupper
+  }
+  return size;
 }
 
 static int preserve_SP_size() {
@@ -242,21 +248,21 @@
 //       from the start of the call to the point where the return address
 //       will point.
 int MachCallStaticJavaNode::ret_addr_offset() {
-  int offset = 5 + pre_call_FPU_size();  // 5 bytes from start of call to where return address points
+  int offset = 5 + pre_call_resets_size();  // 5 bytes from start of call to where return address points
   if (_method_handle_invoke)
     offset += preserve_SP_size();
   return offset;
 }
 
 int MachCallDynamicJavaNode::ret_addr_offset() {
-  return 10 + pre_call_FPU_size();  // 10 bytes from start of call to where return address points
+  return 10 + pre_call_resets_size();  // 10 bytes from start of call to where return address points
 }
 
 static int sizeof_FFree_Float_Stack_All = -1;
 
 int MachCallRuntimeNode::ret_addr_offset() {
   assert(sizeof_FFree_Float_Stack_All != -1, "must have been emitted already");
-  return sizeof_FFree_Float_Stack_All + 5 + pre_call_FPU_size();
+  return sizeof_FFree_Float_Stack_All + 5 + pre_call_resets_size();
 }
 
 // Indicate if the safepoint node needs the polling page as an input.
@@ -272,7 +278,7 @@
 // The address of the call instruction needs to be 4-byte aligned to
 // ensure that it does not span a cache line so that it can be patched.
 int CallStaticJavaDirectNode::compute_padding(int current_offset) const {
-  current_offset += pre_call_FPU_size();  // skip fldcw, if any
+  current_offset += pre_call_resets_size();  // skip fldcw, if any
   current_offset += 1;      // skip call opcode byte
   return round_to(current_offset, alignment_required()) - current_offset;
 }
@@ -280,7 +286,7 @@
 // The address of the call instruction needs to be 4-byte aligned to
 // ensure that it does not span a cache line so that it can be patched.
 int CallStaticJavaHandleNode::compute_padding(int current_offset) const {
-  current_offset += pre_call_FPU_size();  // skip fldcw, if any
+  current_offset += pre_call_resets_size();  // skip fldcw, if any
   current_offset += preserve_SP_size();   // skip mov rbp, rsp
   current_offset += 1;      // skip call opcode byte
   return round_to(current_offset, alignment_required()) - current_offset;
@@ -289,7 +295,7 @@
 // The address of the call instruction needs to be 4-byte aligned to
 // ensure that it does not span a cache line so that it can be patched.
 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const {
-  current_offset += pre_call_FPU_size();  // skip fldcw, if any
+  current_offset += pre_call_resets_size();  // skip fldcw, if any
   current_offset += 5;      // skip MOV instruction
   current_offset += 1;      // skip call opcode byte
   return round_to(current_offset, alignment_required()) - current_offset;
@@ -583,16 +589,20 @@
   // Remove two words for return addr and rbp,
   framesize -= 2*wordSize;
 
-  if( C->in_24_bit_fp_mode() ) {
+  if (C->max_vector_size() > 16) {
+    st->print("VZEROUPPER");
+    st->cr(); st->print("\t");
+  }
+  if (C->in_24_bit_fp_mode()) {
     st->print("FLDCW  standard control word");
     st->cr(); st->print("\t");
   }
-  if( framesize ) {
+  if (framesize) {
     st->print("ADD    ESP,%d\t# Destroy frame",framesize);
     st->cr(); st->print("\t");
   }
   st->print_cr("POPL   EBP"); st->print("\t");
-  if( do_polling() && C->is_method_compilation() ) {
+  if (do_polling() && C->is_method_compilation()) {
     st->print("TEST   PollPage,EAX\t! Poll Safepoint");
     st->cr(); st->print("\t");
   }
@@ -602,8 +612,14 @@
 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
   Compile *C = ra_->C;
 
+  if (C->max_vector_size() > 16) {
+    // Clear upper bits of YMM registers when current compiled code uses
+    // wide vectors to avoid AVX <-> SSE transition penalty during call.
+    MacroAssembler masm(&cbuf);
+    masm.vzeroupper();
+  }
   // If method set FPU control word, restore to standard control word
-  if( C->in_24_bit_fp_mode() ) {
+  if (C->in_24_bit_fp_mode()) {
     MacroAssembler masm(&cbuf);
     masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
   }
@@ -615,12 +631,11 @@
 
   // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here
 
-  if( framesize >= 128 ) {
+  if (framesize >= 128) {
     emit_opcode(cbuf, 0x81); // add  SP, #framesize
     emit_rm(cbuf, 0x3, 0x00, ESP_enc);
     emit_d32(cbuf, framesize);
-  }
-  else if( framesize ) {
+  } else if (framesize) {
     emit_opcode(cbuf, 0x83); // add  SP, #framesize
     emit_rm(cbuf, 0x3, 0x00, ESP_enc);
     emit_d8(cbuf, framesize);
@@ -628,7 +643,7 @@
 
   emit_opcode(cbuf, 0x58 | EBP_enc);
 
-  if( do_polling() && C->is_method_compilation() ) {
+  if (do_polling() && C->is_method_compilation()) {
     cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
     emit_opcode(cbuf,0x85);
     emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
@@ -640,7 +655,8 @@
   Compile *C = ra_->C;
   // If method set FPU control word, restore to standard control word
   int size = C->in_24_bit_fp_mode() ? 6 : 0;
-  if( do_polling() && C->is_method_compilation() ) size += 6;
+  if (C->max_vector_size() > 16) size += 3; // vzeroupper
+  if (do_polling() && C->is_method_compilation()) size += 6;
 
   int framesize = C->frame_slots() << LogBytesPerInt;
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
@@ -649,7 +665,7 @@
 
   size++; // popl rbp,
 
-  if( framesize >= 128 ) {
+  if (framesize >= 128) {
     size += 6;
   } else {
     size += framesize ? 3 : 0;
@@ -1853,20 +1869,26 @@
   %}
 
 
-  enc_class pre_call_FPU %{
+  enc_class pre_call_resets %{
     // If method sets FPU control word restore it here
     debug_only(int off0 = cbuf.insts_size());
-    if( Compile::current()->in_24_bit_fp_mode() ) {
-      MacroAssembler masm(&cbuf);
-      masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
+    if (ra_->C->in_24_bit_fp_mode()) {
+      MacroAssembler _masm(&cbuf);
+      __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
+    }
+    if (ra_->C->max_vector_size() > 16) {
+      // Clear upper bits of YMM registers when current compiled code uses
+      // wide vectors to avoid AVX <-> SSE transition penalty during call.
+      MacroAssembler _masm(&cbuf);
+      __ vzeroupper();
     }
     debug_only(int off1 = cbuf.insts_size());
-    assert(off1 - off0 == pre_call_FPU_size(), "correct size prediction");
+    assert(off1 - off0 == pre_call_resets_size(), "correct size prediction");
   %}
 
   enc_class post_call_FPU %{
     // If method sets FPU control word do it here also
-    if( Compile::current()->in_24_bit_fp_mode() ) {
+    if (Compile::current()->in_24_bit_fp_mode()) {
       MacroAssembler masm(&cbuf);
       masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24()));
     }
@@ -1877,17 +1899,17 @@
     // who we intended to call.
     cbuf.set_insts_mark();
     $$$emit8$primary;
-    if ( !_method ) {
+    if (!_method) {
       emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
                      runtime_call_Relocation::spec(), RELOC_IMM32 );
-    } else if(_optimized_virtual) {
+    } else if (_optimized_virtual) {
       emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
                      opt_virtual_call_Relocation::spec(), RELOC_IMM32 );
     } else {
       emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4),
                      static_call_Relocation::spec(), RELOC_IMM32 );
     }
-    if( _method ) {  // Emit stub for static call
+    if (_method) {  // Emit stub for static call
       emit_java_to_interp(cbuf);
     }
   %}
@@ -12828,7 +12850,7 @@
   ins_cost(300);
   format %{ "CALL,static " %}
   opcode(0xE8); /* E8 cd */
-  ins_encode( pre_call_FPU,
+  ins_encode( pre_call_resets,
               Java_Static_Call( meth ),
               call_epilog,
               post_call_FPU );
@@ -12849,7 +12871,7 @@
   ins_cost(300);
   format %{ "CALL,static/MethodHandle " %}
   opcode(0xE8); /* E8 cd */
-  ins_encode( pre_call_FPU,
+  ins_encode( pre_call_resets,
               preserve_SP,
               Java_Static_Call( meth ),
               restore_SP,
@@ -12870,7 +12892,7 @@
   format %{ "MOV    EAX,(oop)-1\n\t"
             "CALL,dynamic" %}
   opcode(0xE8); /* E8 cd */
-  ins_encode( pre_call_FPU,
+  ins_encode( pre_call_resets,
               Java_Dynamic_Call( meth ),
               call_epilog,
               post_call_FPU );
@@ -12887,7 +12909,7 @@
   format %{ "CALL,runtime " %}
   opcode(0xE8); /* E8 cd */
   // Use FFREEs to clear entries in float stack
-  ins_encode( pre_call_FPU,
+  ins_encode( pre_call_resets,
               FFree_Float_Stack_All,
               Java_To_Runtime( meth ),
               post_call_FPU );
@@ -12902,7 +12924,7 @@
   ins_cost(300);
   format %{ "CALL_LEAF,runtime " %}
   opcode(0xE8); /* E8 cd */
-  ins_encode( pre_call_FPU,
+  ins_encode( pre_call_resets,
               FFree_Float_Stack_All,
               Java_To_Runtime( meth ),
               Verify_FPU_For_Leaf, post_call_FPU );
--- a/src/cpu/x86/vm/x86_64.ad	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/cpu/x86/vm/x86_64.ad	Fri Apr 12 10:14:42 2013 +0100
@@ -399,6 +399,9 @@
 static int preserve_SP_size() {
   return 3;  // rex.w, op, rm(reg/reg)
 }
+static int clear_avx_size() {
+  return (Compile::current()->max_vector_size() > 16) ? 3 : 0;  // vzeroupper
+}
 
 // !!!!! Special hack to get all types of calls to specify the byte offset
 //       from the start of the call to the point where the return address
@@ -406,6 +409,7 @@
 int MachCallStaticJavaNode::ret_addr_offset()
 {
   int offset = 5; // 5 bytes from start of call to where return address points
+  offset += clear_avx_size();
   if (_method_handle_invoke)
     offset += preserve_SP_size();
   return offset;
@@ -413,11 +417,16 @@
 
 int MachCallDynamicJavaNode::ret_addr_offset()
 {
-  return 15; // 15 bytes from start of call to where return address points
+  int offset = 15; // 15 bytes from start of call to where return address points
+  offset += clear_avx_size();
+  return offset;
 }
 
-// In os_cpu .ad file
-// int MachCallRuntimeNode::ret_addr_offset()
+int MachCallRuntimeNode::ret_addr_offset() {
+  int offset = 13; // movq r10,#addr; callq (r10)
+  offset += clear_avx_size();
+  return offset;
+}
 
 // Indicate if the safepoint node needs the polling page as an input,
 // it does if the polling page is more than disp32 away.
@@ -434,6 +443,7 @@
 // ensure that it does not span a cache line so that it can be patched.
 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
 {
+  current_offset += clear_avx_size(); // skip vzeroupper
   current_offset += 1; // skip call opcode byte
   return round_to(current_offset, alignment_required()) - current_offset;
 }
@@ -443,6 +453,7 @@
 int CallStaticJavaHandleNode::compute_padding(int current_offset) const
 {
   current_offset += preserve_SP_size();   // skip mov rbp, rsp
+  current_offset += clear_avx_size(); // skip vzeroupper
   current_offset += 1; // skip call opcode byte
   return round_to(current_offset, alignment_required()) - current_offset;
 }
@@ -451,6 +462,7 @@
 // ensure that it does not span a cache line so that it can be patched.
 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
 {
+  current_offset += clear_avx_size(); // skip vzeroupper
   current_offset += 11; // skip movq instruction + call opcode byte
   return round_to(current_offset, alignment_required()) - current_offset;
 }
@@ -764,6 +776,11 @@
 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
 {
   Compile* C = ra_->C;
+  if (C->max_vector_size() > 16) {
+    st->print("vzeroupper");
+    st->cr(); st->print("\t");
+  }
+
   int framesize = C->frame_slots() << LogBytesPerInt;
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
   // Remove word for return adr already pushed
@@ -793,6 +810,13 @@
 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
 {
   Compile* C = ra_->C;
+  if (C->max_vector_size() > 16) {
+    // Clear upper bits of YMM registers when current compiled code uses
+    // wide vectors to avoid AVX <-> SSE transition penalty during call.
+    MacroAssembler _masm(&cbuf);
+    __ vzeroupper();
+  }
+
   int framesize = C->frame_slots() << LogBytesPerInt;
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
   // Remove word for return adr already pushed
@@ -1669,17 +1693,6 @@
   return PTR_RBP_REG_mask();
 }
 
-static Address build_address(int b, int i, int s, int d) {
-  Register index = as_Register(i);
-  Address::ScaleFactor scale = (Address::ScaleFactor)s;
-  if (index == rsp) {
-    index = noreg;
-    scale = Address::no_scale;
-  }
-  Address addr(as_Register(b), index, scale, d);
-  return addr;
-}
-
 %}
 
 //----------ENCODING BLOCK-----------------------------------------------------
@@ -2008,6 +2021,25 @@
     __ bind(miss);
   %}
 
+  enc_class clear_avx %{
+    debug_only(int off0 = cbuf.insts_size());
+    if (ra_->C->max_vector_size() > 16) {
+      // Clear upper bits of YMM registers when current compiled code uses
+      // wide vectors to avoid AVX <-> SSE transition penalty during call.
+      MacroAssembler _masm(&cbuf);
+      __ vzeroupper();
+    }
+    debug_only(int off1 = cbuf.insts_size());
+    assert(off1 - off0 == clear_avx_size(), "correct size prediction");
+  %}
+
+  enc_class Java_To_Runtime(method meth) %{
+    // No relocation needed
+    MacroAssembler _masm(&cbuf);
+    __ mov64(r10, (int64_t) $meth$$method);
+    __ call(r10);
+  %}
+
   enc_class Java_To_Interpreter(method meth)
   %{
     // CALL Java_To_Interpreter
@@ -11366,7 +11398,7 @@
   ins_cost(300);
   format %{ "call,static " %}
   opcode(0xE8); /* E8 cd */
-  ins_encode(Java_Static_Call(meth), call_epilog);
+  ins_encode(clear_avx, Java_Static_Call(meth), call_epilog);
   ins_pipe(pipe_slow);
   ins_alignment(4);
 %}
@@ -11384,7 +11416,7 @@
   ins_cost(300);
   format %{ "call,static/MethodHandle " %}
   opcode(0xE8); /* E8 cd */
-  ins_encode(preserve_SP,
+  ins_encode(clear_avx, preserve_SP,
              Java_Static_Call(meth),
              restore_SP,
              call_epilog);
@@ -11403,7 +11435,7 @@
   ins_cost(300);
   format %{ "movq    rax, #Universe::non_oop_word()\n\t"
             "call,dynamic " %}
-  ins_encode(Java_Dynamic_Call(meth), call_epilog);
+  ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog);
   ins_pipe(pipe_slow);
   ins_alignment(4);
 %}
@@ -11416,8 +11448,7 @@
 
   ins_cost(300);
   format %{ "call,runtime " %}
-  opcode(0xE8); /* E8 cd */
-  ins_encode(Java_To_Runtime(meth));
+  ins_encode(clear_avx, Java_To_Runtime(meth));
   ins_pipe(pipe_slow);
 %}
 
@@ -11429,8 +11460,7 @@
 
   ins_cost(300);
   format %{ "call_leaf,runtime " %}
-  opcode(0xE8); /* E8 cd */
-  ins_encode(Java_To_Runtime(meth));
+  ins_encode(clear_avx, Java_To_Runtime(meth));
   ins_pipe(pipe_slow);
 %}
 
@@ -11442,7 +11472,6 @@
 
   ins_cost(300);
   format %{ "call_leaf_nofp,runtime " %}
-  opcode(0xE8); /* E8 cd */
   ins_encode(Java_To_Runtime(meth));
   ins_pipe(pipe_slow);
 %}
--- a/src/os/bsd/vm/os_bsd.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/bsd/vm/os_bsd.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -152,7 +152,6 @@
 // utility functions
 
 static int SR_initialize();
-static int SR_finalize();
 
 julong os::available_memory() {
   return Bsd::available_memory();
@@ -167,20 +166,6 @@
   return Bsd::physical_memory();
 }
 
-julong os::allocatable_physical_memory(julong size) {
-#ifdef _LP64
-  return size;
-#else
-  julong result = MIN2(size, (julong)3800*M);
-   if (!is_allocatable(result)) {
-     // See comments under solaris for alignment considerations
-     julong reasonable_size = (julong)2*G - 2 * os::vm_page_size();
-     result =  MIN2(size, reasonable_size);
-   }
-   return result;
-#endif // _LP64
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // environment support
 
@@ -1214,6 +1199,9 @@
   } else if (strchr(pname, *os::path_separator()) != NULL) {
     int n;
     char** pelements = split_path(pname, &n);
+    if (pelements == NULL) {
+      return false;
+    }
     for (int i = 0 ; i < n ; i++) {
       // Really shouldn't be NULL, but check can't hurt
       if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
@@ -2780,10 +2768,6 @@
   return 0;
 }
 
-static int SR_finalize() {
-  return 0;
-}
-
 
 // returns true on success and false on error - really an error is fatal
 // but this seems the normal response to library errors
@@ -3592,16 +3576,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // debug support
 
-static address same_page(address x, address y) {
-  int page_bits = -os::vm_page_size();
-  if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
-    return x;
-  else if (x > y)
-    return (address)(intptr_t(y) | ~page_bits) + 1;
-  else
-    return (address)(intptr_t(y) & page_bits);
-}
-
 bool os::find(address addr, outputStream* st) {
   Dl_info dlinfo;
   memset(&dlinfo, 0, sizeof(dlinfo));
@@ -3625,8 +3599,8 @@
 
     if (Verbose) {
       // decode some bytes around the PC
-      address begin = same_page(addr-40, addr);
-      address end   = same_page(addr+40, addr);
+      address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size());
+      address end   = clamp_address_in_page(addr+40, addr, os::vm_page_size());
       address       lowest = (address) dlinfo.dli_sname;
       if (!lowest)  lowest = (address) dlinfo.dli_fbase;
       if (begin < lowest)  begin = lowest;
--- a/src/os/bsd/vm/perfMemory_bsd.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/bsd/vm/perfMemory_bsd.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -672,15 +672,15 @@
   RESTARTABLE(::open(filename, oflags), result);
   if (result == OS_ERR) {
     if (errno == ENOENT) {
-      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-                  "Process not found");
+      THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+                  "Process not found", OS_ERR);
     }
     else if (errno == EACCES) {
-      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-                  "Permission denied");
+      THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+                  "Permission denied", OS_ERR);
     }
     else {
-      THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
+      THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
     }
   }
 
@@ -828,7 +828,7 @@
   char* mapAddress;
   int result;
   int fd;
-  size_t size;
+  size_t size = 0;
   const char* luser = NULL;
 
   int mmap_prot;
@@ -899,9 +899,12 @@
 
   if (*sizep == 0) {
     size = sharedmem_filesize(fd, CHECK);
-    assert(size != 0, "unexpected size");
+  } else {
+    size = *sizep;
   }
 
+  assert(size > 0, "unexpected size <= 0");
+
   mapAddress = (char*)::mmap((char*)0, size, mmap_prot, MAP_SHARED, fd, 0);
 
   // attempt to close the file - restart if it gets interrupted,
--- a/src/os/linux/vm/os_linux.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/linux/vm/os_linux.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -176,7 +176,6 @@
 // utility functions
 
 static int SR_initialize();
-static int SR_finalize();
 
 julong os::available_memory() {
   return Linux::available_memory();
@@ -194,20 +193,6 @@
   return Linux::physical_memory();
 }
 
-julong os::allocatable_physical_memory(julong size) {
-#ifdef _LP64
-  return size;
-#else
-  julong result = MIN2(size, (julong)3800*M);
-   if (!is_allocatable(result)) {
-     // See comments under solaris for alignment considerations
-     julong reasonable_size = (julong)2*G - 2 * os::vm_page_size();
-     result =  MIN2(size, reasonable_size);
-   }
-   return result;
-#endif // _LP64
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // environment support
 
@@ -1647,6 +1632,9 @@
   } else if (strchr(pname, *os::path_separator()) != NULL) {
     int n;
     char** pelements = split_path(pname, &n);
+    if (pelements == NULL) {
+      return false;
+    }
     for (int i = 0 ; i < n ; i++) {
       // Really shouldn't be NULL, but check can't hurt
       if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
@@ -1811,13 +1799,15 @@
 class VM_LinuxDllLoad: public VM_Operation {
  private:
   const char *_filename;
+  char *_ebuf;
+  int _ebuflen;
   void *_lib;
  public:
-  VM_LinuxDllLoad(const char *fn) :
-    _filename(fn), _lib(NULL) {}
+  VM_LinuxDllLoad(const char *fn, char *ebuf, int ebuflen) :
+    _filename(fn), _ebuf(ebuf), _ebuflen(ebuflen), _lib(NULL) {}
   VMOp_Type type() const { return VMOp_LinuxDllLoad; }
   void doit() {
-    _lib = os::Linux::dll_load_inner(_filename);
+    _lib = os::Linux::dll_load_in_vmthread(_filename, _ebuf, _ebuflen);
     os::Linux::_stack_is_executable = true;
   }
   void* loaded_library() { return _lib; }
@@ -1865,13 +1855,13 @@
             // This is for the case where the DLL has an static
             // constructor function that executes JNI code. We cannot
             // load such DLLs in the VMThread.
-            result = ::dlopen(filename, RTLD_LAZY);
+            result = os::Linux::dlopen_helper(filename, ebuf, ebuflen);
           }
 
           ThreadInVMfromNative tiv(jt);
           debug_only(VMNativeEntryWrapper vew;)
 
-          VM_LinuxDllLoad op(filename);
+          VM_LinuxDllLoad op(filename, ebuf, ebuflen);
           VMThread::execute(&op);
           if (LoadExecStackDllInVMThread) {
             result = op.loaded_library();
@@ -1883,7 +1873,7 @@
   }
 
   if (!load_attempted) {
-    result = ::dlopen(filename, RTLD_LAZY);
+    result = os::Linux::dlopen_helper(filename, ebuf, ebuflen);
   }
 
   if (result != NULL) {
@@ -1892,11 +1882,6 @@
   }
 
   Elf32_Ehdr elf_head;
-
-  // Read system error message into ebuf
-  // It may or may not be overwritten below
-  ::strncpy(ebuf, ::dlerror(), ebuflen-1);
-  ebuf[ebuflen-1]='\0';
   int diag_msg_max_length=ebuflen-strlen(ebuf);
   char* diag_msg_buf=ebuf+strlen(ebuf);
 
@@ -2039,10 +2024,19 @@
   return NULL;
 }
 
-void * os::Linux::dll_load_inner(const char *filename) {
+void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) {
+  void * result = ::dlopen(filename, RTLD_LAZY);
+  if (result == NULL) {
+    ::strncpy(ebuf, ::dlerror(), ebuflen - 1);
+    ebuf[ebuflen-1] = '\0';
+  }
+  return result;
+}
+
+void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf, int ebuflen) {
   void * result = NULL;
   if (LoadExecStackDllInVMThread) {
-    result = ::dlopen(filename, RTLD_LAZY);
+    result = dlopen_helper(filename, ebuf, ebuflen);
   }
 
   // Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a
@@ -3663,10 +3657,6 @@
   return 0;
 }
 
-static int SR_finalize() {
-  return 0;
-}
-
 
 // returns true on success and false on error - really an error is fatal
 // but this seems the normal response to library errors
@@ -4508,16 +4498,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // debug support
 
-static address same_page(address x, address y) {
-  int page_bits = -os::vm_page_size();
-  if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
-    return x;
-  else if (x > y)
-    return (address)(intptr_t(y) | ~page_bits) + 1;
-  else
-    return (address)(intptr_t(y) & page_bits);
-}
-
 bool os::find(address addr, outputStream* st) {
   Dl_info dlinfo;
   memset(&dlinfo, 0, sizeof(dlinfo));
@@ -4541,8 +4521,8 @@
 
     if (Verbose) {
       // decode some bytes around the PC
-      address begin = same_page(addr-40, addr);
-      address end   = same_page(addr+40, addr);
+      address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size());
+      address end   = clamp_address_in_page(addr+40, addr, os::vm_page_size());
       address       lowest = (address) dlinfo.dli_sname;
       if (!lowest)  lowest = (address) dlinfo.dli_fbase;
       if (begin < lowest)  begin = lowest;
--- a/src/os/linux/vm/os_linux.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/linux/vm/os_linux.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -95,7 +95,8 @@
 
  public:
   static bool _stack_is_executable;
-  static void *dll_load_inner(const char *name);
+  static void *dlopen_helper(const char *name, char *ebuf, int ebuflen);
+  static void *dll_load_in_vmthread(const char *name, char *ebuf, int ebuflen);
 
   static void init_thread_fpu_state();
   static int  get_fpu_control_word();
--- a/src/os/linux/vm/perfMemory_linux.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/linux/vm/perfMemory_linux.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -672,15 +672,15 @@
   RESTARTABLE(::open(filename, oflags), result);
   if (result == OS_ERR) {
     if (errno == ENOENT) {
-      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-                  "Process not found");
+      THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+                  "Process not found", OS_ERR);
     }
     else if (errno == EACCES) {
-      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-                  "Permission denied");
+      THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+                  "Permission denied", OS_ERR);
     }
     else {
-      THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
+      THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
     }
   }
 
@@ -828,7 +828,7 @@
   char* mapAddress;
   int result;
   int fd;
-  size_t size;
+  size_t size = 0;
   const char* luser = NULL;
 
   int mmap_prot;
@@ -899,9 +899,12 @@
 
   if (*sizep == 0) {
     size = sharedmem_filesize(fd, CHECK);
-    assert(size != 0, "unexpected size");
+  } else {
+    size = *sizep;
   }
 
+  assert(size > 0, "unexpected size <= 0");
+
   mapAddress = (char*)::mmap((char*)0, size, mmap_prot, MAP_SHARED, fd, 0);
 
   // attempt to close the file - restart if it gets interrupted,
--- a/src/os/posix/launcher/launcher.script	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/posix/launcher/launcher.script	Fri Apr 12 10:14:42 2013 +0100
@@ -199,7 +199,7 @@
 	rm -f $GDBSCR
         ;;
     dbx)
-        $DBX -s $MYDIR/.dbxrc $LAUNCHER $JPARAMS
+        $DBX -s $HOME/.dbxrc $LAUNCHER $JPARMS
         ;;
     valgrind)
         echo Warning: Defaulting to 16Mb heap to make Valgrind run faster, use -Xmx for larger heap
--- a/src/os/posix/vm/os_posix.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/posix/vm/os_posix.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -188,4 +188,66 @@
   st->cr();
 }
 
+bool os::has_allocatable_memory_limit(julong* limit) {
+  struct rlimit rlim;
+  int getrlimit_res = getrlimit(RLIMIT_AS, &rlim);
+  // if there was an error when calling getrlimit, assume that there is no limitation
+  // on virtual memory.
+  bool result;
+  if ((getrlimit_res != 0) || (rlim.rlim_cur == RLIM_INFINITY)) {
+    result = false;
+  } else {
+    *limit = (julong)rlim.rlim_cur;
+    result = true;
+  }
+#ifdef _LP64
+  return result;
+#else
+  // arbitrary virtual space limit for 32 bit Unices found by testing. If
+  // getrlimit above returned a limit, bound it with this limit. Otherwise
+  // directly use it.
+  const julong max_virtual_limit = (julong)3800*M;
+  if (result) {
+    *limit = MIN2(*limit, max_virtual_limit);
+  } else {
+    *limit = max_virtual_limit;
+  }
 
+  // bound by actually allocatable memory. The algorithm uses two bounds, an
+  // upper and a lower limit. The upper limit is the current highest amount of
+  // memory that could not be allocated, the lower limit is the current highest
+  // amount of memory that could be allocated.
+  // The algorithm iteratively refines the result by halving the difference
+  // between these limits, updating either the upper limit (if that value could
+  // not be allocated) or the lower limit (if the that value could be allocated)
+  // until the difference between these limits is "small".
+
+  // the minimum amount of memory we care about allocating.
+  const julong min_allocation_size = M;
+
+  julong upper_limit = *limit;
+
+  // first check a few trivial cases
+  if (is_allocatable(upper_limit) || (upper_limit <= min_allocation_size)) {
+    *limit = upper_limit;
+  } else if (!is_allocatable(min_allocation_size)) {
+    // we found that not even min_allocation_size is allocatable. Return it
+    // anyway. There is no point to search for a better value any more.
+    *limit = min_allocation_size;
+  } else {
+    // perform the binary search.
+    julong lower_limit = min_allocation_size;
+    while ((upper_limit - lower_limit) > min_allocation_size) {
+      julong temp_limit = ((upper_limit - lower_limit) / 2) + lower_limit;
+      temp_limit = align_size_down_(temp_limit, min_allocation_size);
+      if (is_allocatable(temp_limit)) {
+        lower_limit = temp_limit;
+      } else {
+        upper_limit = temp_limit;
+      }
+    }
+    *limit = lower_limit;
+  }
+  return true;
+#endif
+}
--- a/src/os/solaris/vm/os_solaris.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/solaris/vm/os_solaris.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -476,24 +476,6 @@
    return Solaris::physical_memory();
 }
 
-julong os::allocatable_physical_memory(julong size) {
-#ifdef _LP64
-   return size;
-#else
-   julong result = MIN2(size, (julong)3835*M);
-   if (!is_allocatable(result)) {
-     // Memory allocations will be aligned but the alignment
-     // is not known at this point.  Alignments will
-     // be at most to LargePageSizeInBytes.  Protect
-     // allocations from alignments up to illegal
-     // values. If at this point 2G is illegal.
-     julong reasonable_size = (julong)2*G - 2 * LargePageSizeInBytes;
-     result =  MIN2(size, reasonable_size);
-   }
-   return result;
-#endif
-}
-
 static hrtime_t first_hrtime = 0;
 static const hrtime_t hrtime_hz = 1000*1000*1000;
 const int LOCK_BUSY = 1;
@@ -1903,6 +1885,9 @@
   } else if (strchr(pname, *os::path_separator()) != NULL) {
     int n;
     char** pelements = split_path(pname, &n);
+    if (pelements == NULL) {
+      return false;
+    }
     for (int i = 0 ; i < n ; i++) {
       // really shouldn't be NULL but what the heck, check can't hurt
       if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
@@ -5805,16 +5790,6 @@
 
 //---------------------------------------------------------------------------------
 
-static address same_page(address x, address y) {
-  intptr_t page_bits = -os::vm_page_size();
-  if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
-    return x;
-  else if (x > y)
-    return (address)(intptr_t(y) | ~page_bits) + 1;
-  else
-    return (address)(intptr_t(y) & page_bits);
-}
-
 bool os::find(address addr, outputStream* st) {
   Dl_info dlinfo;
   memset(&dlinfo, 0, sizeof(dlinfo));
@@ -5840,8 +5815,8 @@
 
     if (Verbose) {
       // decode some bytes around the PC
-      address begin = same_page(addr-40, addr);
-      address end   = same_page(addr+40, addr);
+      address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size());
+      address end   = clamp_address_in_page(addr+40, addr, os::vm_page_size());
       address       lowest = (address) dlinfo.dli_sname;
       if (!lowest)  lowest = (address) dlinfo.dli_fbase;
       if (begin < lowest)  begin = lowest;
--- a/src/os/solaris/vm/perfMemory_solaris.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/solaris/vm/perfMemory_solaris.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -687,15 +687,15 @@
   RESTARTABLE(::open(filename, oflags), result);
   if (result == OS_ERR) {
     if (errno == ENOENT) {
-      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-                  "Process not found");
+      THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+                  "Process not found", OS_ERR);
     }
     else if (errno == EACCES) {
-      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-                  "Permission denied");
+      THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+                  "Permission denied", OS_ERR);
     }
     else {
-      THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
+      THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
     }
   }
 
@@ -843,7 +843,7 @@
   char* mapAddress;
   int result;
   int fd;
-  size_t size;
+  size_t size = 0;
   const char* luser = NULL;
 
   int mmap_prot;
@@ -914,9 +914,12 @@
 
   if (*sizep == 0) {
     size = sharedmem_filesize(fd, CHECK);
-    assert(size != 0, "unexpected size");
+  } else {
+    size = *sizep;
   }
 
+  assert(size > 0, "unexpected size <= 0");
+
   mapAddress = (char*)::mmap((char*)0, size, mmap_prot, MAP_SHARED, fd, 0);
 
   // attempt to close the file - restart if it gets interrupted,
--- a/src/os/windows/vm/os_windows.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/windows/vm/os_windows.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -686,12 +686,17 @@
   return win32::physical_memory();
 }
 
-julong os::allocatable_physical_memory(julong size) {
+bool os::has_allocatable_memory_limit(julong* limit) {
+  MEMORYSTATUSEX ms;
+  ms.dwLength = sizeof(ms);
+  GlobalMemoryStatusEx(&ms);
 #ifdef _LP64
-  return size;
+  *limit = (julong)ms.ullAvailVirtual;
+  return true;
 #else
   // Limit to 1400m because of the 2gb address space wall
-  return MIN2(size, (julong)1400*M);
+  *limit = MIN2((julong)1400*M, (julong)ms.ullAvailVirtual);
+  return true;
 #endif
 }
 
@@ -1177,6 +1182,9 @@
   } else if (strchr(pname, *os::path_separator()) != NULL) {
     int n;
     char** pelements = split_path(pname, &n);
+    if (pelements == NULL) {
+      return false;
+    }
     for (int i = 0 ; i < n ; i++) {
       char* path = pelements[i];
       // Really shouldn't be NULL, but check can't hurt
@@ -3768,6 +3776,8 @@
   }
 }
 
+static jint initSock();
+
 // this is called _after_ the global arguments have been parsed
 jint os::init_2(void) {
   // Allocate a single page and mark it as readable for safepoint polling
@@ -3898,6 +3908,10 @@
     if (!success) UseNUMAInterleaving = false;
   }
 
+  if (initSock() != JNI_OK) {
+    return JNI_ERR;
+  }
+
   return JNI_OK;
 }
 
@@ -4894,42 +4908,24 @@
 // We don't build a headless jre for Windows
 bool os::is_headless_jre() { return false; }
 
-
-typedef CRITICAL_SECTION mutex_t;
-#define mutexInit(m)    InitializeCriticalSection(m)
-#define mutexDestroy(m) DeleteCriticalSection(m)
-#define mutexLock(m)    EnterCriticalSection(m)
-#define mutexUnlock(m)  LeaveCriticalSection(m)
-
-static bool sock_initialized = FALSE;
-static mutex_t sockFnTableMutex;
-
-static void initSock() {
+static jint initSock() {
   WSADATA wsadata;
 
   if (!os::WinSock2Dll::WinSock2Available()) {
-    jio_fprintf(stderr, "Could not load Winsock 2 (error: %d)\n",
+    jio_fprintf(stderr, "Could not load Winsock (error: %d)\n",
       ::GetLastError());
-    return;
-  }
-  if (sock_initialized == TRUE) return;
-
-  ::mutexInit(&sockFnTableMutex);
-  ::mutexLock(&sockFnTableMutex);
-  if (os::WinSock2Dll::WSAStartup(MAKEWORD(1,1), &wsadata) != 0) {
-      jio_fprintf(stderr, "Could not initialize Winsock\n");
-  }
-  sock_initialized = TRUE;
-  ::mutexUnlock(&sockFnTableMutex);
+    return JNI_ERR;
+  }
+
+  if (os::WinSock2Dll::WSAStartup(MAKEWORD(2,2), &wsadata) != 0) {
+    jio_fprintf(stderr, "Could not initialize Winsock (error: %d)\n",
+      ::GetLastError());
+    return JNI_ERR;
+  }
+  return JNI_OK;
 }
 
 struct hostent* os::get_host_by_name(char* name) {
-  if (!sock_initialized) {
-    initSock();
-  }
-  if (!os::WinSock2Dll::WinSock2Available()) {
-    return NULL;
-  }
   return (struct hostent*)os::WinSock2Dll::gethostbyname(name);
 }
 
--- a/src/os/windows/vm/perfMemory_windows.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os/windows/vm/perfMemory_windows.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1581,7 +1581,7 @@
   ResourceMark rm;
 
   void *mapAddress = 0;
-  size_t size;
+  size_t size = 0;
   HANDLE fmh;
   DWORD ofm_access;
   DWORD mv_access;
@@ -1652,9 +1652,12 @@
 
   if (*sizep == 0) {
     size = sharedmem_filesize(rfilename, CHECK);
-    assert(size != 0, "unexpected size");
+  } else {
+    size = *sizep;
   }
 
+  assert(size > 0, "unexpected size <= 0");
+
   // Open the file mapping object with the given name
   fmh = open_sharedmem_object(robjectname, ofm_access, CHECK);
 
--- a/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad	Fri Apr 12 10:14:42 2013 +0100
@@ -55,20 +55,6 @@
   // adding a syntax that specifies the sizes of fields in an order,
   // so that the adlc can build the emit functions automagically
 
-  enc_class Java_To_Runtime(method meth) %{
-    // No relocation needed
-
-    // movq r10, <meth>
-    emit_opcode(cbuf, Assembler::REX_WB);
-    emit_opcode(cbuf, 0xB8 | (R10_enc - 8));
-    emit_d64(cbuf, (int64_t) $meth$$method);
-
-    // call (r10)
-    emit_opcode(cbuf, Assembler::REX_B);
-    emit_opcode(cbuf, 0xFF);
-    emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
-  %}
-
 %}
 
 
@@ -76,8 +62,4 @@
 
 source %{
 
-int MachCallRuntimeNode::ret_addr_offset() {
-  return 13; // movq r10,#addr; callq (r10)
-}
-
 %}
--- a/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -46,7 +46,7 @@
 
 define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
 
-// Used on 64 bit platforms for UseCompressedOops base address or CDS
+// Used on 64 bit platforms for UseCompressedOops base address
 define_pd_global(uintx, HeapBaseMinAddress,      2*G);
 
 #endif // OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP
--- a/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -41,7 +41,7 @@
 define_pd_global(intx,  CompilerThreadStackSize, 0);
 define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
 
-// Used on 64 bit platforms for UseCompressedOops base address or CDS
+// Used on 64 bit platforms for UseCompressedOops base address
 define_pd_global(uintx, HeapBaseMinAddress,      2*G);
 
 #endif // OS_CPU_BSD_ZERO_VM_GLOBALS_BSD_ZERO_HPP
--- a/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -33,7 +33,7 @@
 define_pd_global(uintx, JVMInvokeMethodSlack,    12288);
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
-// Used on 64 bit platforms for UseCompressedOops base address or CDS
+// Used on 64 bit platforms for UseCompressedOops base address
 define_pd_global(uintx, HeapBaseMinAddress,      CONST64(4)*G);
 
 #endif // OS_CPU_LINUX_SPARC_VM_GLOBALS_LINUX_SPARC_HPP
--- a/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -44,7 +44,7 @@
 
 define_pd_global(uintx,JVMInvokeMethodSlack,     8192);
 
-// Used on 64 bit platforms for UseCompressedOops base address or CDS
+// Used on 64 bit platforms for UseCompressedOops base address
 define_pd_global(uintx,HeapBaseMinAddress,       2*G);
 
 #endif // OS_CPU_LINUX_X86_VM_GLOBALS_LINUX_X86_HPP
--- a/src/os_cpu/linux_x86/vm/linux_x86_64.ad	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/linux_x86/vm/linux_x86_64.ad	Fri Apr 12 10:14:42 2013 +0100
@@ -55,20 +55,6 @@
   // adding a syntax that specifies the sizes of fields in an order,
   // so that the adlc can build the emit functions automagically
 
-  enc_class Java_To_Runtime(method meth) %{
-    // No relocation needed
-
-    // movq r10, <meth>
-    emit_opcode(cbuf, Assembler::REX_WB);
-    emit_opcode(cbuf, 0xB8 | (R10_enc - 8));
-    emit_d64(cbuf, (int64_t) $meth$$method);
-
-    // call (r10)
-    emit_opcode(cbuf, Assembler::REX_B);
-    emit_opcode(cbuf, 0xFF);
-    emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
-  %}
-
 %}
 
 
@@ -76,8 +62,4 @@
 
 source %{
 
-int MachCallRuntimeNode::ret_addr_offset() {
-  return 13; // movq r10,#addr; callq (r10)
-}
-
 %}
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -340,7 +340,7 @@
         // here if the underlying file has been truncated.
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
-        nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
+        nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL;
         if (nm != NULL && nm->has_unsafe_access()) {
           stub = StubRoutines::handler_for_unsafe_access();
         }
--- a/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -41,7 +41,7 @@
 define_pd_global(intx,  CompilerThreadStackSize, 0);
 define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
 
-// Used on 64 bit platforms for UseCompressedOops base address or CDS
+// Used on 64 bit platforms for UseCompressedOops base address
 define_pd_global(uintx, HeapBaseMinAddress,      2*G);
 
 #endif // OS_CPU_LINUX_ZERO_VM_GLOBALS_LINUX_ZERO_HPP
--- a/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -33,7 +33,7 @@
 define_pd_global(uintx, JVMInvokeMethodSlack,    12288);
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
-// Used on 64 bit platforms for UseCompressedOops base address or CDS
+// Used on 64 bit platforms for UseCompressedOops base address
 #ifdef _LP64
 define_pd_global(uintx, HeapBaseMinAddress,      CONST64(4)*G);
 #else
--- a/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -43,7 +43,7 @@
 
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
-// Used on 64 bit platforms for UseCompressedOops base address or CDS
+// Used on 64 bit platforms for UseCompressedOops base address
 define_pd_global(uintx,HeapBaseMinAddress,       256*M);
 
 #endif // OS_CPU_SOLARIS_X86_VM_GLOBALS_SOLARIS_X86_HPP
--- a/src/os_cpu/solaris_x86/vm/solaris_x86_64.ad	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/solaris_x86/vm/solaris_x86_64.ad	Fri Apr 12 10:14:42 2013 +0100
@@ -54,39 +54,10 @@
   // main source block for now.  In future, we can generalize this by
   // adding a syntax that specifies the sizes of fields in an order,
   // so that the adlc can build the emit functions automagically
-
-  enc_class Java_To_Runtime(method meth) %{
-    // No relocation needed
-
-    // movq r10, <meth>
-    emit_opcode(cbuf, Assembler::REX_WB);
-    emit_opcode(cbuf, 0xB8 | (R10_enc - 8));
-    emit_d64(cbuf, (int64_t) $meth$$method);
-
-    // call (r10)
-    emit_opcode(cbuf, Assembler::REX_B);
-    emit_opcode(cbuf, 0xFF);
-    emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
-  %}
-
-  enc_class post_call_verify_mxcsr %{
-    MacroAssembler _masm(&cbuf);
-    if (RestoreMXCSROnJNICalls) {
-      __ ldmxcsr(ExternalAddress(StubRoutines::amd64::mxcsr_std()));
-    }
-    else if (CheckJNICalls) {
-      __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::amd64::verify_mxcsr_entry())));
-    }
-  %}
 %}
 
 
 // Platform dependent source
 
 source %{
-
-int MachCallRuntimeNode::ret_addr_offset() {
-  return 13; // movq r10,#addr; callq (r10)
-}
-
 %}
--- a/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -45,7 +45,7 @@
 
 define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
 
-// Used on 64 bit platforms for UseCompressedOops base address or CDS
+// Used on 64 bit platforms for UseCompressedOops base address
 define_pd_global(uintx, HeapBaseMinAddress,      2*G);
 
 #endif // OS_CPU_WINDOWS_X86_VM_GLOBALS_WINDOWS_X86_HPP
--- a/src/os_cpu/windows_x86/vm/windows_x86_64.ad	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/os_cpu/windows_x86/vm/windows_x86_64.ad	Fri Apr 12 10:14:42 2013 +0100
@@ -53,30 +53,11 @@
   // adding a syntax that specifies the sizes of fields in an order,
   // so that the adlc can build the emit functions automagically
 
-  enc_class Java_To_Runtime (method meth) %{    // CALL Java_To_Runtime
-    // No relocation needed
+%}
+
 
-    // movq r10, <meth>
-    emit_opcode(cbuf, Assembler::REX_WB);
-    emit_opcode(cbuf, 0xB8 | (R10_enc - 8));
-    emit_d64(cbuf, (int64_t) $meth$$method);
+// Platform dependent source
 
-    // call (r10)
-    emit_opcode(cbuf, Assembler::REX_B);
-    emit_opcode(cbuf, 0xFF);
-    emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
-  %}
+source %{
 
 %}
-
-//
-// Platform dependent source
-//
-source %{
-
-int MachCallRuntimeNode::ret_addr_offset()
-{
-  return 13; // movq r10,#addr; callq (r10)
-}
-
-%}
--- a/src/share/tools/ProjectCreator/BuildConfig.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/tools/ProjectCreator/BuildConfig.java	Fri Apr 12 10:14:42 2013 +0100
@@ -568,36 +568,6 @@
     }
 }
 
-class KernelDebugConfig extends GenericDebugConfig {
-    String getOptFlag() {
-        return getCI().getNoOptFlag();
-    }
-
-    KernelDebugConfig() {
-        initNames("kernel", "debug", "jvm.dll");
-        init(getIncludes(), getDefines());
-    }
-}
-
-
-class KernelFastDebugConfig extends GenericDebugConfig {
-    String getOptFlag() {
-        return getCI().getOptFlag();
-    }
-
-    KernelFastDebugConfig() {
-        initNames("kernel", "fastdebug", "jvm.dll");
-        init(getIncludes(), getDefines());
-    }
-}
-
-
-class KernelProductConfig extends ProductConfig {
-    KernelProductConfig() {
-        initNames("kernel", "product", "jvm.dll");
-        init(getIncludes(), getDefines());
-    }
-}
 
 abstract class CompilerInterface {
     abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir);
--- a/src/share/tools/ProjectCreator/WinGammaPlatform.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/tools/ProjectCreator/WinGammaPlatform.java	Fri Apr 12 10:14:42 2013 +0100
@@ -564,12 +564,6 @@
         allConfigs.add(new CoreFastDebugConfig());
         allConfigs.add(new CoreProductConfig());
 
-        if (platform.equals("Win32")) {
-            allConfigs.add(new KernelDebugConfig());
-            allConfigs.add(new KernelFastDebugConfig());
-            allConfigs.add(new KernelProductConfig());
-        }
-
         return allConfigs;
     }
 
--- a/src/share/tools/launcher/wildcard.c	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/tools/launcher/wildcard.c	Fri Apr 12 10:14:42 2013 +0100
@@ -368,8 +368,10 @@
     const char *basename;
     FileList fl = FileList_new(16);
     WildcardIterator it = WildcardIterator_for(wildcard);
-    if (it == NULL)
+    if (it == NULL) {
+        FileList_free(fl);
         return NULL;
+    }
     while ((basename = WildcardIterator_next(it)) != NULL)
         if (isJarFileName(basename))
             FileList_add(fl, wildcardConcat(wildcard, basename));
--- a/src/share/vm/adlc/archDesc.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/adlc/archDesc.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -832,6 +832,7 @@
     int         length  = (int)strlen(rc_name) + (int)strlen(mask) + 5;
     char       *regMask = new char[length];
     sprintf(regMask,"%s%s()", rc_name, mask);
+    delete[] rc_name;
     return regMask;
   }
 }
--- a/src/share/vm/adlc/dfa.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/adlc/dfa.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -191,12 +191,19 @@
 // Macro equivalent to: _kids[0]->valid(FOO) && _kids[1]->valid(BAR)
 //
 static void child_test(FILE *fp, MatchList &mList) {
-  if( mList._lchild )           // If left child, check it
-    fprintf(fp, "STATE__VALID_CHILD(_kids[0], %s)", ArchDesc::getMachOperEnum(mList._lchild));
-  if( mList._lchild && mList._rchild )      // If both, add the "&&"
-    fprintf(fp, " && " );
-  if( mList._rchild )           // If right child, check it
-    fprintf(fp, "STATE__VALID_CHILD(_kids[1], %s)", ArchDesc::getMachOperEnum(mList._rchild));
+  if (mList._lchild) { // If left child, check it
+    const char* lchild_to_upper = ArchDesc::getMachOperEnum(mList._lchild);
+    fprintf(fp, "STATE__VALID_CHILD(_kids[0], %s)", lchild_to_upper);
+    delete[] lchild_to_upper;
+  }
+  if (mList._lchild && mList._rchild) { // If both, add the "&&"
+    fprintf(fp, " && ");
+  }
+  if (mList._rchild) { // If right child, check it
+    const char* rchild_to_upper = ArchDesc::getMachOperEnum(mList._rchild);
+    fprintf(fp, "STATE__VALID_CHILD(_kids[1], %s)", rchild_to_upper);
+    delete[] rchild_to_upper;
+  }
 }
 
 //---------------------------calc_cost-----------------------------------------
@@ -206,13 +213,17 @@
 Expr *ArchDesc::calc_cost(FILE *fp, const char *spaces, MatchList &mList, ProductionState &status) {
   fprintf(fp, "%sunsigned int c = ", spaces);
   Expr *c = new Expr("0");
-  if (mList._lchild ) {                   // If left child, add it in
-    sprintf(Expr::buffer(), "_kids[0]->_cost[%s]", ArchDesc::getMachOperEnum(mList._lchild));
+  if (mList._lchild) { // If left child, add it in
+    const char* lchild_to_upper = ArchDesc::getMachOperEnum(mList._lchild);
+    sprintf(Expr::buffer(), "_kids[0]->_cost[%s]", lchild_to_upper);
     c->add(Expr::buffer());
+    delete[] lchild_to_upper;
 }
-  if (mList._rchild) {                    // If right child, add it in
-    sprintf(Expr::buffer(), "_kids[1]->_cost[%s]", ArchDesc::getMachOperEnum(mList._rchild));
+  if (mList._rchild) { // If right child, add it in
+    const char* rchild_to_upper = ArchDesc::getMachOperEnum(mList._rchild);
+    sprintf(Expr::buffer(), "_kids[1]->_cost[%s]", rchild_to_upper);
     c->add(Expr::buffer());
+    delete[] rchild_to_upper;
   }
   // Add in cost of this rule
   const char *mList_cost = mList.get_cost();
@@ -232,15 +243,17 @@
   fprintf(fp, "%s", spaces4);
   // Only generate child tests if this is not a leaf node
   bool has_child_constraints = mList._lchild || mList._rchild;
-  const char *predicate_test        = mList.get_pred();
-  if( has_child_constraints || predicate_test ) {
+  const char *predicate_test = mList.get_pred();
+  if (has_child_constraints || predicate_test) {
     // Open the child-and-predicate-test braces
     fprintf(fp, "if( ");
     status.set_constraint(hasConstraint);
     child_test(fp, mList);
     // Only generate predicate test if one exists for this match
-    if( predicate_test ) {
-      if( has_child_constraints ) { fprintf(fp," &&\n"); }
+    if (predicate_test) {
+      if (has_child_constraints) {
+        fprintf(fp," &&\n");
+      }
       fprintf(fp, "%s  %s", spaces6, predicate_test);
     }
     // End of outer tests
--- a/src/share/vm/asm/assembler.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/asm/assembler.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -284,15 +284,19 @@
   DelayedConstant::update_all();
 }
 
-
-
-
 void AbstractAssembler::block_comment(const char* comment) {
   if (sect() == CodeBuffer::SECT_INSTS) {
     code_section()->outer()->block_comment(offset(), comment);
   }
 }
 
+const char* AbstractAssembler::code_string(const char* str) {
+  if (sect() == CodeBuffer::SECT_INSTS || sect() == CodeBuffer::SECT_STUBS) {
+    return code_section()->outer()->code_string(str);
+  }
+  return NULL;
+}
+
 bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
   // Exception handler checks the nmethod's implicit null checks table
   // only when this method returns false.
--- a/src/share/vm/asm/assembler.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/asm/assembler.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -336,6 +336,8 @@
   // along with the disassembly when printing nmethods.  Currently
   // only supported in the instruction section of the code buffer.
   void block_comment(const char* comment);
+  // Copy str to a buffer that has the same lifetime as the CodeBuffer
+  const char* code_string(const char* str);
 
   // Label functions
   void bind(Label& L); // binds an unbound label L to the current code position
--- a/src/share/vm/asm/codeBuffer.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/asm/codeBuffer.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -703,8 +703,8 @@
   this->compute_final_layout(&dest);
   relocate_code_to(&dest);
 
-  // transfer comments from buffer to blob
-  dest_blob->set_comments(_comments);
+  // transfer strings and comments from buffer to blob
+  dest_blob->set_strings(_strings);
 
   // Done moving code bytes; were they the right size?
   assert(round_to(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity");
@@ -1003,58 +1003,78 @@
 
 
 void CodeBuffer::block_comment(intptr_t offset, const char * comment) {
-  _comments.add_comment(offset, comment);
+  _strings.add_comment(offset, comment);
+}
+
+const char* CodeBuffer::code_string(const char* str) {
+  return _strings.add_string(str);
 }
 
-class CodeComment: public CHeapObj<mtCode> {
+class CodeString: public CHeapObj<mtCode> {
  private:
-  friend class CodeComments;
+  friend class CodeStrings;
+  const char * _string;
+  CodeString*  _next;
   intptr_t     _offset;
-  const char * _comment;
-  CodeComment* _next;
 
-  ~CodeComment() {
+  ~CodeString() {
     assert(_next == NULL, "wrong interface for freeing list");
-    os::free((void*)_comment, mtCode);
-  }
-
- public:
-  CodeComment(intptr_t offset, const char * comment) {
-    _offset = offset;
-    _comment = os::strdup(comment, mtCode);
-    _next = NULL;
+    os::free((void*)_string, mtCode);
   }
 
-  intptr_t     offset()  const { return _offset;  }
-  const char * comment() const { return _comment; }
-  CodeComment* next()          { return _next; }
-
-  void set_next(CodeComment* next) { _next = next; }
+  bool is_comment() const { return _offset >= 0; }
 
-  CodeComment* find(intptr_t offset) {
-    CodeComment* a = this;
-    while (a != NULL && a->_offset != offset) {
-      a = a->_next;
-    }
-    return a;
+ public:
+  CodeString(const char * string, intptr_t offset = -1)
+    : _next(NULL), _offset(offset) {
+    _string = os::strdup(string, mtCode);
   }
 
-  // Convenience for add_comment.
-  CodeComment* find_last(intptr_t offset) {
-    CodeComment* a = find(offset);
-    if (a != NULL) {
-      while ((a->_next != NULL) && (a->_next->_offset == offset)) {
-        a = a->_next;
-      }
+  const char * string() const { return _string; }
+  intptr_t     offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset;  }
+  CodeString* next()    const { return _next; }
+
+  void set_next(CodeString* next) { _next = next; }
+
+  CodeString* first_comment() {
+    if (is_comment()) {
+      return this;
+    } else {
+      return next_comment();
     }
-    return a;
+  }
+  CodeString* next_comment() const {
+    CodeString* s = _next;
+    while (s != NULL && !s->is_comment()) {
+      s = s->_next;
+    }
+    return s;
   }
 };
 
+CodeString* CodeStrings::find(intptr_t offset) const {
+  CodeString* a = _strings->first_comment();
+  while (a != NULL && a->offset() != offset) {
+    a = a->next_comment();
+  }
+  return a;
+}
 
-void CodeComments::add_comment(intptr_t offset, const char * comment) {
-  CodeComment* c      = new CodeComment(offset, comment);
-  CodeComment* inspos = (_comments == NULL) ? NULL : _comments->find_last(offset);
+// Convenience for add_comment.
+CodeString* CodeStrings::find_last(intptr_t offset) const {
+  CodeString* a = find(offset);
+  if (a != NULL) {
+    CodeString* c = NULL;
+    while (((c = a->next_comment()) != NULL) && (c->offset() == offset)) {
+      a = c;
+    }
+  }
+  return a;
+}
+
+void CodeStrings::add_comment(intptr_t offset, const char * comment) {
+  CodeString* c      = new CodeString(comment, offset);
+  CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset);
 
   if (inspos) {
     // insert after already existing comments with same offset
@@ -1062,43 +1082,47 @@
     inspos->set_next(c);
   } else {
     // no comments with such offset, yet. Insert before anything else.
-    c->set_next(_comments);
-    _comments = c;
+    c->set_next(_strings);
+    _strings = c;
   }
 }
 
-
-void CodeComments::assign(CodeComments& other) {
-  _comments = other._comments;
+void CodeStrings::assign(CodeStrings& other) {
+  _strings = other._strings;
 }
 
-
-void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) const {
-  if (_comments != NULL) {
-    CodeComment* c = _comments->find(offset);
+void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
+  if (_strings != NULL) {
+    CodeString* c = find(offset);
     while (c && c->offset() == offset) {
       stream->bol();
       stream->print("  ;; ");
-      stream->print_cr(c->comment());
-      c = c->next();
+      stream->print_cr(c->string());
+      c = c->next_comment();
     }
   }
 }
 
 
-void CodeComments::free() {
-  CodeComment* n = _comments;
+void CodeStrings::free() {
+  CodeString* n = _strings;
   while (n) {
     // unlink the node from the list saving a pointer to the next
-    CodeComment* p = n->_next;
-    n->_next = NULL;
+    CodeString* p = n->next();
+    n->set_next(NULL);
     delete n;
     n = p;
   }
-  _comments = NULL;
+  _strings = NULL;
 }
 
-
+const char* CodeStrings::add_string(const char * string) {
+  CodeString* s = new CodeString(string);
+  s->set_next(_strings);
+  _strings = s;
+  assert(s->string() != NULL, "should have a string");
+  return s->string();
+}
 
 void CodeBuffer::decode() {
   ttyLocker ttyl;
--- a/src/share/vm/asm/codeBuffer.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/asm/codeBuffer.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -28,7 +28,7 @@
 #include "code/oopRecorder.hpp"
 #include "code/relocInfo.hpp"
 
-class CodeComments;
+class CodeStrings;
 class PhaseCFG;
 class Compile;
 class BufferBlob;
@@ -240,27 +240,31 @@
 #endif //PRODUCT
 };
 
-class CodeComment;
-class CodeComments VALUE_OBJ_CLASS_SPEC {
+class CodeString;
+class CodeStrings VALUE_OBJ_CLASS_SPEC {
 private:
 #ifndef PRODUCT
-  CodeComment* _comments;
+  CodeString* _strings;
 #endif
 
+  CodeString* find(intptr_t offset) const;
+  CodeString* find_last(intptr_t offset) const;
+
 public:
-  CodeComments() {
+  CodeStrings() {
 #ifndef PRODUCT
-    _comments = NULL;
+    _strings = NULL;
 #endif
   }
 
+  const char* add_string(const char * string) PRODUCT_RETURN_(return NULL;);
+
   void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
   void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN;
-  void assign(CodeComments& other)  PRODUCT_RETURN;
+  void assign(CodeStrings& other)  PRODUCT_RETURN;
   void free() PRODUCT_RETURN;
 };
 
-
 // A CodeBuffer describes a memory space into which assembly
 // code is generated.  This memory space usually occupies the
 // interior of a single BufferBlob, but in some cases it may be
@@ -326,7 +330,7 @@
   csize_t      _total_size;     // size in bytes of combined memory buffer
 
   OopRecorder* _oop_recorder;
-  CodeComments _comments;
+  CodeStrings  _strings;
   OopRecorder  _default_oop_recorder;  // override with initialize_oop_recorder
   Arena*       _overflow_arena;
 
@@ -527,7 +531,7 @@
   void initialize_oop_recorder(OopRecorder* r);
 
   OopRecorder* oop_recorder() const   { return _oop_recorder; }
-  CodeComments& comments()            { return _comments; }
+  CodeStrings& strings()              { return _strings; }
 
   // Code generation
   void relocate(address at, RelocationHolder const& rspec, int format = 0) {
@@ -556,6 +560,7 @@
   address transform_address(const CodeBuffer &cb, address addr) const;
 
   void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
+  const char* code_string(const char* str) PRODUCT_RETURN_(return NULL;);
 
   // Log a little info about section usage in the CodeBuffer
   void log_section_sizes(const char* name);
--- a/src/share/vm/c1/c1_Canonicalizer.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_Canonicalizer.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -937,4 +937,6 @@
 void Canonicalizer::do_ProfileCall(ProfileCall* x) {}
 void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {}
 void Canonicalizer::do_RuntimeCall(RuntimeCall* x) {}
+void Canonicalizer::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
+void Canonicalizer::do_Assert(Assert* x) {}
 void Canonicalizer::do_MemBar(MemBar* x) {}
--- a/src/share/vm/c1/c1_Canonicalizer.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_Canonicalizer.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -107,6 +107,8 @@
   virtual void do_ProfileInvoke  (ProfileInvoke*   x);
   virtual void do_RuntimeCall    (RuntimeCall*     x);
   virtual void do_MemBar         (MemBar*          x);
+  virtual void do_RangeCheckPredicate(RangeCheckPredicate* x);
+  virtual void do_Assert         (Assert*          x);
 };
 
 #endif // SHARE_VM_C1_C1_CANONICALIZER_HPP
--- a/src/share/vm/c1/c1_CodeStubs.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_CodeStubs.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -166,6 +166,22 @@
 #endif // PRODUCT
 };
 
+// stub used when predicate fails and deoptimization is needed
+class PredicateFailedStub: public CodeStub {
+ private:
+  CodeEmitInfo* _info;
+
+ public:
+  PredicateFailedStub(CodeEmitInfo* info);
+  virtual void emit_code(LIR_Assembler* e);
+  virtual CodeEmitInfo* info() const             { return _info; }
+  virtual void visit(LIR_OpVisitState* visitor) {
+    visitor->do_slow_case(_info);
+  }
+#ifndef PRODUCT
+  virtual void print_name(outputStream* out) const { out->print("PredicateFailedStub"); }
+#endif // PRODUCT
+};
 
 class DivByZeroStub: public CodeStub {
  private:
--- a/src/share/vm/c1/c1_Compilation.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_Compilation.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -33,13 +33,16 @@
 #include "c1/c1_ValueStack.hpp"
 #include "code/debugInfoRec.hpp"
 #include "compiler/compileLog.hpp"
+#include "c1/c1_RangeCheckElimination.hpp"
 
 
 typedef enum {
   _t_compile,
   _t_setup,
-  _t_optimizeIR,
   _t_buildIR,
+  _t_optimize_blocks,
+  _t_optimize_null_checks,
+  _t_rangeCheckElimination,
   _t_emit_lir,
   _t_linearScan,
   _t_lirGeneration,
@@ -52,8 +55,10 @@
 static const char * timer_name[] = {
   "compile",
   "setup",
-  "optimizeIR",
   "buildIR",
+  "optimize_blocks",
+  "optimize_null_checks",
+  "rangeCheckElimination",
   "emit_lir",
   "linearScan",
   "lirGeneration",
@@ -159,9 +164,9 @@
   if (UseC1Optimizations) {
     NEEDS_CLEANUP
     // optimization
-    PhaseTraceTime timeit(_t_optimizeIR);
+    PhaseTraceTime timeit(_t_optimize_blocks);
 
-    _hir->optimize();
+    _hir->optimize_blocks();
   }
 
   _hir->verify();
@@ -180,13 +185,47 @@
   _hir->compute_code();
 
   if (UseGlobalValueNumbering) {
-    ResourceMark rm;
+    // No resource mark here! LoopInvariantCodeMotion can allocate ValueStack objects.
     int instructions = Instruction::number_of_instructions();
     GlobalValueNumbering gvn(_hir);
     assert(instructions == Instruction::number_of_instructions(),
            "shouldn't have created an instructions");
   }
 
+  _hir->verify();
+
+#ifndef PRODUCT
+  if (PrintCFGToFile) {
+    CFGPrinter::print_cfg(_hir, "Before RangeCheckElimination", true, false);
+  }
+#endif
+
+  if (RangeCheckElimination) {
+    if (_hir->osr_entry() == NULL) {
+      PhaseTraceTime timeit(_t_rangeCheckElimination);
+      RangeCheckElimination::eliminate(_hir);
+    }
+  }
+
+#ifndef PRODUCT
+  if (PrintCFGToFile) {
+    CFGPrinter::print_cfg(_hir, "After RangeCheckElimination", true, false);
+  }
+#endif
+
+  if (UseC1Optimizations) {
+    // loop invariant code motion reorders instructions and range
+    // check elimination adds new instructions so do null check
+    // elimination after.
+    NEEDS_CLEANUP
+    // optimization
+    PhaseTraceTime timeit(_t_optimize_null_checks);
+
+    _hir->eliminate_null_checks();
+  }
+
+  _hir->verify();
+
   // compute use counts after global value numbering
   _hir->compute_use_counts();
 
@@ -502,6 +541,7 @@
 , _next_id(0)
 , _next_block_id(0)
 , _code(buffer_blob)
+, _has_access_indexed(false)
 , _current_instruction(NULL)
 #ifndef PRODUCT
 , _last_instruction_printed(NULL)
@@ -567,7 +607,9 @@
   tty->print_cr("    Detailed C1 Timings");
   tty->print_cr("       Setup time:        %6.3f s (%4.1f%%)",    timers[_t_setup].seconds(),           (timers[_t_setup].seconds() / total) * 100.0);
   tty->print_cr("       Build IR:          %6.3f s (%4.1f%%)",    timers[_t_buildIR].seconds(),         (timers[_t_buildIR].seconds() / total) * 100.0);
-  tty->print_cr("         Optimize:           %6.3f s (%4.1f%%)", timers[_t_optimizeIR].seconds(),      (timers[_t_optimizeIR].seconds() / total) * 100.0);
+  float t_optimizeIR = timers[_t_optimize_blocks].seconds() + timers[_t_optimize_null_checks].seconds();
+  tty->print_cr("         Optimize:           %6.3f s (%4.1f%%)", t_optimizeIR,                         (t_optimizeIR / total) * 100.0);
+  tty->print_cr("         RCE:                %6.3f s (%4.1f%%)", timers[_t_rangeCheckElimination].seconds(),      (timers[_t_rangeCheckElimination].seconds() / total) * 100.0);
   tty->print_cr("       Emit LIR:          %6.3f s (%4.1f%%)",    timers[_t_emit_lir].seconds(),        (timers[_t_emit_lir].seconds() / total) * 100.0);
   tty->print_cr("         LIR Gen:          %6.3f s (%4.1f%%)",   timers[_t_lirGeneration].seconds(), (timers[_t_lirGeneration].seconds() / total) * 100.0);
   tty->print_cr("         Linear Scan:      %6.3f s (%4.1f%%)",   timers[_t_linearScan].seconds(),    (timers[_t_linearScan].seconds() / total) * 100.0);
--- a/src/share/vm/c1/c1_Compilation.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_Compilation.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -26,8 +26,10 @@
 #define SHARE_VM_C1_C1_COMPILATION_HPP
 
 #include "ci/ciEnv.hpp"
+#include "ci/ciMethodData.hpp"
 #include "code/exceptionHandlerTable.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/deoptimization.hpp"
 
 class CompilationResourceObj;
 class XHandlers;
@@ -85,6 +87,7 @@
   LinearScan*        _allocator;
   CodeOffsets        _offsets;
   CodeBuffer         _code;
+  bool               _has_access_indexed;
 
   // compilation helpers
   void initialize();
@@ -140,6 +143,7 @@
   C1_MacroAssembler* masm() const                { return _masm; }
   CodeOffsets* offsets()                         { return &_offsets; }
   Arena* arena()                                 { return _arena; }
+  bool has_access_indexed()                      { return _has_access_indexed; }
 
   // Instruction ids
   int get_next_id()                              { return _next_id++; }
@@ -154,6 +158,7 @@
   void set_has_fpu_code(bool f)                  { _has_fpu_code = f; }
   void set_has_unsafe_access(bool f)             { _has_unsafe_access = f; }
   void set_would_profile(bool f)                 { _would_profile = f; }
+  void set_has_access_indexed(bool f)            { _has_access_indexed = f; }
   // Add a set of exception handlers covering the given PC offset
   void add_exception_handlers_for_pco(int pco, XHandlers* exception_handlers);
   // Statistics gathering
@@ -233,6 +238,14 @@
     return env()->comp_level() == CompLevel_full_profile &&
       C1UpdateMethodData && C1ProfileCheckcasts;
   }
+
+  // will compilation make optimistic assumptions that might lead to
+  // deoptimization and that the runtime will account for?
+  bool is_optimistic() const                             {
+    return !TieredCompilation &&
+      (RangeCheckElimination || UseLoopInvariantCodeMotion) &&
+      method()->method_data()->trap_count(Deoptimization::Reason_none) == 0;
+  }
 };
 
 
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -947,7 +947,9 @@
 
 
 void GraphBuilder::load_indexed(BasicType type) {
-  ValueStack* state_before = copy_state_for_exception();
+  // In case of in block code motion in range check elimination
+  ValueStack* state_before = copy_state_indexed_access();
+  compilation()->set_has_access_indexed(true);
   Value index = ipop();
   Value array = apop();
   Value length = NULL;
@@ -961,7 +963,9 @@
 
 
 void GraphBuilder::store_indexed(BasicType type) {
-  ValueStack* state_before = copy_state_for_exception();
+  // In case of in block code motion in range check elimination
+  ValueStack* state_before = copy_state_indexed_access();
+  compilation()->set_has_access_indexed(true);
   Value value = pop(as_ValueType(type));
   Value index = ipop();
   Value array = apop();
@@ -1179,7 +1183,9 @@
   BlockBegin* tsux = block_at(stream()->get_dest());
   BlockBegin* fsux = block_at(stream()->next_bci());
   bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci();
-  Instruction *i = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb));
+  // In case of loop invariant code motion or predicate insertion
+  // before the body of a loop the state is needed
+  Instruction *i = append(new If(x, cond, false, y, tsux, fsux, (is_bb || compilation()->is_optimistic()) ? state_before : NULL, is_bb));
 
   assert(i->as_Goto() == NULL ||
          (i->as_Goto()->sux_at(0) == tsux  && i->as_Goto()->is_safepoint() == tsux->bci() < stream()->cur_bci()) ||
@@ -1294,7 +1300,9 @@
     BlockBegin* tsux = block_at(bci() + sw.dest_offset_at(0));
     BlockBegin* fsux = block_at(bci() + sw.default_offset());
     bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
-    ValueStack* state_before = is_bb ? copy_state_before() : NULL;
+    // In case of loop invariant code motion or predicate insertion
+    // before the body of a loop the state is needed
+    ValueStack* state_before = copy_state_if_bb(is_bb);
     append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
   } else {
     // collect successors
@@ -1308,7 +1316,9 @@
     // add default successor
     if (sw.default_offset() < 0) has_bb = true;
     sux->at_put(i, block_at(bci() + sw.default_offset()));
-    ValueStack* state_before = has_bb ? copy_state_before() : NULL;
+    // In case of loop invariant code motion or predicate insertion
+    // before the body of a loop the state is needed
+    ValueStack* state_before = copy_state_if_bb(has_bb);
     Instruction* res = append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb));
 #ifdef ASSERT
     if (res->as_Goto()) {
@@ -1336,7 +1346,9 @@
     BlockBegin* tsux = block_at(bci() + pair.offset());
     BlockBegin* fsux = block_at(bci() + sw.default_offset());
     bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
-    ValueStack* state_before = is_bb ? copy_state_before() : NULL;
+    // In case of loop invariant code motion or predicate insertion
+    // before the body of a loop the state is needed
+    ValueStack* state_before = copy_state_if_bb(is_bb);;
     append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
   } else {
     // collect successors & keys
@@ -1353,7 +1365,9 @@
     // add default successor
     if (sw.default_offset() < 0) has_bb = true;
     sux->at_put(i, block_at(bci() + sw.default_offset()));
-    ValueStack* state_before = has_bb ? copy_state_before() : NULL;
+    // In case of loop invariant code motion or predicate insertion
+    // before the body of a loop the state is needed
+    ValueStack* state_before = copy_state_if_bb(has_bb);
     Instruction* res = append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
 #ifdef ASSERT
     if (res->as_Goto()) {
--- a/src/share/vm/c1/c1_GraphBuilder.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_GraphBuilder.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -301,6 +301,8 @@
   ValueStack* copy_state_exhandling();
   ValueStack* copy_state_for_exception_with_bci(int bci);
   ValueStack* copy_state_for_exception();
+  ValueStack* copy_state_if_bb(bool is_bb) { return (is_bb || compilation()->is_optimistic()) ? copy_state_before() : NULL; }
+  ValueStack* copy_state_indexed_access() { return compilation()->is_optimistic() ? copy_state_before() : copy_state_for_exception(); }
 
   //
   // Inlining support
--- a/src/share/vm/c1/c1_IR.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_IR.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -182,13 +182,14 @@
 // Implementation of CodeEmitInfo
 
 // Stack must be NON-null
-CodeEmitInfo::CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers)
+CodeEmitInfo::CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, bool deoptimize_on_exception)
   : _scope(stack->scope())
   , _scope_debug_info(NULL)
   , _oop_map(NULL)
   , _stack(stack)
   , _exception_handlers(exception_handlers)
-  , _is_method_handle_invoke(false) {
+  , _is_method_handle_invoke(false)
+  , _deoptimize_on_exception(deoptimize_on_exception) {
   assert(_stack != NULL, "must be non null");
 }
 
@@ -199,7 +200,8 @@
   , _scope_debug_info(NULL)
   , _oop_map(NULL)
   , _stack(stack == NULL ? info->_stack : stack)
-  , _is_method_handle_invoke(info->_is_method_handle_invoke) {
+  , _is_method_handle_invoke(info->_is_method_handle_invoke)
+  , _deoptimize_on_exception(info->_deoptimize_on_exception) {
 
   // deep copy of exception handlers
   if (info->_exception_handlers != NULL) {
@@ -239,7 +241,7 @@
 }
 
 
-void IR::optimize() {
+void IR::optimize_blocks() {
   Optimizer opt(this);
   if (!compilation()->profile_branches()) {
     if (DoCEE) {
@@ -257,6 +259,10 @@
 #endif
     }
   }
+}
+
+void IR::eliminate_null_checks() {
+  Optimizer opt(this);
   if (EliminateNullChecks) {
     opt.eliminate_null_checks();
 #ifndef PRODUCT
@@ -429,6 +435,7 @@
   BlockList  _loop_end_blocks;     // list of all loop end blocks collected during count_edges
   BitMap2D   _loop_map;            // two-dimensional bit set: a bit is set if a block is contained in a loop
   BlockList  _work_list;           // temporary list (used in mark_loops and compute_order)
+  BlockList  _loop_headers;
 
   Compilation* _compilation;
 
@@ -594,6 +601,7 @@
     TRACE_LINEAR_SCAN(3, tty->print_cr("Block B%d is loop header of loop %d", cur->block_id(), _num_loops));
 
     cur->set_loop_index(_num_loops);
+    _loop_headers.append(cur);
     _num_loops++;
   }
 
@@ -656,6 +664,16 @@
       // -> this is not a natural loop, so ignore it
       TRACE_LINEAR_SCAN(2, tty->print_cr("Loop %d is non-natural, so it is ignored", i));
 
+      BlockBegin *loop_header = _loop_headers.at(i);
+      assert(loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Must be loop header");
+
+      for (int j = 0; j < loop_header->number_of_preds(); j++) {
+        BlockBegin *pred = loop_header->pred_at(j);
+        pred->clear(BlockBegin::linear_scan_loop_end_flag);
+      }
+
+      loop_header->clear(BlockBegin::linear_scan_loop_header_flag);
+
       for (int block_id = _max_block_id - 1; block_id >= 0; block_id--) {
         clear_block_in_loop(i, block_id);
       }
@@ -729,9 +747,20 @@
 
   } else if (!(cur->is_set(BlockBegin::linear_scan_loop_header_flag) && parent->is_set(BlockBegin::linear_scan_loop_end_flag))) {
     TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: computing dominator of B%d: common dominator of B%d and B%d is B%d", cur->block_id(), parent->block_id(), cur->dominator()->block_id(), common_dominator(cur->dominator(), parent)->block_id()));
-    assert(cur->number_of_preds() > 1, "");
+    // Does not hold for exception blocks
+    assert(cur->number_of_preds() > 1 || cur->is_set(BlockBegin::exception_entry_flag), "");
     cur->set_dominator(common_dominator(cur->dominator(), parent));
   }
+
+  // Additional edge to xhandler of all our successors
+  // range check elimination needs that the state at the end of a
+  // block be valid in every block it dominates so cur must dominate
+  // the exception handlers of its successors.
+  int num_cur_xhandler = cur->number_of_exception_handlers();
+  for (int j = 0; j < num_cur_xhandler; j++) {
+    BlockBegin* xhandler = cur->exception_handler_at(j);
+    compute_dominator(xhandler, parent);
+  }
 }
 
 
@@ -898,7 +927,6 @@
     num_sux = cur->number_of_exception_handlers();
     for (i = 0; i < num_sux; i++) {
       BlockBegin* sux = cur->exception_handler_at(i);
-      compute_dominator(sux, cur);
       if (ready_for_processing(sux)) {
         sort_into_work_list(sux);
       }
@@ -918,8 +946,23 @@
 
     BlockBegin* dominator = block->pred_at(0);
     int num_preds = block->number_of_preds();
-    for (int i = 1; i < num_preds; i++) {
-      dominator = common_dominator(dominator, block->pred_at(i));
+
+    TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: Processing B%d", block->block_id()));
+
+    for (int j = 0; j < num_preds; j++) {
+
+      BlockBegin *pred = block->pred_at(j);
+      TRACE_LINEAR_SCAN(4, tty->print_cr("   DOM: Subrocessing B%d", pred->block_id()));
+
+      if (block->is_set(BlockBegin::exception_entry_flag)) {
+        dominator = common_dominator(dominator, pred);
+        int num_pred_preds = pred->number_of_preds();
+        for (int k = 0; k < num_pred_preds; k++) {
+          dominator = common_dominator(dominator, pred->pred_at(k));
+        }
+      } else {
+        dominator = common_dominator(dominator, pred);
+      }
     }
 
     if (dominator != block->dominator()) {
@@ -946,6 +989,21 @@
 
   // check that dominators are correct
   assert(!compute_dominators_iter(), "fix point not reached");
+
+  // Add Blocks to dominates-Array
+  int num_blocks = _linear_scan_order->length();
+  for (int i = 0; i < num_blocks; i++) {
+    BlockBegin* block = _linear_scan_order->at(i);
+
+    BlockBegin *dom = block->dominator();
+    if (dom) {
+      assert(dom->dominator_depth() != -1, "Dominator must have been visited before");
+      dom->dominates()->append(block);
+      block->set_dominator_depth(dom->dominator_depth() + 1);
+    } else {
+      block->set_dominator_depth(0);
+    }
+  }
 }
 
 
@@ -1032,7 +1090,7 @@
       BlockBegin* sux = cur->sux_at(j);
 
       assert(sux->linear_scan_number() >= 0 && sux->linear_scan_number() == _linear_scan_order->index_of(sux), "incorrect linear_scan_number");
-      if (!cur->is_set(BlockBegin::linear_scan_loop_end_flag)) {
+      if (!sux->is_set(BlockBegin::backward_branch_target_flag)) {
         assert(cur->linear_scan_number() < sux->linear_scan_number(), "invalid order");
       }
       if (cur->loop_depth() == sux->loop_depth()) {
@@ -1044,7 +1102,7 @@
       BlockBegin* pred = cur->pred_at(j);
 
       assert(pred->linear_scan_number() >= 0 && pred->linear_scan_number() == _linear_scan_order->index_of(pred), "incorrect linear_scan_number");
-      if (!cur->is_set(BlockBegin::linear_scan_loop_header_flag)) {
+      if (!cur->is_set(BlockBegin::backward_branch_target_flag)) {
         assert(cur->linear_scan_number() > pred->linear_scan_number(), "invalid order");
       }
       if (cur->loop_depth() == pred->loop_depth()) {
@@ -1060,7 +1118,8 @@
     } else {
       assert(cur->dominator() != NULL, "all but first block must have dominator");
     }
-    assert(cur->number_of_preds() != 1 || cur->dominator() == cur->pred_at(0), "Single predecessor must also be dominator");
+    // Assertion does not hold for exception handlers
+    assert(cur->number_of_preds() != 1 || cur->dominator() == cur->pred_at(0) || cur->is_set(BlockBegin::exception_entry_flag), "Single predecessor must also be dominator");
   }
 
   // check that all loops are continuous
@@ -1249,9 +1308,22 @@
   }
 };
 
+class VerifyBlockBeginField : public BlockClosure {
+
+public:
+
+  virtual void block_do(BlockBegin *block) {
+    for ( Instruction *cur = block; cur != NULL; cur = cur->next()) {
+      assert(cur->block() == block, "Block begin is not correct");
+    }
+  }
+};
+
 void IR::verify() {
 #ifdef ASSERT
   PredecessorValidator pv(this);
+  VerifyBlockBeginField verifier;
+  this->iterate_postorder(&verifier);
 #endif
 }
 
--- a/src/share/vm/c1/c1_IR.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_IR.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -254,6 +254,7 @@
   OopMap*           _oop_map;
   ValueStack*       _stack;                      // used by deoptimization (contains also monitors
   bool              _is_method_handle_invoke;    // true if the associated call site is a MethodHandle call site.
+  bool              _deoptimize_on_exception;
 
   FrameMap*     frame_map() const                { return scope()->compilation()->frame_map(); }
   Compilation*  compilation() const              { return scope()->compilation(); }
@@ -261,7 +262,7 @@
  public:
 
   // use scope from ValueStack
-  CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers);
+  CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, bool deoptimize_on_exception = false);
 
   // make a copy
   CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack = NULL);
@@ -272,6 +273,7 @@
   IRScope* scope() const                         { return _scope; }
   XHandlers* exception_handlers() const          { return _exception_handlers; }
   ValueStack* stack() const                      { return _stack; }
+  bool deoptimize_on_exception() const           { return _deoptimize_on_exception; }
 
   void add_register_oop(LIR_Opr opr);
   void record_debug_info(DebugInformationRecorder* recorder, int pc_offset);
@@ -309,7 +311,8 @@
   int              max_stack() const             { return top_scope()->max_stack(); } // expensive
 
   // ir manipulation
-  void optimize();
+  void optimize_blocks();
+  void eliminate_null_checks();
   void compute_predecessors();
   void split_critical_edges();
   void compute_code();
--- a/src/share/vm/c1/c1_Instruction.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_Instruction.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -34,6 +34,15 @@
 // Implementation of Instruction
 
 
+int Instruction::dominator_depth() {
+  int result = -1;
+  if (block()) {
+    result = block()->dominator_depth();
+  }
+  assert(result != -1 || this->as_Local(), "Only locals have dominator depth -1");
+  return result;
+}
+
 Instruction::Condition Instruction::mirror(Condition cond) {
   switch (cond) {
     case eql: return eql;
@@ -42,6 +51,8 @@
     case leq: return geq;
     case gtr: return lss;
     case geq: return leq;
+    case aeq: return beq;
+    case beq: return aeq;
   }
   ShouldNotReachHere();
   return eql;
@@ -56,6 +67,8 @@
     case leq: return gtr;
     case gtr: return leq;
     case geq: return lss;
+    case aeq: assert(false, "Above equal cannot be negated");
+    case beq: assert(false, "Below equal cannot be negated");
   }
   ShouldNotReachHere();
   return eql;
@@ -70,10 +83,10 @@
   }
 }
 
-
-Instruction* Instruction::prev(BlockBegin* block) {
+// Prev without need to have BlockBegin
+Instruction* Instruction::prev() {
   Instruction* p = NULL;
-  Instruction* q = block;
+  Instruction* q = block();
   while (q != this) {
     assert(q != NULL, "this is not in the block's instruction list");
     p = q; q = q->next();
@@ -122,15 +135,24 @@
 
 // perform constant and interval tests on index value
 bool AccessIndexed::compute_needs_range_check() {
-  Constant* clength = length()->as_Constant();
-  Constant* cindex = index()->as_Constant();
-  if (clength && cindex) {
-    IntConstant* l = clength->type()->as_IntConstant();
-    IntConstant* i = cindex->type()->as_IntConstant();
-    if (l && i && i->value() < l->value() && i->value() >= 0) {
-      return false;
+
+  if (length()) {
+
+    Constant* clength = length()->as_Constant();
+    Constant* cindex = index()->as_Constant();
+    if (clength && cindex) {
+      IntConstant* l = clength->type()->as_IntConstant();
+      IntConstant* i = cindex->type()->as_IntConstant();
+      if (l && i && i->value() < l->value() && i->value() >= 0) {
+        return false;
+      }
     }
   }
+
+  if (!this->check_flag(NeedsRangeCheckFlag)) {
+    return false;
+  }
+
   return true;
 }
 
@@ -631,19 +653,25 @@
 // of the inserted block, without recomputing the values of the other blocks
 // in the CFG. Therefore the value of "depth_first_number" in BlockBegin becomes meaningless.
 BlockBegin* BlockBegin::insert_block_between(BlockBegin* sux) {
-  BlockBegin* new_sux = new BlockBegin(end()->state()->bci());
+  int bci = sux->bci();
+  // critical edge splitting may introduce a goto after a if and array
+  // bound check elimination may insert a predicate between the if and
+  // goto. The bci of the goto can't be the one of the if otherwise
+  // the state and bci are inconsistent and a deoptimization triggered
+  // by the predicate would lead to incorrect execution/a crash.
+  BlockBegin* new_sux = new BlockBegin(bci);
 
   // mark this block (special treatment when block order is computed)
   new_sux->set(critical_edge_split_flag);
 
   // This goto is not a safepoint.
   Goto* e = new Goto(sux, false);
-  new_sux->set_next(e, end()->state()->bci());
+  new_sux->set_next(e, bci);
   new_sux->set_end(e);
   // setup states
   ValueStack* s = end()->state();
-  new_sux->set_state(s->copy());
-  e->set_state(s->copy());
+  new_sux->set_state(s->copy(s->kind(), bci));
+  e->set_state(s->copy(s->kind(), bci));
   assert(new_sux->state()->locals_size() == s->locals_size(), "local size mismatch!");
   assert(new_sux->state()->stack_size() == s->stack_size(), "stack size mismatch!");
   assert(new_sux->state()->locks_size() == s->locks_size(), "locks size mismatch!");
@@ -960,15 +988,14 @@
   BlockList* sux = NULL;
   if (begin != NULL) {
     sux = begin->successors();
-  } else if (_begin != NULL) {
+  } else if (this->begin() != NULL) {
     // copy our sux list
-    BlockList* sux = new BlockList(_begin->number_of_sux());
-    for (int i = 0; i < _begin->number_of_sux(); i++) {
-      sux->append(_begin->sux_at(i));
+    BlockList* sux = new BlockList(this->begin()->number_of_sux());
+    for (int i = 0; i < this->begin()->number_of_sux(); i++) {
+      sux->append(this->begin()->sux_at(i));
     }
   }
   _sux = sux;
-  _begin = begin;
 }
 
 
@@ -1008,7 +1035,38 @@
   }
 }
 
+#ifdef ASSERT
+// Constructor of Assert
+Assert::Assert(Value x, Condition cond, bool unordered_is_true, Value y) : Instruction(illegalType)
+  , _x(x)
+  , _cond(cond)
+  , _y(y)
+{
+  set_flag(UnorderedIsTrueFlag, unordered_is_true);
+  assert(x->type()->tag() == y->type()->tag(), "types must match");
+  pin();
 
+  stringStream strStream;
+  Compilation::current()->method()->print_name(&strStream);
+
+  stringStream strStream1;
+  InstructionPrinter ip1(1, &strStream1);
+  ip1.print_instr(x);
+
+  stringStream strStream2;
+  InstructionPrinter ip2(1, &strStream2);
+  ip2.print_instr(y);
+
+  stringStream ss;
+  ss.print("Assertion %s %s %s in method %s", strStream1.as_string(), ip2.cond_name(cond), strStream2.as_string(), strStream.as_string());
+
+  _message = ss.as_string();
+}
+#endif
+
+void RangeCheckPredicate::check_state() {
+  assert(state()->kind() != ValueStack::EmptyExceptionState && state()->kind() != ValueStack::ExceptionState, "will deopt with empty state");
+}
 
 void ProfileInvoke::state_values_do(ValueVisitor* f) {
   if (state() != NULL) state()->values_do(f);
--- a/src/share/vm/c1/c1_Instruction.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_Instruction.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -110,6 +110,8 @@
 class   ProfileInvoke;
 class   RuntimeCall;
 class   MemBar;
+class   RangeCheckPredicate;
+class   Assert;
 
 // A Value is a reference to the instruction creating the value
 typedef Instruction* Value;
@@ -210,6 +212,10 @@
   virtual void do_ProfileInvoke  (ProfileInvoke*   x) = 0;
   virtual void do_RuntimeCall    (RuntimeCall*     x) = 0;
   virtual void do_MemBar         (MemBar*          x) = 0;
+  virtual void do_RangeCheckPredicate(RangeCheckPredicate* x) = 0;
+#ifdef ASSERT
+  virtual void do_Assert         (Assert*          x) = 0;
+#endif
 };
 
 
@@ -306,8 +312,9 @@
 
   void update_exception_state(ValueStack* state);
 
- //protected:
- public:
+ protected:
+  BlockBegin*  _block;                           // Block that contains this instruction
+
   void set_type(ValueType* type) {
     assert(type != NULL, "type must exist");
     _type = type;
@@ -342,6 +349,9 @@
     ThrowIncompatibleClassChangeErrorFlag,
     ProfileMDOFlag,
     IsLinkedInBlockFlag,
+    NeedsRangeCheckFlag,
+    InWorkListFlag,
+    DeoptimizeOnException,
     InstructionLastFlag
   };
 
@@ -351,7 +361,7 @@
 
   // 'globally' used condition values
   enum Condition {
-    eql, neq, lss, leq, gtr, geq
+    eql, neq, lss, leq, gtr, geq, aeq, beq
   };
 
   // Instructions may be pinned for many reasons and under certain conditions
@@ -381,6 +391,7 @@
   , _pin_state(0)
   , _type(type)
   , _next(NULL)
+  , _block(NULL)
   , _subst(NULL)
   , _flags(0)
   , _operand(LIR_OprFact::illegalOpr)
@@ -399,11 +410,13 @@
   int printable_bci() const                      { assert(has_printable_bci(), "_printable_bci should have been set"); return _printable_bci; }
   void set_printable_bci(int bci)                { _printable_bci = bci; }
 #endif
+  int dominator_depth();
   int use_count() const                          { return _use_count; }
   int pin_state() const                          { return _pin_state; }
   bool is_pinned() const                         { return _pin_state != 0 || PinAllInstructions; }
   ValueType* type() const                        { return _type; }
-  Instruction* prev(BlockBegin* block);          // use carefully, expensive operation
+  BlockBegin *block() const                      { return _block; }
+  Instruction* prev();                           // use carefully, expensive operation
   Instruction* next() const                      { return _next; }
   bool has_subst() const                         { return _subst != NULL; }
   Instruction* subst()                           { return _subst == NULL ? this : _subst->subst(); }
@@ -432,6 +445,9 @@
     assert(as_BlockEnd() == NULL, "BlockEnd instructions must have no next");
     assert(next->can_be_linked(), "shouldn't link these instructions into list");
 
+    BlockBegin *block = this->block();
+    next->_block = block;
+
     next->set_flag(Instruction::IsLinkedInBlockFlag, true);
     _next = next;
     return next;
@@ -444,6 +460,29 @@
     return set_next(next);
   }
 
+  // when blocks are merged
+  void fixup_block_pointers() {
+    Instruction *cur = next()->next(); // next()'s block is set in set_next
+    while (cur && cur->_block != block()) {
+      cur->_block = block();
+      cur = cur->next();
+    }
+  }
+
+  Instruction *insert_after(Instruction *i) {
+    Instruction* n = _next;
+    set_next(i);
+    i->set_next(n);
+    return _next;
+  }
+
+  Instruction *insert_after_same_bci(Instruction *i) {
+#ifndef PRODUCT
+    i->set_printable_bci(printable_bci());
+#endif
+    return insert_after(i);
+  }
+
   void set_subst(Instruction* subst)             {
     assert(subst == NULL ||
            type()->base() == subst->type()->base() ||
@@ -452,6 +491,7 @@
   }
   void set_exception_handlers(XHandlers *xhandlers) { _exception_handlers = xhandlers; }
   void set_exception_state(ValueStack* s)        { check_state(s); _exception_state = s; }
+  void set_state_before(ValueStack* s)           { check_state(s); _state_before = s; }
 
   // machine-specifics
   void set_operand(LIR_Opr operand)              { assert(operand != LIR_OprFact::illegalOpr, "operand must exist"); _operand = operand; }
@@ -509,6 +549,11 @@
   virtual ExceptionObject*  as_ExceptionObject() { return NULL; }
   virtual UnsafeOp*         as_UnsafeOp()        { return NULL; }
   virtual ProfileInvoke*    as_ProfileInvoke()   { return NULL; }
+  virtual RangeCheckPredicate* as_RangeCheckPredicate() { return NULL; }
+
+#ifdef ASSERT
+  virtual Assert*           as_Assert()          { return NULL; }
+#endif
 
   virtual void visit(InstructionVisitor* v)      = 0;
 
@@ -570,7 +615,6 @@
 
 LEAF(Phi, Instruction)
  private:
-  BlockBegin* _block;    // the block to which the phi function belongs
   int         _pf_flags; // the flags of the phi function
   int         _index;    // to value on operand stack (index < 0) or to local
  public:
@@ -578,9 +622,9 @@
   Phi(ValueType* type, BlockBegin* b, int index)
   : Instruction(type->base())
   , _pf_flags(0)
-  , _block(b)
   , _index(index)
   {
+    _block = b;
     NOT_PRODUCT(set_printable_bci(Value(b)->printable_bci()));
     if (type->is_illegal()) {
       make_illegal();
@@ -603,8 +647,6 @@
   Value operand_at(int i) const;
   int   operand_count() const;
 
-  BlockBegin* block() const       { return _block; }
-
   void   set(Flag f)              { _pf_flags |=  f; }
   void   clear(Flag f)            { _pf_flags &= ~f; }
   bool   is_set(Flag f) const     { return (_pf_flags & f) != 0; }
@@ -670,6 +712,7 @@
     pin();
   }
 
+  // generic
   virtual bool can_trap() const                  { return state_before() != NULL; }
   virtual void input_values_do(ValueVisitor* f)   { /* no values */ }
 
@@ -852,6 +895,7 @@
   , _length(length)
   , _elt_type(elt_type)
   {
+    set_flag(Instruction::NeedsRangeCheckFlag, true);
     ASSERT_VALUES
   }
 
@@ -860,6 +904,7 @@
   Value length() const                           { return _length; }
   BasicType elt_type() const                     { return _elt_type; }
 
+  void clear_length()                            { _length = NULL; }
   // perform elimination of range checks involving constants
   bool compute_needs_range_check();
 
@@ -1524,6 +1569,7 @@
   int        _bci;                               // start-bci of block
   int        _depth_first_number;                // number of this block in a depth-first ordering
   int        _linear_scan_number;                // number of this block in linear-scan ordering
+  int        _dominator_depth;
   int        _loop_depth;                        // the loop nesting level of this block
   int        _loop_index;                        // number of the innermost loop of this block
   int        _flags;                             // the flags associated with this block
@@ -1535,6 +1581,7 @@
   // SSA specific fields: (factor out later)
   BlockList   _successors;                       // the successors of this block
   BlockList   _predecessors;                     // the predecessors of this block
+  BlockList   _dominates;                        // list of blocks that are dominated by this block
   BlockBegin* _dominator;                        // the dominator of this block
   // SSA specific ends
   BlockEnd*  _end;                               // the last instruction of this block
@@ -1583,10 +1630,12 @@
   , _linear_scan_number(-1)
   , _loop_depth(0)
   , _flags(0)
+  , _dominator_depth(-1)
   , _dominator(NULL)
   , _end(NULL)
   , _predecessors(2)
   , _successors(2)
+  , _dominates(2)
   , _exception_handlers(1)
   , _exception_states(NULL)
   , _exception_handler_pco(-1)
@@ -1603,6 +1652,7 @@
   , _total_preds(0)
   , _stores_to_locals()
   {
+    _block = this;
 #ifndef PRODUCT
     set_printable_bci(bci);
 #endif
@@ -1612,8 +1662,10 @@
   int block_id() const                           { return _block_id; }
   int bci() const                                { return _bci; }
   BlockList* successors()                        { return &_successors; }
+  BlockList* dominates()                         { return &_dominates; }
   BlockBegin* dominator() const                  { return _dominator; }
   int loop_depth() const                         { return _loop_depth; }
+  int dominator_depth() const                    { return _dominator_depth; }
   int depth_first_number() const                 { return _depth_first_number; }
   int linear_scan_number() const                 { return _linear_scan_number; }
   BlockEnd* end() const                          { return _end; }
@@ -1634,6 +1686,7 @@
   // manipulation
   void set_dominator(BlockBegin* dom)            { _dominator = dom; }
   void set_loop_depth(int d)                     { _loop_depth = d; }
+  void set_dominator_depth(int d)                { _dominator_depth = d; }
   void set_depth_first_number(int dfn)           { _depth_first_number = dfn; }
   void set_linear_scan_number(int lsn)           { _linear_scan_number = lsn; }
   void set_end(BlockEnd* end);
@@ -1695,7 +1748,8 @@
     parser_loop_header_flag       = 1 << 7,  // set by parser to identify blocks where phi functions can not be created on demand
     critical_edge_split_flag      = 1 << 8, // set for all blocks that are introduced when critical edges are split
     linear_scan_loop_header_flag  = 1 << 9, // set during loop-detection for LinearScan
-    linear_scan_loop_end_flag     = 1 << 10  // set during loop-detection for LinearScan
+    linear_scan_loop_end_flag     = 1 << 10, // set during loop-detection for LinearScan
+    donot_eliminate_range_checks  = 1 << 11  // Should be try to eliminate range checks in this block
   };
 
   void set(Flag f)                               { _flags |= f; }
@@ -1728,7 +1782,6 @@
 
 BASE(BlockEnd, StateSplit)
  private:
-  BlockBegin* _begin;
   BlockList*  _sux;
 
  protected:
@@ -1746,7 +1799,6 @@
   // creation
   BlockEnd(ValueType* type, ValueStack* state_before, bool is_safepoint)
   : StateSplit(type, state_before)
-  , _begin(NULL)
   , _sux(NULL)
   {
     set_flag(IsSafepointFlag, is_safepoint);
@@ -1754,7 +1806,8 @@
 
   // accessors
   bool is_safepoint() const                      { return check_flag(IsSafepointFlag); }
-  BlockBegin* begin() const                      { return _begin; }
+  // For compatibility with old code, for new code use block()
+  BlockBegin* begin() const                      { return _block; }
 
   // manipulation
   void set_begin(BlockBegin* begin);
@@ -1811,6 +1864,74 @@
   void set_direction(Direction d)                { _direction = d; }
 };
 
+#ifdef ASSERT
+LEAF(Assert, Instruction)
+  private:
+  Value       _x;
+  Condition   _cond;
+  Value       _y;
+  char        *_message;
+
+ public:
+  // creation
+  // unordered_is_true is valid for float/double compares only
+   Assert(Value x, Condition cond, bool unordered_is_true, Value y);
+
+  // accessors
+  Value x() const                                { return _x; }
+  Condition cond() const                         { return _cond; }
+  bool unordered_is_true() const                 { return check_flag(UnorderedIsTrueFlag); }
+  Value y() const                                { return _y; }
+  const char *message() const                    { return _message; }
+
+  // generic
+  virtual void input_values_do(ValueVisitor* f)  { f->visit(&_x); f->visit(&_y); }
+};
+#endif
+
+LEAF(RangeCheckPredicate, StateSplit)
+ private:
+  Value       _x;
+  Condition   _cond;
+  Value       _y;
+
+  void check_state();
+
+ public:
+  // creation
+  // unordered_is_true is valid for float/double compares only
+   RangeCheckPredicate(Value x, Condition cond, bool unordered_is_true, Value y, ValueStack* state) : StateSplit(illegalType)
+  , _x(x)
+  , _cond(cond)
+  , _y(y)
+  {
+    ASSERT_VALUES
+    set_flag(UnorderedIsTrueFlag, unordered_is_true);
+    assert(x->type()->tag() == y->type()->tag(), "types must match");
+    this->set_state(state);
+    check_state();
+  }
+
+  // Always deoptimize
+  RangeCheckPredicate(ValueStack* state) : StateSplit(illegalType)
+  {
+    this->set_state(state);
+    _x = _y = NULL;
+    check_state();
+  }
+
+  // accessors
+  Value x() const                                { return _x; }
+  Condition cond() const                         { return _cond; }
+  bool unordered_is_true() const                 { return check_flag(UnorderedIsTrueFlag); }
+  Value y() const                                { return _y; }
+
+  void always_fail()                             { _x = _y = NULL; }
+
+  // generic
+  virtual void input_values_do(ValueVisitor* f)  { StateSplit::input_values_do(f); f->visit(&_x); f->visit(&_y); }
+  HASHING3(RangeCheckPredicate, true, x()->subst(), y()->subst(), cond())
+};
 
 LEAF(If, BlockEnd)
  private:
--- a/src/share/vm/c1/c1_InstructionPrinter.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_InstructionPrinter.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -57,6 +57,8 @@
     case If::leq: return "<=";
     case If::gtr: return ">";
     case If::geq: return ">=";
+    case If::aeq: return "|>=|";
+    case If::beq: return "|<=|";
   }
   ShouldNotReachHere();
   return NULL;
@@ -181,6 +183,11 @@
   output()->put('[');
   print_value(indexed->index());
   output()->put(']');
+  if (indexed->length() != NULL) {
+    output()->put('(');
+    print_value(indexed->length());
+    output()->put(')');
+  }
 }
 
 
@@ -373,6 +380,7 @@
 void InstructionPrinter::do_LoadField(LoadField* x) {
   print_field(x);
   output()->print(" (%c)", type2char(x->field()->type()->basic_type()));
+  output()->print(" %s", x->field()->name()->as_utf8());
 }
 
 
@@ -381,6 +389,7 @@
   output()->print(" := ");
   print_value(x->value());
   output()->print(" (%c)", type2char(x->field()->type()->basic_type()));
+  output()->print(" %s", x->field()->name()->as_utf8());
 }
 
 
@@ -393,6 +402,9 @@
 void InstructionPrinter::do_LoadIndexed(LoadIndexed* x) {
   print_indexed(x);
   output()->print(" (%c)", type2char(x->elt_type()));
+  if (x->check_flag(Instruction::NeedsRangeCheckFlag)) {
+    output()->print(" [rc]");
+  }
 }
 
 
@@ -401,6 +413,9 @@
   output()->print(" := ");
   print_value(x->value());
   output()->print(" (%c)", type2char(x->elt_type()));
+  if (x->check_flag(Instruction::NeedsRangeCheckFlag)) {
+    output()->print(" [rc]");
+  }
 }
 
 void InstructionPrinter::do_NegateOp(NegateOp* x) {
@@ -843,6 +858,25 @@
   output()->put(')');
 }
 
+void InstructionPrinter::do_RangeCheckPredicate(RangeCheckPredicate* x) {
+
+  if (x->x() != NULL && x->y() != NULL) {
+    output()->print("if ");
+    print_value(x->x());
+    output()->print(" %s ", cond_name(x->cond()));
+    print_value(x->y());
+    output()->print(" then deoptimize!");
+  } else {
+    output()->print("always deoptimize!");
+  }
+}
+
+void InstructionPrinter::do_Assert(Assert* x) {
+  output()->print("assert ");
+  print_value(x->x());
+  output()->print(" %s ", cond_name(x->cond()));
+  print_value(x->y());
+}
 
 void InstructionPrinter::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {
   print_unsafe_object_op(x, "UnsafePrefetchWrite");
--- a/src/share/vm/c1/c1_InstructionPrinter.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_InstructionPrinter.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -135,6 +135,8 @@
   virtual void do_ProfileInvoke  (ProfileInvoke*   x);
   virtual void do_RuntimeCall    (RuntimeCall*     x);
   virtual void do_MemBar         (MemBar*          x);
+  virtual void do_RangeCheckPredicate(RangeCheckPredicate* x);
+  virtual void do_Assert         (Assert*          x);
 };
 #endif // PRODUCT
 
--- a/src/share/vm/c1/c1_LIR.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_LIR.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -633,6 +633,7 @@
     case lir_ushr:
     case lir_xadd:
     case lir_xchg:
+    case lir_assert:
     {
       assert(op->as_Op2() != NULL, "must be");
       LIR_Op2* op2 = (LIR_Op2*)op;
@@ -1112,6 +1113,11 @@
   }
 }
 
+#ifdef ASSERT
+void LIR_OpAssert::emit_code(LIR_Assembler* masm) {
+  masm->emit_assert(this);
+}
+#endif
 
 void LIR_OpDelay::emit_code(LIR_Assembler* masm) {
   masm->emit_delay(this);
@@ -1771,6 +1777,8 @@
      case lir_cas_int:               s = "cas_int";      break;
      // LIR_OpProfileCall
      case lir_profile_call:          s = "profile_call";  break;
+     // LIR_OpAssert
+     case lir_assert:                s = "assert";        break;
      case lir_none:                  ShouldNotReachHere();break;
     default:                         s = "illegal_op";    break;
   }
@@ -2017,6 +2025,13 @@
   out->print("[lbl:0x%x]", stub()->entry());
 }
 
+void LIR_OpAssert::print_instr(outputStream* out) const {
+  print_condition(out, condition()); out->print(" ");
+  in_opr1()->print(out);             out->print(" ");
+  in_opr2()->print(out);             out->print(", \"");
+  out->print(msg());                 out->print("\"");
+}
+
 
 void LIR_OpDelay::print_instr(outputStream* out) const {
   _op->print_on(out);
--- a/src/share/vm/c1/c1_LIR.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_LIR.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -881,6 +881,7 @@
 class    LIR_OpTypeCheck;
 class    LIR_OpCompareAndSwap;
 class    LIR_OpProfileCall;
+class    LIR_OpAssert;
 
 
 // LIR operation codes
@@ -1000,6 +1001,9 @@
   , begin_opMDOProfile
     , lir_profile_call
   , end_opMDOProfile
+  , begin_opAssert
+    , lir_assert
+  , end_opAssert
 };
 
 
@@ -1135,6 +1139,7 @@
   virtual LIR_OpTypeCheck* as_OpTypeCheck() { return NULL; }
   virtual LIR_OpCompareAndSwap* as_OpCompareAndSwap() { return NULL; }
   virtual LIR_OpProfileCall* as_OpProfileCall() { return NULL; }
+  virtual LIR_OpAssert* as_OpAssert() { return NULL; }
 
   virtual void verify() const {}
 };
@@ -1623,7 +1628,7 @@
     , _tmp3(LIR_OprFact::illegalOpr)
     , _tmp4(LIR_OprFact::illegalOpr)
     , _tmp5(LIR_OprFact::illegalOpr) {
-    assert(code == lir_cmp, "code check");
+    assert(code == lir_cmp || code == lir_assert, "code check");
   }
 
   LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type)
@@ -1683,7 +1688,7 @@
   LIR_Opr tmp4_opr() const                       { return _tmp4; }
   LIR_Opr tmp5_opr() const                       { return _tmp5; }
   LIR_Condition condition() const  {
-    assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove"); return _condition;
+    assert(code() == lir_cmp || code() == lir_cmove || code() == lir_assert, "only valid for cmp and cmove and assert"); return _condition;
   }
   void set_condition(LIR_Condition condition) {
     assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove");  _condition = condition;
@@ -1823,6 +1828,30 @@
   CodeEmitInfo* call_info() const { return info(); }
 };
 
+#ifdef ASSERT
+// LIR_OpAssert
+class LIR_OpAssert : public LIR_Op2 {
+ friend class LIR_OpVisitState;
+
+ private:
+  const char* _msg;
+  bool        _halt;
+
+ public:
+  LIR_OpAssert(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, const char* msg, bool halt)
+    : LIR_Op2(lir_assert, condition, opr1, opr2)
+    , _halt(halt)
+    , _msg(msg) {
+  }
+
+  const char* msg() const                        { return _msg; }
+  bool        halt() const                       { return _halt; }
+
+  virtual void emit_code(LIR_Assembler* masm);
+  virtual LIR_OpAssert* as_OpAssert()            { return this; }
+  virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
+};
+#endif
 
 // LIR_OpCompareAndSwap
 class LIR_OpCompareAndSwap : public LIR_Op {
@@ -2196,6 +2225,9 @@
 
   void xadd(LIR_Opr src, LIR_Opr add, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xadd, src, add, res, tmp)); }
   void xchg(LIR_Opr src, LIR_Opr set, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xchg, src, set, res, tmp)); }
+#ifdef ASSERT
+  void lir_assert(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, const char* msg, bool halt) { append(new LIR_OpAssert(condition, opr1, opr2, msg, halt)); }
+#endif
 };
 
 void print_LIR(BlockList* blocks);
--- a/src/share/vm/c1/c1_LIRAssembler.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_LIRAssembler.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -210,6 +210,9 @@
   void arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack);
   void arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info);
   void intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr unused, LIR_Opr dest, LIR_Op* op);
+#ifdef ASSERT
+  void emit_assert(LIR_OpAssert* op);
+#endif
 
   void logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest);
 
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -403,6 +403,10 @@
 CodeEmitInfo* LIRGenerator::state_for(Instruction* x, ValueStack* state, bool ignore_xhandler) {
   assert(state != NULL, "state must be defined");
 
+#ifndef PRODUCT
+  state->verify();
+#endif
+
   ValueStack* s = state;
   for_each_state(s) {
     if (s->kind() == ValueStack::EmptyExceptionState) {
@@ -453,7 +457,7 @@
     }
   }
 
-  return new CodeEmitInfo(state, ignore_xhandler ? NULL : x->exception_handlers());
+  return new CodeEmitInfo(state, ignore_xhandler ? NULL : x->exception_handlers(), x->check_flag(Instruction::DeoptimizeOnException));
 }
 
 
@@ -707,25 +711,6 @@
   }
 }
 
-static Value maxvalue(IfOp* ifop) {
-  switch (ifop->cond()) {
-    case If::eql: return NULL;
-    case If::neq: return NULL;
-    case If::lss: // x <  y ? x : y
-    case If::leq: // x <= y ? x : y
-      if (ifop->x() == ifop->tval() &&
-          ifop->y() == ifop->fval()) return ifop->y();
-      return NULL;
-
-    case If::gtr: // x >  y ? y : x
-    case If::geq: // x >= y ? y : x
-      if (ifop->x() == ifop->tval() &&
-          ifop->y() == ifop->fval()) return ifop->y();
-      return NULL;
-
-  }
-}
-
 static ciType* phi_declared_type(Phi* phi) {
   ciType* t = phi->operand_at(0)->declared_type();
   if (t == NULL) {
@@ -1792,11 +1777,18 @@
   }
 #endif
 
+  bool stress_deopt = StressLoopInvariantCodeMotion && info && info->deoptimize_on_exception();
   if (x->needs_null_check() &&
       (needs_patching ||
-       MacroAssembler::needs_explicit_null_check(x->offset()))) {
+       MacroAssembler::needs_explicit_null_check(x->offset()) ||
+       stress_deopt)) {
+    LIR_Opr obj = object.result();
+    if (stress_deopt) {
+      obj = new_register(T_OBJECT);
+      __ move(LIR_OprFact::oopConst(NULL), obj);
+    }
     // emit an explicit null check because the offset is too large
-    __ null_check(object.result(), new CodeEmitInfo(info));
+    __ null_check(obj, new CodeEmitInfo(info));
   }
 
   LIR_Opr reg = rlock_result(x, field_type);
@@ -1873,6 +1865,11 @@
     } else {
       info = state_for(nc);
     }
+    if (StressLoopInvariantCodeMotion && info->deoptimize_on_exception()) {
+      LIR_Opr obj = new_register(T_OBJECT);
+      __ move(LIR_OprFact::oopConst(NULL), obj);
+      __ null_check(obj, new CodeEmitInfo(info));
+    }
   }
   __ load(new LIR_Address(array.result(), arrayOopDesc::length_offset_in_bytes(), T_INT), reg, info, lir_patch_none);
 }
@@ -1883,14 +1880,11 @@
   LIRItem array(x->array(), this);
   LIRItem index(x->index(), this);
   LIRItem length(this);
-  bool needs_range_check = true;
-
-  if (use_length) {
-    needs_range_check = x->compute_needs_range_check();
-    if (needs_range_check) {
-      length.set_instruction(x->length());
-      length.load_item();
-    }
+  bool needs_range_check = x->compute_needs_range_check();
+
+  if (use_length && needs_range_check) {
+    length.set_instruction(x->length());
+    length.load_item();
   }
 
   array.load_item();
@@ -1910,13 +1904,20 @@
     } else {
       null_check_info = range_check_info;
     }
+    if (StressLoopInvariantCodeMotion && null_check_info->deoptimize_on_exception()) {
+      LIR_Opr obj = new_register(T_OBJECT);
+      __ move(LIR_OprFact::oopConst(NULL), obj);
+      __ null_check(obj, new CodeEmitInfo(null_check_info));
+    }
   }
 
   // emit array address setup early so it schedules better
   LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), false);
 
   if (GenerateRangeChecks && needs_range_check) {
-    if (use_length) {
+    if (StressLoopInvariantCodeMotion && range_check_info->deoptimize_on_exception()) {
+      __ branch(lir_cond_always, T_ILLEGAL, new RangeCheckStub(range_check_info, index.result()));
+    } else if (use_length) {
       // TODO: use a (modified) version of array_range_check that does not require a
       //       constant length to be loaded to a register
       __ cmp(lir_cond_belowEqual, length.result(), index.result());
@@ -2634,7 +2635,7 @@
       LIR_Opr lock = new_register(T_INT);
       __ load_stack_address_monitor(0, lock);
 
-      CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL);
+      CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, x->check_flag(Instruction::DeoptimizeOnException));
       CodeStub* slow_path = new MonitorEnterStub(obj, lock, info);
 
       // receiver is guaranteed non-NULL so don't need CodeEmitInfo
@@ -2644,7 +2645,7 @@
 
   // increment invocation counters if needed
   if (!method()->is_accessor()) { // Accessors do not have MDOs, so no counting.
-    CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL);
+    CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, false);
     increment_invocation_counter(info);
   }
 
@@ -3102,6 +3103,95 @@
   }
 }
 
+void LIRGenerator::do_Assert(Assert *x) {
+#ifdef ASSERT
+  ValueTag tag = x->x()->type()->tag();
+  If::Condition cond = x->cond();
+
+  LIRItem xitem(x->x(), this);
+  LIRItem yitem(x->y(), this);
+  LIRItem* xin = &xitem;
+  LIRItem* yin = &yitem;
+
+  assert(tag == intTag, "Only integer assertions are valid!");
+
+  xin->load_item();
+  yin->dont_load_item();
+
+  set_no_result(x);
+
+  LIR_Opr left = xin->result();
+  LIR_Opr right = yin->result();
+
+  __ lir_assert(lir_cond(x->cond()), left, right, x->message(), true);
+#endif
+}
+
+
+void LIRGenerator::do_RangeCheckPredicate(RangeCheckPredicate *x) {
+
+
+  Instruction *a = x->x();
+  Instruction *b = x->y();
+  if (!a || StressRangeCheckElimination) {
+    assert(!b || StressRangeCheckElimination, "B must also be null");
+
+    CodeEmitInfo *info = state_for(x, x->state());
+    CodeStub* stub = new PredicateFailedStub(info);
+
+    __ jump(stub);
+  } else if (a->type()->as_IntConstant() && b->type()->as_IntConstant()) {
+    int a_int = a->type()->as_IntConstant()->value();
+    int b_int = b->type()->as_IntConstant()->value();
+
+    bool ok = false;
+
+    switch(x->cond()) {
+      case Instruction::eql: ok = (a_int == b_int); break;
+      case Instruction::neq: ok = (a_int != b_int); break;
+      case Instruction::lss: ok = (a_int < b_int); break;
+      case Instruction::leq: ok = (a_int <= b_int); break;
+      case Instruction::gtr: ok = (a_int > b_int); break;
+      case Instruction::geq: ok = (a_int >= b_int); break;
+      case Instruction::aeq: ok = ((unsigned int)a_int >= (unsigned int)b_int); break;
+      case Instruction::beq: ok = ((unsigned int)a_int <= (unsigned int)b_int); break;
+      default: ShouldNotReachHere();
+    }
+
+    if (ok) {
+
+      CodeEmitInfo *info = state_for(x, x->state());
+      CodeStub* stub = new PredicateFailedStub(info);
+
+      __ jump(stub);
+    }
+  } else {
+
+    ValueTag tag = x->x()->type()->tag();
+    If::Condition cond = x->cond();
+    LIRItem xitem(x->x(), this);
+    LIRItem yitem(x->y(), this);
+    LIRItem* xin = &xitem;
+    LIRItem* yin = &yitem;
+
+    assert(tag == intTag, "Only integer deoptimizations are valid!");
+
+    xin->load_item();
+    yin->dont_load_item();
+    set_no_result(x);
+
+    LIR_Opr left = xin->result();
+    LIR_Opr right = yin->result();
+
+    CodeEmitInfo *info = state_for(x, x->state());
+    CodeStub* stub = new PredicateFailedStub(info);
+
+    __ cmp(lir_cond(cond), left, right);
+    __ branch(lir_cond(cond), right->type(), stub);
+  }
+}
+
+
 LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) {
   LIRItemList args(1);
   LIRItem value(arg1, this);
--- a/src/share/vm/c1/c1_LIRGenerator.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_LIRGenerator.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -412,6 +412,8 @@
     case If::leq: l = lir_cond_lessEqual;    break;
     case If::geq: l = lir_cond_greaterEqual; break;
     case If::gtr: l = lir_cond_greater;      break;
+    case If::aeq: l = lir_cond_aboveEqual;   break;
+    case If::beq: l = lir_cond_belowEqual;   break;
     };
     return l;
   }
@@ -534,6 +536,8 @@
   virtual void do_ProfileInvoke  (ProfileInvoke*   x);
   virtual void do_RuntimeCall    (RuntimeCall*     x);
   virtual void do_MemBar         (MemBar*          x);
+  virtual void do_RangeCheckPredicate(RangeCheckPredicate* x);
+  virtual void do_Assert         (Assert*          x);
 };
 
 
--- a/src/share/vm/c1/c1_LinearScan.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -6231,26 +6231,29 @@
             assert(prev_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch");
             LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op;
 
-            LIR_Op2* prev_cmp = NULL;
-
-            for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) {
-              prev_op = instructions->at(j);
-              if(prev_op->code() == lir_cmp) {
-                assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2");
-                prev_cmp = (LIR_Op2*)prev_op;
-                assert(prev_branch->cond() == prev_cmp->condition(), "should be the same");
+            if (prev_branch->stub() == NULL) {
+
+              LIR_Op2* prev_cmp = NULL;
+
+              for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) {
+                prev_op = instructions->at(j);
+                if (prev_op->code() == lir_cmp) {
+                  assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2");
+                  prev_cmp = (LIR_Op2*)prev_op;
+                  assert(prev_branch->cond() == prev_cmp->condition(), "should be the same");
+                }
               }
-            }
-            assert(prev_cmp != NULL, "should have found comp instruction for branch");
-            if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) {
-
-              TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id()));
-
-              // eliminate a conditional branch to the immediate successor
-              prev_branch->change_block(last_branch->block());
-              prev_branch->negate_cond();
-              prev_cmp->set_condition(prev_branch->cond());
-              instructions->truncate(instructions->length() - 1);
+              assert(prev_cmp != NULL, "should have found comp instruction for branch");
+              if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) {
+
+                TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id()));
+
+                // eliminate a conditional branch to the immediate successor
+                prev_branch->change_block(last_branch->block());
+                prev_branch->negate_cond();
+                prev_cmp->set_condition(prev_branch->cond());
+                instructions->truncate(instructions->length() - 1);
+              }
             }
           }
         }
--- a/src/share/vm/c1/c1_Optimizer.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_Optimizer.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -178,7 +178,7 @@
   // 2) substitute conditional expression
   //    with an IfOp followed by a Goto
   // cut if_ away and get node before
-  Instruction* cur_end = if_->prev(block);
+  Instruction* cur_end = if_->prev();
 
   // append constants of true- and false-block if necessary
   // clone constants because original block must not be destroyed
@@ -202,7 +202,7 @@
   }
 
   // append Goto to successor
-  ValueStack* state_before = if_->is_safepoint() ? if_->state_before() : NULL;
+  ValueStack* state_before = if_->state_before();
   Goto* goto_ = new Goto(sux, state_before, if_->is_safepoint() || t_goto->is_safepoint() || f_goto->is_safepoint());
 
   // prepare state for Goto
@@ -367,10 +367,11 @@
 #endif
 
         // find instruction before end & append first instruction of sux block
-        Instruction* prev = end->prev(block);
+        Instruction* prev = end->prev();
         Instruction* next = sux->next();
         assert(prev->as_BlockEnd() == NULL, "must not be a BlockEnd");
         prev->set_next(next);
+        prev->fixup_block_pointers();
         sux->disconnect_from_graph();
         block->set_end(sux->end());
         // add exception handlers of deleted block, if any
@@ -533,6 +534,8 @@
   void do_ProfileInvoke  (ProfileInvoke*   x);
   void do_RuntimeCall    (RuntimeCall*     x);
   void do_MemBar         (MemBar*          x);
+  void do_RangeCheckPredicate(RangeCheckPredicate* x);
+  void do_Assert         (Assert*          x);
 };
 
 
@@ -714,6 +717,8 @@
 void NullCheckVisitor::do_ProfileInvoke  (ProfileInvoke*   x) {}
 void NullCheckVisitor::do_RuntimeCall    (RuntimeCall*     x) {}
 void NullCheckVisitor::do_MemBar         (MemBar*          x) {}
+void NullCheckVisitor::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
+void NullCheckVisitor::do_Assert         (Assert*          x) {}
 
 
 void NullCheckEliminator::visit(Value* p) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/c1/c1_RangeCheckElimination.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,1517 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "c1/c1_ValueStack.hpp"
+#include "c1/c1_RangeCheckElimination.hpp"
+#include "c1/c1_IR.hpp"
+#include "c1/c1_Canonicalizer.hpp"
+#include "c1/c1_ValueMap.hpp"
+#include "ci/ciMethodData.hpp"
+#include "runtime/deoptimization.hpp"
+
+// Macros for the Trace and the Assertion flag
+#ifdef ASSERT
+#define TRACE_RANGE_CHECK_ELIMINATION(code) if (TraceRangeCheckElimination) { code; }
+#define ASSERT_RANGE_CHECK_ELIMINATION(code) if (AssertRangeCheckElimination) { code; }
+#define TRACE_OR_ASSERT_RANGE_CHECK_ELIMINATION(code) if (TraceRangeCheckElimination || AssertRangeCheckElimination) { code; }
+#else
+#define TRACE_RANGE_CHECK_ELIMINATION(code)
+#define ASSERT_RANGE_CHECK_ELIMINATION(code)
+#define TRACE_OR_ASSERT_RANGE_CHECK_ELIMINATION(code)
+#endif
+
+// Entry point for the optimization
+void RangeCheckElimination::eliminate(IR *ir) {
+  bool do_elimination = ir->compilation()->has_access_indexed();
+  ASSERT_RANGE_CHECK_ELIMINATION(do_elimination = true);
+  if (do_elimination) {
+    RangeCheckEliminator rce(ir);
+  }
+}
+
+// Constructor
+RangeCheckEliminator::RangeCheckEliminator(IR *ir) :
+  _bounds(Instruction::number_of_instructions(), NULL),
+  _access_indexed_info(Instruction::number_of_instructions(), NULL)
+{
+  _visitor.set_range_check_eliminator(this);
+  _ir = ir;
+  _number_of_instructions = Instruction::number_of_instructions();
+  _optimistic = ir->compilation()->is_optimistic();
+
+  TRACE_RANGE_CHECK_ELIMINATION(
+    tty->print_cr("");
+    tty->print_cr("Range check elimination");
+    ir->method()->print_name(tty);
+    tty->print_cr("");
+  );
+
+  TRACE_RANGE_CHECK_ELIMINATION(
+    tty->print_cr("optimistic=%d", (int)_optimistic);
+  );
+
+#ifdef ASSERT
+  // Verifies several conditions that must be true on the IR-input. Only used for debugging purposes.
+  TRACE_RANGE_CHECK_ELIMINATION(
+    tty->print_cr("Verification of IR . . .");
+  );
+  Verification verification(ir);
+#endif
+
+  // Set process block flags
+  // Optimization so a blocks is only processed if it contains an access indexed instruction or if
+  // one of its children in the dominator tree contains an access indexed instruction.
+  set_process_block_flags(ir->start());
+
+  // Pass over instructions in the dominator tree
+  TRACE_RANGE_CHECK_ELIMINATION(
+    tty->print_cr("Starting pass over dominator tree . . .")
+  );
+  calc_bounds(ir->start(), NULL);
+
+  TRACE_RANGE_CHECK_ELIMINATION(
+    tty->print_cr("Finished!")
+  );
+}
+
+// Instruction specific work for some instructions
+// Constant
+void RangeCheckEliminator::Visitor::do_Constant(Constant *c) {
+  IntConstant *ic = c->type()->as_IntConstant();
+  if (ic != NULL) {
+    int value = ic->value();
+    _bound = new Bound(value, NULL, value, NULL);
+  }
+}
+
+// LogicOp
+void RangeCheckEliminator::Visitor::do_LogicOp(LogicOp *lo) {
+  if (lo->type()->as_IntType() && lo->op() == Bytecodes::_iand && (lo->x()->as_Constant() || lo->y()->as_Constant())) {
+    int constant = 0;
+    Constant *c = lo->x()->as_Constant();
+    if (c != NULL) {
+      constant = c->type()->as_IntConstant()->value();
+    } else {
+      constant = lo->y()->as_Constant()->type()->as_IntConstant()->value();
+    }
+    if (constant >= 0) {
+      _bound = new Bound(0, NULL, constant, NULL);
+    }
+  }
+}
+
+// Phi
+void RangeCheckEliminator::Visitor::do_Phi(Phi *phi) {
+  if (!phi->type()->as_IntType() && !phi->type()->as_ObjectType()) return;
+
+  BlockBegin *block = phi->block();
+  int op_count = phi->operand_count();
+  bool has_upper = true;
+  bool has_lower = true;
+  assert(phi, "Phi must not be null");
+  Bound *bound = NULL;
+
+  // TODO: support more difficult phis
+  for (int i=0; i<op_count; i++) {
+    Value v = phi->operand_at(i);
+
+    if (v == phi) continue;
+
+    // Check if instruction is connected with phi itself
+    Op2 *op2 = v->as_Op2();
+    if (op2 != NULL) {
+      Value x = op2->x();
+      Value y = op2->y();
+      if ((x == phi || y == phi)) {
+        Value other = x;
+        if (other == phi) {
+          other = y;
+        }
+        ArithmeticOp *ao = v->as_ArithmeticOp();
+        if (ao != NULL && ao->op() == Bytecodes::_iadd) {
+          assert(ao->op() == Bytecodes::_iadd, "Has to be add!");
+          if (ao->type()->as_IntType()) {
+            Constant *c = other->as_Constant();
+            if (c != NULL) {
+              assert(c->type()->as_IntConstant(), "Constant has to be of type integer");
+              int value = c->type()->as_IntConstant()->value();
+              if (value == 1) {
+                has_upper = false;
+              } else if (value > 1) {
+                // Overflow not guaranteed
+                has_upper = false;
+                has_lower = false;
+              } else if (value < 0) {
+                has_lower = false;
+              }
+              continue;
+            }
+          }
+        }
+      }
+    }
+
+    // No connection -> new bound
+    Bound *v_bound = _rce->get_bound(v);
+    Bound *cur_bound;
+    int cur_constant = 0;
+    Value cur_value = v;
+
+    if (v->type()->as_IntConstant()) {
+      cur_constant = v->type()->as_IntConstant()->value();
+      cur_value = NULL;
+    }
+    if (!v_bound->has_upper() || !v_bound->has_lower()) {
+      cur_bound = new Bound(cur_constant, cur_value, cur_constant, cur_value);
+    } else {
+      cur_bound = v_bound;
+    }
+    if (cur_bound) {
+      if (!bound) {
+        bound = cur_bound->copy();
+      } else {
+        bound->or_op(cur_bound);
+      }
+    } else {
+      // No bound!
+      bound = NULL;
+      break;
+    }
+  }
+
+  if (bound) {
+    if (!has_upper) {
+      bound->remove_upper();
+    }
+    if (!has_lower) {
+      bound->remove_lower();
+    }
+    _bound = bound;
+  } else {
+    _bound = new Bound();
+  }
+}
+
+
+// ArithmeticOp
+void RangeCheckEliminator::Visitor::do_ArithmeticOp(ArithmeticOp *ao) {
+  Value x = ao->x();
+  Value y = ao->y();
+
+  if (ao->op() == Bytecodes::_irem) {
+    Bound* x_bound = _rce->get_bound(x);
+    Bound* y_bound = _rce->get_bound(y);
+    if (x_bound->lower() >= 0 && x_bound->lower_instr() == NULL && y->as_ArrayLength() != NULL) {
+      _bound = new Bound(0, NULL, -1, y);
+    } else {
+      _bound = new Bound();
+    }
+  } else if (!x->as_Constant() || !y->as_Constant()) {
+    assert(!x->as_Constant() || !y->as_Constant(), "One of the operands must be non-constant!");
+    if (((x->as_Constant() || y->as_Constant()) && (ao->op() == Bytecodes::_iadd)) || (y->as_Constant() && ao->op() == Bytecodes::_isub)) {
+      assert(ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub, "Operand must be iadd or isub");
+
+      if (y->as_Constant()) {
+        Value tmp = x;
+        x = y;
+        y = tmp;
+      }
+      assert(x->as_Constant()->type()->as_IntConstant(), "Constant must be int constant!");
+
+      // Constant now in x
+      int const_value = x->as_Constant()->type()->as_IntConstant()->value();
+      if (ao->op() == Bytecodes::_iadd || const_value != min_jint) {
+        if (ao->op() == Bytecodes::_isub) {
+          const_value = -const_value;
+        }
+
+        Bound * bound = _rce->get_bound(y);
+        if (bound->has_upper() && bound->has_lower()) {
+          int new_lower = bound->lower() + const_value;
+          jlong new_lowerl = ((jlong)bound->lower()) + const_value;
+          int new_upper = bound->upper() + const_value;
+          jlong new_upperl = ((jlong)bound->upper()) + const_value;
+
+          if (((jlong)new_lower) == new_lowerl && ((jlong)new_upper == new_upperl)) {
+            Bound *newBound = new Bound(new_lower, bound->lower_instr(), new_upper, bound->upper_instr());
+            _bound = newBound;
+          } else {
+            // overflow
+            _bound = new Bound();
+          }
+        } else {
+          _bound = new Bound();
+        }
+      } else {
+        _bound = new Bound();
+      }
+    } else {
+      Bound *bound = _rce->get_bound(x);
+      if (ao->op() == Bytecodes::_isub) {
+        if (bound->lower_instr() == y) {
+          _bound = new Bound(Instruction::geq, NULL, bound->lower());
+        } else {
+          _bound = new Bound();
+        }
+      } else {
+        _bound = new Bound();
+      }
+    }
+  }
+}
+
+// IfOp
+void RangeCheckEliminator::Visitor::do_IfOp(IfOp *ifOp)
+{
+  if (ifOp->tval()->type()->as_IntConstant() && ifOp->fval()->type()->as_IntConstant()) {
+    int min = ifOp->tval()->type()->as_IntConstant()->value();
+    int max = ifOp->fval()->type()->as_IntConstant()->value();
+    if (min > max) {
+      // min ^= max ^= min ^= max;
+      int tmp = min;
+      min = max;
+      max = tmp;
+    }
+    _bound = new Bound(min, NULL, max, NULL);
+  }
+}
+
+// Get bound. Returns the current bound on Value v. Normally this is the topmost element on the bound stack.
+RangeCheckEliminator::Bound *RangeCheckEliminator::get_bound(Value v) {
+  // Wrong type or NULL -> No bound
+  if (!v || (!v->type()->as_IntType() && !v->type()->as_ObjectType())) return NULL;
+
+  if (!_bounds[v->id()]) {
+    // First (default) bound is calculated
+    // Create BoundStack
+    _bounds[v->id()] = new BoundStack();
+    _visitor.clear_bound();
+    Value visit_value = v;
+    visit_value->visit(&_visitor);
+    Bound *bound = _visitor.bound();
+    if (bound) {
+      _bounds[v->id()]->push(bound);
+    }
+    if (_bounds[v->id()]->length() == 0) {
+      assert(!(v->as_Constant() && v->type()->as_IntConstant()), "constants not handled here");
+      _bounds[v->id()]->push(new Bound());
+    }
+  } else if (_bounds[v->id()]->length() == 0) {
+    // To avoid endless loops, bound is currently in calculation -> nothing known about it
+    return new Bound();
+  }
+
+  // Return bound
+  return _bounds[v->id()]->top();
+}
+
+// Update bound
+void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Instruction::Condition cond, Value value, int constant) {
+  if (cond == Instruction::gtr) {
+    cond = Instruction::geq;
+    constant++;
+  } else if (cond == Instruction::lss) {
+    cond = Instruction::leq;
+    constant--;
+  }
+  Bound *bound = new Bound(cond, value, constant);
+  update_bound(pushed, v, bound);
+}
+
+// Checks for loop invariance. Returns true if the instruction is outside of the loop which is identified by loop_header.
+bool RangeCheckEliminator::loop_invariant(BlockBegin *loop_header, Instruction *instruction) {
+  assert(loop_header, "Loop header must not be null!");
+  if (!instruction) return true;
+  return instruction->dominator_depth() < loop_header->dominator_depth();
+}
+
+// Update bound. Pushes a new bound onto the stack. Tries to do a conjunction with the current bound.
+void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Bound *bound) {
+  if (v->as_Constant()) {
+    // No bound update for constants
+    return;
+  }
+  if (!_bounds[v->id()]) {
+    get_bound(v);
+    assert(_bounds[v->id()], "Now Stack must exist");
+  }
+  Bound *top = NULL;
+  if (_bounds[v->id()]->length() > 0) {
+    top = _bounds[v->id()]->top();
+  }
+  if (top) {
+    bound->and_op(top);
+  }
+  _bounds[v->id()]->push(bound);
+  pushed.append(v->id());
+}
+
+// Add instruction + idx for in block motion
+void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int idx, Value instruction, AccessIndexed *ai) {
+  int id = instruction->id();
+  AccessIndexedInfo *aii = _access_indexed_info[id];
+  if (aii == NULL) {
+    aii = new AccessIndexedInfo();
+    _access_indexed_info[id] = aii;
+    indices.append(instruction);
+    aii->_min = idx;
+    aii->_max = idx;
+    aii->_list = new AccessIndexedList();
+  } else if (idx >= aii->_min && idx <= aii->_max) {
+    remove_range_check(ai);
+    return;
+  }
+  aii->_min = MIN2(aii->_min, idx);
+  aii->_max = MAX2(aii->_max, idx);
+  aii->_list->append(ai);
+}
+
+// In block motion. Tries to reorder checks in order to reduce some of them.
+// Example:
+// a[i] = 0;
+// a[i+2] = 0;
+// a[i+1] = 0;
+// In this example the check for a[i+1] would be considered as unnecessary during the first iteration.
+// After this i is only checked once for i >= 0 and i+2 < a.length before the first array access. If this
+// check fails, deoptimization is called.
+void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList &accessIndexed, InstructionList &arrays) {
+  InstructionList indices;
+
+  // Now iterate over all arrays
+  for (int i=0; i<arrays.length(); i++) {
+    int max_constant = -1;
+    AccessIndexedList list_constant;
+    Value array = arrays.at(i);
+
+    // For all AccessIndexed-instructions in this block concerning the current array.
+    for(int j=0; j<accessIndexed.length(); j++) {
+      AccessIndexed *ai = accessIndexed.at(j);
+      if (ai->array() != array || !ai->check_flag(Instruction::NeedsRangeCheckFlag)) continue;
+
+      Value index = ai->index();
+      Constant *c = index->as_Constant();
+      if (c != NULL) {
+        int constant_value = c->type()->as_IntConstant()->value();
+        if (constant_value >= 0) {
+          if (constant_value <= max_constant) {
+            // No range check needed for this
+            remove_range_check(ai);
+          } else {
+            max_constant = constant_value;
+            list_constant.append(ai);
+          }
+        }
+      } else {
+        int last_integer = 0;
+        Instruction *last_instruction = index;
+        int base = 0;
+        ArithmeticOp *ao = index->as_ArithmeticOp();
+
+        while (ao != NULL && (ao->x()->as_Constant() || ao->y()->as_Constant()) && (ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub)) {
+          c = ao->y()->as_Constant();
+          Instruction *other = ao->x();
+          if (!c && ao->op() == Bytecodes::_iadd) {
+            c = ao->x()->as_Constant();
+            other = ao->y();
+          }
+
+          if (c) {
+            int value = c->type()->as_IntConstant()->value();
+            if (value != min_jint) {
+              if (ao->op() == Bytecodes::_isub) {
+                value = -value;
+              }
+              base += value;
+              last_integer = base;
+              last_instruction = other;
+            }
+            index = other;
+          } else {
+            break;
+          }
+          ao = index->as_ArithmeticOp();
+        }
+        add_access_indexed_info(indices, last_integer, last_instruction, ai);
+      }
+    }
+
+    // Iterate over all different indices
+    if (_optimistic) {
+      for (int i=0; i<indices.length(); i++) {
+        Instruction *index_instruction = indices.at(i);
+        AccessIndexedInfo *info = _access_indexed_info[index_instruction->id()];
+        assert(info != NULL, "Info must not be null");
+
+        // if idx < 0, max > 0, max + idx may fall between 0 and
+        // length-1 and if min < 0, min + idx may overflow and be >=
+        // 0. The predicate wouldn't trigger but some accesses could
+        // be with a negative index. This test guarantees that for the
+        // min and max value that are kept the predicate can't let
+        // some incorrect accesses happen.
+        bool range_cond = (info->_max < 0 || info->_max + min_jint <= info->_min);
+
+        // Generate code only if more than 2 range checks can be eliminated because of that.
+        // 2 because at least 2 comparisons are done
+        if (info->_list->length() > 2 && range_cond) {
+          AccessIndexed *first = info->_list->at(0);
+          Instruction *insert_position = first->prev();
+          assert(insert_position->next() == first, "prev was calculated");
+          ValueStack *state = first->state_before();
+
+          // Load min Constant
+          Constant *min_constant = NULL;
+          if (info->_min != 0) {
+            min_constant = new Constant(new IntConstant(info->_min));
+            NOT_PRODUCT(min_constant->set_printable_bci(first->printable_bci()));
+            insert_position = insert_position->insert_after(min_constant);
+          }
+
+          // Load max Constant
+          Constant *max_constant = NULL;
+          if (info->_max != 0) {
+            max_constant = new Constant(new IntConstant(info->_max));
+            NOT_PRODUCT(max_constant->set_printable_bci(first->printable_bci()));
+            insert_position = insert_position->insert_after(max_constant);
+          }
+
+          // Load array length
+          Value length_instr = first->length();
+          if (!length_instr) {
+            ArrayLength *length = new ArrayLength(array, first->state_before()->copy());
+            length->set_exception_state(length->state_before());
+            length->set_flag(Instruction::DeoptimizeOnException, true);
+            insert_position = insert_position->insert_after_same_bci(length);
+            length_instr = length;
+          }
+
+          // Calculate lower bound
+          Instruction *lower_compare = index_instruction;
+          if (min_constant) {
+            ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, min_constant, lower_compare, false, NULL);
+            insert_position = insert_position->insert_after_same_bci(ao);
+            lower_compare = ao;
+          }
+
+          // Calculate upper bound
+          Instruction *upper_compare = index_instruction;
+          if (max_constant) {
+            ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, max_constant, upper_compare, false, NULL);
+            insert_position = insert_position->insert_after_same_bci(ao);
+            upper_compare = ao;
+          }
+
+          // Trick with unsigned compare is done
+          int bci = NOT_PRODUCT(first->printable_bci()) PRODUCT_ONLY(-1);
+          insert_position = predicate(upper_compare, Instruction::aeq, length_instr, state, insert_position, bci);
+          insert_position = predicate_cmp_with_const(lower_compare, Instruction::leq, -1, state, insert_position);
+          for (int j = 0; j<info->_list->length(); j++) {
+            AccessIndexed *ai = info->_list->at(j);
+            remove_range_check(ai);
+          }
+        }
+        _access_indexed_info[index_instruction->id()] = NULL;
+      }
+      indices.clear();
+
+      if (list_constant.length() > 1) {
+        AccessIndexed *first = list_constant.at(0);
+        Instruction *insert_position = first->prev();
+        ValueStack *state = first->state_before();
+        // Load max Constant
+        Constant *constant = new Constant(new IntConstant(max_constant));
+        NOT_PRODUCT(constant->set_printable_bci(first->printable_bci()));
+        insert_position = insert_position->insert_after(constant);
+        Instruction *compare_instr = constant;
+        Value length_instr = first->length();
+        if (!length_instr) {
+          ArrayLength *length = new ArrayLength(array, state->copy());
+          length->set_exception_state(length->state_before());
+          length->set_flag(Instruction::DeoptimizeOnException, true);
+          insert_position = insert_position->insert_after_same_bci(length);
+          length_instr = length;
+        }
+        // Compare for greater or equal to array length
+        insert_position = predicate(compare_instr, Instruction::geq, length_instr, state, insert_position);
+        for (int j = 0; j<list_constant.length(); j++) {
+          AccessIndexed *ai = list_constant.at(j);
+          remove_range_check(ai);
+        }
+      }
+    }
+  }
+}
+
+bool RangeCheckEliminator::set_process_block_flags(BlockBegin *block) {
+  Instruction *cur = block;
+  bool process = false;
+
+  while (cur) {
+    process |= (cur->as_AccessIndexed() != NULL);
+    cur = cur->next();
+  }
+
+  BlockList *dominates = block->dominates();
+  for (int i=0; i<dominates->length(); i++) {
+    BlockBegin *next = dominates->at(i);
+    process |= set_process_block_flags(next);
+  }
+
+  if (!process) {
+    block->set(BlockBegin::donot_eliminate_range_checks);
+  }
+  return process;
+}
+
+bool RangeCheckEliminator::is_ok_for_deoptimization(Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper) {
+  bool upper_check = true;
+  assert(lower_instr || lower >= 0, "If no lower_instr present, lower must be greater 0");
+  assert(!lower_instr || lower_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
+  assert(!upper_instr || upper_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
+  assert(array_instr, "Array instruction must exist");
+  assert(array_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
+  assert(!length_instr || length_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller");
+
+  if (upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr) {
+    // static check
+    if (upper >= 0) return false; // would always trigger a deopt:
+                                  // array_length + x >= array_length, x >= 0 is always true
+    upper_check = false;
+  }
+  if (lower_instr && lower_instr->as_ArrayLength() && lower_instr->as_ArrayLength()->array() == array_instr) {
+    if (lower > 0) return false;
+  }
+  // No upper check required -> skip
+  if (upper_check && upper_instr && upper_instr->type()->as_ObjectType() && upper_instr == array_instr) {
+    // upper_instr is object means that the upper bound is the length
+    // of the upper_instr.
+    return false;
+  }
+  return true;
+}
+
+Instruction* RangeCheckEliminator::insert_after(Instruction* insert_position, Instruction* instr, int bci) {
+  if (bci != -1) {
+    NOT_PRODUCT(instr->set_printable_bci(bci));
+    return insert_position->insert_after(instr);
+  } else {
+    return insert_position->insert_after_same_bci(instr);
+  }
+}
+
+Instruction* RangeCheckEliminator::predicate(Instruction* left, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {
+  RangeCheckPredicate *deoptimize = new RangeCheckPredicate(left, cond, true, right, state->copy());
+  return insert_after(insert_position, deoptimize, bci);
+}
+
+Instruction* RangeCheckEliminator::predicate_cmp_with_const(Instruction* instr, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {
+  Constant *const_instr = new Constant(new IntConstant(constant));
+  insert_position = insert_after(insert_position, const_instr, bci);
+  return predicate(instr, cond, const_instr, state, insert_position);
+}
+
+Instruction* RangeCheckEliminator::predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {
+  Constant *constant = new Constant(new IntConstant(left_const));
+  insert_position = insert_after(insert_position, constant, bci);
+  ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, left, false, NULL);
+  insert_position = insert_position->insert_after_same_bci(ao);
+  return predicate(ao, cond, right, state, insert_position);
+}
+
+Instruction* RangeCheckEliminator::predicate_add_cmp_with_const(Instruction* left, int left_const, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) {
+  Constant *const_instr = new Constant(new IntConstant(constant));
+  insert_position = insert_after(insert_position, const_instr, bci);
+  return predicate_add(left, left_const, cond, const_instr, state, insert_position);
+}
+
+// Insert deoptimization
+void RangeCheckEliminator::insert_deoptimization(ValueStack *state, Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper, AccessIndexed *ai) {
+  assert(is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, lower, upper_instr, upper), "should have been tested before");
+  bool upper_check = !(upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr);
+
+  int bci = NOT_PRODUCT(ai->printable_bci()) PRODUCT_ONLY(-1);
+  if (lower_instr) {
+    assert(!lower_instr->type()->as_ObjectType(), "Must not be object type");
+    if (lower == 0) {
+      // Compare for less than 0
+      insert_position = predicate_cmp_with_const(lower_instr, Instruction::lss, 0, state, insert_position, bci);
+    } else if (lower > 0) {
+      // Compare for smaller 0
+      insert_position = predicate_add_cmp_with_const(lower_instr, lower, Instruction::lss, 0, state, insert_position, bci);
+    } else {
+      assert(lower < 0, "");
+      // Add 1
+      lower++;
+      lower = -lower;
+      // Compare for smaller or equal 0
+      insert_position = predicate_cmp_with_const(lower_instr, Instruction::leq, lower, state, insert_position, bci);
+    }
+  }
+
+  // No upper check required -> skip
+  if (!upper_check) return;
+
+  // We need to know length of array
+  if (!length_instr) {
+    // Load length if necessary
+    ArrayLength *length = new ArrayLength(array_instr, state->copy());
+    NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));
+    length->set_exception_state(length->state_before());
+    length->set_flag(Instruction::DeoptimizeOnException, true);
+    insert_position = insert_position->insert_after(length);
+    length_instr = length;
+  }
+
+  if (!upper_instr) {
+    // Compare for geq array.length
+    insert_position = predicate_cmp_with_const(length_instr, Instruction::leq, upper, state, insert_position, bci);
+  } else {
+    if (upper_instr->type()->as_ObjectType()) {
+      assert(state, "must not be null");
+      assert(upper_instr != array_instr, "should be");
+      ArrayLength *length = new ArrayLength(upper_instr, state->copy());
+      NOT_PRODUCT(length->set_printable_bci(ai->printable_bci()));
+      length->set_flag(Instruction::DeoptimizeOnException, true);
+      length->set_exception_state(length->state_before());
+      insert_position = insert_position->insert_after(length);
+      upper_instr = length;
+    }
+    assert(upper_instr->type()->as_IntType(), "Must not be object type!");
+
+    if (upper == 0) {
+      // Compare for geq array.length
+      insert_position = predicate(upper_instr, Instruction::geq, length_instr, state, insert_position, bci);
+    } else if (upper < 0) {
+      // Compare for geq array.length
+      insert_position = predicate_add(upper_instr, upper, Instruction::geq, length_instr, state, insert_position, bci);
+    } else {
+      assert(upper > 0, "");
+      upper = -upper;
+      // Compare for geq array.length
+      insert_position = predicate_add(length_instr, upper, Instruction::leq, upper_instr, state, insert_position, bci);
+    }
+  }
+}
+
+// Add if condition
+void RangeCheckEliminator::add_if_condition(IntegerStack &pushed, Value x, Value y, Instruction::Condition condition) {
+  if (y->as_Constant()) return;
+
+  int const_value = 0;
+  Value instr_value = x;
+  Constant *c = x->as_Constant();
+  ArithmeticOp *ao = x->as_ArithmeticOp();
+
+  if (c != NULL) {
+    const_value = c->type()->as_IntConstant()->value();
+    instr_value = NULL;
+  } else if (ao != NULL &&  (!ao->x()->as_Constant() || !ao->y()->as_Constant()) && ((ao->op() == Bytecodes::_isub && ao->y()->as_Constant()) || ao->op() == Bytecodes::_iadd)) {
+    assert(!ao->x()->as_Constant() || !ao->y()->as_Constant(), "At least one operator must be non-constant!");
+    assert(ao->op() == Bytecodes::_isub || ao->op() == Bytecodes::_iadd, "Operation has to be add or sub!");
+    c = ao->x()->as_Constant();
+    if (c != NULL) {
+      const_value = c->type()->as_IntConstant()->value();
+      instr_value = ao->y();
+    } else {
+      c = ao->y()->as_Constant();
+      if (c != NULL) {
+        const_value = c->type()->as_IntConstant()->value();
+        instr_value = ao->x();
+      }
+    }
+    if (ao->op() == Bytecodes::_isub) {
+      assert(ao->y()->as_Constant(), "1 - x not supported, only x - 1 is valid!");
+      if (const_value > min_jint) {
+        const_value = -const_value;
+      } else {
+        const_value = 0;
+        instr_value = x;
+      }
+    }
+  }
+
+  update_bound(pushed, y, condition, instr_value, const_value);
+}
+
+// Process If
+void RangeCheckEliminator::process_if(IntegerStack &pushed, BlockBegin *block, If *cond) {
+  // Only if we are direct true / false successor and NOT both ! (even this may occur)
+  if ((cond->tsux() == block || cond->fsux() == block) && cond->tsux() != cond->fsux()) {
+    Instruction::Condition condition = cond->cond();
+    if (cond->fsux() == block) {
+      condition = Instruction::negate(condition);
+    }
+    Value x = cond->x();
+    Value y = cond->y();
+    if (x->type()->as_IntType() && y->type()->as_IntType()) {
+      add_if_condition(pushed, y, x, condition);
+      add_if_condition(pushed, x, y, Instruction::mirror(condition));
+    }
+  }
+}
+
+// Process access indexed
+void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai) {
+  TRACE_RANGE_CHECK_ELIMINATION(
+    tty->fill_to(block->dominator_depth()*2)
+  );
+  TRACE_RANGE_CHECK_ELIMINATION(
+    tty->print_cr("Access indexed: index=%d length=%d", ai->index()->id(), (ai->length() != NULL ? ai->length()->id() :-1 ))
+  );
+
+  if (ai->check_flag(Instruction::NeedsRangeCheckFlag)) {
+    Bound *index_bound = get_bound(ai->index());
+    if (!index_bound->has_lower() || !index_bound->has_upper()) {
+      TRACE_RANGE_CHECK_ELIMINATION(
+        tty->fill_to(block->dominator_depth()*2);
+        tty->print_cr("Index instruction %d has no lower and/or no upper bound!", ai->index()->id())
+      );
+      return;
+    }
+
+    Bound *array_bound;
+    if (ai->length()) {
+      array_bound = get_bound(ai->length());
+    } else {
+      array_bound = get_bound(ai->array());
+    }
+
+    if (in_array_bound(index_bound, ai->array()) ||
+      (index_bound && array_bound && index_bound->is_smaller(array_bound) && !index_bound->lower_instr() && index_bound->lower() >= 0)) {
+        TRACE_RANGE_CHECK_ELIMINATION(
+          tty->fill_to(block->dominator_depth()*2);
+          tty->print_cr("Bounds check for instruction %d in block B%d can be fully eliminated!", ai->id(), ai->block()->block_id())
+        );
+
+        remove_range_check(ai);
+    } else if (_optimistic && loop_header) {
+      assert(ai->array(), "Array must not be null!");
+      assert(ai->index(), "Index must not be null!");
+
+      // Array instruction
+      Instruction *array_instr = ai->array();
+      if (!loop_invariant(loop_header, array_instr)) {
+        TRACE_RANGE_CHECK_ELIMINATION(
+          tty->fill_to(block->dominator_depth()*2);
+          tty->print_cr("Array %d is not loop invariant to header B%d", ai->array()->id(), loop_header->block_id())
+        );
+        return;
+      }
+
+      // Lower instruction
+      Value index_instr = ai->index();
+      Value lower_instr = index_bound->lower_instr();
+      if (!loop_invariant(loop_header, lower_instr)) {
+        TRACE_RANGE_CHECK_ELIMINATION(
+          tty->fill_to(block->dominator_depth()*2);
+          tty->print_cr("Lower instruction %d not loop invariant!", lower_instr->id())
+        );
+        return;
+      }
+      if (!lower_instr && index_bound->lower() < 0) {
+        TRACE_RANGE_CHECK_ELIMINATION(
+          tty->fill_to(block->dominator_depth()*2);
+          tty->print_cr("Lower bound smaller than 0 (%d)!", index_bound->lower())
+        );
+        return;
+      }
+
+      // Upper instruction
+      Value upper_instr = index_bound->upper_instr();
+      if (!loop_invariant(loop_header, upper_instr)) {
+        TRACE_RANGE_CHECK_ELIMINATION(
+          tty->fill_to(block->dominator_depth()*2);
+          tty->print_cr("Upper instruction %d not loop invariant!", upper_instr->id())
+        );
+        return;
+      }
+
+      // Length instruction
+      Value length_instr = ai->length();
+      if (!loop_invariant(loop_header, length_instr)) {
+        // Generate length instruction yourself!
+        length_instr = NULL;
+      }
+
+      TRACE_RANGE_CHECK_ELIMINATION(
+        tty->fill_to(block->dominator_depth()*2);
+        tty->print_cr("LOOP INVARIANT access indexed %d found in block B%d!", ai->id(), ai->block()->block_id())
+      );
+
+      BlockBegin *pred_block = loop_header->dominator();
+      assert(pred_block != NULL, "Every loop header has a dominator!");
+      BlockEnd *pred_block_end = pred_block->end();
+      Instruction *insert_position = pred_block_end->prev();
+      ValueStack *state = pred_block_end->state_before();
+      if (pred_block_end->as_Goto() && state == NULL) state = pred_block_end->state();
+      assert(state, "State must not be null");
+
+      // Add deoptimization to dominator of loop header
+      TRACE_RANGE_CHECK_ELIMINATION(
+        tty->fill_to(block->dominator_depth()*2);
+        tty->print_cr("Inserting deopt at bci %d in block B%d!", state->bci(), insert_position->block()->block_id())
+      );
+
+      if (!is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper())) {
+        TRACE_RANGE_CHECK_ELIMINATION(
+          tty->fill_to(block->dominator_depth()*2);
+          tty->print_cr("Could not eliminate because of static analysis!")
+        );
+        return;
+      }
+
+      insert_deoptimization(state, insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper(), ai);
+
+      // Finally remove the range check!
+      remove_range_check(ai);
+    }
+  }
+}
+
+void RangeCheckEliminator::remove_range_check(AccessIndexed *ai) {
+  ai->set_flag(Instruction::NeedsRangeCheckFlag, false);
+  // no range check, no need for the length instruction anymore
+  ai->clear_length();
+
+  TRACE_RANGE_CHECK_ELIMINATION(
+    tty->fill_to(ai->dominator_depth()*2);
+    tty->print_cr("Range check for instruction %d eliminated!", ai->id());
+  );
+
+  ASSERT_RANGE_CHECK_ELIMINATION(
+    Value array_length = ai->length();
+    if (!array_length) {
+      array_length = ai->array();
+      assert(array_length->type()->as_ObjectType(), "Has to be object type!");
+    }
+    int cur_constant = -1;
+    Value cur_value = array_length;
+    if (cur_value->type()->as_IntConstant()) {
+      cur_constant += cur_value->type()->as_IntConstant()->value();
+      cur_value = NULL;
+    }
+    Bound *new_index_bound = new Bound(0, NULL, cur_constant, cur_value);
+    add_assertions(new_index_bound, ai->index(), ai);
+  );
+}
+
+// Calculate bounds for instruction in this block and children blocks in the dominator tree
+void RangeCheckEliminator::calc_bounds(BlockBegin *block, BlockBegin *loop_header) {
+  // Ensures a valid loop_header
+  assert(!loop_header || loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Loop header has to be real !");
+
+  // Tracing output
+  TRACE_RANGE_CHECK_ELIMINATION(
+    tty->fill_to(block->dominator_depth()*2);
+    tty->print_cr("Block B%d", block->block_id());
+  );
+
+  // Pushed stack for conditions
+  IntegerStack pushed;
+  // Process If
+  BlockBegin *parent = block->dominator();
+  if (parent != NULL) {
+    If *cond = parent->end()->as_If();
+    if (cond != NULL) {
+      process_if(pushed, block, cond);
+    }
+  }
+
+  // Interate over current block
+  InstructionList arrays;
+  AccessIndexedList accessIndexed;
+  Instruction *cur = block;
+
+  while (cur) {
+    // Ensure cur wasn't inserted during the elimination
+    if (cur->id() < this->_bounds.length()) {
+      // Process only if it is an access indexed instruction
+      AccessIndexed *ai = cur->as_AccessIndexed();
+      if (ai != NULL) {
+        process_access_indexed(loop_header, block, ai);
+        accessIndexed.append(ai);
+        if (!arrays.contains(ai->array())) {
+          arrays.append(ai->array());
+        }
+        Bound *b = get_bound(ai->index());
+        if (!b->lower_instr()) {
+          // Lower bound is constant
+          update_bound(pushed, ai->index(), Instruction::geq, NULL, 0);
+        }
+        if (!b->has_upper()) {
+          if (ai->length() && ai->length()->type()->as_IntConstant()) {
+            int value = ai->length()->type()->as_IntConstant()->value();
+            update_bound(pushed, ai->index(), Instruction::lss, NULL, value);
+          } else {
+            // Has no upper bound
+            Instruction *instr = ai->length();
+            if (instr != NULL) instr = ai->array();
+            update_bound(pushed, ai->index(), Instruction::lss, instr, 0);
+          }
+        }
+      }
+    }
+    cur = cur->next();
+  }
+
+  // Output current condition stack
+  TRACE_RANGE_CHECK_ELIMINATION(dump_condition_stack(block));
+
+  // Do in block motion of range checks
+  in_block_motion(block, accessIndexed, arrays);
+
+  // Call all dominated blocks
+  for (int i=0; i<block->dominates()->length(); i++) {
+    BlockBegin *next = block->dominates()->at(i);
+    if (!next->is_set(BlockBegin::donot_eliminate_range_checks)) {
+      // if current block is a loop header and:
+      // - next block belongs to the same loop
+      // or
+      // - next block belongs to an inner loop
+      // then current block is the loop header for next block
+      if (block->is_set(BlockBegin::linear_scan_loop_header_flag) && (block->loop_index() == next->loop_index() || next->loop_depth() > block->loop_depth())) {
+        calc_bounds(next, block);
+      } else {
+        calc_bounds(next, loop_header);
+      }
+    }
+  }
+
+  // Reset stack
+  for (int i=0; i<pushed.length(); i++) {
+    _bounds[pushed[i]]->pop();
+  }
+}
+
+#ifndef PRODUCT
+// Dump condition stack
+void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) {
+  for (int i=0; i<_ir->linear_scan_order()->length(); i++) {
+    BlockBegin *cur_block = _ir->linear_scan_order()->at(i);
+    Instruction *instr = cur_block;
+    for_each_phi_fun(cur_block, phi,
+                     BoundStack *bound_stack = _bounds.at(phi->id());
+                     if (bound_stack && bound_stack->length() > 0) {
+                       Bound *bound = bound_stack->top();
+                       if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != phi || bound->upper_instr() != phi || bound->lower() != 0 || bound->upper() != 0)) {
+                           TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());
+                                                         tty->print("i%d", phi->id());
+                                                         tty->print(": ");
+                                                         bound->print();
+                                                         tty->print_cr("");
+                           );
+                         }
+                     });
+
+    while (!instr->as_BlockEnd()) {
+      if (instr->id() < _bounds.length()) {
+        BoundStack *bound_stack = _bounds.at(instr->id());
+        if (bound_stack && bound_stack->length() > 0) {
+          Bound *bound = bound_stack->top();
+          if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != instr || bound->upper_instr() != instr || bound->lower() != 0 || bound->upper() != 0)) {
+              TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth());
+                                            tty->print("i%d", instr->id());
+                                            tty->print(": ");
+                                            bound->print();
+                                            tty->print_cr("");
+              );
+          }
+        }
+      }
+      instr = instr->next();
+    }
+  }
+}
+#endif
+
+// Verification or the IR
+RangeCheckEliminator::Verification::Verification(IR *ir) : _used(BlockBegin::number_of_blocks(), false) {
+  this->_ir = ir;
+  ir->iterate_linear_scan_order(this);
+}
+
+// Verify this block
+void RangeCheckEliminator::Verification::block_do(BlockBegin *block) {
+  If *cond = block->end()->as_If();
+  // Watch out: tsux and fsux can be the same!
+  if (block->number_of_sux() > 1) {
+    for (int i=0; i<block->number_of_sux(); i++) {
+      BlockBegin *sux = block->sux_at(i);
+      BlockBegin *pred = NULL;
+      for (int j=0; j<sux->number_of_preds(); j++) {
+        BlockBegin *cur = sux->pred_at(j);
+        assert(cur != NULL, "Predecessor must not be null");
+        if (!pred) {
+          pred = cur;
+        }
+        assert(cur == pred, "Block must not have more than one predecessor if its predecessor has more than one successor");
+      }
+      assert(sux->number_of_preds() >= 1, "Block must have at least one predecessor");
+      assert(sux->pred_at(0) == block, "Wrong successor");
+    }
+  }
+
+  BlockBegin *dominator = block->dominator();
+  if (dominator) {
+    assert(block != _ir->start(), "Start block must not have a dominator!");
+    assert(can_reach(dominator, block), "Dominator can't reach his block !");
+    assert(can_reach(_ir->start(), dominator), "Dominator is unreachable !");
+    assert(!can_reach(_ir->start(), block, dominator), "Wrong dominator ! Block can be reached anyway !");
+    BlockList *all_blocks = _ir->linear_scan_order();
+    for (int i=0; i<all_blocks->length(); i++) {
+      BlockBegin *cur = all_blocks->at(i);
+      if (cur != dominator && cur != block) {
+        assert(can_reach(dominator, block, cur), "There has to be another dominator!");
+      }
+    }
+  } else {
+    assert(block == _ir->start(), "Only start block must not have a dominator");
+  }
+
+  if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) {
+    int loop_index = block->loop_index();
+    BlockList *all_blocks = _ir->linear_scan_order();
+    assert(block->number_of_preds() >= 1, "Block must have at least one predecessor");
+    assert(!block->is_set(BlockBegin::exception_entry_flag), "Loop header must not be exception handler!");
+    // Sometimes, the backbranch comes from an exception handler. In
+    // this case, loop indexes/loop depths may not appear correct.
+    bool loop_through_xhandler = false;
+    for (int i = 0; i < block->number_of_exception_handlers(); i++) {
+      BlockBegin *xhandler = block->exception_handler_at(i);
+      for (int j = 0; j < block->number_of_preds(); j++) {
+        if (dominates(xhandler, block->pred_at(j)) || xhandler == block->pred_at(j)) {
+          loop_through_xhandler = true;
+        }
+      }
+    }
+
+    for (int i=0; i<block->number_of_sux(); i++) {
+      BlockBegin *sux = block->sux_at(i);
+      assert(sux->loop_depth() != block->loop_depth() || sux->loop_index() == block->loop_index() || loop_through_xhandler, "Loop index has to be same");
+      assert(sux->loop_depth() == block->loop_depth() || sux->loop_index() != block->loop_index(), "Loop index has to be different");
+    }
+
+    for (int i=0; i<all_blocks->length(); i++) {
+      BlockBegin *cur = all_blocks->at(i);
+      if (cur->loop_index() == loop_index && cur != block) {
+        assert(dominates(block->dominator(), cur), "Dominator of loop header must dominate all loop blocks");
+      }
+    }
+  }
+
+  Instruction *cur = block;
+  while (cur) {
+    assert(cur->block() == block, "Block begin has to be set correctly!");
+    cur = cur->next();
+  }
+}
+
+// Loop header must dominate all loop blocks
+bool RangeCheckEliminator::Verification::dominates(BlockBegin *dominator, BlockBegin *block) {
+  BlockBegin *cur = block->dominator();
+  while (cur && cur != dominator) {
+    cur = cur->dominator();
+  }
+  return cur == dominator;
+}
+
+// Try to reach Block end beginning in Block start and not using Block dont_use
+bool RangeCheckEliminator::Verification::can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use /* = NULL */) {
+  if (start == end) return start != dont_use;
+  // Simple BSF from start to end
+  //  BlockBeginList _current;
+  for (int i=0; i<_used.length(); i++) {
+    _used[i] = false;
+  }
+  _current.truncate(0);
+  _successors.truncate(0);
+  if (start != dont_use) {
+    _current.push(start);
+    _used[start->block_id()] = true;
+  }
+
+  //  BlockBeginList _successors;
+  while (_current.length() > 0) {
+    BlockBegin *cur = _current.pop();
+    // Add exception handlers to list
+    for (int i=0; i<cur->number_of_exception_handlers(); i++) {
+      BlockBegin *xhandler = cur->exception_handler_at(i);
+      _successors.push(xhandler);
+      // Add exception handlers of _successors to list
+      for (int j=0; j<xhandler->number_of_exception_handlers(); j++) {
+        BlockBegin *sux_xhandler = xhandler->exception_handler_at(j);
+        _successors.push(sux_xhandler);
+      }
+    }
+    // Add normal _successors to list
+    for (int i=0; i<cur->number_of_sux(); i++) {
+      BlockBegin *sux = cur->sux_at(i);
+      _successors.push(sux);
+      // Add exception handlers of _successors to list
+      for (int j=0; j<sux->number_of_exception_handlers(); j++) {
+        BlockBegin *xhandler = sux->exception_handler_at(j);
+        _successors.push(xhandler);
+      }
+    }
+    for (int i=0; i<_successors.length(); i++) {
+      BlockBegin *sux = _successors[i];
+      assert(sux != NULL, "Successor must not be NULL!");
+      if (sux == end) {
+        return true;
+      }
+      if (sux != dont_use && !_used[sux->block_id()]) {
+        _used[sux->block_id()] = true;
+        _current.push(sux);
+      }
+    }
+    _successors.truncate(0);
+  }
+
+  return false;
+}
+
+// Bound
+RangeCheckEliminator::Bound::~Bound() {
+}
+
+// Bound constructor
+RangeCheckEliminator::Bound::Bound() {
+  init();
+  this->_lower = min_jint;
+  this->_upper = max_jint;
+  this->_lower_instr = NULL;
+  this->_upper_instr = NULL;
+}
+
+// Bound constructor
+RangeCheckEliminator::Bound::Bound(int lower, Value lower_instr, int upper, Value upper_instr) {
+  init();
+  assert(!lower_instr || !lower_instr->as_Constant() || !lower_instr->type()->as_IntConstant(), "Must not be constant!");
+  assert(!upper_instr || !upper_instr->as_Constant() || !upper_instr->type()->as_IntConstant(), "Must not be constant!");
+  this->_lower = lower;
+  this->_upper = upper;
+  this->_lower_instr = lower_instr;
+  this->_upper_instr = upper_instr;
+}
+
+// Bound constructor
+RangeCheckEliminator::Bound::Bound(Instruction::Condition cond, Value v, int constant) {
+  assert(!v || (v->type() && (v->type()->as_IntType() || v->type()->as_ObjectType())), "Type must be array or integer!");
+  assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");
+
+  init();
+  if (cond == Instruction::eql) {
+    _lower = constant;
+    _lower_instr = v;
+    _upper = constant;
+    _upper_instr = v;
+  } else if (cond == Instruction::neq) {
+    _lower = min_jint;
+    _upper = max_jint;
+    _lower_instr = NULL;
+    _upper_instr = NULL;
+    if (v == NULL) {
+      if (constant == min_jint) {
+        _lower++;
+      }
+      if (constant == max_jint) {
+        _upper--;
+      }
+    }
+  } else if (cond == Instruction::geq) {
+    _lower = constant;
+    _lower_instr = v;
+    _upper = max_jint;
+    _upper_instr = NULL;
+  } else if (cond == Instruction::leq) {
+    _lower = min_jint;
+    _lower_instr = NULL;
+    _upper = constant;
+    _upper_instr = v;
+  } else {
+    ShouldNotReachHere();
+  }
+}
+
+// Set lower
+void RangeCheckEliminator::Bound::set_lower(int value, Value v) {
+  assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");
+  this->_lower = value;
+  this->_lower_instr = v;
+}
+
+// Set upper
+void RangeCheckEliminator::Bound::set_upper(int value, Value v) {
+  assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!");
+  this->_upper = value;
+  this->_upper_instr = v;
+}
+
+// Add constant -> no overflow may occur
+void RangeCheckEliminator::Bound::add_constant(int value) {
+  this->_lower += value;
+  this->_upper += value;
+}
+
+// Init
+void RangeCheckEliminator::Bound::init() {
+}
+
+// or
+void RangeCheckEliminator::Bound::or_op(Bound *b) {
+  // Watch out, bound is not guaranteed not to overflow!
+  // Update lower bound
+  if (_lower_instr != b->_lower_instr || (_lower_instr && _lower != b->_lower)) {
+    _lower_instr = NULL;
+    _lower = min_jint;
+  } else {
+    _lower = MIN2(_lower, b->_lower);
+  }
+  // Update upper bound
+  if (_upper_instr != b->_upper_instr || (_upper_instr && _upper != b->_upper)) {
+    _upper_instr = NULL;
+    _upper = max_jint;
+  } else {
+    _upper = MAX2(_upper, b->_upper);
+  }
+}
+
+// and
+void RangeCheckEliminator::Bound::and_op(Bound *b) {
+  // Update lower bound
+  if (_lower_instr == b->_lower_instr) {
+    _lower = MAX2(_lower, b->_lower);
+  }
+  if (b->has_lower()) {
+    bool set = true;
+    if (_lower_instr != NULL && b->_lower_instr != NULL) {
+      set = (_lower_instr->dominator_depth() > b->_lower_instr->dominator_depth());
+    }
+    if (set) {
+      _lower = b->_lower;
+      _lower_instr = b->_lower_instr;
+    }
+  }
+  // Update upper bound
+  if (_upper_instr == b->_upper_instr) {
+    _upper = MIN2(_upper, b->_upper);
+  }
+  if (b->has_upper()) {
+    bool set = true;
+    if (_upper_instr != NULL && b->_upper_instr != NULL) {
+      set = (_upper_instr->dominator_depth() > b->_upper_instr->dominator_depth());
+    }
+    if (set) {
+      _upper = b->_upper;
+      _upper_instr = b->_upper_instr;
+    }
+  }
+}
+
+// has_upper
+bool RangeCheckEliminator::Bound::has_upper() {
+  return _upper_instr != NULL || _upper < max_jint;
+}
+
+// is_smaller
+bool RangeCheckEliminator::Bound::is_smaller(Bound *b) {
+  if (b->_lower_instr != _upper_instr) {
+    return false;
+  }
+  return _upper < b->_lower;
+}
+
+// has_lower
+bool RangeCheckEliminator::Bound::has_lower() {
+  return _lower_instr != NULL || _lower > min_jint;
+}
+
+// in_array_bound
+bool RangeCheckEliminator::in_array_bound(Bound *bound, Value array){
+  if (!bound) return false;
+  assert(array != NULL, "Must not be null!");
+  assert(bound != NULL, "Must not be null!");
+  if (bound->lower() >=0 && bound->lower_instr() == NULL && bound->upper() < 0 && bound->upper_instr() != NULL) {
+    ArrayLength *len = bound->upper_instr()->as_ArrayLength();
+    if (bound->upper_instr() == array || (len != NULL && len->array() == array)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// remove_lower
+void RangeCheckEliminator::Bound::remove_lower() {
+  _lower = min_jint;
+  _lower_instr = NULL;
+}
+
+// remove_upper
+void RangeCheckEliminator::Bound::remove_upper() {
+  _upper = max_jint;
+  _upper_instr = NULL;
+}
+
+// upper
+int RangeCheckEliminator::Bound::upper() {
+  return _upper;
+}
+
+// lower
+int RangeCheckEliminator::Bound::lower() {
+  return _lower;
+}
+
+// upper_instr
+Value RangeCheckEliminator::Bound::upper_instr() {
+  return _upper_instr;
+}
+
+// lower_instr
+Value RangeCheckEliminator::Bound::lower_instr() {
+  return _lower_instr;
+}
+
+// print
+void RangeCheckEliminator::Bound::print() {
+  tty->print("");
+  if (this->_lower_instr || this->_lower != min_jint) {
+    if (this->_lower_instr) {
+      tty->print("i%d", this->_lower_instr->id());
+      if (this->_lower > 0) {
+        tty->print("+%d", _lower);
+      }
+      if (this->_lower < 0) {
+        tty->print("%d", _lower);
+      }
+    } else {
+      tty->print("%d", _lower);
+    }
+    tty->print(" <= ");
+  }
+  tty->print("x");
+  if (this->_upper_instr || this->_upper != max_jint) {
+    tty->print(" <= ");
+    if (this->_upper_instr) {
+      tty->print("i%d", this->_upper_instr->id());
+      if (this->_upper > 0) {
+        tty->print("+%d", _upper);
+      }
+      if (this->_upper < 0) {
+        tty->print("%d", _upper);
+      }
+    } else {
+      tty->print("%d", _upper);
+    }
+  }
+}
+
+// Copy
+RangeCheckEliminator::Bound *RangeCheckEliminator::Bound::copy() {
+  Bound *b = new Bound();
+  b->_lower = _lower;
+  b->_lower_instr = _lower_instr;
+  b->_upper = _upper;
+  b->_upper_instr = _upper_instr;
+  return b;
+}
+
+#ifdef ASSERT
+// Add assertion
+void RangeCheckEliminator::Bound::add_assertion(Instruction *instruction, Instruction *position, int i, Value instr, Instruction::Condition cond) {
+  Instruction *result = position;
+  Instruction *compare_with = NULL;
+  ValueStack *state = position->state_before();
+  if (position->as_BlockEnd() && !position->as_Goto()) {
+    state = position->as_BlockEnd()->state_before();
+  }
+  Instruction *instruction_before = position->prev();
+  if (position->as_Return() && Compilation::current()->method()->is_synchronized() && instruction_before->as_MonitorExit()) {
+    instruction_before = instruction_before->prev();
+  }
+  result = instruction_before;
+  // Load constant only if needed
+  Constant *constant = NULL;
+  if (i != 0 || !instr) {
+    constant = new Constant(new IntConstant(i));
+    NOT_PRODUCT(constant->set_printable_bci(position->printable_bci()));
+    result = result->insert_after(constant);
+    compare_with = constant;
+  }
+
+  if (instr) {
+    assert(instr->type()->as_ObjectType() || instr->type()->as_IntType(), "Type must be array or integer!");
+    compare_with = instr;
+    // Load array length if necessary
+    Instruction *op = instr;
+    if (instr->type()->as_ObjectType()) {
+      assert(state, "must not be null");
+      ArrayLength *length = new ArrayLength(instr, state->copy());
+      NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));
+      length->set_exception_state(length->state_before());
+      result = result->insert_after(length);
+      op = length;
+      compare_with = length;
+    }
+    // Add operation only if necessary
+    if (constant) {
+      ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, op, false, NULL);
+      NOT_PRODUCT(ao->set_printable_bci(position->printable_bci()));
+      result = result->insert_after(ao);
+      compare_with = ao;
+      // TODO: Check that add operation does not overflow!
+    }
+  }
+  assert(compare_with != NULL, "You have to compare with something!");
+  assert(instruction != NULL, "Instruction must not be null!");
+
+  if (instruction->type()->as_ObjectType()) {
+    // Load array length if necessary
+    Instruction *op = instruction;
+    assert(state, "must not be null");
+    ArrayLength *length = new ArrayLength(instruction, state->copy());
+    length->set_exception_state(length->state_before());
+    NOT_PRODUCT(length->set_printable_bci(position->printable_bci()));
+    result = result->insert_after(length);
+    instruction = length;
+  }
+
+  Assert *assert = new Assert(instruction, cond, false, compare_with);
+  NOT_PRODUCT(assert->set_printable_bci(position->printable_bci()));
+  result->insert_after(assert);
+}
+
+// Add assertions
+void RangeCheckEliminator::add_assertions(Bound *bound, Instruction *instruction, Instruction *position) {
+  // Add lower bound assertion
+  if (bound->has_lower()) {
+    bound->add_assertion(instruction, position, bound->lower(), bound->lower_instr(), Instruction::geq);
+  }
+  // Add upper bound assertion
+  if (bound->has_upper()) {
+    bound->add_assertion(instruction, position, bound->upper(), bound->upper_instr(), Instruction::leq);
+  }
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/c1/c1_RangeCheckElimination.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_C1_C1_RANGECHECKELIMINATION_HPP
+#define SHARE_VM_C1_C1_RANGECHECKELIMINATION_HPP
+
+#include "c1/c1_Instruction.hpp"
+
+// Base class for range check elimination
+class RangeCheckElimination : AllStatic {
+public:
+  static void eliminate(IR *ir);
+};
+
+// Implementation
+class RangeCheckEliminator VALUE_OBJ_CLASS_SPEC {
+private:
+  int _number_of_instructions;
+  bool _optimistic; // Insert predicates and deoptimize when they fail
+  IR *_ir;
+
+  define_array(BlockBeginArray, BlockBegin*)
+  define_stack(BlockBeginList, BlockBeginArray)
+  define_stack(IntegerStack, intArray)
+  define_array(IntegerMap, IntegerStack*)
+
+  class Verification : public _ValueObj /*VALUE_OBJ_CLASS_SPEC*/, public BlockClosure {
+  private:
+    IR *_ir;
+    boolArray _used;
+    BlockBeginList _current;
+    BlockBeginList _successors;
+
+  public:
+    Verification(IR *ir);
+    virtual void block_do(BlockBegin *block);
+    bool can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use = NULL);
+    bool dominates(BlockBegin *dominator, BlockBegin *block);
+  };
+
+public:
+  // Bounds for an instruction in the form x + c which c integer
+  // constant and x another instruction
+  class Bound : public CompilationResourceObj {
+  private:
+    int _upper;
+    Value _upper_instr;
+    int _lower;
+    Value _lower_instr;
+
+  public:
+    Bound();
+    Bound(Value v);
+    Bound(Instruction::Condition cond, Value v, int constant = 0);
+    Bound(int lower, Value lower_instr, int upper, Value upper_instr);
+    ~Bound();
+
+#ifdef ASSERT
+    void add_assertion(Instruction *instruction, Instruction *position, int i, Value instr, Instruction::Condition cond);
+#endif
+    int upper();
+    Value upper_instr();
+    int lower();
+    Value lower_instr();
+    void print();
+    bool check_no_overflow(int const_value);
+    void or_op(Bound *b);
+    void and_op(Bound *b);
+    bool has_upper();
+    bool has_lower();
+    void set_upper(int upper, Value upper_instr);
+    void set_lower(int lower, Value lower_instr);
+    bool is_smaller(Bound *b);
+    void remove_upper();
+    void remove_lower();
+    void add_constant(int value);
+    Bound *copy();
+
+  private:
+    void init();
+  };
+
+
+  class Visitor : public InstructionVisitor {
+  private:
+    Bound *_bound;
+    RangeCheckEliminator *_rce;
+
+  public:
+    void set_range_check_eliminator(RangeCheckEliminator *rce) { _rce = rce; }
+    Bound *bound() const { return _bound; }
+    void clear_bound() { _bound = NULL; }
+
+  protected:
+    // visitor functions
+    void do_Constant       (Constant*        x);
+    void do_IfOp           (IfOp*            x);
+    void do_LogicOp        (LogicOp*         x);
+    void do_ArithmeticOp   (ArithmeticOp*    x);
+    void do_Phi            (Phi*             x);
+
+    void do_StoreField     (StoreField*      x) { /* nothing to do */ };
+    void do_StoreIndexed   (StoreIndexed*    x) { /* nothing to do */ };
+    void do_MonitorEnter   (MonitorEnter*    x) { /* nothing to do */ };
+    void do_MonitorExit    (MonitorExit*     x) { /* nothing to do */ };
+    void do_Invoke         (Invoke*          x) { /* nothing to do */ };
+    void do_UnsafePutRaw   (UnsafePutRaw*    x) { /* nothing to do */ };
+    void do_UnsafePutObject(UnsafePutObject* x) { /* nothing to do */ };
+    void do_Intrinsic      (Intrinsic*       x) { /* nothing to do */ };
+    void do_Local          (Local*           x) { /* nothing to do */ };
+    void do_LoadField      (LoadField*       x) { /* nothing to do */ };
+    void do_ArrayLength    (ArrayLength*     x) { /* nothing to do */ };
+    void do_LoadIndexed    (LoadIndexed*     x) { /* nothing to do */ };
+    void do_NegateOp       (NegateOp*        x) { /* nothing to do */ };
+    void do_ShiftOp        (ShiftOp*         x) { /* nothing to do */ };
+    void do_CompareOp      (CompareOp*       x) { /* nothing to do */ };
+    void do_Convert        (Convert*         x) { /* nothing to do */ };
+    void do_NullCheck      (NullCheck*       x) { /* nothing to do */ };
+    void do_TypeCast       (TypeCast*        x) { /* nothing to do */ };
+    void do_NewInstance    (NewInstance*     x) { /* nothing to do */ };
+    void do_NewTypeArray   (NewTypeArray*    x) { /* nothing to do */ };
+    void do_NewObjectArray (NewObjectArray*  x) { /* nothing to do */ };
+    void do_NewMultiArray  (NewMultiArray*   x) { /* nothing to do */ };
+    void do_CheckCast      (CheckCast*       x) { /* nothing to do */ };
+    void do_InstanceOf     (InstanceOf*      x) { /* nothing to do */ };
+    void do_BlockBegin     (BlockBegin*      x) { /* nothing to do */ };
+    void do_Goto           (Goto*            x) { /* nothing to do */ };
+    void do_If             (If*              x) { /* nothing to do */ };
+    void do_IfInstanceOf   (IfInstanceOf*    x) { /* nothing to do */ };
+    void do_TableSwitch    (TableSwitch*     x) { /* nothing to do */ };
+    void do_LookupSwitch   (LookupSwitch*    x) { /* nothing to do */ };
+    void do_Return         (Return*          x) { /* nothing to do */ };
+    void do_Throw          (Throw*           x) { /* nothing to do */ };
+    void do_Base           (Base*            x) { /* nothing to do */ };
+    void do_OsrEntry       (OsrEntry*        x) { /* nothing to do */ };
+    void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ };
+    void do_RoundFP        (RoundFP*         x) { /* nothing to do */ };
+    void do_UnsafeGetRaw   (UnsafeGetRaw*    x) { /* nothing to do */ };
+    void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ };
+    void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { /* nothing to do */ };
+    void do_UnsafePrefetchRead (UnsafePrefetchRead*  x) { /* nothing to do */ };
+    void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ };
+    void do_ProfileCall    (ProfileCall*     x) { /* nothing to do */ };
+    void do_ProfileInvoke  (ProfileInvoke*  x)  { /* nothing to do */ };
+    void do_RuntimeCall    (RuntimeCall*     x) { /* nothing to do */ };
+    void do_MemBar         (MemBar*          x) { /* nothing to do */ };
+    void do_RangeCheckPredicate(RangeCheckPredicate* x) { /* nothing to do */ };
+    void do_Assert         (Assert*          x) { /* nothing to do */ };
+  };
+
+#ifdef ASSERT
+  void add_assertions(Bound *bound, Instruction *instruction, Instruction *position);
+#endif
+
+  define_array(BoundArray, Bound *)
+  define_stack(BoundStack, BoundArray)
+  define_array(BoundMap, BoundStack *)
+  define_array(AccessIndexedArray, AccessIndexed *)
+  define_stack(AccessIndexedList, AccessIndexedArray)
+  define_array(InstructionArray, Instruction *)
+  define_stack(InstructionList, InstructionArray)
+
+  class AccessIndexedInfo : public CompilationResourceObj  {
+  public:
+    AccessIndexedList *_list;
+    int _min;
+    int _max;
+  };
+
+  define_array(AccessIndexedInfoArray, AccessIndexedInfo *)
+  BoundMap _bounds; // Mapping from Instruction's id to current bound
+  AccessIndexedInfoArray _access_indexed_info; // Mapping from Instruction's id to AccessIndexedInfo for in block motion
+  Visitor _visitor;
+
+public:
+  RangeCheckEliminator(IR *ir);
+
+  IR *ir() const { return _ir; }
+
+  // Pass over the dominator tree to identify blocks where there's an oppportunity for optimization
+  bool set_process_block_flags(BlockBegin *block);
+  // The core of the optimization work: pass over the dominator tree
+  // to propagate bound information, insert predicate out of loops,
+  // eliminate bound checks when possible and perform in block motion
+  void calc_bounds(BlockBegin *block, BlockBegin *loop_header);
+  // reorder bound checks within a block in order to eliminate some of them
+  void in_block_motion(BlockBegin *block, AccessIndexedList &accessIndexed, InstructionList &arrays);
+
+  // update/access current bound
+  void update_bound(IntegerStack &pushed, Value v, Instruction::Condition cond, Value value, int constant);
+  void update_bound(IntegerStack &pushed, Value v, Bound *bound);
+  Bound *get_bound(Value v);
+
+  bool loop_invariant(BlockBegin *loop_header, Instruction *instruction);                                    // check for loop invariance
+  void add_access_indexed_info(InstructionList &indices, int i, Value instruction, AccessIndexed *ai); // record indexed access for in block motion
+  void remove_range_check(AccessIndexed *ai);                                                                // Mark this instructions as not needing a range check
+  void add_if_condition(IntegerStack &pushed, Value x, Value y, Instruction::Condition condition);           // Update bound for an If
+  bool in_array_bound(Bound *bound, Value array);                                                            // Check whether bound is known to fall within array
+
+  // helper functions to work with predicates
+  Instruction* insert_after(Instruction* insert_position, Instruction* instr, int bci);
+  Instruction* predicate(Instruction* left, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci=-1);
+  Instruction* predicate_cmp_with_const(Instruction* instr, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci=1);
+  Instruction* predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci=-1);
+  Instruction* predicate_add_cmp_with_const(Instruction* left, int left_const, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci=-1);
+
+  void insert_deoptimization(ValueStack *state, Instruction *insert_position, Instruction *array_instr,      // Add predicate
+                             Instruction *length_instruction, Instruction *lower_instr, int lower,
+                             Instruction *upper_instr, int upper, AccessIndexed *ai);
+  bool is_ok_for_deoptimization(Instruction *insert_position, Instruction *array_instr,                      // Can we safely add a predicate?
+                                Instruction *length_instr, Instruction *lower_instr,
+                                int lower, Instruction *upper_instr, int upper);
+  void process_if(IntegerStack &pushed, BlockBegin *block, If *cond);                                        // process If Instruction
+  void process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai);                // process indexed access
+
+  void dump_condition_stack(BlockBegin *cur_block);
+  static void print_statistics();
+};
+
+#endif // SHARE_VM_C1_C1_RANGECHECKELIMINATION_HPP
--- a/src/share/vm/c1/c1_Runtime1.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1330,6 +1330,50 @@
   return (k != NULL && obj != NULL && obj->is_a(k)) ? 1 : 0;
 JRT_END
 
+JRT_ENTRY(void, Runtime1::predicate_failed_trap(JavaThread* thread))
+  ResourceMark rm;
+
+  assert(!TieredCompilation, "incompatible with tiered compilation");
+
+  RegisterMap reg_map(thread, false);
+  frame runtime_frame = thread->last_frame();
+  frame caller_frame = runtime_frame.sender(&reg_map);
+
+  nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
+  assert (nm != NULL, "no more nmethod?");
+  nm->make_not_entrant();
+
+  methodHandle m(nm->method());
+  MethodData* mdo = m->method_data();
+
+  if (mdo == NULL && !HAS_PENDING_EXCEPTION) {
+    // Build an MDO.  Ignore errors like OutOfMemory;
+    // that simply means we won't have an MDO to update.
+    Method::build_interpreter_method_data(m, THREAD);
+    if (HAS_PENDING_EXCEPTION) {
+      assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
+      CLEAR_PENDING_EXCEPTION;
+    }
+    mdo = m->method_data();
+  }
+
+  if (mdo != NULL) {
+    mdo->inc_trap_count(Deoptimization::Reason_none);
+  }
+
+  if (TracePredicateFailedTraps) {
+    stringStream ss1, ss2;
+    vframeStream vfst(thread);
+    methodHandle inlinee = methodHandle(vfst.method());
+    inlinee->print_short_name(&ss1);
+    m->print_short_name(&ss2);
+    tty->print_cr("Predicate failed trap in method %s at bci %d inlined in %s at pc %x", ss1.as_string(), vfst.bci(), ss2.as_string(), caller_frame.pc());
+  }
+
+
+  Deoptimization::deoptimize_frame(thread, caller_frame.id());
+
+JRT_END
 
 #ifndef PRODUCT
 void Runtime1::print_statistics() {
--- a/src/share/vm/c1/c1_Runtime1.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -71,6 +71,7 @@
   stub(g1_post_barrier_slow)         \
   stub(fpu2long_stub)                \
   stub(counter_overflow)             \
+  stub(predicate_failed_trap)        \
   last_entry(number_of_ids)
 
 #define DECLARE_STUB_ID(x)       x ## _id ,
@@ -190,6 +191,8 @@
   static void oop_arraycopy(HeapWord* src, HeapWord* dst, int length);
   static int  is_instance_of(oopDesc* mirror, oopDesc* obj);
 
+  static void predicate_failed_trap(JavaThread* thread);
+
   static void print_statistics()                 PRODUCT_RETURN;
 };
 
--- a/src/share/vm/c1/c1_ValueMap.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_ValueMap.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -26,9 +26,9 @@
 #include "c1/c1_Canonicalizer.hpp"
 #include "c1/c1_IR.hpp"
 #include "c1/c1_ValueMap.hpp"
+#include "c1/c1_ValueStack.hpp"
 #include "utilities/bitMap.inline.hpp"
 
-
 #ifndef PRODUCT
 
   int ValueMap::_number_of_finds = 0;
@@ -192,10 +192,6 @@
                    && lf->field()->holder() == field->holder()                           \
                    && (all_offsets || lf->field()->offset() == field->offset());
 
-#define MUST_KILL_EXCEPTION(must_kill, entry, value)                                     \
-  assert(entry->nesting() < nesting(), "must not find bigger nesting than current");     \
-  bool must_kill = (entry->nesting() == nesting() - 1);
-
 
 void ValueMap::kill_memory() {
   GENERIC_KILL_VALUE(MUST_KILL_MEMORY);
@@ -209,11 +205,6 @@
   GENERIC_KILL_VALUE(MUST_KILL_FIELD);
 }
 
-void ValueMap::kill_exception() {
-  GENERIC_KILL_VALUE(MUST_KILL_EXCEPTION);
-}
-
-
 void ValueMap::kill_map(ValueMap* map) {
   assert(is_global_value_numbering(), "only for global value numbering");
   _killed_values.set_union(&map->_killed_values);
@@ -274,6 +265,8 @@
   GlobalValueNumbering* _gvn;
   BlockList             _loop_blocks;
   bool                  _too_complicated_loop;
+  bool                  _has_field_store[T_ARRAY + 1];
+  bool                  _has_indexed_store[T_ARRAY + 1];
 
   // simplified access to methods of GlobalValueNumbering
   ValueMap* current_map()                        { return _gvn->current_map(); }
@@ -281,8 +274,16 @@
 
   // implementation for abstract methods of ValueNumberingVisitor
   void      kill_memory()                                 { _too_complicated_loop = true; }
-  void      kill_field(ciField* field, bool all_offsets)  { current_map()->kill_field(field, all_offsets); };
-  void      kill_array(ValueType* type)                   { current_map()->kill_array(type); };
+  void      kill_field(ciField* field, bool all_offsets)  {
+    current_map()->kill_field(field, all_offsets);
+    assert(field->type()->basic_type() >= 0 && field->type()->basic_type() <= T_ARRAY, "Invalid type");
+    _has_field_store[field->type()->basic_type()] = true;
+  }
+  void      kill_array(ValueType* type)                   {
+    current_map()->kill_array(type);
+    BasicType basic_type = as_BasicType(type); assert(basic_type >= 0 && basic_type <= T_ARRAY, "Invalid type");
+    _has_indexed_store[basic_type] = true;
+  }
 
  public:
   ShortLoopOptimizer(GlobalValueNumbering* gvn)
@@ -290,11 +291,141 @@
     , _loop_blocks(ValueMapMaxLoopSize)
     , _too_complicated_loop(false)
   {
+    for (int i=0; i<= T_ARRAY; i++){
+      _has_field_store[i] = false;
+      _has_indexed_store[i] = false;
+    }
+  }
+
+  bool has_field_store(BasicType type) {
+    assert(type >= 0 && type <= T_ARRAY, "Invalid type");
+    return _has_field_store[type];
+  }
+
+  bool has_indexed_store(BasicType type) {
+    assert(type >= 0 && type <= T_ARRAY, "Invalid type");
+    return _has_indexed_store[type];
   }
 
   bool process(BlockBegin* loop_header);
 };
 
+class LoopInvariantCodeMotion : public StackObj  {
+ private:
+  GlobalValueNumbering* _gvn;
+  ShortLoopOptimizer*   _short_loop_optimizer;
+  Instruction*          _insertion_point;
+  ValueStack *          _state;
+
+  void set_invariant(Value v) const    { _gvn->set_processed(v); }
+  bool is_invariant(Value v) const     { return _gvn->is_processed(v); }
+
+  void process_block(BlockBegin* block);
+
+ public:
+  LoopInvariantCodeMotion(ShortLoopOptimizer *slo, GlobalValueNumbering* gvn, BlockBegin* loop_header, BlockList* loop_blocks);
+};
+
+LoopInvariantCodeMotion::LoopInvariantCodeMotion(ShortLoopOptimizer *slo, GlobalValueNumbering* gvn, BlockBegin* loop_header, BlockList* loop_blocks)
+  : _gvn(gvn), _short_loop_optimizer(slo) {
+
+  TRACE_VALUE_NUMBERING(tty->print_cr("using loop invariant code motion loop_header = %d", loop_header->block_id()));
+  TRACE_VALUE_NUMBERING(tty->print_cr("** loop invariant code motion for short loop B%d", loop_header->block_id()));
+
+  BlockBegin* insertion_block = loop_header->dominator();
+  if (insertion_block->number_of_preds() == 0) {
+    return;  // only the entry block does not have a predecessor
+  }
+
+  assert(insertion_block->end()->as_Base() == NULL, "cannot insert into entry block");
+  _insertion_point = insertion_block->end()->prev();
+
+  BlockEnd *block_end = insertion_block->end();
+  _state = block_end->state_before();
+
+  if (!_state) {
+    // If, TableSwitch and LookupSwitch always have state_before when
+    // loop invariant code motion happens..
+    assert(block_end->as_Goto(), "Block has to be goto");
+    _state = block_end->state();
+  }
+
+  // the loop_blocks are filled by going backward from the loop header, so this processing order is best
+  assert(loop_blocks->at(0) == loop_header, "loop header must be first loop block");
+  process_block(loop_header);
+  for (int i = loop_blocks->length() - 1; i >= 1; i--) {
+    process_block(loop_blocks->at(i));
+  }
+}
+
+void LoopInvariantCodeMotion::process_block(BlockBegin* block) {
+  TRACE_VALUE_NUMBERING(tty->print_cr("processing block B%d", block->block_id()));
+
+  Instruction* prev = block;
+  Instruction* cur = block->next();
+
+  while (cur != NULL) {
+
+    // determine if cur instruction is loop invariant
+    // only selected instruction types are processed here
+    bool cur_invariant = false;
+
+    if (cur->as_Constant() != NULL) {
+      cur_invariant = !cur->can_trap();
+    } else if (cur->as_ArithmeticOp() != NULL || cur->as_LogicOp() != NULL || cur->as_ShiftOp() != NULL) {
+      assert(cur->as_Op2() != NULL, "must be Op2");
+      Op2* op2 = (Op2*)cur;
+      cur_invariant = !op2->can_trap() && is_invariant(op2->x()) && is_invariant(op2->y());
+    } else if (cur->as_LoadField() != NULL) {
+      LoadField* lf = (LoadField*)cur;
+      // deoptimizes on NullPointerException
+      cur_invariant = !lf->needs_patching() && !lf->field()->is_volatile() && !_short_loop_optimizer->has_field_store(lf->field()->type()->basic_type()) && is_invariant(lf->obj());
+    } else if (cur->as_ArrayLength() != NULL) {
+      ArrayLength *length = cur->as_ArrayLength();
+      cur_invariant = is_invariant(length->array());
+    } else if (cur->as_LoadIndexed() != NULL) {
+      LoadIndexed *li = (LoadIndexed *)cur->as_LoadIndexed();
+      cur_invariant = !_short_loop_optimizer->has_indexed_store(as_BasicType(cur->type())) && is_invariant(li->array()) && is_invariant(li->index());
+    }
+
+    if (cur_invariant) {
+      // perform value numbering and mark instruction as loop-invariant
+      _gvn->substitute(cur);
+
+      if (cur->as_Constant() == NULL) {
+        // ensure that code for non-constant instructions is always generated
+        cur->pin();
+      }
+
+      // remove cur instruction from loop block and append it to block before loop
+      Instruction* next = cur->next();
+      Instruction* in = _insertion_point->next();
+      _insertion_point = _insertion_point->set_next(cur);
+      cur->set_next(in);
+
+      //  Deoptimize on exception
+      cur->set_flag(Instruction::DeoptimizeOnException, true);
+
+      //  Clear exception handlers
+      cur->set_exception_handlers(NULL);
+
+      TRACE_VALUE_NUMBERING(tty->print_cr("Instruction %c%d is loop invariant", cur->type()->tchar(), cur->id()));
+
+      if (cur->state_before() != NULL) {
+        cur->set_state_before(_state->copy());
+      }
+      if (cur->exception_state() != NULL) {
+        cur->set_exception_state(_state->copy());
+      }
+
+      cur = prev->set_next(next);
+
+    } else {
+      prev = cur;
+      cur = cur->next();
+    }
+  }
+}
 
 bool ShortLoopOptimizer::process(BlockBegin* loop_header) {
   TRACE_VALUE_NUMBERING(tty->print_cr("** loop header block"));
@@ -316,6 +447,10 @@
     for (int j = block->number_of_preds() - 1; j >= 0; j--) {
       BlockBegin* pred = block->pred_at(j);
 
+      if (pred->is_set(BlockBegin::osr_entry_flag)) {
+        return false;
+      }
+
       ValueMap* pred_map = value_map_of(pred);
       if (pred_map != NULL) {
         current_map()->kill_map(pred_map);
@@ -336,6 +471,12 @@
     }
   }
 
+  bool optimistic = this->_gvn->compilation()->is_optimistic();
+
+  if (UseLoopInvariantCodeMotion && optimistic) {
+    LoopInvariantCodeMotion code_motion(this, _gvn, loop_header, &_loop_blocks);
+  }
+
   TRACE_VALUE_NUMBERING(tty->print_cr("** loop successfully optimized"));
   return true;
 }
@@ -344,11 +485,11 @@
 GlobalValueNumbering::GlobalValueNumbering(IR* ir)
   : _current_map(NULL)
   , _value_maps(ir->linear_scan_order()->length(), NULL)
+  , _compilation(ir->compilation())
 {
   TRACE_VALUE_NUMBERING(tty->print_cr("****** start of global value numbering"));
 
   ShortLoopOptimizer short_loop_optimizer(this);
-  int subst_count = 0;
 
   BlockList* blocks = ir->linear_scan_order();
   int num_blocks = blocks->length();
@@ -357,6 +498,12 @@
   assert(start_block == ir->start() && start_block->number_of_preds() == 0 && start_block->dominator() == NULL, "must be start block");
   assert(start_block->next()->as_Base() != NULL && start_block->next()->next() == NULL, "start block must not have instructions");
 
+  // method parameters are not linked in instructions list, so process them separateley
+  for_each_state_value(start_block->state(), value,
+     assert(value->as_Local() != NULL, "only method parameters allowed");
+     set_processed(value);
+  );
+
   // initial, empty value map with nesting 0
   set_value_map_of(start_block, new ValueMap());
 
@@ -374,7 +521,7 @@
     // create new value map with increased nesting
     _current_map = new ValueMap(value_map_of(dominator));
 
-    if (num_preds == 1) {
+    if (num_preds == 1 && !block->is_set(BlockBegin::exception_entry_flag)) {
       assert(dominator == block->pred_at(0), "dominator must be equal to predecessor");
       // nothing to do here
 
@@ -403,36 +550,41 @@
       }
     }
 
-    if (block->is_set(BlockBegin::exception_entry_flag)) {
-      current_map()->kill_exception();
-    }
+    // phi functions are not linked in instructions list, so process them separateley
+    for_each_phi_fun(block, phi,
+      set_processed(phi);
+    );
 
     TRACE_VALUE_NUMBERING(tty->print("value map before processing block: "); current_map()->print());
 
     // visit all instructions of this block
     for (Value instr = block->next(); instr != NULL; instr = instr->next()) {
-      assert(!instr->has_subst(), "substitution already set");
-
       // check if instruction kills any values
       instr->visit(this);
-
-      if (instr->hash() != 0) {
-        Value f = current_map()->find_insert(instr);
-        if (f != instr) {
-          assert(!f->has_subst(), "can't have a substitution");
-          instr->set_subst(f);
-          subst_count++;
-        }
-      }
+      // perform actual value numbering
+      substitute(instr);
     }
 
     // remember value map for successors
     set_value_map_of(block, current_map());
   }
 
-  if (subst_count != 0) {
+  if (_has_substitutions) {
     SubstitutionResolver resolver(ir);
   }
 
   TRACE_VALUE_NUMBERING(tty->print("****** end of global value numbering. "); ValueMap::print_statistics());
 }
+
+void GlobalValueNumbering::substitute(Instruction* instr) {
+  assert(!instr->has_subst(), "substitution already set");
+  Value subst = current_map()->find_insert(instr);
+  if (subst != instr) {
+    assert(!subst->has_subst(), "can't have a substitution");
+
+    TRACE_VALUE_NUMBERING(tty->print_cr("substitution for %d set to %d", instr->id(), subst->id()));
+    instr->set_subst(subst);
+    _has_substitutions = true;
+  }
+  set_processed(instr);
+}
--- a/src/share/vm/c1/c1_ValueMap.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_ValueMap.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -206,6 +206,8 @@
   void do_ProfileInvoke  (ProfileInvoke*   x) { /* nothing to do */ };
   void do_RuntimeCall    (RuntimeCall*     x) { /* nothing to do */ };
   void do_MemBar         (MemBar*          x) { /* nothing to do */ };
+  void do_RangeCheckPredicate(RangeCheckPredicate* x) { /* nothing to do */ };
+  void do_Assert         (Assert*          x) { /* nothing to do */ };
 };
 
 
@@ -225,15 +227,22 @@
 
 class GlobalValueNumbering: public ValueNumberingVisitor {
  private:
+  Compilation*  _compilation;     // compilation data
   ValueMap*     _current_map;     // value map of current block
   ValueMapArray _value_maps;      // list of value maps for all blocks
+  ValueSet      _processed_values;  // marker for instructions that were already processed
+  bool          _has_substitutions; // set to true when substitutions must be resolved
 
  public:
   // accessors
+  Compilation*  compilation() const              { return _compilation; }
   ValueMap*     current_map()                    { return _current_map; }
   ValueMap*     value_map_of(BlockBegin* block)  { return _value_maps.at(block->linear_scan_number()); }
   void          set_value_map_of(BlockBegin* block, ValueMap* map)   { assert(value_map_of(block) == NULL, ""); _value_maps.at_put(block->linear_scan_number(), map); }
 
+  bool          is_processed(Value v)            { return _processed_values.contains(v); }
+  void          set_processed(Value v)           { _processed_values.put(v); }
+
   // implementation for abstract methods of ValueNumberingVisitor
   void          kill_memory()                                 { current_map()->kill_memory(); }
   void          kill_field(ciField* field, bool all_offsets)  { current_map()->kill_field(field, all_offsets); }
@@ -241,6 +250,7 @@
 
   // main entry point that performs global value numbering
   GlobalValueNumbering(IR* ir);
+  void          substitute(Instruction* instr);  // substitute instruction if it is contained in current value map
 };
 
 #endif // SHARE_VM_C1_C1_VALUEMAP_HPP
--- a/src/share/vm/c1/c1_globals.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/c1/c1_globals.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -119,6 +119,24 @@
   develop(bool, UseGlobalValueNumbering, true,                              \
           "Use Global Value Numbering (separate phase)")                    \
                                                                             \
+  product(bool, UseLoopInvariantCodeMotion, true,                           \
+          "Simple loop invariant code motion for short loops during GVN")   \
+                                                                            \
+  develop(bool, TracePredicateFailedTraps, false,                           \
+          "trace runtime traps caused by predicate failure")                \
+                                                                            \
+  develop(bool, StressLoopInvariantCodeMotion, false,                       \
+          "stress loop invariant code motion")                              \
+                                                                            \
+  develop(bool, TraceRangeCheckElimination, false,                          \
+          "Trace Range Check Elimination")                                  \
+                                                                            \
+  develop(bool, AssertRangeCheckElimination, false,                         \
+          "Assert Range Check Elimination")                                 \
+                                                                            \
+  develop(bool, StressRangeCheckElimination, false,                         \
+          "stress Range Check Elimination")                                 \
+                                                                            \
   develop(bool, PrintValueNumbering, false,                                 \
           "Print Value Numbering")                                          \
                                                                             \
--- a/src/share/vm/ci/ciEnv.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/ci/ciEnv.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -802,6 +802,7 @@
   // require checks to make sure the expected type was found.  Given that this
   // only occurs for clone() the more extensive fix seems like overkill so
   // instead we simply smear the array type into Object.
+  guarantee(method_holder != NULL, "no method holder");
   if (method_holder->is_instance_klass()) {
     return method_holder->as_instance_klass();
   } else if (method_holder->is_array_klass()) {
--- a/src/share/vm/ci/ciMethod.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/ci/ciMethod.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -790,6 +790,17 @@
   return count;
 }
 
+
+// ------------------------------------------------------------------
+// ciMethod::is_special_get_caller_class_method
+//
+bool ciMethod::is_ignored_by_security_stack_walk() const {
+  check_is_loaded();
+  VM_ENTRY_MARK;
+  return get_Method()->is_ignored_by_security_stack_walk();
+}
+
+
 // ------------------------------------------------------------------
 // invokedynamic support
 
--- a/src/share/vm/ci/ciMethod.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/ci/ciMethod.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -166,8 +166,9 @@
   // Code size for inlining decisions.
   int code_size_for_inlining();
 
-  bool force_inline() { return get_Method()->force_inline(); }
-  bool dont_inline()  { return get_Method()->dont_inline();  }
+  bool caller_sensitive() { return get_Method()->caller_sensitive(); }
+  bool force_inline()     { return get_Method()->force_inline();     }
+  bool dont_inline()      { return get_Method()->dont_inline();      }
 
   int comp_level();
   int highest_osr_comp_level();
@@ -264,6 +265,9 @@
   int instructions_size();
   int scale_count(int count, float prof_factor = 1.);  // make MDO count commensurate with IIC
 
+  // Stack walking support
+  bool is_ignored_by_security_stack_walk() const;
+
   // JSR 292 support
   bool is_method_handle_intrinsic()  const;
   bool is_compiled_lambda_form() const;
--- a/src/share/vm/classfile/classFileParser.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/classFileParser.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1735,9 +1735,14 @@
                                                                 Symbol* name) {
   vmSymbols::SID sid = vmSymbols::find_sid(name);
   // Privileged code can use all annotations.  Other code silently drops some.
-  bool privileged = loader_data->is_the_null_class_loader_data() ||
-                    loader_data->is_anonymous();
+  const bool privileged = loader_data->is_the_null_class_loader_data() ||
+                          loader_data->is_ext_class_loader_data() ||
+                          loader_data->is_anonymous();
   switch (sid) {
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_reflect_CallerSensitive_signature):
+    if (_location != _in_method)  break;  // only allow for methods
+    if (!privileged)              break;  // only allow in privileged code
+    return _method_CallerSensitive;
   case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature):
     if (_location != _in_method)  break;  // only allow for methods
     if (!privileged)              break;  // only allow in privileged code
@@ -1775,6 +1780,8 @@
 }
 
 void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) {
+  if (has_annotation(_method_CallerSensitive))
+    m->set_caller_sensitive(true);
   if (has_annotation(_method_ForceInline))
     m->set_force_inline(true);
   if (has_annotation(_method_DontInline))
@@ -2196,8 +2203,7 @@
                                       true,     // is LVTT
                                       CHECK_(nullHandle));
           lvtt_cnt++;
-        } else if (UseSplitVerifier &&
-                   _major_version >= Verifier::STACKMAP_ATTRIBUTE_MAJOR_VERSION &&
+        } else if (_major_version >= Verifier::STACKMAP_ATTRIBUTE_MAJOR_VERSION &&
                    _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_stack_map_table()) {
           // Stack map is only needed by the new verifier in JDK1.5.
           if (parsed_stackmap_attribute) {
--- a/src/share/vm/classfile/classFileParser.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/classFileParser.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -119,6 +119,7 @@
     enum Location { _in_field, _in_method, _in_class };
     enum ID {
       _unknown = 0,
+      _method_CallerSensitive,
       _method_ForceInline,
       _method_DontInline,
       _method_LambdaForm_Compiled,
--- a/src/share/vm/classfile/classLoaderData.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/classLoaderData.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -105,6 +105,7 @@
 void ClassLoaderData::classes_do(KlassClosure* klass_closure) {
   for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
     klass_closure->do_klass(k);
+    assert(k != k->next_link(), "no loops!");
   }
 }
 
@@ -113,6 +114,7 @@
     if (k->oop_is_instance()) {
       f(InstanceKlass::cast(k));
     }
+    assert(k != k->next_link(), "no loops!");
   }
 }
 
@@ -258,6 +260,7 @@
       return;
     }
     prev = k;
+    assert(k != k->next_link(), "no loops!");
   }
   ShouldNotReachHere();   // should have found this class!!
 }
@@ -318,6 +321,13 @@
   }
 }
 
+/**
+ * Returns true if this class loader data is for the extension class loader.
+ */
+bool ClassLoaderData::is_ext_class_loader_data() const {
+  return SystemDictionary::is_ext_class_loader(class_loader());
+}
+
 Metaspace* ClassLoaderData::metaspace_non_null() {
   assert(!DumpSharedSpaces, "wrong metaspace!");
   // If the metaspace has not been allocated, create a new one.  Might want
@@ -439,6 +449,7 @@
     while (k != NULL) {
       out->print_cr("klass "PTR_FORMAT", %s, CT: %d, MUT: %d", k, k->name()->as_C_string(),
           k->has_modified_oops(), k->has_accumulated_modified_oops());
+      assert(k != k->next_link(), "no loops!");
       k = k->next_link();
     }
   }
@@ -465,6 +476,7 @@
   for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
     guarantee(k->class_loader_data() == this, "Must be the same");
     k->verify();
+    assert(k != k->next_link(), "no loops!");
   }
 }
 
--- a/src/share/vm/classfile/classLoaderData.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/classLoaderData.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -191,6 +191,7 @@
   bool is_the_null_class_loader_data() const {
     return this == _the_null_class_loader_data;
   }
+  bool is_ext_class_loader_data() const;
 
   // The Metaspace is created lazily so may be NULL.  This
   // method will allocate a Metaspace if needed.
--- a/src/share/vm/classfile/defaultMethods.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/defaultMethods.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -348,7 +348,7 @@
 
   void disqualify_method(Method* method) {
     int* index = _member_index.get(method);
-    assert(index != NULL && *index >= 0 && *index < _members.length(), "bad index");
+    guarantee(index != NULL && *index >= 0 && *index < _members.length(), "bad index");
     _members.at(*index).second = DISQUALIFIED;
   }
 
--- a/src/share/vm/classfile/javaClasses.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/javaClasses.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1050,15 +1050,16 @@
 
   // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
   enum {
-    MN_IS_METHOD           = 0x00010000, // method (not constructor)
-    MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
-    MN_IS_FIELD            = 0x00040000, // field
-    MN_IS_TYPE             = 0x00080000, // nested type
+    MN_IS_METHOD            = 0x00010000, // method (not constructor)
+    MN_IS_CONSTRUCTOR       = 0x00020000, // constructor
+    MN_IS_FIELD             = 0x00040000, // field
+    MN_IS_TYPE              = 0x00080000, // nested type
+    MN_CALLER_SENSITIVE     = 0x00100000, // @CallerSensitive annotation detected
     MN_REFERENCE_KIND_SHIFT = 24, // refKind
-    MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+    MN_REFERENCE_KIND_MASK  = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
     // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
-    MN_SEARCH_SUPERCLASSES = 0x00100000, // walk super classes
-    MN_SEARCH_INTERFACES   = 0x00200000  // walk implemented interfaces
+    MN_SEARCH_SUPERCLASSES  = 0x00100000, // walk super classes
+    MN_SEARCH_INTERFACES    = 0x00200000  // walk implemented interfaces
   };
 
   // Accessors for code generation:
--- a/src/share/vm/classfile/symbolTable.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/symbolTable.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -677,9 +677,14 @@
   ResourceMark rm;
   int length;
   jchar* chars = symbol->as_unicode(length);
-  unsigned int hashValue = hash_string(chars, length);
-  int index = the_table()->hash_to_index(hashValue);
-  return the_table()->lookup(index, chars, length, hashValue);
+  return lookup(chars, length);
+}
+
+
+oop StringTable::lookup(jchar* name, int len) {
+  unsigned int hash = hash_string(name, len);
+  int index = the_table()->hash_to_index(hash);
+  return the_table()->lookup(index, name, len, hash);
 }
 
 
--- a/src/share/vm/classfile/symbolTable.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/symbolTable.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -287,6 +287,7 @@
 
   // Probing
   static oop lookup(Symbol* symbol);
+  static oop lookup(jchar* chars, int length);
 
   // Interning
   static oop intern(Symbol* symbol, TRAPS);
--- a/src/share/vm/classfile/systemDictionary.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/systemDictionary.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -146,6 +146,17 @@
    }
    return false;
 }
+
+/**
+ * Returns true if the passed class loader is the extension class loader.
+ */
+bool SystemDictionary::is_ext_class_loader(Handle class_loader) {
+  if (class_loader.is_null()) {
+    return false;
+  }
+  return (class_loader->klass()->name() == vmSymbols::sun_misc_Launcher_ExtClassLoader());
+}
+
 // ----------------------------------------------------------------------------
 // Resolving of classes
 
@@ -804,6 +815,47 @@
       }
     } // load_instance_class loop
 
+    if (HAS_PENDING_EXCEPTION) {
+      // An exception, such as OOM could have happened at various places inside
+      // load_instance_class. We might have partially initialized a shared class
+      // and need to clean it up.
+      if (class_loader.is_null()) {
+        // In some cases k may be null. Let's find the shared class again.
+        instanceKlassHandle ik(THREAD, find_shared_class(name));
+        if (ik.not_null()) {
+          if (ik->class_loader_data() == NULL) {
+            // We didn't go as far as Klass::restore_unshareable_info(),
+            // so nothing to clean up.
+          } else {
+            Klass *kk;
+            {
+              MutexLocker mu(SystemDictionary_lock, THREAD);
+              kk = find_class(name, ik->class_loader_data());
+            }
+            if (kk != NULL) {
+              // No clean up is needed if the shared class has been entered
+              // into system dictionary, as load_shared_class() won't be called
+              // again.
+            } else {
+              // This must be done outside of the SystemDictionary_lock to
+              // avoid deadlock.
+              //
+              // Note that Klass::restore_unshareable_info (called via
+              // load_instance_class above) is also called outside
+              // of SystemDictionary_lock. Other threads are blocked from
+              // loading this class because they are waiting on the
+              // SystemDictionary_lock until this thread removes
+              // the placeholder below.
+              //
+              // This need to be re-thought when parallel-capable non-boot
+              // classloaders are supported by CDS (today they're not).
+              clean_up_shared_class(ik, class_loader, THREAD);
+            }
+          }
+        }
+      }
+    }
+
     if (load_instance_added == true) {
       // clean up placeholder entries for LOAD_INSTANCE success or error
       // This brackets the SystemDictionary updates for both defining
@@ -1140,11 +1192,6 @@
   return load_shared_class(ik, class_loader, THREAD);
 }
 
-// Note well!  Changes to this method may affect oop access order
-// in the shared archive.  Please take care to not make changes that
-// adversely affect cold start time by changing the oop access order
-// that is specified in dump.cpp MarkAndMoveOrderedReadOnly and
-// MarkAndMoveOrderedReadWrite closures.
 instanceKlassHandle SystemDictionary::load_shared_class(
                  instanceKlassHandle ik, Handle class_loader, TRAPS) {
   assert(class_loader.is_null(), "non-null classloader for shared class?");
@@ -1205,6 +1252,19 @@
   return ik;
 }
 
+void SystemDictionary::clean_up_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS) {
+  // Updating methods must be done under a lock so multiple
+  // threads don't update these in parallel
+  // Shared classes are all currently loaded by the bootstrap
+  // classloader, so this will never cause a deadlock on
+  // a custom class loader lock.
+  {
+    Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
+    check_loader_lock_contention(lockObject, THREAD);
+    ObjectLocker ol(lockObject, THREAD, true);
+    ik->remove_unshareable_info();
+  }
+}
 
 instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
   instanceKlassHandle nh = instanceKlassHandle(); // null Handle
@@ -2151,10 +2211,9 @@
 // Make sure all class components (including arrays) in the given
 // signature will be resolved to the same class in both loaders.
 // Returns the name of the type that failed a loader constraint check, or
-// NULL if no constraint failed. The returned C string needs cleaning up
-// with a ResourceMark in the caller.  No exception except OOME is thrown.
+// NULL if no constraint failed.  No exception except OOME is thrown.
 // Arrays are not added to the loader constraint table, their elements are.
-char* SystemDictionary::check_signature_loaders(Symbol* signature,
+Symbol* SystemDictionary::check_signature_loaders(Symbol* signature,
                                                Handle loader1, Handle loader2,
                                                bool is_method, TRAPS)  {
   // Nothing to do if loaders are the same.
@@ -2162,14 +2221,12 @@
     return NULL;
   }
 
-  ResourceMark rm(THREAD);
   SignatureStream sig_strm(signature, is_method);
   while (!sig_strm.is_done()) {
     if (sig_strm.is_object()) {
-      Symbol* s = sig_strm.as_symbol(CHECK_NULL);
-      Symbol*  sig  = s;
+      Symbol* sig = sig_strm.as_symbol(CHECK_NULL);
       if (!add_loader_constraint(sig, loader1, loader2, THREAD)) {
-        return sig->as_C_string();
+        return sig;
       }
     }
     sig_strm.next();
--- a/src/share/vm/classfile/systemDictionary.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/systemDictionary.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -106,6 +106,7 @@
   do_klass(ThreadDeath_klass,                           java_lang_ThreadDeath,                     Pre                 ) \
   do_klass(Exception_klass,                             java_lang_Exception,                       Pre                 ) \
   do_klass(RuntimeException_klass,                      java_lang_RuntimeException,                Pre                 ) \
+  do_klass(SecurityManager_klass,                       java_lang_SecurityManager,                 Pre                 ) \
   do_klass(ProtectionDomain_klass,                      java_security_ProtectionDomain,            Pre                 ) \
   do_klass(AccessControlContext_klass,                  java_security_AccessControlContext,        Pre                 ) \
   do_klass(ClassNotFoundException_klass,                java_lang_ClassNotFoundException,          Pre                 ) \
@@ -138,13 +139,14 @@
   /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */                              \
   /* Universe::is_gte_jdk14x_version() is not set up by this point. */                                                   \
   /* It's okay if this turns out to be NULL in non-1.4 JDKs. */                                                          \
-  do_klass(lambda_MagicLambdaImpl_klass,                java_lang_invoke_MagicLambdaImpl, Opt ) \
+  do_klass(lambda_MagicLambdaImpl_klass,                java_lang_invoke_MagicLambdaImpl,          Opt                 ) \
   do_klass(reflect_MagicAccessorImpl_klass,             sun_reflect_MagicAccessorImpl,             Opt                 ) \
   do_klass(reflect_MethodAccessorImpl_klass,            sun_reflect_MethodAccessorImpl,            Opt_Only_JDK14NewRef) \
   do_klass(reflect_ConstructorAccessorImpl_klass,       sun_reflect_ConstructorAccessorImpl,       Opt_Only_JDK14NewRef) \
   do_klass(reflect_DelegatingClassLoader_klass,         sun_reflect_DelegatingClassLoader,         Opt                 ) \
   do_klass(reflect_ConstantPool_klass,                  sun_reflect_ConstantPool,                  Opt_Only_JDK15      ) \
   do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15      ) \
+  do_klass(reflect_CallerSensitive_klass,               sun_reflect_CallerSensitive,               Opt                 ) \
                                                                                                                          \
   /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */                                            \
   do_klass(MethodHandle_klass,                          java_lang_invoke_MethodHandle,             Pre_JSR292          ) \
@@ -483,8 +485,8 @@
   // Check class loader constraints
   static bool add_loader_constraint(Symbol* name, Handle loader1,
                                     Handle loader2, TRAPS);
-  static char* check_signature_loaders(Symbol* signature, Handle loader1,
-                                       Handle loader2, bool is_method, TRAPS);
+  static Symbol* check_signature_loaders(Symbol* signature, Handle loader1,
+                                         Handle loader2, bool is_method, TRAPS);
 
   // JSR 292
   // find a java.lang.invoke.MethodHandle.invoke* method for a given signature
@@ -621,18 +623,22 @@
                                                Handle class_loader, TRAPS);
   static instanceKlassHandle load_shared_class(instanceKlassHandle ik,
                                                Handle class_loader, TRAPS);
+  static void clean_up_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS);
   static instanceKlassHandle load_instance_class(Symbol* class_name, Handle class_loader, TRAPS);
   static Handle compute_loader_lock_object(Handle class_loader, TRAPS);
   static void check_loader_lock_contention(Handle loader_lock, TRAPS);
   static bool is_parallelCapable(Handle class_loader);
   static bool is_parallelDefine(Handle class_loader);
 
+public:
+  static bool is_ext_class_loader(Handle class_loader);
+
+private:
   static Klass* find_shared_class(Symbol* class_name);
 
   // Setup link to hierarchy
   static void add_to_hierarchy(instanceKlassHandle k, TRAPS);
 
-private:
   // We pass in the hashtable index so we can calculate it outside of
   // the SystemDictionary_lock.
 
--- a/src/share/vm/classfile/verifier.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/verifier.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -61,8 +61,9 @@
 # include "bytes_ppc.hpp"
 #endif
 
-#define NOFAILOVER_MAJOR_VERSION                  51
-#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION  52
+#define NOFAILOVER_MAJOR_VERSION                       51
+#define NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION  51
+#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION       52
 
 // Access to external entry for VerifyClassCodes - old byte code verifier
 
@@ -127,8 +128,7 @@
     if (TraceClassInitialization) {
       tty->print_cr("Start class verification for: %s", klassName);
     }
-    if (UseSplitVerifier &&
-        klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
+    if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
       ClassVerifier split_verifier(klass, THREAD);
       split_verifier.verify_class(THREAD);
       exception_name = split_verifier.result();
@@ -2027,16 +2027,19 @@
   address bcp = bcs->bcp();
   address aligned_bcp = (address) round_to((intptr_t)(bcp + 1), jintSize);
 
-  // 4639449 & 4647081: padding bytes must be 0
-  u2 padding_offset = 1;
-  while ((bcp + padding_offset) < aligned_bcp) {
-    if(*(bcp + padding_offset) != 0) {
-      verify_error(ErrorContext::bad_code(bci),
-                   "Nonzero padding byte in lookswitch or tableswitch");
-      return;
+  if (_klass->major_version() < NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION) {
+    // 4639449 & 4647081: padding bytes must be 0
+    u2 padding_offset = 1;
+    while ((bcp + padding_offset) < aligned_bcp) {
+      if(*(bcp + padding_offset) != 0) {
+        verify_error(ErrorContext::bad_code(bci),
+                     "Nonzero padding byte in lookswitch or tableswitch");
+        return;
+      }
+      padding_offset++;
     }
-    padding_offset++;
   }
+
   int default_offset = (int) Bytes::get_Java_u4(aligned_bcp);
   int keys, delta;
   current_frame->pop_stack(
--- a/src/share/vm/classfile/vmSymbols.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -91,6 +91,7 @@
   template(java_lang_StringBuffer,                    "java/lang/StringBuffer")                   \
   template(java_lang_StringBuilder,                   "java/lang/StringBuilder")                  \
   template(java_lang_CharSequence,                    "java/lang/CharSequence")                   \
+  template(java_lang_SecurityManager,                 "java/lang/SecurityManager")                \
   template(java_security_AccessControlContext,        "java/security/AccessControlContext")       \
   template(java_security_ProtectionDomain,            "java/security/ProtectionDomain")           \
   template(java_io_OutputStream,                      "java/io/OutputStream")                     \
@@ -211,6 +212,8 @@
   template(sun_reflect_SerializationConstructorAccessorImpl, "sun/reflect/SerializationConstructorAccessorImpl") \
   template(sun_reflect_DelegatingClassLoader,         "sun/reflect/DelegatingClassLoader")        \
   template(sun_reflect_Reflection,                    "sun/reflect/Reflection")                   \
+  template(sun_reflect_CallerSensitive,               "sun/reflect/CallerSensitive")              \
+  template(sun_reflect_CallerSensitive_signature,     "Lsun/reflect/CallerSensitive;")            \
   template(checkedExceptions_name,                    "checkedExceptions")                        \
   template(clazz_name,                                "clazz")                                    \
   template(exceptionTypes_name,                       "exceptionTypes")                           \
@@ -343,6 +346,7 @@
   template(contextClassLoader_name,                   "contextClassLoader")                       \
   template(inheritedAccessControlContext_name,        "inheritedAccessControlContext")            \
   template(isPrivileged_name,                         "isPrivileged")                             \
+  template(getClassContext_name,                      "getClassContext")                          \
   template(wait_name,                                 "wait")                                     \
   template(checkPackageAccess_name,                   "checkPackageAccess")                       \
   template(stackSize_name,                            "stackSize")                                \
@@ -463,6 +467,7 @@
   template(void_classloader_signature,                "()Ljava/lang/ClassLoader;")                                \
   template(void_object_signature,                     "()Ljava/lang/Object;")                                     \
   template(void_class_signature,                      "()Ljava/lang/Class;")                                      \
+  template(void_class_array_signature,                "()[Ljava/lang/Class;")                                     \
   template(void_string_signature,                     "()Ljava/lang/String;")                                     \
   template(object_array_object_signature,             "([Ljava/lang/Object;)Ljava/lang/Object;")                  \
   template(object_object_array_object_signature,      "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")\
@@ -705,9 +710,8 @@
   do_intrinsic(_getLength,                java_lang_reflect_Array, getLength_name, object_int_signature,         F_SN)  \
    do_name(     getLength_name,                                   "getLength")                                          \
                                                                                                                         \
-  do_intrinsic(_getCallerClass,           sun_reflect_Reflection, getCallerClass_name, getCallerClass_signature, F_SN)  \
+  do_intrinsic(_getCallerClass,           sun_reflect_Reflection, getCallerClass_name, void_class_signature,     F_SN)  \
    do_name(     getCallerClass_name,                             "getCallerClass")                                      \
-   do_signature(getCallerClass_signature,                        "(I)Ljava/lang/Class;")                                \
                                                                                                                         \
   do_intrinsic(_newArray,                 java_lang_reflect_Array, newArray_name, newArray_signature,            F_SN)  \
    do_name(     newArray_name,                                    "newArray")                                           \
--- a/src/share/vm/code/codeBlob.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/code/codeBlob.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -186,7 +186,7 @@
     FREE_C_HEAP_ARRAY(unsigned char, _oop_maps, mtCode);
     _oop_maps = NULL;
   }
-  _comments.free();
+  _strings.free();
 }
 
 
--- a/src/share/vm/code/codeBlob.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/code/codeBlob.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -66,7 +66,7 @@
   int        _data_offset;                       // offset to where data region begins
   int        _frame_size;                        // size of stack frame
   OopMapSet* _oop_maps;                          // OopMap for this CodeBlob
-  CodeComments _comments;
+  CodeStrings _strings;
 
  public:
   // Returns the space needed for CodeBlob
@@ -186,12 +186,12 @@
   // Print the comment associated with offset on stream, if there is one
   virtual void print_block_comment(outputStream* stream, address block_begin) const {
     intptr_t offset = (intptr_t)(block_begin - code_begin());
-    _comments.print_block_comment(stream, offset);
+    _strings.print_block_comment(stream, offset);
   }
 
   // Transfer ownership of comments to this CodeBlob
-  void set_comments(CodeComments& comments) {
-    _comments.assign(comments);
+  void set_strings(CodeStrings& strings) {
+    _strings.assign(strings);
   }
 };
 
--- a/src/share/vm/code/codeCache.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/code/codeCache.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -156,6 +156,11 @@
   static address  low_bound()                    { return (address) _heap->low_boundary(); }
   static address  high_bound()                   { return (address) _heap->high_boundary(); }
 
+  static bool has_space(int size) {
+    // Always leave some room in the CodeCache for I2C/C2I adapters
+    return largest_free_block() > (CodeCacheMinimumFreeSpace + size);
+  }
+
   // Profiling
   static address first_address();                // first address used for CodeBlobs
   static address last_address();                 // last  address used for CodeBlobs
--- a/src/share/vm/code/compiledIC.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/code/compiledIC.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -552,7 +552,7 @@
 
 void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) {
   address stub=find_stub();
-  assert(stub!=NULL, "stub not found");
+  guarantee(stub != NULL, "stub not found");
 
   if (TraceICs) {
     ResourceMark rm;
--- a/src/share/vm/code/icBuffer.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/code/icBuffer.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -50,7 +50,7 @@
   friend class ICStubInterface;
   // This will be called only by ICStubInterface
   void    initialize(int size,
-                     CodeComments comments)      { _size = size; _ic_site = NULL; }
+                     CodeStrings strings)        { _size = size; _ic_site = NULL; }
   void    finalize(); // called when a method is removed
 
   // General info
--- a/src/share/vm/code/nmethod.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/code/nmethod.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -486,7 +486,6 @@
 #endif // def HAVE_DTRACE_H
 }
 
-
 nmethod* nmethod::new_native_nmethod(methodHandle method,
   int compile_id,
   CodeBuffer *code_buffer,
@@ -502,17 +501,19 @@
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     int native_nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
-    CodeOffsets offsets;
-    offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
-    offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
-    nm = new (native_nmethod_size)
-      nmethod(method(), native_nmethod_size, compile_id, &offsets,
-              code_buffer, frame_size,
-              basic_lock_owner_sp_offset, basic_lock_sp_offset,
-              oop_maps);
-    NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_native_nmethod(nm));
-    if (PrintAssembly && nm != NULL)
-      Disassembler::decode(nm);
+    if (CodeCache::has_space(native_nmethod_size)) {
+      CodeOffsets offsets;
+      offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
+      offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
+      nm = new (native_nmethod_size) nmethod(method(), native_nmethod_size,
+                                             compile_id, &offsets,
+                                             code_buffer, frame_size,
+                                             basic_lock_owner_sp_offset,
+                                             basic_lock_sp_offset, oop_maps);
+      NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_native_nmethod(nm));
+      if (PrintAssembly && nm != NULL)
+        Disassembler::decode(nm);
+    }
   }
   // verify nmethod
   debug_only(if (nm) nm->verify();) // might block
@@ -537,16 +538,19 @@
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     int nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
-    CodeOffsets offsets;
-    offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
-    offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset);
-    offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
+    if (CodeCache::has_space(nmethod_size)) {
+      CodeOffsets offsets;
+      offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
+      offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset);
+      offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
 
-    nm = new (nmethod_size) nmethod(method(), nmethod_size, &offsets, code_buffer, frame_size);
+      nm = new (nmethod_size) nmethod(method(), nmethod_size,
+                                      &offsets, code_buffer, frame_size);
 
-    NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_nmethod(nm));
-    if (PrintAssembly && nm != NULL)
-      Disassembler::decode(nm);
+      NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_nmethod(nm));
+      if (PrintAssembly && nm != NULL)
+        Disassembler::decode(nm);
+    }
   }
   // verify nmethod
   debug_only(if (nm) nm->verify();) // might block
@@ -587,7 +591,8 @@
       + round_to(handler_table->size_in_bytes(), oopSize)
       + round_to(nul_chk_table->size_in_bytes(), oopSize)
       + round_to(debug_info->data_size()       , oopSize);
-    nm = new (nmethod_size)
+    if (CodeCache::has_space(nmethod_size)) {
+      nm = new (nmethod_size)
       nmethod(method(), nmethod_size, compile_id, entry_bci, offsets,
               orig_pc_offset, debug_info, dependencies, code_buffer, frame_size,
               oop_maps,
@@ -595,6 +600,7 @@
               nul_chk_table,
               compiler,
               comp_level);
+    }
     if (nm != NULL) {
       // To make dependency checking during class loading fast, record
       // the nmethod dependencies in the classes it is dependent on.
@@ -793,9 +799,9 @@
 #endif // def HAVE_DTRACE_H
 
 void* nmethod::operator new(size_t size, int nmethod_size) {
-  // Always leave some room in the CodeCache for I2C/C2I adapters
-  if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) return NULL;
-  return CodeCache::allocate(nmethod_size);
+  void*  alloc = CodeCache::allocate(nmethod_size);
+  guarantee(alloc != NULL, "CodeCache should have enough space");
+  return alloc;
 }
 
 
--- a/src/share/vm/code/stubs.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/code/stubs.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -101,8 +101,8 @@
 
 Stub* StubQueue::request_committed(int code_size) {
   Stub* s = request(code_size);
-  CodeComments comments;
-  if (s != NULL) commit(code_size, comments);
+  CodeStrings strings;
+  if (s != NULL) commit(code_size, strings);
   return s;
 }
 
@@ -119,8 +119,8 @@
       assert(_buffer_limit == _buffer_size, "buffer must be fully usable");
       if (_queue_end + requested_size <= _buffer_size) {
         // code fits in at the end => nothing to do
-        CodeComments comments;
-        stub_initialize(s, requested_size, comments);
+        CodeStrings strings;
+        stub_initialize(s, requested_size, strings);
         return s;
       } else {
         // stub doesn't fit in at the queue end
@@ -137,8 +137,8 @@
     // Queue: |XXX|.......|XXXXXXX|.......|
     //        ^0  ^end    ^begin  ^limit  ^size
     s = current_stub();
-    CodeComments comments;
-    stub_initialize(s, requested_size, comments);
+    CodeStrings strings;
+    stub_initialize(s, requested_size, strings);
     return s;
   }
   // Not enough space left
@@ -147,12 +147,12 @@
 }
 
 
-void StubQueue::commit(int committed_code_size, CodeComments& comments) {
+void StubQueue::commit(int committed_code_size, CodeStrings& strings) {
   assert(committed_code_size > 0, "committed_code_size must be > 0");
   int committed_size = round_to(stub_code_size_to_size(committed_code_size), CodeEntryAlignment);
   Stub* s = current_stub();
   assert(committed_size <= stub_size(s), "committed size must not exceed requested size");
-  stub_initialize(s, committed_size, comments);
+  stub_initialize(s, committed_size, strings);
   _queue_end += committed_size;
   _number_of_stubs++;
   if (_mutex != NULL) _mutex->unlock();
--- a/src/share/vm/code/stubs.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/code/stubs.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -73,7 +73,7 @@
  public:
   // Initialization/finalization
   void    initialize(int size,
-                     CodeComments& comments)     { ShouldNotCallThis(); }                // called to initialize/specify the stub's size
+                     CodeStrings& strings)       { ShouldNotCallThis(); }                // called to initialize/specify the stub's size
   void    finalize()                             { ShouldNotCallThis(); }                // called before the stub is deallocated
 
   // General info/converters
@@ -107,7 +107,7 @@
  public:
   // Initialization/finalization
   virtual void    initialize(Stub* self, int size,
-                             CodeComments& comments)       = 0; // called after creation (called twice if allocated via (request, commit))
+                             CodeStrings& strings)         = 0; // called after creation (called twice if allocated via (request, commit))
   virtual void    finalize(Stub* self)                     = 0; // called before deallocation
 
   // General info/converters
@@ -136,7 +136,7 @@
    public:                                                 \
     /* Initialization/finalization */                      \
     virtual void    initialize(Stub* self, int size,       \
-                               CodeComments& comments)     { cast(self)->initialize(size, comments); } \
+                               CodeStrings& strings)       { cast(self)->initialize(size, strings); } \
     virtual void    finalize(Stub* self)                   { cast(self)->finalize(); }             \
                                                            \
     /* General info */                                     \
@@ -176,7 +176,7 @@
 
   // Stub functionality accessed via interface
   void  stub_initialize(Stub* s, int size,
-                        CodeComments& comments)  { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, comments); }
+                        CodeStrings& strings)    { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, strings); }
   void  stub_finalize(Stub* s)                   { _stub_interface->finalize(s); }
   int   stub_size(Stub* s) const                 { return _stub_interface->size(s); }
   bool  stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); }
@@ -206,7 +206,7 @@
   Stub* request_committed(int code_size);        // request a stub that provides exactly code_size space for code
   Stub* request(int requested_code_size);        // request a stub with a (maximum) code space - locks the queue
   void  commit (int committed_code_size,
-                CodeComments& comments);         // commit the previously requested stub - unlocks the queue
+                CodeStrings& strings);           // commit the previously requested stub - unlocks the queue
 
   // Stub deallocation
   void  remove_first();                          // remove the first stub in the queue
--- a/src/share/vm/compiler/compileBroker.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/compiler/compileBroker.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -65,9 +65,8 @@
 HS_DTRACE_PROBE_DECL9(hotspot, method__compile__end,
   char*, intptr_t, char*, intptr_t, char*, intptr_t, char*, intptr_t, bool);
 
-#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method)              \
+#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method, comp_name)   \
   {                                                                      \
-    char* comp_name = (char*)(compiler)->name();                         \
     Symbol* klass_name = (method)->klass_name();                         \
     Symbol* name = (method)->name();                                     \
     Symbol* signature = (method)->signature();                           \
@@ -78,9 +77,9 @@
       signature->bytes(), signature->utf8_length());                     \
   }
 
-#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, success)       \
+#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method,                \
+                                        comp_name, success)              \
   {                                                                      \
-    char* comp_name = (char*)(compiler)->name();                         \
     Symbol* klass_name = (method)->klass_name();                         \
     Symbol* name = (method)->name();                                     \
     Symbol* signature = (method)->signature();                           \
@@ -93,22 +92,21 @@
 
 #else /* USDT2 */
 
-#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method)              \
+#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method, comp_name)   \
   {                                                                      \
-    char* comp_name = (char*)(compiler)->name();                         \
     Symbol* klass_name = (method)->klass_name();                         \
     Symbol* name = (method)->name();                                     \
     Symbol* signature = (method)->signature();                           \
-    HOTSPOT_METHOD_COMPILE_BEGIN(                                       \
+    HOTSPOT_METHOD_COMPILE_BEGIN(                                        \
       comp_name, strlen(comp_name),                                      \
-      (char *) klass_name->bytes(), klass_name->utf8_length(),          \
+      (char *) klass_name->bytes(), klass_name->utf8_length(),           \
       (char *) name->bytes(), name->utf8_length(),                       \
       (char *) signature->bytes(), signature->utf8_length());            \
   }
 
-#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, success)       \
+#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method,                \
+                                        comp_name, success)              \
   {                                                                      \
-    char* comp_name = (char*)(compiler)->name();                         \
     Symbol* klass_name = (method)->klass_name();                         \
     Symbol* name = (method)->name();                                     \
     Symbol* signature = (method)->signature();                           \
@@ -122,8 +120,8 @@
 
 #else //  ndef DTRACE_ENABLED
 
-#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method)
-#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, success)
+#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method, comp_name)
+#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, comp_name, success)
 
 #endif // ndef DTRACE_ENABLED
 
@@ -359,7 +357,7 @@
 //
 void CompileTask::print_line_on_error(outputStream* st, char* buf, int buflen) {
   // print compiler name
-  st->print("%s:", CompileBroker::compiler(comp_level())->name());
+  st->print("%s:", CompileBroker::compiler_name(comp_level()));
   print_compilation(st);
 }
 
@@ -368,7 +366,7 @@
 void CompileTask::print_line() {
   ttyLocker ttyl;  // keep the following output all in one block
   // print compiler name if requested
-  if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler(comp_level())->name());
+  if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler_name(comp_level()));
   print_compilation();
 }
 
@@ -1217,8 +1215,9 @@
 
   // lock, make sure that the compilation
   // isn't prohibited in a straightforward way.
-
-  if (compiler(comp_level) == NULL || !compiler(comp_level)->can_compile_method(method) || compilation_is_prohibited(method, osr_bci, comp_level)) {
+  AbstractCompiler *comp = CompileBroker::compiler(comp_level);
+  if (comp == NULL || !comp->can_compile_method(method) ||
+      compilation_is_prohibited(method, osr_bci, comp_level)) {
     return NULL;
   }
 
@@ -1255,7 +1254,7 @@
 
   assert(!HAS_PENDING_EXCEPTION, "No exception should be present");
   // some prerequisites that are compiler specific
-  if (compiler(comp_level)->is_c2() || compiler(comp_level)->is_shark()) {
+  if (comp->is_c2() || comp->is_shark()) {
     method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NULL);
     // Resolve all classes seen in the signature of the method
     // we are compiling.
@@ -1372,8 +1371,9 @@
 bool CompileBroker::compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level) {
   bool is_native = method->is_native();
   // Some compilers may not support the compilation of natives.
+  AbstractCompiler *comp = compiler(comp_level);
   if (is_native &&
-      (!CICompileNatives || !compiler(comp_level)->supports_native())) {
+      (!CICompileNatives || comp == NULL || !comp->supports_native())) {
     method->set_not_compilable_quietly(comp_level);
     return true;
   }
@@ -1381,7 +1381,7 @@
   bool is_osr = (osr_bci != standard_entry_bci);
   // Some compilers may not support on stack replacement.
   if (is_osr &&
-      (!CICompileOSR || !compiler(comp_level)->supports_osr())) {
+      (!CICompileOSR || comp == NULL || !comp->supports_osr())) {
     method->set_not_osr_compilable(comp_level);
     return true;
   }
@@ -1753,6 +1753,7 @@
   bool is_osr = (osr_bci != standard_entry_bci);
   bool should_log = (thread->log() != NULL);
   bool should_break = false;
+  int task_level = task->comp_level();
   {
     // create the handle inside it's own block so it can't
     // accidentally be referenced once the thread transitions to
@@ -1766,9 +1767,10 @@
     assert(!method->is_native(), "no longer compile natives");
 
     // Save information about this method in case of failure.
-    set_last_compile(thread, method, is_osr, task->comp_level());
+    set_last_compile(thread, method, is_osr, task_level);
 
-    DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler(task->comp_level()), method);
+    DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler(task_level), method,
+                                      compiler_name(task_level));
   }
 
   // Allocate a new set of JNI handles.
@@ -1805,7 +1807,12 @@
 
     TraceTime t1("compilation", &time);
 
-    compiler(task->comp_level())->compile_method(&ci_env, target, osr_bci);
+    AbstractCompiler *comp = compiler(task_level);
+    if (comp == NULL) {
+      ci_env.record_method_not_compilable("no compiler", !TieredCompilation);
+    } else {
+      comp->compile_method(&ci_env, target, osr_bci);
+    }
 
     if (!ci_env.failing() && task->code() == NULL) {
       //assert(false, "compiler should always document failure");
@@ -1843,7 +1850,8 @@
 
   methodHandle method(thread, task->method());
 
-  DTRACE_METHOD_COMPILE_END_PROBE(compiler(task->comp_level()), method, task->is_success());
+  DTRACE_METHOD_COMPILE_END_PROBE(compiler(task_level), method,
+                                  compiler_name(task_level), task->is_success());
 
   collect_statistics(thread, time, task);
 
@@ -1868,9 +1876,9 @@
     break;
   case ciEnv::MethodCompilable_not_at_tier:
     if (is_osr)
-      method->set_not_osr_compilable_quietly(task->comp_level());
+      method->set_not_osr_compilable_quietly(task_level);
     else
-      method->set_not_compilable_quietly(task->comp_level());
+      method->set_not_compilable_quietly(task_level);
     break;
   }
 
@@ -2128,7 +2136,14 @@
   if (UsePerfData) counters->set_current_method("");
 }
 
-
+const char* CompileBroker::compiler_name(int comp_level) {
+  AbstractCompiler *comp = CompileBroker::compiler(comp_level);
+  if (comp == NULL) {
+    return "no compiler";
+  } else {
+    return (comp->name());
+  }
+}
 
 void CompileBroker::print_times() {
   tty->cr();
@@ -2142,13 +2157,18 @@
                 CompileBroker::_t_standard_compilation.seconds() / CompileBroker::_total_standard_compile_count);
   tty->print_cr("    On stack replacement   : %6.3f s, Average : %2.3f", CompileBroker::_t_osr_compilation.seconds(), CompileBroker::_t_osr_compilation.seconds() / CompileBroker::_total_osr_compile_count);
 
-  if (compiler(CompLevel_simple) != NULL) {
-    compiler(CompLevel_simple)->print_timers();
+  AbstractCompiler *comp = compiler(CompLevel_simple);
+  if (comp != NULL) {
+    comp->print_timers();
   }
-  if (compiler(CompLevel_full_optimization) != NULL) {
-    compiler(CompLevel_full_optimization)->print_timers();
+  comp = compiler(CompLevel_full_optimization);
+  if (comp != NULL) {
+    comp->print_timers();
   }
   tty->cr();
+  tty->print_cr("  Total compiled methods   : %6d methods", CompileBroker::_total_compile_count);
+  tty->print_cr("    Standard compilation   : %6d methods", CompileBroker::_total_standard_compile_count);
+  tty->print_cr("    On stack replacement   : %6d methods", CompileBroker::_total_osr_compile_count);
   int tcb = CompileBroker::_sum_osr_bytes_compiled + CompileBroker::_sum_standard_bytes_compiled;
   tty->print_cr("  Total compiled bytecodes : %6d bytes", tcb);
   tty->print_cr("    Standard compilation   : %6d bytes", CompileBroker::_sum_standard_bytes_compiled);
--- a/src/share/vm/compiler/compileBroker.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/compiler/compileBroker.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -418,6 +418,9 @@
   static void print_last_compile();
 
   static void print_compiler_threads_on(outputStream* st);
+
+  // compiler name for debugging
+  static const char* compiler_name(int comp_level);
 };
 
 #endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP
--- a/src/share/vm/compiler/compileLog.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/compiler/compileLog.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -60,28 +60,6 @@
 }
 
 
-// Advance kind up to a null or space, return this tail.
-// Make sure kind is null-terminated, not space-terminated.
-// Use the buffer if necessary.
-static const char* split_attrs(const char* &kind, char* buffer) {
-  const char* attrs = strchr(kind, ' ');
-  // Tease apart the first word from the rest:
-  if (attrs == NULL) {
-    return "";  // no attrs, no split
-  } else if (kind == buffer) {
-    ((char*) attrs)[-1] = 0;
-    return attrs;
-  } else {
-    // park it in the buffer, so we can put a null on the end
-    assert(!(kind >= buffer && kind < buffer+100), "not obviously in buffer");
-    int klen = attrs - kind;
-    strncpy(buffer, kind, klen);
-    buffer[klen] = 0;
-    kind = buffer;  // return by reference
-    return attrs;
-  }
-}
-
 // see_tag, pop_tag:  Override the default do-nothing methods on xmlStream.
 // These methods provide a hook for managing the the extra context markup.
 void CompileLog::see_tag(const char* tag, bool push) {
--- a/src/share/vm/compiler/compilerOracle.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/compiler/compilerOracle.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -237,13 +237,6 @@
   "help"
 };
 
-static const char * command_name(OracleCommand command) {
-  if (command < OracleFirstCommand || command >= OracleCommandCount) {
-    return "unknown command";
-  }
-  return command_names[command];
-}
-
 class MethodMatcher;
 static MethodMatcher* lists[OracleCommandCount] = { 0, };
 
--- a/src/share/vm/compiler/disassembler.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/compiler/disassembler.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -158,7 +158,7 @@
  private:
   nmethod*      _nm;
   CodeBlob*     _code;
-  CodeComments  _comments;
+  CodeStrings   _strings;
   outputStream* _output;
   address       _start, _end;
 
@@ -198,7 +198,7 @@
   void print_address(address value);
 
  public:
-  decode_env(CodeBlob* code, outputStream* output, CodeComments c = CodeComments());
+  decode_env(CodeBlob* code, outputStream* output, CodeStrings c = CodeStrings());
 
   address decode_instructions(address start, address end);
 
@@ -242,13 +242,13 @@
   const char* options() { return _option_buf; }
 };
 
-decode_env::decode_env(CodeBlob* code, outputStream* output, CodeComments c) {
+decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) {
   memset(this, 0, sizeof(*this));
   _output = output ? output : tty;
   _code = code;
   if (code != NULL && code->is_nmethod())
     _nm = (nmethod*) code;
-  _comments.assign(c);
+  _strings.assign(c);
 
   // by default, output pc but not bytes:
   _print_pc       = true;
@@ -370,7 +370,7 @@
   if (cb != NULL) {
     cb->print_block_comment(st, p);
   }
-  _comments.print_block_comment(st, (intptr_t)(p - _start));
+  _strings.print_block_comment(st, (intptr_t)(p - _start));
   if (_print_pc) {
     st->print("  " PTR_FORMAT ": ", p);
   }
@@ -498,7 +498,7 @@
   env.decode_instructions(cb->code_begin(), cb->code_end());
 }
 
-void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) {
+void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c) {
   if (!load_library())  return;
   decode_env env(CodeCache::find_blob_unsafe(start), st, c);
   env.decode_instructions(start, end);
--- a/src/share/vm/compiler/disassembler.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/compiler/disassembler.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -100,7 +100,7 @@
   }
   static void decode(CodeBlob *cb,               outputStream* st = NULL);
   static void decode(nmethod* nm,                outputStream* st = NULL);
-  static void decode(address begin, address end, outputStream* st = NULL, CodeComments c = CodeComments());
+  static void decode(address begin, address end, outputStream* st = NULL, CodeStrings c = CodeStrings());
 };
 
 #endif // SHARE_VM_COMPILER_DISASSEMBLER_HPP
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -6068,6 +6068,10 @@
   verify_work_stacks_empty();
   verify_overflow_empty();
 
+  if (should_unload_classes()) {
+    ClassLoaderDataGraph::purge();
+  }
+
   _intra_sweep_timer.stop();
   _intra_sweep_estimate.sample(_intra_sweep_timer.seconds());
 
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -784,7 +784,7 @@
   }
 }
 
-void ConcurrentMark::set_phase(uint active_tasks, bool concurrent) {
+void ConcurrentMark::set_concurrency(uint active_tasks) {
   assert(active_tasks <= _max_worker_id, "we should not have more");
 
   _active_tasks = active_tasks;
@@ -793,6 +793,10 @@
   _terminator   = ParallelTaskTerminator((int) active_tasks, _task_queues);
   _first_overflow_barrier_sync.set_n_workers((int) active_tasks);
   _second_overflow_barrier_sync.set_n_workers((int) active_tasks);
+}
+
+void ConcurrentMark::set_concurrency_and_phase(uint active_tasks, bool concurrent) {
+  set_concurrency(active_tasks);
 
   _concurrent = concurrent;
   // We propagate this to all tasks, not just the active ones.
@@ -806,7 +810,9 @@
     // false before we start remark. At this point we should also be
     // in a STW phase.
     assert(!concurrent_marking_in_progress(), "invariant");
-    assert(_finger == _heap_end, "only way to get here");
+    assert(_finger == _heap_end,
+           err_msg("only way to get here: _finger: "PTR_FORMAT", _heap_end: "PTR_FORMAT,
+                   _finger, _heap_end));
     update_g1_committed(true);
   }
 }
@@ -974,20 +980,28 @@
     gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id);
   }
 
-  // let the task associated with with worker 0 do this
-  if (worker_id == 0) {
-    // task 0 is responsible for clearing the global data structures
-    // We should be here because of an overflow. During STW we should
-    // not clear the overflow flag since we rely on it being true when
-    // we exit this method to abort the pause and restart concurent
-    // marking.
-    reset_marking_state(concurrent() /* clear_overflow */);
-    force_overflow()->update();
-
-    if (G1Log::fine()) {
-      gclog_or_tty->date_stamp(PrintGCDateStamps);
-      gclog_or_tty->stamp(PrintGCTimeStamps);
-      gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]");
+  // If we're executing the concurrent phase of marking, reset the marking
+  // state; otherwise the marking state is reset after reference processing,
+  // during the remark pause.
+  // If we reset here as a result of an overflow during the remark we will
+  // see assertion failures from any subsequent set_concurrency_and_phase()
+  // calls.
+  if (concurrent()) {
+    // let the task associated with with worker 0 do this
+    if (worker_id == 0) {
+      // task 0 is responsible for clearing the global data structures
+      // We should be here because of an overflow. During STW we should
+      // not clear the overflow flag since we rely on it being true when
+      // we exit this method to abort the pause and restart concurent
+      // marking.
+      reset_marking_state(true /* clear_overflow */);
+      force_overflow()->update();
+
+      if (G1Log::fine()) {
+        gclog_or_tty->date_stamp(PrintGCDateStamps);
+        gclog_or_tty->stamp(PrintGCTimeStamps);
+        gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]");
+      }
     }
   }
 
@@ -1007,7 +1021,7 @@
   if (concurrent()) {
     ConcurrentGCThread::stsJoin();
   }
-  // at this point everything should be re-initialised and ready to go
+  // at this point everything should be re-initialized and ready to go
 
   if (verbose_low()) {
     gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id);
@@ -1065,8 +1079,8 @@
         double mark_step_duration_ms = G1ConcMarkStepDurationMillis;
 
         the_task->do_marking_step(mark_step_duration_ms,
-                                  true /* do_stealing    */,
-                                  true /* do_termination */);
+                                  true  /* do_termination */,
+                                  false /* is_serial*/);
 
         double end_time_sec = os::elapsedTime();
         double end_vtime_sec = os::elapsedVTime();
@@ -1222,8 +1236,8 @@
 
   uint active_workers = MAX2(1U, parallel_marking_threads());
 
-  // Parallel task terminator is set in "set_phase()"
-  set_phase(active_workers, true /* concurrent */);
+  // Parallel task terminator is set in "set_concurrency_and_phase()"
+  set_concurrency_and_phase(active_workers, true /* concurrent */);
 
   CMConcurrentMarkingTask markingTask(this, cmThread());
   if (use_parallel_marking_threads()) {
@@ -1275,12 +1289,22 @@
   if (has_overflown()) {
     // Oops.  We overflowed.  Restart concurrent marking.
     _restart_for_overflow = true;
+    if (G1TraceMarkStackOverflow) {
+      gclog_or_tty->print_cr("\nRemark led to restart for overflow.");
+    }
+
+    // Verify the heap w.r.t. the previous marking bitmap.
+    if (VerifyDuringGC) {
+      HandleMark hm;  // handle scope
+      gclog_or_tty->print(" VerifyDuringGC:(overflow)");
+      Universe::heap()->prepare_for_verify();
+      Universe::verify(/* silent */ false,
+                       /* option */ VerifyOption_G1UsePrevMarking);
+    }
+
     // Clear the marking state because we will be restarting
     // marking due to overflowing the global mark stack.
     reset_marking_state();
-    if (G1TraceMarkStackOverflow) {
-      gclog_or_tty->print_cr("\nRemark led to restart for overflow.");
-    }
   } else {
     // Aggregate the per-task counting data that we have accumulated
     // while marking.
@@ -2184,14 +2208,17 @@
 // operating on the global stack.
 
 class G1CMKeepAliveAndDrainClosure: public OopClosure {
-  ConcurrentMark*  _cm;
-  CMTask*          _task;
-  int              _ref_counter_limit;
-  int              _ref_counter;
+  ConcurrentMark* _cm;
+  CMTask*         _task;
+  int             _ref_counter_limit;
+  int             _ref_counter;
+  bool            _is_serial;
  public:
-  G1CMKeepAliveAndDrainClosure(ConcurrentMark* cm, CMTask* task) :
-    _cm(cm), _task(task), _ref_counter_limit(G1RefProcDrainInterval) {
+  G1CMKeepAliveAndDrainClosure(ConcurrentMark* cm, CMTask* task, bool is_serial) :
+    _cm(cm), _task(task), _is_serial(is_serial),
+    _ref_counter_limit(G1RefProcDrainInterval) {
     assert(_ref_counter_limit > 0, "sanity");
+    assert(!_is_serial || _task->worker_id() == 0, "only task 0 for serial code");
     _ref_counter = _ref_counter_limit;
   }
 
@@ -2230,8 +2257,8 @@
         do {
           double mark_step_duration_ms = G1ConcMarkStepDurationMillis;
           _task->do_marking_step(mark_step_duration_ms,
-                                 false /* do_stealing    */,
-                                 false /* do_termination */);
+                                 false      /* do_termination */,
+                                 _is_serial);
         } while (_task->has_aborted() && !_cm->has_overflown());
         _ref_counter = _ref_counter_limit;
       }
@@ -2253,27 +2280,18 @@
 class G1CMDrainMarkingStackClosure: public VoidClosure {
   ConcurrentMark* _cm;
   CMTask*         _task;
-  bool            _do_stealing;
-  bool            _do_termination;
+  bool            _is_serial;
  public:
-  G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task, bool is_par) :
-    _cm(cm), _task(task) {
-    assert(is_par || _task->worker_id() == 0,
-           "Only task for worker 0 should be used if ref processing is single threaded");
-    // We only allow stealing and only enter the termination protocol
-    // in CMTask::do_marking_step() if this closure is being instantiated
-    // for parallel reference processing.
-    _do_stealing = _do_termination = is_par;
+  G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task, bool is_serial) :
+    _cm(cm), _task(task), _is_serial(is_serial) {
+    assert(!_is_serial || _task->worker_id() == 0, "only task 0 for serial code");
   }
 
   void do_void() {
     do {
       if (_cm->verbose_high()) {
-        gclog_or_tty->print_cr("\t[%u] Drain: Calling do_marking_step - "
-                               "stealing: %s, termination: %s",
-                               _task->worker_id(),
-                               BOOL_TO_STR(_do_stealing),
-                               BOOL_TO_STR(_do_termination));
+        gclog_or_tty->print_cr("\t[%u] Drain: Calling do_marking_step - serial: %s",
+                               _task->worker_id(), BOOL_TO_STR(_is_serial));
       }
 
       // We call CMTask::do_marking_step() to completely drain the local
@@ -2294,8 +2312,8 @@
       // has_aborted() flag that the marking step has completed.
 
       _task->do_marking_step(1000000000.0 /* something very large */,
-                             _do_stealing,
-                             _do_termination);
+                             true         /* do_termination */,
+                             _is_serial);
     } while (_task->has_aborted() && !_cm->has_overflown());
   }
 };
@@ -2328,7 +2346,6 @@
   ProcessTask&     _proc_task;
   G1CollectedHeap* _g1h;
   ConcurrentMark*  _cm;
-  bool             _processing_is_mt;
 
 public:
   G1CMRefProcTaskProxy(ProcessTask& proc_task,
@@ -2336,15 +2353,15 @@
                      ConcurrentMark* cm) :
     AbstractGangTask("Process reference objects in parallel"),
     _proc_task(proc_task), _g1h(g1h), _cm(cm) {
-      ReferenceProcessor* rp = _g1h->ref_processor_cm();
-      _processing_is_mt = rp->processing_is_mt();
-    }
+    ReferenceProcessor* rp = _g1h->ref_processor_cm();
+    assert(rp->processing_is_mt(), "shouldn't be here otherwise");
+  }
 
   virtual void work(uint worker_id) {
-    CMTask* marking_task = _cm->task(worker_id);
+    CMTask* task = _cm->task(worker_id);
     G1CMIsAliveClosure g1_is_alive(_g1h);
-    G1CMKeepAliveAndDrainClosure g1_par_keep_alive(_cm, marking_task);
-    G1CMDrainMarkingStackClosure g1_par_drain(_cm, marking_task, _processing_is_mt);
+    G1CMKeepAliveAndDrainClosure g1_par_keep_alive(_cm, task, false /* is_serial */);
+    G1CMDrainMarkingStackClosure g1_par_drain(_cm, task, false /* is_serial */);
 
     _proc_task.work(worker_id, g1_is_alive, g1_par_keep_alive, g1_par_drain);
   }
@@ -2356,9 +2373,11 @@
 
   G1CMRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _cm);
 
-  // We need to reset the phase for each task execution so that
-  // the termination protocol of CMTask::do_marking_step works.
-  _cm->set_phase(_active_workers, false /* concurrent */);
+  // We need to reset the concurrency level before each
+  // proxy task execution, so that the termination protocol
+  // and overflow handling in CMTask::do_marking_step() knows
+  // how many workers to wait for.
+  _cm->set_concurrency(_active_workers);
   _g1h->set_par_threads(_active_workers);
   _workers->run_task(&proc_task_proxy);
   _g1h->set_par_threads(0);
@@ -2384,12 +2403,29 @@
 
   G1CMRefEnqueueTaskProxy enq_task_proxy(enq_task);
 
+  // Not strictly necessary but...
+  //
+  // We need to reset the concurrency level before each
+  // proxy task execution, so that the termination protocol
+  // and overflow handling in CMTask::do_marking_step() knows
+  // how many workers to wait for.
+  _cm->set_concurrency(_active_workers);
   _g1h->set_par_threads(_active_workers);
   _workers->run_task(&enq_task_proxy);
   _g1h->set_par_threads(0);
 }
 
 void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
+  if (has_overflown()) {
+    // Skip processing the discovered references if we have
+    // overflown the global marking stack. Reference objects
+    // only get discovered once so it is OK to not
+    // de-populate the discovered reference lists. We could have,
+    // but the only benefit would be that, when marking restarts,
+    // less reference objects are discovered.
+    return;
+  }
+
   ResourceMark rm;
   HandleMark   hm;
 
@@ -2415,26 +2451,39 @@
     rp->setup_policy(clear_all_soft_refs);
     assert(_markStack.isEmpty(), "mark stack should be empty");
 
-    // Non-MT instances 'Keep Alive' and 'Complete GC' oop closures.
-    G1CMKeepAliveAndDrainClosure g1_keep_alive(this, task(0));
-    G1CMDrainMarkingStackClosure g1_drain_mark_stack(this, task(0), false);
-
-    // We need at least one active thread. If reference processing is
-    // not multi-threaded we use the current (ConcurrentMarkThread) thread,
-    // otherwise we use the work gang from the G1CollectedHeap and we
-    // utilize all the worker threads we can.
-    uint active_workers = (rp->processing_is_mt() && g1h->workers() != NULL
-                                ? g1h->workers()->active_workers()
-                                : 1U);
-
+    // Instances of the 'Keep Alive' and 'Complete GC' closures used
+    // in serial reference processing. Note these closures are also
+    // used for serially processing (by the the current thread) the
+    // JNI references during parallel reference processing.
+    //
+    // These closures do not need to synchronize with the worker
+    // threads involved in parallel reference processing as these
+    // instances are executed serially by the current thread (e.g.
+    // reference processing is not multi-threaded and is thus
+    // performed by the current thread instead of a gang worker).
+    //
+    // The gang tasks involved in parallel reference procssing create
+    // their own instances of these closures, which do their own
+    // synchronization among themselves.
+    G1CMKeepAliveAndDrainClosure g1_keep_alive(this, task(0), true /* is_serial */);
+    G1CMDrainMarkingStackClosure g1_drain_mark_stack(this, task(0), true /* is_serial */);
+
+    // We need at least one active thread. If reference processing
+    // is not multi-threaded we use the current (VMThread) thread,
+    // otherwise we use the work gang from the G1CollectedHeap and
+    // we utilize all the worker threads we can.
+    bool processing_is_mt = rp->processing_is_mt() && g1h->workers() != NULL;
+    uint active_workers = (processing_is_mt ? g1h->workers()->active_workers() : 1U);
     active_workers = MAX2(MIN2(active_workers, _max_worker_id), 1U);
 
+    // Parallel processing task executor.
     G1CMRefProcTaskExecutor par_task_executor(g1h, this,
                                               g1h->workers(), active_workers);
-
-    AbstractRefProcTaskExecutor* executor = (rp->processing_is_mt()
-                                                ? &par_task_executor
-                                                : NULL);
+    AbstractRefProcTaskExecutor* executor = (processing_is_mt ? &par_task_executor : NULL);
+
+    // Set the concurrency level. The phase was already set prior to
+    // executing the remark task.
+    set_concurrency(active_workers);
 
     // Set the degree of MT processing here.  If the discovery was done MT,
     // the number of threads involved during discovery could differ from
@@ -2454,6 +2503,7 @@
 
     assert(_markStack.overflow() || _markStack.isEmpty(),
             "mark stack should be empty (unless it overflowed)");
+
     if (_markStack.overflow()) {
       // This should have been done already when we tried to push an
       // entry on to the global mark stack. But let's do it again.
@@ -2482,8 +2532,8 @@
 
 class CMRemarkTask: public AbstractGangTask {
 private:
-  ConcurrentMark *_cm;
-
+  ConcurrentMark* _cm;
+  bool            _is_serial;
 public:
   void work(uint worker_id) {
     // Since all available tasks are actually started, we should
@@ -2493,8 +2543,8 @@
       task->record_start_time();
       do {
         task->do_marking_step(1000000000.0 /* something very large */,
-                              true /* do_stealing    */,
-                              true /* do_termination */);
+                              true         /* do_termination       */,
+                              _is_serial);
       } while (task->has_aborted() && !_cm->has_overflown());
       // If we overflow, then we do not want to restart. We instead
       // want to abort remark and do concurrent marking again.
@@ -2502,8 +2552,8 @@
     }
   }
 
-  CMRemarkTask(ConcurrentMark* cm, int active_workers) :
-    AbstractGangTask("Par Remark"), _cm(cm) {
+  CMRemarkTask(ConcurrentMark* cm, int active_workers, bool is_serial) :
+    AbstractGangTask("Par Remark"), _cm(cm), _is_serial(is_serial) {
     _cm->terminator()->reset_for_reuse(active_workers);
   }
 };
@@ -2524,30 +2574,40 @@
       active_workers = (uint) ParallelGCThreads;
       g1h->workers()->set_active_workers(active_workers);
     }
-    set_phase(active_workers, false /* concurrent */);
+    set_concurrency_and_phase(active_workers, false /* concurrent */);
     // Leave _parallel_marking_threads at it's
     // value originally calculated in the ConcurrentMark
     // constructor and pass values of the active workers
     // through the gang in the task.
 
-    CMRemarkTask remarkTask(this, active_workers);
+    CMRemarkTask remarkTask(this, active_workers, false /* is_serial */);
+    // We will start all available threads, even if we decide that the
+    // active_workers will be fewer. The extra ones will just bail out
+    // immediately.
     g1h->set_par_threads(active_workers);
     g1h->workers()->run_task(&remarkTask);
     g1h->set_par_threads(0);
   } else {
     G1CollectedHeap::StrongRootsScope srs(g1h);
-    // this is remark, so we'll use up all available threads
     uint active_workers = 1;
-    set_phase(active_workers, false /* concurrent */);
-
-    CMRemarkTask remarkTask(this, active_workers);
-    // We will start all available threads, even if we decide that the
-    // active_workers will be fewer. The extra ones will just bail out
-    // immediately.
+    set_concurrency_and_phase(active_workers, false /* concurrent */);
+
+    // Note - if there's no work gang then the VMThread will be
+    // the thread to execute the remark - serially. We have
+    // to pass true for the is_serial parameter so that
+    // CMTask::do_marking_step() doesn't enter the sync
+    // barriers in the event of an overflow. Doing so will
+    // cause an assert that the current thread is not a
+    // concurrent GC thread.
+    CMRemarkTask remarkTask(this, active_workers, true /* is_serial*/);
     remarkTask.work(0);
   }
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
-  guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant");
+  guarantee(has_overflown() ||
+            satb_mq_set.completed_buffers_num() == 0,
+            err_msg("Invariant: has_overflown = %s, num buffers = %d",
+                    BOOL_TO_STR(has_overflown()),
+                    satb_mq_set.completed_buffers_num()));
 
   print_stats();
 }
@@ -3854,8 +3914,8 @@
 
 /*****************************************************************************
 
-    The do_marking_step(time_target_ms) method is the building block
-    of the parallel marking framework. It can be called in parallel
+    The do_marking_step(time_target_ms, ...) method is the building
+    block of the parallel marking framework. It can be called in parallel
     with other invocations of do_marking_step() on different tasks
     (but only one per task, obviously) and concurrently with the
     mutator threads, or during remark, hence it eliminates the need
@@ -3865,7 +3925,7 @@
     pauses too, since do_marking_step() ensures that it aborts before
     it needs to yield.
 
-    The data structures that is uses to do marking work are the
+    The data structures that it uses to do marking work are the
     following:
 
       (1) Marking Bitmap. If there are gray objects that appear only
@@ -3914,7 +3974,7 @@
       (2) When a global overflow (on the global stack) has been
       triggered. Before the task aborts, it will actually sync up with
       the other tasks to ensure that all the marking data structures
-      (local queues, stacks, fingers etc.)  are re-initialised so that
+      (local queues, stacks, fingers etc.)  are re-initialized so that
       when do_marking_step() completes, the marking phase can
       immediately restart.
 
@@ -3951,11 +4011,25 @@
     place, it was natural to piggy-back all the other conditions on it
     too and not constantly check them throughout the code.
 
+    If do_termination is true then do_marking_step will enter its
+    termination protocol.
+
+    The value of is_serial must be true when do_marking_step is being
+    called serially (i.e. by the VMThread) and do_marking_step should
+    skip any synchronization in the termination and overflow code.
+    Examples include the serial remark code and the serial reference
+    processing closures.
+
+    The value of is_serial must be false when do_marking_step is
+    being called by any of the worker threads in a work gang.
+    Examples include the concurrent marking code (CMMarkingTask),
+    the MT remark code, and the MT reference processing closures.
+
  *****************************************************************************/
 
 void CMTask::do_marking_step(double time_target_ms,
-                             bool do_stealing,
-                             bool do_termination) {
+                             bool do_termination,
+                             bool is_serial) {
   assert(time_target_ms >= 1.0, "minimum granularity is 1ms");
   assert(concurrent() == _cm->concurrent(), "they should be the same");
 
@@ -3976,6 +4050,12 @@
   _start_time_ms = os::elapsedVTime() * 1000.0;
   statsOnly( _interval_start_time_ms = _start_time_ms );
 
+  // If do_stealing is true then do_marking_step will attempt to
+  // steal work from the other CMTasks. It only makes sense to
+  // enable stealing when the termination protocol is enabled
+  // and do_marking_step() is not being called serially.
+  bool do_stealing = do_termination && !is_serial;
+
   double diff_prediction_ms =
     g1_policy->get_new_prediction(&_marking_step_diffs_ms);
   _time_target_ms = time_target_ms - diff_prediction_ms;
@@ -4237,10 +4317,12 @@
     }
 
     _termination_start_time_ms = os::elapsedVTime() * 1000.0;
+
     // The CMTask class also extends the TerminatorTerminator class,
     // hence its should_exit_termination() method will also decide
     // whether to exit the termination protocol or not.
-    bool finished = _cm->terminator()->offer_termination(this);
+    bool finished = (is_serial ||
+                     _cm->terminator()->offer_termination(this));
     double termination_end_time_ms = os::elapsedVTime() * 1000.0;
     _termination_time_ms +=
       termination_end_time_ms - _termination_start_time_ms;
@@ -4320,20 +4402,28 @@
         gclog_or_tty->print_cr("[%u] detected overflow", _worker_id);
       }
 
-      _cm->enter_first_sync_barrier(_worker_id);
-      // When we exit this sync barrier we know that all tasks have
-      // stopped doing marking work. So, it's now safe to
-      // re-initialise our data structures. At the end of this method,
-      // task 0 will clear the global data structures.
+      if (!is_serial) {
+        // We only need to enter the sync barrier if being called
+        // from a parallel context
+        _cm->enter_first_sync_barrier(_worker_id);
+
+        // When we exit this sync barrier we know that all tasks have
+        // stopped doing marking work. So, it's now safe to
+        // re-initialise our data structures. At the end of this method,
+        // task 0 will clear the global data structures.
+      }
 
       statsOnly( ++_aborted_overflow );
 
       // We clear the local state of this task...
       clear_region_fields();
 
-      // ...and enter the second barrier.
-      _cm->enter_second_sync_barrier(_worker_id);
-      // At this point everything has bee re-initialised and we're
+      if (!is_serial) {
+        // ...and enter the second barrier.
+        _cm->enter_second_sync_barrier(_worker_id);
+      }
+      // At this point, if we're during the concurrent phase of
+      // marking, everything has been re-initialized and we're
       // ready to restart.
     }
 
--- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -166,7 +166,7 @@
 class CMMarkStack VALUE_OBJ_CLASS_SPEC {
   VirtualSpace _virtual_space;   // Underlying backing store for actual stack
   ConcurrentMark* _cm;
-  oop*   _base;        // bottom of stack
+  oop* _base;        // bottom of stack
   jint _index;       // one more than last occupied index
   jint _capacity;    // max #elements
   jint _saved_index; // value of _index saved at start of GC
@@ -491,9 +491,12 @@
   // structures are initialised to a sensible and predictable state.
   void set_non_marking_state();
 
+  // Called to indicate how many threads are currently active.
+  void set_concurrency(uint active_tasks);
+
   // It should be called to indicate which phase we're in (concurrent
   // mark or remark) and how many threads are currently active.
-  void set_phase(uint active_tasks, bool concurrent);
+  void set_concurrency_and_phase(uint active_tasks, bool concurrent);
 
   // prints all gathered CM-related statistics
   void print_stats();
@@ -1146,7 +1149,9 @@
   // trying not to exceed the given duration. However, it might exit
   // prematurely, according to some conditions (i.e. SATB buffers are
   // available for processing).
-  void do_marking_step(double target_ms, bool do_stealing, bool do_termination);
+  void do_marking_step(double target_ms,
+                       bool do_termination,
+                       bool is_serial);
 
   // These two calls start and stop the timer
   void record_start_time() {
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -854,7 +854,8 @@
   assert(!isHumongous(word_size), "we do not allow humongous TLABs");
 
   unsigned int dummy_gc_count_before;
-  return attempt_allocation(word_size, &dummy_gc_count_before);
+  int dummy_gclocker_retry_count = 0;
+  return attempt_allocation(word_size, &dummy_gc_count_before, &dummy_gclocker_retry_count);
 }
 
 HeapWord*
@@ -863,14 +864,14 @@
   assert_heap_not_locked_and_not_at_safepoint();
 
   // Loop until the allocation is satisified, or unsatisfied after GC.
-  for (int try_count = 1; /* we'll return */; try_count += 1) {
+  for (int try_count = 1, gclocker_retry_count = 0; /* we'll return */; try_count += 1) {
     unsigned int gc_count_before;
 
     HeapWord* result = NULL;
     if (!isHumongous(word_size)) {
-      result = attempt_allocation(word_size, &gc_count_before);
+      result = attempt_allocation(word_size, &gc_count_before, &gclocker_retry_count);
     } else {
-      result = attempt_allocation_humongous(word_size, &gc_count_before);
+      result = attempt_allocation_humongous(word_size, &gc_count_before, &gclocker_retry_count);
     }
     if (result != NULL) {
       return result;
@@ -894,6 +895,9 @@
       }
       return result;
     } else {
+      if (gclocker_retry_count > GCLockerRetryAllocationCount) {
+        return NULL;
+      }
       assert(op.result() == NULL,
              "the result should be NULL if the VM op did not succeed");
     }
@@ -910,7 +914,8 @@
 }
 
 HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size,
-                                           unsigned int *gc_count_before_ret) {
+                                           unsigned int *gc_count_before_ret,
+                                           int* gclocker_retry_count_ret) {
   // Make sure you read the note in attempt_allocation_humongous().
 
   assert_heap_not_locked_and_not_at_safepoint();
@@ -986,10 +991,16 @@
         return NULL;
       }
     } else {
+      if (*gclocker_retry_count_ret > GCLockerRetryAllocationCount) {
+        MutexLockerEx x(Heap_lock);
+        *gc_count_before_ret = total_collections();
+        return NULL;
+      }
       // The GCLocker is either active or the GCLocker initiated
       // GC has not yet been performed. Stall until it is and
       // then retry the allocation.
       GC_locker::stall_until_clear();
+      (*gclocker_retry_count_ret) += 1;
     }
 
     // We can reach here if we were unsuccessul in scheduling a
@@ -1019,7 +1030,8 @@
 }
 
 HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size,
-                                          unsigned int * gc_count_before_ret) {
+                                          unsigned int * gc_count_before_ret,
+                                          int* gclocker_retry_count_ret) {
   // The structure of this method has a lot of similarities to
   // attempt_allocation_slow(). The reason these two were not merged
   // into a single one is that such a method would require several "if
@@ -1104,10 +1116,16 @@
         return NULL;
       }
     } else {
+      if (*gclocker_retry_count_ret > GCLockerRetryAllocationCount) {
+        MutexLockerEx x(Heap_lock);
+        *gc_count_before_ret = total_collections();
+        return NULL;
+      }
       // The GCLocker is either active or the GCLocker initiated
       // GC has not yet been performed. Stall until it is and
       // then retry the allocation.
       GC_locker::stall_until_clear();
+      (*gclocker_retry_count_ret) += 1;
     }
 
     // We can reach here if we were unsuccessul in scheduling a
@@ -3270,12 +3288,12 @@
 
 void G1CollectedHeap::verify(bool silent,
                              VerifyOption vo) {
-  if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) {
+  if (SafepointSynchronize::is_at_safepoint()) {
     if (!silent) { gclog_or_tty->print("Roots "); }
     VerifyRootsClosure rootsCl(vo);
 
     assert(Thread::current()->is_VM_thread(),
-      "Expected to be executed serially by the VM thread at this point");
+           "Expected to be executed serially by the VM thread at this point");
 
     CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false);
     VerifyKlassClosure klassCl(this, &rootsCl);
@@ -3360,7 +3378,8 @@
     }
     guarantee(!failures, "there should not have been any failures");
   } else {
-    if (!silent) gclog_or_tty->print("(SKIPPING roots, heapRegions, remset) ");
+    if (!silent)
+      gclog_or_tty->print("(SKIPPING roots, heapRegionSets, heapRegions, remset) ");
   }
 }
 
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -559,18 +559,21 @@
   // the mutator alloc region without taking the Heap_lock. This
   // should only be used for non-humongous allocations.
   inline HeapWord* attempt_allocation(size_t word_size,
-                                      unsigned int* gc_count_before_ret);
+                                      unsigned int* gc_count_before_ret,
+                                      int* gclocker_retry_count_ret);
 
   // Second-level mutator allocation attempt: take the Heap_lock and
   // retry the allocation attempt, potentially scheduling a GC
   // pause. This should only be used for non-humongous allocations.
   HeapWord* attempt_allocation_slow(size_t word_size,
-                                    unsigned int* gc_count_before_ret);
+                                    unsigned int* gc_count_before_ret,
+                                    int* gclocker_retry_count_ret);
 
   // Takes the Heap_lock and attempts a humongous allocation. It can
   // potentially schedule a GC pause.
   HeapWord* attempt_allocation_humongous(size_t word_size,
-                                         unsigned int* gc_count_before_ret);
+                                         unsigned int* gc_count_before_ret,
+                                         int* gclocker_retry_count_ret);
 
   // Allocation attempt that should be called during safepoints (e.g.,
   // at the end of a successful GC). expect_null_mutator_alloc_region
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -60,7 +60,8 @@
 
 inline HeapWord*
 G1CollectedHeap::attempt_allocation(size_t word_size,
-                                    unsigned int* gc_count_before_ret) {
+                                    unsigned int* gc_count_before_ret,
+                                    int* gclocker_retry_count_ret) {
   assert_heap_not_locked_and_not_at_safepoint();
   assert(!isHumongous(word_size), "attempt_allocation() should not "
          "be called for humongous allocation requests");
@@ -68,7 +69,9 @@
   HeapWord* result = _mutator_alloc_region.attempt_allocation(word_size,
                                                       false /* bot_updates */);
   if (result == NULL) {
-    result = attempt_allocation_slow(word_size, gc_count_before_ret);
+    result = attempt_allocation_slow(word_size,
+                                     gc_count_before_ret,
+                                     gclocker_retry_count_ret);
   }
   assert_heap_not_locked();
   if (result != NULL) {
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1359,18 +1359,6 @@
 #endif // PRODUCT
 }
 
-#ifndef PRODUCT
-// for debugging, bit of a hack...
-static char*
-region_num_to_mbs(int length) {
-  static char buffer[64];
-  double bytes = (double) (length * HeapRegion::GrainBytes);
-  double mbs = bytes / (double) (1024 * 1024);
-  sprintf(buffer, "%7.2lfMB", mbs);
-  return buffer;
-}
-#endif // PRODUCT
-
 uint G1CollectorPolicy::max_regions(int purpose) {
   switch (purpose) {
     case GCAllocForSurvived:
--- a/src/share/vm/gc_implementation/g1/ptrQueue.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/gc_implementation/g1/ptrQueue.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -53,15 +53,6 @@
 }
 
 
-static int byte_index_to_index(int ind) {
-  assert((ind % oopSize) == 0, "Invariant.");
-  return ind / oopSize;
-}
-
-static int index_to_byte_index(int byte_ind) {
-  return byte_ind * oopSize;
-}
-
 void PtrQueue::enqueue_known_active(void* ptr) {
   assert(0 <= _index && _index <= _sz, "Invariant.");
   assert(_index == 0 || _buf != NULL, "invariant");
--- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -326,6 +326,7 @@
 
   uint loop_count = 0;
   uint gc_count = 0;
+  int gclocker_stalled_count = 0;
 
   while (result == NULL) {
     // We don't want to have multiple collections for a single filled generation.
@@ -354,6 +355,10 @@
         return result;
       }
 
+      if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
+        return NULL;
+      }
+
       // Failed to allocate without a gc.
       if (GC_locker::is_active_and_needs_gc()) {
         // If this thread is not in a jni critical section, we stall
@@ -366,6 +371,7 @@
         if (!jthr->in_critical()) {
           MutexUnlocker mul(Heap_lock);
           GC_locker::stall_until_clear();
+          gclocker_stalled_count += 1;
           continue;
         } else {
           if (CheckJNICalls) {
@@ -656,7 +662,7 @@
     tty->print_cr("[Accumulated GC generation 0 time %3.7f secs]", time);
   }
   if (TraceGen1Time) {
-    double time = PSMarkSweep::accumulated_time()->seconds();
+    double time = UseParallelOldGC ? PSParallelCompact::accumulated_time()->seconds() : PSMarkSweep::accumulated_time()->seconds();
     tty->print_cr("[Accumulated GC generation 1 time %3.7f secs]", time);
   }
 }
--- a/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -256,7 +256,7 @@
   }
 
   if (PrintGC && Verbose) {
-    if (success && GC_locker::is_active()) {
+    if (success && GC_locker::is_active_and_needs_gc()) {
       gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
     }
   }
--- a/src/share/vm/interpreter/interpreter.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/interpreter/interpreter.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -76,7 +76,7 @@
 
   if (PrintInterpreter) {
     st->cr();
-    Disassembler::decode(code_begin(), code_end(), st, DEBUG_ONLY(_comments) NOT_DEBUG(CodeComments()));
+    Disassembler::decode(code_begin(), code_end(), st, DEBUG_ONLY(_strings) NOT_DEBUG(CodeStrings()));
   }
 }
 
--- a/src/share/vm/interpreter/interpreter.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/interpreter/interpreter.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -48,12 +48,12 @@
   int         _size;                             // the size in bytes
   const char* _description;                      // a description of the codelet, for debugging & printing
   Bytecodes::Code _bytecode;                     // associated bytecode if any
-  DEBUG_ONLY(CodeComments _comments;)            // Comments for annotating assembler output.
+  DEBUG_ONLY(CodeStrings _strings;)              // Comments for annotating assembler output.
 
  public:
   // Initialization/finalization
   void    initialize(int size,
-                     CodeComments& comments)     { _size = size; DEBUG_ONLY(_comments.assign(comments);) }
+                     CodeStrings& strings)       { _size = size; DEBUG_ONLY(_strings.assign(strings);) }
   void    finalize()                             { ShouldNotCallThis(); }
 
   // General info/converters
@@ -131,7 +131,7 @@
 
 
     // commit Codelet
-    AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size(), (*_masm)->code()->comments());
+    AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size(), (*_masm)->code()->strings());
     // make sure nobody can use _masm outside a CodeletMark lifespan
     *_masm = NULL;
   }
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -557,11 +557,6 @@
 // be shared by method invocation and synchronized blocks.
 //%note synchronization_3
 
-static void trace_locking(Handle& h_locking_obj, bool is_locking) {
-  ObjectSynchronizer::trace_locking(h_locking_obj, false, true, is_locking);
-}
-
-
 //%note monitor_1
 IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem))
 #ifdef ASSERT
--- a/src/share/vm/interpreter/linkResolver.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/interpreter/linkResolver.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -458,25 +458,27 @@
     Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
     {
       ResourceMark rm(THREAD);
-      char* failed_type_name =
+      Symbol* failed_type_symbol =
         SystemDictionary::check_signature_loaders(method_signature, loader,
                                                   class_loader, true, CHECK);
-      if (failed_type_name != NULL) {
+      if (failed_type_symbol != NULL) {
         const char* msg = "loader constraint violation: when resolving method"
           " \"%s\" the class loader (instance of %s) of the current class, %s,"
-          " and the class loader (instance of %s) for resolved class, %s, have"
+          " and the class loader (instance of %s) for the method's defining class, %s, have"
           " different Class objects for the type %s used in the signature";
         char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature);
         const char* loader1 = SystemDictionary::loader_name(loader());
         char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
         const char* loader2 = SystemDictionary::loader_name(class_loader());
-        char* resolved = InstanceKlass::cast(resolved_klass())->name()->as_C_string();
+        char* target = InstanceKlass::cast(resolved_method->method_holder())
+                       ->name()->as_C_string();
+        char* failed_type_name = failed_type_symbol->as_C_string();
         size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
-          strlen(current) + strlen(loader2) + strlen(resolved) +
-          strlen(failed_type_name);
+          strlen(current) + strlen(loader2) + strlen(target) +
+          strlen(failed_type_name) + 1;
         char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
         jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
-                     resolved, failed_type_name);
+                     target, failed_type_name);
         THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
       }
     }
@@ -520,26 +522,28 @@
     Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
     {
       ResourceMark rm(THREAD);
-      char* failed_type_name =
+      Symbol* failed_type_symbol =
         SystemDictionary::check_signature_loaders(method_signature, loader,
                                                   class_loader, true, CHECK);
-      if (failed_type_name != NULL) {
+      if (failed_type_symbol != NULL) {
         const char* msg = "loader constraint violation: when resolving "
           "interface method \"%s\" the class loader (instance of %s) of the "
           "current class, %s, and the class loader (instance of %s) for "
-          "resolved class, %s, have different Class objects for the type %s "
+          "the method's defining class, %s, have different Class objects for the type %s "
           "used in the signature";
         char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature);
         const char* loader1 = SystemDictionary::loader_name(loader());
         char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
         const char* loader2 = SystemDictionary::loader_name(class_loader());
-        char* resolved = InstanceKlass::cast(resolved_klass())->name()->as_C_string();
+        char* target = InstanceKlass::cast(resolved_method->method_holder())
+                       ->name()->as_C_string();
+        char* failed_type_name = failed_type_symbol->as_C_string();
         size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
-          strlen(current) + strlen(loader2) + strlen(resolved) +
-          strlen(failed_type_name);
+          strlen(current) + strlen(loader2) + strlen(target) +
+          strlen(failed_type_name) + 1;
         char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
         jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
-                     resolved, failed_type_name);
+                     target, failed_type_name);
         THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
       }
     }
@@ -642,12 +646,12 @@
     Symbol*  signature_ref  = pool->signature_ref_at(index);
     {
       ResourceMark rm(THREAD);
-      char* failed_type_name =
+      Symbol* failed_type_symbol =
         SystemDictionary::check_signature_loaders(signature_ref,
                                                   ref_loader, sel_loader,
                                                   false,
                                                   CHECK);
-      if (failed_type_name != NULL) {
+      if (failed_type_symbol != NULL) {
         const char* msg = "loader constraint violation: when resolving field"
           " \"%s\" the class loader (instance of %s) of the referring class, "
           "%s, and the class loader (instance of %s) for the field's resolved "
@@ -656,8 +660,9 @@
         const char* loader1 = SystemDictionary::loader_name(ref_loader());
         char* sel = InstanceKlass::cast(sel_klass())->name()->as_C_string();
         const char* loader2 = SystemDictionary::loader_name(sel_loader());
+        char* failed_type_name = failed_type_symbol->as_C_string();
         size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) +
-          strlen(sel) + strlen(loader2) + strlen(failed_type_name);
+          strlen(sel) + strlen(loader2) + strlen(failed_type_name) + 1;
         char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
         jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2,
                      failed_type_name);
--- a/src/share/vm/memory/collectorPolicy.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/memory/collectorPolicy.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -532,7 +532,7 @@
 
   // Loop until the allocation is satisified,
   // or unsatisfied after GC.
-  for (int try_count = 1; /* return or throw */; try_count += 1) {
+  for (int try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
     HandleMark hm; // discard any handles allocated in each iteration
 
     // First allocation attempt is lock-free.
@@ -576,6 +576,10 @@
           }
         }
 
+        if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
+          return NULL; // we didn't get to do a GC and we didn't get any memory
+        }
+
         // If this thread is not in a jni critical section, we stall
         // the requestor until the critical section has cleared and
         // GC allowed. When the critical section clears, a GC is
@@ -587,6 +591,7 @@
           MutexUnlocker mul(Heap_lock);
           // Wait for JNI critical section to be exited
           GC_locker::stall_until_clear();
+          gclocker_stalled_count += 1;
           continue;
         } else {
           if (CheckJNICalls) {
--- a/src/share/vm/memory/filemap.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/memory/filemap.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -372,7 +372,7 @@
   // other reserved memory (like the code cache).
   ReservedSpace rs(size, alignment, false, requested_addr);
   if (!rs.is_reserved()) {
-    fail_continue(err_msg("Unable to reserved shared space at required address " INTPTR_FORMAT, requested_addr));
+    fail_continue(err_msg("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr));
     return rs;
   }
   // the reserved virtual memory is for mapping class data sharing archive
--- a/src/share/vm/memory/genCollectedHeap.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/memory/genCollectedHeap.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -554,6 +554,8 @@
     }
 
     if (complete) {
+      // Delete metaspaces for unloaded class loaders and clean up loader_data graph
+      ClassLoaderDataGraph::purge();
       // Resize the metaspace capacity after full collections
       MetaspaceGC::compute_new_size();
       update_full_collections_completed();
@@ -564,11 +566,6 @@
 
     gc_epilogue(complete);
 
-    // Delete metaspaces for unloaded class loaders and clean up loader_data graph
-    if (complete) {
-      ClassLoaderDataGraph::purge();
-    }
-
     if (must_restore_marks_for_biased_locking) {
       BiasedLocking::restore_marks();
     }
--- a/src/share/vm/memory/heap.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/memory/heap.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -79,13 +79,6 @@
 }
 
 
-static size_t align_to_allocation_size(size_t size) {
-  const size_t alignment = (size_t)os::vm_allocation_granularity();
-  assert(is_power_of_2(alignment), "no kidding ???");
-  return (size + alignment - 1) & ~(alignment - 1);
-}
-
-
 void CodeHeap::on_code_mapping(char* base, size_t size) {
 #ifdef LINUX
   extern void linux_wrap_code(char* base, size_t size);
--- a/src/share/vm/memory/metaspace.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/memory/metaspace.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -334,27 +334,19 @@
 
   // byte_size is the size of the associated virtualspace.
 VirtualSpaceNode::VirtualSpaceNode(size_t byte_size) : _top(NULL), _next(NULL), _rs(0) {
-  // This allocates memory with mmap.  For DumpSharedspaces, allocate the
-  // space at low memory so that other shared images don't conflict.
-  // This is the same address as memory needed for UseCompressedOops but
-  // compressed oops don't work with CDS (offsets in metadata are wrong), so
-  // borrow the same address.
+  // align up to vm allocation granularity
+  byte_size = align_size_up(byte_size, os::vm_allocation_granularity());
+
+  // This allocates memory with mmap.  For DumpSharedspaces, try to reserve
+  // configurable address, generally at the top of the Java heap so other
+  // memory addresses don't conflict.
   if (DumpSharedSpaces) {
-    char* shared_base = (char*)HeapBaseMinAddress;
+    char* shared_base = (char*)SharedBaseAddress;
     _rs = ReservedSpace(byte_size, 0, false, shared_base, 0);
     if (_rs.is_reserved()) {
-      assert(_rs.base() == shared_base, "should match");
+      assert(shared_base == 0 || _rs.base() == shared_base, "should match");
     } else {
-      // If we are dumping the heap, then allocate a wasted block of address
-      // space in order to push the heap to a lower address.  This extra
-      // address range allows for other (or larger) libraries to be loaded
-      // without them occupying the space required for the shared spaces.
-      uintx reserved = 0;
-      uintx block_size = 64*1024*1024;
-      while (reserved < SharedDummyBlockSize) {
-        char* dummy = os::reserve_memory(block_size);
-        reserved += block_size;
-      }
+      // Get a mmap region anywhere if the SharedBaseAddress fails.
       _rs = ReservedSpace(byte_size);
     }
     MetaspaceShared::set_shared_rs(&_rs);
@@ -1100,25 +1092,24 @@
 }
 
 bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) {
+  // If the user wants a limit, impose one.
+  if (!FLAG_IS_DEFAULT(MaxMetaspaceSize) &&
+      MetaspaceAux::reserved_in_bytes() >= MaxMetaspaceSize) {
+    return false;
+  }
 
   // Class virtual space should always be expanded.  Call GC for the other
   // metadata virtual space.
   if (vsl == Metaspace::class_space_list()) return true;
 
-  // If the user wants a limit, impose one.
-  size_t max_metaspace_size_words = MaxMetaspaceSize / BytesPerWord;
-  size_t metaspace_size_words = MetaspaceSize / BytesPerWord;
-  if (!FLAG_IS_DEFAULT(MaxMetaspaceSize) &&
-      vsl->capacity_words_sum() >= max_metaspace_size_words) {
-    return false;
-  }
-
   // If this is part of an allocation after a GC, expand
   // unconditionally.
   if(MetaspaceGC::expand_after_GC()) {
     return true;
   }
 
+  size_t metaspace_size_words = MetaspaceSize / BytesPerWord;
+
   // If the capacity is below the minimum capacity, allow the
   // expansion.  Also set the high-water-mark (capacity_until_GC)
   // to that minimum capacity so that a GC will not be induced
@@ -1308,8 +1299,7 @@
       gclog_or_tty->print_cr("  metaspace HWM: %.1fK", new_capacity_until_GC / (double) K);
     }
   }
-  assert(vsl->used_bytes_sum() == used_after_gc &&
-         used_after_gc <= vsl->capacity_bytes_sum(),
+  assert(used_after_gc <= vsl->capacity_bytes_sum(),
          "sanity check");
 
 }
@@ -1969,6 +1959,9 @@
 }
 
 SpaceManager::~SpaceManager() {
+  // This call this->_lock which can't be done while holding expand_lock()
+  const size_t in_use_before = sum_capacity_in_chunks_in_use();
+
   MutexLockerEx fcl(SpaceManager::expand_lock(),
                     Mutex::_no_safepoint_check_flag);
 
@@ -1986,7 +1979,7 @@
 
   // Have to update before the chunks_in_use lists are emptied
   // below.
-  chunk_manager->inc_free_chunks_total(sum_capacity_in_chunks_in_use(),
+  chunk_manager->inc_free_chunks_total(in_use_before,
                                        sum_count_in_chunks_in_use());
 
   // Add all the chunks in use by this space manager
--- a/src/share/vm/memory/sharedHeap.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/memory/sharedHeap.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -178,7 +178,7 @@
       SystemDictionary::always_strong_oops_do(roots);
       ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
     } else {
-      ShouldNotReachHere2("We should always have selected either SO_AllClasses or SO_SystemClasses");
+      fatal("We should always have selected either SO_AllClasses or SO_SystemClasses");
     }
   }
 
--- a/src/share/vm/memory/universe.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/memory/universe.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -953,15 +953,6 @@
 void universe2_init() {
   EXCEPTION_MARK;
   Universe::genesis(CATCH);
-  // Although we'd like to verify here that the state of the heap
-  // is good, we can't because the main thread has not yet added
-  // itself to the threads list (so, using current interfaces
-  // we can't "fill" its TLAB), unless TLABs are disabled.
-  if (VerifyBeforeGC && !UseTLAB &&
-      Universe::heap()->total_collections() >= VerifyGCStartAt) {
-     Universe::heap()->prepare_for_verify();
-     Universe::verify();   // make sure we're starting with a clean slate
-  }
 }
 
 
@@ -1335,6 +1326,8 @@
 static uintptr_t _verify_klass_data[2] = {0, (uintptr_t)-1};
 
 
+#ifndef PRODUCT
+
 static void calculate_verify_data(uintptr_t verify_data[2],
                                   HeapWord* low_boundary,
                                   HeapWord* high_boundary) {
@@ -1369,9 +1362,7 @@
   verify_data[1] = bits;
 }
 
-
 // Oop verification (see MacroAssembler::verify_oop)
-#ifndef PRODUCT
 
 uintptr_t Universe::verify_oop_mask() {
   MemRegion m = heap()->reserved_region();
--- a/src/share/vm/oops/constMethod.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/constMethod.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -363,6 +363,26 @@
   return (AnnotationArray**)constMethod_end() - offset;
 }
 
+// copy annotations from 'cm' to 'this'
+void ConstMethod::copy_annotations_from(ConstMethod* cm) {
+  if (cm->has_method_annotations()) {
+    assert(has_method_annotations(), "should be allocated already");
+    set_method_annotations(cm->method_annotations());
+  }
+  if (cm->has_parameter_annotations()) {
+    assert(has_parameter_annotations(), "should be allocated already");
+    set_parameter_annotations(cm->parameter_annotations());
+  }
+  if (cm->has_type_annotations()) {
+    assert(has_type_annotations(), "should be allocated already");
+    set_type_annotations(cm->type_annotations());
+  }
+  if (cm->has_default_annotations()) {
+    assert(has_default_annotations(), "should be allocated already");
+    set_default_annotations(cm->default_annotations());
+  }
+}
+
 // Printing
 
 void ConstMethod::print_on(outputStream* st) const {
--- a/src/share/vm/oops/constMethod.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/constMethod.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -441,6 +441,9 @@
     return has_default_annotations() ? default_annotations()->length() : 0;
   }
 
+  // Copy annotations from other ConstMethod
+  void copy_annotations_from(ConstMethod* cm);
+
   // byte codes
   void    set_code(address code) {
     if (code_size() > 0) {
--- a/src/share/vm/oops/constantPool.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/constantPool.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1378,12 +1378,13 @@
 
 // JVMTI GetConstantPool support
 
-// For temporary use until code is stable.
-#define DBG(code)
+// For debugging of constant pool
+const bool debug_cpool = false;
 
-static const char* WARN_MSG = "Must not be such entry!";
+#define DBG(code) do { if (debug_cpool) { (code); } } while(0)
 
 static void print_cpool_bytes(jint cnt, u1 *bytes) {
+  const char* WARN_MSG = "Must not be such entry!";
   jint size = 0;
   u2   idx1, idx2;
 
@@ -1669,8 +1670,7 @@
         idx1 = tbl->symbol_to_value(sym);
         assert(idx1 != 0, "Have not found a hashtable entry");
         Bytes::put_Java_u2((address) (bytes+1), idx1);
-        DBG(char *str = sym->as_utf8());
-        DBG(printf("JVM_CONSTANT_String: idx=#%03hd, %s", idx1, str));
+        DBG(printf("JVM_CONSTANT_String: idx=#%03hd, %s", idx1, sym->as_utf8()));
         break;
       }
       case JVM_CONSTANT_Fieldref:
@@ -1745,6 +1745,8 @@
   return (int)(bytes - start_bytes);
 } /* end copy_cpool_bytes */
 
+#undef DBG
+
 
 void ConstantPool::set_on_stack(const bool value) {
   if (value) {
@@ -1852,6 +1854,7 @@
   switch (tag_at(index).value()) {
     case JVM_CONSTANT_Class :
       { Klass* k = klass_at(index, CATCH);
+        guarantee(k != NULL, "need klass");
         k->print_value_on(st);
         st->print(" {0x%lx}", (address)k);
       }
--- a/src/share/vm/oops/fieldInfo.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/fieldInfo.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -108,11 +108,11 @@
         return build_int_from_shorts(_shorts[low_packed_offset], _shorts[high_packed_offset]) >> FIELDINFO_TAG_SIZE;
 #ifndef PRODUCT
       case FIELDINFO_TAG_TYPE_PLAIN:
-        ShouldNotReachHere2("Asking offset for the plain type field");
+        fatal("Asking offset for the plain type field");
       case FIELDINFO_TAG_TYPE_CONTENDED:
-        ShouldNotReachHere2("Asking offset for the contended type field");
+        fatal("Asking offset for the contended type field");
       case FIELDINFO_TAG_BLANK:
-        ShouldNotReachHere2("Asking offset for the blank field");
+        fatal("Asking offset for the blank field");
 #endif
     }
     ShouldNotReachHere();
@@ -128,9 +128,9 @@
         return true;
 #ifndef PRODUCT
       case FIELDINFO_TAG_OFFSET:
-        ShouldNotReachHere2("Asking contended flag for the field with offset");
+        fatal("Asking contended flag for the field with offset");
       case FIELDINFO_TAG_BLANK:
-        ShouldNotReachHere2("Asking contended flag for the blank field");
+        fatal("Asking contended flag for the blank field");
 #endif
     }
     ShouldNotReachHere();
@@ -146,9 +146,9 @@
         return _shorts[high_packed_offset];
 #ifndef PRODUCT
       case FIELDINFO_TAG_OFFSET:
-        ShouldNotReachHere2("Asking the contended group for the field with offset");
+        fatal("Asking the contended group for the field with offset");
       case FIELDINFO_TAG_BLANK:
-        ShouldNotReachHere2("Asking the contended group for the blank field");
+        fatal("Asking the contended group for the blank field");
 #endif
     }
     ShouldNotReachHere();
@@ -163,9 +163,9 @@
         return (lo >> FIELDINFO_TAG_SIZE);
 #ifndef PRODUCT
       case FIELDINFO_TAG_OFFSET:
-        ShouldNotReachHere2("Asking the field type for field with offset");
+        fatal("Asking the field type for field with offset");
       case FIELDINFO_TAG_BLANK:
-        ShouldNotReachHere2("Asking the field type for the blank field");
+        fatal("Asking the field type for the blank field");
 #endif
     }
     ShouldNotReachHere();
@@ -211,7 +211,7 @@
       case FIELDINFO_TAG_TYPE_PLAIN:
       case FIELDINFO_TAG_TYPE_CONTENDED:
       case FIELDINFO_TAG_OFFSET:
-        ShouldNotReachHere2("Setting the field type with overwriting");
+        fatal("Setting the field type with overwriting");
 #endif
     }
     ShouldNotReachHere();
@@ -226,11 +226,11 @@
         return;
 #ifndef PRODUCT
       case FIELDINFO_TAG_TYPE_CONTENDED:
-        ShouldNotReachHere2("Overwriting contended group");
+        fatal("Overwriting contended group");
       case FIELDINFO_TAG_BLANK:
-        ShouldNotReachHere2("Setting contended group for the blank field");
+        fatal("Setting contended group for the blank field");
       case FIELDINFO_TAG_OFFSET:
-        ShouldNotReachHere2("Setting contended group for field with offset");
+        fatal("Setting contended group for field with offset");
 #endif
     }
     ShouldNotReachHere();
--- a/src/share/vm/oops/generateOopMap.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/generateOopMap.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -762,6 +762,7 @@
 // monitor matching is purely informational and doesn't say anything
 // about the correctness of the code.
 void GenerateOopMap::merge_state_into_bb(BasicBlock *bb) {
+  guarantee(bb != NULL, "null basicblock");
   assert(bb->is_alive(), "merging state into a dead basicblock");
 
   if (_stack_top == bb->_stack_top) {
@@ -1189,6 +1190,7 @@
 
       if (start_pc <= bci && bci < end_pc) {
         BasicBlock *excBB = get_basic_block_at(handler_pc);
+        guarantee(excBB != NULL, "no basic block for exception");
         CellTypeState *excStk = excBB->stack();
         CellTypeState *cOpStck = stack();
         CellTypeState cOpStck_0 = cOpStck[0];
@@ -1803,6 +1805,7 @@
     // possibility that this bytecode will throw an
     // exception.
     BasicBlock* bb = get_basic_block_containing(bci);
+    guarantee(bb != NULL, "no basic block for bci");
     bb->set_changed(true);
     bb->_monitor_top = bad_monitors;
 
@@ -2190,6 +2193,7 @@
 
   // Find basicblock and report results
   BasicBlock* bb = get_basic_block_containing(bci);
+  guarantee(bb != NULL, "no basic block for bci");
   assert(bb->is_reachable(), "getting result from unreachable basicblock");
   bb->set_changed(true);
   interp_bb(bb);
--- a/src/share/vm/oops/instanceKlass.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/instanceKlass.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -2228,8 +2228,6 @@
 }
 
 void InstanceKlass::clean_method_data(BoolObjectClosure* is_alive) {
-#ifdef COMPILER2
-  // Currently only used by C2.
   for (int m = 0; m < methods()->length(); m++) {
     MethodData* mdo = methods()->at(m)->method_data();
     if (mdo != NULL) {
@@ -2240,15 +2238,6 @@
       }
     }
   }
-#else
-#ifdef ASSERT
-  // Verify that we haven't started to use MDOs for C1.
-  for (int m = 0; m < methods()->length(); m++) {
-    MethodData* mdo = methods()->at(m)->method_data();
-    assert(mdo == NULL, "Didn't expect C1 to use MDOs");
-  }
-#endif // ASSERT
-#endif // !COMPILER2
 }
 
 
@@ -3168,7 +3157,7 @@
     Array<int>* method_ordering = this->method_ordering();
     int length = method_ordering->length();
     if (JvmtiExport::can_maintain_original_method_order() ||
-        (UseSharedSpaces && length != 0)) {
+        ((UseSharedSpaces || DumpSharedSpaces) && length != 0)) {
       guarantee(length == methods()->length(), "invalid method ordering length");
       jlong sum = 0;
       for (int j = 0; j < length; j++) {
--- a/src/share/vm/oops/klass.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/klass.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -486,6 +486,12 @@
 }
 
 void Klass::remove_unshareable_info() {
+  if (!DumpSharedSpaces) {
+    // Clean up after OOM during class loading
+    if (class_loader_data() != NULL) {
+      class_loader_data()->remove_class(this);
+    }
+  }
   set_subklass(NULL);
   set_next_sibling(NULL);
   // Clear the java mirror
--- a/src/share/vm/oops/klassVtable.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/klassVtable.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -327,11 +327,11 @@
 
           if (target_loader() != super_loader()) {
             ResourceMark rm(THREAD);
-            char* failed_type_name =
+            Symbol* failed_type_symbol =
               SystemDictionary::check_signature_loaders(signature, target_loader,
                                                         super_loader, true,
                                                         CHECK_(false));
-            if (failed_type_name != NULL) {
+            if (failed_type_symbol != NULL) {
               const char* msg = "loader constraint violation: when resolving "
                 "overridden method \"%s\" the class loader (instance"
                 " of %s) of the current class, %s, and its superclass loader "
@@ -341,6 +341,7 @@
               const char* loader1 = SystemDictionary::loader_name(target_loader());
               char* current = _klass->name()->as_C_string();
               const char* loader2 = SystemDictionary::loader_name(super_loader());
+              char* failed_type_name = failed_type_symbol->as_C_string();
               size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
                 strlen(current) + strlen(loader2) + strlen(failed_type_name);
               char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
@@ -787,12 +788,12 @@
         Handle method_holder_loader (THREAD, target->method_holder()->class_loader());
         if (method_holder_loader() != interface_loader()) {
           ResourceMark rm(THREAD);
-          char* failed_type_name =
+          Symbol* failed_type_symbol =
             SystemDictionary::check_signature_loaders(method_signature,
                                                       method_holder_loader,
                                                       interface_loader,
                                                       true, CHECK);
-          if (failed_type_name != NULL) {
+          if (failed_type_symbol != NULL) {
             const char* msg = "loader constraint violation in interface "
               "itable initialization: when resolving method \"%s\" the class"
               " loader (instance of %s) of the current class, %s, "
@@ -804,6 +805,7 @@
             char* current = klass->name()->as_C_string();
             const char* loader2 = SystemDictionary::loader_name(interface_loader());
             char* iface = InstanceKlass::cast(interf_h())->name()->as_C_string();
+            char* failed_type_name = failed_type_symbol->as_C_string();
             size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
               strlen(current) + strlen(loader2) + strlen(iface) +
               strlen(failed_type_name);
--- a/src/share/vm/oops/method.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/method.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -798,7 +798,15 @@
   backedge_counter()->reset();
   _adapter = NULL;
   _from_compiled_entry = NULL;
-  assert(_method_data == NULL, "unexpected method data?");
+
+  // In case of DumpSharedSpaces, _method_data should always be NULL.
+  //
+  // During runtime (!DumpSharedSpaces), when we are cleaning a
+  // shared class that failed to load, this->link_method() may
+  // have already been called (before an exception happened), so
+  // this->_method_data may not be NULL.
+  assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?");
+
   set_method_data(NULL);
   set_interpreter_throwout_count(0);
   set_interpreter_invocation_count(0);
@@ -959,6 +967,32 @@
   return false;
 }
 
+
+/**
+ *  Returns true if this is one of the specially treated methods for
+ *  security related stack walks (like Reflection.getCallerClass).
+ */
+bool Method::is_ignored_by_security_stack_walk() const {
+  const bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection;
+
+  assert(intrinsic_id() != vmIntrinsics::_invoke || Universe::reflect_invoke_cache()->is_same_method((Method*)this), "sanity");
+  if (intrinsic_id() == vmIntrinsics::_invoke) {
+    // This is Method.invoke() -- ignore it
+    return true;
+  }
+  if (use_new_reflection &&
+      method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
+    // This is an auxilary frame -- ignore it
+    return true;
+  }
+  if (is_method_handle_intrinsic() || is_compiled_lambda_form()) {
+    // This is an internal adapter frame for method handles -- ignore it
+    return true;
+  }
+  return false;
+}
+
+
 // Constant pool structure for invoke methods:
 enum {
   _imcp_invoke_name = 1,        // utf8: 'invokeExact', etc.
@@ -1162,6 +1196,8 @@
     newm->set_stackmap_data(stackmap_data);
   }
 
+  // copy annotations over to new method
+  newcm->copy_annotations_from(cm);
   return newm;
 }
 
@@ -1170,13 +1206,13 @@
   // because we are not loading from core libraries
   // exception: the AES intrinsics come from lib/ext/sunjce_provider.jar
   // which does not use the class default class loader so we check for its loader here
-  if ((InstanceKlass::cast(holder)->class_loader() != NULL) &&
-       InstanceKlass::cast(holder)->class_loader()->klass()->name() != vmSymbols::sun_misc_Launcher_ExtClassLoader()) {
+  InstanceKlass* ik = InstanceKlass::cast(holder);
+  if ((ik->class_loader() != NULL) && !SystemDictionary::is_ext_class_loader(ik->class_loader())) {
     return vmSymbols::NO_SID;   // regardless of name, no intrinsics here
   }
 
   // see if the klass name is well-known:
-  Symbol* klass_name = InstanceKlass::cast(holder)->name();
+  Symbol* klass_name = ik->name();
   return vmSymbols::find_sid(klass_name);
 }
 
--- a/src/share/vm/oops/method.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/method.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -118,11 +118,12 @@
 #endif
   u2                _method_size;                // size of this object
   u1                _intrinsic_id;               // vmSymbols::intrinsic_id (0 == _none)
-  u1                _jfr_towrite  : 1,           // Flags
-                    _force_inline : 1,
-                    _hidden       : 1,
-                    _dont_inline  : 1,
-                                  : 4;
+  u1                _jfr_towrite      : 1,       // Flags
+                    _caller_sensitive : 1,
+                    _force_inline     : 1,
+                    _hidden           : 1,
+                    _dont_inline      : 1,
+                                      : 3;
   u2                _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
   u2                _number_of_breakpoints;      // fullspeed debugging support
   InvocationCounter _invocation_counter;         // Incremented before each activation of the method - used to trigger frequency-based optimizations
@@ -618,6 +619,9 @@
   // Reflection support
   bool is_overridden_in(Klass* k) const;
 
+  // Stack walking support
+  bool is_ignored_by_security_stack_walk() const;
+
   // JSR 292 support
   bool is_method_handle_intrinsic() const;          // MethodHandles::is_signature_polymorphic_intrinsic(intrinsic_id)
   bool is_compiled_lambda_form() const;             // intrinsic_id() == vmIntrinsics::_compiledLambdaForm
@@ -705,15 +709,16 @@
   void init_intrinsic_id();     // updates from _none if a match
   static vmSymbols::SID klass_id_for_intrinsics(Klass* holder);
 
-  bool jfr_towrite()                 { return _jfr_towrite; }
-  void set_jfr_towrite(bool towrite) { _jfr_towrite = towrite; }
-
-  bool     force_inline()       { return _force_inline;     }
-  void set_force_inline(bool x) {        _force_inline = x; }
-  bool     dont_inline()        { return _dont_inline;      }
-  void set_dont_inline(bool x)  {        _dont_inline = x;  }
-  bool  is_hidden()             { return _hidden;           }
-  void set_hidden(bool x)       {        _hidden = x;       }
+  bool     jfr_towrite()            { return _jfr_towrite;          }
+  void set_jfr_towrite(bool x)      {        _jfr_towrite = x;      }
+  bool     caller_sensitive()       { return _caller_sensitive;     }
+  void set_caller_sensitive(bool x) {        _caller_sensitive = x; }
+  bool     force_inline()           { return _force_inline;         }
+  void set_force_inline(bool x)     {        _force_inline = x;     }
+  bool     dont_inline()            { return _dont_inline;          }
+  void set_dont_inline(bool x)      {        _dont_inline = x;      }
+  bool  is_hidden()                 { return _hidden;               }
+  void set_hidden(bool x)           {        _hidden = x;           }
   ConstMethod::MethodType method_type() const {
       return _constMethod->method_type();
   }
--- a/src/share/vm/oops/methodData.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/methodData.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -392,6 +392,9 @@
 }
 
 int MethodData::bytecode_cell_count(Bytecodes::Code code) {
+#if defined(COMPILER1) && !defined(COMPILER2)
+  return no_profile_data;
+#else
   switch (code) {
   case Bytecodes::_checkcast:
   case Bytecodes::_instanceof:
@@ -438,6 +441,7 @@
     return variable_cell_count;
   }
   return no_profile_data;
+#endif
 }
 
 // Compute the size of the profiling information corresponding to
@@ -509,6 +513,9 @@
 // the segment in bytes.
 int MethodData::initialize_data(BytecodeStream* stream,
                                        int data_index) {
+#if defined(COMPILER1) && !defined(COMPILER2)
+  return 0;
+#else
   int cell_count = -1;
   int tag = DataLayout::no_tag;
   DataLayout* data_layout = data_layout_at(data_index);
@@ -587,6 +594,7 @@
     assert(!bytecode_has_profile(c), "agree w/ !BHP");
     return 0;
   }
+#endif
 }
 
 // Get the data at an arbitrary (sort of) data index.
--- a/src/share/vm/oops/symbol.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/oops/symbol.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -162,7 +162,7 @@
   const char *ptr = (const char *)&_body[0];
   int quoted_length = UTF8::quoted_ascii_length(ptr, utf8_length());
   char* result = NEW_RESOURCE_ARRAY(char, quoted_length + 1);
-  UTF8::as_quoted_ascii(ptr, result, quoted_length + 1);
+  UTF8::as_quoted_ascii(ptr, utf8_length(), result, quoted_length + 1);
   return result;
 }
 
--- a/src/share/vm/opto/block.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/block.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1028,26 +1028,6 @@
 }
 
 #ifndef PRODUCT
-static void edge_dump(GrowableArray<CFGEdge *> *edges) {
-  tty->print_cr("---- Edges ----");
-  for (int i = 0; i < edges->length(); i++) {
-    CFGEdge *e = edges->at(i);
-    if (e != NULL) {
-      edges->at(i)->dump();
-    }
-  }
-}
-
-static void trace_dump(Trace *traces[], int count) {
-  tty->print_cr("---- Traces ----");
-  for (int i = 0; i < count; i++) {
-    Trace *tr = traces[i];
-    if (tr != NULL) {
-      tr->dump();
-    }
-  }
-}
-
 void Trace::dump( ) const {
   tty->print_cr("Trace (freq %f)", first_block()->_freq);
   for (Block *b = first_block(); b != NULL; b = next(b)) {
--- a/src/share/vm/opto/bytecodeInfo.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/bytecodeInfo.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -157,9 +157,10 @@
   } else {
     // Not hot.  Check for medium-sized pre-existing nmethod at cold sites.
     if (callee_method->has_compiled_code() &&
-        callee_method->instructions_size() > inline_small_code_size)
+        callee_method->instructions_size() > inline_small_code_size) {
       set_msg("already compiled into a medium method");
       return false;
+    }
   }
   if (size > max_inline_size) {
     if (max_inline_size > default_max_inline_size) {
--- a/src/share/vm/opto/compile.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/compile.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -2326,12 +2326,14 @@
   int  get_inner_loop_count() const { return _inner_loop_count; }
 };
 
+#ifdef ASSERT
 static bool oop_offset_is_sane(const TypeInstPtr* tp) {
   ciInstanceKlass *k = tp->klass()->as_instance_klass();
   // Make sure the offset goes inside the instance layout.
   return k->contains_field_offset(tp->offset());
   // Note that OffsetBot and OffsetTop are very negative.
 }
+#endif
 
 // Eliminate trivially redundant StoreCMs and accumulate their
 // precedence edges.
--- a/src/share/vm/opto/connode.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/connode.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -465,29 +465,6 @@
   return (phase->type(in(1)) == phase->type(this)) ? in(1) : this;
 }
 
-// Determine whether "n" is a node which can cause an alias of one of its inputs.  Node types
-// which can create aliases are: CheckCastPP, Phi, and any store (if there is also a load from
-// the location.)
-// Note:  this checks for aliases created in this compilation, not ones which may
-//        be potentially created at call sites.
-static bool can_cause_alias(Node *n, PhaseTransform *phase) {
-  bool possible_alias = false;
-
-  if (n->is_Store()) {
-    possible_alias = !n->as_Store()->value_never_loaded(phase);
-  } else {
-    int opc = n->Opcode();
-    possible_alias = n->is_Phi() ||
-        opc == Op_CheckCastPP ||
-        opc == Op_StorePConditional ||
-        opc == Op_CompareAndSwapP ||
-        opc == Op_CompareAndSwapN ||
-        opc == Op_GetAndSetP ||
-        opc == Op_GetAndSetN;
-  }
-  return possible_alias;
-}
-
 //------------------------------Value------------------------------------------
 // Take 'join' of input and cast-up type, unless working with an Interface
 const Type *CheckCastPPNode::Value( PhaseTransform *phase ) const {
--- a/src/share/vm/opto/graphKit.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/graphKit.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -3445,7 +3445,6 @@
 
 void GraphKit::final_sync(IdealKit& ideal) {
   // Final sync IdealKit and graphKit.
-  __ drain_delay_transform();
   sync_kit(ideal);
 }
 
--- a/src/share/vm/opto/idealKit.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/idealKit.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -48,9 +48,9 @@
   _cvstate = NULL;
   // We can go memory state free or else we need the entire memory state
   assert(_initial_memory == NULL || _initial_memory->Opcode() == Op_MergeMem, "memory must be pre-split");
+  assert(!_gvn.is_IterGVN(), "IdealKit can't be used during Optimize phase");
   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);
   DEBUG_ONLY(_state = new (C->node_arena()) GrowableArray<int>(C->node_arena(), init_size, 0, 0));
   if (!has_declarations) {
      declarations_done();
@@ -296,19 +296,16 @@
     return delay_transform(n);
   } else {
     n = gvn().transform(n);
-    if (!gvn().is_IterGVN()) {
-      C->record_for_igvn(n);
-    }
+    C->record_for_igvn(n);
     return n;
   }
 }
 
 //-----------------------------delay_transform-----------------------------------
 Node* IdealKit::delay_transform(Node* n) {
-  if (!gvn().is_IterGVN() || !gvn().is_IterGVN()->delay_transform()) {
-    gvn().set_type(n, n->bottom_type());
-  }
-  _delay_transform->push(n);
+  // Delay transform until IterativeGVN
+  gvn().set_type(n, n->bottom_type());
+  C->record_for_igvn(n);
   return n;
 }
 
@@ -332,17 +329,6 @@
   for (uint i = 0; i < m->req(); i++) m->set_req(i, NULL);
 }
 
-//-----------------------------drain_delay_transform----------------------------
-void IdealKit::drain_delay_transform() {
-  while (_delay_transform->length() > 0) {
-    Node* n = _delay_transform->pop();
-    gvn().transform(n);
-    if (!gvn().is_IterGVN()) {
-      C->record_for_igvn(n);
-    }
-  }
-}
-
 //-----------------------------IdealVariable----------------------------
 IdealVariable::IdealVariable(IdealKit &k) {
   k.declare(this);
@@ -351,9 +337,7 @@
 Node* IdealKit::memory(uint alias_idx) {
   MergeMemNode* mem = merged_memory();
   Node* p = mem->memory_at(alias_idx);
-  if (!gvn().is_IterGVN() || !gvn().is_IterGVN()->delay_transform()) {
-    _gvn.set_type(p, Type::MEMORY);  // must be mapped
-  }
+  _gvn.set_type(p, Type::MEMORY);  // must be mapped
   return p;
 }
 
--- a/src/share/vm/opto/idealKit.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/idealKit.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -102,7 +102,6 @@
   Compile * const C;
   PhaseGVN &_gvn;
   GrowableArray<Node*>* _pending_cvstates; // stack of cvstates
-  GrowableArray<Node*>* _delay_transform;  // delay invoking gvn.transform until drain
   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
@@ -121,7 +120,7 @@
   void clear(Node* m);                     // clear a cvstate
   void stop() { clear(_cvstate); }         // clear current cvstate
   Node* delay_transform(Node* n);
-  Node* transform(Node* n);                // gvn.transform or push node on delay list
+  Node* transform(Node* n);                // gvn.transform or skip it
   Node* promote_to_phi(Node* n, Node* reg);// Promote "n" to a phi on region "reg"
   bool was_promoted_to_phi(Node* n, Node* reg) {
     return (n->is_Phi() && n->in(0) == reg);
@@ -146,7 +145,6 @@
   IdealKit(GraphKit* gkit, bool delay_all_transforms = false, bool has_declarations = false);
   ~IdealKit() {
     stop();
-    drain_delay_transform();
   }
   void sync_kit(GraphKit* gkit);
 
@@ -173,7 +171,6 @@
   void bind(Node* lab);
   void goto_(Node* lab, bool bind = false);
   void declarations_done();
-  void drain_delay_transform();
 
   Node* IfTrue(IfNode* iff)  { return transform(new (C) IfTrueNode(iff)); }
   Node* IfFalse(IfNode* iff) { return transform(new (C) IfFalseNode(iff)); }
@@ -198,7 +195,11 @@
   Node* thread()  {  return gvn().transform(new (C) ThreadLocalNode()); }
 
   // Pointers
-  Node* AddP(Node *base, Node *ptr, Node *off) { return transform(new (C) AddPNode(base, ptr, off)); }
+
+  // Raw address should be transformed regardless 'delay_transform' flag
+  // to produce canonical form CastX2P(offset).
+  Node* AddP(Node *base, Node *ptr, Node *off) { return _gvn.transform(new (C) AddPNode(base, ptr, off)); }
+
   Node* CmpP(Node* l, Node* r) { return transform(new (C) CmpPNode(l, r)); }
 #ifdef _LP64
   Node* XorX(Node* l, Node* r) { return transform(new (C) XorLNode(l, r)); }
@@ -208,8 +209,6 @@
   Node* URShiftX(Node* l, Node* r) { return transform(new (C) URShiftXNode(l, r)); }
   Node* ConX(jint k) { return (Node*)gvn().MakeConX(k); }
   Node* CastPX(Node* ctl, Node* p) { return transform(new (C) CastP2XNode(ctl, p)); }
-  // Add a fixed offset to a pointer
-  Node* basic_plus_adr(Node* base, Node* ptr, intptr_t offset);
 
   // Memory operations
 
--- a/src/share/vm/opto/ifg.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/ifg.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -37,8 +37,6 @@
 #include "opto/memnode.hpp"
 #include "opto/opcodes.hpp"
 
-#define EXACT_PRESSURE 1
-
 //=============================================================================
 //------------------------------IFG--------------------------------------------
 PhaseIFG::PhaseIFG( Arena *arena ) : Phase(Interference_Graph), _arena(arena) {
@@ -445,23 +443,15 @@
       pressure[1] -= lrg->reg_pressure();
       if( pressure[1] == (uint)FLOATPRESSURE ) {
         hrp_index[1] = where;
-#ifdef EXACT_PRESSURE
-      if( pressure[1] > b->_freg_pressure )
-        b->_freg_pressure = pressure[1]+1;
-#else
-        b->_freg_pressure = (uint)FLOATPRESSURE+1;
-#endif
+        if( pressure[1] > b->_freg_pressure )
+          b->_freg_pressure = pressure[1]+1;
       }
     } else if( lrg->mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) ) {
       pressure[0] -= lrg->reg_pressure();
       if( pressure[0] == (uint)INTPRESSURE   ) {
         hrp_index[0] = where;
-#ifdef EXACT_PRESSURE
-      if( pressure[0] > b->_reg_pressure )
-        b->_reg_pressure = pressure[0]+1;
-#else
-        b->_reg_pressure = (uint)INTPRESSURE+1;
-#endif
+        if( pressure[0] > b->_reg_pressure )
+          b->_reg_pressure = pressure[0]+1;
       }
     }
   }
@@ -526,17 +516,13 @@
       if (lrg.mask().is_UP() && lrg.mask_size()) {
         if (lrg._is_float || lrg._is_vector) {   // Count float pressure
           pressure[1] += lrg.reg_pressure();
-#ifdef EXACT_PRESSURE
           if( pressure[1] > b->_freg_pressure )
             b->_freg_pressure = pressure[1];
-#endif
           // Count int pressure, but do not count the SP, flags
         } else if( lrgs(lidx).mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) ) {
           pressure[0] += lrg.reg_pressure();
-#ifdef EXACT_PRESSURE
           if( pressure[0] > b->_reg_pressure )
             b->_reg_pressure = pressure[0];
-#endif
         }
       }
     }
@@ -589,30 +575,20 @@
             RegMask itmp = lrgs(r).mask();
             itmp.AND(*Matcher::idealreg2regmask[Op_RegI]);
             int iregs = itmp.Size();
-#ifdef EXACT_PRESSURE
             if( pressure[0]+iregs > b->_reg_pressure )
               b->_reg_pressure = pressure[0]+iregs;
-#endif
             if( pressure[0]       <= (uint)INTPRESSURE &&
                 pressure[0]+iregs >  (uint)INTPRESSURE ) {
-#ifndef EXACT_PRESSURE
-              b->_reg_pressure = (uint)INTPRESSURE+1;
-#endif
               hrp_index[0] = j-1;
             }
             // Count the float-only registers
             RegMask ftmp = lrgs(r).mask();
             ftmp.AND(*Matcher::idealreg2regmask[Op_RegD]);
             int fregs = ftmp.Size();
-#ifdef EXACT_PRESSURE
             if( pressure[1]+fregs > b->_freg_pressure )
               b->_freg_pressure = pressure[1]+fregs;
-#endif
             if( pressure[1]       <= (uint)FLOATPRESSURE &&
                 pressure[1]+fregs >  (uint)FLOATPRESSURE ) {
-#ifndef EXACT_PRESSURE
-              b->_freg_pressure = (uint)FLOATPRESSURE+1;
-#endif
               hrp_index[1] = j-1;
             }
           }
@@ -769,16 +745,12 @@
             if (lrg.mask().is_UP() && lrg.mask_size()) {
               if (lrg._is_float || lrg._is_vector) {
                 pressure[1] += lrg.reg_pressure();
-#ifdef EXACT_PRESSURE
                 if( pressure[1] > b->_freg_pressure )
                   b->_freg_pressure = pressure[1];
-#endif
               } else if( lrg.mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) ) {
                 pressure[0] += lrg.reg_pressure();
-#ifdef EXACT_PRESSURE
                 if( pressure[0] > b->_reg_pressure )
                   b->_reg_pressure = pressure[0];
-#endif
               }
             }
             assert( pressure[0] == count_int_pressure  (&liveout), "" );
@@ -794,21 +766,13 @@
     // the whole block is high pressure.
     if( pressure[0] > (uint)INTPRESSURE   ) {
       hrp_index[0] = 0;
-#ifdef EXACT_PRESSURE
       if( pressure[0] > b->_reg_pressure )
         b->_reg_pressure = pressure[0];
-#else
-      b->_reg_pressure = (uint)INTPRESSURE+1;
-#endif
     }
     if( pressure[1] > (uint)FLOATPRESSURE ) {
       hrp_index[1] = 0;
-#ifdef EXACT_PRESSURE
       if( pressure[1] > b->_freg_pressure )
         b->_freg_pressure = pressure[1];
-#else
-      b->_freg_pressure = (uint)FLOATPRESSURE+1;
-#endif
     }
 
     // Compute high pressure indice; avoid landing in the middle of projnodes
--- a/src/share/vm/opto/library_call.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/library_call.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -231,7 +231,6 @@
   void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark);
   bool inline_native_clone(bool is_virtual);
   bool inline_native_Reflection_getCallerClass();
-  bool is_method_invoke_or_aux_frame(JVMState* jvms);
   // Helper function for inlining native object hash method
   bool inline_native_hashcode(bool is_virtual, bool is_static);
   bool inline_native_getClass();
@@ -393,7 +392,7 @@
   case vmIntrinsics::_getCallerClass:
     if (!UseNewReflection)  return NULL;
     if (!InlineReflectionGetCallerClass)  return NULL;
-    if (!JDK_Version::is_gte_jdk14x_version())  return NULL;
+    if (SystemDictionary::reflect_CallerSensitive_klass() == NULL)  return NULL;
     break;
 
   case vmIntrinsics::_bitCount_i:
@@ -3872,13 +3871,13 @@
 }
 
 //-----------------inline_native_Reflection_getCallerClass---------------------
-// public static native Class<?> sun.reflect.Reflection.getCallerClass(int realFramesToSkip);
+// public static native Class<?> sun.reflect.Reflection.getCallerClass();
 //
 // In the presence of deep enough inlining, getCallerClass() becomes a no-op.
 //
-// NOTE that this code must perform the same logic as
-// vframeStream::security_get_caller_frame in that it must skip
-// Method.invoke() and auxiliary frames.
+// NOTE: This code must perform the same logic as JVM_GetCallerClass
+// in that it must skip particular security frames and checks for
+// caller sensitive methods.
 bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
 #ifndef PRODUCT
   if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
@@ -3886,35 +3885,6 @@
   }
 #endif
 
-  Node* caller_depth_node = argument(0);
-
-  // The depth value must be a constant in order for the runtime call
-  // to be eliminated.
-  const TypeInt* caller_depth_type = _gvn.type(caller_depth_node)->isa_int();
-  if (caller_depth_type == NULL || !caller_depth_type->is_con()) {
-#ifndef PRODUCT
-    if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
-      tty->print_cr("  Bailing out because caller depth was not a constant");
-    }
-#endif
-    return false;
-  }
-  // Note that the JVM state at this point does not include the
-  // getCallerClass() frame which we are trying to inline. The
-  // semantics of getCallerClass(), however, are that the "first"
-  // frame is the getCallerClass() frame, so we subtract one from the
-  // requested depth before continuing. We don't inline requests of
-  // getCallerClass(0).
-  int caller_depth = caller_depth_type->get_con() - 1;
-  if (caller_depth < 0) {
-#ifndef PRODUCT
-    if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
-      tty->print_cr("  Bailing out because caller depth was %d", caller_depth);
-    }
-#endif
-    return false;
-  }
-
   if (!jvms()->has_method()) {
 #ifndef PRODUCT
     if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
@@ -3923,96 +3893,67 @@
 #endif
     return false;
   }
-  int _depth = jvms()->depth();  // cache call chain depth
 
   // Walk back up the JVM state to find the caller at the required
-  // depth. NOTE that this code must perform the same logic as
-  // vframeStream::security_get_caller_frame in that it must skip
-  // Method.invoke() and auxiliary frames. Note also that depth is
-  // 1-based (1 is the bottom of the inlining).
-  int inlining_depth = _depth;
-  JVMState* caller_jvms = NULL;
-
-  if (inlining_depth > 0) {
-    caller_jvms = jvms();
-    assert(caller_jvms = jvms()->of_depth(inlining_depth), "inlining_depth == our depth");
-    do {
-      // The following if-tests should be performed in this order
-      if (is_method_invoke_or_aux_frame(caller_jvms)) {
-        // Skip a Method.invoke() or auxiliary frame
-      } else if (caller_depth > 0) {
-        // Skip real frame
-        --caller_depth;
-      } else {
-        // We're done: reached desired caller after skipping.
-        break;
+  // depth.
+  JVMState* caller_jvms = jvms();
+
+  // Cf. JVM_GetCallerClass
+  // NOTE: Start the loop at depth 1 because the current JVM state does
+  // not include the Reflection.getCallerClass() frame.
+  for (int n = 1; caller_jvms != NULL; caller_jvms = caller_jvms->caller(), n++) {
+    ciMethod* m = caller_jvms->method();
+    switch (n) {
+    case 0:
+      fatal("current JVM state does not include the Reflection.getCallerClass frame");
+      break;
+    case 1:
+      // Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass).
+      if (!m->caller_sensitive()) {
+#ifndef PRODUCT
+        if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
+          tty->print_cr("  Bailing out: CallerSensitive annotation expected at frame %d", n);
+        }
+#endif
+        return false;  // bail-out; let JVM_GetCallerClass do the work
       }
-      caller_jvms = caller_jvms->caller();
-      --inlining_depth;
-    } while (inlining_depth > 0);
-  }
-
-  if (inlining_depth == 0) {
+      break;
+    default:
+      if (!m->is_ignored_by_security_stack_walk()) {
+        // We have reached the desired frame; return the holder class.
+        // Acquire method holder as java.lang.Class and push as constant.
+        ciInstanceKlass* caller_klass = caller_jvms->method()->holder();
+        ciInstance* caller_mirror = caller_klass->java_mirror();
+        set_result(makecon(TypeInstPtr::make(caller_mirror)));
+
 #ifndef PRODUCT
-    if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
-      tty->print_cr("  Bailing out because caller depth (%d) exceeded inlining depth (%d)", caller_depth_type->get_con(), _depth);
-      tty->print_cr("  JVM state at this point:");
-      for (int i = _depth; i >= 1; i--) {
-        ciMethod* m = jvms()->of_depth(i)->method();
-        tty->print_cr("   %d) %s.%s", i, m->holder()->name()->as_utf8(), m->name()->as_utf8());
-      }
-    }
+        if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
+          tty->print_cr("  Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth());
+          tty->print_cr("  JVM state at this point:");
+          for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) {
+            ciMethod* m = jvms()->of_depth(i)->method();
+            tty->print_cr("   %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8());
+          }
+        }
 #endif
-    return false; // Reached end of inlining
+        return true;
+      }
+      break;
+    }
   }
 
-  // Acquire method holder as java.lang.Class
-  ciInstanceKlass* caller_klass  = caller_jvms->method()->holder();
-  ciInstance*      caller_mirror = caller_klass->java_mirror();
-
-  // Push this as a constant
-  set_result(makecon(TypeInstPtr::make(caller_mirror)));
-
 #ifndef PRODUCT
   if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
-    tty->print_cr("  Succeeded: caller = %s.%s, caller depth = %d, depth = %d", caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), caller_depth_type->get_con(), _depth);
+    tty->print_cr("  Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth());
     tty->print_cr("  JVM state at this point:");
-    for (int i = _depth; i >= 1; i--) {
+    for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) {
       ciMethod* m = jvms()->of_depth(i)->method();
-      tty->print_cr("   %d) %s.%s", i, m->holder()->name()->as_utf8(), m->name()->as_utf8());
+      tty->print_cr("   %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8());
     }
   }
 #endif
-  return true;
-}
-
-// Helper routine for above
-bool LibraryCallKit::is_method_invoke_or_aux_frame(JVMState* jvms) {
-  ciMethod* method = jvms->method();
-
-  // Is this the Method.invoke method itself?
-  if (method->intrinsic_id() == vmIntrinsics::_invoke)
-    return true;
-
-  // Is this a helper, defined somewhere underneath MethodAccessorImpl.
-  ciKlass* k = method->holder();
-  if (k->is_instance_klass()) {
-    ciInstanceKlass* ik = k->as_instance_klass();
-    for (; ik != NULL; ik = ik->super()) {
-      if (ik->name() == ciSymbol::sun_reflect_MethodAccessorImpl() &&
-          ik == env()->find_system_klass(ik->name())) {
-        return true;
-      }
-    }
-  }
-
-  if (method->is_method_handle_intrinsic() ||
-      method->is_compiled_lambda_form()) {
-    // This is an internal adapter frame from the MethodHandleCompiler -- skip it
-    return true;
-  }
-
-  return false;
+
+  return false;  // bail-out; let JVM_GetCallerClass do the work
 }
 
 bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) {
--- a/src/share/vm/opto/loopTransform.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/loopTransform.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -888,6 +888,7 @@
   CountedLoopNode *main_head = loop->_head->as_CountedLoop();
   assert( main_head->is_normal_loop(), "" );
   CountedLoopEndNode *main_end = main_head->loopexit();
+  guarantee(main_end != NULL, "no loop exit node");
   assert( main_end->outcnt() == 2, "1 true, 1 false path only" );
   uint dd_main_head = dom_depth(main_head);
   uint max = main_head->outcnt();
@@ -2554,13 +2555,16 @@
   ok.set(store->_idx);
   ok.set(store->in(MemNode::Memory)->_idx);
 
+  CountedLoopEndNode* loop_exit = head->loopexit();
+  guarantee(loop_exit != NULL, "no loop exit node");
+
   // Loop structure is ok
   ok.set(head->_idx);
-  ok.set(head->loopexit()->_idx);
+  ok.set(loop_exit->_idx);
   ok.set(head->phi()->_idx);
   ok.set(head->incr()->_idx);
-  ok.set(head->loopexit()->cmp_node()->_idx);
-  ok.set(head->loopexit()->in(1)->_idx);
+  ok.set(loop_exit->cmp_node()->_idx);
+  ok.set(loop_exit->in(1)->_idx);
 
   // Address elements are ok
   if (con)   ok.set(con->_idx);
@@ -2572,7 +2576,7 @@
     if (n->outcnt() == 0) continue; // Ignore dead
     if (ok.test(n->_idx)) continue;
     // Backedge projection is ok
-    if (n->is_IfTrue() && n->in(0) == head->loopexit()) continue;
+    if (n->is_IfTrue() && n->in(0) == loop_exit) continue;
     if (!n->is_AddP()) {
       msg = "unhandled node";
       msg_node = n;
@@ -2585,7 +2589,7 @@
     Node* n = lpt->_body.at(i);
     // These values can be replaced with other nodes if they are used
     // outside the loop.
-    if (n == store || n == head->loopexit() || n == head->incr() || n == store->in(MemNode::Memory)) continue;
+    if (n == store || n == loop_exit || n == head->incr() || n == store->in(MemNode::Memory)) continue;
     for (SimpleDUIterator iter(n); iter.has_next(); iter.next()) {
       Node* use = iter.get();
       if (!lpt->_body.contains(use)) {
--- a/src/share/vm/opto/loopnode.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/loopnode.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -2251,6 +2251,11 @@
     return;
   }
 
+  // clear out the dead code after build_loop_late
+  while (_deadlist.size()) {
+    _igvn.remove_globally_dead_node(_deadlist.pop());
+  }
+
   if (stop_early) {
     assert(do_expensive_nodes, "why are we here?");
     if (process_expensive_nodes()) {
@@ -2260,9 +2265,7 @@
       // nodes again.
       C->set_major_progress();
     }
-
     _igvn.optimize();
-
     return;
   }
 
@@ -2273,11 +2276,6 @@
     eliminate_useless_predicates();
   }
 
-  // clear out the dead code
-  while(_deadlist.size()) {
-    _igvn.remove_globally_dead_node(_deadlist.pop());
-  }
-
 #ifndef PRODUCT
   C->verify_graph_edges();
   if (_verify_me) {             // Nested verify pass?
--- a/src/share/vm/opto/loopnode.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/loopnode.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -603,7 +603,10 @@
   }
 
 public:
-  bool has_node( Node* n ) const { return _nodes[n->_idx] != NULL; }
+  bool has_node( Node* n ) const {
+    guarantee(n != NULL, "No Node.");
+    return _nodes[n->_idx] != NULL;
+  }
   // check if transform created new nodes that need _ctrl recorded
   Node *get_late_ctrl( Node *n, Node *early );
   Node *get_early_ctrl( Node *n );
@@ -737,7 +740,8 @@
     return n;
   }
   uint dom_depth(Node* d) const {
-    assert(d->_idx < _idom_size, "");
+    guarantee(d != NULL, "Null dominator info.");
+    guarantee(d->_idx < _idom_size, "");
     return _dom_depth[d->_idx];
   }
   void set_idom(Node* d, Node* n, uint dom_depth);
--- a/src/share/vm/opto/loopopts.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/loopopts.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -232,7 +232,11 @@
   // Loop predicates may have depending checks which should not
   // be skipped. For example, range check predicate has two checks
   // for lower and upper bounds.
-  ProjNode* unc_proj = iff->as_If()->proj_out(1 - dp->as_Proj()->_con)->as_Proj();
+  if (dp == NULL)
+    return;
+
+  ProjNode* dp_proj  = dp->as_Proj();
+  ProjNode* unc_proj = iff->as_If()->proj_out(1 - dp_proj->_con)->as_Proj();
   if (exclude_loop_predicate &&
       is_uncommon_trap_proj(unc_proj, Deoptimization::Reason_predicate))
     return; // Let IGVN transformation change control dependence.
@@ -866,8 +870,11 @@
 
     // Now split the bool up thru the phi
     Node *bolphi = split_thru_phi( bol, n_ctrl, -1 );
+    guarantee(bolphi != NULL, "null boolean phi node");
+
     _igvn.replace_node( bol, bolphi );
     assert( iff->in(1) == bolphi, "" );
+
     if( bolphi->Value(&_igvn)->singleton() )
       return;
 
@@ -1628,6 +1635,7 @@
 //------------------------------ short_circuit_if -------------------------------------
 // Force the iff control output to be the live_proj
 Node* PhaseIdealLoop::short_circuit_if(IfNode* iff, ProjNode* live_proj) {
+  guarantee(live_proj != NULL, "null projection");
   int proj_con = live_proj->_con;
   assert(proj_con == 0 || proj_con == 1, "false or true projection");
   Node *con = _igvn.intcon(proj_con);
@@ -1686,6 +1694,7 @@
   set_idom(proj, new_if, ddepth);
 
   ProjNode* new_exit = proj_clone(other_proj, new_if)->as_Proj();
+  guarantee(new_exit != NULL, "null exit node");
   register_node(new_exit, get_loop(other_proj), new_if, ddepth);
 
   return new_exit;
@@ -1793,7 +1802,10 @@
   int stride = stride_of_possible_iv(if_cmpu);
   if (stride == 0) return NULL;
 
-  ProjNode* lp_continue = stay_in_loop(if_cmpu, loop)->as_Proj();
+  Node* lp_proj = stay_in_loop(if_cmpu, loop);
+  guarantee(lp_proj != NULL, "null loop node");
+
+  ProjNode* lp_continue = lp_proj->as_Proj();
   ProjNode* lp_exit     = if_cmpu->proj_out(!lp_continue->is_IfTrue())->as_Proj();
 
   Node* limit = NULL;
@@ -1805,6 +1817,7 @@
   }
   // Create a new region on the exit path
   RegionNode* reg = insert_region_before_proj(lp_exit);
+  guarantee(reg != NULL, "null region node");
 
   // Clone the if-cmpu-true-false using a signed compare
   BoolTest::mask rel_i = stride > 0 ? bol->_test._test : BoolTest::ge;
--- a/src/share/vm/opto/output.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/output.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -449,6 +449,17 @@
       int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit();
       if (max_loop_pad > 0) {
         assert(is_power_of_2(max_loop_pad+relocInfo::addr_unit()), "");
+        // Adjust last_call_adr and/or last_avoid_back_to_back_adr.
+        // If either is the last instruction in this block, bump by
+        // max_loop_pad in lock-step with blk_size, so sizing
+        // calculations in subsequent blocks still can conservatively
+        // detect that it may the last instruction in this block.
+        if (last_call_adr == blk_starts[i]+blk_size) {
+          last_call_adr += max_loop_pad;
+        }
+        if (last_avoid_back_to_back_adr == blk_starts[i]+blk_size) {
+          last_avoid_back_to_back_adr += max_loop_pad;
+        }
         blk_size += max_loop_pad;
       }
     }
@@ -1193,8 +1204,6 @@
   int last_call_offset = -1;
   int last_avoid_back_to_back_offset = -1;
 #ifdef ASSERT
-  int block_alignment_padding = 0;
-
   uint* jmp_target = NEW_RESOURCE_ARRAY(uint,nblocks);
   uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks);
   uint* jmp_size   = NEW_RESOURCE_ARRAY(uint,nblocks);
@@ -1228,8 +1237,6 @@
   Node *delay_slot = NULL;
 
   for (uint i=0; i < nblocks; i++) {
-    guarantee(blk_starts[i] >= (uint)cb->insts_size(),"should not increase size");
-
     Block *b = _cfg->_blocks[i];
 
     Node *head = b->head();
@@ -1250,14 +1257,6 @@
     jmp_offset[i] = 0;
     jmp_size[i]   = 0;
     jmp_rule[i]   = 0;
-
-    // Maximum alignment padding for loop block was used
-    // during first round of branches shortening, as result
-    // padding for nodes (sfpt after call) was not added.
-    // Take this into account for block's size change check
-    // and allow increase block's size by the difference
-    // of maximum and actual alignment paddings.
-    int orig_blk_size = blk_starts[i+1] - blk_starts[i] + block_alignment_padding;
 #endif
     int blk_offset = current_offset;
 
@@ -1557,8 +1556,6 @@
       }
 
     } // End for all instructions in block
-    assert((uint)blk_offset <= blk_starts[i], "shouldn't increase distance");
-    blk_starts[i] = blk_offset;
 
     // If the next block is the top of a loop, pad this block out to align
     // the loop top a little. Helps prevent pipe stalls at loop back branches.
@@ -1572,16 +1569,13 @@
         nop->emit(*cb, _regalloc);
         current_offset = cb->insts_size();
       }
-#ifdef ASSERT
-      int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit();
-      block_alignment_padding = (max_loop_pad - padding);
-      assert(block_alignment_padding >= 0, "sanity");
-#endif
     }
     // Verify that the distance for generated before forward
     // short branches is still valid.
-    assert(orig_blk_size >= (current_offset - blk_offset), "shouldn't increase block size");
-
+    guarantee((int)(blk_starts[i+1] - blk_starts[i]) >= (current_offset - blk_offset), "shouldn't increase block size");
+
+    // Save new block start offset
+    blk_starts[i] = blk_offset;
   } // End of for all blocks
   blk_starts[nblocks] = current_offset;
 
@@ -2518,6 +2512,7 @@
     // Schedule the remaining instructions in the block
     while ( _available.size() > 0 ) {
       Node *n = ChooseNodeToBundle();
+      guarantee(n != NULL, "no nodes available");
       AddNodeToBundle(n,bb);
     }
 
--- a/src/share/vm/opto/parse2.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/parse2.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -104,7 +104,8 @@
     if (C->log() != NULL)   C->log()->elem("observe that='!need_range_check'");
   }
 
-  if (!arytype->klass()->is_loaded()) {
+  ciKlass * arytype_klass = arytype->klass();
+  if ((arytype_klass != NULL) && (!arytype_klass->is_loaded())) {
     // Only fails for some -Xcomp runs
     // The class is unloaded.  We have to run this bytecode in the interpreter.
     uncommon_trap(Deoptimization::Reason_unloaded,
@@ -1385,6 +1386,7 @@
   if (TraceOptoParse) {
     tty->print(" @");
     dump_bci(bci());
+    tty->cr();
   }
 #endif
 
--- a/src/share/vm/opto/phaseX.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/phaseX.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1166,31 +1166,30 @@
     if (progress_state == PROCESS_INPUTS) {
       // After following inputs, continue to outputs
       _stack.set_index(PROCESS_OUTPUTS);
-      // Remove from iterative worklist
-      _worklist.remove(dead);
       if (!dead->is_Con()) { // Don't kill cons but uses
         bool recurse = false;
         // Remove from hash table
         _table.hash_delete( dead );
         // Smash all inputs to 'dead', isolating him completely
-        for( uint i = 0; i < dead->req(); i++ ) {
+        for (uint i = 0; i < dead->req(); i++) {
           Node *in = dead->in(i);
-          if( in ) {                 // Points to something?
-            dead->set_req(i,NULL);  // Kill the edge
-            if (in->outcnt() == 0 && in != C->top()) {// Made input go dead?
+          if (in != NULL && in != C->top()) {  // Points to something?
+            int nrep = dead->replace_edge(in, NULL);  // Kill edges
+            assert((nrep > 0), "sanity");
+            if (in->outcnt() == 0) { // Made input go dead?
               _stack.push(in, PROCESS_INPUTS); // Recursively remove
               recurse = true;
             } else if (in->outcnt() == 1 &&
                        in->has_special_unique_user()) {
               _worklist.push(in->unique_out());
             } else if (in->outcnt() <= 2 && dead->is_Phi()) {
-              if( in->Opcode() == Op_Region )
+              if (in->Opcode() == Op_Region) {
                 _worklist.push(in);
-              else if( in->is_Store() ) {
+              } else if (in->is_Store()) {
                 DUIterator_Fast imax, i = in->fast_outs(imax);
                 _worklist.push(in->fast_out(i));
                 i++;
-                if(in->outcnt() == 2) {
+                if (in->outcnt() == 2) {
                   _worklist.push(in->fast_out(i));
                   i++;
                 }
@@ -1209,38 +1208,42 @@
                 }
               }
             }
-          }
-        }
-        C->record_dead_node(dead->_idx);
-        if (dead->is_macro()) {
-          C->remove_macro_node(dead);
-        }
-        if (dead->is_expensive()) {
-          C->remove_expensive_node(dead);
-        }
-
+          } // if (in != NULL && in != C->top())
+        } // for (uint i = 0; i < dead->req(); i++)
         if (recurse) {
           continue;
         }
-      }
-      // Constant node that has no out-edges and has only one in-edge from
-      // root is usually dead. However, sometimes reshaping walk makes
-      // it reachable by adding use edges. So, we will NOT count Con nodes
-      // as dead to be conservative about the dead node count at any
-      // given time.
-    }
+      } // if (!dead->is_Con())
+    } // if (progress_state == PROCESS_INPUTS)
 
     // Aggressively kill globally dead uses
     // (Rather than pushing all the outs at once, we push one at a time,
     // plus the parent to resume later, because of the indefinite number
     // of edge deletions per loop trip.)
     if (dead->outcnt() > 0) {
-      // Recursively remove
+      // Recursively remove output edges
       _stack.push(dead->raw_out(0), PROCESS_INPUTS);
     } else {
+      // Finished disconnecting all input and output edges.
       _stack.pop();
+      // Remove dead node from iterative worklist
+      _worklist.remove(dead);
+      // Constant node that has no out-edges and has only one in-edge from
+      // root is usually dead. However, sometimes reshaping walk makes
+      // it reachable by adding use edges. So, we will NOT count Con nodes
+      // as dead to be conservative about the dead node count at any
+      // given time.
+      if (!dead->is_Con()) {
+        C->record_dead_node(dead->_idx);
+      }
+      if (dead->is_macro()) {
+        C->remove_macro_node(dead);
+      }
+      if (dead->is_expensive()) {
+        C->remove_expensive_node(dead);
+      }
     }
-  }
+  } // while (_stack.is_nonempty())
 }
 
 //------------------------------subsume_node-----------------------------------
--- a/src/share/vm/opto/subnode.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/subnode.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1078,16 +1078,6 @@
   return (_test._test == b->_test._test);
 }
 
-//------------------------------clone_cmp--------------------------------------
-// Clone a compare/bool tree
-static Node *clone_cmp( Node *cmp, Node *cmp1, Node *cmp2, PhaseGVN *gvn, BoolTest::mask test ) {
-  Node *ncmp = cmp->clone();
-  ncmp->set_req(1,cmp1);
-  ncmp->set_req(2,cmp2);
-  ncmp = gvn->transform( ncmp );
-  return new (gvn->C) BoolNode( ncmp, test );
-}
-
 //-------------------------------make_predicate--------------------------------
 Node* BoolNode::make_predicate(Node* test_value, PhaseGVN* phase) {
   if (test_value->is_Con())   return test_value;
--- a/src/share/vm/opto/type.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/opto/type.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -4193,6 +4193,7 @@
   bool    xk = klass_is_exact();
   //return TypeInstPtr::make(TypePtr::NotNull, k, xk, NULL, 0);
   const TypeOopPtr* toop = TypeOopPtr::make_from_klass_raw(k);
+  guarantee(toop != NULL, "need type for given klass");
   toop = toop->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr();
   return toop->cast_to_exactness(xk)->is_oopptr();
 }
--- a/src/share/vm/prims/jni.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/prims/jni.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -92,7 +92,7 @@
 # include "os_bsd.inline.hpp"
 #endif
 
-static jint CurrentVersion = JNI_VERSION_1_6;
+static jint CurrentVersion = JNI_VERSION_1_8;
 
 
 // The DT_RETURN_MARK macros create a scoped object to fire the dtrace
@@ -1289,32 +1289,6 @@
   JNI_NONVIRTUAL
 };
 
-static methodHandle jni_resolve_interface_call(Handle recv, methodHandle method, TRAPS) {
-  assert(!method.is_null() , "method should not be null");
-
-  KlassHandle recv_klass; // Default to NULL (use of ?: can confuse gcc)
-  if (recv.not_null()) recv_klass = KlassHandle(THREAD, recv->klass());
-  KlassHandle spec_klass (THREAD, method->method_holder());
-  Symbol*  name  = method->name();
-  Symbol*  signature  = method->signature();
-  CallInfo info;
-  LinkResolver::resolve_interface_call(info, recv, recv_klass,  spec_klass, name, signature, KlassHandle(), false, true, CHECK_(methodHandle()));
-  return info.selected_method();
-}
-
-static methodHandle jni_resolve_virtual_call(Handle recv, methodHandle method, TRAPS) {
-  assert(!method.is_null() , "method should not be null");
-
-  KlassHandle recv_klass; // Default to NULL (use of ?: can confuse gcc)
-  if (recv.not_null()) recv_klass = KlassHandle(THREAD, recv->klass());
-  KlassHandle spec_klass (THREAD, method->method_holder());
-  Symbol*  name  = method->name();
-  Symbol*  signature  = method->signature();
-  CallInfo info;
-  LinkResolver::resolve_virtual_call(info, recv, recv_klass,  spec_klass, name, signature, KlassHandle(), false, true, CHECK_(methodHandle()));
-  return info.selected_method();
-}
-
 
 
 static void jni_invoke_static(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
@@ -5053,6 +5027,7 @@
 void execute_internal_vm_tests() {
   if (ExecuteInternalVMTests) {
     tty->print_cr("Running internal VM tests");
+    run_unit_test(GlobalDefinitions::test_globals());
     run_unit_test(arrayOopDesc::test_max_array_length());
     run_unit_test(CollectedHeap::test_is_in());
     run_unit_test(QuickSort::test_quick_sort());
--- a/src/share/vm/prims/jni.h	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/prims/jni.h	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1951,6 +1951,7 @@
 #define JNI_VERSION_1_2 0x00010002
 #define JNI_VERSION_1_4 0x00010004
 #define JNI_VERSION_1_6 0x00010006
+#define JNI_VERSION_1_8 0x00010008
 
 #ifdef __cplusplus
 } /* extern "C" */
--- a/src/share/vm/prims/jniCheck.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/prims/jniCheck.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -33,7 +33,7 @@
   // within IN_VM macro), one to be called when in NATIVE state.
 
   // When in VM state:
-  static void ReportJNIFatalError(JavaThread* thr, const char *msg) {
+  static inline void ReportJNIFatalError(JavaThread* thr, const char *msg) {
     tty->print_cr("FATAL ERROR in native method: %s", msg);
     thr->print_stack();
     os::abort(true);
--- a/src/share/vm/prims/jvm.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/prims/jvm.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -30,6 +30,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
+#include "interpreter/bytecode.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/fieldStreams.hpp"
@@ -665,8 +666,51 @@
 
 JVM_ENTRY(jclass, JVM_GetCallerClass(JNIEnv* env, int depth))
   JVMWrapper("JVM_GetCallerClass");
-  Klass* k = thread->security_get_caller_class(depth);
-  return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, k->java_mirror());
+
+  // Pre-JDK 8 and early builds of JDK 8 don't have a CallerSensitive annotation.
+  if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) {
+    Klass* k = thread->security_get_caller_class(depth);
+    return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, k->java_mirror());
+  } else {
+    // Basic handshaking with Java_sun_reflect_Reflection_getCallerClass
+    assert(depth == -1, "wrong handshake depth");
+  }
+
+  // Getting the class of the caller frame.
+  //
+  // The call stack at this point looks something like this:
+  //
+  // [0] [ @CallerSensitive public sun.reflect.Reflection.getCallerClass ]
+  // [1] [ @CallerSensitive API.method                                   ]
+  // [.] [ (skipped intermediate frames)                                 ]
+  // [n] [ caller                                                        ]
+  vframeStream vfst(thread);
+  // Cf. LibraryCallKit::inline_native_Reflection_getCallerClass
+  for (int n = 0; !vfst.at_end(); vfst.security_next(), n++) {
+    Method* m = vfst.method();
+    assert(m != NULL, "sanity");
+    switch (n) {
+    case 0:
+      // This must only be called from Reflection.getCallerClass
+      if (m->intrinsic_id() != vmIntrinsics::_getCallerClass) {
+        THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetCallerClass must only be called from Reflection.getCallerClass");
+      }
+      // fall-through
+    case 1:
+      // Frame 0 and 1 must be caller sensitive.
+      if (!m->caller_sensitive()) {
+        THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), err_msg("CallerSensitive annotation expected at frame %d", n));
+      }
+      break;
+    default:
+      if (!m->is_ignored_by_security_stack_walk()) {
+        // We have reached the desired frame; return the holder class.
+        return (jclass) JNIHandles::make_local(env, m->method_holder()->java_mirror());
+      }
+      break;
+    }
+  }
+  return NULL;
 JVM_END
 
 
@@ -1457,7 +1501,7 @@
 JVM_ENTRY(jbyteArray, JVM_GetClassAnnotations(JNIEnv *env, jclass cls))
   assert (cls != NULL, "illegal class");
   JVMWrapper("JVM_GetClassAnnotations");
-  ResourceMark rm(THREAD);
+
   // Return null for arrays and primitives
   if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
     Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
@@ -1470,20 +1514,15 @@
 JVM_END
 
 
-JVM_ENTRY(jbyteArray, JVM_GetFieldAnnotations(JNIEnv *env, jobject field))
-  assert(field != NULL, "illegal field");
-  JVMWrapper("JVM_GetFieldAnnotations");
-
+static bool jvm_get_field_common(jobject field, fieldDescriptor& fd, TRAPS) {
   // some of this code was adapted from from jni_FromReflectedField
 
-  // field is a handle to a java.lang.reflect.Field object
   oop reflected = JNIHandles::resolve_non_null(field);
   oop mirror    = java_lang_reflect_Field::clazz(reflected);
   Klass* k    = java_lang_Class::as_Klass(mirror);
   int slot      = java_lang_reflect_Field::slot(reflected);
   int modifiers = java_lang_reflect_Field::modifiers(reflected);
 
-  fieldDescriptor fd;
   KlassHandle kh(THREAD, k);
   intptr_t offset = InstanceKlass::cast(kh())->field_offset(slot);
 
@@ -1491,16 +1530,29 @@
     // for static fields we only look in the current class
     if (!InstanceKlass::cast(kh())->find_local_field_from_offset(offset, true, &fd)) {
       assert(false, "cannot find static field");
-      return NULL;  // robustness
+      return false;
     }
   } else {
     // for instance fields we start with the current class and work
     // our way up through the superclass chain
     if (!InstanceKlass::cast(kh())->find_field_from_offset(offset, false, &fd)) {
       assert(false, "cannot find instance field");
-      return NULL;  // robustness
+      return false;
     }
   }
+  return true;
+}
+
+JVM_ENTRY(jbyteArray, JVM_GetFieldAnnotations(JNIEnv *env, jobject field))
+  // field is a handle to a java.lang.reflect.Field object
+  assert(field != NULL, "illegal field");
+  JVMWrapper("JVM_GetFieldAnnotations");
+
+  fieldDescriptor fd;
+  bool gotFd = jvm_get_field_common(field, fd, CHECK_NULL);
+  if (!gotFd) {
+    return NULL;
+  }
 
   return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(fd.annotations(), THREAD));
 JVM_END
@@ -1525,12 +1577,8 @@
   Klass* k = java_lang_Class::as_Klass(mirror);
 
   Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
-  if (m == NULL) {
-    assert(false, "cannot find method");
-    return NULL;  // robustness
-  }
-
-  return m;
+  assert(m != NULL, "cannot find method");
+  return m;  // caller has to deal with NULL in product mode
 }
 
 
@@ -1539,6 +1587,10 @@
 
   // method is a handle to a java.lang.reflect.Method object
   Method* m = jvm_get_method_common(method);
+  if (m == NULL) {
+    return NULL;
+  }
+
   return (jbyteArray) JNIHandles::make_local(env,
     Annotations::make_java_array(m->annotations(), THREAD));
 JVM_END
@@ -1549,6 +1601,10 @@
 
   // method is a handle to a java.lang.reflect.Method object
   Method* m = jvm_get_method_common(method);
+  if (m == NULL) {
+    return NULL;
+  }
+
   return (jbyteArray) JNIHandles::make_local(env,
     Annotations::make_java_array(m->annotation_default(), THREAD));
 JVM_END
@@ -1559,6 +1615,10 @@
 
   // method is a handle to a java.lang.reflect.Method object
   Method* m = jvm_get_method_common(method);
+  if (m == NULL) {
+    return NULL;
+  }
+
   return (jbyteArray) JNIHandles::make_local(env,
     Annotations::make_java_array(m->parameter_annotations(), THREAD));
 JVM_END
@@ -1583,6 +1643,38 @@
   return NULL;
 JVM_END
 
+JVM_ENTRY(jbyteArray, JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method))
+  assert (method != NULL, "illegal method");
+  JVMWrapper("JVM_GetMethodTypeAnnotations");
+
+  // method is a handle to a java.lang.reflect.Method object
+  Method* m = jvm_get_method_common(method);
+  if (m == NULL) {
+    return NULL;
+  }
+
+  AnnotationArray* type_annotations = m->type_annotations();
+  if (type_annotations != NULL) {
+    typeArrayOop a = Annotations::make_java_array(type_annotations, CHECK_NULL);
+    return (jbyteArray) JNIHandles::make_local(env, a);
+  }
+
+  return NULL;
+JVM_END
+
+JVM_ENTRY(jbyteArray, JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field))
+  assert (field != NULL, "illegal field");
+  JVMWrapper("JVM_GetFieldTypeAnnotations");
+
+  fieldDescriptor fd;
+  bool gotFd = jvm_get_field_common(field, fd, CHECK_NULL);
+  if (!gotFd) {
+    return NULL;
+  }
+
+  return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(fd.type_annotations(), THREAD));
+JVM_END
+
 static void bounds_check(constantPoolHandle cp, jint index, TRAPS) {
   if (!cp->is_within_bounds(index)) {
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds");
@@ -1722,7 +1814,7 @@
   int i;
   for (i = 0; i < methods_length; i++) {
     methodHandle method(THREAD, methods->at(i));
-    if (!method->is_initializer()) {
+    if (!method->is_initializer() && !method->is_overpass()) {
       if (!publicOnly || method->is_public()) {
         ++num_methods;
       }
@@ -1736,7 +1828,7 @@
   int out_idx = 0;
   for (i = 0; i < methods_length; i++) {
     methodHandle method(THREAD, methods->at(i));
-    if (!method->is_initializer()) {
+    if (!method->is_initializer() && !method->is_overpass()) {
       if (!publicOnly || method->is_public()) {
         oop m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL);
         result->obj_at_put(out_idx, m);
@@ -3160,11 +3252,24 @@
   KlassLink* first = NULL;
   KlassLink* last  = NULL;
   int depth = 0;
-
-  for(vframeStream vfst(thread); !vfst.at_end(); vfst.security_get_caller_frame(1)) {
+  vframeStream vfst(thread);
+
+  if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) {
+    // This must only be called from SecurityManager.getClassContext
+    Method* m = vfst.method();
+    if (!(m->method_holder() == SystemDictionary::SecurityManager_klass() &&
+          m->name()          == vmSymbols::getClassContext_name() &&
+          m->signature()     == vmSymbols::void_class_array_signature())) {
+      THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext");
+    }
+  }
+
+  // Collect method holders
+  for (; !vfst.at_end(); vfst.security_next()) {
+    Method* m = vfst.method();
     // Native frames are not returned
-    if (!vfst.method()->is_native()) {
-      Klass* holder = vfst.method()->method_holder();
+    if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) {
+      Klass* holder = m->method_holder();
       assert(holder->is_klass(), "just checking");
       depth++;
       KlassLink* l = new KlassLink(KlassHandle(thread, holder));
--- a/src/share/vm/prims/jvm.h	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/prims/jvm.h	Fri Apr 12 10:14:42 2013 +0100
@@ -523,6 +523,14 @@
 JNIEXPORT jbyteArray JNICALL
 JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls);
 
+// field is a handle to a java.lang.reflect.Field object
+JNIEXPORT jbyteArray JNICALL
+JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field);
+
+// method is a handle to a java.lang.reflect.Method object
+JNIEXPORT jbyteArray JNICALL
+JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method);
+
 /*
  * New (JDK 1.4) reflection implementation
  */
--- a/src/share/vm/prims/jvmtiEventController.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/prims/jvmtiEventController.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -39,7 +39,12 @@
 #include "runtime/vm_operations.hpp"
 
 #ifdef JVMTI_TRACE
-#define EC_TRACE(out) if (JvmtiTrace::trace_event_controller()) { SafeResourceMark rm; tty->print_cr out; } while (0)
+#define EC_TRACE(out) do { \
+  if (JvmtiTrace::trace_event_controller()) { \
+    SafeResourceMark rm; \
+    tty->print_cr out; \
+  } \
+} while (0)
 #else
 #define EC_TRACE(out)
 #endif /*JVMTI_TRACE */
--- a/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -72,36 +72,6 @@
 //    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_NO_CR(level, args) \
-  if ((TraceRedefineClasses & level) != 0) { \
-    ResourceMark rm; \
-    tty->print("RedefineClasses-0x%x: ", level); \
-    tty->print 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.
@@ -120,16 +90,49 @@
 #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) \
+// Note: The ResourceMark is to cleanup resource allocated args.
+// The "do {...} while (0)" is so we can use semi-colon at end of RC_TRACE().
+#define RC_TRACE(level, args) do { \
+  if (RC_TRACE_ENABLED(level)) { \
+    ResourceMark rm; \
+    tty->print("RedefineClasses-0x%x: ", level); \
+    tty->print_cr args; \
+  } \
+} while (0)
+
+#define RC_TRACE_NO_CR(level, args) do { \
+  if (RC_TRACE_ENABLED(level)) { \
+    ResourceMark rm; \
+    tty->print("RedefineClasses-0x%x: ", level); \
+    tty->print args; \
+  } \
+} while (0)
+
+#define RC_TRACE_WITH_THREAD(level, thread, args) do { \
+  if (RC_TRACE_ENABLED(level)) { \
+    ResourceMark rm(thread); \
+    tty->print("RedefineClasses-0x%x: ", level); \
+    tty->print_cr args; \
+  } \
+} while (0)
+
+#define RC_TRACE_MESG(args) do { \
+  ResourceMark rm; \
+  tty->print("RedefineClasses: "); \
+  tty->print_cr args; \
+} while (0)
+
+// Timer support macros. Only do timer operations if timer tracing is enabled.
+// The "do {...} while (0)" is so we can use semi-colon at end of the macro.
+#define RC_TIMER_START(t) do { \
   if (RC_TRACE_ENABLED(0x00000004)) { \
     t.start(); \
-  } while (0)
-#define RC_TIMER_STOP(t) \
+  } \
+} while (0)
+#define RC_TIMER_STOP(t) do { \
   if (RC_TRACE_ENABLED(0x00000004)) { \
     t.stop(); \
-  } while (0)
+  } \
+} while (0)
 
 #endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSESTRACE_HPP
--- a/src/share/vm/prims/methodHandles.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/prims/methodHandles.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -105,14 +105,15 @@
 
 // import java_lang_invoke_MemberName.*
 enum {
-  IS_METHOD      = java_lang_invoke_MemberName::MN_IS_METHOD,
-  IS_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
-  IS_FIELD       = java_lang_invoke_MemberName::MN_IS_FIELD,
-  IS_TYPE        = java_lang_invoke_MemberName::MN_IS_TYPE,
+  IS_METHOD            = java_lang_invoke_MemberName::MN_IS_METHOD,
+  IS_CONSTRUCTOR       = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
+  IS_FIELD             = java_lang_invoke_MemberName::MN_IS_FIELD,
+  IS_TYPE              = java_lang_invoke_MemberName::MN_IS_TYPE,
+  CALLER_SENSITIVE     = java_lang_invoke_MemberName::MN_CALLER_SENSITIVE,
   REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
   REFERENCE_KIND_MASK  = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
-  SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
-  SEARCH_INTERFACES   = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
+  SEARCH_SUPERCLASSES  = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
+  SEARCH_INTERFACES    = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
   ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
 };
 
@@ -207,10 +208,15 @@
     vmindex = m->vtable_index();
   }
 
-  java_lang_invoke_MemberName::set_flags(mname_oop,    flags);
+  // @CallerSensitive annotation detected
+  if (m->caller_sensitive()) {
+    flags |= CALLER_SENSITIVE;
+  }
+
+  java_lang_invoke_MemberName::set_flags(   mname_oop, flags);
   java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
-  java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);   // vtable/itable index
-  java_lang_invoke_MemberName::set_clazz(mname_oop,    receiver_limit->java_mirror());
+  java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex);   // vtable/itable index
+  java_lang_invoke_MemberName::set_clazz(   mname_oop, receiver_limit->java_mirror());
   // Note:  name and type can be lazily computed by resolve_MemberName,
   // if Java code needs them as resolved String and MethodType objects.
   // The clazz must be eagerly stored, because it provides a GC
@@ -940,6 +946,7 @@
     template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
     template(java_lang_invoke_MemberName,MN_IS_FIELD) \
     template(java_lang_invoke_MemberName,MN_IS_TYPE) \
+    template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
     template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
     template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
     template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
--- a/src/share/vm/prims/unsafe.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/prims/unsafe.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -868,7 +868,7 @@
   env->ThrowNew(cls, msg);
 }
 
-static jclass Unsafe_DefineClass(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) {
+static jclass Unsafe_DefineClass_impl(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) {
   {
     // Code lifted from JDK 1.3 ClassLoader.c
 
@@ -939,6 +939,15 @@
 }
 
 
+UNSAFE_ENTRY(jclass, Unsafe_DefineClass(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd))
+  UnsafeWrapper("Unsafe_DefineClass");
+  {
+    ThreadToNativeFromVM ttnfv(thread);
+    return Unsafe_DefineClass_impl(env, name, data, offset, length, loader, pd);
+  }
+UNSAFE_END
+
+
 UNSAFE_ENTRY(jclass, Unsafe_DefineClass0(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length))
   UnsafeWrapper("Unsafe_DefineClass");
   {
@@ -949,20 +958,11 @@
     jobject loader = (caller == NULL) ? NULL : JVM_GetClassLoader(env, caller);
     jobject pd     = (caller == NULL) ? NULL : JVM_GetProtectionDomain(env, caller);
 
-    return Unsafe_DefineClass(env, name, data, offset, length, loader, pd);
+    return Unsafe_DefineClass_impl(env, name, data, offset, length, loader, pd);
   }
 UNSAFE_END
 
 
-UNSAFE_ENTRY(jclass, Unsafe_DefineClass1(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd))
-  UnsafeWrapper("Unsafe_DefineClass");
-  {
-    ThreadToNativeFromVM ttnfv(thread);
-
-    return Unsafe_DefineClass(env, name, data, offset, length, loader, pd);
-  }
-UNSAFE_END
-
 #define DAC_Args CLS"[B["OBJ
 // define a class but do not make it known to the class loader or system dictionary
 // - host_class:  supplies context for linkage, access control, protection domain, and class loader
@@ -1323,7 +1323,7 @@
 #define THR LANG"Throwable;"
 
 #define DC0_Args LANG"String;[BII"
-#define DC1_Args DC0_Args LANG"ClassLoader;" "Ljava/security/ProtectionDomain;"
+#define DC_Args  DC0_Args LANG"ClassLoader;" "Ljava/security/ProtectionDomain;"
 
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
@@ -1352,10 +1352,8 @@
 
 
 
-// %%% These are temporarily supported until the SDK sources
-// contain the necessarily updated Unsafe.java.
+// These are the methods for 1.4.0
 static JNINativeMethod methods_140[] = {
-
     {CC"getObject",        CC"("OBJ"I)"OBJ"",   FN_PTR(Unsafe_GetObject140)},
     {CC"putObject",        CC"("OBJ"I"OBJ")V",  FN_PTR(Unsafe_SetObject140)},
 
@@ -1381,12 +1379,10 @@
 
     {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
     {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
-//  {CC"setMemory",          CC"("ADR"JB)V",             FN_PTR(Unsafe_SetMemory)},
-//  {CC"copyMemory",         CC"("ADR ADR"J)V",          FN_PTR(Unsafe_CopyMemory)},
     {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
 
-    {CC"fieldOffset",        CC"("FLD")I",               FN_PTR(Unsafe_FieldOffset)}, //deprecated
-    {CC"staticFieldBase",    CC"("CLS")"OBJ,             FN_PTR(Unsafe_StaticFieldBaseFromClass)}, //deprecated
+    {CC"fieldOffset",        CC"("FLD")I",               FN_PTR(Unsafe_FieldOffset)},
+    {CC"staticFieldBase",    CC"("CLS")"OBJ,             FN_PTR(Unsafe_StaticFieldBaseFromClass)},
     {CC"ensureClassInitialized",CC"("CLS")V",            FN_PTR(Unsafe_EnsureClassInitialized)},
     {CC"arrayBaseOffset",    CC"("CLS")I",               FN_PTR(Unsafe_ArrayBaseOffset)},
     {CC"arrayIndexScale",    CC"("CLS")I",               FN_PTR(Unsafe_ArrayIndexScale)},
@@ -1394,16 +1390,15 @@
     {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
 
     {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
-    {CC"defineClass",        CC"("DC1_Args")"CLS,        FN_PTR(Unsafe_DefineClass1)},
+    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
     {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
     {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
     {CC"throwException",     CC"("THR")V",               FN_PTR(Unsafe_ThrowException)}
 };
 
-// These are the old methods prior to the JSR 166 changes in 1.5.0
+// These are the methods prior to the JSR 166 changes in 1.5.0
 static JNINativeMethod methods_141[] = {
-
     {CC"getObject",        CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObject)},
     {CC"putObject",        CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObject)},
 
@@ -1429,8 +1424,6 @@
 
     {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
     {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
-//  {CC"setMemory",          CC"("ADR"JB)V",             FN_PTR(Unsafe_SetMemory)},
-//  {CC"copyMemory",         CC"("ADR ADR"J)V",          FN_PTR(Unsafe_CopyMemory)},
     {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
 
     {CC"objectFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_ObjectFieldOffset)},
@@ -1443,7 +1436,7 @@
     {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
 
     {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
-    {CC"defineClass",        CC"("DC1_Args")"CLS,        FN_PTR(Unsafe_DefineClass1)},
+    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
     {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
     {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
@@ -1451,9 +1444,8 @@
 
 };
 
-// These are the old methods prior to the JSR 166 changes in 1.6.0
+// These are the methods prior to the JSR 166 changes in 1.6.0
 static JNINativeMethod methods_15[] = {
-
     {CC"getObject",        CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObject)},
     {CC"putObject",        CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObject)},
     {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObjectVolatile)},
@@ -1482,8 +1474,6 @@
 
     {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
     {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
-//  {CC"setMemory",          CC"("ADR"JB)V",             FN_PTR(Unsafe_SetMemory)},
-//  {CC"copyMemory",         CC"("ADR ADR"J)V",          FN_PTR(Unsafe_CopyMemory)},
     {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
 
     {CC"objectFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_ObjectFieldOffset)},
@@ -1496,7 +1486,7 @@
     {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
 
     {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
-    {CC"defineClass",        CC"("DC1_Args")"CLS,        FN_PTR(Unsafe_DefineClass1)},
+    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
     {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
     {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
@@ -1509,14 +1499,69 @@
 
 };
 
-// These are the correct methods, moving forward:
-static JNINativeMethod methods[] = {
-
+// These are the methods for 1.6.0 and 1.7.0
+static JNINativeMethod methods_16[] = {
     {CC"getObject",        CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObject)},
     {CC"putObject",        CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObject)},
     {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObjectVolatile)},
     {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObjectVolatile)},
 
+    DECLARE_GETSETOOP(Boolean, Z),
+    DECLARE_GETSETOOP(Byte, B),
+    DECLARE_GETSETOOP(Short, S),
+    DECLARE_GETSETOOP(Char, C),
+    DECLARE_GETSETOOP(Int, I),
+    DECLARE_GETSETOOP(Long, J),
+    DECLARE_GETSETOOP(Float, F),
+    DECLARE_GETSETOOP(Double, D),
+
+    DECLARE_GETSETNATIVE(Byte, B),
+    DECLARE_GETSETNATIVE(Short, S),
+    DECLARE_GETSETNATIVE(Char, C),
+    DECLARE_GETSETNATIVE(Int, I),
+    DECLARE_GETSETNATIVE(Long, J),
+    DECLARE_GETSETNATIVE(Float, F),
+    DECLARE_GETSETNATIVE(Double, D),
+
+    {CC"getAddress",         CC"("ADR")"ADR,             FN_PTR(Unsafe_GetNativeAddress)},
+    {CC"putAddress",         CC"("ADR""ADR")V",          FN_PTR(Unsafe_SetNativeAddress)},
+
+    {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
+    {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
+    {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
+
+    {CC"objectFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_ObjectFieldOffset)},
+    {CC"staticFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_StaticFieldOffset)},
+    {CC"staticFieldBase",    CC"("FLD")"OBJ,             FN_PTR(Unsafe_StaticFieldBaseFromField)},
+    {CC"ensureClassInitialized",CC"("CLS")V",            FN_PTR(Unsafe_EnsureClassInitialized)},
+    {CC"arrayBaseOffset",    CC"("CLS")I",               FN_PTR(Unsafe_ArrayBaseOffset)},
+    {CC"arrayIndexScale",    CC"("CLS")I",               FN_PTR(Unsafe_ArrayIndexScale)},
+    {CC"addressSize",        CC"()I",                    FN_PTR(Unsafe_AddressSize)},
+    {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
+
+    {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
+    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
+    {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
+    {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
+    {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
+    {CC"tryMonitorEnter",    CC"("OBJ")Z",               FN_PTR(Unsafe_TryMonitorEnter)},
+    {CC"throwException",     CC"("THR")V",               FN_PTR(Unsafe_ThrowException)},
+    {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z",  FN_PTR(Unsafe_CompareAndSwapObject)},
+    {CC"compareAndSwapInt",  CC"("OBJ"J""I""I"")Z",      FN_PTR(Unsafe_CompareAndSwapInt)},
+    {CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z",      FN_PTR(Unsafe_CompareAndSwapLong)},
+    {CC"putOrderedObject",   CC"("OBJ"J"OBJ")V",         FN_PTR(Unsafe_SetOrderedObject)},
+    {CC"putOrderedInt",      CC"("OBJ"JI)V",             FN_PTR(Unsafe_SetOrderedInt)},
+    {CC"putOrderedLong",     CC"("OBJ"JJ)V",             FN_PTR(Unsafe_SetOrderedLong)},
+    {CC"park",               CC"(ZJ)V",                  FN_PTR(Unsafe_Park)},
+    {CC"unpark",             CC"("OBJ")V",               FN_PTR(Unsafe_Unpark)}
+};
+
+// These are the methods for 1.8.0
+static JNINativeMethod methods_18[] = {
+    {CC"getObject",        CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObject)},
+    {CC"putObject",        CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObject)},
+    {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObjectVolatile)},
+    {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObjectVolatile)},
 
     DECLARE_GETSETOOP(Boolean, Z),
     DECLARE_GETSETOOP(Byte, B),
@@ -1540,8 +1585,6 @@
 
     {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
     {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
-//  {CC"setMemory",          CC"("ADR"JB)V",             FN_PTR(Unsafe_SetMemory)},
-//  {CC"copyMemory",         CC"("ADR ADR"J)V",          FN_PTR(Unsafe_CopyMemory)},
     {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
 
     {CC"objectFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_ObjectFieldOffset)},
@@ -1553,8 +1596,7 @@
     {CC"addressSize",        CC"()I",                    FN_PTR(Unsafe_AddressSize)},
     {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
 
-    {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
-    {CC"defineClass",        CC"("DC1_Args")"CLS,        FN_PTR(Unsafe_DefineClass1)},
+    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
     {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
     {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
@@ -1566,23 +1608,12 @@
     {CC"putOrderedObject",   CC"("OBJ"J"OBJ")V",         FN_PTR(Unsafe_SetOrderedObject)},
     {CC"putOrderedInt",      CC"("OBJ"JI)V",             FN_PTR(Unsafe_SetOrderedInt)},
     {CC"putOrderedLong",     CC"("OBJ"JJ)V",             FN_PTR(Unsafe_SetOrderedLong)},
-    {CC"loadFence",          CC"()V",                    FN_PTR(Unsafe_LoadFence)},
-    {CC"storeFence",         CC"()V",                    FN_PTR(Unsafe_StoreFence)},
-    {CC"fullFence",          CC"()V",                    FN_PTR(Unsafe_FullFence)},
     {CC"park",               CC"(ZJ)V",                  FN_PTR(Unsafe_Park)},
     {CC"unpark",             CC"("OBJ")V",               FN_PTR(Unsafe_Unpark)}
-
-//    {CC"getLoadAverage",     CC"([DI)I",                 FN_PTR(Unsafe_Loadavg)},
-
-//    {CC"prefetchRead",       CC"("OBJ"J)V",              FN_PTR(Unsafe_PrefetchRead)},
-//    {CC"prefetchWrite",      CC"("OBJ"J)V",              FN_PTR(Unsafe_PrefetchWrite)}
-//    {CC"prefetchReadStatic", CC"("OBJ"J)V",              FN_PTR(Unsafe_PrefetchRead)},
-//    {CC"prefetchWriteStatic",CC"("OBJ"J)V",              FN_PTR(Unsafe_PrefetchWrite)}
-
 };
 
 JNINativeMethod loadavg_method[] = {
-    {CC"getLoadAverage",            CC"([DI)I",                 FN_PTR(Unsafe_Loadavg)}
+    {CC"getLoadAverage",     CC"([DI)I",                 FN_PTR(Unsafe_Loadavg)}
 };
 
 JNINativeMethod prefetch_methods[] = {
@@ -1592,7 +1623,7 @@
     {CC"prefetchWriteStatic",CC"("OBJ"J)V",              FN_PTR(Unsafe_PrefetchWrite)}
 };
 
-JNINativeMethod memcopy_methods[] = {
+JNINativeMethod memcopy_methods_17[] = {
     {CC"copyMemory",         CC"("OBJ"J"OBJ"JJ)V",       FN_PTR(Unsafe_CopyMemory2)},
     {CC"setMemory",          CC"("OBJ"JJB)V",            FN_PTR(Unsafe_SetMemory2)}
 };
@@ -1610,6 +1641,12 @@
     {CC"shouldBeInitialized",CC"("CLS")Z",               FN_PTR(Unsafe_ShouldBeInitialized)},
 };
 
+JNINativeMethod fence_methods[] = {
+    {CC"loadFence",          CC"()V",                    FN_PTR(Unsafe_LoadFence)},
+    {CC"storeFence",         CC"()V",                    FN_PTR(Unsafe_StoreFence)},
+    {CC"fullFence",          CC"()V",                    FN_PTR(Unsafe_FullFence)},
+};
+
 #undef CC
 #undef FN_PTR
 
@@ -1622,12 +1659,32 @@
 #undef MTH
 #undef THR
 #undef DC0_Args
-#undef DC1_Args
+#undef DC_Args
 
 #undef DECLARE_GETSETOOP
 #undef DECLARE_GETSETNATIVE
 
 
+/**
+ * Helper method to register native methods.
+ */
+static bool register_natives(const char* message, JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
+  int status = env->RegisterNatives(clazz, methods, nMethods);
+  if (status < 0 || env->ExceptionOccurred()) {
+    if (PrintMiscellaneous && (Verbose || WizardMode)) {
+      tty->print_cr("Unsafe:  failed registering %s", message);
+    }
+    env->ExceptionClear();
+    return false;
+  } else {
+    if (PrintMiscellaneous && (Verbose || WizardMode)) {
+      tty->print_cr("Unsafe:  successfully registered %s", message);
+    }
+    return true;
+  }
+}
+
+
 // This one function is exported, used by NativeLookup.
 // The Unsafe_xxx functions above are called only from the interpreter.
 // The optimizer looks at names and signatures to recognize
@@ -1637,83 +1694,57 @@
   UnsafeWrapper("JVM_RegisterUnsafeMethods");
   {
     ThreadToNativeFromVM ttnfv(thread);
-    {
-      env->RegisterNatives(unsafecls, loadavg_method, sizeof(loadavg_method)/sizeof(JNINativeMethod));
-      if (env->ExceptionOccurred()) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          tty->print_cr("Warning:  SDK 1.6 Unsafe.loadavg not found.");
-        }
-        env->ExceptionClear();
-      }
-    }
+
+    // Unsafe methods
     {
-      env->RegisterNatives(unsafecls, prefetch_methods, sizeof(prefetch_methods)/sizeof(JNINativeMethod));
-      if (env->ExceptionOccurred()) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          tty->print_cr("Warning:  SDK 1.6 Unsafe.prefetchRead/Write not found.");
-        }
-        env->ExceptionClear();
+      bool success = false;
+      // We need to register the 1.6 methods first because the 1.8 methods would register fine on 1.7 and 1.6
+      if (!success) {
+        success = register_natives("1.6 methods",   env, unsafecls, methods_16,  sizeof(methods_16)/sizeof(JNINativeMethod));
+      }
+      if (!success) {
+        success = register_natives("1.8 methods",   env, unsafecls, methods_18,  sizeof(methods_18)/sizeof(JNINativeMethod));
+      }
+      if (!success) {
+        success = register_natives("1.5 methods",   env, unsafecls, methods_15,  sizeof(methods_15)/sizeof(JNINativeMethod));
+      }
+      if (!success) {
+        success = register_natives("1.4.1 methods", env, unsafecls, methods_141, sizeof(methods_141)/sizeof(JNINativeMethod));
       }
+      if (!success) {
+        success = register_natives("1.4.0 methods", env, unsafecls, methods_140, sizeof(methods_140)/sizeof(JNINativeMethod));
+      }
+      guarantee(success, "register unsafe natives");
     }
+
+    // Unsafe.getLoadAverage
+    register_natives("1.6 loadavg method", env, unsafecls, loadavg_method, sizeof(loadavg_method)/sizeof(JNINativeMethod));
+
+    // Prefetch methods
+    register_natives("1.6 prefetch methods", env, unsafecls, prefetch_methods, sizeof(prefetch_methods)/sizeof(JNINativeMethod));
+
+    // Memory copy methods
     {
-      env->RegisterNatives(unsafecls, memcopy_methods, sizeof(memcopy_methods)/sizeof(JNINativeMethod));
-      if (env->ExceptionOccurred()) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          tty->print_cr("Warning:  SDK 1.7 Unsafe.copyMemory not found.");
-        }
-        env->ExceptionClear();
-        env->RegisterNatives(unsafecls, memcopy_methods_15, sizeof(memcopy_methods_15)/sizeof(JNINativeMethod));
-        if (env->ExceptionOccurred()) {
-          if (PrintMiscellaneous && (Verbose || WizardMode)) {
-            tty->print_cr("Warning:  SDK 1.5 Unsafe.copyMemory not found.");
-          }
-          env->ExceptionClear();
-        }
+      bool success = false;
+      if (!success) {
+        success = register_natives("1.7 memory copy methods", env, unsafecls, memcopy_methods_17, sizeof(memcopy_methods_17)/sizeof(JNINativeMethod));
+      }
+      if (!success) {
+        success = register_natives("1.5 memory copy methods", env, unsafecls, memcopy_methods_15, sizeof(memcopy_methods_15)/sizeof(JNINativeMethod));
       }
     }
+
+    // Unsafe.defineAnonymousClass
     if (EnableInvokeDynamic) {
-      env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
-      if (env->ExceptionOccurred()) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          tty->print_cr("Warning:  SDK 1.7 Unsafe.defineClass (anonymous version) not found.");
-        }
-        env->ExceptionClear();
-      }
-    }
-    if (EnableInvokeDynamic) {
-      env->RegisterNatives(unsafecls, lform_methods, sizeof(lform_methods)/sizeof(JNINativeMethod));
-      if (env->ExceptionOccurred()) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          tty->print_cr("Warning:  SDK 1.7 LambdaForm support in Unsafe not found.");
-        }
-        env->ExceptionClear();
-      }
+      register_natives("1.7 define anonymous class method", env, unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
     }
-    int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
-    if (env->ExceptionOccurred()) {
-      if (PrintMiscellaneous && (Verbose || WizardMode)) {
-        tty->print_cr("Warning:  SDK 1.6 version of Unsafe not found.");
-      }
-      env->ExceptionClear();
-      // %%% For now, be backward compatible with an older class:
-      status = env->RegisterNatives(unsafecls, methods_15, sizeof(methods_15)/sizeof(JNINativeMethod));
+
+    // Unsafe.shouldBeInitialized
+    if (EnableInvokeDynamic) {
+      register_natives("1.7 LambdaForm support", env, unsafecls, lform_methods, sizeof(lform_methods)/sizeof(JNINativeMethod));
     }
-    if (env->ExceptionOccurred()) {
-      if (PrintMiscellaneous && (Verbose || WizardMode)) {
-        tty->print_cr("Warning:  SDK 1.5 version of Unsafe not found.");
-      }
-      env->ExceptionClear();
-      // %%% For now, be backward compatible with an older class:
-      status = env->RegisterNatives(unsafecls, methods_141, sizeof(methods_141)/sizeof(JNINativeMethod));
-    }
-    if (env->ExceptionOccurred()) {
-      if (PrintMiscellaneous && (Verbose || WizardMode)) {
-        tty->print_cr("Warning:  SDK 1.4.1 version of Unsafe not found.");
-      }
-      env->ExceptionClear();
-      // %%% For now, be backward compatible with an older class:
-      status = env->RegisterNatives(unsafecls, methods_140, sizeof(methods_140)/sizeof(JNINativeMethod));
-    }
-    guarantee(status == 0, "register unsafe natives");
+
+    // Fence methods
+    register_natives("1.8 fence methods", env, unsafecls, fence_methods, sizeof(fence_methods)/sizeof(JNINativeMethod));
   }
 JVM_END
--- a/src/share/vm/prims/whitebox.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/prims/whitebox.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -118,45 +118,46 @@
 #endif // INCLUDE_ALL_GCS
 
 #ifdef INCLUDE_NMT
-// Keep track of the 3 allocations in NMTAllocTest so we can free them later
-// on and verify that they're not visible anymore
-static void* nmtMtTest1 = NULL, *nmtMtTest2 = NULL, *nmtMtTest3 = NULL;
-
 // Alloc memory using the test memory type so that we can use that to see if
 // NMT picks it up correctly
-WB_ENTRY(jboolean, WB_NMTAllocTest(JNIEnv* env))
-  void *mem;
+WB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size))
+  jlong addr = 0;
 
-  if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
-    return false;
+  if (MemTracker::is_on() && !MemTracker::shutdown_in_progress()) {
+    addr = (jlong)(uintptr_t)os::malloc(size, mtTest);
   }
 
-  // Allocate 2 * 128k + 256k + 1024k and free the 1024k one to make sure we track
-  // everything correctly. Total should be 512k held alive.
-  nmtMtTest1 = os::malloc(128 * 1024, mtTest);
-  mem = os::malloc(1024 * 1024, mtTest);
-  nmtMtTest2 = os::malloc(256 * 1024, mtTest);
-  os::free(mem, mtTest);
-  nmtMtTest3 = os::malloc(128 * 1024, mtTest);
-
-  return true;
+  return addr;
 WB_END
 
 // Free the memory allocated by NMTAllocTest
-WB_ENTRY(jboolean, WB_NMTFreeTestMemory(JNIEnv* env))
+WB_ENTRY(void, WB_NMTFree(JNIEnv* env, jobject o, jlong mem))
+  os::free((void*)(uintptr_t)mem, mtTest);
+WB_END
 
-  if (nmtMtTest1 == NULL || nmtMtTest2 == NULL || nmtMtTest3 == NULL) {
-    return false;
+WB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size))
+  jlong addr = 0;
+
+  if (MemTracker::is_on() && !MemTracker::shutdown_in_progress()) {
+    addr = (jlong)(uintptr_t)os::reserve_memory(size);
+    MemTracker::record_virtual_memory_type((address)addr, mtTest);
   }
 
-  os::free(nmtMtTest1, mtTest);
-  nmtMtTest1 = NULL;
-  os::free(nmtMtTest2, mtTest);
-  nmtMtTest2 = NULL;
-  os::free(nmtMtTest3, mtTest);
-  nmtMtTest3 = NULL;
+  return addr;
+WB_END
+
 
-  return true;
+WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
+  os::commit_memory((char *)(uintptr_t)addr, size);
+  MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest);
+WB_END
+
+WB_ENTRY(void, WB_NMTUncommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
+  os::uncommit_memory((char *)(uintptr_t)addr, size);
+WB_END
+
+WB_ENTRY(void, WB_NMTReleaseMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
+  os::release_memory((char *)(uintptr_t)addr, size);
 WB_END
 
 // Block until the current generation of NMT data to be merged, used to reliably test the NMT feature
@@ -254,6 +255,24 @@
          CompileBroker::queue_size(CompLevel_full_profile) /* C1 */;
 WB_END
 
+WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
+  ResourceMark rm(THREAD);
+  int len;
+  jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len);
+  oop found_string = StringTable::the_table()->lookup(name, len);
+  if (found_string == NULL) {
+        return false;
+  }
+  return true;
+WB_END
+
+
+WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
+  Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
+  Universe::heap()->collect(GCCause::_last_ditch_collection);
+WB_END
+
+
 //Some convenience methods to deal with objects from java
 int WhiteBox::offset_for_field(const char* field_name, oop object,
     Symbol* signature_symbol) {
@@ -322,9 +341,13 @@
   {CC"g1RegionSize",       CC"()I",                   (void*)&WB_G1RegionSize      },
 #endif // INCLUDE_ALL_GCS
 #ifdef INCLUDE_NMT
-  {CC"NMTAllocTest",       CC"()Z",                   (void*)&WB_NMTAllocTest      },
-  {CC"NMTFreeTestMemory",  CC"()Z",                   (void*)&WB_NMTFreeTestMemory },
-  {CC"NMTWaitForDataMerge",CC"()Z",                   (void*)&WB_NMTWaitForDataMerge},
+  {CC"NMTMalloc",           CC"(J)J",                 (void*)&WB_NMTMalloc          },
+  {CC"NMTFree",             CC"(J)V",                 (void*)&WB_NMTFree            },
+  {CC"NMTReserveMemory",    CC"(J)J",                 (void*)&WB_NMTReserveMemory   },
+  {CC"NMTCommitMemory",     CC"(JJ)V",                (void*)&WB_NMTCommitMemory    },
+  {CC"NMTUncommitMemory",   CC"(JJ)V",                (void*)&WB_NMTUncommitMemory  },
+  {CC"NMTReleaseMemory",    CC"(JJ)V",                (void*)&WB_NMTReleaseMemory   },
+  {CC"NMTWaitForDataMerge", CC"()Z",                  (void*)&WB_NMTWaitForDataMerge},
 #endif // INCLUDE_NMT
   {CC"deoptimizeAll",      CC"()V",                   (void*)&WB_DeoptimizeAll     },
   {CC"deoptimizeMethod",   CC"(Ljava/lang/reflect/Method;)I",
@@ -343,6 +366,8 @@
       CC"(Ljava/lang/reflect/Method;)I",              (void*)&WB_GetMethodCompilationLevel},
   {CC"getCompileQueuesSize",
       CC"()I",                                        (void*)&WB_GetCompileQueuesSize},
+  {CC"isInStringTable",   CC"(Ljava/lang/String;)Z",  (void*)&WB_IsInStringTable  },
+  {CC"fullGC",   CC"()V",                             (void*)&WB_FullGC },
 };
 
 #undef CC
--- a/src/share/vm/runtime/arguments.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/arguments.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -260,6 +260,7 @@
   { "CMSRevisitStackSize",           JDK_Version::jdk(8), JDK_Version::jdk(9) },
   { "PrintRevisitStats",             JDK_Version::jdk(8), JDK_Version::jdk(9) },
   { "UseVectoredExceptions",         JDK_Version::jdk(8), JDK_Version::jdk(9) },
+  { "UseSplitVerifier",              JDK_Version::jdk(8), JDK_Version::jdk(9) },
 #ifdef PRODUCT
   { "DesiredMethodLimit",
                            JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) },
@@ -1169,7 +1170,6 @@
     set_parnew_gc_flags();
   }
 
-  // MaxHeapSize is aligned down in collectorPolicy
   size_t max_heap = align_size_down(MaxHeapSize,
                                     CardTableRS::ct_max_alignment_constraint());
 
@@ -1207,10 +1207,6 @@
     }
 
     // Code along this path potentially sets NewSize and OldSize
-
-    assert(max_heap >= InitialHeapSize, "Error");
-    assert(max_heap >= NewSize, "Error");
-
     if (PrintGCDetails && Verbose) {
       // Too early to use gclog_or_tty
       tty->print_cr("CMS set min_heap_size: " SIZE_FORMAT
@@ -1557,6 +1553,15 @@
   }
 }
 
+julong Arguments::limit_by_allocatable_memory(julong limit) {
+  julong max_allocatable;
+  julong result = limit;
+  if (os::has_allocatable_memory_limit(&max_allocatable)) {
+    result = MIN2(result, max_allocatable / MaxVirtMemFraction);
+  }
+  return result;
+}
+
 void Arguments::set_heap_size() {
   if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) {
     // Deprecated flag
@@ -1595,12 +1600,12 @@
       }
       reasonable_max = MIN2(reasonable_max, max_coop_heap);
     }
-    reasonable_max = os::allocatable_physical_memory(reasonable_max);
+    reasonable_max = limit_by_allocatable_memory(reasonable_max);
 
     if (!FLAG_IS_DEFAULT(InitialHeapSize)) {
       // An initial heap size was specified on the command line,
       // so be sure that the maximum size is consistent.  Done
-      // after call to allocatable_physical_memory because that
+      // after call to limit_by_allocatable_memory because that
       // method might reduce the allocation size.
       reasonable_max = MAX2(reasonable_max, (julong)InitialHeapSize);
     }
@@ -1620,14 +1625,14 @@
 
     reasonable_minimum = MIN2(reasonable_minimum, (julong)MaxHeapSize);
 
-    reasonable_minimum = os::allocatable_physical_memory(reasonable_minimum);
+    reasonable_minimum = limit_by_allocatable_memory(reasonable_minimum);
 
     julong reasonable_initial = phys_mem / InitialRAMFraction;
 
     reasonable_initial = MAX2(reasonable_initial, reasonable_minimum);
     reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize);
 
-    reasonable_initial = os::allocatable_physical_memory(reasonable_initial);
+    reasonable_initial = limit_by_allocatable_memory(reasonable_initial);
 
     if (PrintGCDetails && Verbose) {
       // Cannot use gclog_or_tty yet.
@@ -1749,11 +1754,15 @@
   return false;
 }
 
+#if !INCLUDE_ALL_GCS
+#ifdef ASSERT
 static bool verify_serial_gc_flags() {
   return (UseSerialGC &&
         !(UseParNewGC || (UseConcMarkSweepGC || CMSIncrementalMode) || UseG1GC ||
           UseParallelGC || UseParallelOldGC));
 }
+#endif // ASSERT
+#endif // INCLUDE_ALL_GCS
 
 // check if do gclog rotation
 // +UseGCLogFileRotation is a must,
@@ -2613,9 +2622,7 @@
       initHeapSize = MIN2(total_memory / (julong)2,
                           total_memory - (julong)160*M);
 
-      // Make sure that if we have a lot of memory we cap the 32 bit
-      // process space.  The 64bit VM version of this function is a nop.
-      initHeapSize = os::allocatable_physical_memory(initHeapSize);
+      initHeapSize = limit_by_allocatable_memory(initHeapSize);
 
       if (FLAG_IS_DEFAULT(MaxHeapSize)) {
          FLAG_SET_CMDLINE(uintx, MaxHeapSize, initHeapSize);
@@ -3089,6 +3096,7 @@
   }                                                                   \
 } while(0)
 
+#if !INCLUDE_ALL_GCS
 static void force_serial_gc() {
   FLAG_SET_DEFAULT(UseSerialGC, true);
   FLAG_SET_DEFAULT(CMSIncrementalMode, false);  // special CMS suboption
@@ -3098,6 +3106,7 @@
   UNSUPPORTED_GC_OPTION(UseConcMarkSweepGC);
   UNSUPPORTED_GC_OPTION(UseParNewGC);
 }
+#endif // INCLUDE_ALL_GCS
 
 // Parse entry point called from JNI_CreateJavaVM
 
@@ -3324,6 +3333,13 @@
   }
   check_deprecated_gcs();
   check_deprecated_gc_flags();
+  if (AssumeMP && !UseSerialGC) {
+    if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) {
+      warning("If the number of processors is expected to increase from one, then"
+              " you should configure the number of parallel GC threads appropriately"
+              " using -XX:ParallelGCThreads=N");
+    }
+  }
 #else // INCLUDE_ALL_GCS
   assert(verify_serial_gc_flags(), "SerialGC unset");
 #endif // INCLUDE_ALL_GCS
--- a/src/share/vm/runtime/arguments.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/arguments.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -312,6 +312,9 @@
   static void set_use_compressed_oops();
   static void set_ergonomics_flags();
   static void set_shared_spaces_flags();
+  // limits the given memory size by the maximum amount of memory this process is
+  // currently allowed to allocate or reserve.
+  static julong limit_by_allocatable_memory(julong size);
   // Setup heap size
   static void set_heap_size();
   // Based on automatic selection criteria, should the
--- a/src/share/vm/runtime/globals.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/globals.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -457,6 +457,9 @@
   lp64_product(intx, ObjectAlignmentInBytes, 8,                             \
           "Default object alignment in bytes, 8 is minimum")                \
                                                                             \
+  product(bool, AssumeMP, false,                                            \
+          "Instruct the VM to assume multiple processors are available")    \
+                                                                            \
   /* UseMembar is theoretically a temp flag used for memory barrier         \
    * removal testing.  It was supposed to be removed before FCS but has     \
    * been re-added (see 6401008) */                                         \
@@ -679,9 +682,6 @@
   product(bool, UseCompilerSafepoints, true,                                \
           "Stop at safepoints in compiled code")                            \
                                                                             \
-  product(bool, UseSplitVerifier, true,                                     \
-          "use split verifier with StackMapTable attributes")               \
-                                                                            \
   product(bool, FailOverToOldVerifier, true,                                \
           "fail over to old verifier when split verifier fails")            \
                                                                             \
@@ -869,6 +869,11 @@
   diagnostic(bool, PrintNMTStatistics, false,                               \
           "Print native memory tracking summary data if it is on")          \
                                                                             \
+  diagnostic(bool, AutoShutdownNMT, true,                                   \
+          "Automatically shutdown native memory tracking under stress "     \
+          "situation. When set to false, native memory tracking tries to "  \
+          "stay alive at the expense of JVM performance")                   \
+                                                                            \
   diagnostic(bool, LogCompilation, false,                                   \
           "Log compilation activity in detail to hotspot.log or LogFile")   \
                                                                             \
@@ -1402,6 +1407,10 @@
           "How much the GC can expand the eden by while the GC locker  "    \
           "is active (as a percentage)")                                    \
                                                                             \
+  diagnostic(intx, GCLockerRetryAllocationCount, 2,                         \
+          "Number of times to retry allocations when"                       \
+          " blocked by the GC locker")                                      \
+                                                                            \
   develop(bool, UseCMSAdaptiveFreeLists, true,                              \
           "Use Adaptive Free Lists in the CMS generation")                  \
                                                                             \
@@ -1958,6 +1967,10 @@
   product(uintx, InitialRAMFraction, 64,                                    \
           "Fraction (1/n) of real memory used for initial heap size")       \
                                                                             \
+  develop(uintx, MaxVirtMemFraction, 2,                                     \
+          "Maximum fraction (1/n) of virtual memory used for ergonomically" \
+          "determining maximum heap size")                                  \
+                                                                            \
   product(bool, UseAutoGCSelectPolicy, false,                               \
           "Use automatic collection selection policy")                      \
                                                                             \
@@ -2515,7 +2528,7 @@
           "disable locking assertions (for speed)")                         \
                                                                             \
   product(bool, RangeCheckElimination, true,                                \
-          "Split loop iterations to eliminate range checks")                \
+          "Eliminate range checks")                                         \
                                                                             \
   develop_pd(bool, UncommonNullCast,                                        \
           "track occurrences of null in casts; adjust compiler tactics")    \
@@ -2905,6 +2918,10 @@
           "if non-zero, start verifying C heap after Nth call to "          \
           "malloc/realloc/free")                                            \
                                                                             \
+  diagnostic(uintx, MallocMaxTestWords,     0,                              \
+          "if non-zero, max # of Words that malloc/realloc can allocate "   \
+          "(for testing only)")                                             \
+                                                                            \
   product(intx, TypeProfileWidth,     2,                                    \
           "number of receiver types to record in call/cast profile")        \
                                                                             \
@@ -3569,8 +3586,9 @@
   product(uintx, SharedMiscCodeSize,    120*K,                              \
           "Size of the shared miscellaneous code area (in bytes)")          \
                                                                             \
-  product(uintx, SharedDummyBlockSize, 0,                                   \
-          "Size of dummy block used to shift heap addresses (in bytes)")    \
+  product(uintx, SharedBaseAddress, LP64_ONLY(32*G)                         \
+          NOT_LP64(LINUX_ONLY(2*G) NOT_LINUX(0)),                           \
+          "Address to allocate shared memory region for class data")        \
                                                                             \
   diagnostic(bool, EnableInvokeDynamic, true,                               \
           "support JSR 292 (method handles, invokedynamic, "                \
--- a/src/share/vm/runtime/init.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/init.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -132,15 +132,6 @@
   javaClasses_init();   // must happen after vtable initialization
   stubRoutines_init2(); // note: StubRoutines need 2-phase init
 
-  // Although we'd like to, we can't easily do a heap verify
-  // here because the main thread isn't yet a JavaThread, so
-  // its TLAB may not be made parseable from the usual interfaces.
-  if (VerifyBeforeGC && !UseTLAB &&
-      Universe::heap()->total_collections() >= VerifyGCStartAt) {
-    Universe::heap()->prepare_for_verify();
-    Universe::verify();   // make sure we're starting with a clean slate
-  }
-
   // All the flags that get adjusted by VM_Version_init and os::init_2
   // have been set so dump the flags now.
   if (PrintFlagsFinal) {
--- a/src/share/vm/runtime/os.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/os.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -80,6 +80,8 @@
 julong os::free_bytes = 0;          // # of bytes freed
 #endif
 
+static juint cur_malloc_words = 0;  // current size for MallocMaxTestWords
+
 void os_init_globals() {
   // Called from init_globals().
   // See Threads::create_vm() in thread.cpp, and init.cpp.
@@ -570,6 +572,26 @@
 }
 #endif
 
+//
+// This function supports testing of the malloc out of memory
+// condition without really running the system out of memory.
+//
+static u_char* testMalloc(size_t alloc_size) {
+  assert(MallocMaxTestWords > 0, "sanity check");
+
+  if ((cur_malloc_words + (alloc_size / BytesPerWord)) > MallocMaxTestWords) {
+    return NULL;
+  }
+
+  u_char* ptr = (u_char*)::malloc(alloc_size);
+
+  if (ptr != NULL) {
+    Atomic::add(((jint) (alloc_size / BytesPerWord)),
+                (volatile jint *) &cur_malloc_words);
+  }
+  return ptr;
+}
+
 void* os::malloc(size_t size, MEMFLAGS memflags, address caller) {
   NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
   NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
@@ -579,11 +601,22 @@
     // if NULL is returned the calling functions assume out of memory.
     size = 1;
   }
-  if (size > size + space_before + space_after) { // Check for rollover.
+
+  const size_t alloc_size = size + space_before + space_after;
+
+  if (size > alloc_size) { // Check for rollover.
     return NULL;
   }
+
   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
-  u_char* ptr = (u_char*)::malloc(size + space_before + space_after);
+
+  u_char* ptr;
+
+  if (MallocMaxTestWords > 0) {
+    ptr = testMalloc(alloc_size);
+  } else {
+    ptr = (u_char*)::malloc(alloc_size);
+  }
 
 #ifdef ASSERT
   if (ptr == NULL) return NULL;
--- a/src/share/vm/runtime/os.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/os.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -180,11 +180,11 @@
   // Interface for detecting multiprocessor system
   static inline bool is_MP() {
     assert(_processor_count > 0, "invalid processor count");
-    return _processor_count > 1;
+    return _processor_count > 1 || AssumeMP;
   }
   static julong available_memory();
   static julong physical_memory();
-  static julong allocatable_physical_memory(julong size);
+  static bool has_allocatable_memory_limit(julong* limit);
   static bool is_server_class_machine();
 
   // number of CPUs
--- a/src/share/vm/runtime/safepoint.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/safepoint.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -735,6 +735,9 @@
 // Exception handlers
 
 #ifndef PRODUCT
+
+#ifdef SPARC
+
 #ifdef _LP64
 #define PTR_PAD ""
 #else
@@ -755,7 +758,6 @@
                 newptr, is_oop?"oop":"   ", (wasoop && !is_oop) ? "STALE" : ((wasoop==false&&is_oop==false&&oldptr !=newptr)?"STOMP":"     "));
 }
 
-#ifdef SPARC
 static void print_me(intptr_t *new_sp, intptr_t *old_sp, bool *was_oops) {
 #ifdef _LP64
   tty->print_cr("--------+------address-----+------before-----------+-------after----------+");
--- a/src/share/vm/runtime/stubCodeGenerator.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/stubCodeGenerator.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -87,7 +87,7 @@
     CodeBuffer* cbuf = _masm->code();
     CodeBlob*   blob = CodeCache::find_blob_unsafe(cbuf->insts()->start());
     if (blob != NULL) {
-      blob->set_comments(cbuf->comments());
+      blob->set_strings(cbuf->strings());
     }
     bool saw_first = false;
     StubCodeDesc* toprint[1000];
--- a/src/share/vm/runtime/synchronizer.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/synchronizer.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -449,8 +449,6 @@
 // and explicit fences (barriers) to control for architectural reordering performed
 // by the CPU(s) or platform.
 
-static int  MBFence (int x) { OrderAccess::fence(); return x; }
-
 struct SharedGlobals {
     // These are highly shared mostly-read variables.
     // To avoid false-sharing they need to be the sole occupants of a $ line.
@@ -1639,11 +1637,6 @@
 
 #ifndef PRODUCT
 
-void ObjectSynchronizer::trace_locking(Handle locking_obj, bool is_compiled,
-                                       bool is_method, bool is_locking) {
-  // Don't know what to do here
-}
-
 // Verify all monitors in the monitor cache, the verification is weak.
 void ObjectSynchronizer::verify() {
   ObjectMonitor* block = gBlockList;
--- a/src/share/vm/runtime/synchronizer.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/synchronizer.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -121,7 +121,6 @@
   static void oops_do(OopClosure* f);
 
   // debugging
-  static void trace_locking(Handle obj, bool is_compiled, bool is_method, bool is_locking) PRODUCT_RETURN;
   static void verify() PRODUCT_RETURN;
   static int  verify_objmon_isinpool(ObjectMonitor *addr) PRODUCT_RETURN0;
 
--- a/src/share/vm/runtime/thread.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/thread.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -3423,12 +3423,6 @@
   // real raw monitor. VM is setup enough here for raw monitor enter.
   JvmtiExport::transition_pending_onload_raw_monitors();
 
-  if (VerifyBeforeGC &&
-      Universe::heap()->total_collections() >= VerifyGCStartAt) {
-    Universe::heap()->prepare_for_verify();
-    Universe::verify();   // make sure we're starting with a clean slate
-  }
-
   // Fully start NMT
   MemTracker::start();
 
@@ -3452,6 +3446,11 @@
   }
 
   assert (Universe::is_fully_initialized(), "not initialized");
+  if (VerifyBeforeGC && VerifyGCStartAt == 0) {
+    Universe::heap()->prepare_for_verify();
+    Universe::verify();   // make sure we're starting with a clean slate
+  }
+
   EXCEPTION_MARK;
 
   // At this point, the Universe is initialized, but we have not executed
@@ -4061,6 +4060,7 @@
   if (version == JNI_VERSION_1_2) return JNI_TRUE;
   if (version == JNI_VERSION_1_4) return JNI_TRUE;
   if (version == JNI_VERSION_1_6) return JNI_TRUE;
+  if (version == JNI_VERSION_1_8) return JNI_TRUE;
   return JNI_FALSE;
 }
 
--- a/src/share/vm/runtime/vframe.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/vframe.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -391,40 +391,27 @@
 // Step back n frames, skip any pseudo frames in between.
 // This function is used in Class.forName, Class.newInstance, Method.Invoke,
 // AccessController.doPrivileged.
-//
-// NOTE that in JDK 1.4 this has been exposed to Java as
-// sun.reflect.Reflection.getCallerClass(), which can be inlined.
-// Inlined versions must match this routine's logic.
-// Native method prefixing logic does not need to match since
-// the method names don't match and inlining will not occur.
-// See, for example,
-// Parse::inline_native_Reflection_getCallerClass in
-// opto/library_call.cpp.
 void vframeStreamCommon::security_get_caller_frame(int depth) {
-  bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection;
+  assert(depth >= 0, err_msg("invalid depth: %d", depth));
+  for (int n = 0; !at_end(); security_next()) {
+    if (!method()->is_ignored_by_security_stack_walk()) {
+      if (n == depth) {
+        // We have reached the desired depth; return.
+        return;
+      }
+      n++;  // this is a non-skipped frame; count it against the depth
+    }
+  }
+  // NOTE: At this point there were not enough frames on the stack
+  // to walk to depth.  Callers of this method have to check for at_end.
+}
 
-  while (!at_end()) {
-    if (Universe::reflect_invoke_cache()->is_same_method(method())) {
-      // This is Method.invoke() -- skip it
-    } else if (use_new_reflection &&
-              method()->method_holder()
-                 ->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
-      // This is an auxilary frame -- skip it
-    } else if (method()->is_method_handle_intrinsic() ||
-               method()->is_compiled_lambda_form()) {
-      // This is an internal adapter frame for method handles -- skip it
-    } else {
-      // This is non-excluded frame, we need to count it against the depth
-      if (depth-- <= 0) {
-        // we have reached the desired depth, we are done
-        break;
-      }
-    }
-    if (method()->is_prefixed_native()) {
-      skip_prefixed_method_and_wrappers();
-    } else {
-      next();
-    }
+
+void vframeStreamCommon::security_next() {
+  if (method()->is_prefixed_native()) {
+    skip_prefixed_method_and_wrappers();  // calls next()
+  } else {
+    next();
   }
 }
 
--- a/src/share/vm/runtime/vframe.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/vframe.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -336,6 +336,7 @@
       _frame = _frame.sender(&_reg_map);
     } while (!fill_from_frame());
   }
+  void security_next();
 
   bool at_end() const { return _mode == at_end_mode; }
 
--- a/src/share/vm/runtime/vm_version.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/runtime/vm_version.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -211,6 +211,10 @@
         #define HOTSPOT_BUILD_COMPILER "MS VC++ 8.0 (VS2005)"
       #elif _MSC_VER == 1500
         #define HOTSPOT_BUILD_COMPILER "MS VC++ 9.0 (VS2008)"
+      #elif _MSC_VER == 1600
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 10.0 (VS2010)"
+      #elif _MSC_VER == 1700
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 11.0 (VS2012)"
       #else
         #define HOTSPOT_BUILD_COMPILER "unknown MS VC++:" XSTR(_MSC_VER)
       #endif
--- a/src/share/vm/services/memTracker.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/services/memTracker.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -68,6 +68,7 @@
 volatile jint                   MemTracker::_pooled_recorder_count = 0;
 volatile unsigned long          MemTracker::_processing_generation = 0;
 volatile bool                   MemTracker::_worker_thread_idle = false;
+volatile bool                   MemTracker::_slowdown_calling_thread = false;
 debug_only(intx                 MemTracker::_main_thread_tid = 0;)
 NOT_PRODUCT(volatile jint       MemTracker::_pending_recorder_count = 0;)
 
@@ -126,12 +127,15 @@
   assert(_state == NMT_bootstrapping_multi_thread, "wrong state");
 
   _snapshot = new (std::nothrow)MemSnapshot();
-  if (_snapshot != NULL && !_snapshot->out_of_memory()) {
-    if (start_worker()) {
+  if (_snapshot != NULL) {
+    if (!_snapshot->out_of_memory() && start_worker()) {
       _state = NMT_started;
       NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack());
       return;
     }
+
+    delete _snapshot;
+    _snapshot = NULL;
   }
 
   // fail to start native memory tracking, shut it down
@@ -364,6 +368,12 @@
     }
 
     if (thread != NULL) {
+      // slow down all calling threads except NMT worker thread, so it
+      // can catch up.
+      if (_slowdown_calling_thread && thread != _worker_thread) {
+        os::yield_all();
+      }
+
       if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) {
         JavaThread*      java_thread = (JavaThread*)thread;
         JavaThreadState  state = java_thread->thread_state();
@@ -442,6 +452,7 @@
 #define MAX_SAFEPOINTS_TO_SKIP     128
 #define SAFE_SEQUENCE_THRESHOLD    30
 #define HIGH_GENERATION_THRESHOLD  60
+#define MAX_RECORDER_THREAD_RATIO  30
 
 void MemTracker::sync() {
   assert(_tracking_level > NMT_off, "NMT is not enabled");
@@ -487,6 +498,13 @@
         pending_recorders = _global_recorder;
         _global_recorder = NULL;
       }
+
+      // see if NMT has too many outstanding recorder instances, it usually
+      // means that worker thread is lagging behind in processing them.
+      if (!AutoShutdownNMT) {
+        _slowdown_calling_thread = (MemRecorder::_instance_count > MAX_RECORDER_THREAD_RATIO * _thread_count);
+      }
+
       // check _worker_thread with lock to avoid racing condition
       if (_worker_thread != NULL) {
         _worker_thread->at_sync_point(pending_recorders, InstanceKlass::number_of_instance_classes());
@@ -529,7 +547,10 @@
   assert(_worker_thread == NULL, "Just Check");
   _worker_thread = new (std::nothrow) MemTrackWorker();
   if (_worker_thread == NULL || _worker_thread->has_error()) {
-    shutdown(NMT_initialization);
+    if (_worker_thread != NULL) {
+      delete _worker_thread;
+      _worker_thread = NULL;
+    }
     return false;
   }
   _worker_thread->start();
--- a/src/share/vm/services/memTracker.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/services/memTracker.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -84,14 +84,15 @@
    static inline bool baseline() { return false; }
    static inline bool has_baseline() { return false; }
 
+   static inline void set_autoShutdown(bool value) { }
    static void shutdown(ShutdownReason reason) { }
-   static inline bool shutdown_in_progress() {  }
+   static inline bool shutdown_in_progress() { return false; }
    static bool print_memory_usage(BaselineOutputer& out, size_t unit,
-            bool summary_only = true) { }
+            bool summary_only = true) { return false; }
    static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
-            bool summary_only = true) { }
+            bool summary_only = true) { return false; }
 
-   static bool wbtest_wait_for_data_merge() { }
+   static bool wbtest_wait_for_data_merge() { return false; }
 
    static inline void sync() { }
    static inline void thread_exiting(JavaThread* thread) { }
@@ -238,6 +239,16 @@
   // if native memory tracking tracks callsite
   static inline bool track_callsite() { return _tracking_level == NMT_detail; }
 
+  // NMT automatically shuts itself down under extreme situation by default.
+  // When the value is set to false,  NMT will try its best to stay alive,
+  // even it has to slow down VM.
+  static inline void set_autoShutdown(bool value) {
+    AutoShutdownNMT = value;
+    if (AutoShutdownNMT && _slowdown_calling_thread) {
+      _slowdown_calling_thread = false;
+    }
+  }
+
   // shutdown native memory tracking capability. Native memory tracking
   // can be shutdown by VM when it encounters low memory scenarios.
   // Memory tracker should gracefully shutdown itself, and preserve the
@@ -507,6 +518,10 @@
   // although NMT is still procesing current generation, but
   // there is not more recorder to process, set idle state
   static volatile bool             _worker_thread_idle;
+
+  // if NMT should slow down calling thread to allow
+  // worker thread to catch up
+  static volatile bool             _slowdown_calling_thread;
 };
 
 #endif // !INCLUDE_NMT
--- a/src/share/vm/services/memoryService.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/services/memoryService.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -240,6 +240,7 @@
 void MemoryService::add_generation_memory_pool(Generation* gen,
                                                MemoryManager* major_mgr,
                                                MemoryManager* minor_mgr) {
+  guarantee(gen != NULL, "No generation for memory pool");
   Generation::Name kind = gen->kind();
   int index = _pools_list->length();
 
--- a/src/share/vm/services/nmtDCmd.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/services/nmtDCmd.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -49,6 +49,9 @@
   _shutdown("shutdown", "request runtime to shutdown itself and free the " \
             "memory used by runtime.",
             "BOOLEAN", false, "false"),
+  _auto_shutdown("autoShutdown", "automatically shutdown itself under "    \
+            "stress situation",
+            "BOOLEAN", true, "true"),
 #ifndef PRODUCT
   _debug("debug", "print tracker statistics. Debug only, not thread safe", \
             "BOOLEAN", false, "false"),
@@ -61,6 +64,7 @@
   _dcmdparser.add_dcmd_option(&_summary_diff);
   _dcmdparser.add_dcmd_option(&_detail_diff);
   _dcmdparser.add_dcmd_option(&_shutdown);
+  _dcmdparser.add_dcmd_option(&_auto_shutdown);
 #ifndef PRODUCT
   _dcmdparser.add_dcmd_option(&_debug);
 #endif
@@ -84,17 +88,19 @@
   }
 
   int nopt = 0;
-  if(_summary.is_set() && _summary.value()) { ++nopt; }
-  if(_detail.is_set() && _detail.value()) { ++nopt; }
-  if(_baseline.is_set() && _baseline.value()) { ++nopt; }
-  if(_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
-  if(_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
-  if(_shutdown.is_set() && _shutdown.value()) { ++nopt; }
+  if (_summary.is_set() && _summary.value()) { ++nopt; }
+  if (_detail.is_set() && _detail.value()) { ++nopt; }
+  if (_baseline.is_set() && _baseline.value()) { ++nopt; }
+  if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
+  if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
+  if (_shutdown.is_set() && _shutdown.value()) { ++nopt; }
+  if (_auto_shutdown.is_set()) { ++nopt; }
+
 #ifndef PRODUCT
-  if(_debug.is_set() && _debug.value()) { ++nopt; }
+  if (_debug.is_set() && _debug.value()) { ++nopt; }
 #endif
 
-  if(nopt > 1) {
+  if (nopt > 1) {
       output()->print_cr("At most one of the following option can be specified: " \
         "summary, detail, baseline, summary.diff, detail.diff, shutdown"
 #ifndef PRODUCT
@@ -156,6 +162,8 @@
     MemTracker::shutdown(MemTracker::NMT_shutdown_user);
     output()->print_cr("Shutdown is in progress, it will take a few moments to " \
       "completely shutdown");
+  } else if (_auto_shutdown.is_set()) {
+    MemTracker::set_autoShutdown(_auto_shutdown.value());
   } else {
     ShouldNotReachHere();
     output()->print_cr("Unknown command");
--- a/src/share/vm/services/nmtDCmd.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/services/nmtDCmd.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -39,6 +39,7 @@
   DCmdArgument<bool>  _summary_diff;
   DCmdArgument<bool>  _detail_diff;
   DCmdArgument<bool>  _shutdown;
+  DCmdArgument<bool>  _auto_shutdown;
 #ifndef PRODUCT
   DCmdArgument<bool>  _debug;
 #endif
--- a/src/share/vm/utilities/debug.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/utilities/debug.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -248,10 +248,6 @@
   report_vm_error(file, line, "ShouldNotReachHere()");
 }
 
-void report_should_not_reach_here2(const char* file, int line, const char* message) {
-  report_vm_error(file, line, "ShouldNotReachHere()", message);
-}
-
 void report_unimplemented(const char* file, int line) {
   report_vm_error(file, line, "Unimplemented()");
 }
@@ -612,18 +608,6 @@
   return  CodeCache::find_nmethod((address)addr);
 }
 
-static address same_page(address x, address y) {
-  intptr_t page_bits = -os::vm_page_size();
-  if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) {
-    return x;
-  } else if (x > y) {
-    return (address)(intptr_t(y) | ~page_bits) + 1;
-  } else {
-    return (address)(intptr_t(y) & page_bits);
-  }
-}
-
-
 // Another interface that isn't ambiguous in dbx.
 // Can we someday rename the other find to hsfind?
 extern "C" void hsfind(intptr_t x) {
--- a/src/share/vm/utilities/debug.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/utilities/debug.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -192,12 +192,6 @@
   BREAKPOINT;                                                                \
 } while (0)
 
-#define ShouldNotReachHere2(message)                                         \
-do {                                                                         \
-  report_should_not_reach_here2(__FILE__, __LINE__, message);                \
-  BREAKPOINT;                                                                \
-} while (0)
-
 #define Unimplemented()                                                      \
 do {                                                                         \
   report_unimplemented(__FILE__, __LINE__);                                  \
@@ -218,7 +212,6 @@
                              const char* message);
 void report_should_not_call(const char* file, int line);
 void report_should_not_reach_here(const char* file, int line);
-void report_should_not_reach_here2(const char* file, int line, const char* message);
 void report_unimplemented(const char* file, int line);
 void report_untested(const char* file, int line, const char* message);
 
--- a/src/share/vm/utilities/globalDefinitions.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/utilities/globalDefinitions.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -355,3 +355,33 @@
 
     return size_t(result);
 }
+
+#ifndef PRODUCT
+
+void GlobalDefinitions::test_globals() {
+  intptr_t page_sizes[] = { os::vm_page_size(), 4096, 8192, 65536, 2*1024*1024 };
+  const int num_page_sizes = sizeof(page_sizes) / sizeof(page_sizes[0]);
+
+  for (int i = 0; i < num_page_sizes; i++) {
+    intptr_t page_size = page_sizes[i];
+
+    address a_page = (address)(10*page_size);
+
+    // Check that address within page is returned as is
+    assert(clamp_address_in_page(a_page, a_page, page_size) == a_page, "incorrect");
+    assert(clamp_address_in_page(a_page + 128, a_page, page_size) == a_page + 128, "incorrect");
+    assert(clamp_address_in_page(a_page + page_size - 1, a_page, page_size) == a_page + page_size - 1, "incorrect");
+
+    // Check that address above page returns start of next page
+    assert(clamp_address_in_page(a_page + page_size, a_page, page_size) == a_page + page_size, "incorrect");
+    assert(clamp_address_in_page(a_page + page_size + 1, a_page, page_size) == a_page + page_size, "incorrect");
+    assert(clamp_address_in_page(a_page + page_size*5 + 1, a_page, page_size) == a_page + page_size, "incorrect");
+
+    // Check that address below page returns start of page
+    assert(clamp_address_in_page(a_page - 1, a_page, page_size) == a_page, "incorrect");
+    assert(clamp_address_in_page(a_page - 2*page_size - 1, a_page, page_size) == a_page, "incorrect");
+    assert(clamp_address_in_page(a_page - 5*page_size - 1, a_page, page_size) == a_page, "incorrect");
+  }
+}
+
+#endif // PRODUCT
--- a/src/share/vm/utilities/globalDefinitions.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -419,6 +419,24 @@
   return align_size_up(offset, HeapWordsPerLong);
 }
 
+// Clamp an address to be within a specific page
+// 1. If addr is on the page it is returned as is
+// 2. If addr is above the page_address the start of the *next* page will be returned
+// 3. Otherwise, if addr is below the page_address the start of the page will be returned
+inline address clamp_address_in_page(address addr, address page_address, intptr_t page_size) {
+  if (align_size_down(intptr_t(addr), page_size) == align_size_down(intptr_t(page_address), page_size)) {
+    // address is in the specified page, just return it as is
+    return addr;
+  } else if (addr > page_address) {
+    // address is above specified page, return start of next page
+    return (address)align_size_down(intptr_t(page_address), page_size) + page_size;
+  } else {
+    // address is below specified page, return start of page
+    return (address)align_size_down(intptr_t(page_address), page_size);
+  }
+}
+
+
 // The expected size in bytes of a cache line, used to pad data structures.
 #define DEFAULT_CACHE_LINE_SIZE 64
 
@@ -1296,4 +1314,15 @@
   return *(void**)addr;
 }
 
+
+#ifndef PRODUCT
+
+// For unit testing only
+class GlobalDefinitions {
+public:
+  static void test_globals();
+};
+
+#endif // PRODUCT
+
 #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_HPP
--- a/src/share/vm/utilities/utf8.cpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/utilities/utf8.cpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -180,11 +180,12 @@
 }
 
 // converts a utf8 string to quoted ascii
-void UTF8::as_quoted_ascii(const char* utf8_str, char* buf, int buflen) {
+void UTF8::as_quoted_ascii(const char* utf8_str, int utf8_length, char* buf, int buflen) {
   const char *ptr = utf8_str;
+  const char *utf8_end = ptr + utf8_length;
   char* p = buf;
   char* end = buf + buflen;
-  while (*ptr != '\0') {
+  while (ptr < utf8_end) {
     jchar c;
     ptr = UTF8::next(ptr, &c);
     if (c >= 32 && c < 127) {
@@ -196,6 +197,7 @@
       p += 6;
     }
   }
+  assert(p < end, "sanity");
   *p = '\0';
 }
 
--- a/src/share/vm/utilities/utf8.hpp	Tue Feb 26 16:16:54 2013 -0800
+++ b/src/share/vm/utilities/utf8.hpp	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -45,7 +45,7 @@
   static int quoted_ascii_length(const char* utf8_str, int utf8_length);
 
   // converts a utf8 string to quoted ascii
-  static void as_quoted_ascii(const char* utf8_str, char* buf, int buflen);
+  static void as_quoted_ascii(const char* utf8_str, int utf8_length, char* buf, int buflen);
 
   // converts a quoted ascii string to utf8 string.  returns the original
   // string unchanged if nothing needs to be done.
--- a/test/compiler/5091921/Test6890943.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/5091921/Test6890943.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -22,26 +22,16 @@
 # questions.
 # 
 # 
-
+## some tests require path to find test source dir
 if [ "${TESTSRC}" = "" ]
 then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
 echo "TESTSRC=${TESTSRC}"
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTJAVA=${TESTJAVA}"
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTCLASSES=${TESTCLASSES}"
-echo "CLASSPATH=${CLASSPATH}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
+
 
 set -x
 
@@ -50,7 +40,7 @@
 cp ${TESTSRC}/output6890943.txt .
 cp ${TESTSRC}/Test6890943.sh .
 
-${TESTJAVA}/bin/javac -d . Test6890943.java
+${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test6890943.java
 
 ${TESTJAVA}/bin/java -XX:-PrintVMOptions -XX:+IgnoreUnrecognizedVMOptions ${TESTVMOPTS} Test6890943 < input6890943.txt > pretest.out 2>&1
 
--- a/test/compiler/5091921/Test7005594.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/5091921/Test7005594.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -22,26 +22,15 @@
 # questions.
 # 
 # 
-
+## some tests require path to find test source dir
 if [ "${TESTSRC}" = "" ]
 then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
 echo "TESTSRC=${TESTSRC}"
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTJAVA=${TESTJAVA}"
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTCLASSES=${TESTCLASSES}"
-echo "CLASSPATH=${CLASSPATH}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 # Amount of physical memory in megabytes
 MEM=0
@@ -87,7 +76,7 @@
 cp ${TESTSRC}/Test7005594.java .
 cp ${TESTSRC}/Test7005594.sh .
 
-${TESTJAVA}/bin/javac -d . Test7005594.java
+${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7005594.java
 
 ${TESTJAVA}/bin/java ${TESTVMOPTS} -Xms1600m -XX:+IgnoreUnrecognizedVMOptions -XX:-ZapUnusedHeapArea -Xcomp -XX:CompileOnly=Test7005594.test Test7005594 > test.out 2>&1
 
--- a/test/compiler/6857159/Test6857159.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/6857159/Test6857159.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -22,33 +22,22 @@
 # questions.
 # 
 # 
-
+## some tests require path to find test source dir
 if [ "${TESTSRC}" = "" ]
 then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
 echo "TESTSRC=${TESTSRC}"
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTJAVA=${TESTJAVA}"
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTCLASSES=${TESTCLASSES}"
-echo "CLASSPATH=${CLASSPATH}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 set -x
 
 cp ${TESTSRC}/Test6857159.java .
 cp ${TESTSRC}/Test6857159.sh .
 
-${TESTJAVA}/bin/javac -d . Test6857159.java
+${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test6857159.java
 
 ${TESTJAVA}/bin/java  ${TESTVMOPTS} -Xbatch -XX:+PrintCompilation -XX:CompileOnly=Test6857159\$ct.run Test6857159 > test.out 2>&1
 
--- a/test/compiler/7068051/Test7068051.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/7068051/Test7068051.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -22,28 +22,24 @@
 # questions.
 # 
 # 
-
+## some tests require path to find test source dir
 if [ "${TESTSRC}" = "" ]
 then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
 echo "TESTSRC=${TESTSRC}"
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTJAVA=${TESTJAVA}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 set -x
 
-${TESTJAVA}/bin/jar xf ${TESTJAVA}/jre/lib/javaws.jar
-${TESTJAVA}/bin/jar cf foo.jar *
+${COMPILEJAVA}/bin/jar xf ${COMPILEJAVA}/jre/lib/javaws.jar
+${COMPILEJAVA}/bin/jar cf foo.jar *
 cp ${TESTSRC}/Test7068051.java ./
-${TESTJAVA}/bin/jar -uf0 foo.jar Test7068051.java
+${COMPILEJAVA}/bin/jar -uf0 foo.jar Test7068051.java
 
-${TESTJAVA}/bin/javac -d . Test7068051.java
+${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7068051.java
 
 ${TESTJAVA}/bin/java ${TESTVMOPTS} -showversion -Xbatch Test7068051 foo.jar
 
--- a/test/compiler/7070134/Test7070134.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/7070134/Test7070134.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -22,33 +22,22 @@
 # questions.
 # 
 # 
-
+## some tests require path to find test source dir
 if [ "${TESTSRC}" = "" ]
 then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
 echo "TESTSRC=${TESTSRC}"
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTJAVA=${TESTJAVA}"
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTCLASSES=${TESTCLASSES}"
-echo "CLASSPATH=${CLASSPATH}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 set -x
 
 cp ${TESTSRC}/Stemmer.java .
 cp ${TESTSRC}/words .
 
-${TESTJAVA}/bin/javac -d . Stemmer.java
+${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Stemmer.java
 
 ${TESTJAVA}/bin/java ${TESTVMOPTS} -Xbatch Stemmer words > test.out 2>&1
 
--- a/test/compiler/7200264/Test7200264.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/7200264/Test7200264.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -23,50 +23,15 @@
 # 
 # 
 
+## some tests require path to find test source dir
 if [ "${TESTSRC}" = "" ]
 then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
 echo "TESTSRC=${TESTSRC}"
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTJAVA=${TESTJAVA}"
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTCLASSES=${TESTCLASSES}"
-echo "CLASSPATH=${CLASSPATH}"
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  SunOS | Linux | Darwin )
-    NULL=/dev/null
-    PS=":"
-    FS="/"
-    ;;
-  Windows_* )
-    NULL=NUL
-    PS=";"
-    FS="\\"
-    ;;
-  CYGWIN_* )
-    NULL=/dev/null
-    PS=";"
-    FS="/"
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
-
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion | sed 's/amd64/x86/' | grep "x86" | grep "Server VM" | grep "debug"
 
@@ -88,7 +53,7 @@
 fi
 
 cp ${TESTSRC}${FS}TestIntVect.java .
-${TESTJAVA}${FS}bin${FS}javac -d . TestIntVect.java
+${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} -d . TestIntVect.java
 
 ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+PrintCompilation -XX:+TraceNewVectors TestIntVect > test.out 2>&1
 
--- a/test/compiler/8009761/Test8009761.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/8009761/Test8009761.java	Fri Apr 12 10:14:42 2013 +0100
@@ -25,7 +25,7 @@
  * @test
  * @bug 8009761
  * @summary Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates
- * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8009761
+ * @run main/othervm -Xmixed -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8009761
  *
  */
 
--- a/test/compiler/whitebox/CompilerWhiteBoxTest.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java	Fri Apr 12 10:14:42 2013 +0100
@@ -35,6 +35,8 @@
     protected static final Method METHOD = getMethod("method");
     protected static final int COMPILE_THRESHOLD
             = Integer.parseInt(getVMOption("CompileThreshold", "10000"));
+    protected static final boolean BACKGROUND_COMPILATION
+            = Boolean.valueOf(getVMOption("BackgroundCompilation", "true"));
 
     protected static Method getMethod(String name) {
         try {
@@ -45,11 +47,16 @@
         }
     }
 
-    protected static String getVMOption(String name, String defaultValue) {
+    protected static String getVMOption(String name) {
         String result;
         HotSpotDiagnosticMXBean diagnostic
                 = ManagementFactoryHelper.getDiagnosticMXBean();
         result = diagnostic.getVMOption(name).getValue();
+        return result;
+    }
+
+    protected static String getVMOption(String name, String defaultValue) {
+        String result = getVMOption(name);
         return result == null ? defaultValue : result;
     }
 
@@ -66,6 +73,7 @@
         } catch (Exception e) {
             System.out.printf("on exception '%s':", e.getMessage());
             printInfo(METHOD);
+            e.printStackTrace();
             throw new RuntimeException(e);
         }
         System.out.println("at test's end:");
@@ -100,6 +108,9 @@
 
     protected static void waitBackgroundCompilation(Method method)
             throws InterruptedException {
+        if (!BACKGROUND_COMPILATION) {
+            return;
+        }
         final Object obj = new Object();
         synchronized (obj) {
             for (int i = 0; i < 10; ++i) {
@@ -129,13 +140,14 @@
 
     protected final int compile() {
         int result = 0;
-        for (int i = 0; i < COMPILE_THRESHOLD; ++i) {
+        int count = Math.max(COMPILE_THRESHOLD, 150000);
+        for (int i = 0; i < count; ++i) {
             result += method();
         }
+        System.out.println("method was invoked " + count + " times");
         return result;
     }
 
-
     protected int method() {
         return 42;
     }
--- a/test/compiler/whitebox/DeoptimizeAllTest.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/whitebox/DeoptimizeAllTest.java	Fri Apr 12 10:14:42 2013 +0100
@@ -32,12 +32,12 @@
 public class DeoptimizeAllTest extends CompilerWhiteBoxTest {
 
     public static void main(String[] args) throws Exception {
+        // to prevent inlining #method into #compile()
+        WHITE_BOX.setDontInlineMethod(METHOD, true);
         new DeoptimizeAllTest().runTest();
     }
 
     protected void test() throws Exception {
-        // to prevent inlining #method into #compile()
-        WHITE_BOX.setDontInlineMethod(METHOD, true);
         compile();
         checkCompiled(METHOD);
         WHITE_BOX.deoptimizeAll();
--- a/test/compiler/whitebox/DeoptimizeMethodTest.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/whitebox/DeoptimizeMethodTest.java	Fri Apr 12 10:14:42 2013 +0100
@@ -32,12 +32,12 @@
 public class DeoptimizeMethodTest extends CompilerWhiteBoxTest {
 
     public static void main(String[] args) throws Exception {
+        // to prevent inlining #method into #compile()
+        WHITE_BOX.setDontInlineMethod(METHOD, true);
         new DeoptimizeMethodTest().runTest();
     }
 
     protected void test() throws Exception {
-        // to prevent inlining #method into #compile()
-        WHITE_BOX.setDontInlineMethod(METHOD, true);
         compile();
         checkCompiled(METHOD);
         WHITE_BOX.deoptimizeMethod(METHOD);
--- a/test/compiler/whitebox/IsMethodCompilableTest.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/whitebox/IsMethodCompilableTest.java	Fri Apr 12 10:14:42 2013 +0100
@@ -44,6 +44,8 @@
     }
 
     public static void main(String[] args) throws Exception {
+        // to prevent inlining #method into #compile()
+        WHITE_BOX.setDontInlineMethod(METHOD, true);
         new IsMethodCompilableTest().runTest();
     }
 
@@ -58,8 +60,6 @@
                     "Warning: test is not applicable if PerMethodRecompilationCutoff == Inf");
             return;
         }
-        // to prevent inlining #method into #compile()
-        WHITE_BOX.setDontInlineMethod(METHOD, true);
         boolean madeNotCompilable = false;
 
         for (long i = 0; i < PER_METHOD_RECOMPILATION_CUTOFF; ++i) {
--- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Fri Apr 12 10:14:42 2013 +0100
@@ -32,6 +32,8 @@
 public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
 
     public static void main(String[] args) throws Exception {
+        // to prevent inlining #method into #compile()
+        WHITE_BOX.setDontInlineMethod(METHOD, true);
         new MakeMethodNotCompilableTest().runTest();
     }
 
--- a/test/gc/6941923/test6941923.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/gc/6941923/test6941923.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -5,38 +5,25 @@
 ## @author yqi 
 ## @run shell test6941923.sh
 ##
+## some tests require path to find test source dir
+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
 
 ## skip on windows
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | Darwin )
-    NULL=/dev/null
-    PS=":"
-    FS="/"
-    ;;
   Windows_* | CYGWIN_* )
     echo "Test skipped for Windows"
     exit 0 
     ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
 esac
 
-if [ "${JAVA_HOME}" = "" ]
-then
-  echo "JAVA_HOME not set"
-  exit 0
-fi
-
-$JAVA_HOME/bin/java ${TESTVMOPTS} -version > $NULL 2>&1
-
-if [ $? != 0 ]; then
-  echo "Wrong JAVA_HOME? JAVA_HOME: $JAVA_HOME"
-  exit $?
-fi
-
 # create a small test case
 testname="Test"
 if [ -e ${testname}.java ]; then
@@ -96,10 +83,10 @@
 msgfail="failed"
 gclogsize="16K"
 filesize=$((16*1024))
-$JAVA_HOME/bin/javac ${testname}.java > $NULL 2>&1
+${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${testname}.java > $NULL 2>&1
 
 if [ $? != 0 ]; then
-  echo "$JAVA_HOME/bin/javac ${testname}.java $fail"
+  echo "${COMPILEJAVA}/bin/javac ${testname}.java $fail"
   exit -1
 fi
 
@@ -119,7 +106,7 @@
 
 options="-Xloggc:$logfile -XX:+UseConcMarkSweepGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+UseGCLogFileRotation  -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=$gclogsize"
 echo "Test gc log rotation in same file, wait for $tts minutes ...."
-$JAVA_HOME/bin/java ${TESTVMOPTS} $options $testname $tts
+${TESTJAVA}/bin/java $options $testname $tts
 if [ $? != 0 ]; then
   echo "$msgfail"
   exit -1
@@ -148,7 +135,7 @@
 numoffiles=3
 options="-Xloggc:$logfile -XX:+UseConcMarkSweepGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+UseGCLogFileRotation  -XX:NumberOfGCLogFiles=$numoffiles -XX:GCLogFileSize=$gclogsize"
 echo "Test gc log rotation in $numoffiles files, wait for $tts minutes ...."
-$JAVA_HOME/bin/java ${TESTVMOPTS} $options $testname $tts
+${TESTJAVA}/bin/java $options $testname $tts
 if [ $? != 0 ]; then
   echo "$msgfail"
   exit -1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/TestVerifyBeforeGCDuringStartup.java	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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 TestVerifyBeforeGCDuringStartup.java
+ * @key gc
+ * @bug 8010463
+ * @summary Simple test run with -XX:+VerifyBeforeGC -XX:-UseTLAB to verify 8010463
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class TestVerifyBeforeGCDuringStartup {
+  public static void main(String args[]) throws Exception {
+    ProcessBuilder pb =
+      ProcessTools.createJavaProcessBuilder(System.getProperty("test.vm.opts"),
+                                            "-XX:-UseTLAB",
+                                            "-XX:+UnlockDiagnosticVMOptions",
+                                            "-XX:+VerifyBeforeGC", "-version");
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("[Verifying");
+    output.shouldHaveExitValue(0);
+  }
+}
--- a/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java	Fri Apr 12 10:14:42 2013 +0100
@@ -39,8 +39,10 @@
     public static void main(String[] args) throws Exception {
         String pid = Integer.toString(ProcessTools.getProcessId());
 
-        ProcessBuilder pb = new ProcessBuilder();
-        pb.command(JDKToolFinder.getJDKTool("jmap"), "-heap",  pid);
+        JDKToolLauncher jmap = JDKToolLauncher.create("jmap")
+                                              .addToolArg("-heap")
+                                              .addToolArg(pid);
+        ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
 
         File out = new File("ClassMetaspaceSizeInJmapHeap.stdout.txt");
         pb.redirectOutput(out);
--- a/test/runtime/6626217/Test6626217.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/6626217/Test6626217.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -27,78 +27,29 @@
 # @summary Loader-constraint table allows arrays instead of only the base-classes
 # @run shell Test6626217.sh
 #
-
+## some tests require path to find test source dir
 if [ "${TESTSRC}" = "" ]
-  then TESTSRC=.
-fi
-
-if [ "${TESTJAVA}" = "" ]
 then
-  PARENT=`dirname \`which java\``
-  TESTJAVA=`dirname ${PARENT}`
-  echo "TESTJAVA not set, selecting " ${TESTJAVA}
-  echo "If this is incorrect, try setting the variable manually."
-fi
-
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  SunOS | Linux | Darwin )
-    NULL=/dev/null
-    PS=":"
-    FS="/"
-    RM=/bin/rm
-    CP=/bin/cp
-    MV=/bin/mv
-    ;;
-  Windows_* )
-    NULL=NUL
-    PS=";"
-    FS="\\"
-    RM=rm
-    CP=cp
-    MV=mv
-    ;;
-  CYGWIN_* )
-    NULL=/dev/null
-    PS=";"
-    FS="/"
-    RM=rm
-    CP=cp
-    MV=mv
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
-
-JEMMYPATH=${CPAPPEND}
-CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH
-
-THIS_DIR=`pwd`
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 JAVA=${TESTJAVA}${FS}bin${FS}java
-JAVAC=${TESTJAVA}${FS}bin${FS}javac
-
-${JAVA} ${TESTVMOPTS} -version
+JAVAC=${COMPILEJAVA}${FS}bin${FS}javac
 
 # Current directory is scratch directory, copy all the test source there
 # (for the subsequent moves to work).
-${CP} ${TESTSRC}${FS}*  ${THIS_DIR}
+${CP} ${TESTSRC}${FS}* ${THIS_DIR}
 
 # A Clean Compile: this line will probably fail within jtreg as have a clean dir:
 ${RM} -f *.class *.impl many_loader.java
 
 # Compile all the usual suspects, including the default 'many_loader'
 ${CP} many_loader1.java.foo many_loader.java
-${JAVAC} -source 1.4 -target 1.4 -Xlint *.java
+${JAVAC} ${TESTJAVACOPTS} -source 1.4 -target 1.4 -Xlint *.java
 
 # Rename the class files, so the custom loader (and not the system loader) will find it
 ${MV} from_loader2.class from_loader2.impl2
@@ -106,7 +57,7 @@
 # Compile the next version of 'many_loader'
 ${MV} many_loader.class many_loader.impl1
 ${CP} many_loader2.java.foo many_loader.java
-${JAVAC} -source 1.4 -target 1.4 -Xlint many_loader.java
+${JAVAC} ${TESTJAVACOPTS} -source 1.4 -target 1.4 -Xlint many_loader.java
 
 # Rename the class file, so the custom loader (and not the system loader) will find it
 ${MV} many_loader.class many_loader.impl2
--- a/test/runtime/6878713/Test6878713.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/6878713/Test6878713.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -1,71 +1,137 @@
 #!/bin/sh
 
+# 
+#  Copyright (c) 2011, 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 6878713
+## @bug 7030610
+## @bug 7037122
+## @bug 7123945
 ## @summary Verifier heap corruption, relating to backward jsrs
-## @run shell/timeout=120 Test6878713.sh
+## @run shell Test6878713.sh
 ##
-
+## some tests require path to find test source dir
 if [ "${TESTSRC}" = "" ]
-then TESTSRC=.
-fi
-
-if [ "${TESTJAVA}" = "" ]
 then
-  PARENT=`dirname \`which java\``
-  TESTJAVA=`dirname ${PARENT}`
-  echo "TESTJAVA not set, selecting " ${TESTJAVA}
-  echo "If this is incorrect, try setting the variable manually."
+  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
 
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
+TARGET_CLASS=OOMCrashClass1960_2
+
+echo "INFO: extracting the target class."
+${COMPILEJAVA}${FS}bin${FS}jar xvf \
+    ${TESTSRC}${FS}testcase.jar ${TARGET_CLASS}.class
+
+# remove any hs_err_pid that might exist here
+rm -f hs_err_pid*.log
+
+echo "INFO: checking for 32-bit versus 64-bit VM."
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version 2>&1 \
+    | grep "64-Bit [^ ][^ ]* VM" > /dev/null 2>&1
+status="$?"
+if [ "$status" = 0 ]; then
+    echo "INFO: testing a 64-bit VM."
+    is_64_bit=true
+else
+    echo "INFO: testing a 32-bit VM."
 fi
 
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  SunOS | Linux | Darwin )
-    NULL=/dev/null
-    PS=":"
-    FS="/"
-    ;;
-  Windows_* )
-    NULL=NUL
-    PS=";"
-    FS="\\"
-    ;;
-  CYGWIN_* )
-    NULL=/dev/null
-    PS=";"
-    FS="/"
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
+if [ "$is_64_bit" = true ]; then
+    # limit is 768MB in 8-byte words (1024 * 1024 * 768 / 8) == 100663296
+    MALLOC_MAX=100663296
+else
+    # limit is 768MB in 4-byte words (1024 * 1024 * 768 / 4) == 201326592
+    MALLOC_MAX=201326592
+fi
+echo "INFO: MALLOC_MAX=$MALLOC_MAX"
+
+echo "INFO: executing the target class."
+# -XX:+PrintCommandLineFlags for debugging purposes
+# -XX:+IgnoreUnrecognizedVMOptions so test will run on a VM without
+#     the new -XX:MallocMaxTestWords option
+# -XX:+UnlockDiagnosticVMOptions so we can use -XX:MallocMaxTestWords
+# -XX:MallocMaxTestWords limits malloc to $MALLOC_MAX
+${TESTJAVA}${FS}bin${FS}java \
+    -XX:+PrintCommandLineFlags \
+    -XX:+IgnoreUnrecognizedVMOptions \
+    -XX:+UnlockDiagnosticVMOptions \
+    -XX:MallocMaxTestWords=$MALLOC_MAX \
+    ${TESTVMOPTS} ${TARGET_CLASS} > test.out 2>&1
+
+echo "INFO: begin contents of test.out:"
+cat test.out
+echo "INFO: end contents of test.out."
 
-JEMMYPATH=${CPAPPEND}
-CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH
-
-THIS_DIR=`pwd`
-
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version
-
-${TESTJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar
+echo "INFO: checking for memory allocation error message."
+# We are looking for this specific memory allocation failure mesg so
+# we know we exercised the right allocation path with the test class:
+MESG1="Native memory allocation (malloc) failed to allocate 25696531[0-9][0-9] bytes"
+grep "$MESG1" test.out
+status="$?"
+if [ "$status" = 0 ]; then
+    echo "INFO: found expected memory allocation error message."
+else
+    echo "INFO: did not find expected memory allocation error message."
 
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass1960_2 > test.out 2>&1
+    # If we didn't find MESG1 above, then there are several scenarios:
+    # 1) -XX:MallocMaxTestWords is not supported by the current VM and we
+    #    didn't fail TARGET_CLASS's memory allocation attempt; instead
+    #    we failed to find TARGET_CLASS's main() method. The TARGET_CLASS
+    #    is designed to provoke a memory allocation failure during class
+    #    loading; we actually don't care about running the class which is
+    #    why it doesn't have a main() method.
+    # 2) we failed a memory allocation, but not the one we were looking
+    #    so it might be that TARGET_CLASS no longer tickles the same
+    #    memory allocation code path
+    # 3) TARGET_CLASS reproduces the failure mode (SIGSEGV) fixed by
+    #    6878713 because the test is running on a pre-fix VM.
+    echo "INFO: checking for no main() method message."
+    MESG2="Error: Main method not found in class"
+    grep "$MESG2" test.out
+    status="$?"
+    if [ "$status" = 0 ]; then
+        echo "INFO: found no main() method message."
+    else
+        echo "FAIL: did not find no main() method message."
+        # status is non-zero for exit below
 
-if [ -s core -o -s "hs_*.log" ]
-then
-    cat hs*.log
-    echo "Test Failed"
-    exit 1
-else
-    echo "Test Passed"
-    exit 0
+        if [ -s hs_err_pid*.log ]; then
+            echo "INFO: begin contents of hs_err_pid file:"
+            cat hs_err_pid*.log
+            echo "INFO: end contents of hs_err_pid file."
+        fi
+    fi
 fi
+
+if [ "$status" = 0 ]; then
+    echo "PASS: test found one of the expected messages."
+fi
+exit "$status"
--- a/test/runtime/6929067/Test6929067.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/6929067/Test6929067.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -7,18 +7,15 @@
 ## @compile T.java
 ## @run shell Test6929067.sh
 ##
-
+set -x
 if [ "${TESTSRC}" = "" ]
-then TESTSRC=.
+then
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
-
-if [ "${TESTJAVA}" = "" ]
-then
-  PARENT=`dirname \`which java\``
-  TESTJAVA=`dirname ${PARENT}`
-  echo "TESTJAVA not set, selecting " ${TESTJAVA}
-  echo "If this is incorrect, try setting the variable manually."
-fi
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 # set platform-dependent variables
 OS=`uname -s`
@@ -107,7 +104,7 @@
 fi
 
 
-LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${ARCH}/${VMTYPE}:/usr/lib:$LD_LIBRARY_PATH
+LD_LIBRARY_PATH=.:${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE}:/usr/lib:$LD_LIBRARY_PATH
 export LD_LIBRARY_PATH
 
 cp ${TESTSRC}${FS}invoke.c .
@@ -115,15 +112,16 @@
 # Copy the result of our @compile action:
 cp ${TESTCLASSES}${FS}T.class .
 
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -fullversion
-
 echo "Architecture: ${ARCH}"
 echo "Compilation flag: ${COMP_FLAG}"
 echo "VM type: ${VMTYPE}"
+# Note pthread may not be found thus invoke creation will fail to be created.
+# Check to ensure you have a /usr/lib/libpthread.so if you don't please look
+# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation.
 
 gcc -DLINUX ${COMP_FLAG} -o invoke \
-  -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \
-  -L${TESTJAVA}/jre/lib/${ARCH}/${VMTYPE} \
+  -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
+  -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
   -ljvm -lpthread invoke.c
 
 ./invoke
--- a/test/runtime/7020373/Test7020373.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/7020373/Test7020373.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -10,55 +10,15 @@
 ##
 
 if [ "${TESTSRC}" = "" ]
-then TESTSRC=.
+then
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
-
-if [ "${TESTJAVA}" = "" ]
-then
-  PARENT=`dirname \`which java\``
-  TESTJAVA=`dirname ${PARENT}`
-  echo "TESTJAVA not set, selecting " ${TESTJAVA}
-  echo "If this is incorrect, try setting the variable manually."
-fi
-
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  SunOS | Linux | Darwin )
-    NULL=/dev/null
-    PS=":"
-    FS="/"
-    ;;
-  Windows_* )
-    NULL=NUL
-    PS=";"
-    FS="\\"
-    ;;
-  CYGWIN_* )
-    NULL=/dev/null
-    PS=";"
-    FS="/"
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
-
-JEMMYPATH=${CPAPPEND}
-CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH
-
-THIS_DIR=`pwd`
-
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version
-
-${TESTJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar
+${COMPILEJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar
 
 ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass4000_1 > test.out 2>&1
 
--- a/test/runtime/7051189/Xchecksig.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/7051189/Xchecksig.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -29,34 +29,22 @@
 #
 
 if [ "${TESTSRC}" = "" ]
-  then TESTSRC=.
+then
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
-
-if [ "${TESTJAVA}" = "" ]
-then
-  PARENT=`dirname \`which java\``
-  TESTJAVA=`dirname ${PARENT}`
-  printf "TESTJAVA not set, selecting " ${TESTJAVA}
-  printf "  If this is incorrect, try setting the variable manually.\n"
-fi
-
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux | Darwin )
-    FS="/"
-    ;;
   Windows_* | CYGWIN_* )
     printf "Not testing libjsig.so on Windows. PASSED.\n "
     exit 0
     ;;
-  * )
-    printf "Not testing libjsig.so on unrecognised system. PASSED.\n "
-    exit 0
-    ;;
 esac
 
-
 JAVA=${TESTJAVA}${FS}bin${FS}java
 
 # LD_PRELOAD arch needs to match the binary we run, so run the java
@@ -97,7 +85,7 @@
   ;; 
 esac
 
-LIBJSIG=${TESTJAVA}${FS}jre${FS}lib${FS}${ARCH}${FS}libjsig.so
+LIBJSIG=${COMPILEJAVA}${FS}jre${FS}lib${FS}${ARCH}${FS}libjsig.so
 
 # If libjsig and binary do not match, skip test.
 
--- a/test/runtime/7107135/Test7107135.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/7107135/Test7107135.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -32,26 +32,19 @@
 ##
 
 if [ "${TESTSRC}" = "" ]
-then TESTSRC=.
+then
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
-
-if [ "${TESTJAVA}" = "" ]
-then
-  PARENT=`dirname \`which java\``
-  TESTJAVA=`dirname ${PARENT}`
-  echo "TESTJAVA not set, selecting " ${TESTJAVA}
-  echo "If this is incorrect, try setting the variable manually."
-fi
-
-BIT_FLAG=""
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
   Linux)
-    NULL=/dev/null
-    PS=":"
-    FS="/"
+    echo "Testing on Linux"
     ;;
   *)
     NULL=NUL
@@ -64,7 +57,7 @@
 
 ARCH=`uname -m`
 
-THIS_DIR=`pwd`
+THIS_DIR=.
 
 cp ${TESTSRC}${FS}*.java ${THIS_DIR}
 ${TESTJAVA}${FS}bin${FS}javac *.java
--- a/test/runtime/7110720/Test7110720.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/7110720/Test7110720.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -12,22 +12,13 @@
 #
 
 if [ "${TESTSRC}" = "" ]
-  then TESTSRC=.
+then
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
-
-if [ "${TESTJAVA}" = "" ]
-then
-  PARENT=`dirname \`which java\``
-  TESTJAVA=`dirname ${PARENT}`
-  echo "TESTJAVA not set, selecting " ${TESTJAVA}
-  echo "If this is incorrect, try setting the variable manually."
-fi
-
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 # Jtreg sets TESTVMOPTS which may include -d64 which is
 # required to test a 64-bit JVM on some platforms.
--- a/test/runtime/7116786/Test7116786.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/7116786/Test7116786.java	Fri Apr 12 10:14:42 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -338,9 +338,12 @@
                  "invalid constant pool index in ldc",
                  "Invalid index in ldc"),
 
-        new Case("case58", "verifier.cpp", true, "verify_switch",
+        /* No longer a valid test case for bytecode version >= 51. Nonzero
+         * padding bytes are permitted with lookupswitch and tableswitch
+         * bytecodes as of JVMS 3d edition */
+        new Case("case58", "verifier.cpp", false, "verify_switch",
                  "bad switch padding",
-                 "Nonzero padding byte in lookswitch or tableswitch"),
+                 "Nonzero padding byte in lookupswitch or tableswitch"),
 
         new Case("case59", "verifier.cpp", true, "verify_switch",
                  "tableswitch low is greater than high",
--- a/test/runtime/7158804/Test7158804.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/7158804/Test7158804.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -10,13 +10,14 @@
 ## @summary Improve config file parsing
 ## @run shell Test7158804.sh
 ##
-
-if [ "${TESTJAVA}" = "" ]
+if [ "${TESTSRC}" = "" ]
 then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
-echo "TESTJAVA=${TESTJAVA}"
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 rm -f .hotspotrc
 echo -XX:+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >.hotspotrc
--- a/test/runtime/7162488/Test7162488.sh	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/7162488/Test7162488.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -29,27 +29,13 @@
 #
 
 if [ "${TESTSRC}" = "" ]
-  then TESTSRC=.
-fi
-
-if [ "${TESTJAVA}" = "" ]
 then
-  PARENT=`dirname \`which java\``
-  TESTJAVA=`dirname ${PARENT}`
-  printf "TESTJAVA not set, selecting " ${TESTJAVA}
-  printf "  If this is incorrect, try setting the variable manually.\n"
+  TESTSRC=${PWD}
+  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  Windows_* )
-    FS="\\"
-    ;;
-  * )
-    FS="/"
-    ;;
-esac
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
 
 JAVA=${TESTJAVA}${FS}bin${FS}java
 
--- a/test/runtime/8007736/TestStaticIF.java	Tue Feb 26 16:16:54 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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 8007736
- * @summary Test static interface method.
- * @run main/othervm -Xverify:all TestStaticIF
- */
-
-public class TestStaticIF implements StaticMethodInInterface {
-
-    public static void main(String[] args) {
-        System.out.printf("main: %s%n", StaticMethodInInterface.get());
-    }
-}
-
-interface StaticMethodInInterface {
-
-    public static String get() {
-        return "Hello from StaticMethodInInterface.get()";
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/8010389/VMThreadDlopen.java	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+/*
+ * @test
+ * @key regression
+ * @bug 8010389
+ * @run main/othervm -Djava.library.path=. VMThreadDlopen
+ */
+
+public class VMThreadDlopen {
+    public static void main(String[] args) throws Exception {
+        File file = new File("libbroken.so");
+        file.createNewFile();
+        try {
+            System.loadLibrary("broken");
+        } catch (UnsatisfiedLinkError e) {
+            e.printStackTrace();
+            // expected
+        }
+    }
+}
--- a/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java	Fri Apr 12 10:14:42 2013 +0100
@@ -33,17 +33,17 @@
 public class BooleanFlagWithInvalidValue {
   public static void main(String[] args) throws Exception {
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:+UseLargePages=8", "-version");
+        "-XX:+PrintWarnings=8", "-version");
 
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
-    output.shouldContain("Improperly specified VM option 'UseLargePages=8'");
+    output.shouldContain("Improperly specified VM option 'PrintWarnings=8'");
     output.shouldHaveExitValue(1);
 
     pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:-UseLargePages=8", "-version");
+        "-XX:-PrintWarnings=8", "-version");
 
     output = new OutputAnalyzer(pb.start());
-    output.shouldContain("Improperly specified VM option 'UseLargePages=8'");
+    output.shouldContain("Improperly specified VM option 'PrintWarnings=8'");
     output.shouldHaveExitValue(1);
   }
 }
--- a/test/runtime/CommandLine/FlagWithInvalidValue.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/CommandLine/FlagWithInvalidValue.java	Fri Apr 12 10:14:42 2013 +0100
@@ -33,10 +33,10 @@
 public class FlagWithInvalidValue {
   public static void main(String[] args) throws Exception {
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:ObjectAlignmentInBytes=v", "-version");
+        "-XX:MaxRAMFraction=v", "-version");
 
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
-    output.shouldContain("Improperly specified VM option 'ObjectAlignmentInBytes=v'");
+    output.shouldContain("Improperly specified VM option 'MaxRAMFraction=v'");
     output.shouldHaveExitValue(1);
   }
 }
--- a/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java	Fri Apr 12 10:14:42 2013 +0100
@@ -33,17 +33,17 @@
 public class NonBooleanFlagWithInvalidBooleanPrefix {
   public static void main(String[] args) throws Exception {
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:-ObjectAlignmentInBytes=16", "-version");
+        "-XX:-MaxRAMFraction=16", "-version");
 
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
-    output.shouldContain("Unexpected +/- setting in VM option 'ObjectAlignmentInBytes=16'");
+    output.shouldContain("Unexpected +/- setting in VM option 'MaxRAMFraction=16'");
     output.shouldHaveExitValue(1);
 
     pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:+ObjectAlignmentInBytes=16", "-version");
+        "-XX:+MaxRAMFraction=16", "-version");
 
     output = new OutputAnalyzer(pb.start());
-    output.shouldContain("Unexpected +/- setting in VM option 'ObjectAlignmentInBytes=16'");
+    output.shouldContain("Unexpected +/- setting in VM option 'MaxRAMFraction=16'");
     output.shouldHaveExitValue(1);
 
   }
--- a/test/runtime/NMT/AllocTestType.java	Tue Feb 26 16:16:54 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * 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
- * @summary Test consistency of NMT by leaking a few select allocations of the Test type and then verify visibility with jcmd
- * @key nmt jcmd
- * @library /testlibrary /testlibrary/whitebox
- * @build AllocTestType
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail AllocTestType
- */
-
-import com.oracle.java.testlibrary.*;
-import sun.hotspot.WhiteBox;
-
-public class AllocTestType {
-
-  public static void main(String args[]) throws Exception {
-    OutputAnalyzer output;
-
-    // Grab my own PID
-    String pid = Integer.toString(ProcessTools.getProcessId());
-    ProcessBuilder pb = new ProcessBuilder();
-
-    // Use WB API to alloc with the mtTest type
-    if (!WhiteBox.getWhiteBox().NMTAllocTest()) {
-      throw new Exception("Call to WB API NMTAllocTest() failed");
-    }
-
-    // Use WB API to ensure that all data has been merged before we continue
-    if (!WhiteBox.getWhiteBox().NMTWaitForDataMerge()) {
-      throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
-    }
-
-    // Run 'jcmd <pid> VM.native_memory summary'
-    pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
-    output = new OutputAnalyzer(pb.start());
-    output.shouldContain("Test (reserved=512KB, committed=512KB)");
-
-    // Free the memory allocated by NMTAllocTest
-    if (!WhiteBox.getWhiteBox().NMTFreeTestMemory()) {
-      throw new Exception("Call to WB API NMTFreeTestMemory() failed");
-    }
-
-    // Use WB API to ensure that all data has been merged before we continue
-    if (!WhiteBox.getWhiteBox().NMTWaitForDataMerge()) {
-      throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
-    }
-    output = new OutputAnalyzer(pb.start());
-    output.shouldNotContain("Test (reserved=");
-  }
-}
--- a/test/runtime/NMT/BaselineWithParameter.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/NMT/BaselineWithParameter.java	Fri Apr 12 10:14:42 2013 +0100
@@ -43,7 +43,7 @@
 
     // Run 'jcmd <pid> VM.native_memory baseline=false'
     pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "baseline=false"});
-    pb.start();
+    pb.start().waitFor();
 
     // Run 'jcmd <pid> VM.native_memory summary=false'
     pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary=false"});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/NMT/MallocTestType.java	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,74 @@
+/*
+ * 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
+ * @summary Test consistency of NMT by leaking a few select allocations of the Test type and then verify visibility with jcmd
+ * @key nmt jcmd
+ * @library /testlibrary /testlibrary/whitebox
+ * @build MallocTestType
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocTestType
+ */
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+public class MallocTestType {
+
+  public static void main(String args[]) throws Exception {
+    OutputAnalyzer output;
+    WhiteBox wb = WhiteBox.getWhiteBox();
+
+    // Grab my own PID
+    String pid = Integer.toString(ProcessTools.getProcessId());
+    ProcessBuilder pb = new ProcessBuilder();
+
+    // Use WB API to alloc and free with the mtTest type
+    long memAlloc3 = wb.NMTMalloc(128 * 1024);
+    long memAlloc2 = wb.NMTMalloc(256 * 1024);
+    wb.NMTFree(memAlloc3);
+    long memAlloc1 = wb.NMTMalloc(512 * 1024);
+    wb.NMTFree(memAlloc2);
+
+    // Use WB API to ensure that all data has been merged before we continue
+    if (!wb.NMTWaitForDataMerge()) {
+      throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+    }
+
+    // Run 'jcmd <pid> VM.native_memory summary'
+    pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Test (reserved=512KB, committed=512KB)");
+
+    // Free the memory allocated by NMTAllocTest
+    wb.NMTFree(memAlloc1);
+
+    // Use WB API to ensure that all data has been merged before we continue
+    if (!wb.NMTWaitForDataMerge()) {
+      throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+    }
+    output = new OutputAnalyzer(pb.start());
+    output.shouldNotContain("Test (reserved=");
+  }
+}
--- a/test/runtime/NMT/PrintNMTStatistics.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/runtime/NMT/PrintNMTStatistics.java	Fri Apr 12 10:14:42 2013 +0100
@@ -27,7 +27,9 @@
  * @bug 8005936
  * @summary Make sure PrintNMTStatistics works on normal JVM exit
  * @library /testlibrary /testlibrary/whitebox
- * @run compile PrintNMTStatistics.java
+ * @build PrintNMTStatistics
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main PrintNMTStatistics
  */
 
 import com.oracle.java.testlibrary.*;
@@ -52,13 +54,15 @@
 
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
         "-XX:+UnlockDiagnosticVMOptions",
+        "-Xbootclasspath/a:.",
+        "-XX:+WhiteBoxAPI",
         "-XX:NativeMemoryTracking=summary",
-        "+XX:+PrintNMTStatistics",
+        "-XX:+PrintNMTStatistics",
         "PrintNMTStatistics",
         "test");
 
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
-    output.shouldContain("Java Heap  (reserved=");
+    output.shouldContain("Java Heap (reserved=");
     output.shouldNotContain("error");
     output.shouldNotContain("warning");
     output.shouldHaveExitValue(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/NMT/ThreadedMallocTestType.java	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,91 @@
+/*
+ * 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
+ * @key nmt jcmd
+ * @library /testlibrary /testlibrary/whitebox
+ * @build ThreadedMallocTestType
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail ThreadedMallocTestType
+ */
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+public class ThreadedMallocTestType {
+  public static long memAlloc1;
+  public static long memAlloc2;
+  public static long memAlloc3;
+
+  public static void main(String args[]) throws Exception {
+    OutputAnalyzer output;
+    final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    // Grab my own PID
+    String pid = Integer.toString(ProcessTools.getProcessId());
+    ProcessBuilder pb = new ProcessBuilder();
+
+    Thread allocThread = new Thread() {
+      public void run() {
+        // Alloc memory using the WB api
+        memAlloc1 = wb.NMTMalloc(128 * 1024);
+        memAlloc2 = wb.NMTMalloc(256 * 1024);
+        memAlloc3 = wb.NMTMalloc(512 * 1024);
+      }
+    };
+
+    allocThread.start();
+    allocThread.join();
+
+    // Use WB API to ensure that all data has been merged before we continue
+    if (!wb.NMTWaitForDataMerge()) {
+      throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+    }
+
+    // Run 'jcmd <pid> VM.native_memory summary'
+    pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Test (reserved=896KB, committed=896KB)");
+
+    Thread freeThread = new Thread() {
+      public void run() {
+        // Free the memory allocated by NMTMalloc
+        wb.NMTFree(memAlloc1);
+        wb.NMTFree(memAlloc2);
+        wb.NMTFree(memAlloc3);
+      }
+    };
+
+    freeThread.start();
+    freeThread.join();
+
+    // Use WB API to ensure that all data has been merged before we continue
+    if (!wb.NMTWaitForDataMerge()) {
+      throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+    }
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldNotContain("Test (reserved=");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/NMT/ThreadedVirtualAllocTestType.java	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,112 @@
+/*
+ * 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
+ * @key nmt jcmd
+ * @library /testlibrary /testlibrary/whitebox
+ * @build ThreadedVirtualAllocTestType
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail ThreadedVirtualAllocTestType
+ */
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+public class ThreadedVirtualAllocTestType {
+  public static long addr;
+  public static final WhiteBox wb = WhiteBox.getWhiteBox();
+  public static final long commitSize = 128 * 1024;
+  public static final long reserveSize = 512 * 1024;
+
+  public static void main(String args[]) throws Exception {
+    OutputAnalyzer output;
+
+    String pid = Integer.toString(ProcessTools.getProcessId());
+    ProcessBuilder pb = new ProcessBuilder();
+
+    Thread reserveThread = new Thread() {
+      public void run() {
+        addr = wb.NMTReserveMemory(reserveSize);
+      }
+    };
+    reserveThread.start();
+    reserveThread.join();
+
+    mergeData();
+
+    pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"});
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Test (reserved=512KB, committed=0KB)");
+    output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 512KB for Test");
+
+    Thread commitThread = new Thread() {
+      public void run() {
+        wb.NMTCommitMemory(addr, commitSize);
+      }
+    };
+    commitThread.start();
+    commitThread.join();
+
+    mergeData();
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Test (reserved=512KB, committed=128KB)");
+    output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed 128KB");
+
+    Thread uncommitThread = new Thread() {
+      public void run() {
+        wb.NMTUncommitMemory(addr, commitSize);
+      }
+    };
+    uncommitThread.start();
+    uncommitThread.join();
+
+    mergeData();
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Test (reserved=512KB, committed=0KB)");
+    output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed");
+
+    Thread releaseThread = new Thread() {
+      public void run() {
+        wb.NMTReleaseMemory(addr, reserveSize);
+      }
+    };
+    releaseThread.start();
+    releaseThread.join();
+
+    mergeData();
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldNotContain("Test (reserved=");
+    output.shouldNotContain("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved");
+  }
+
+  public static void mergeData() throws Exception {
+    // Use WB API to ensure that all data has been merged before we continue
+    if (!wb.NMTWaitForDataMerge()) {
+      throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/NMT/VirtualAllocTestType.java	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,88 @@
+/*
+ * 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
+ * @summary Test Reserve/Commit/Uncommit/Release of virtual memory and that we track it correctly
+ * @key nmt jcmd
+ * @library /testlibrary /testlibrary/whitebox
+ * @build VirtualAllocTestType
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocTestType
+ */
+
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+public class VirtualAllocTestType {
+
+  public static WhiteBox wb = WhiteBox.getWhiteBox();
+  public static void main(String args[]) throws Exception {
+    OutputAnalyzer output;
+    long commitSize = 128 * 1024;
+    long reserveSize = 256 * 1024;
+    long addr;
+
+    String pid = Integer.toString(ProcessTools.getProcessId());
+    ProcessBuilder pb = new ProcessBuilder();
+
+    addr = wb.NMTReserveMemory(reserveSize);
+    mergeData();
+
+    pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"});
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Test (reserved=256KB, committed=0KB)");
+    output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 256KB for Test");
+
+    wb.NMTCommitMemory(addr, commitSize);
+
+    mergeData();
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Test (reserved=256KB, committed=128KB)");
+    output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed 128KB");
+
+    wb.NMTUncommitMemory(addr, commitSize);
+
+    mergeData();
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Test (reserved=256KB, committed=0KB)");
+    output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed");
+
+    wb.NMTReleaseMemory(addr, reserveSize);
+
+    mergeData();
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldNotContain("Test (reserved=");
+    output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved");
+  }
+
+  public static void mergeData() throws Exception {
+    // Use WB API to ensure that all data has been merged before we continue
+    if (!wb.NMTWaitForDataMerge()) {
+      throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/interned/SanityTest.java	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,59 @@
+/*
+ * 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 SanityTest
+ * @summary Sanity check of String.intern() & GC
+ * @library /testlibrary /testlibrary/whitebox
+ * @build SanityTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SanityTest
+ */
+
+import java.util.*;
+import sun.hotspot.WhiteBox;
+
+
+public class SanityTest {
+    public static Object tmp;
+    public static void main(String... args) {
+
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        StringBuilder sb = new StringBuilder();
+        sb.append("1234x"); sb.append("x56789");
+        String str = sb.toString();
+
+        if (wb.isInStringTable(str)) {
+            throw new RuntimeException("String " + str + " is already interned");
+        }
+        str.intern();
+        if (!wb.isInStringTable(str)) {
+            throw new RuntimeException("String " + str + " is not interned");
+        }
+        str = sb.toString();
+        wb.fullGC();
+        if (wb.isInStringTable(str)) {
+            throw new RuntimeException("String " + str + " is in StringTable even after GC");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/test_env.sh	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,193 @@
+#!/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.
+# 
+
+#
+# This Environment script was written to capture typically used environment
+# setup for a given shell test. 
+#
+
+# TESTJAVA can be a JDK or JRE. If JRE you need to set COMPILEJAVA
+if [ "${TESTJAVA}" = "" ]
+then
+  echo "TESTJAVA not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTJAVA=${TESTJAVA}"
+
+# COMPILEJAVA requires a JDK, some shell test use javac,jar,etc 
+if [ "${COMPILEJAVA}" = "" ]
+then
+ echo "COMPILEJAVA not set.  Using TESTJAVA as default"
+ COMPILEJAVA=${TESTJAVA}
+fi
+echo "COMPILEJAVA=${COMPILEJAVA}"
+
+if [ "${TESTCLASSES}" = "" ]
+then
+  echo "TESTCLASES not set.  Using "." as default"
+  TESTCLASSES=.
+fi
+echo "TESTCLASSES=${TESTCLASSES}"
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux | Darwin )
+    NULL=/dev/null
+    PS=":"
+    FS="/"
+    RM=/bin/rm
+    CP=/bin/cp
+    MV=/bin/mv
+    ;;
+  Windows_* )
+    NULL=NUL
+    PS=";"
+    FS="\\"
+    RM=rm
+    CP=cp
+    MV=mv
+    ;;
+  CYGWIN_* )
+    NULL=/dev/null
+    PS=";"
+    FS="/"
+    RM=rm
+    CP=cp
+    MV=mv
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+export NULL PS FS RM CP MV
+echo "NULL =${NULL}"
+echo "PS =${PS}"
+echo "FS =${FS}"
+echo "RM =${RM}"
+echo "CP =${CP}"
+echo "MV =${MV}"
+
+# jtreg -classpathappend:<path>
+JEMMYPATH=${CPAPPEND}
+CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH
+echo "CLASSPATH =${CLASSPATH}"
+
+# Current directory is scratch directory 
+THIS_DIR=.
+echo "THIS_DIR=${THIS_DIR}"
+
+# Check to ensure the java defined actually works
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version
+if [ $? != 0 ]; then
+  echo "Wrong TESTJAVA or TESTVMOPTS:"
+  echo $TESTJAVA TESTVMOPTS
+  exit 1
+fi
+
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion > vm_version.out 2>&1
+
+VM_TYPE="unknown"
+grep "Server" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_TYPE="server"
+fi
+grep "Client" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_TYPE="client"
+fi
+
+VM_BITS="32"
+grep "64-Bit" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_BITS="64"
+fi
+
+VM_OS="unknown"
+grep "solaris" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_OS="solaris"
+fi
+grep "linux" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_OS="linux"
+fi
+grep "windows" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_OS="windows"
+fi
+grep "bsd" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_OS="bsd"
+fi
+
+VM_CPU="unknown"
+grep "sparc" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_CPU="sparc"
+  if [ $VM_BITS = "64" ]
+  then
+    VM_CPU="sparcv9"
+  fi
+fi
+grep "x86" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_CPU="i386"
+fi
+grep "amd64" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_CPU="amd64"
+fi
+grep "arm" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_CPU="arm"
+fi
+grep "ppc" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_CPU="ppc"
+fi
+grep "ia64" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_CPU="ia64"
+fi
+export VM_TYPE VM_BITS VM_OS VM_CPU
+echo "VM_TYPE=${VM_TYPE}"
+echo "VM_BITS=${VM_BITS}"
+echo "VM_OS=${VM_OS}"
+echo "VM_CPU=${VM_CPU}"
--- a/test/testlibrary/OutputAnalyzerTest.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/testlibrary/OutputAnalyzerTest.java	Fri Apr 12 10:14:42 2013 +0100
@@ -36,6 +36,11 @@
     String stdout = "aaaaaa";
     String stderr = "bbbbbb";
 
+    // Regexps used for testing pattern matching of the test input
+    String stdoutPattern = "[a]";
+    String stderrPattern = "[b]";
+    String nonExistingPattern = "[c]";
+
     OutputAnalyzer output = new OutputAnalyzer(stdout, stderr);
 
     if (!stdout.equals(output.getStdout())) {
@@ -99,10 +104,73 @@
     }
 
     try {
-      output.stderrShouldNotContain(stderr);
-      throw new Exception("shouldContain() failed to throw exception");
+        output.stderrShouldNotContain(stderr);
+        throw new Exception("shouldContain() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    // Should match
+    try {
+        output.shouldMatch(stdoutPattern);
+        output.stdoutShouldMatch(stdoutPattern);
+        output.shouldMatch(stderrPattern);
+        output.stderrShouldMatch(stderrPattern);
+    } catch (RuntimeException e) {
+        throw new Exception("shouldMatch() failed", e);
+    }
+
+    try {
+        output.shouldMatch(nonExistingPattern);
+        throw new Exception("shouldMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    try {
+        output.stdoutShouldMatch(stderrPattern);
+        throw new Exception(
+                "stdoutShouldMatch() failed to throw exception");
     } catch (RuntimeException e) {
-      // expected
+        // expected
+    }
+
+    try {
+        output.stderrShouldMatch(stdoutPattern);
+        throw new Exception(
+                "stderrShouldMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    // Should not match
+    try {
+        output.shouldNotMatch(nonExistingPattern);
+        output.stdoutShouldNotMatch(nonExistingPattern);
+        output.stderrShouldNotMatch(nonExistingPattern);
+    } catch (RuntimeException e) {
+        throw new Exception("shouldNotMatch() failed", e);
+    }
+
+    try {
+        output.shouldNotMatch(stdoutPattern);
+        throw new Exception("shouldNotMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    try {
+        output.stdoutShouldNotMatch(stdoutPattern);
+        throw new Exception("shouldNotMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    try {
+        output.stderrShouldNotMatch(stderrPattern);
+        throw new Exception("shouldNotMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
     }
   }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/com/oracle/java/testlibrary/JDKToolLauncher.java	Fri Apr 12 10:14:42 2013 +0100
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+package com.oracle.java.testlibrary;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import com.oracle.java.testlibrary.JDKToolFinder;
+import com.oracle.java.testlibrary.ProcessTools;
+
+/**
+ * A utility for constructing command lines for starting JDK tool processes.
+ *
+ * The JDKToolLauncher can in particular be combined with a
+ * java.lang.ProcessBuilder to easily run a JDK tool. For example, the
+ * following code run {@code jmap -heap} against a process with GC logging
+ * turned on for the {@code jmap} process:
+ *
+ * <pre>
+ * {@code
+ * JDKToolLauncher jmap = JDKToolLauncher.create("jmap")
+ *                                       .addVMArg("-XX:+PrintGC");
+ *                                       .addVMArg("-XX:+PrintGCDetails")
+ *                                       .addToolArg("-heap")
+ *                                       .addToolArg(pid);
+ * ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
+ * Process p = pb.start();
+ * }
+ * </pre>
+ */
+public class JDKToolLauncher {
+    private final String executable;
+    private final List<String> vmArgs = new ArrayList<String>();
+    private final List<String> toolArgs = new ArrayList<String>();
+
+    private JDKToolLauncher(String tool) {
+        executable = JDKToolFinder.getJDKTool(tool);
+        vmArgs.addAll(Arrays.asList(ProcessTools.getPlatformSpecificVMArgs()));
+    }
+
+    /**
+     * Creates a new JDKToolLauncher for the specified tool.
+     *
+     * @param tool The name of the tool
+     * @return A new JDKToolLauncher
+     */
+    public static JDKToolLauncher create(String tool) {
+        return new JDKToolLauncher(tool);
+    }
+
+    /**
+     * Adds an argument to the JVM running the tool.
+     *
+     * The JVM arguments are passed to the underlying JVM running the tool.
+     * Arguments will automatically be prepended with "-J".
+     *
+     * Any platform specific arguments required for running the tool are
+     * automatically added.
+     *
+     *
+     * @param arg The argument to VM running the tool
+     * @return The JDKToolLauncher instance
+     */
+    public JDKToolLauncher addVMArg(String arg) {
+        vmArgs.add("-J" + arg);
+        return this;
+    }
+
+    /**
+     * Adds an argument to the tool.
+     *
+     * @param arg The argument to the tool
+     * @return The JDKToolLauncher instance
+     */
+    public JDKToolLauncher addToolArg(String arg) {
+        toolArgs.add(arg);
+        return this;
+    }
+
+    /**
+     * Returns the command that can be used for running the tool.
+     *
+     * @return An array whose elements are the arguments of the command.
+     */
+    public String[] getCommand() {
+        List<String> command = new ArrayList<String>();
+        command.add(executable);
+        command.addAll(vmArgs);
+        command.addAll(toolArgs);
+        return command.toArray(new String[command.size()]);
+    }
+}
--- a/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java	Fri Apr 12 10:14:42 2013 +0100
@@ -24,6 +24,8 @@
 package com.oracle.java.testlibrary;
 
 import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public final class OutputAnalyzer {
 
@@ -142,15 +144,112 @@
   }
 
   /**
+   * Verify that the stdout and stderr contents of output buffer matches
+   * the pattern
+   *
+   * @param pattern
+   * @throws RuntimeException If the pattern was not found
+   */
+  public void shouldMatch(String pattern) {
+      Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+      Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+      if (!stdoutMatcher.find() && !stderrMatcher.find()) {
+          throw new RuntimeException("'" + pattern
+                  + "' missing from stdout/stderr: [" + stdout + stderr
+                  + "]\n");
+      }
+  }
+
+  /**
+   * Verify that the stdout contents of output buffer matches the
+   * pattern
+   *
+   * @param pattern
+   * @throws RuntimeException If the pattern was not found
+   */
+  public void stdoutShouldMatch(String pattern) {
+      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+      if (!matcher.find()) {
+          throw new RuntimeException("'" + pattern
+                  + "' missing from stdout: [" + stdout + "]\n");
+      }
+  }
+
+  /**
+   * Verify that the stderr contents of output buffer matches the
+   * pattern
+   *
+   * @param pattern
+   * @throws RuntimeException If the pattern was not found
+   */
+  public void stderrShouldMatch(String pattern) {
+      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+      if (!matcher.find()) {
+          throw new RuntimeException("'" + pattern
+                  + "' missing from stderr: [" + stderr + "]\n");
+      }
+  }
+
+  /**
+   * Verify that the stdout and stderr contents of output buffer does not
+   * match the pattern
+   *
+   * @param pattern
+   * @throws RuntimeException If the pattern was found
+   */
+  public void shouldNotMatch(String pattern) {
+      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+      if (matcher.find()) {
+          throw new RuntimeException("'" + pattern
+                  + "' found in stdout: [" + stdout + "]\n");
+      }
+      matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+      if (matcher.find()) {
+          throw new RuntimeException("'" + pattern
+                  + "' found in stderr: [" + stderr + "]\n");
+      }
+  }
+
+  /**
+   * Verify that the stdout contents of output buffer does not match the
+   * pattern
+   *
+   * @param pattern
+   * @throws RuntimeException If the pattern was found
+   */
+  public void stdoutShouldNotMatch(String pattern) {
+      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
+      if (matcher.find()) {
+          throw new RuntimeException("'" + pattern
+                  + "' found in stdout: [" + stdout + "]\n");
+      }
+  }
+
+  /**
+   * Verify that the stderr contents of output buffer does not match the
+   * pattern
+   *
+   * @param pattern
+   * @throws RuntimeException If the pattern was found
+   */
+  public void stderrShouldNotMatch(String pattern) {
+      Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
+      if (matcher.find()) {
+          throw new RuntimeException("'" + pattern
+                  + "' found in stderr: [" + stderr + "]\n");
+      }
+  }
+
+  /**
    * Verifiy the exit value of the process
    *
    * @param expectedExitValue Expected exit value from process
    * @throws RuntimeException If the exit value from the process did not match the expected value
    */
   public void shouldHaveExitValue(int expectedExitValue) {
-    if (getExitValue() != expectedExitValue) {
-      throw new RuntimeException("Exit value " + getExitValue() + " , expected to get " + expectedExitValue);
-    }
+      if (getExitValue() != expectedExitValue) {
+          throw new RuntimeException("Exit value " + getExitValue() + " , expected to get " + expectedExitValue);
+      }
   }
 
   /**
--- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Tue Feb 26 16:16:54 2013 -0800
+++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Fri Apr 12 10:14:42 2013 +0100
@@ -80,8 +80,12 @@
   public native Object[]    parseCommandLine(String commandline, DiagnosticCommand[] args);
 
   // NMT
-  public native boolean NMTAllocTest();
-  public native boolean NMTFreeTestMemory();
+  public native long NMTMalloc(long size);
+  public native void NMTFree(long mem);
+  public native long NMTReserveMemory(long size);
+  public native void NMTCommitMemory(long addr, long size);
+  public native void NMTUncommitMemory(long addr, long size);
+  public native void NMTReleaseMemory(long addr, long size);
   public native boolean NMTWaitForDataMerge();
 
   // Compiler
@@ -94,4 +98,10 @@
   public native int     getMethodCompilationLevel(Method method);
   public native boolean setDontInlineMethod(Method method, boolean value);
   public native int     getCompileQueuesSize();
+
+  //Intered strings
+  public native boolean isInStringTable(String str);
+
+  // force Full GC
+  public native void fullGC();
 }