Merge
authorbharadwaj
Thu, 17 Apr 2014 13:50:26 -0400
changeset 24023 965f85aeb674
parent 24000 4ed166e87a9d (current diff)
parent 24022 3cedd541a6f3 (diff)
child 24024 cc0ee6fd0e97
child 24089 4e49589fbfa8
Merge
hotspot/src/share/vm/runtime/sharedRuntime.cpp
--- a/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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
@@ -2947,17 +2947,60 @@
   istate->_last_Java_fp = last_Java_fp;
 }
 
-int AbstractInterpreter::layout_activation(Method* method,
-                                           int temps,        // Number of slots on java expression stack in use.
-                                           int popframe_args,
-                                           int monitors,     // Number of active monitors.
-                                           int caller_actual_parameters,
-                                           int callee_params,// Number of slots for callee parameters.
-                                           int callee_locals,// Number of slots for locals.
-                                           frame* caller,
-                                           frame* interpreter_frame,
-                                           bool is_top_frame,
-                                           bool is_bottom_frame) {
+// Computes monitor_size and top_frame_size in bytes.
+static void frame_size_helper(int max_stack,
+                              int monitors,
+                              int& monitor_size,
+                              int& top_frame_size) {
+  monitor_size = frame::interpreter_frame_monitor_size_in_bytes() * monitors;
+  top_frame_size = round_to(frame::interpreter_frame_cinterpreterstate_size_in_bytes()
+                            + monitor_size
+                            + max_stack * Interpreter::stackElementSize
+                            + 2 * Interpreter::stackElementSize,
+                            frame::alignment_in_bytes)
+                   + frame::top_ijava_frame_abi_size;
+}
+
+// Returns number of stackElementWords needed for the interpreter frame with the
+// given sections.
+int AbstractInterpreter::size_activation(int max_stack,
+                                         int temps,
+                                         int extra_args,
+                                         int monitors,
+                                         int callee_params,
+                                         int callee_locals,
+                                         bool is_top_frame) {
+  int monitor_size = 0;
+  int top_frame_size = 0;
+  frame_size_helper(max_stack, monitors, monitor_size, top_frame_size);
+
+  int frame_size;
+  if (is_top_frame) {
+    frame_size = top_frame_size;
+  } else {
+    frame_size = round_to(frame::interpreter_frame_cinterpreterstate_size_in_bytes()
+                          + monitor_size
+                          + (temps - callee_params + callee_locals) * Interpreter::stackElementSize
+                          + 2 * Interpreter::stackElementSize,
+                          frame::alignment_in_bytes)
+                 + frame::parent_ijava_frame_abi_size;
+    assert(extra_args == 0, "non-zero for top_frame only");
+  }
+
+  return frame_size / Interpreter::stackElementSize;
+}
+
+void AbstractInterpreter::layout_activation(Method* method,
+                                            int temps,        // Number of slots on java expression stack in use.
+                                            int popframe_args,
+                                            int monitors,     // Number of active monitors.
+                                            int caller_actual_parameters,
+                                            int callee_params,// Number of slots for callee parameters.
+                                            int callee_locals,// Number of slots for locals.
+                                            frame* caller,
+                                            frame* interpreter_frame,
+                                            bool is_top_frame,
+                                            bool is_bottom_frame) {
 
   // NOTE this code must exactly mimic what
   // InterpreterGenerator::generate_compute_interpreter_state() does
@@ -2967,86 +3010,64 @@
   // both the abi scratch area and a place to hold a result from a
   // callee on its way to the callers stack.
 
-  int monitor_size = frame::interpreter_frame_monitor_size_in_bytes() * monitors;
-  int frame_size;
-  int top_frame_size = round_to(frame::interpreter_frame_cinterpreterstate_size_in_bytes()
-                                + monitor_size
-                                + (method->max_stack() *Interpreter::stackElementWords * BytesPerWord)
-                                + 2*BytesPerWord,
-                                frame::alignment_in_bytes)
-                      + frame::top_ijava_frame_abi_size;
-  if (is_top_frame) {
-    frame_size = top_frame_size;
+  int monitor_size = 0;
+  int top_frame_size = 0;
+  frame_size_helper(method->max_stack(), monitors, monitor_size, top_frame_size);
+
+  intptr_t sp = (intptr_t)interpreter_frame->sp();
+  intptr_t fp = *(intptr_t *)sp;
+  assert(fp == (intptr_t)caller->sp(), "fp must match");
+  interpreterState cur_state =
+    (interpreterState)(fp - frame::interpreter_frame_cinterpreterstate_size_in_bytes());
+
+  // Now fill in the interpreterState object.
+
+  intptr_t* locals;
+  if (caller->is_interpreted_frame()) {
+    // Locals must agree with the caller because it will be used to set the
+    // caller's tos when we return.
+    interpreterState prev  = caller->get_interpreterState();
+    // Calculate start of "locals" for MH calls.  For MH calls, the
+    // current method() (= MH target) and prev->callee() (=
+    // MH.invoke*()) are different and especially have different
+    // signatures. To pop the argumentsof the caller, we must use
+    // the prev->callee()->size_of_arguments() because that's what
+    // the caller actually pushed.  Currently, for synthetic MH
+    // calls (deoptimized from inlined MH calls), detected by
+    // is_method_handle_invoke(), we use the callee's arguments
+    // because here, the caller's and callee's signature match.
+    if (true /*!caller->is_at_mh_callsite()*/) {
+      locals = prev->stack() + method->size_of_parameters();
+    } else {
+      // Normal MH call.
+      locals = prev->stack() + prev->callee()->size_of_parameters();
+    }
   } else {
-    frame_size = round_to(frame::interpreter_frame_cinterpreterstate_size_in_bytes()
-                          + monitor_size
-                          + ((temps - callee_params + callee_locals) *
-                             Interpreter::stackElementWords * BytesPerWord)
-                          + 2*BytesPerWord,
-                          frame::alignment_in_bytes)
-                 + frame::parent_ijava_frame_abi_size;
-    assert(popframe_args==0, "non-zero for top_frame only");
+    bool is_deopted;
+    locals = (intptr_t*) (fp + ((method->max_locals() - 1) * BytesPerWord) +
+                          frame::parent_ijava_frame_abi_size);
   }
 
-  // If we actually have a frame to layout we must now fill in all the pieces.
-  if (interpreter_frame != NULL) {
-
-    intptr_t sp = (intptr_t)interpreter_frame->sp();
-    intptr_t fp = *(intptr_t *)sp;
-    assert(fp == (intptr_t)caller->sp(), "fp must match");
-    interpreterState cur_state =
-      (interpreterState)(fp - frame::interpreter_frame_cinterpreterstate_size_in_bytes());
-
-    // Now fill in the interpreterState object.
-
-    intptr_t* locals;
-    if (caller->is_interpreted_frame()) {
-      // Locals must agree with the caller because it will be used to set the
-      // caller's tos when we return.
-      interpreterState prev  = caller->get_interpreterState();
-      // Calculate start of "locals" for MH calls.  For MH calls, the
-      // current method() (= MH target) and prev->callee() (=
-      // MH.invoke*()) are different and especially have different
-      // signatures. To pop the argumentsof the caller, we must use
-      // the prev->callee()->size_of_arguments() because that's what
-      // the caller actually pushed.  Currently, for synthetic MH
-      // calls (deoptimized from inlined MH calls), detected by
-      // is_method_handle_invoke(), we use the callee's arguments
-      // because here, the caller's and callee's signature match.
-      if (true /*!caller->is_at_mh_callsite()*/) {
-        locals = prev->stack() + method->size_of_parameters();
-      } else {
-        // Normal MH call.
-        locals = prev->stack() + prev->callee()->size_of_parameters();
-      }
-    } else {
-      bool is_deopted;
-      locals = (intptr_t*) (fp + ((method->max_locals() - 1) * BytesPerWord) +
-                            frame::parent_ijava_frame_abi_size);
-    }
-
-    intptr_t* monitor_base = (intptr_t*) cur_state;
-    intptr_t* stack_base   = (intptr_t*) ((intptr_t) monitor_base - monitor_size);
-
-    // Provide pop_frame capability on PPC64, add popframe_args.
-    // +1 because stack is always prepushed.
-    intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (temps + popframe_args + 1) * BytesPerWord);
-
-    BytecodeInterpreter::layout_interpreterState(cur_state,
-                                                 caller,
-                                                 interpreter_frame,
-                                                 method,
-                                                 locals,
-                                                 stack,
-                                                 stack_base,
-                                                 monitor_base,
-                                                 (intptr_t*)(((intptr_t)fp)-top_frame_size),
-                                                 is_top_frame);
-
-    BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address,
-                                                    interpreter_frame->fp());
-  }
-  return frame_size/BytesPerWord;
+  intptr_t* monitor_base = (intptr_t*) cur_state;
+  intptr_t* stack_base   = (intptr_t*) ((intptr_t) monitor_base - monitor_size);
+
+  // Provide pop_frame capability on PPC64, add popframe_args.
+  // +1 because stack is always prepushed.
+  intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (temps + popframe_args + 1) * BytesPerWord);
+
+  BytecodeInterpreter::layout_interpreterState(cur_state,
+                                               caller,
+                                               interpreter_frame,
+                                               method,
+                                               locals,
+                                               stack,
+                                               stack_base,
+                                               monitor_base,
+                                               (intptr_t*)(((intptr_t)fp) - top_frame_size),
+                                               is_top_frame);
+
+  BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address,
+                                                  interpreter_frame->fp());
 }
 
 #endif // CC_INTERP
--- a/hotspot/src/cpu/ppc/vm/ppc.ad	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad	Thu Apr 17 13:50:26 2014 -0400
@@ -1,6 +1,6 @@
 //
-// Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
-// Copyright 2012, 2013 SAP AG. All rights reserved.
+// Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+// Copyright 2012, 2014 SAP AG. 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
@@ -1362,8 +1362,8 @@
   Compile* C = ra_->C;
   MacroAssembler _masm(&cbuf);
 
-  const long framesize = ((long)C->frame_slots()) << LogBytesPerInt;
-  assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment");
+  const long framesize = C->frame_size_in_bytes();
+  assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment");
 
   const bool method_is_frameless      = false /* TODO: PPC port C->is_frameless_method()*/;
 
@@ -1388,19 +1388,22 @@
   // careful, because some VM calls (such as call site linkage) can
   // use several kilobytes of stack. But the stack safety zone should
   // account for that. See bugs 4446381, 4468289, 4497237.
-  if (C->need_stack_bang(framesize) && UseStackBanging) {
+
+  int bangsize = C->bang_size_in_bytes();
+  assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect");
+  if (C->need_stack_bang(bangsize) && UseStackBanging) {
     // Unfortunately we cannot use the function provided in
     // assembler.cpp as we have to emulate the pipes. So I had to
     // insert the code of generate_stack_overflow_check(), see
     // assembler.cpp for some illuminative comments.
     const int page_size = os::vm_page_size();
-    int bang_end = StackShadowPages*page_size;
+    int bang_end = StackShadowPages * page_size;
 
     // This is how far the previous frame's stack banging extended.
     const int bang_end_safe = bang_end;
 
-    if (framesize > page_size) {
-      bang_end += framesize;
+    if (bangsize > page_size) {
+      bang_end += bangsize;
     }
 
     int bang_offset = bang_end_safe;
@@ -1446,7 +1449,7 @@
 
   unsigned int bytes = (unsigned int)framesize;
   long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
-  ciMethod *currMethod = C -> method();
+  ciMethod *currMethod = C->method();
 
   // Optimized version for most common case.
   if (UsePower6SchedulerPPC64 &&
--- a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -1334,21 +1334,42 @@
 int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
   const int max_alignment_size = 2;
   const int abi_scratch = frame::abi_reg_args_size;
-  return method->max_locals() + method->max_stack() + frame::interpreter_frame_monitor_size() + max_alignment_size + abi_scratch;
+  return method->max_locals() + method->max_stack() +
+         frame::interpreter_frame_monitor_size() + max_alignment_size + abi_scratch;
 }
 
-// Fills a sceletal interpreter frame generated during deoptimizations
-// and returns the frame size in slots.
+// Returns number of stackElementWords needed for the interpreter frame with the
+// given sections.
+// This overestimates the stack by one slot in case of alignments.
+int AbstractInterpreter::size_activation(int max_stack,
+                                         int temps,
+                                         int extra_args,
+                                         int monitors,
+                                         int callee_params,
+                                         int callee_locals,
+                                         bool is_top_frame) {
+  // Note: This calculation must exactly parallel the frame setup
+  // in AbstractInterpreterGenerator::generate_method_entry.
+  assert(Interpreter::stackElementWords == 1, "sanity");
+  const int max_alignment_space = StackAlignmentInBytes / Interpreter::stackElementSize;
+  const int abi_scratch = is_top_frame ? (frame::abi_reg_args_size / Interpreter::stackElementSize) :
+                                         (frame::abi_minframe_size / Interpreter::stackElementSize);
+  const int size =
+    max_stack                                                +
+    (callee_locals - callee_params)                          +
+    monitors * frame::interpreter_frame_monitor_size()       +
+    max_alignment_space                                      +
+    abi_scratch                                              +
+    frame::ijava_state_size / Interpreter::stackElementSize;
+
+  // Fixed size of an interpreter frame, align to 16-byte.
+  return (size & -2);
+}
+
+// Fills a sceletal interpreter frame generated during deoptimizations.
 //
 // Parameters:
 //
-// interpreter_frame == NULL:
-//   Only calculate the size of an interpreter activation, no actual layout.
-//   Note: This calculation must exactly parallel the frame setup
-//   in TemplateInterpreter::generate_normal_entry. But it does not
-//   account for the SP alignment, that might further enhance the
-//   frame size, depending on FP.
-//
 // interpreter_frame != NULL:
 //   set up the method, locals, and monitors.
 //   The frame interpreter_frame, if not NULL, is guaranteed to be the
@@ -1365,59 +1386,41 @@
 //   the arguments off advance the esp by dummy popframe_extra_args slots.
 //   Popping off those will establish the stack layout as it was before the call.
 //
-int AbstractInterpreter::layout_activation(Method* method,
-                                           int tempcount,
-                                           int popframe_extra_args,
-                                           int moncount,
-                                           int caller_actual_parameters,
-                                           int callee_param_count,
-                                           int callee_locals,
-                                           frame* caller,
-                                           frame* interpreter_frame,
-                                           bool is_top_frame,
-                                           bool is_bottom_frame) {
+void AbstractInterpreter::layout_activation(Method* method,
+                                            int tempcount,
+                                            int popframe_extra_args,
+                                            int moncount,
+                                            int caller_actual_parameters,
+                                            int callee_param_count,
+                                            int callee_locals_count,
+                                            frame* caller,
+                                            frame* interpreter_frame,
+                                            bool is_top_frame,
+                                            bool is_bottom_frame) {
 
-  const int max_alignment_space = 2;
   const int abi_scratch = is_top_frame ? (frame::abi_reg_args_size / Interpreter::stackElementSize) :
-                                         (frame::abi_minframe_size / Interpreter::stackElementSize) ;
-  const int conservative_framesize_in_slots =
-    method->max_stack() + callee_locals - callee_param_count +
-    (moncount * frame::interpreter_frame_monitor_size()) + max_alignment_space +
-    abi_scratch + frame::ijava_state_size / Interpreter::stackElementSize;
-
-  assert(!is_top_frame || conservative_framesize_in_slots * 8 > frame::abi_reg_args_size + frame::ijava_state_size, "frame too small");
+                                         (frame::abi_minframe_size / Interpreter::stackElementSize);
 
-  if (interpreter_frame == NULL) {
-    // Since we don't know the exact alignment, we return the conservative size.
-    return (conservative_framesize_in_slots & -2);
-  } else {
-    // Now we know our caller, calc the exact frame layout and size.
-    intptr_t* locals_base  = (caller->is_interpreted_frame()) ?
-      caller->interpreter_frame_esp() + caller_actual_parameters :
-      caller->sp() + method->max_locals() - 1 + (frame::abi_minframe_size / Interpreter::stackElementSize) ;
+  intptr_t* locals_base  = (caller->is_interpreted_frame()) ?
+    caller->interpreter_frame_esp() + caller_actual_parameters :
+    caller->sp() + method->max_locals() - 1 + (frame::abi_minframe_size / Interpreter::stackElementSize) ;
 
-    intptr_t* monitor_base = caller->sp() - frame::ijava_state_size / Interpreter::stackElementSize ;
-    intptr_t* monitor      = monitor_base - (moncount * frame::interpreter_frame_monitor_size());
-    intptr_t* esp_base     = monitor - 1;
-    intptr_t* esp          = esp_base - tempcount - popframe_extra_args;
-    intptr_t* sp           = (intptr_t *) (((intptr_t) (esp_base- callee_locals + callee_param_count - method->max_stack()- abi_scratch)) & -StackAlignmentInBytes);
-    intptr_t* sender_sp    = caller->sp() + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize;
-    intptr_t* top_frame_sp = is_top_frame ? sp : sp + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize;
+  intptr_t* monitor_base = caller->sp() - frame::ijava_state_size / Interpreter::stackElementSize ;
+  intptr_t* monitor      = monitor_base - (moncount * frame::interpreter_frame_monitor_size());
+  intptr_t* esp_base     = monitor - 1;
+  intptr_t* esp          = esp_base - tempcount - popframe_extra_args;
+  intptr_t* sp           = (intptr_t *) (((intptr_t) (esp_base - callee_locals_count + callee_param_count - method->max_stack()- abi_scratch)) & -StackAlignmentInBytes);
+  intptr_t* sender_sp    = caller->sp() + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize;
+  intptr_t* top_frame_sp = is_top_frame ? sp : sp + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize;
 
-    interpreter_frame->interpreter_frame_set_method(method);
-    interpreter_frame->interpreter_frame_set_locals(locals_base);
-    interpreter_frame->interpreter_frame_set_cpcache(method->constants()->cache());
-    interpreter_frame->interpreter_frame_set_esp(esp);
-    interpreter_frame->interpreter_frame_set_monitor_end((BasicObjectLock *)monitor);
-    interpreter_frame->interpreter_frame_set_top_frame_sp(top_frame_sp);
-    if (!is_bottom_frame) {
-      interpreter_frame->interpreter_frame_set_sender_sp(sender_sp);
-    }
-
-    int framesize_in_slots = caller->sp() - sp;
-    assert(!is_top_frame ||framesize_in_slots >= (frame::abi_reg_args_size / Interpreter::stackElementSize) + frame::ijava_state_size / Interpreter::stackElementSize, "frame too small");
-    assert(framesize_in_slots <= conservative_framesize_in_slots, "exact frame size must be smaller than the convervative size!");
-    return framesize_in_slots;
+  interpreter_frame->interpreter_frame_set_method(method);
+  interpreter_frame->interpreter_frame_set_locals(locals_base);
+  interpreter_frame->interpreter_frame_set_cpcache(method->constants()->cache());
+  interpreter_frame->interpreter_frame_set_esp(esp);
+  interpreter_frame->interpreter_frame_set_monitor_end((BasicObjectLock *)monitor);
+  interpreter_frame->interpreter_frame_set_top_frame_sp(top_frame_sp);
+  if (!is_bottom_frame) {
+    interpreter_frame->interpreter_frame_set_sender_sp(sender_sp);
   }
 }
 
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -630,11 +630,20 @@
   }
 
  protected:
+  // Insert a nop if the previous is cbcond
+  void insert_nop_after_cbcond() {
+    if (UseCBCond && cbcond_before()) {
+      nop();
+    }
+  }
   // Delay slot helpers
   // cti is called when emitting control-transfer instruction,
   // BEFORE doing the emitting.
   // Only effective when assertion-checking is enabled.
   void cti() {
+    // A cbcond instruction immediately followed by a CTI
+    // instruction introduces pipeline stalls, we need to avoid that.
+    no_cbcond_before();
 #ifdef CHECK_DELAY
     assert_not_delayed("cti should not be in delay slot");
 #endif
@@ -658,7 +667,6 @@
   void no_cbcond_before() {
     assert(offset() == 0 || !cbcond_before(), "cbcond should not follow an other cbcond");
   }
-
 public:
 
   bool use_cbcond(Label& L) {
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -54,33 +54,33 @@
 inline void Assembler::add(Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | rs2(s2) ); }
 inline void Assembler::add(Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
 
-inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only();  cti();  emit_data( op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt);  has_delay_slot(); }
-inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, Label& L) { bpr( c, a, p, s1, target(L)); }
+inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only(); insert_nop_after_cbcond(); cti();  emit_data( op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt);  has_delay_slot(); }
+inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, Label& L) { insert_nop_after_cbcond(); bpr( c, a, p, s1, target(L)); }
 
-inline void Assembler::fb( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep();  cti();  emit_data( op(branch_op) | annul(a) | cond(c) | op2(fb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt);  has_delay_slot(); }
-inline void Assembler::fb( Condition c, bool a, Label& L ) { fb(c, a, target(L)); }
+inline void Assembler::fb( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep();  insert_nop_after_cbcond(); cti();  emit_data( op(branch_op) | annul(a) | cond(c) | op2(fb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt);  has_delay_slot(); }
+inline void Assembler::fb( Condition c, bool a, Label& L ) { insert_nop_after_cbcond(); fb(c, a, target(L)); }
 
-inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only();  cti();  emit_data( op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt);  has_delay_slot(); }
-inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L ) { fbp(c, a, cc, p, target(L)); }
+inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); insert_nop_after_cbcond(); cti();  emit_data( op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt);  has_delay_slot(); }
+inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L ) { insert_nop_after_cbcond(); fbp(c, a, cc, p, target(L)); }
 
-inline void Assembler::br( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep();  cti();   emit_data( op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt);  has_delay_slot(); }
-inline void Assembler::br( Condition c, bool a, Label& L ) { br(c, a, target(L)); }
+inline void Assembler::br( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); insert_nop_after_cbcond(); cti();   emit_data( op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt);  has_delay_slot(); }
+inline void Assembler::br( Condition c, bool a, Label& L ) { insert_nop_after_cbcond(); br(c, a, target(L)); }
 
-inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only();  cti();  emit_data( op(branch_op) | annul(a) | cond(c) | op2(bp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt);  has_delay_slot(); }
-inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, Label& L ) { bp(c, a, cc, p, target(L)); }
+inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only();  insert_nop_after_cbcond(); cti();  emit_data( op(branch_op) | annul(a) | cond(c) | op2(bp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt);  has_delay_slot(); }
+inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, Label& L ) { insert_nop_after_cbcond(); bp(c, a, cc, p, target(L)); }
 
 // compare and branch
 inline void Assembler::cbcond(Condition c, CC cc, Register s1, Register s2, Label& L) { cti();  no_cbcond_before();  emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | rs2(s2)); }
 inline void Assembler::cbcond(Condition c, CC cc, Register s1, int simm5, Label& L)   { cti();  no_cbcond_before();  emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | immed(true) | simm(simm5, 5)); }
 
-inline void Assembler::call( address d,  relocInfo::relocType rt ) { cti();  emit_data( op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt);  has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); }
-inline void Assembler::call( Label& L,   relocInfo::relocType rt ) { call( target(L), rt); }
+inline void Assembler::call( address d,  relocInfo::relocType rt ) { insert_nop_after_cbcond(); cti();  emit_data( op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt);  has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); }
+inline void Assembler::call( Label& L,   relocInfo::relocType rt ) { insert_nop_after_cbcond(); call( target(L), rt); }
 
 inline void Assembler::flush( Register s1, Register s2) { emit_int32( op(arith_op) | op3(flush_op3) | rs1(s1) | rs2(s2)); }
 inline void Assembler::flush( Register s1, int simm13a) { emit_data( op(arith_op) | op3(flush_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
 
-inline void Assembler::jmpl( Register s1, Register s2, Register d ) { cti();  emit_int32( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2));  has_delay_slot(); }
-inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { cti();  emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec);  has_delay_slot(); }
+inline void Assembler::jmpl( Register s1, Register s2, Register d ) { insert_nop_after_cbcond(); cti();  emit_int32( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2));  has_delay_slot(); }
+inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { insert_nop_after_cbcond(); cti();  emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec);  has_delay_slot(); }
 
 inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); }
 inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); }
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -152,7 +152,7 @@
 }
 
 
-int LIR_Assembler::initial_frame_size_in_bytes() {
+int LIR_Assembler::initial_frame_size_in_bytes() const {
   return in_bytes(frame_map()->framesize_in_bytes());
 }
 
@@ -182,7 +182,7 @@
   int number_of_locks = entry_state->locks_size();
 
   // Create a frame for the compiled activation.
-  __ build_frame(initial_frame_size_in_bytes());
+  __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes());
 
   // OSR buffer is
   //
--- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -55,9 +55,9 @@
 }
 
 
-void C1_MacroAssembler::build_frame(int frame_size_in_bytes) {
-
-  generate_stack_overflow_check(frame_size_in_bytes);
+void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
+  assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
+  generate_stack_overflow_check(bang_size_in_bytes);
   // Create the frame.
   save_frame_c1(frame_size_in_bytes);
 }
--- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -2099,7 +2099,7 @@
   int monitor_size    = method->is_synchronized() ?
                                 1*frame::interpreter_frame_monitor_size() : 0;
   return size_activation_helper(method->max_locals(), method->max_stack(),
-                                 monitor_size) + call_stub_size;
+                                monitor_size) + call_stub_size;
 }
 
 void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
@@ -2183,31 +2183,31 @@
   istate->_last_Java_pc = (intptr_t*) last_Java_pc;
 }
 
-
-int AbstractInterpreter::layout_activation(Method* method,
-                                           int tempcount, // Number of slots on java expression stack in use
-                                           int popframe_extra_args,
-                                           int moncount,  // Number of active monitors
-                                           int caller_actual_parameters,
-                                           int callee_param_size,
-                                           int callee_locals_size,
-                                           frame* caller,
-                                           frame* interpreter_frame,
-                                           bool is_top_frame,
-                                           bool is_bottom_frame) {
+static int frame_size_helper(int max_stack,
+                             int moncount,
+                             int callee_param_size,
+                             int callee_locals_size,
+                             bool is_top_frame,
+                             int& monitor_size,
+                             int& full_frame_words) {
+  int extra_locals_size = callee_locals_size - callee_param_size;
+  monitor_size = (sizeof(BasicObjectLock) * moncount) / wordSize;
+  full_frame_words = size_activation_helper(extra_locals_size, max_stack, monitor_size);
+  int short_frame_words = size_activation_helper(extra_locals_size, max_stack, monitor_size);
+  int frame_words = is_top_frame ? full_frame_words : short_frame_words;
 
-  assert(popframe_extra_args == 0, "NEED TO FIX");
-  // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
-  // does as far as allocating an interpreter frame.
-  // If interpreter_frame!=NULL, set up the method, locals, and monitors.
-  // The frame interpreter_frame, if not NULL, is guaranteed to be the right size,
-  // as determined by a previous call to this method.
-  // It is also guaranteed to be walkable even though it is in a skeletal state
+  return frame_words;
+}
+
+int AbstractInterpreter::size_activation(int max_stack,
+                                         int tempcount,
+                                         int extra_args,
+                                         int moncount,
+                                         int callee_param_size,
+                                         int callee_locals_size,
+                                         bool is_top_frame) {
+  assert(extra_args == 0, "NEED TO FIX");
   // NOTE: return size is in words not bytes
-  // NOTE: tempcount is the current size of the java expression stack. For top most
-  //       frames we will allocate a full sized expression stack and not the curback
-  //       version that non-top frames have.
-
   // Calculate the amount our frame will be adjust by the callee. For top frame
   // this is zero.
 
@@ -2216,87 +2216,108 @@
   // to it. So it ignores last_frame_adjust value. Seems suspicious as far
   // as getting sender_sp correct.
 
-  int extra_locals_size = callee_locals_size - callee_param_size;
-  int monitor_size = (sizeof(BasicObjectLock) * moncount) / wordSize;
-  int full_frame_words = size_activation_helper(extra_locals_size, method->max_stack(), monitor_size);
-  int short_frame_words = size_activation_helper(extra_locals_size, method->max_stack(), monitor_size);
-  int frame_words = is_top_frame ? full_frame_words : short_frame_words;
+  int unused_monitor_size = 0;
+  int unused_full_frame_words = 0;
+  return frame_size_helper(max_stack, moncount, callee_param_size, callee_locals_size, is_top_frame,
+                           unused_monitor_size, unused_full_frame_words);
+}
+void AbstractInterpreter::layout_activation(Method* method,
+                                            int tempcount, // Number of slots on java expression stack in use
+                                            int popframe_extra_args,
+                                            int moncount,  // Number of active monitors
+                                            int caller_actual_parameters,
+                                            int callee_param_size,
+                                            int callee_locals_size,
+                                            frame* caller,
+                                            frame* interpreter_frame,
+                                            bool is_top_frame,
+                                            bool is_bottom_frame) {
+  assert(popframe_extra_args == 0, "NEED TO FIX");
+  // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
+  // does as far as allocating an interpreter frame.
+  // Set up the method, locals, and monitors.
+  // The frame interpreter_frame is guaranteed to be the right size,
+  // as determined by a previous call to the size_activation() method.
+  // It is also guaranteed to be walkable even though it is in a skeletal state
+  // NOTE: tempcount is the current size of the java expression stack. For top most
+  //       frames we will allocate a full sized expression stack and not the curback
+  //       version that non-top frames have.
 
+  int monitor_size = 0;
+  int full_frame_words = 0;
+  int frame_words = frame_size_helper(method->max_stack(), moncount, callee_param_size, callee_locals_size,
+                                      is_top_frame, monitor_size, full_frame_words);
 
   /*
-    if we actually have a frame to layout we must now fill in all the pieces. This means both
+    We must now fill in all the pieces of the frame. This means both
     the interpreterState and the registers.
   */
-  if (interpreter_frame != NULL) {
 
-    // MUCHO HACK
+  // MUCHO HACK
 
-    intptr_t* frame_bottom = interpreter_frame->sp() - (full_frame_words - frame_words);
-    // 'interpreter_frame->sp()' is unbiased while 'frame_bottom' must be a biased value in 64bit mode.
-    assert(((intptr_t)frame_bottom & 0xf) == 0, "SP biased in layout_activation");
-    frame_bottom = (intptr_t*)((intptr_t)frame_bottom - STACK_BIAS);
+  intptr_t* frame_bottom = interpreter_frame->sp() - (full_frame_words - frame_words);
+  // 'interpreter_frame->sp()' is unbiased while 'frame_bottom' must be a biased value in 64bit mode.
+  assert(((intptr_t)frame_bottom & 0xf) == 0, "SP biased in layout_activation");
+  frame_bottom = (intptr_t*)((intptr_t)frame_bottom - STACK_BIAS);
 
-    /* Now fillin the interpreterState object */
+  /* Now fillin the interpreterState object */
 
-    interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() -  sizeof(BytecodeInterpreter));
+  interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() -  sizeof(BytecodeInterpreter));
 
 
-    intptr_t* locals;
+  intptr_t* locals;
+
+  // Calculate the postion of locals[0]. This is painful because of
+  // stack alignment (same as ia64). The problem is that we can
+  // not compute the location of locals from fp(). fp() will account
+  // for the extra locals but it also accounts for aligning the stack
+  // and we can't determine if the locals[0] was misaligned but max_locals
+  // was enough to have the
+  // calculate postion of locals. fp already accounts for extra locals.
+  // +2 for the static long no_params() issue.
 
-    // Calculate the postion of locals[0]. This is painful because of
-    // stack alignment (same as ia64). The problem is that we can
-    // not compute the location of locals from fp(). fp() will account
-    // for the extra locals but it also accounts for aligning the stack
-    // and we can't determine if the locals[0] was misaligned but max_locals
-    // was enough to have the
-    // calculate postion of locals. fp already accounts for extra locals.
-    // +2 for the static long no_params() issue.
+  if (caller->is_interpreted_frame()) {
+    // locals must agree with the caller because it will be used to set the
+    // caller's tos when we return.
+    interpreterState prev  = caller->get_interpreterState();
+    // stack() is prepushed.
+    locals = prev->stack() + method->size_of_parameters();
+  } else {
+    // Lay out locals block in the caller adjacent to the register window save area.
+    //
+    // Compiled frames do not allocate a varargs area which is why this if
+    // statement is needed.
+    //
+    intptr_t* fp = interpreter_frame->fp();
+    int local_words = method->max_locals() * Interpreter::stackElementWords;
 
-    if (caller->is_interpreted_frame()) {
-      // locals must agree with the caller because it will be used to set the
-      // caller's tos when we return.
-      interpreterState prev  = caller->get_interpreterState();
-      // stack() is prepushed.
-      locals = prev->stack() + method->size_of_parameters();
+    if (caller->is_compiled_frame()) {
+      locals = fp + frame::register_save_words + local_words - 1;
     } else {
-      // Lay out locals block in the caller adjacent to the register window save area.
-      //
-      // Compiled frames do not allocate a varargs area which is why this if
-      // statement is needed.
-      //
-      intptr_t* fp = interpreter_frame->fp();
-      int local_words = method->max_locals() * Interpreter::stackElementWords;
+      locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1;
+    }
 
-      if (caller->is_compiled_frame()) {
-        locals = fp + frame::register_save_words + local_words - 1;
-      } else {
-        locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1;
-      }
+  }
+  // END MUCHO HACK
 
-    }
-    // END MUCHO HACK
-
-    intptr_t* monitor_base = (intptr_t*) cur_state;
-    intptr_t* stack_base =  monitor_base - monitor_size;
-    /* +1 because stack is always prepushed */
-    intptr_t* stack = stack_base - (tempcount + 1);
+  intptr_t* monitor_base = (intptr_t*) cur_state;
+  intptr_t* stack_base =  monitor_base - monitor_size;
+  /* +1 because stack is always prepushed */
+  intptr_t* stack = stack_base - (tempcount + 1);
 
 
-    BytecodeInterpreter::layout_interpreterState(cur_state,
-                                          caller,
-                                          interpreter_frame,
-                                          method,
-                                          locals,
-                                          stack,
-                                          stack_base,
-                                          monitor_base,
-                                          frame_bottom,
-                                          is_top_frame);
+  BytecodeInterpreter::layout_interpreterState(cur_state,
+                                               caller,
+                                               interpreter_frame,
+                                               method,
+                                               locals,
+                                               stack,
+                                               stack_base,
+                                               monitor_base,
+                                               frame_bottom,
+                                               is_top_frame);
 
-    BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp());
-
-  }
-  return frame_words;
+  BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp());
 }
 
 #endif // CC_INTERP
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -3531,7 +3531,7 @@
   // was post-decremented.)  Skip this address by starting at i=1, and
   // touch a few more pages below.  N.B.  It is important to touch all
   // the way down to and including i=StackShadowPages.
-  for (int i = 1; i <= StackShadowPages; i++) {
+  for (int i = 1; i < StackShadowPages; i++) {
     set((-i*offset)+STACK_BIAS, Rscratch);
     st(G0, Rtsp, Rscratch);
   }
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -233,6 +233,7 @@
 }
 
 inline void MacroAssembler::br( Condition c, bool a, Predict p, Label& L ) {
+  insert_nop_after_cbcond();
   br(c, a, p, target(L));
 }
 
@@ -248,6 +249,7 @@
 }
 
 inline void MacroAssembler::brx( Condition c, bool a, Predict p, Label& L ) {
+  insert_nop_after_cbcond();
   brx(c, a, p, target(L));
 }
 
@@ -269,6 +271,7 @@
 }
 
 inline void MacroAssembler::fb( Condition c, bool a, Predict p, Label& L ) {
+  insert_nop_after_cbcond();
   fb(c, a, p, target(L));
 }
 
@@ -318,6 +321,7 @@
 }
 
 inline void MacroAssembler::call( Label& L,   relocInfo::relocType rt ) {
+  insert_nop_after_cbcond();
   MacroAssembler::call( target(L), rt);
 }
 
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -3355,13 +3355,16 @@
   Register        O4array_size       = O4;
   Label           loop;
 
-  // Before we make new frames, check to see if stack is available.
-  // Do this after the caller's return address is on top of stack
+#ifdef ASSERT
+  // Compilers generate code that bang the stack by as much as the
+  // interpreter would need. So this stack banging should never
+  // trigger a fault. Verify that it does not on non product builds.
   if (UseStackBanging) {
     // Get total frame size for interpreted frames
     __ ld(O2UnrollBlock, Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes(), O4);
     __ bang_stack_size(O4, O3, G3_scratch);
   }
+#endif
 
   __ ld(O2UnrollBlock, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes(), O4array_size);
   __ ld_ptr(O2UnrollBlock, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes(), G3pcs);
@@ -3409,9 +3412,11 @@
   ResourceMark rm;
   // setup code generation tools
   int pad = VerifyThread ? 512 : 0;// Extra slop space for more verify code
+#ifdef ASSERT
   if (UseStackBanging) {
     pad += StackShadowPages*16 + 32;
   }
+#endif
 #ifdef _LP64
   CodeBuffer buffer("deopt_blob", 2100+pad, 512);
 #else
@@ -3632,9 +3637,11 @@
   ResourceMark rm;
   // setup code generation tools
   int pad = VerifyThread ? 512 : 0;
+#ifdef ASSERT
   if (UseStackBanging) {
     pad += StackShadowPages*16 + 32;
   }
+#endif
 #ifdef _LP64
   CodeBuffer buffer("uncommon_trap_blob", 2700+pad, 512);
 #else
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Thu Apr 17 13:50:26 2014 -0400
@@ -1193,15 +1193,16 @@
     st->print_cr("Verify_Thread"); st->print("\t");
   }
 
-  size_t framesize = C->frame_slots() << LogBytesPerInt;
+  size_t framesize = C->frame_size_in_bytes();
+  int bangsize = C->bang_size_in_bytes();
 
   // Calls to C2R adapters often do not accept exceptional returns.
   // We require that their callers must bang for them.  But be careful, because
   // some VM calls (such as call site linkage) can use several kilobytes of
   // stack.  But the stack safety zone should account for that.
   // See bugs 4446381, 4468289, 4497237.
-  if (C->need_stack_bang(framesize)) {
-    st->print_cr("! stack bang"); st->print("\t");
+  if (C->need_stack_bang(bangsize)) {
+    st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t");
   }
 
   if (Assembler::is_simm13(-framesize)) {
@@ -1225,17 +1226,18 @@
 
   __ verify_thread();
 
-  size_t framesize = C->frame_slots() << LogBytesPerInt;
+  size_t framesize = C->frame_size_in_bytes();
   assert(framesize >= 16*wordSize, "must have room for reg. save area");
   assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment");
+  int bangsize = C->bang_size_in_bytes();
 
   // Calls to C2R adapters often do not accept exceptional returns.
   // We require that their callers must bang for them.  But be careful, because
   // some VM calls (such as call site linkage) can use several kilobytes of
   // stack.  But the stack safety zone should account for that.
   // See bugs 4446381, 4468289, 4497237.
-  if (C->need_stack_bang(framesize)) {
-    __ generate_stack_overflow_check(framesize);
+  if (C->need_stack_bang(bangsize)) {
+    __ generate_stack_overflow_check(bangsize);
   }
 
   if (Assembler::is_simm13(-framesize)) {
@@ -1268,7 +1270,7 @@
 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
   Compile* C = ra_->C;
 
-  if( do_polling() && ra_->C->is_method_compilation() ) {
+  if(do_polling() && ra_->C->is_method_compilation()) {
     st->print("SETHI  #PollAddr,L0\t! Load Polling address\n\t");
 #ifdef _LP64
     st->print("LDX    [L0],G0\t!Poll for Safepointing\n\t");
@@ -1277,8 +1279,12 @@
 #endif
   }
 
-  if( do_polling() )
+  if(do_polling()) {
+    if (UseCBCond && !ra_->C->is_method_compilation()) {
+      st->print("NOP\n\t");
+    }
     st->print("RET\n\t");
+  }
 
   st->print("RESTORE");
 }
@@ -1291,15 +1297,20 @@
   __ verify_thread();
 
   // If this does safepoint polling, then do it here
-  if( do_polling() && ra_->C->is_method_compilation() ) {
+  if(do_polling() && ra_->C->is_method_compilation()) {
     AddressLiteral polling_page(os::get_polling_page());
     __ sethi(polling_page, L0);
     __ relocate(relocInfo::poll_return_type);
-    __ ld_ptr( L0, 0, G0 );
+    __ ld_ptr(L0, 0, G0);
   }
 
   // If this is a return, then stuff the restore in the delay slot
-  if( do_polling() ) {
+  if(do_polling()) {
+    if (UseCBCond && !ra_->C->is_method_compilation()) {
+      // Insert extra padding for the case when the epilogue is preceded by
+      // a cbcond jump, which can't be followed by a CTI instruction
+      __ nop();
+    }
     __ ret();
     __ delayed()->restore();
   } else {
@@ -2538,7 +2549,7 @@
   enc_class call_epilog %{
     if( VerifyStackAtCalls ) {
       MacroAssembler _masm(&cbuf);
-      int framesize = ra_->C->frame_slots() << LogBytesPerInt;
+      int framesize = ra_->C->frame_size_in_bytes();
       Register temp_reg = G3;
       __ add(SP, framesize, temp_reg);
       __ cmp(temp_reg, FP);
@@ -3330,7 +3341,18 @@
 //----------Instruction Attributes---------------------------------------------
 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
 ins_attrib ins_size(32);           // Required size attribute (in bits)
-ins_attrib ins_avoid_back_to_back(0); // instruction should not be generated back to back
+
+// avoid_back_to_back attribute is an expression that must return
+// one of the following values defined in MachNode:
+// AVOID_NONE   - instruction can be placed anywhere
+// AVOID_BEFORE - instruction cannot be placed after an
+//                instruction with MachNode::AVOID_AFTER
+// AVOID_AFTER  - the next instruction cannot be the one 
+//                with MachNode::AVOID_BEFORE
+// AVOID_BEFORE_AND_AFTER - BEFORE and AFTER attributes at 
+//                          the same time                                
+ins_attrib ins_avoid_back_to_back(MachNode::AVOID_NONE);
+
 ins_attrib ins_short_branch(0);    // Required flag: is this instruction a
                                    // non-matching short branch variant of some
                                                             // long branch?
@@ -6630,6 +6652,7 @@
   ins_encode %{
     __ encode_heap_oop($src$$Register, $dst$$Register);
   %}
+  ins_avoid_back_to_back(Universe::narrow_oop_base() == NULL ? AVOID_NONE : AVOID_BEFORE);
   ins_pipe(ialu_reg);
 %}
 
@@ -9199,6 +9222,7 @@
     __ ba(*L);
     __ delayed()->nop();
   %}
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br);
 %}
 
@@ -9217,7 +9241,7 @@
     __ ba_short(*L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_imm);
 %}
 
@@ -9231,6 +9255,7 @@
   format %{ "BP$cmp   $icc,$labl" %}
   // Prim = bits 24-22, Secnd = bits 31-30
   ins_encode( enc_bp( labl, cmp, icc ) );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br_cc);
 %}
 
@@ -9242,6 +9267,7 @@
   format %{ "BP$cmp  $icc,$labl" %}
   // Prim = bits 24-22, Secnd = bits 31-30
   ins_encode( enc_bp( labl, cmp, icc ) );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br_cc);
 %}
 
@@ -9260,6 +9286,7 @@
     __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L);
     __ delayed()->nop();
   %}
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br_cc);
 %}
 
@@ -9278,6 +9305,7 @@
     __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L);
     __ delayed()->nop();
   %}
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br_fcc);
 %}
 
@@ -9290,6 +9318,7 @@
   format %{ "BP$cmp   $icc,$labl\t! Loop end" %}
   // Prim = bits 24-22, Secnd = bits 31-30
   ins_encode( enc_bp( labl, cmp, icc ) );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br_cc);
 %}
 
@@ -9302,6 +9331,7 @@
   format %{ "BP$cmp  $icc,$labl\t! Loop end" %}
   // Prim = bits 24-22, Secnd = bits 31-30
   ins_encode( enc_bp( labl, cmp, icc ) );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br_cc);
 %}
 
@@ -9552,7 +9582,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_reg);
 %}
 
@@ -9570,7 +9600,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_imm);
 %}
 
@@ -9588,7 +9618,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_reg);
 %}
 
@@ -9606,7 +9636,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_imm);
 %}
 
@@ -9624,7 +9654,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$Register, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_reg);
 %}
 
@@ -9642,7 +9672,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$constant, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_imm);
 %}
 
@@ -9665,7 +9695,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, $op2$$Register, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_reg);
 %}
 
@@ -9687,7 +9717,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, G0, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_reg);
 %}
 
@@ -9705,7 +9735,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_reg);
 %}
 
@@ -9723,7 +9753,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, G0, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_reg);
 %}
 
@@ -9742,7 +9772,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_reg);
 %}
 
@@ -9760,7 +9790,7 @@
     __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L);
   %}
   ins_short_branch(1);
-  ins_avoid_back_to_back(1);
+  ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
   ins_pipe(cbcond_reg_imm);
 %}
 
@@ -9777,6 +9807,7 @@
   ins_cost(BRANCH_COST);
   format %{ "BR$cmp   $op1,$labl" %}
   ins_encode( enc_bpr( labl, cmp, op1 ) );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br_reg);
 %}
 
@@ -9789,6 +9820,7 @@
   ins_cost(BRANCH_COST);
   format %{ "BR$cmp   $op1,$labl" %}
   ins_encode( enc_bpr( labl, cmp, op1 ) );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br_reg);
 %}
 
@@ -9801,6 +9833,7 @@
   ins_cost(BRANCH_COST);
   format %{ "BR$cmp   $op1,$labl" %}
   ins_encode( enc_bpr( labl, cmp, op1 ) );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br_reg);
 %}
 
@@ -9841,6 +9874,7 @@
     __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
     __ delayed()->nop();
   %}
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(br_cc);
 %}
 
@@ -9968,6 +10002,7 @@
   ins_cost(CALL_COST);
   format %{ "CALL,static  ; NOP ==> " %}
   ins_encode( Java_Static_Call( meth ), call_epilog );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(simple_call);
 %}
 
@@ -10004,6 +10039,7 @@
   format %{ "CALL,runtime" %}
   ins_encode( Java_To_Runtime( meth ),
               call_epilog, adjust_long_from_native_call );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(simple_call);
 %}
 
@@ -10016,6 +10052,7 @@
   ins_encode( Java_To_Runtime( meth ),
               call_epilog,
               adjust_long_from_native_call );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(simple_call);
 %}
 
@@ -10028,6 +10065,7 @@
   ins_encode( Java_To_Runtime( meth ),
               call_epilog,
               adjust_long_from_native_call );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(simple_call);
 %}
 
@@ -10041,6 +10079,7 @@
   ins_cost(CALL_COST);
   format %{ "Jmp     $jump_target  ; NOP \t! $method_oop holds method oop" %}
   ins_encode(form_jmpl(jump_target));
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(tail_call);
 %}
 
@@ -10072,6 +10111,7 @@
   // opcode(Assembler::jmpl_op3, Assembler::arith_op);
   // The hack duplicates the exception oop into G3, so that CreateEx can use it there.
   // ins_encode( form3_rs1_simm13_rd( jump_target, 0x00, R_G0 ), move_return_pc_to_o1() );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(tail_call);
 %}
 
@@ -10102,6 +10142,7 @@
   // use the following format syntax
   format %{ "Jmp    rethrow_stub" %}
   ins_encode(enc_rethrow);
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(tail_call);
 %}
 
@@ -10130,6 +10171,7 @@
   ins_cost(DEFAULT_COST*10);
   format %{ "CALL   PartialSubtypeCheck\n\tNOP" %}
   ins_encode( enc_PartialSubtypeCheck() );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(partial_subtype_check_pipe);
 %}
 
@@ -10139,6 +10181,7 @@
   ins_cost(DEFAULT_COST*10);
   format %{ "CALL   PartialSubtypeCheck\n\tNOP\t# (sets condition codes)" %}
   ins_encode( enc_PartialSubtypeCheck() );
+  ins_avoid_back_to_back(AVOID_BEFORE);
   ins_pipe(partial_subtype_check_pipe);
 %}
 
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -1564,37 +1564,23 @@
   int monitor_size    = method->is_synchronized() ?
                                 1*frame::interpreter_frame_monitor_size() : 0;
   return size_activation_helper(method->max_locals(), method->max_stack(),
-                                 monitor_size) + call_stub_size;
+                                monitor_size) + call_stub_size;
 }
 
-int AbstractInterpreter::layout_activation(Method* method,
-                                           int tempcount,
-                                           int popframe_extra_args,
-                                           int moncount,
-                                           int caller_actual_parameters,
-                                           int callee_param_count,
-                                           int callee_local_count,
-                                           frame* caller,
-                                           frame* interpreter_frame,
-                                           bool is_top_frame,
-                                           bool is_bottom_frame) {
+int AbstractInterpreter::size_activation(int max_stack,
+                                         int temps,
+                                         int extra_args,
+                                         int monitors,
+                                         int callee_params,
+                                         int callee_locals,
+                                         bool is_top_frame) {
   // Note: This calculation must exactly parallel the frame setup
   // in InterpreterGenerator::generate_fixed_frame.
-  // If f!=NULL, set up the following variables:
-  //   - Lmethod
-  //   - Llocals
-  //   - Lmonitors (to the indicated number of monitors)
-  //   - Lesp (to the indicated number of temps)
-  // The frame f (if not NULL) on entry is a description of the caller of the frame
-  // we are about to layout. We are guaranteed that we will be able to fill in a
-  // new interpreter frame as its callee (i.e. the stack space is allocated and
-  // the amount was determined by an earlier call to this method with f == NULL).
-  // On return f (if not NULL) while describe the interpreter frame we just layed out.
 
-  int monitor_size           = moncount * frame::interpreter_frame_monitor_size();
-  int rounded_vm_local_words = round_to(frame::interpreter_frame_vm_local_words,WordsPerLong);
+  int monitor_size           = monitors * frame::interpreter_frame_monitor_size();
 
   assert(monitor_size == round_to(monitor_size, WordsPerLong), "must align");
+
   //
   // Note: if you look closely this appears to be doing something much different
   // than generate_fixed_frame. What is happening is this. On sparc we have to do
@@ -1619,146 +1605,171 @@
   // there is no sense in messing working code.
   //
 
-  int rounded_cls = round_to((callee_local_count - callee_param_count), WordsPerLong);
+  int rounded_cls = round_to((callee_locals - callee_params), WordsPerLong);
   assert(rounded_cls == round_to(rounded_cls, WordsPerLong), "must align");
 
-  int raw_frame_size = size_activation_helper(rounded_cls, method->max_stack(),
-                                              monitor_size);
+  int raw_frame_size = size_activation_helper(rounded_cls, max_stack, monitor_size);
 
-  if (interpreter_frame != NULL) {
-    // The skeleton frame must already look like an interpreter frame
-    // even if not fully filled out.
-    assert(interpreter_frame->is_interpreted_frame(), "Must be interpreted frame");
-
-    intptr_t* fp = interpreter_frame->fp();
+  return raw_frame_size;
+}
 
-    JavaThread* thread = JavaThread::current();
-    RegisterMap map(thread, false);
-    // More verification that skeleton frame is properly walkable
-    assert(fp == caller->sp(), "fp must match");
-
-    intptr_t* montop     = fp - rounded_vm_local_words;
+void AbstractInterpreter::layout_activation(Method* method,
+                                            int tempcount,
+                                            int popframe_extra_args,
+                                            int moncount,
+                                            int caller_actual_parameters,
+                                            int callee_param_count,
+                                            int callee_local_count,
+                                            frame* caller,
+                                            frame* interpreter_frame,
+                                            bool is_top_frame,
+                                            bool is_bottom_frame) {
+  // Set up the following variables:
+  //   - Lmethod
+  //   - Llocals
+  //   - Lmonitors (to the indicated number of monitors)
+  //   - Lesp (to the indicated number of temps)
+  // The frame caller on entry is a description of the caller of the
+  // frame we are about to layout. We are guaranteed that we will be
+  // able to fill in a new interpreter frame as its callee (i.e. the
+  // stack space is allocated and the amount was determined by an
+  // earlier call to the size_activation() method).  On return caller
+  // while describe the interpreter frame we just layed out.
 
-    // preallocate monitors (cf. __ add_monitor_to_stack)
-    intptr_t* monitors = montop - monitor_size;
+  // The skeleton frame must already look like an interpreter frame
+  // even if not fully filled out.
+  assert(interpreter_frame->is_interpreted_frame(), "Must be interpreted frame");
+
+  int rounded_vm_local_words = round_to(frame::interpreter_frame_vm_local_words,WordsPerLong);
+  int monitor_size           = moncount * frame::interpreter_frame_monitor_size();
+  assert(monitor_size == round_to(monitor_size, WordsPerLong), "must align");
+
+  intptr_t* fp = interpreter_frame->fp();
 
-    // preallocate stack space
-    intptr_t*  esp = monitors - 1 -
-                     (tempcount * Interpreter::stackElementWords) -
-                     popframe_extra_args;
+  JavaThread* thread = JavaThread::current();
+  RegisterMap map(thread, false);
+  // More verification that skeleton frame is properly walkable
+  assert(fp == caller->sp(), "fp must match");
+
+  intptr_t* montop     = fp - rounded_vm_local_words;
+
+  // preallocate monitors (cf. __ add_monitor_to_stack)
+  intptr_t* monitors = montop - monitor_size;
+
+  // preallocate stack space
+  intptr_t*  esp = monitors - 1 -
+    (tempcount * Interpreter::stackElementWords) -
+    popframe_extra_args;
 
-    int local_words = method->max_locals() * Interpreter::stackElementWords;
-    NEEDS_CLEANUP;
-    intptr_t* locals;
-    if (caller->is_interpreted_frame()) {
-      // Can force the locals area to end up properly overlapping the top of the expression stack.
-      intptr_t* Lesp_ptr = caller->interpreter_frame_tos_address() - 1;
-      // Note that this computation means we replace size_of_parameters() values from the caller
-      // interpreter frame's expression stack with our argument locals
-      int parm_words  = caller_actual_parameters * Interpreter::stackElementWords;
-      locals = Lesp_ptr + parm_words;
-      int delta = local_words - parm_words;
-      int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0;
-      *interpreter_frame->register_addr(I5_savedSP)    = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS;
-      if (!is_bottom_frame) {
-        // Llast_SP is set below for the current frame to SP (with the
-        // extra space for the callee's locals). Here we adjust
-        // Llast_SP for the caller's frame, removing the extra space
-        // for the current method's locals.
-        *caller->register_addr(Llast_SP) = *interpreter_frame->register_addr(I5_savedSP);
-      } else {
-        assert(*caller->register_addr(Llast_SP) >= *interpreter_frame->register_addr(I5_savedSP), "strange Llast_SP");
-      }
+  int local_words = method->max_locals() * Interpreter::stackElementWords;
+  NEEDS_CLEANUP;
+  intptr_t* locals;
+  if (caller->is_interpreted_frame()) {
+    // Can force the locals area to end up properly overlapping the top of the expression stack.
+    intptr_t* Lesp_ptr = caller->interpreter_frame_tos_address() - 1;
+    // Note that this computation means we replace size_of_parameters() values from the caller
+    // interpreter frame's expression stack with our argument locals
+    int parm_words  = caller_actual_parameters * Interpreter::stackElementWords;
+    locals = Lesp_ptr + parm_words;
+    int delta = local_words - parm_words;
+    int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0;
+    *interpreter_frame->register_addr(I5_savedSP)    = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS;
+    if (!is_bottom_frame) {
+      // Llast_SP is set below for the current frame to SP (with the
+      // extra space for the callee's locals). Here we adjust
+      // Llast_SP for the caller's frame, removing the extra space
+      // for the current method's locals.
+      *caller->register_addr(Llast_SP) = *interpreter_frame->register_addr(I5_savedSP);
     } else {
-      assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases");
-      // Don't have Lesp available; lay out locals block in the caller
-      // adjacent to the register window save area.
-      //
-      // Compiled frames do not allocate a varargs area which is why this if
-      // statement is needed.
-      //
-      if (caller->is_compiled_frame()) {
-        locals = fp + frame::register_save_words + local_words - 1;
-      } else {
-        locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1;
-      }
-      if (!caller->is_entry_frame()) {
-        // Caller wants his own SP back
-        int caller_frame_size = caller->cb()->frame_size();
-        *interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - STACK_BIAS;
+      assert(*caller->register_addr(Llast_SP) >= *interpreter_frame->register_addr(I5_savedSP), "strange Llast_SP");
+    }
+  } else {
+    assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases");
+    // Don't have Lesp available; lay out locals block in the caller
+    // adjacent to the register window save area.
+    //
+    // Compiled frames do not allocate a varargs area which is why this if
+    // statement is needed.
+    //
+    if (caller->is_compiled_frame()) {
+      locals = fp + frame::register_save_words + local_words - 1;
+    } else {
+      locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1;
+    }
+    if (!caller->is_entry_frame()) {
+      // Caller wants his own SP back
+      int caller_frame_size = caller->cb()->frame_size();
+      *interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - STACK_BIAS;
+    }
+  }
+  if (TraceDeoptimization) {
+    if (caller->is_entry_frame()) {
+      // make sure I5_savedSP and the entry frames notion of saved SP
+      // agree.  This assertion duplicate a check in entry frame code
+      // but catches the failure earlier.
+      assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP),
+             "would change callers SP");
+    }
+    if (caller->is_entry_frame()) {
+      tty->print("entry ");
+    }
+    if (caller->is_compiled_frame()) {
+      tty->print("compiled ");
+      if (caller->is_deoptimized_frame()) {
+        tty->print("(deopt) ");
       }
     }
-    if (TraceDeoptimization) {
-      if (caller->is_entry_frame()) {
-        // make sure I5_savedSP and the entry frames notion of saved SP
-        // agree.  This assertion duplicate a check in entry frame code
-        // but catches the failure earlier.
-        assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP),
-               "would change callers SP");
-      }
-      if (caller->is_entry_frame()) {
-        tty->print("entry ");
-      }
-      if (caller->is_compiled_frame()) {
-        tty->print("compiled ");
-        if (caller->is_deoptimized_frame()) {
-          tty->print("(deopt) ");
-        }
-      }
-      if (caller->is_interpreted_frame()) {
-        tty->print("interpreted ");
-      }
-      tty->print_cr("caller fp=0x%x sp=0x%x", caller->fp(), caller->sp());
-      tty->print_cr("save area = 0x%x, 0x%x", caller->sp(), caller->sp() + 16);
-      tty->print_cr("save area = 0x%x, 0x%x", caller->fp(), caller->fp() + 16);
-      tty->print_cr("interpreter fp=0x%x sp=0x%x", interpreter_frame->fp(), interpreter_frame->sp());
-      tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->sp(), interpreter_frame->sp() + 16);
-      tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->fp(), interpreter_frame->fp() + 16);
-      tty->print_cr("Llocals = 0x%x", locals);
-      tty->print_cr("Lesp = 0x%x", esp);
-      tty->print_cr("Lmonitors = 0x%x", monitors);
+    if (caller->is_interpreted_frame()) {
+      tty->print("interpreted ");
     }
+    tty->print_cr("caller fp=0x%x sp=0x%x", caller->fp(), caller->sp());
+    tty->print_cr("save area = 0x%x, 0x%x", caller->sp(), caller->sp() + 16);
+    tty->print_cr("save area = 0x%x, 0x%x", caller->fp(), caller->fp() + 16);
+    tty->print_cr("interpreter fp=0x%x sp=0x%x", interpreter_frame->fp(), interpreter_frame->sp());
+    tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->sp(), interpreter_frame->sp() + 16);
+    tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->fp(), interpreter_frame->fp() + 16);
+    tty->print_cr("Llocals = 0x%x", locals);
+    tty->print_cr("Lesp = 0x%x", esp);
+    tty->print_cr("Lmonitors = 0x%x", monitors);
+  }
 
-    if (method->max_locals() > 0) {
-      assert(locals < caller->sp() || locals >= (caller->sp() + 16), "locals in save area");
-      assert(locals < caller->fp() || locals > (caller->fp() + 16), "locals in save area");
-      assert(locals < interpreter_frame->sp() || locals > (interpreter_frame->sp() + 16), "locals in save area");
-      assert(locals < interpreter_frame->fp() || locals >= (interpreter_frame->fp() + 16), "locals in save area");
-    }
+  if (method->max_locals() > 0) {
+    assert(locals < caller->sp() || locals >= (caller->sp() + 16), "locals in save area");
+    assert(locals < caller->fp() || locals > (caller->fp() + 16), "locals in save area");
+    assert(locals < interpreter_frame->sp() || locals > (interpreter_frame->sp() + 16), "locals in save area");
+    assert(locals < interpreter_frame->fp() || locals >= (interpreter_frame->fp() + 16), "locals in save area");
+  }
 #ifdef _LP64
-    assert(*interpreter_frame->register_addr(I5_savedSP) & 1, "must be odd");
+  assert(*interpreter_frame->register_addr(I5_savedSP) & 1, "must be odd");
 #endif
 
-    *interpreter_frame->register_addr(Lmethod)     = (intptr_t) method;
-    *interpreter_frame->register_addr(Llocals)     = (intptr_t) locals;
-    *interpreter_frame->register_addr(Lmonitors)   = (intptr_t) monitors;
-    *interpreter_frame->register_addr(Lesp)        = (intptr_t) esp;
-    // Llast_SP will be same as SP as there is no adapter space
-    *interpreter_frame->register_addr(Llast_SP)    = (intptr_t) interpreter_frame->sp() - STACK_BIAS;
-    *interpreter_frame->register_addr(LcpoolCache) = (intptr_t) method->constants()->cache();
+  *interpreter_frame->register_addr(Lmethod)     = (intptr_t) method;
+  *interpreter_frame->register_addr(Llocals)     = (intptr_t) locals;
+  *interpreter_frame->register_addr(Lmonitors)   = (intptr_t) monitors;
+  *interpreter_frame->register_addr(Lesp)        = (intptr_t) esp;
+  // Llast_SP will be same as SP as there is no adapter space
+  *interpreter_frame->register_addr(Llast_SP)    = (intptr_t) interpreter_frame->sp() - STACK_BIAS;
+  *interpreter_frame->register_addr(LcpoolCache) = (intptr_t) method->constants()->cache();
 #ifdef FAST_DISPATCH
-    *interpreter_frame->register_addr(IdispatchTables) = (intptr_t) Interpreter::dispatch_table();
+  *interpreter_frame->register_addr(IdispatchTables) = (intptr_t) Interpreter::dispatch_table();
 #endif
 
 
 #ifdef ASSERT
-    BasicObjectLock* mp = (BasicObjectLock*)monitors;
-
-    assert(interpreter_frame->interpreter_frame_method() == method, "method matches");
-    assert(interpreter_frame->interpreter_frame_local_at(9) == (intptr_t *)((intptr_t)locals - (9 * Interpreter::stackElementSize)), "locals match");
-    assert(interpreter_frame->interpreter_frame_monitor_end()   == mp, "monitor_end matches");
-    assert(((intptr_t *)interpreter_frame->interpreter_frame_monitor_begin()) == ((intptr_t *)mp)+monitor_size, "monitor_begin matches");
-    assert(interpreter_frame->interpreter_frame_tos_address()-1 == esp, "esp matches");
+  BasicObjectLock* mp = (BasicObjectLock*)monitors;
 
-    // check bounds
-    intptr_t* lo = interpreter_frame->sp() + (frame::memory_parameter_word_sp_offset - 1);
-    intptr_t* hi = interpreter_frame->fp() - rounded_vm_local_words;
-    assert(lo < monitors && montop <= hi, "monitors in bounds");
-    assert(lo <= esp && esp < monitors, "esp in bounds");
+  assert(interpreter_frame->interpreter_frame_method() == method, "method matches");
+  assert(interpreter_frame->interpreter_frame_local_at(9) == (intptr_t *)((intptr_t)locals - (9 * Interpreter::stackElementSize)), "locals match");
+  assert(interpreter_frame->interpreter_frame_monitor_end()   == mp, "monitor_end matches");
+  assert(((intptr_t *)interpreter_frame->interpreter_frame_monitor_begin()) == ((intptr_t *)mp)+monitor_size, "monitor_begin matches");
+  assert(interpreter_frame->interpreter_frame_tos_address()-1 == esp, "esp matches");
+
+  // check bounds
+  intptr_t* lo = interpreter_frame->sp() + (frame::memory_parameter_word_sp_offset - 1);
+  intptr_t* hi = interpreter_frame->fp() - rounded_vm_local_words;
+  assert(lo < monitors && montop <= hi, "monitors in bounds");
+  assert(lo <= esp && esp < monitors, "esp in bounds");
 #endif // ASSERT
-  }
-
-  return raw_frame_size;
 }
 
 //----------------------------------------------------------------------------------------------------
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -288,7 +288,7 @@
 
   // build frame
   ciMethod* m = compilation()->method();
-  __ build_frame(initial_frame_size_in_bytes());
+  __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes());
 
   // OSR buffer is
   //
@@ -376,7 +376,7 @@
 }
 
 // This specifies the rsp decrement needed to build the frame
-int LIR_Assembler::initial_frame_size_in_bytes() {
+int LIR_Assembler::initial_frame_size_in_bytes() const {
   // if rounding, must let FrameMap know!
 
   // The frame_map records size in slots (32bit word)
--- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -349,13 +349,14 @@
 }
 
 
-void C1_MacroAssembler::build_frame(int frame_size_in_bytes) {
+void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
+  assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
   // Make sure there is enough stack space for this method's activation.
   // Note that we do this before doing an enter(). This matches the
   // ordering of C2's stack overflow check / rsp decrement and allows
   // the SharedRuntime stack overflow handling to be consistent
   // between the two compilers.
-  generate_stack_overflow_check(frame_size_in_bytes);
+  generate_stack_overflow_check(bang_size_in_bytes);
 
   push(rbp);
 #ifdef TIERED
--- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -2342,29 +2342,42 @@
          "Stack top out of range");
 }
 
-int AbstractInterpreter::layout_activation(Method* method,
-                                           int tempcount,  //
-                                           int popframe_extra_args,
-                                           int moncount,
-                                           int caller_actual_parameters,
-                                           int callee_param_count,
-                                           int callee_locals,
-                                           frame* caller,
-                                           frame* interpreter_frame,
-                                           bool is_top_frame,
-                                           bool is_bottom_frame) {
-
-  assert(popframe_extra_args == 0, "FIX ME");
-  // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
-  // does as far as allocating an interpreter frame.
-  // If interpreter_frame!=NULL, set up the method, locals, and monitors.
-  // The frame interpreter_frame, if not NULL, is guaranteed to be the right size,
-  // as determined by a previous call to this method.
-  // It is also guaranteed to be walkable even though it is in a skeletal state
+
+static int frame_size_helper(int max_stack,
+                             int tempcount,
+                             int moncount,
+                             int callee_param_count,
+                             int callee_locals,
+                             bool is_top_frame,
+                             int& monitor_size,
+                             int& full_frame_size) {
+  int extra_locals_size = (callee_locals - callee_param_count) * BytesPerWord;
+  monitor_size = sizeof(BasicObjectLock) * moncount;
+
+  // First calculate the frame size without any java expression stack
+  int short_frame_size = size_activation_helper(extra_locals_size,
+                                                monitor_size);
+
+  // Now with full size expression stack
+  full_frame_size = short_frame_size + max_stack * BytesPerWord;
+
+  // and now with only live portion of the expression stack
+  short_frame_size = short_frame_size + tempcount * BytesPerWord;
+
+  // the size the activation is right now. Only top frame is full size
+  int frame_size = (is_top_frame ? full_frame_size : short_frame_size);
+  return frame_size;
+}
+
+int AbstractInterpreter::size_activation(int max_stack,
+                                         int tempcount,
+                                         int extra_args,
+                                         int moncount,
+                                         int callee_param_count,
+                                         int callee_locals,
+                                         bool is_top_frame) {
+  assert(extra_args == 0, "FIX ME");
   // NOTE: return size is in words not bytes
-  // NOTE: tempcount is the current size of the java expression stack. For top most
-  //       frames we will allocate a full sized expression stack and not the curback
-  //       version that non-top frames have.
 
   // Calculate the amount our frame will be adjust by the callee. For top frame
   // this is zero.
@@ -2374,87 +2387,102 @@
   // to it. So it ignores last_frame_adjust value. Seems suspicious as far
   // as getting sender_sp correct.
 
-  int extra_locals_size = (callee_locals - callee_param_count) * BytesPerWord;
-  int monitor_size = sizeof(BasicObjectLock) * moncount;
-
-  // First calculate the frame size without any java expression stack
-  int short_frame_size = size_activation_helper(extra_locals_size,
-                                                monitor_size);
-
-  // Now with full size expression stack
-  int full_frame_size = short_frame_size + method->max_stack() * BytesPerWord;
-
-  // and now with only live portion of the expression stack
-  short_frame_size = short_frame_size + tempcount * BytesPerWord;
-
-  // the size the activation is right now. Only top frame is full size
-  int frame_size = (is_top_frame ? full_frame_size : short_frame_size);
-
-  if (interpreter_frame != NULL) {
+  int unused_monitor_size = 0;
+  int unused_full_frame_size = 0;
+  return frame_size_helper(max_stack, tempcount, moncount, callee_param_count, callee_locals,
+                           is_top_frame, unused_monitor_size, unused_full_frame_size)/BytesPerWord;
+}
+
+void AbstractInterpreter::layout_activation(Method* method,
+                                            int tempcount,  //
+                                            int popframe_extra_args,
+                                            int moncount,
+                                            int caller_actual_parameters,
+                                            int callee_param_count,
+                                            int callee_locals,
+                                            frame* caller,
+                                            frame* interpreter_frame,
+                                            bool is_top_frame,
+                                            bool is_bottom_frame) {
+
+  assert(popframe_extra_args == 0, "FIX ME");
+  // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
+  // does as far as allocating an interpreter frame.
+  // Set up the method, locals, and monitors.
+  // The frame interpreter_frame is guaranteed to be the right size,
+  // as determined by a previous call to the size_activation() method.
+  // It is also guaranteed to be walkable even though it is in a skeletal state
+  // NOTE: tempcount is the current size of the java expression stack. For top most
+  //       frames we will allocate a full sized expression stack and not the curback
+  //       version that non-top frames have.
+
+  int monitor_size = 0;
+  int full_frame_size = 0;
+  int frame_size = frame_size_helper(method->max_stack(), tempcount, moncount, callee_param_count, callee_locals,
+                                     is_top_frame, monitor_size, full_frame_size);
+
 #ifdef ASSERT
-    assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
+  assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
 #endif
 
-    // MUCHO HACK
-
-    intptr_t* frame_bottom = (intptr_t*) ((intptr_t)interpreter_frame->sp() - (full_frame_size - frame_size));
-
-    /* Now fillin the interpreterState object */
-
-    // The state object is the first thing on the frame and easily located
-
-    interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter));
-
-
-    // Find the locals pointer. This is rather simple on x86 because there is no
-    // confusing rounding at the callee to account for. We can trivially locate
-    // our locals based on the current fp().
-    // Note: the + 2 is for handling the "static long no_params() method" issue.
-    // (too bad I don't really remember that issue well...)
-
-    intptr_t* locals;
-    // If the caller is interpreted we need to make sure that locals points to the first
-    // argument that the caller passed and not in an area where the stack might have been extended.
-    // because the stack to stack to converter needs a proper locals value in order to remove the
-    // arguments from the caller and place the result in the proper location. Hmm maybe it'd be
-    // simpler if we simply stored the result in the BytecodeInterpreter object and let the c++ code
-    // adjust the stack?? HMMM QQQ
-    //
-    if (caller->is_interpreted_frame()) {
-      // locals must agree with the caller because it will be used to set the
-      // caller's tos when we return.
-      interpreterState prev  = caller->get_interpreterState();
-      // stack() is prepushed.
-      locals = prev->stack() + method->size_of_parameters();
-      // locals = caller->unextended_sp() + (method->size_of_parameters() - 1);
-      if (locals != interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2) {
-        // os::breakpoint();
-      }
-    } else {
-      // this is where a c2i would have placed locals (except for the +2)
-      locals = interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2;
+  // MUCHO HACK
+
+  intptr_t* frame_bottom = (intptr_t*) ((intptr_t)interpreter_frame->sp() - (full_frame_size - frame_size));
+
+  /* Now fillin the interpreterState object */
+
+  // The state object is the first thing on the frame and easily located
+
+  interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter));
+
+
+  // Find the locals pointer. This is rather simple on x86 because there is no
+  // confusing rounding at the callee to account for. We can trivially locate
+  // our locals based on the current fp().
+  // Note: the + 2 is for handling the "static long no_params() method" issue.
+  // (too bad I don't really remember that issue well...)
+
+  intptr_t* locals;
+  // If the caller is interpreted we need to make sure that locals points to the first
+  // argument that the caller passed and not in an area where the stack might have been extended.
+  // because the stack to stack to converter needs a proper locals value in order to remove the
+  // arguments from the caller and place the result in the proper location. Hmm maybe it'd be
+  // simpler if we simply stored the result in the BytecodeInterpreter object and let the c++ code
+  // adjust the stack?? HMMM QQQ
+  //
+  if (caller->is_interpreted_frame()) {
+    // locals must agree with the caller because it will be used to set the
+    // caller's tos when we return.
+    interpreterState prev  = caller->get_interpreterState();
+    // stack() is prepushed.
+    locals = prev->stack() + method->size_of_parameters();
+    // locals = caller->unextended_sp() + (method->size_of_parameters() - 1);
+    if (locals != interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2) {
+      // os::breakpoint();
     }
-
-    intptr_t* monitor_base = (intptr_t*) cur_state;
-    intptr_t* stack_base = (intptr_t*) ((intptr_t) monitor_base - monitor_size);
-    /* +1 because stack is always prepushed */
-    intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (tempcount + 1) * BytesPerWord);
-
-
-    BytecodeInterpreter::layout_interpreterState(cur_state,
-                                          caller,
-                                          interpreter_frame,
-                                          method,
-                                          locals,
-                                          stack,
-                                          stack_base,
-                                          monitor_base,
-                                          frame_bottom,
-                                          is_top_frame);
-
-    // BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp());
+  } else {
+    // this is where a c2i would have placed locals (except for the +2)
+    locals = interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2;
   }
-  return frame_size/BytesPerWord;
+
+  intptr_t* monitor_base = (intptr_t*) cur_state;
+  intptr_t* stack_base = (intptr_t*) ((intptr_t) monitor_base - monitor_size);
+  /* +1 because stack is always prepushed */
+  intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (tempcount + 1) * BytesPerWord);
+
+
+  BytecodeInterpreter::layout_interpreterState(cur_state,
+                                               caller,
+                                               interpreter_frame,
+                                               method,
+                                               locals,
+                                               stack,
+                                               stack_base,
+                                               monitor_base,
+                                               frame_bottom,
+                                               is_top_frame);
+
+  // BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp());
 }
 
 bool AbstractInterpreter::can_be_compiled(methodHandle m) {
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -1051,7 +1051,7 @@
   // was post-decremented.)  Skip this address by starting at i=1, and
   // touch a few more pages below.  N.B.  It is important to touch all
   // the way down to and including i=StackShadowPages.
-  for (int i = 1; i <= StackShadowPages; i++) {
+  for (int i = 1; i < StackShadowPages; i++) {
     // this could be any sized move but this is can be a debugging crumb
     // so the bigger the better.
     movptr(Address(tmp, (-i*os::vm_page_size())), size );
@@ -6093,7 +6093,7 @@
 
 
 // C2 compiled method's prolog code.
-void MacroAssembler::verified_entry(int framesize, bool stack_bang, bool fp_mode_24b) {
+void MacroAssembler::verified_entry(int framesize, int stack_bang_size, bool fp_mode_24b) {
 
   // WARNING: Initial instruction MUST be 5 bytes or longer so that
   // NativeJump::patch_verified_entry will be able to patch out the entry
@@ -6101,18 +6101,20 @@
   // the frame allocation can be either 3 or 6 bytes. So if we don't do
   // stack bang then we must use the 6 byte frame allocation even if
   // we have no frame. :-(
+  assert(stack_bang_size >= framesize || stack_bang_size <= 0, "stack bang size incorrect");
 
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
   // Remove word for return addr
   framesize -= wordSize;
+  stack_bang_size -= wordSize;
 
   // Calls to C2R adapters often do not accept exceptional returns.
   // We require that their callers must bang for them.  But be careful, because
   // some VM calls (such as call site linkage) can use several kilobytes of
   // stack.  But the stack safety zone should account for that.
   // See bugs 4446381, 4468289, 4497237.
-  if (stack_bang) {
-    generate_stack_overflow_check(framesize);
+  if (stack_bang_size > 0) {
+    generate_stack_overflow_check(stack_bang_size);
 
     // We always push rbp, so that on return to interpreter rbp, will be
     // restored correctly and we can correct the stack.
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -1170,7 +1170,7 @@
   void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); }
 
   // C2 compiled method's prolog code.
-  void verified_entry(int framesize, bool stack_bang, bool fp_mode_24b);
+  void verified_entry(int framesize, int stack_bang_size, bool fp_mode_24b);
 
   // clear memory of size 'cnt' qwords, starting at 'base'.
   void clear_mem(Register base, Register cnt, Register rtmp);
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -3014,11 +3014,15 @@
   // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved)
   __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
 
-  // Stack bang to make sure there's enough room for these interpreter frames.
+#ifdef ASSERT
+  // Compilers generate code that bang the stack by as much as the
+  // interpreter would need. So this stack banging should never
+  // trigger a fault. Verify that it does not on non product builds.
   if (UseStackBanging) {
     __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()));
     __ bang_stack_size(rbx, rcx);
   }
+#endif
 
   // Load array of frame pcs into ECX
   __ movptr(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()));
@@ -3240,12 +3244,15 @@
   // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved)
   __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
 
-  // Stack bang to make sure there's enough room for these interpreter frames.
+#ifdef ASSERT
+  // Compilers generate code that bang the stack by as much as the
+  // interpreter would need. So this stack banging should never
+  // trigger a fault. Verify that it does not on non product builds.
   if (UseStackBanging) {
     __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()));
     __ bang_stack_size(rbx, rcx);
   }
-
+#endif
 
   // Load array of frame pcs into ECX
   __ movl(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()));
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -3484,11 +3484,15 @@
   // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved)
   __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
 
-  // Stack bang to make sure there's enough room for these interpreter frames.
+#ifdef ASSERT
+  // Compilers generate code that bang the stack by as much as the
+  // interpreter would need. So this stack banging should never
+  // trigger a fault. Verify that it does not on non product builds.
   if (UseStackBanging) {
     __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()));
     __ bang_stack_size(rbx, rcx);
   }
+#endif
 
   // Load address of array of frame pcs into rcx
   __ movptr(rcx, Address(rdi, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()));
@@ -3682,11 +3686,15 @@
   // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved)
   __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
 
-  // Stack bang to make sure there's enough room for these interpreter frames.
+#ifdef ASSERT
+  // Compilers generate code that bang the stack by as much as the
+  // interpreter would need. So this stack banging should never
+  // trigger a fault. Verify that it does not on non product builds.
   if (UseStackBanging) {
     __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()));
     __ bang_stack_size(rbx, rcx);
   }
+#endif
 
   // Load address of array of frame pcs into rcx (address*)
   __ movptr(rcx, Address(rdi, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1997, 2014, 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 "ci/ciMethod.hpp"
+#include "interpreter/interpreter.hpp"
+#include "runtime/frame.inline.hpp"
+
+#ifndef CC_INTERP
+
+// asm based interpreter deoptimization helpers
+int AbstractInterpreter::size_activation(int max_stack,
+                                         int temps,
+                                         int extra_args,
+                                         int monitors,
+                                         int callee_params,
+                                         int callee_locals,
+                                         bool is_top_frame) {
+  // Note: This calculation must exactly parallel the frame setup
+  // in AbstractInterpreterGenerator::generate_method_entry.
+
+  // fixed size of an interpreter frame:
+  int overhead = frame::sender_sp_offset -
+                 frame::interpreter_frame_initial_sp_offset;
+  // Our locals were accounted for by the caller (or last_frame_adjust
+  // on the transistion) Since the callee parameters already account
+  // for the callee's params we only need to account for the extra
+  // locals.
+  int size = overhead +
+         (callee_locals - callee_params)*Interpreter::stackElementWords +
+         monitors * frame::interpreter_frame_monitor_size() +
+         temps* Interpreter::stackElementWords + extra_args;
+
+  return size;
+}
+
+void AbstractInterpreter::layout_activation(Method* method,
+                                            int tempcount,
+                                            int popframe_extra_args,
+                                            int moncount,
+                                            int caller_actual_parameters,
+                                            int callee_param_count,
+                                            int callee_locals,
+                                            frame* caller,
+                                            frame* interpreter_frame,
+                                            bool is_top_frame,
+                                            bool is_bottom_frame) {
+  // The frame interpreter_frame is guaranteed to be the right size,
+  // as determined by a previous call to the size_activation() method.
+  // It is also guaranteed to be walkable even though it is in a
+  // skeletal state
+
+  int max_locals = method->max_locals() * Interpreter::stackElementWords;
+  int extra_locals = (method->max_locals() - method->size_of_parameters()) *
+    Interpreter::stackElementWords;
+
+#ifdef ASSERT
+  if (!EnableInvokeDynamic) {
+    // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
+    // Probably, since deoptimization doesn't work yet.
+    assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
+  }
+  assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)");
+#endif
+
+  interpreter_frame->interpreter_frame_set_method(method);
+  // NOTE the difference in using sender_sp and
+  // interpreter_frame_sender_sp interpreter_frame_sender_sp is
+  // the original sp of the caller (the unextended_sp) and
+  // sender_sp is fp+8/16 (32bit/64bit) XXX
+  intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
+
+#ifdef ASSERT
+  if (caller->is_interpreted_frame()) {
+    assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
+  }
+#endif
+
+  interpreter_frame->interpreter_frame_set_locals(locals);
+  BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
+  BasicObjectLock* monbot = montop - moncount;
+  interpreter_frame->interpreter_frame_set_monitor_end(monbot);
+
+  // Set last_sp
+  intptr_t*  esp = (intptr_t*) monbot -
+    tempcount*Interpreter::stackElementWords -
+    popframe_extra_args;
+  interpreter_frame->interpreter_frame_set_last_sp(esp);
+
+  // All frames but the initial (oldest) interpreter frame we fill in have
+  // a value for sender_sp that allows walking the stack but isn't
+  // truly correct. Correct the value here.
+  if (extra_locals != 0 &&
+      interpreter_frame->sender_sp() ==
+      interpreter_frame->interpreter_frame_sender_sp()) {
+    interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() +
+                                                       extra_locals);
+  }
+  *interpreter_frame->interpreter_frame_cache_addr() =
+    method->constants()->cache();
+}
+
+#endif // CC_INTERP
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -1686,91 +1686,6 @@
   return overhead_size + method_stack + stub_code;
 }
 
-// asm based interpreter deoptimization helpers
-
-int AbstractInterpreter::layout_activation(Method* method,
-                                           int tempcount,
-                                           int popframe_extra_args,
-                                           int moncount,
-                                           int caller_actual_parameters,
-                                           int callee_param_count,
-                                           int callee_locals,
-                                           frame* caller,
-                                           frame* interpreter_frame,
-                                           bool is_top_frame,
-                                           bool is_bottom_frame) {
-  // Note: This calculation must exactly parallel the frame setup
-  // in AbstractInterpreterGenerator::generate_method_entry.
-  // If interpreter_frame!=NULL, set up the method, locals, and monitors.
-  // The frame interpreter_frame, if not NULL, is guaranteed to be the right size,
-  // as determined by a previous call to this method.
-  // It is also guaranteed to be walkable even though it is in a skeletal state
-  // NOTE: return size is in words not bytes
-
-  // fixed size of an interpreter frame:
-  int max_locals = method->max_locals() * Interpreter::stackElementWords;
-  int extra_locals = (method->max_locals() - method->size_of_parameters()) *
-                     Interpreter::stackElementWords;
-
-  int overhead = frame::sender_sp_offset - frame::interpreter_frame_initial_sp_offset;
-
-  // Our locals were accounted for by the caller (or last_frame_adjust on the transistion)
-  // Since the callee parameters already account for the callee's params we only need to account for
-  // the extra locals.
-
-
-  int size = overhead +
-         ((callee_locals - callee_param_count)*Interpreter::stackElementWords) +
-         (moncount*frame::interpreter_frame_monitor_size()) +
-         tempcount*Interpreter::stackElementWords + popframe_extra_args;
-
-  if (interpreter_frame != NULL) {
-#ifdef ASSERT
-    if (!EnableInvokeDynamic)
-      // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
-      // Probably, since deoptimization doesn't work yet.
-      assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
-    assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)");
-#endif
-
-    interpreter_frame->interpreter_frame_set_method(method);
-    // NOTE the difference in using sender_sp and interpreter_frame_sender_sp
-    // interpreter_frame_sender_sp is the original sp of the caller (the unextended_sp)
-    // and sender_sp is fp+8
-    intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
-
-#ifdef ASSERT
-    if (caller->is_interpreted_frame()) {
-      assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
-    }
-#endif
-
-    interpreter_frame->interpreter_frame_set_locals(locals);
-    BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
-    BasicObjectLock* monbot = montop - moncount;
-    interpreter_frame->interpreter_frame_set_monitor_end(monbot);
-
-    // Set last_sp
-    intptr_t*  rsp = (intptr_t*) monbot  -
-                     tempcount*Interpreter::stackElementWords -
-                     popframe_extra_args;
-    interpreter_frame->interpreter_frame_set_last_sp(rsp);
-
-    // All frames but the initial (oldest) interpreter frame we fill in have a
-    // value for sender_sp that allows walking the stack but isn't
-    // truly correct. Correct the value here.
-
-    if (extra_locals != 0 &&
-        interpreter_frame->sender_sp() == interpreter_frame->interpreter_frame_sender_sp() ) {
-      interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + extra_locals);
-    }
-    *interpreter_frame->interpreter_frame_cache_addr() =
-      method->constants()->cache();
-  }
-  return size;
-}
-
-
 //------------------------------------------------------------------------------------------------------------------------
 // Exceptions
 
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -1695,87 +1695,6 @@
   return (overhead_size + method_stack + stub_code);
 }
 
-int AbstractInterpreter::layout_activation(Method* method,
-                                           int tempcount,
-                                           int popframe_extra_args,
-                                           int moncount,
-                                           int caller_actual_parameters,
-                                           int callee_param_count,
-                                           int callee_locals,
-                                           frame* caller,
-                                           frame* interpreter_frame,
-                                           bool is_top_frame,
-                                           bool is_bottom_frame) {
-  // Note: This calculation must exactly parallel the frame setup
-  // in AbstractInterpreterGenerator::generate_method_entry.
-  // If interpreter_frame!=NULL, set up the method, locals, and monitors.
-  // The frame interpreter_frame, if not NULL, is guaranteed to be the
-  // right size, as determined by a previous call to this method.
-  // It is also guaranteed to be walkable even though it is in a skeletal state
-
-  // fixed size of an interpreter frame:
-  int max_locals = method->max_locals() * Interpreter::stackElementWords;
-  int extra_locals = (method->max_locals() - method->size_of_parameters()) *
-                     Interpreter::stackElementWords;
-
-  int overhead = frame::sender_sp_offset -
-                 frame::interpreter_frame_initial_sp_offset;
-  // Our locals were accounted for by the caller (or last_frame_adjust
-  // on the transistion) Since the callee parameters already account
-  // for the callee's params we only need to account for the extra
-  // locals.
-  int size = overhead +
-         (callee_locals - callee_param_count)*Interpreter::stackElementWords +
-         moncount * frame::interpreter_frame_monitor_size() +
-         tempcount* Interpreter::stackElementWords + popframe_extra_args;
-  if (interpreter_frame != NULL) {
-#ifdef ASSERT
-    if (!EnableInvokeDynamic)
-      // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences?
-      // Probably, since deoptimization doesn't work yet.
-      assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
-    assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)");
-#endif
-
-    interpreter_frame->interpreter_frame_set_method(method);
-    // NOTE the difference in using sender_sp and
-    // interpreter_frame_sender_sp interpreter_frame_sender_sp is
-    // the original sp of the caller (the unextended_sp) and
-    // sender_sp is fp+16 XXX
-    intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
-
-#ifdef ASSERT
-    if (caller->is_interpreted_frame()) {
-      assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
-    }
-#endif
-
-    interpreter_frame->interpreter_frame_set_locals(locals);
-    BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
-    BasicObjectLock* monbot = montop - moncount;
-    interpreter_frame->interpreter_frame_set_monitor_end(monbot);
-
-    // Set last_sp
-    intptr_t*  esp = (intptr_t*) monbot -
-                     tempcount*Interpreter::stackElementWords -
-                     popframe_extra_args;
-    interpreter_frame->interpreter_frame_set_last_sp(esp);
-
-    // All frames but the initial (oldest) interpreter frame we fill in have
-    // a value for sender_sp that allows walking the stack but isn't
-    // truly correct. Correct the value here.
-    if (extra_locals != 0 &&
-        interpreter_frame->sender_sp() ==
-        interpreter_frame->interpreter_frame_sender_sp()) {
-      interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() +
-                                                         extra_locals);
-    }
-    *interpreter_frame->interpreter_frame_cache_addr() =
-      method->constants()->cache();
-  }
-  return size;
-}
-
 //-----------------------------------------------------------------------------
 // Exceptions
 
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Thu Apr 17 13:50:26 2014 -0400
@@ -512,14 +512,15 @@
 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
   Compile* C = ra_->C;
 
-  int framesize = C->frame_slots() << LogBytesPerInt;
+  int framesize = C->frame_size_in_bytes();
+  int bangsize = C->bang_size_in_bytes();
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
   // Remove wordSize for return addr which is already pushed.
   framesize -= wordSize;
 
-  if (C->need_stack_bang(framesize)) {
+  if (C->need_stack_bang(bangsize)) {
     framesize -= wordSize;
-    st->print("# stack bang");
+    st->print("# stack bang (%d bytes)", bangsize);
     st->print("\n\t");
     st->print("PUSH   EBP\t# Save EBP");
     if (framesize) {
@@ -563,9 +564,10 @@
   Compile* C = ra_->C;
   MacroAssembler _masm(&cbuf);
 
-  int framesize = C->frame_slots() << LogBytesPerInt;
-
-  __ verified_entry(framesize, C->need_stack_bang(framesize), C->in_24_bit_fp_mode());
+  int framesize = C->frame_size_in_bytes();
+  int bangsize = C->bang_size_in_bytes();
+
+  __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, C->in_24_bit_fp_mode());
 
   C->set_frame_complete(cbuf.insts_size());
 
@@ -589,7 +591,7 @@
 #ifndef PRODUCT
 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
   Compile *C = ra_->C;
-  int framesize = C->frame_slots() << LogBytesPerInt;
+  int framesize = C->frame_size_in_bytes();
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
   // Remove two words for return addr and rbp,
   framesize -= 2*wordSize;
@@ -629,7 +631,7 @@
     masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
   }
 
-  int framesize = C->frame_slots() << LogBytesPerInt;
+  int framesize = C->frame_size_in_bytes();
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
   // Remove two words for return addr and rbp,
   framesize -= 2*wordSize;
@@ -663,7 +665,7 @@
   if (C->max_vector_size() > 16) size += 3; // vzeroupper
   if (do_polling() && C->is_method_compilation()) size += 6;
 
-  int framesize = C->frame_slots() << LogBytesPerInt;
+  int framesize = C->frame_size_in_bytes();
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
   // Remove two words for return addr and rbp,
   framesize -= 2*wordSize;
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Thu Apr 17 13:50:26 2014 -0400
@@ -713,14 +713,15 @@
 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
   Compile* C = ra_->C;
 
-  int framesize = C->frame_slots() << LogBytesPerInt;
+  int framesize = C->frame_size_in_bytes();
+  int bangsize = C->bang_size_in_bytes();
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
   // Remove wordSize for return addr which is already pushed.
   framesize -= wordSize;
 
-  if (C->need_stack_bang(framesize)) {
+  if (C->need_stack_bang(bangsize)) {
     framesize -= wordSize;
-    st->print("# stack bang");
+    st->print("# stack bang (%d bytes)", bangsize);
     st->print("\n\t");
     st->print("pushq   rbp\t# Save rbp");
     if (framesize) {
@@ -751,9 +752,10 @@
   Compile* C = ra_->C;
   MacroAssembler _masm(&cbuf);
 
-  int framesize = C->frame_slots() << LogBytesPerInt;
-
-  __ verified_entry(framesize, C->need_stack_bang(framesize), false);
+  int framesize = C->frame_size_in_bytes();
+  int bangsize = C->bang_size_in_bytes();
+
+  __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false);
 
   C->set_frame_complete(cbuf.insts_size());
 
@@ -786,7 +788,7 @@
     st->cr(); st->print("\t");
   }
 
-  int framesize = C->frame_slots() << LogBytesPerInt;
+  int framesize = C->frame_size_in_bytes();
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
   // Remove word for return adr already pushed
   // and RBP
@@ -822,7 +824,7 @@
     __ vzeroupper();
   }
 
-  int framesize = C->frame_slots() << LogBytesPerInt;
+  int framesize = C->frame_size_in_bytes();
   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
   // Remove word for return adr already pushed
   // and RBP
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -916,17 +916,32 @@
   return (InterpreterFrame *) fp;
 }
 
-int AbstractInterpreter::layout_activation(Method* method,
-                                           int       tempcount,
-                                           int       popframe_extra_args,
-                                           int       moncount,
-                                           int       caller_actual_parameters,
-                                           int       callee_param_count,
-                                           int       callee_locals,
-                                           frame*    caller,
-                                           frame*    interpreter_frame,
-                                           bool      is_top_frame,
-                                           bool      is_bottom_frame) {
+int AbstractInterpreter::size_activation(int       max_stack,
+                                         int       tempcount,
+                                         int       extra_args,
+                                         int       moncount,
+                                         int       callee_param_count,
+                                         int       callee_locals,
+                                         bool      is_top_frame) {
+  int header_words        = InterpreterFrame::header_words;
+  int monitor_words       = moncount * frame::interpreter_frame_monitor_size();
+  int stack_words         = is_top_frame ? max_stack : tempcount;
+  int callee_extra_locals = callee_locals - callee_param_count;
+
+  return header_words + monitor_words + stack_words + callee_extra_locals;
+}
+
+void AbstractInterpreter::layout_activation(Method* method,
+                                            int       tempcount,
+                                            int       popframe_extra_args,
+                                            int       moncount,
+                                            int       caller_actual_parameters,
+                                            int       callee_param_count,
+                                            int       callee_locals,
+                                            frame*    caller,
+                                            frame*    interpreter_frame,
+                                            bool      is_top_frame,
+                                            bool      is_bottom_frame) {
   assert(popframe_extra_args == 0, "what to do?");
   assert(!is_top_frame || (!callee_locals && !callee_param_count),
          "top frame should have no caller");
@@ -935,39 +950,31 @@
   // does (the full InterpreterFrame::build, that is, not the
   // one that creates empty frames for the deoptimizer).
   //
-  // If interpreter_frame is not NULL then it will be filled in.
-  // It's size is determined by a previous call to this method,
-  // so it should be correct.
+  // interpreter_frame will be filled in.  It's size is determined by
+  // a previous call to the size_activation() method,
   //
   // Note that tempcount is the current size of the expression
   // stack.  For top most frames we will allocate a full sized
   // expression stack and not the trimmed version that non-top
   // frames have.
 
-  int header_words        = InterpreterFrame::header_words;
   int monitor_words       = moncount * frame::interpreter_frame_monitor_size();
-  int stack_words         = is_top_frame ? method->max_stack() : tempcount;
-  int callee_extra_locals = callee_locals - callee_param_count;
-
-  if (interpreter_frame) {
-    intptr_t *locals        = interpreter_frame->fp() + method->max_locals();
-    interpreterState istate = interpreter_frame->get_interpreterState();
-    intptr_t *monitor_base  = (intptr_t*) istate;
-    intptr_t *stack_base    = monitor_base - monitor_words;
-    intptr_t *stack         = stack_base - tempcount - 1;
+  intptr_t *locals        = interpreter_frame->fp() + method->max_locals();
+  interpreterState istate = interpreter_frame->get_interpreterState();
+  intptr_t *monitor_base  = (intptr_t*) istate;
+  intptr_t *stack_base    = monitor_base - monitor_words;
+  intptr_t *stack         = stack_base - tempcount - 1;
 
-    BytecodeInterpreter::layout_interpreterState(istate,
-                                                 caller,
-                                                 NULL,
-                                                 method,
-                                                 locals,
-                                                 stack,
-                                                 stack_base,
-                                                 monitor_base,
-                                                 NULL,
-                                                 is_top_frame);
-  }
-  return header_words + monitor_words + stack_words + callee_extra_locals;
+  BytecodeInterpreter::layout_interpreterState(istate,
+                                               caller,
+                                               NULL,
+                                               method,
+                                               locals,
+                                               stack,
+                                               stack_base,
+                                               monitor_base,
+                                               NULL,
+                                               is_top_frame);
 }
 
 void BytecodeInterpreter::layout_interpreterState(interpreterState istate,
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java	Thu Apr 17 13:50:26 2014 -0400
@@ -25,6 +25,7 @@
 package com.sun.hotspot.tools.compiler;
 
 import java.io.PrintStream;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -40,6 +41,7 @@
     private int endNodes;
     private int endLiveNodes;
     private double timeStamp;
+    private long inlineId;
 
     CallSite() {
     }
@@ -94,7 +96,7 @@
 
     public void print(PrintStream stream, int indent) {
         emit(stream, indent);
-        String m = getMethod().getHolder().replace('/', '.') + "::" + getMethod().getName();
+        String m = getMethod().getHolder() + "::" + getMethod().getName();
         if (getReason() == null) {
             stream.print("  @ " + getBci() + " " + m + " (" + getMethod().getBytes() + " bytes)");
 
@@ -214,4 +216,45 @@
         return timeStamp;
     }
 
+    private boolean matches(CallSite other) {
+        // Every late inline call site has a unique inline id. If the
+        // call site we're looking for has one then use it other rely
+        // on method name and bci.
+        if (other.inlineId != 0) {
+            return inlineId == other.inlineId;
+        }
+        return method.equals(other.method) && bci == other.bci;
+    }
+
+    public CallSite findCallSite(ArrayDeque<CallSite> sites) {
+        // Locate a late inline call site. Multiple chains of
+        // identical call sites with the same method name/bci are
+        // possible so we have to try them all until we find the late
+        // inline call site that has a matching inline id.
+        CallSite site = sites.pop();
+        for (CallSite c : calls) {
+            if (c.matches(site)) {
+                if (!sites.isEmpty()) {
+                    CallSite res = c.findCallSite(sites);
+                    if (res != null) {
+                        sites.push(site);
+                        return res;
+                    }
+                } else {
+                    sites.push(site);
+                    return c;
+                }
+            }
+        }
+        sites.push(site);
+        return null;
+    }
+
+    public long getInlineId() {
+        return inlineId;
+    }
+
+    public void setInlineId(long inlineId) {
+        this.inlineId = inlineId;
+    }
 }
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java	Thu Apr 17 13:50:26 2014 -0400
@@ -31,6 +31,7 @@
 
 import java.io.FileReader;
 import java.io.Reader;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -144,9 +145,12 @@
     private Stack<CallSite> scopes = new Stack<CallSite>();
     private Compilation compile;
     private CallSite site;
+    private CallSite methodHandleSite;
     private Stack<Phase> phaseStack = new Stack<Phase>();
     private UncommonTrapEvent currentTrap;
-    private Stack<CallSite> late_inline_scope;
+    private Stack<CallSite> lateInlineScope;
+    private boolean lateInlining;
+
 
     long parseLong(String l) {
         try {
@@ -330,18 +334,61 @@
             }
             methods.put(id, m);
         } else if (qname.equals("call")) {
-            site = new CallSite(bci, method(search(atts, "method")));
+            if (methodHandleSite != null) {
+                methodHandleSite = null;
+            }
+            Method m = method(search(atts, "method"));
+            if (lateInlining && scopes.size() == 0) {
+                // re-attempting already seen call site (late inlining for MH invokes)
+                if (m != site.getMethod()) {
+                    if (bci != site.getBci()) {
+                        System.out.println(m + " bci: " + bci);
+                        System.out.println(site.getMethod() +  " bci: " + site.getBci());
+                        throw new InternalError("bci mismatch after late inlining");
+                    }
+                    site.setMethod(m);
+                }
+            } else {
+                site = new CallSite(bci, m);
+            }
             site.setCount(Integer.parseInt(search(atts, "count", "0")));
             String receiver = atts.getValue("receiver");
             if (receiver != null) {
                 site.setReceiver(type(receiver));
                 site.setReceiver_count(Integer.parseInt(search(atts, "receiver_count")));
             }
-            scopes.peek().add(site);
+            int methodHandle = Integer.parseInt(search(atts, "method_handle_intrinsic", "0"));
+            if (lateInlining && scopes.size() == 0) {
+                // The call was added before this round of late inlining
+            } else if (methodHandle == 0) {
+                scopes.peek().add(site);
+            } else {
+                // method handle call site can be followed by another
+                // call (in case it is inlined). If that happens we
+                // discard the method handle call site. So we keep
+                // track of it but don't add it to the list yet.
+                methodHandleSite = site;
+            }
         } else if (qname.equals("regalloc")) {
             compile.setAttempts(Integer.parseInt(search(atts, "attempts")));
         } else if (qname.equals("inline_fail")) {
-            scopes.peek().last().setReason(search(atts, "reason"));
+            if (methodHandleSite != null) {
+                scopes.peek().add(methodHandleSite);
+                methodHandleSite = null;
+            }
+            if (lateInlining && scopes.size() == 0) {
+                site.setReason(search(atts, "reason"));
+                lateInlining = false;
+            } else {
+                scopes.peek().last().setReason(search(atts, "reason"));
+            }
+        } else if (qname.equals("inline_success")) {
+            if (methodHandleSite != null) {
+                throw new InternalError("method handle site should have been replaced");
+            }
+            if (lateInlining && scopes.size() == 0) {
+                site.setReason(null);
+            }
         } else if (qname.equals("failure")) {
             failureReason = search(atts, "reason");
         } else if (qname.equals("task_done")) {
@@ -371,22 +418,30 @@
                 // ignore for now
             }
         } else if (qname.equals("late_inline")) {
-            late_inline_scope = new Stack<CallSite>();
+            long inlineId = Long.parseLong(search(atts, "inline_id"));
+            lateInlineScope = new Stack<CallSite>();
             site = new CallSite(-999, method(search(atts, "method")));
-            late_inline_scope.push(site);
+            site.setInlineId(inlineId);
+            lateInlineScope.push(site);
         } else if (qname.equals("jvms")) {
             // <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/>
             if (currentTrap != null) {
                 currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci")));
-            } else if (late_inline_scope != null) {
+            } else if (lateInlineScope != null) {
                 bci = Integer.parseInt(search(atts, "bci"));
                 site = new CallSite(bci, method(search(atts, "method")));
-                late_inline_scope.push(site);
+                lateInlineScope.push(site);
             } else {
                 // Ignore <eliminate_allocation type='667'>,
                 //        <eliminate_lock lock='1'>,
                 //        <replace_string_concat arguments='2' string_alloc='0' multiple='0'>
             }
+        } else if (qname.equals("inline_id")) {
+            if (methodHandleSite != null) {
+                throw new InternalError("method handle site should have been replaced");
+            }
+            long id = Long.parseLong(search(atts, "id"));
+            site.setInlineId(id);
         } else if (qname.equals("nmethod")) {
             String id = makeId(atts);
             NMethod nm = new NMethod(Double.parseDouble(search(atts, "stamp")),
@@ -396,8 +451,18 @@
             nmethods.put(id, nm);
             events.add(nm);
         } else if (qname.equals("parse")) {
+            if (methodHandleSite != null) {
+                throw new InternalError("method handle site should have been replaced");
+            }
             Method m = method(search(atts, "method"));
-            if (scopes.size() == 0) {
+            if (lateInlining && scopes.size() == 0) {
+                if (site.getMethod() != m) {
+                    System.out.println(site.getMethod());
+                    System.out.println(m);
+                    throw new InternalError("Unexpected method mismatch during late inlining");
+                }
+            }
+            if (scopes.size() == 0 && !lateInlining) {
                 compile.setMethod(m);
                 scopes.push(site);
             } else {
@@ -427,14 +492,19 @@
         if (qname.equals("parse")) {
             indent -= 2;
             scopes.pop();
+            if (scopes.size() == 0) {
+                lateInlining = false;
+            }
         } else if (qname.equals("uncommon_trap")) {
             currentTrap = null;
         } else if (qname.equals("late_inline")) {
             // Populate late inlining info.
-
-            // late_inline scopes are specified in reverse order:
+            if (scopes.size() != 0) {
+                throw new InternalError("scopes should be empty for late inline");
+            }
+            // late inline scopes are specified in reverse order:
             // compiled method should be on top of stack.
-            CallSite caller = late_inline_scope.pop();
+            CallSite caller = lateInlineScope.pop();
             Method m = compile.getMethod();
             if (m != caller.getMethod()) {
                 System.out.println(m);
@@ -444,28 +514,42 @@
 
             // late_inline contains caller+bci info, convert it
             // to bci+callee info used by LogCompilation.
-            site = compile.getLateInlineCall();
+            CallSite lateInlineSite = compile.getLateInlineCall();
+            ArrayDeque<CallSite> thisCallScopes = new ArrayDeque<CallSite>();
             do {
                 bci = caller.getBci();
                 // Next inlined call.
-                caller = late_inline_scope.pop();
+                caller = lateInlineScope.pop();
                 CallSite callee =  new CallSite(bci, caller.getMethod());
-                site.add(callee);
-                site = callee;
-            } while (!late_inline_scope.empty());
+                callee.setInlineId(caller.getInlineId());
+                thisCallScopes.addLast(callee);
+                lateInlineSite.add(callee);
+                lateInlineSite = callee;
+            } while (!lateInlineScope.empty());
+
+            site = compile.getCall().findCallSite(thisCallScopes);
+            if (site == null) {
+                System.out.println(caller.getMethod() + " bci: " + bci);
+                throw new InternalError("couldn't find call site");
+            }
+            lateInlining = true;
 
             if (caller.getBci() != -999) {
                 System.out.println(caller.getMethod());
                 throw new InternalError("broken late_inline info");
             }
             if (site.getMethod() != caller.getMethod()) {
-                System.out.println(site.getMethod());
-                System.out.println(caller.getMethod());
-                throw new InternalError("call site and late_inline info don't match");
+                if (site.getInlineId() == caller.getInlineId()) {
+                    site.setMethod(caller.getMethod());
+                } else {
+                    System.out.println(site.getMethod());
+                    System.out.println(caller.getMethod());
+                    throw new InternalError("call site and late_inline info don't match");
+                }
             }
             // late_inline is followed by parse with scopes.size() == 0,
             // 'site' will be pushed to scopes.
-            late_inline_scope = null;
+            lateInlineScope = null;
         } else if (qname.equals("task")) {
             types.clear();
             methods.clear();
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java	Thu Apr 17 13:50:26 2014 -0400
@@ -51,15 +51,15 @@
 
     String format(int osr_bci) {
         if (osr_bci >= 0) {
-            return getHolder().replace('/', '.') + "::" + getName() + " @ " + osr_bci + " (" + getBytes() + " bytes)";
+            return getHolder() + "::" + getName() + " @ " + osr_bci + " (" + getBytes() + " bytes)";
         } else {
-            return getHolder().replace('/', '.') + "::" + getName() + " (" + getBytes() + " bytes)";
+            return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)";
         }
     }
 
     @Override
     public String toString() {
-        return getHolder().replace('/', '.') + "::" + getName() + " (" + getBytes() + " bytes)";
+        return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)";
     }
 
     public String getHolder() {
@@ -117,4 +117,14 @@
     public void setFlags(String flags) {
         this.flags = flags;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof Method) {
+            Method other = (Method)o;
+            return holder.equals(other.holder) && name.equals(other.name) &&
+                arguments.equals(other.arguments) && returnType.equals(other.returnType);
+        }
+        return false;
+    }
 }
--- a/hotspot/src/share/vm/adlc/output_h.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/adlc/output_h.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -1613,21 +1613,20 @@
     // Each instruction attribute results in a virtual call of same name.
     // The ins_cost is not handled here.
     Attribute *attr = instr->_attribs;
-    bool avoid_back_to_back = false;
+    Attribute *avoid_back_to_back_attr = NULL;
     while (attr != NULL) {
-      if (strcmp (attr->_ident, "ins_cost") != 0 &&
+      if (strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") == 0) {
+        fprintf(fp, "  virtual bool           is_TrapBasedCheckNode() const { return %s; }\n", attr->_val);
+      } else if (strcmp (attr->_ident, "ins_cost") != 0 &&
           strncmp(attr->_ident, "ins_field_", 10) != 0 &&
           // Must match function in node.hpp: return type bool, no prefix "ins_".
           strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") != 0 &&
           strcmp (attr->_ident, "ins_short_branch") != 0) {
         fprintf(fp, "  virtual int            %s() const { return %s; }\n", attr->_ident, attr->_val);
       }
-      // Check value for ins_avoid_back_to_back, and if it is true (1), set the flag
-      if (!strcmp(attr->_ident, "ins_avoid_back_to_back") != 0 && attr->int_val(*this) != 0)
-        avoid_back_to_back = true;
-      if (strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") == 0)
-        fprintf(fp, "  virtual bool           is_TrapBasedCheckNode() const { return %s; }\n", attr->_val);
-
+      if (strcmp(attr->_ident, "ins_avoid_back_to_back") == 0) {
+        avoid_back_to_back_attr = attr;
+      }
       attr = (Attribute *)attr->_next;
     }
 
@@ -1799,11 +1798,11 @@
     }
 
     // flag: if this instruction should not be generated back to back.
-    if ( avoid_back_to_back ) {
-      if ( node_flags_set ) {
-        fprintf(fp," | Flag_avoid_back_to_back");
+    if (avoid_back_to_back_attr != NULL) {
+      if (node_flags_set) {
+        fprintf(fp," | (%s)", avoid_back_to_back_attr->_val);
       } else {
-        fprintf(fp,"init_flags(Flag_avoid_back_to_back");
+        fprintf(fp,"init_flags((%s)", avoid_back_to_back_attr->_val);
         node_flags_set = true;
       }
     }
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -968,6 +968,7 @@
 
 void CodeBuffer::log_section_sizes(const char* name) {
   if (xtty != NULL) {
+    ttyLocker ttyl;
     // log info about buffer usage
     xtty->print_cr("<blob name='%s' size='%d'>", name, _total_size);
     for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -546,6 +546,7 @@
 , _code(buffer_blob)
 , _has_access_indexed(false)
 , _current_instruction(NULL)
+, _interpreter_frame_size(0)
 #ifndef PRODUCT
 , _last_instruction_printed(NULL)
 #endif // PRODUCT
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -88,6 +88,7 @@
   CodeOffsets        _offsets;
   CodeBuffer         _code;
   bool               _has_access_indexed;
+  int                _interpreter_frame_size; // Stack space needed in case of a deoptimization
 
   // compilation helpers
   void initialize();
@@ -262,6 +263,18 @@
 
   // Dump inlining replay data to the stream.
   void dump_inline_data(outputStream* out) { /* do nothing now */ }
+
+  // How much stack space would the interpreter need in case of a
+  // deoptimization (worst case)
+  void update_interpreter_frame_size(int size) {
+    if (_interpreter_frame_size < size) {
+      _interpreter_frame_size = size;
+    }
+  }
+
+  int interpreter_frame_size() const {
+    return _interpreter_frame_size;
+  }
 };
 
 
--- a/hotspot/src/share/vm/c1/c1_IR.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/c1/c1_IR.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -227,8 +227,38 @@
   _oop_map->set_oop(name);
 }
 
+// Mirror the stack size calculation in the deopt code
+// How much stack space would we need at this point in the program in
+// case of deoptimization?
+int CodeEmitInfo::interpreter_frame_size() const {
+  ValueStack* state = _stack;
+  int size = 0;
+  int callee_parameters = 0;
+  int callee_locals = 0;
+  int extra_args = state->scope()->method()->max_stack() - state->stack_size();
 
+  while (state != NULL) {
+    int locks = state->locks_size();
+    int temps = state->stack_size();
+    bool is_top_frame = (state == _stack);
+    ciMethod* method = state->scope()->method();
 
+    int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(),
+                                                                 temps + callee_parameters,
+                                                                 extra_args,
+                                                                 locks,
+                                                                 callee_parameters,
+                                                                 callee_locals,
+                                                                 is_top_frame);
+    size += frame_size;
+
+    callee_parameters = method->size_of_parameters();
+    callee_locals = method->max_locals();
+    extra_args = 0;
+    state = state->caller_state();
+  }
+  return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord;
+}
 
 // Implementation of IR
 
--- a/hotspot/src/share/vm/c1/c1_IR.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/c1/c1_IR.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -284,6 +284,8 @@
 
   bool     is_method_handle_invoke() const { return _is_method_handle_invoke;     }
   void set_is_method_handle_invoke(bool x) {        _is_method_handle_invoke = x; }
+
+  int interpreter_frame_size() const;
 };
 
 
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -190,6 +190,13 @@
   return _masm->pc();
 }
 
+// To bang the stack of this compiled method we use the stack size
+// that the interpreter would need in case of a deoptimization. This
+// removes the need to bang the stack in the deoptimization blob which
+// in turn simplifies stack overflow handling.
+int LIR_Assembler::bang_size_in_bytes() const {
+  return MAX2(initial_frame_size_in_bytes(), _compilation->interpreter_frame_size());
+}
 
 void LIR_Assembler::emit_exception_entries(ExceptionInfoList* info_list) {
   for (int i = 0; i < info_list->length(); i++) {
@@ -797,7 +804,7 @@
 
 
 void LIR_Assembler::build_frame() {
-  _masm->build_frame(initial_frame_size_in_bytes());
+  _masm->build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes());
 }
 
 
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -132,7 +132,8 @@
   int code_offset() const;
   address pc() const;
 
-  int  initial_frame_size_in_bytes();
+  int  initial_frame_size_in_bytes() const;
+  int  bang_size_in_bytes() const;
 
   // test for constants which can be encoded directly in instructions
   static bool is_small_constant(LIR_Opr opr);
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -2451,6 +2451,9 @@
     CodeEmitInfo* info = visitor.info_at(i);
     OopMap* oop_map = first_oop_map;
 
+    // compute worst case interpreter size in case of a deoptimization
+    _compilation->update_interpreter_frame_size(info->interpreter_frame_size());
+
     if (info->stack()->locks_size() != first_info->stack()->locks_size()) {
       // this info has a different number of locks then the precomputed oop map
       // (possible for lock and unlock instructions) -> compute oop map with
--- a/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -39,7 +39,7 @@
   void explicit_null_check(Register base);
 
   void inline_cache_check(Register receiver, Register iCache);
-  void build_frame(int frame_size_in_bytes);
+  void build_frame(int frame_size_in_bytes, int bang_size_in_bytes);
   void remove_frame(int frame_size_in_bytes);
 
   void unverified_entry(Register receiver, Register ic_klass);
--- a/hotspot/src/share/vm/ci/ciKlass.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/ci/ciKlass.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -237,3 +237,9 @@
 void ciKlass::print_name_on(outputStream* st) {
   name()->print_symbol_on(st);
 }
+
+const char* ciKlass::external_name() const {
+  GUARDED_VM_ENTRY(
+    return get_Klass()->external_name();
+  )
+}
--- a/hotspot/src/share/vm/ci/ciKlass.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/ci/ciKlass.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -125,6 +125,8 @@
   virtual ciKlass* exact_klass() = 0;
 
   void print_name_on(outputStream* st);
+
+  const char* external_name() const;
 };
 
 #endif // SHARE_VM_CI_CIKLASS_HPP
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -80,6 +80,7 @@
   _code_size          = h_m()->code_size();
   _intrinsic_id       = h_m()->intrinsic_id();
   _handler_count      = h_m()->exception_table_length();
+  _size_of_parameters = h_m()->size_of_parameters();
   _uses_monitors      = h_m()->access_flags().has_monitor_bytecodes();
   _balanced_monitors  = !_uses_monitors || h_m()->access_flags().is_monitor_matching();
   _is_c1_compilable   = !h_m()->is_not_c1_compilable();
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -71,6 +71,7 @@
   int _interpreter_invocation_count;
   int _interpreter_throwout_count;
   int _instructions_size;
+  int _size_of_parameters;
 
   bool _uses_monitors;
   bool _balanced_monitors;
@@ -166,6 +167,7 @@
   int exception_table_length() const             { check_is_loaded(); return _handler_count; }
   int interpreter_invocation_count() const       { check_is_loaded(); return _interpreter_invocation_count; }
   int interpreter_throwout_count() const         { check_is_loaded(); return _interpreter_throwout_count; }
+  int size_of_parameters() const                 { check_is_loaded(); return _size_of_parameters; }
 
   // Code size for inlining decisions.
   int code_size_for_inlining();
@@ -241,7 +243,6 @@
 
   ciField*      get_field_at_bci( int bci, bool &will_link);
   ciMethod*     get_method_at_bci(int bci, bool &will_link, ciSignature* *declared_signature);
-
   // Given a certain calling environment, find the monomorphic target
   // for the call.  Return NULL if the call is not monomorphic in
   // its calling environment.
--- a/hotspot/src/share/vm/ci/ciSymbol.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/ci/ciSymbol.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -123,6 +123,10 @@
   GUARDED_VM_ENTRY(get_symbol()->print_symbol_on(st);)
 }
 
+const char* ciSymbol::as_klass_external_name() const {
+  GUARDED_VM_ENTRY(return get_symbol()->as_klass_external_name(););
+}
+
 // ------------------------------------------------------------------
 // ciSymbol::make_impl
 //
--- a/hotspot/src/share/vm/ci/ciSymbol.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/ci/ciSymbol.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -90,6 +90,7 @@
   void print_symbol() {
     print_symbol_on(tty);
   }
+  const char* as_klass_external_name() const;
 
   // Make a ciSymbol from a C string.
   // Consider adding to vmSymbols.hpp instead of using this constructor.
--- a/hotspot/src/share/vm/compiler/compileLog.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/compiler/compileLog.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -106,7 +106,7 @@
     if (mobj->is_klass()) {
       ciKlass* klass = mobj->as_klass();
       begin_elem("klass id='%d'", id);
-      name(klass->name());
+      name(klass);
       if (!klass->is_loaded()) {
         print(" unloaded='1'");
       } else {
@@ -171,6 +171,15 @@
   print("'");
 }
 
+void CompileLog::name(ciKlass* k) {
+  print(" name='");
+  if (!k->is_loaded()) {
+    text()->print(k->name()->as_klass_external_name());
+  } else {
+    text()->print(k->external_name());
+  }
+  print("'");
+}
 
 // ------------------------------------------------------------------
 // CompileLog::clear_identities
--- a/hotspot/src/share/vm/compiler/compileLog.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/compiler/compileLog.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -28,6 +28,7 @@
 #include "utilities/xmlstream.hpp"
 
 class ciBaseObject;
+class ciKlass;
 class ciObject;
 class ciMetadata;
 class ciSymbol;
@@ -72,6 +73,7 @@
 
   void          name(ciSymbol* s);               // name='s'
   void          name(Symbol* s)                  { xmlStream::name(s); }
+  void          name(ciKlass* k);
 
   // Output an object description, return obj->ident().
   int           identify(ciBaseObject* obj);
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -181,30 +181,16 @@
   // Deoptimization should reexecute this bytecode
   static bool    bytecode_should_reexecute(Bytecodes::Code code);
 
-  // share implementation of size_activation and layout_activation:
-  static int        size_activation(Method* method,
+  // deoptimization support
+  static int        size_activation(int max_stack,
                                     int temps,
-                                    int popframe_args,
+                                    int extra_args,
                                     int monitors,
-                                    int caller_actual_parameters,
                                     int callee_params,
                                     int callee_locals,
-                                    bool is_top_frame,
-                                    bool is_bottom_frame) {
-    return layout_activation(method,
-                             temps,
-                             popframe_args,
-                             monitors,
-                             caller_actual_parameters,
-                             callee_params,
-                             callee_locals,
-                             (frame*)NULL,
-                             (frame*)NULL,
-                             is_top_frame,
-                             is_bottom_frame);
-  }
+                                    bool is_top_frame);
 
-  static int       layout_activation(Method* method,
+  static void      layout_activation(Method* method,
                                      int temps,
                                      int popframe_args,
                                      int monitors,
--- a/hotspot/src/share/vm/opto/callGenerator.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -266,14 +266,17 @@
 
 // Allow inlining decisions to be delayed
 class LateInlineCallGenerator : public DirectCallGenerator {
+ private:
+  // unique id for log compilation
+  jlong _unique_id;
+
  protected:
   CallGenerator* _inline_cg;
-
   virtual bool do_late_inline_check(JVMState* jvms) { return true; }
 
  public:
   LateInlineCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
-    DirectCallGenerator(method, true), _inline_cg(inline_cg) {}
+    DirectCallGenerator(method, true), _inline_cg(inline_cg), _unique_id(0) {}
 
   virtual bool is_late_inline() const { return true; }
 
@@ -283,6 +286,8 @@
   virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
     Compile *C = Compile::current();
 
+    C->log_inline_id(this);
+
     // Record that this call site should be revisited once the main
     // parse is finished.
     if (!is_mh_late_inline()) {
@@ -304,6 +309,14 @@
     C->print_inlining_move_to(this);
     C->print_inlining_update_delayed(this);
   }
+
+  virtual void set_unique_id(jlong id) {
+    _unique_id = id;
+  }
+
+  virtual jlong unique_id() const {
+    return _unique_id;
+  }
 };
 
 void LateInlineCallGenerator::do_late_inline() {
@@ -368,6 +381,8 @@
 
   C->print_inlining_move_to(this);
 
+  C->log_late_inline(this);
+
   // This check is done here because for_method_handle_inline() method
   // needs jvms for inlined state.
   if (!do_late_inline_check(jvms)) {
@@ -375,17 +390,6 @@
     return;
   }
 
-  CompileLog* log = C->log();
-  if (log != NULL) {
-    log->head("late_inline method='%d'", log->identify(method()));
-    JVMState* p = jvms;
-    while (p != NULL) {
-      log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
-      p = p->caller();
-    }
-    log->tail("late_inline");
-  }
-
   // Setup default node notes to be picked up by the inlining
   Node_Notes* old_nn = C->default_node_notes();
   if (old_nn != NULL) {
@@ -438,11 +442,12 @@
   virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
     JVMState* new_jvms = LateInlineCallGenerator::generate(jvms, parent_parser);
 
+    Compile* C = Compile::current();
     if (_input_not_const) {
       // inlining won't be possible so no need to enqueue right now.
       call_node()->set_generator(this);
     } else {
-      Compile::current()->add_late_inline(this);
+      C->add_late_inline(this);
     }
     return new_jvms;
   }
@@ -483,6 +488,9 @@
 
   virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
     Compile *C = Compile::current();
+
+    C->log_inline_id(this);
+
     C->add_string_late_inline(this);
 
     JVMState* new_jvms =  DirectCallGenerator::generate(jvms, parent_parser);
@@ -505,6 +513,8 @@
   virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
     Compile *C = Compile::current();
 
+    C->log_inline_id(this);
+
     C->add_boxing_late_inline(this);
 
     JVMState* new_jvms =  DirectCallGenerator::generate(jvms, parent_parser);
@@ -786,6 +796,7 @@
       } else {
         const char* msg = "receiver not constant";
         if (PrintInlining)  C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
+        C->log_inline_failure(msg);
       }
     }
     break;
@@ -858,6 +869,7 @@
       } else {
         const char* msg = "member_name not constant";
         if (PrintInlining)  C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
+        C->log_inline_failure(msg);
       }
     }
     break;
--- a/hotspot/src/share/vm/opto/callGenerator.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/callGenerator.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -84,6 +84,9 @@
 
   virtual CallStaticJavaNode* call_node() const { ShouldNotReachHere(); return NULL; }
 
+  virtual void set_unique_id(jlong id)          { fatal("unique id only for late inlines"); };
+  virtual jlong unique_id() const               { fatal("unique id only for late inlines"); return 0; };
+
   // Note:  It is possible for a CG to be both inline and virtual.
   // (The hashCode intrinsic does a vtable check and an inlined fast path.)
 
--- a/hotspot/src/share/vm/opto/callnode.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -608,6 +608,39 @@
   }
 }
 
+// Mirror the stack size calculation in the deopt code
+// How much stack space would we need at this point in the program in
+// case of deoptimization?
+int JVMState::interpreter_frame_size() const {
+  const JVMState* jvms = this;
+  int size = 0;
+  int callee_parameters = 0;
+  int callee_locals = 0;
+  int extra_args = method()->max_stack() - stk_size();
+
+  while (jvms != NULL) {
+    int locks = jvms->nof_monitors();
+    int temps = jvms->stk_size();
+    bool is_top_frame = (jvms == this);
+    ciMethod* method = jvms->method();
+
+    int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(),
+                                                                 temps + callee_parameters,
+                                                                 extra_args,
+                                                                 locks,
+                                                                 callee_parameters,
+                                                                 callee_locals,
+                                                                 is_top_frame);
+    size += frame_size;
+
+    callee_parameters = method->size_of_parameters();
+    callee_locals = method->max_locals();
+    extra_args = 0;
+    jvms = jvms->caller();
+  }
+  return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord;
+}
+
 //=============================================================================
 uint CallNode::cmp( const Node &n ) const
 { return _tf == ((CallNode&)n)._tf && _jvms == ((CallNode&)n)._jvms; }
--- a/hotspot/src/share/vm/opto/callnode.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/callnode.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -300,6 +300,7 @@
   JVMState* clone_shallow(Compile* C) const; // retains uncloned caller
   void      set_map_deep(SafePointNode *map);// reset map for all callers
   void      adapt_position(int delta);       // Adapt offsets in in-array after adding an edge.
+  int       interpreter_frame_size() const;
 
 #ifndef PRODUCT
   void      format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const;
--- a/hotspot/src/share/vm/opto/compile.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/compile.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -440,6 +440,14 @@
   return words;
 }
 
+// To bang the stack of this compiled method we use the stack size
+// that the interpreter would need in case of a deoptimization. This
+// removes the need to bang the stack in the deoptimization blob which
+// in turn simplifies stack overflow handling.
+int Compile::bang_size_in_bytes() const {
+  return MAX2(_interpreter_frame_size, frame_size_in_bytes());
+}
+
 // ============================================================================
 //------------------------------CompileWrapper---------------------------------
 class CompileWrapper : public StackObj {
@@ -664,7 +672,8 @@
                   _print_inlining_list(NULL),
                   _print_inlining_stream(NULL),
                   _print_inlining_idx(0),
-                  _preserve_jvm_state(0) {
+                  _preserve_jvm_state(0),
+                  _interpreter_frame_size(0) {
   C = this;
 
   CompileWrapper cw(this);
@@ -969,7 +978,8 @@
     _print_inlining_stream(NULL),
     _print_inlining_idx(0),
     _preserve_jvm_state(0),
-    _allowed_reasons(0) {
+    _allowed_reasons(0),
+    _interpreter_frame_size(0) {
   C = this;
 
 #ifndef PRODUCT
@@ -3078,8 +3088,12 @@
       Node* m = n->in(i);
       ++i;
       if (m != NULL && !frc._visited.test_set(m->_idx)) {
-        if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL)
+        if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL) {
+          // compute worst case interpreter size in case of a deoptimization
+          update_interpreter_frame_size(m->as_SafePoint()->jvms()->interpreter_frame_size());
+
           sfpt.push(m);
+        }
         cnt = m->req();
         nstack.push(n, i); // put on stack parent and next input's index
         n = m;
@@ -3851,7 +3865,7 @@
 
 void Compile::dump_inlining() {
   bool do_print_inlining = print_inlining() || print_intrinsics();
-  if (do_print_inlining) {
+  if (do_print_inlining || log() != NULL) {
     // Print inlining message for candidates that we couldn't inline
     // for lack of space
     for (int i = 0; i < _late_inlines.length(); i++) {
@@ -3861,6 +3875,7 @@
         if (do_print_inlining) {
           cg->print_inlining_late(msg);
         }
+        log_late_inline_failure(cg, msg);
       }
     }
   }
@@ -3871,6 +3886,48 @@
   }
 }
 
+void Compile::log_late_inline(CallGenerator* cg) {
+  if (log() != NULL) {
+    log()->head("late_inline method='%d'  inline_id='" JLONG_FORMAT "'", log()->identify(cg->method()),
+                cg->unique_id());
+    JVMState* p = cg->call_node()->jvms();
+    while (p != NULL) {
+      log()->elem("jvms bci='%d' method='%d'", p->bci(), log()->identify(p->method()));
+      p = p->caller();
+    }
+    log()->tail("late_inline");
+  }
+}
+
+void Compile::log_late_inline_failure(CallGenerator* cg, const char* msg) {
+  log_late_inline(cg);
+  if (log() != NULL) {
+    log()->inline_fail(msg);
+  }
+}
+
+void Compile::log_inline_id(CallGenerator* cg) {
+  if (log() != NULL) {
+    // The LogCompilation tool needs a unique way to identify late
+    // inline call sites. This id must be unique for this call site in
+    // this compilation. Try to have it unique across compilations as
+    // well because it can be convenient when grepping through the log
+    // file.
+    // Distinguish OSR compilations from others in case CICountOSR is
+    // on.
+    jlong id = ((jlong)unique()) + (((jlong)compile_id()) << 33) + (CICountOSR && is_osr_compilation() ? ((jlong)1) << 32 : 0);
+    cg->set_unique_id(id);
+    log()->elem("inline_id id='" JLONG_FORMAT "'", id);
+  }
+}
+
+void Compile::log_inline_failure(const char* msg) {
+  if (C->log() != NULL) {
+    C->log()->inline_fail(msg);
+  }
+}
+
+
 // Dump inlining replay data to the stream.
 // Don't change thread state and acquire any locks.
 void Compile::dump_inline_data(outputStream* out) {
@@ -4048,8 +4105,8 @@
     worklist.push(root());
     for (uint next = 0; next < worklist.size(); ++next) {
       Node *n  = worklist.at(next);
-      const Type* t = igvn.type(n);
-      assert(t == t->remove_speculative(), "no more speculative types");
+      const Type* t = igvn.type_or_null(n);
+      assert((t == NULL) || (t == t->remove_speculative()), "no more speculative types");
       if (n->is_Type()) {
         t = n->as_Type()->type();
         assert(t == t->remove_speculative(), "no more speculative types");
--- a/hotspot/src/share/vm/opto/compile.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/compile.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -440,6 +440,8 @@
   void print_inlining_push();
   PrintInliningBuffer& print_inlining_current();
 
+  void log_late_inline_failure(CallGenerator* cg, const char* msg);
+
  public:
 
   outputStream* print_inlining_stream() const {
@@ -459,6 +461,10 @@
     print_inlining_stream()->print(ss.as_string());
   }
 
+  void log_late_inline(CallGenerator* cg);
+  void log_inline_id(CallGenerator* cg);
+  void log_inline_failure(const char* msg);
+
   void* replay_inline_data() const { return _replay_inline_data; }
 
   // Dump inlining replay data to the stream.
@@ -478,6 +484,7 @@
   RegMask               _FIRST_STACK_mask;      // All stack slots usable for spills (depends on frame layout)
   Arena*                _indexSet_arena;        // control IndexSet allocation within PhaseChaitin
   void*                 _indexSet_free_block_list; // free list of IndexSet bit blocks
+  int                   _interpreter_frame_size;
 
   uint                  _node_bundling_limit;
   Bundle*               _node_bundling_base;    // Information for instruction bundling
@@ -935,6 +942,7 @@
   PhaseRegAlloc*    regalloc()                  { return _regalloc; }
   int               frame_slots() const         { return _frame_slots; }
   int               frame_size_in_words() const; // frame_slots in units of the polymorphic 'words'
+  int               frame_size_in_bytes() const { return _frame_slots << LogBytesPerInt; }
   RegMask&          FIRST_STACK_mask()          { return _FIRST_STACK_mask; }
   Arena*            indexSet_arena()            { return _indexSet_arena; }
   void*             indexSet_free_block_list()  { return _indexSet_free_block_list; }
@@ -946,6 +954,13 @@
   bool          need_stack_bang(int frame_size_in_bytes) const;
   bool          need_register_stack_bang() const;
 
+  void  update_interpreter_frame_size(int size) {
+    if (_interpreter_frame_size < size) {
+      _interpreter_frame_size = size;
+    }
+  }
+  int           bang_size_in_bytes() const;
+
   void          set_matcher(Matcher* m)                 { _matcher = m; }
 //void          set_regalloc(PhaseRegAlloc* ra)           { _regalloc = ra; }
   void          set_indexSet_arena(Arena* a)            { _indexSet_arena = a; }
--- a/hotspot/src/share/vm/opto/doCall.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -104,6 +104,9 @@
         log->print(" receiver2='%d' receiver2_count='%d'", r2id, profile.receiver_count(1));
       }
     }
+    if (callee->is_method_handle_intrinsic()) {
+      log->print(" method_handle_intrinsic='1'");
+    }
     log->end_elem();
   }
 
@@ -296,6 +299,7 @@
   if (call_does_dispatch) {
     const char* msg = "virtual call";
     if (PrintInlining) print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
+    C->log_inline_failure(msg);
     return CallGenerator::for_virtual_call(callee, vtable_index);
   } else {
     // Class Hierarchy Analysis or Type Profile reveals a unique target,
--- a/hotspot/src/share/vm/opto/escape.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/escape.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -711,7 +711,7 @@
         Node *val = n->in(MemNode::ValueIn);
         PointsToNode* ptn = ptnode_adr(val->_idx);
         assert(ptn != NULL, "node should be registered");
-        ptn->set_escape_state(PointsToNode::GlobalEscape);
+        set_escape_state(ptn, PointsToNode::GlobalEscape);
         // Add edge to object for unsafe access with offset.
         PointsToNode* adr_ptn = ptnode_adr(adr->_idx);
         assert(adr_ptn != NULL, "node should be registered");
--- a/hotspot/src/share/vm/opto/loopTransform.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -1150,6 +1150,7 @@
   // Now force out all loop-invariant dominating tests.  The optimizer
   // finds some, but we _know_ they are all useless.
   peeled_dom_test_elim(loop,old_new);
+  loop->record_for_igvn();
 }
 
 //------------------------------is_invariant-----------------------------
--- a/hotspot/src/share/vm/opto/loopnode.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/loopnode.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -3172,17 +3172,16 @@
   bool had_error = false;
 #ifdef ASSERT
   if (early != C->root()) {
-    // Make sure that there's a dominance path from use to LCA
-    Node* d = use;
-    while (d != LCA) {
-      d = idom(d);
+    // Make sure that there's a dominance path from LCA to early
+    Node* d = LCA;
+    while (d != early) {
       if (d == C->root()) {
-        tty->print_cr("*** Use %d isn't dominated by def %s", use->_idx, n->_idx);
-        n->dump();
-        use->dump();
+        dump_bad_graph("Bad graph detected in compute_lca_of_uses", n, early, LCA);
+        tty->print_cr("*** Use %d isn't dominated by def %d ***", use->_idx, n->_idx);
         had_error = true;
         break;
       }
+      d = idom(d);
     }
   }
 #endif
@@ -3435,6 +3434,13 @@
     _igvn._worklist.push(n);  // Maybe we'll normalize it, if no more loops.
   }
 
+#ifdef ASSERT
+  if (_verify_only && !n->is_CFG()) {
+    // Check def-use domination.
+    compute_lca_of_uses(n, get_ctrl(n), true /* verify */);
+  }
+#endif
+
   // CFG and pinned nodes already handled
   if( n->in(0) ) {
     if( n->in(0)->is_top() ) return; // Dead?
--- a/hotspot/src/share/vm/opto/loopopts.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/loopopts.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -2700,6 +2700,7 @@
   // Inhibit more partial peeling on this loop
   new_head_clone->set_partial_peel_loop();
   C->set_major_progress();
+  loop->record_for_igvn();
 
 #if !defined(PRODUCT)
   if (TracePartialPeeling) {
--- a/hotspot/src/share/vm/opto/machnode.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/machnode.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -210,7 +210,14 @@
   bool may_be_short_branch() const { return (flags() & Flag_may_be_short_branch) != 0; }
 
   // Avoid back to back some instructions on some CPUs.
-  bool avoid_back_to_back() const { return (flags() & Flag_avoid_back_to_back) != 0; }
+  enum AvoidBackToBackFlag { AVOID_NONE = 0,
+                             AVOID_BEFORE = Flag_avoid_back_to_back_before,
+                             AVOID_AFTER = Flag_avoid_back_to_back_after,
+                             AVOID_BEFORE_AND_AFTER = AVOID_BEFORE | AVOID_AFTER };
+
+  bool avoid_back_to_back(AvoidBackToBackFlag flag_value) const {
+    return (flags() & flag_value) == flag_value;
+  }
 
   // instruction implemented with a call
   bool has_call() const { return (flags() & Flag_has_call) != 0; }
--- a/hotspot/src/share/vm/opto/node.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/node.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -645,17 +645,18 @@
 
   // Flags are sorted by usage frequency.
   enum NodeFlags {
-    Flag_is_Copy             = 0x01, // should be first bit to avoid shift
-    Flag_rematerialize       = Flag_is_Copy << 1,
+    Flag_is_Copy                     = 0x01, // should be first bit to avoid shift
+    Flag_rematerialize               = Flag_is_Copy << 1,
     Flag_needs_anti_dependence_check = Flag_rematerialize << 1,
-    Flag_is_macro            = Flag_needs_anti_dependence_check << 1,
-    Flag_is_Con              = Flag_is_macro << 1,
-    Flag_is_cisc_alternate   = Flag_is_Con << 1,
-    Flag_is_dead_loop_safe   = Flag_is_cisc_alternate << 1,
-    Flag_may_be_short_branch = Flag_is_dead_loop_safe << 1,
-    Flag_avoid_back_to_back  = Flag_may_be_short_branch << 1,
-    Flag_has_call            = Flag_avoid_back_to_back << 1,
-    Flag_is_expensive        = Flag_has_call << 1,
+    Flag_is_macro                    = Flag_needs_anti_dependence_check << 1,
+    Flag_is_Con                      = Flag_is_macro << 1,
+    Flag_is_cisc_alternate           = Flag_is_Con << 1,
+    Flag_is_dead_loop_safe           = Flag_is_cisc_alternate << 1,
+    Flag_may_be_short_branch         = Flag_is_dead_loop_safe << 1,
+    Flag_avoid_back_to_back_before   = Flag_may_be_short_branch << 1,
+    Flag_avoid_back_to_back_after    = Flag_avoid_back_to_back_before << 1,
+    Flag_has_call                    = Flag_avoid_back_to_back_after << 1,
+    Flag_is_expensive                = Flag_has_call << 1,
     _max_flags = (Flag_is_expensive << 1) - 1 // allow flags combination
   };
 
--- a/hotspot/src/share/vm/opto/output.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/output.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -165,8 +165,13 @@
   // Determine if we need to generate a stack overflow check.
   // Do it if the method is not a stub function and
   // has java calls or has frame size > vm_page_size/8.
+  // The debug VM checks that deoptimization doesn't trigger an
+  // unexpected stack overflow (compiled method stack banging should
+  // guarantee it doesn't happen) so we always need the stack bang in
+  // a debug VM.
   return (UseStackBanging && stub_function() == NULL &&
-          (has_java_calls() || frame_size_in_bytes > os::vm_page_size()>>3));
+          (has_java_calls() || frame_size_in_bytes > os::vm_page_size()>>3
+           DEBUG_ONLY(|| true)));
 }
 
 bool Compile::need_register_stack_bang() const {
@@ -411,7 +416,7 @@
             blk_size += nop_size;
           }
         }
-        if (mach->avoid_back_to_back()) {
+        if (mach->avoid_back_to_back(MachNode::AVOID_BEFORE)) {
           // Nop is inserted between "avoid back to back" instructions.
           // ScheduleAndBundle() can rearrange nodes in a block,
           // check for all offsets inside this block.
@@ -439,7 +444,7 @@
         last_call_adr = blk_starts[i]+blk_size;
       }
       // Remember end of avoid_back_to_back offset
-      if (nj->is_Mach() && nj->as_Mach()->avoid_back_to_back()) {
+      if (nj->is_Mach() && nj->as_Mach()->avoid_back_to_back(MachNode::AVOID_AFTER)) {
         last_avoid_back_to_back_adr = blk_starts[i]+blk_size;
       }
     }
@@ -525,11 +530,11 @@
           int new_size = replacement->size(_regalloc);
           int diff     = br_size - new_size;
           assert(diff >= (int)nop_size, "short_branch size should be smaller");
-          // Conservatively take into accound padding between
+          // Conservatively take into account padding between
           // avoid_back_to_back branches. Previous branch could be
           // converted into avoid_back_to_back branch during next
           // rounds.
-          if (needs_padding && replacement->avoid_back_to_back()) {
+          if (needs_padding && replacement->avoid_back_to_back(MachNode::AVOID_BEFORE)) {
             jmp_offset[i] += nop_size;
             diff -= nop_size;
           }
@@ -548,7 +553,7 @@
         }
       } // (mach->may_be_short_branch())
       if (mach != NULL && (mach->may_be_short_branch() ||
-                           mach->avoid_back_to_back())) {
+                           mach->avoid_back_to_back(MachNode::AVOID_AFTER))) {
         last_may_be_short_branch_adr = blk_starts[i] + jmp_offset[i] + jmp_size[i];
       }
       blk_starts[i+1] -= adjust_block_start;
@@ -1313,7 +1318,7 @@
         if (is_sfn && !is_mcall && padding == 0 && current_offset == last_call_offset) {
           padding = nop_size;
         }
-        if (padding == 0 && mach->avoid_back_to_back() &&
+        if (padding == 0 && mach->avoid_back_to_back(MachNode::AVOID_BEFORE) &&
             current_offset == last_avoid_back_to_back_offset) {
           // Avoid back to back some instructions.
           padding = nop_size;
@@ -1407,7 +1412,7 @@
               int new_size = replacement->size(_regalloc);
               assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller");
               // Insert padding between avoid_back_to_back branches.
-              if (needs_padding && replacement->avoid_back_to_back()) {
+              if (needs_padding && replacement->avoid_back_to_back(MachNode::AVOID_BEFORE)) {
                 MachNode *nop = new (this) MachNopNode();
                 block->insert_node(nop, j++);
                 _cfg->map_node_to_block(nop, block);
@@ -1515,7 +1520,7 @@
         last_call_offset = current_offset;
       }
 
-      if (n->is_Mach() && n->as_Mach()->avoid_back_to_back()) {
+      if (n->is_Mach() && n->as_Mach()->avoid_back_to_back(MachNode::AVOID_AFTER)) {
         // Avoid back to back some instructions.
         last_avoid_back_to_back_offset = current_offset;
       }
--- a/hotspot/src/share/vm/opto/phaseX.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/phaseX.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -831,154 +831,111 @@
   }
 }
 
+/**
+ * Initialize worklist for each node.
+ */
+void PhaseIterGVN::init_worklist(Node* first) {
+  Unique_Node_List to_process;
+  to_process.push(first);
+
+  while (to_process.size() > 0) {
+    Node* n = to_process.pop();
+    if (!_worklist.member(n)) {
+      _worklist.push(n);
+
+      uint cnt = n->req();
+      for(uint i = 0; i < cnt; i++) {
+        Node* m = n->in(i);
+        if (m != NULL) {
+          to_process.push(m);
+        }
+      }
+    }
+  }
+}
 
 #ifndef PRODUCT
 void PhaseIterGVN::verify_step(Node* n) {
-  _verify_window[_verify_counter % _verify_window_size] = n;
-  ++_verify_counter;
-  ResourceMark rm;
-  ResourceArea *area = Thread::current()->resource_area();
-  VectorSet old_space(area), new_space(area);
-  if (C->unique() < 1000 ||
-      0 == _verify_counter % (C->unique() < 10000 ? 10 : 100)) {
-    ++_verify_full_passes;
-    Node::verify_recur(C->root(), -1, old_space, new_space);
-  }
-  const int verify_depth = 4;
-  for ( int i = 0; i < _verify_window_size; i++ ) {
-    Node* n = _verify_window[i];
-    if ( n == NULL )  continue;
-    if( n->in(0) == NodeSentinel ) {  // xform_idom
-      _verify_window[i] = n->in(1);
-      --i; continue;
+  if (VerifyIterativeGVN) {
+    _verify_window[_verify_counter % _verify_window_size] = n;
+    ++_verify_counter;
+    ResourceMark rm;
+    ResourceArea* area = Thread::current()->resource_area();
+    VectorSet old_space(area), new_space(area);
+    if (C->unique() < 1000 ||
+        0 == _verify_counter % (C->unique() < 10000 ? 10 : 100)) {
+      ++_verify_full_passes;
+      Node::verify_recur(C->root(), -1, old_space, new_space);
     }
-    // Typical fanout is 1-2, so this call visits about 6 nodes.
-    Node::verify_recur(n, verify_depth, old_space, new_space);
-  }
-}
-#endif
-
-
-//------------------------------init_worklist----------------------------------
-// Initialize worklist for each node.
-void PhaseIterGVN::init_worklist( Node *n ) {
-  if( _worklist.member(n) ) return;
-  _worklist.push(n);
-  uint cnt = n->req();
-  for( uint i =0 ; i < cnt; i++ ) {
-    Node *m = n->in(i);
-    if( m ) init_worklist(m);
+    const int verify_depth = 4;
+    for ( int i = 0; i < _verify_window_size; i++ ) {
+      Node* n = _verify_window[i];
+      if ( n == NULL )  continue;
+      if( n->in(0) == NodeSentinel ) {  // xform_idom
+        _verify_window[i] = n->in(1);
+        --i; continue;
+      }
+      // Typical fanout is 1-2, so this call visits about 6 nodes.
+      Node::verify_recur(n, verify_depth, old_space, new_space);
+    }
   }
 }
 
-//------------------------------optimize---------------------------------------
-void PhaseIterGVN::optimize() {
-  debug_only(uint num_processed  = 0;);
-#ifndef PRODUCT
-  {
-    _verify_counter = 0;
-    _verify_full_passes = 0;
-    for ( int i = 0; i < _verify_window_size; i++ ) {
-      _verify_window[i] = NULL;
+void PhaseIterGVN::trace_PhaseIterGVN(Node* n, Node* nn, const Type* oldtype) {
+  if (TraceIterativeGVN) {
+    uint wlsize = _worklist.size();
+    const Type* newtype = type_or_null(n);
+    if (nn != n) {
+      // print old node
+      tty->print("< ");
+      if (oldtype != newtype && oldtype != NULL) {
+        oldtype->dump();
+      }
+      do { tty->print("\t"); } while (tty->position() < 16);
+      tty->print("<");
+      n->dump();
+    }
+    if (oldtype != newtype || nn != n) {
+      // print new node and/or new type
+      if (oldtype == NULL) {
+        tty->print("* ");
+      } else if (nn != n) {
+        tty->print("> ");
+      } else {
+        tty->print("= ");
+      }
+      if (newtype == NULL) {
+        tty->print("null");
+      } else {
+        newtype->dump();
+      }
+      do { tty->print("\t"); } while (tty->position() < 16);
+      nn->dump();
+    }
+    if (Verbose && wlsize < _worklist.size()) {
+      tty->print("  Push {");
+      while (wlsize != _worklist.size()) {
+        Node* pushed = _worklist.at(wlsize++);
+        tty->print(" %d", pushed->_idx);
+      }
+      tty->print_cr(" }");
+    }
+    if (nn != n) {
+      // ignore n, it might be subsumed
+      verify_step((Node*) NULL);
     }
   }
-#endif
-
-#ifdef ASSERT
-  Node* prev = NULL;
-  uint rep_cnt = 0;
-#endif
-  uint loop_count = 0;
-
-  // Pull from worklist; transform node;
-  // If node has changed: update edge info and put uses on worklist.
-  while( _worklist.size() ) {
-    if (C->check_node_count(NodeLimitFudgeFactor * 2,
-                            "out of nodes optimizing method")) {
-      return;
-    }
-    Node *n  = _worklist.pop();
-    if (++loop_count >= K * C->live_nodes()) {
-      debug_only(n->dump(4);)
-      assert(false, "infinite loop in PhaseIterGVN::optimize");
-      C->record_method_not_compilable("infinite loop in PhaseIterGVN::optimize");
-      return;
-    }
-#ifdef ASSERT
-    if (n == prev) {
-      if (++rep_cnt > 3) {
-        n->dump(4);
-        assert(false, "loop in Ideal transformation");
-      }
-    } else {
-      rep_cnt = 0;
-    }
-    prev = n;
-#endif
-    if (TraceIterativeGVN && Verbose) {
-      tty->print("  Pop ");
-      NOT_PRODUCT( n->dump(); )
-      debug_only(if( (num_processed++ % 100) == 0 ) _worklist.print_set();)
-    }
-
-    if (n->outcnt() != 0) {
-
-#ifndef PRODUCT
-      uint wlsize = _worklist.size();
-      const Type* oldtype = type_or_null(n);
-#endif //PRODUCT
-
-      Node *nn = transform_old(n);
+}
 
-#ifndef PRODUCT
-      if (TraceIterativeGVN) {
-        const Type* newtype = type_or_null(n);
-        if (nn != n) {
-          // print old node
-          tty->print("< ");
-          if (oldtype != newtype && oldtype != NULL) {
-            oldtype->dump();
-          }
-          do { tty->print("\t"); } while (tty->position() < 16);
-          tty->print("<");
-          n->dump();
-        }
-        if (oldtype != newtype || nn != n) {
-          // print new node and/or new type
-          if (oldtype == NULL) {
-            tty->print("* ");
-          } else if (nn != n) {
-            tty->print("> ");
-          } else {
-            tty->print("= ");
-          }
-          if (newtype == NULL) {
-            tty->print("null");
-          } else {
-            newtype->dump();
-          }
-          do { tty->print("\t"); } while (tty->position() < 16);
-          nn->dump();
-        }
-        if (Verbose && wlsize < _worklist.size()) {
-          tty->print("  Push {");
-          while (wlsize != _worklist.size()) {
-            Node* pushed = _worklist.at(wlsize++);
-            tty->print(" %d", pushed->_idx);
-          }
-          tty->print_cr(" }");
-        }
-      }
-      if( VerifyIterativeGVN && nn != n ) {
-        verify_step((Node*) NULL);  // ignore n, it might be subsumed
-      }
-#endif
-    } else if (!n->is_top()) {
-      remove_dead_node(n);
-    }
+void PhaseIterGVN::init_verifyPhaseIterGVN() {
+  _verify_counter = 0;
+  _verify_full_passes = 0;
+  for (int i = 0; i < _verify_window_size; i++) {
+    _verify_window[i] = NULL;
   }
+}
 
-#ifndef PRODUCT
+void PhaseIterGVN::verify_PhaseIterGVN() {
   C->verify_graph_edges();
   if( VerifyOpto && allow_progress() ) {
     // Must turn off allow_progress to enable assert and break recursion
@@ -998,21 +955,78 @@
       igvn2.set_allow_progress(true);
     }
   }
-  if ( VerifyIterativeGVN && PrintOpto ) {
-    if ( _verify_counter == _verify_full_passes )
+  if (VerifyIterativeGVN && PrintOpto) {
+    if (_verify_counter == _verify_full_passes) {
       tty->print_cr("VerifyIterativeGVN: %d transforms and verify passes",
                     _verify_full_passes);
-    else
+    } else {
       tty->print_cr("VerifyIterativeGVN: %d transforms, %d full verify passes",
                   _verify_counter, _verify_full_passes);
+    }
   }
-#endif
+}
+#endif /* PRODUCT */
+
+#ifdef ASSERT
+/**
+ * Dumps information that can help to debug the problem. A debug
+ * build fails with an assert.
+ */
+void PhaseIterGVN::dump_infinite_loop_info(Node* n) {
+  n->dump(4);
+  _worklist.dump();
+  assert(false, "infinite loop in PhaseIterGVN::optimize");
+}
+
+/**
+ * Prints out information about IGVN if the 'verbose' option is used.
+ */
+void PhaseIterGVN::trace_PhaseIterGVN_verbose(Node* n, int num_processed) {
+  if (TraceIterativeGVN && Verbose) {
+    tty->print("  Pop ");
+    n->dump();
+    if ((num_processed % 100) == 0) {
+      _worklist.print_set();
+    }
+  }
+}
+#endif /* ASSERT */
+
+void PhaseIterGVN::optimize() {
+  DEBUG_ONLY(uint num_processed  = 0;)
+  NOT_PRODUCT(init_verifyPhaseIterGVN();)
+
+  uint loop_count = 0;
+  // Pull from worklist and transform the node. If the node has changed,
+  // update edge info and put uses on worklist.
+  while(_worklist.size()) {
+    if (C->check_node_count(NodeLimitFudgeFactor * 2, "Out of nodes")) {
+      return;
+    }
+    Node* n  = _worklist.pop();
+    if (++loop_count >= K * C->live_nodes()) {
+      DEBUG_ONLY(dump_infinite_loop_info(n);)
+      C->record_method_not_compilable("infinite loop in PhaseIterGVN::optimize");
+      return;
+    }
+    DEBUG_ONLY(trace_PhaseIterGVN_verbose(n, num_processed++);)
+    if (n->outcnt() != 0) {
+      NOT_PRODUCT(const Type* oldtype = type_or_null(n));
+      // Do the transformation
+      Node* nn = transform_old(n);
+      NOT_PRODUCT(trace_PhaseIterGVN(n, nn, oldtype);)
+    } else if (!n->is_top()) {
+      remove_dead_node(n);
+    }
+  }
+  NOT_PRODUCT(verify_PhaseIterGVN();)
 }
 
 
-//------------------register_new_node_with_optimizer---------------------------
-// Register a new node with the optimizer.  Update the types array, the def-use
-// info.  Put on worklist.
+/**
+ * Register a new node with the optimizer.  Update the types array, the def-use
+ * info.  Put on worklist.
+ */
 Node* PhaseIterGVN::register_new_node_with_optimizer(Node* n, Node* orig) {
   set_type_bottom(n);
   _worklist.push(n);
@@ -1038,32 +1052,29 @@
   return transform_old(n);
 }
 
-//------------------------------transform_old----------------------------------
-Node *PhaseIterGVN::transform_old( Node *n ) {
-#ifndef PRODUCT
-  debug_only(uint loop_count = 0;);
-  set_transforms();
-#endif
+Node *PhaseIterGVN::transform_old(Node* n) {
+  DEBUG_ONLY(uint loop_count = 0;);
+  NOT_PRODUCT(set_transforms());
+
   // Remove 'n' from hash table in case it gets modified
   _table.hash_delete(n);
-  if( VerifyIterativeGVN ) {
-   assert( !_table.find_index(n->_idx), "found duplicate entry in table");
+  if (VerifyIterativeGVN) {
+   assert(!_table.find_index(n->_idx), "found duplicate entry in table");
   }
 
   // Apply the Ideal call in a loop until it no longer applies
-  Node *k = n;
+  Node* k = n;
   DEBUG_ONLY(dead_loop_check(k);)
   DEBUG_ONLY(bool is_new = (k->outcnt() == 0);)
-  Node *i = k->Ideal(this, /*can_reshape=*/true);
+  Node* i = k->Ideal(this, /*can_reshape=*/true);
   assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes");
 #ifndef PRODUCT
-  if( VerifyIterativeGVN )
-    verify_step(k);
-  if( i && VerifyOpto ) {
-    if( !allow_progress() ) {
-      if (i->is_Add() && i->outcnt() == 1) {
+  verify_step(k);
+  if (i && VerifyOpto ) {
+    if (!allow_progress()) {
+      if (i->is_Add() && (i->outcnt() == 1)) {
         // Switched input to left side because this is the only use
-      } else if( i->is_If() && (i->in(0) == NULL) ) {
+      } else if (i->is_If() && (i->in(0) == NULL)) {
         // This IF is dead because it is dominated by an equivalent IF When
         // dominating if changed, info is not propagated sparsely to 'this'
         // Propagating this info further will spuriously identify other
@@ -1071,35 +1082,38 @@
         return i;
       } else
         set_progress();
-    } else
+    } else {
       set_progress();
+    }
   }
 #endif
 
-  while( i ) {
+  while (i != NULL) {
 #ifndef PRODUCT
-    debug_only( if( loop_count >= K ) i->dump(4); )
-    assert(loop_count < K, "infinite loop in PhaseIterGVN::transform");
-    debug_only( loop_count++; )
+    if (loop_count >= K) {
+      dump_infinite_loop_info(i);
+    }
+    loop_count++;
 #endif
     assert((i->_idx >= k->_idx) || i->is_top(), "Idealize should return new nodes, use Identity to return old nodes");
     // Made a change; put users of original Node on worklist
-    add_users_to_worklist( k );
+    add_users_to_worklist(k);
     // Replacing root of transform tree?
-    if( k != i ) {
+    if (k != i) {
       // Make users of old Node now use new.
-      subsume_node( k, i );
+      subsume_node(k, i);
       k = i;
     }
     DEBUG_ONLY(dead_loop_check(k);)
     // Try idealizing again
     DEBUG_ONLY(is_new = (k->outcnt() == 0);)
     i = k->Ideal(this, /*can_reshape=*/true);
-    assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes");
+    assert(i != k || is_new || (i->outcnt() > 0), "don't return dead nodes");
 #ifndef PRODUCT
-    if( VerifyIterativeGVN )
-      verify_step(k);
-    if( i && VerifyOpto ) set_progress();
+    verify_step(k);
+    if (i && VerifyOpto) {
+      set_progress();
+    }
 #endif
   }
 
@@ -1107,48 +1121,49 @@
   ensure_type_or_null(k);
 
   // See what kind of values 'k' takes on at runtime
-  const Type *t = k->Value(this);
+  const Type* t = k->Value(this);
   assert(t != NULL, "value sanity");
 
   // Since I just called 'Value' to compute the set of run-time values
   // for this Node, and 'Value' is non-local (and therefore expensive) I'll
   // cache Value.  Later requests for the local phase->type of this Node can
   // use the cached Value instead of suffering with 'bottom_type'.
-  if (t != type_or_null(k)) {
-    NOT_PRODUCT( set_progress(); )
-    NOT_PRODUCT( inc_new_values();)
+  if (type_or_null(k) != t) {
+#ifndef PRODUCT
+    inc_new_values();
+    set_progress();
+#endif
     set_type(k, t);
     // If k is a TypeNode, capture any more-precise type permanently into Node
     k->raise_bottom_type(t);
     // Move users of node to worklist
-    add_users_to_worklist( k );
+    add_users_to_worklist(k);
   }
-
   // If 'k' computes a constant, replace it with a constant
-  if( t->singleton() && !k->is_Con() ) {
-    NOT_PRODUCT( set_progress(); )
-    Node *con = makecon(t);     // Make a constant
-    add_users_to_worklist( k );
-    subsume_node( k, con );     // Everybody using k now uses con
+  if (t->singleton() && !k->is_Con()) {
+    NOT_PRODUCT(set_progress();)
+    Node* con = makecon(t);     // Make a constant
+    add_users_to_worklist(k);
+    subsume_node(k, con);       // Everybody using k now uses con
     return con;
   }
 
   // Now check for Identities
-  i = k->Identity(this);        // Look for a nearby replacement
-  if( i != k ) {                // Found? Return replacement!
-    NOT_PRODUCT( set_progress(); )
-    add_users_to_worklist( k );
-    subsume_node( k, i );       // Everybody using k now uses i
+  i = k->Identity(this);      // Look for a nearby replacement
+  if (i != k) {                // Found? Return replacement!
+    NOT_PRODUCT(set_progress();)
+    add_users_to_worklist(k);
+    subsume_node(k, i);       // Everybody using k now uses i
     return i;
   }
 
   // Global Value Numbering
   i = hash_find_insert(k);      // Check for pre-existing node
-  if( i && (i != k) ) {
+  if (i && (i != k)) {
     // Return the pre-existing node if it isn't dead
-    NOT_PRODUCT( set_progress(); )
-    add_users_to_worklist( k );
-    subsume_node( k, i );       // Everybody using k now uses i
+    NOT_PRODUCT(set_progress();)
+    add_users_to_worklist(k);
+    subsume_node(k, i);       // Everybody using k now uses i
     return i;
   }
 
@@ -1514,6 +1529,21 @@
   C->set_root( transform(C->root())->as_Root() );
   assert( C->top(),  "missing TOP node" );
   assert( C->root(), "missing root" );
+
+  // Eagerly remove castPP nodes here. CastPP nodes might not be
+  // removed in the subsequent IGVN phase if a node that changes
+  // in(1) of a castPP is processed prior to the castPP node.
+  for (uint i = 0; i < _worklist.size(); i++) {
+    Node* n = _worklist.at(i);
+
+    if (n->is_ConstraintCast()) {
+      Node* nn = n->Identity(this);
+      if (nn != n) {
+        replace_node(n, nn);
+        --i;
+      }
+    }
+  }
 }
 
 //------------------------------transform--------------------------------------
--- a/hotspot/src/share/vm/opto/phaseX.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/opto/phaseX.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -440,6 +440,17 @@
   // and dominator info to a fixed point.
   void optimize();
 
+#ifndef PRODUCT
+  void trace_PhaseIterGVN(Node* n, Node* nn, const Type* old_type);
+  void init_verifyPhaseIterGVN();
+  void verify_PhaseIterGVN();
+#endif
+
+#ifdef ASSERT
+  void dump_infinite_loop_info(Node* n);
+  void trace_PhaseIterGVN_verbose(Node* n, int num_processed);
+#endif
+
   // Register a new node with the iter GVN pass without transforming it.
   // Used when we need to restructure a Region/Phi area and all the Regions
   // and Phis need to complete this one big transform before any other
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -53,7 +53,8 @@
   }
 
   set_c1_count(MAX2(count / 3, 1));
-  set_c2_count(MAX2(count - count / 3, 1));
+  set_c2_count(MAX2(count - c1_count(), 1));
+  FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count());
 
   // Some inlining tuning
 #ifdef X86
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -2402,6 +2402,10 @@
   const int num_min_compiler_threads = (TieredCompilation && (TieredStopAtLevel >= CompLevel_full_optimization)) ? 2 : 1;
   status &=verify_min_value(CICompilerCount, num_min_compiler_threads, "CICompilerCount");
 
+  if (!FLAG_IS_DEFAULT(CICompilerCount) && !FLAG_IS_DEFAULT(CICompilerCountPerCPU) && CICompilerCountPerCPU) {
+    warning("The VM option CICompilerCountPerCPU overrides CICompilerCount.");
+  }
+
   return status;
 }
 
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -182,6 +182,7 @@
     // max(log2(8)-1,1) = 2 compiler threads on an 8-way machine.
     // May help big-app startup time.
     _compiler_count = MAX2(log2_intptr(os::active_processor_count())-1,1);
+    FLAG_SET_ERGO(intx, CICompilerCount, _compiler_count);
   } else {
     _compiler_count = CICompilerCount;
   }
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -420,15 +420,9 @@
     // frame[number_of_frames - 1 ] = on_stack_size(youngest)
     // frame[number_of_frames - 2 ] = on_stack_size(sender(youngest))
     // frame[number_of_frames - 3 ] = on_stack_size(sender(sender(youngest)))
-    int caller_parms = callee_parameters;
-    if ((index == array->frames() - 1) && caller_was_method_handle) {
-      caller_parms = 0;
-    }
-    frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(caller_parms,
-                                                                                                    callee_parameters,
+    frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(callee_parameters,
                                                                                                     callee_locals,
                                                                                                     index == 0,
-                                                                                                    index == array->frames() - 1,
                                                                                                     popframe_extra_args);
     // This pc doesn't have to be perfect just good enough to identify the frame
     // as interpreted so the skeleton frame will be walkable
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -775,10 +775,13 @@
         // going to be unwound. Dispatch to a shared runtime stub
         // which will cause the StackOverflowError to be fabricated
         // and processed.
-        // For stack overflow in deoptimization blob, cleanup thread.
-        if (thread->deopt_mark() != NULL) {
-          Deoptimization::cleanup_deopt_info(thread, NULL);
-        }
+        // Stack overflow should never occur during deoptimization:
+        // the compiled method bangs the stack by as much as the
+        // interpreter would need in case of a deoptimization. The
+        // deoptimization blob and uncommon trap blob bang the stack
+        // in a debug VM to verify the correctness of the compiled
+        // method stack banging.
+        assert(thread->deopt_mark() == NULL, "no stack overflow from deopt blob/uncommon trap");
         Events::log_exception(thread, "StackOverflowError at " INTPTR_FORMAT, pc);
         return StubRoutines::throw_StackOverflowError_entry();
       }
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -142,7 +142,8 @@
     count = MAX2(log2_intptr(os::active_processor_count()), 1) * 3 / 2;
   }
   set_c1_count(MAX2(count / 3, 1));
-  set_c2_count(MAX2(count - count / 3, 1));
+  set_c2_count(MAX2(count - c1_count(), 1));
+  FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count());
 }
 
 void SimpleThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {
--- a/hotspot/src/share/vm/runtime/vframeArray.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/runtime/vframeArray.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -418,24 +418,20 @@
 
 }
 
-int vframeArrayElement::on_stack_size(int caller_actual_parameters,
-                                      int callee_parameters,
+int vframeArrayElement::on_stack_size(int callee_parameters,
                                       int callee_locals,
                                       bool is_top_frame,
-                                      bool is_bottom_frame,
                                       int popframe_extra_stack_expression_els) const {
   assert(method()->max_locals() == locals()->size(), "just checking");
   int locks = monitors() == NULL ? 0 : monitors()->number_of_monitors();
   int temps = expressions()->size();
-  return Interpreter::size_activation(method(),
+  return Interpreter::size_activation(method()->max_stack(),
                                       temps + callee_parameters,
                                       popframe_extra_stack_expression_els,
                                       locks,
-                                      caller_actual_parameters,
                                       callee_parameters,
                                       callee_locals,
-                                      is_top_frame,
-                                      is_bottom_frame);
+                                      is_top_frame);
 }
 
 
--- a/hotspot/src/share/vm/runtime/vframeArray.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/runtime/vframeArray.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -85,10 +85,8 @@
 
   // Returns the on stack word size for this frame
   // callee_parameters is the number of callee locals residing inside this frame
-  int on_stack_size(int caller_actual_parameters,
-                    int callee_parameters,
+  int on_stack_size(int callee_parameters,
                     int callee_locals,
-                    bool is_bottom_frame,
                     bool is_top_frame,
                     int popframe_extra_stack_expression_els) const;
 
--- a/hotspot/src/share/vm/utilities/growableArray.hpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp	Thu Apr 17 13:50:26 2014 -0400
@@ -147,6 +147,9 @@
   }
 };
 
+template<class E> class GrowableArrayIterator;
+template<class E, class UnaryPredicate> class GrowableArrayFilterIterator;
+
 template<class E> class GrowableArray : public GenericGrowableArray {
   friend class VMStructs;
 
@@ -243,6 +246,14 @@
     return _data[_len-1];
   }
 
+  GrowableArrayIterator<E> begin() const {
+    return GrowableArrayIterator<E>(this, 0);
+  }
+
+  GrowableArrayIterator<E> end() const {
+    return GrowableArrayIterator<E>(this, length());
+  }
+
   void push(const E& elem) { append(elem); }
 
   E pop() {
@@ -412,4 +423,83 @@
     tty->print("}\n");
 }
 
+// Custom STL-style iterator to iterate over GrowableArrays
+// It is constructed by invoking GrowableArray::begin() and GrowableArray::end()
+template<class E> class GrowableArrayIterator : public StackObj {
+  friend class GrowableArray<E>;
+  template<class F, class UnaryPredicate> friend class GrowableArrayFilterIterator;
+
+ private:
+  const GrowableArray<E>* _array; // GrowableArray we iterate over
+  int _position;                  // The current position in the GrowableArray
+
+  // Private constructor used in GrowableArray::begin() and GrowableArray::end()
+  GrowableArrayIterator(const GrowableArray<E>* array, int position) : _array(array), _position(position) {
+    assert(0 <= position && position <= _array->length(), "illegal position");
+  }
+
+ public:
+  GrowableArrayIterator<E>& operator++()  { ++_position; return *this; }
+  E operator*()                           { return _array->at(_position); }
+
+  bool operator==(const GrowableArrayIterator<E>& rhs)  {
+    assert(_array == rhs._array, "iterator belongs to different array");
+    return _position == rhs._position;
+  }
+
+  bool operator!=(const GrowableArrayIterator<E>& rhs)  {
+    assert(_array == rhs._array, "iterator belongs to different array");
+    return _position != rhs._position;
+  }
+};
+
+// Custom STL-style iterator to iterate over elements of a GrowableArray that satisfy a given predicate
+template<class E, class UnaryPredicate> class GrowableArrayFilterIterator : public StackObj {
+  friend class GrowableArray<E>;
+
+ private:
+  const GrowableArray<E>* _array;   // GrowableArray we iterate over
+  int _position;                    // Current position in the GrowableArray
+  UnaryPredicate _predicate;        // Unary predicate the elements of the GrowableArray should satisfy
+
+ public:
+  GrowableArrayFilterIterator(const GrowableArrayIterator<E>& begin, UnaryPredicate filter_predicate)
+   : _array(begin._array), _position(begin._position), _predicate(filter_predicate) {
+    // Advance to first element satisfying the predicate
+    while(_position != _array->length() && !_predicate(_array->at(_position))) {
+      ++_position;
+    }
+  }
+
+  GrowableArrayFilterIterator<E, UnaryPredicate>& operator++() {
+    do {
+      // Advance to next element satisfying the predicate
+      ++_position;
+    } while(_position != _array->length() && !_predicate(_array->at(_position)));
+    return *this;
+  }
+
+  E operator*()   { return _array->at(_position); }
+
+  bool operator==(const GrowableArrayIterator<E>& rhs)  {
+    assert(_array == rhs._array, "iterator belongs to different array");
+    return _position == rhs._position;
+  }
+
+  bool operator!=(const GrowableArrayIterator<E>& rhs)  {
+    assert(_array == rhs._array, "iterator belongs to different array");
+    return _position != rhs._position;
+  }
+
+  bool operator==(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs)  {
+    assert(_array == rhs._array, "iterator belongs to different array");
+    return _position == rhs._position;
+  }
+
+  bool operator!=(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs)  {
+    assert(_array == rhs._array, "iterator belongs to different array");
+    return _position != rhs._position;
+  }
+};
+
 #endif // SHARE_VM_UTILITIES_GROWABLEARRAY_HPP
--- a/hotspot/src/share/vm/utilities/xmlstream.cpp	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/src/share/vm/utilities/xmlstream.cpp	Thu Apr 17 13:50:26 2014 -0400
@@ -396,10 +396,10 @@
 }
 
 void xmlStream::method_text(methodHandle method) {
+  ResourceMark rm;
   assert_if_no_error(inside_attrs(), "printing attributes");
   if (method.is_null())  return;
-  //method->print_short_name(text());
-  method->method_holder()->name()->print_symbol_on(text());
+  text()->print(method->method_holder()->external_name());
   print_raw(" ");  // " " is easier for tools to parse than "::"
   method->name()->print_symbol_on(text());
   print_raw(" ");  // separator
--- a/hotspot/test/TEST.groups	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/test/TEST.groups	Thu Apr 17 13:50:26 2014 -0400
@@ -134,7 +134,8 @@
   runtime/InternalApi/ThreadCpuTimesDeadlock.java \
   serviceability/threads/TestFalseDeadLock.java \
   compiler/tiered/NonTieredLevelsTest.java \
-  compiler/tiered/TieredLevelsTest.java
+  compiler/tiered/TieredLevelsTest.java \
+  compiler/intrinsics/bmi/verifycode
 
 # Compact 2 adds full VM tests
 compact2 = \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/EscapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2014 SAP AG.  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 8038048
+ * @summary assert(null_obj->escape_state() == PointsToNode::NoEscape,etc)
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+DoEscapeAnalysis -XX:-TieredCompilation -Xbatch TestUnsafePutAddressNullObjMustNotEscape
+ * @author Richard Reingruber richard DOT reingruber AT sap DOT com
+ */
+
+import java.lang.reflect.Field;
+import sun.misc.Unsafe;
+
+public class TestUnsafePutAddressNullObjMustNotEscape {
+
+    public static Unsafe usafe;
+    public static long mem;
+    public static long checksum;
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("EXECUTING test.");
+
+        {
+            System.out.println("Acquiring sun.misc.Unsafe.theUnsafe using reflection.");
+            getUnsafe();
+            System.out.println("Allocating raw memory.");
+            mem = (usafe.allocateMemory(1024) + 8L) & ~7L;
+            System.out.println("Triggering JIT compilation of the test method");
+            triggerJitCompilationOfTestMethod();
+        }
+
+        System.out.println("SUCCESSFULLY passed test.");
+    }
+
+    public static void triggerJitCompilationOfTestMethod() {
+        long sum = 0;
+        for (int ii = 50000; ii >= 0; ii--) {
+            sum = testMethod();
+        }
+        checksum = sum;
+    }
+
+    public static class IDGen {
+        private static long id;
+        public long nextId() {
+            return id++;
+        }
+    }
+
+    public static long testMethod() {
+        // dummy alloc to trigger escape analysis
+        IDGen gen = new IDGen();
+        // StoreP of null_obj to raw mem triggers assertion in escape analysis
+        usafe.putAddress(mem, 0L);
+        return gen.nextId();
+    }
+
+    private static void getUnsafe() throws Exception {
+        Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
+        field.setAccessible(true);
+        usafe = (sun.misc.Unsafe) field.get(null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build AddnTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AddnTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class AddnTestI extends BmiIntrinsicBase.BmiTestCase {
+
+    protected AddnTestI(Method method) {
+        super(method);
+        // from intel manual VEX.NDS.LZ.0F38.W0 F2 /r, example c4e260f2c2
+        instrMask = new byte[]{
+                (byte) 0xFF,
+                (byte) 0x1F,
+                (byte) 0x00,
+                (byte) 0xFF};
+        instrPattern = new byte[]{
+                (byte) 0xC4, // prefix for 3-byte VEX instruction
+                (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
+                (byte) 0x00,
+                (byte) 0xF2};
+    }
+
+    public static void main(String[] args) throws Exception {
+        BmiIntrinsicBase.verifyTestCase(AddnTestI::new, TestAndnI.AndnIExpr.class.getDeclaredMethods());
+        BmiIntrinsicBase.verifyTestCase(AddnTestI::new, TestAndnI.AndnICommutativeExpr.class.getDeclaredMethods());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build AddnTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AddnTestL
+ */
+
+import java.lang.reflect.Method;
+
+public class AddnTestL extends AddnTestI {
+
+    protected AddnTestL(Method method) {
+        super(method);
+        isLongOperation = true;
+    }
+
+    public static void main(String[] args) throws Exception {
+        BmiIntrinsicBase.verifyTestCase(AddnTestL::new, TestAndnL.AndnLExpr.class.getDeclaredMethods());
+        BmiIntrinsicBase.verifyTestCase(AddnTestL::new, TestAndnL.AndnLCommutativeExpr.class.getDeclaredMethods());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsiTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsiTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsiTestI extends BmiIntrinsicBase.BmiTestCase {
+
+    protected BlsiTestI(Method method) {
+        super(method);
+        //from intel manual VEX.NDD.LZ.0F38.W0 F3 /3
+        instrMask = new byte[]{
+                (byte) 0xFF,
+                (byte) 0x1F,
+                (byte) 0x00,
+                (byte) 0xFF,
+                (byte) 0b0011_1000};
+        instrPattern = new byte[]{
+                (byte) 0xC4, // prefix for 3-byte VEX instruction
+                (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
+                (byte) 0x00,
+                (byte) 0xF3,
+                (byte) 0b0001_1000}; // bits 543 == 011 (3)
+    }
+
+    public static void main(String[] args) throws Exception {
+        BmiIntrinsicBase.verifyTestCase(BlsiTestI::new, TestBlsiI.BlsiIExpr.class.getDeclaredMethods());
+        BmiIntrinsicBase.verifyTestCase(BlsiTestI::new, TestBlsiI.BlsiICommutativeExpr.class.getDeclaredMethods());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsiTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsiTestL
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsiTestL extends BlsiTestI {
+
+    protected BlsiTestL(Method method) {
+        super(method);
+        isLongOperation = true;
+    }
+
+    public static void main(String[] args) throws Exception {
+        BmiIntrinsicBase.verifyTestCase(BlsiTestL::new, TestBlsiL.BlsiLExpr.class.getDeclaredMethods());
+        BmiIntrinsicBase.verifyTestCase(BlsiTestL::new, TestBlsiL.BlsiLCommutativeExpr.class.getDeclaredMethods());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsmskTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsmskTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsmskTestI extends BmiIntrinsicBase.BmiTestCase {
+
+    protected BlsmskTestI(Method method) {
+        super(method);
+        //from intel manual VEX.NDD.LZ.0F38.W0 F3 /2
+        instrMask = new byte[]{
+                (byte) 0xFF,
+                (byte) 0x1F,
+                (byte) 0x00,
+                (byte) 0xFF,
+                (byte) 0b0011_1000};
+        instrPattern = new byte[]{
+                (byte) 0xC4, // prefix for 3-byte VEX instruction
+                (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
+                (byte) 0x00,
+                (byte) 0xF3,
+                (byte) 0b0001_0000}; // bits 543 == 011 (3)
+    }
+
+    public static void main(String[] args) throws Exception {
+        BmiIntrinsicBase.verifyTestCase(BlsmskTestI::new, TestBlsmskI.BlsmskIExpr.class.getDeclaredMethods());
+        BmiIntrinsicBase.verifyTestCase(BlsmskTestI::new, TestBlsmskI.BlsmskICommutativeExpr.class.getDeclaredMethods());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsmskTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsmskTestL
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsmskTestL extends BlsmskTestI {
+
+    protected BlsmskTestL(Method method) {
+        super(method);
+        isLongOperation = true;
+    }
+
+    public static void main(String[] args) throws Exception {
+        BmiIntrinsicBase.verifyTestCase(BlsmskTestL::new, TestBlsmskL.BlsmskLExpr.class.getDeclaredMethods());
+        BmiIntrinsicBase.verifyTestCase(BlsmskTestL::new, TestBlsmskL.BlsmskLCommutativeExpr.class.getDeclaredMethods());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsrTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsrTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsrTestI extends BmiIntrinsicBase.BmiTestCase {
+
+    protected BlsrTestI(Method method) {
+        super(method);
+        //from intel manual VEX.NDD.LZ.0F38.W0 F3 /1
+        instrMask = new byte[]{
+                (byte) 0xFF,
+                (byte) 0x1F,
+                (byte) 0x00,
+                (byte) 0xFF,
+                (byte) 0b0011_1000};
+        instrPattern = new byte[]{
+                (byte) 0xC4, // prefix for 3-byte VEX instruction
+                (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
+                (byte) 0x00,
+                (byte) 0xF3,
+                (byte) 0b0000_1000}; // bits 543 == 011 (3)
+    }
+
+    public static void main(String[] args) throws Exception {
+        BmiIntrinsicBase.verifyTestCase(BlsrTestI::new, TestBlsrI.BlsrIExpr.class.getDeclaredMethods());
+        BmiIntrinsicBase.verifyTestCase(BlsrTestI::new, TestBlsrI.BlsrICommutativeExpr.class.getDeclaredMethods());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsrTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsrTestL
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsrTestL extends BlsrTestI {
+
+    protected BlsrTestL(Method method) {
+        super(method);
+        isLongOperation = true;
+    }
+
+    public static void main(String[] args) throws Exception {
+        BmiIntrinsicBase.verifyTestCase(BlsrTestL::new, TestBlsrL.BlsrLExpr.class.getDeclaredMethods());
+        BmiIntrinsicBase.verifyTestCase(BlsrTestL::new, TestBlsrL.BlsrLCommutativeExpr.class.getDeclaredMethods());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2014, 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 com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.Utils;
+import sun.hotspot.code.NMethod;
+import sun.hotspot.cpuinfo.CPUInfo;
+
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
+import java.util.function.Function;
+
+public class BmiIntrinsicBase extends CompilerWhiteBoxTest {
+
+    protected BmiIntrinsicBase(BmiTestCase testCase) {
+        super(testCase);
+    }
+
+    public static void verifyTestCase(Function<Method, BmiTestCase> constructor, Method... methods) throws Exception {
+        for (Method method : methods) {
+            new BmiIntrinsicBase(constructor.apply(method)).test();
+        }
+    }
+
+    @Override
+    protected void test() throws Exception {
+        BmiTestCase bmiTestCase = (BmiTestCase) testCase;
+
+        if (!(Platform.isX86() || Platform.isX64())) {
+            System.out.println("Unsupported platform, test SKIPPED");
+            return;
+        }
+
+        if (!Platform.isServer()) {
+            System.out.println("Not server VM, test SKIPPED");
+            return;
+        }
+
+        if (!CPUInfo.hasFeature(bmiTestCase.getCpuFlag())) {
+            System.out.println("Unsupported hardware, no required CPU flag " + bmiTestCase.getCpuFlag() + " , test SKIPPED");
+            return;
+        }
+
+        if (!Boolean.valueOf(getVMOption(bmiTestCase.getVMFlag()))) {
+            System.out.println("VM flag " + bmiTestCase.getVMFlag() + " disabled, test SKIPPED");
+            return;
+        }
+
+        System.out.println(testCase.name());
+
+        switch (MODE) {
+            case "compiled mode":
+            case "mixed mode":
+                if (TIERED_COMPILATION && TIERED_STOP_AT_LEVEL != CompilerWhiteBoxTest.COMP_LEVEL_MAX) {
+                    System.out.println("TieredStopAtLevel value (" + TIERED_STOP_AT_LEVEL + ") is too low, test SKIPPED");
+                    return;
+                }
+                deoptimize();
+                compileAtLevelAndCheck(CompilerWhiteBoxTest.COMP_LEVEL_MAX);
+                break;
+            case "interpreted mode": // test is not applicable in this mode;
+                System.err.println("Warning: This test is not applicable in mode: " + MODE);
+                break;
+            default:
+                throw new AssertionError("Test bug, unknown VM mode: " + MODE);
+        }
+    }
+
+    protected void compileAtLevelAndCheck(int level) {
+        WHITE_BOX.enqueueMethodForCompilation(method, level);
+        waitBackgroundCompilation();
+        checkCompilation(method, level);
+        checkEmittedCode(method);
+    }
+
+    protected void checkCompilation(Executable executable, int level) {
+        if (!WHITE_BOX.isMethodCompiled(executable)) {
+            throw new AssertionError("Test bug, expected compilation (level): " + level + ", but not compiled" + WHITE_BOX.isMethodCompilable(executable, level));
+        }
+        final int compilationLevel = WHITE_BOX.getMethodCompilationLevel(executable);
+        if (compilationLevel != level) {
+            throw new AssertionError("Test bug, expected compilation (level): " + level + ", but level: " + compilationLevel);
+        }
+    }
+
+    protected void checkEmittedCode(Executable executable) {
+        final byte[] nativeCode = NMethod.get(executable, false).insts;
+        if (!((BmiTestCase) testCase).verifyPositive(nativeCode)) {
+            throw new AssertionError(testCase.name() + "CPU instructions expected not found: " + Utils.toHexString(nativeCode));
+        } else {
+            System.out.println("CPU instructions found, PASSED");
+        }
+    }
+
+    abstract static class BmiTestCase implements CompilerWhiteBoxTest.TestCase {
+        private final Method method;
+        protected byte[] instrMask;
+        protected byte[] instrPattern;
+        protected boolean isLongOperation;
+
+        public BmiTestCase(Method method) {
+            this.method = method;
+        }
+
+        @Override
+        public String name() {
+            return method.toGenericString();
+        }
+
+        @Override
+        public Executable getExecutable() {
+            return method;
+        }
+
+        @Override
+        public Callable<Integer> getCallable() {
+            return null;
+        }
+
+        @Override
+        public boolean isOsr() {
+            return false;
+        }
+
+        protected int countCpuInstructions(byte[] nativeCode) {
+            int count = 0;
+            int patternSize = Math.min(instrMask.length, instrPattern.length);
+            boolean found;
+            Asserts.assertGreaterThan(patternSize, 0);
+            for (int i = 0, n = nativeCode.length - patternSize; i < n; i++) {
+                found = true;
+                for (int j = 0; j < patternSize; j++) {
+                    if ((nativeCode[i + j] & instrMask[j]) != instrPattern[j]) {
+                        found = false;
+                        break;
+                    }
+                }
+                if (found) {
+                    ++count;
+                    i += patternSize - 1;
+                }
+            }
+            return count;
+        }
+
+        public boolean verifyPositive(byte[] nativeCode) {
+            final int cnt = countCpuInstructions(nativeCode);
+            if (Platform.isX86()) {
+                return cnt >= (isLongOperation ? 2 : 1);
+            } else {
+                return Platform.isX64() && cnt >= 1;
+            }
+        }
+
+        protected String getCpuFlag() {
+            return "bmi1";
+        }
+
+        protected String getVMFlag() {
+            return "UseBMI1Instructions";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build LZcntTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountLeadingZerosInstruction LZcntTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class LZcntTestI extends BmiIntrinsicBase.BmiTestCase {
+
+    protected LZcntTestI(Method method) {
+        super(method);
+        instrMask = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+        instrPattern = new byte[]{(byte) 0xF3, (byte) 0x0F, (byte) 0xBD};
+    }
+
+    public static void main(String[] args) throws Exception {
+        // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
+        System.out.println("class java.lang.Integer should be loaded. Proof: " + Integer.class);
+        BmiIntrinsicBase.verifyTestCase(LZcntTestI::new, TestLzcntI.LzcntIExpr.class.getDeclaredMethods());
+    }
+
+    @Override
+    protected String getVMFlag() {
+        return "UseCountLeadingZerosInstruction";
+    }
+
+    @Override
+    protected String getCpuFlag() {
+        return "lzcnt";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build LZcntTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountLeadingZerosInstruction LZcntTestL
+ */
+
+import com.oracle.java.testlibrary.Platform;
+
+import java.lang.reflect.Method;
+
+public class LZcntTestL extends LZcntTestI {
+
+    protected LZcntTestL(Method method) {
+        super(method);
+        isLongOperation = true;
+        if (Platform.isX64()) {
+            instrMask = new byte[]{(byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF};
+            instrPattern = new byte[]{(byte) 0xF3, (byte) 0x00, (byte) 0x0F, (byte) 0xBD};
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
+        System.out.println("classes java.lang.Long should be loaded. Proof: " + Long.class);
+        BmiIntrinsicBase.verifyTestCase(LZcntTestL::new, TestLzcntL.LzcntLExpr.class.getDeclaredMethods());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build TZcntTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountTrailingZerosInstruction TZcntTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class TZcntTestI extends BmiIntrinsicBase.BmiTestCase {
+
+    protected TZcntTestI(Method method) {
+        super(method);
+        instrMask = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+        instrPattern = new byte[]{(byte) 0xF3, (byte) 0x0F, (byte) 0xBC};
+    }
+
+    public static void main(String[] args) throws Exception {
+        // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
+        System.out.println("class java.lang.Integer should be loaded. Proof: " + Integer.class);
+        BmiIntrinsicBase.verifyTestCase(TZcntTestI::new, TestTzcntI.TzcntIExpr.class.getDeclaredMethods());
+    }
+
+    @Override
+    protected String getVMFlag() {
+        return "UseCountTrailingZerosInstruction";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build TZcntTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountTrailingZerosInstruction TZcntTestL
+ */
+
+import com.oracle.java.testlibrary.Platform;
+
+import java.lang.reflect.Method;
+
+public class TZcntTestL extends TZcntTestI {
+
+    protected TZcntTestL(Method method) {
+        super(method);
+        isLongOperation = true;
+        if (Platform.isX64()) {
+            instrMask = new byte[]{(byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF};
+            instrPattern = new byte[]{(byte) 0xF3, (byte) 0x00, (byte) 0x0F, (byte) 0xBC};
+        }
+        isLongOperation = true;
+    }
+
+    public static void main(String[] args) throws Exception {
+        // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
+        System.out.println("classes java.lang.Long should be loaded. Proof: " + Long.class);
+        BmiIntrinsicBase.verifyTestCase(TZcntTestL::new, TestTzcntL.TzcntLExpr.class.getDeclaredMethods());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/RTMGenericCommandLineOptionTest.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2014, 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 com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.*;
+
+import java.util.function.BooleanSupplier;
+
+/**
+ * Base for all RTM-related CLI tests.
+ */
+public abstract class RTMGenericCommandLineOptionTest
+        extends CommandLineOptionTest {
+    protected static final String RTM_INSTR_ERROR
+            = "RTM instructions are not available on this CPU";
+    protected static final String RTM_UNSUPPORTED_VM_ERROR
+            = "RTM locking optimization is not supported in this VM";
+    protected static final String RTM_ABORT_RATIO_WARNING
+            = "RTMAbortRatio must be in the range 0 to 100, resetting it to 50";
+    protected static final String RTM_FOR_STACK_LOCKS_WARNING
+            = "UseRTMForStackLocks flag should be off when UseRTMLocking "
+            + "flag is off";
+    protected static final String RTM_COUNT_INCR_WARNING
+            = "RTMTotalCountIncrRate must be a power of 2, resetting it to 64";
+    protected static final String RTM_BIASED_LOCKING_WARNING
+            = "Biased locking is not supported with RTM locking; "
+            + "ignoring UseBiasedLocking flag";
+
+    protected final String optionName;
+    protected final String errorMessage;
+    protected final String experimentalOptionError;
+    protected final boolean isExperimental;
+    protected final boolean isBoolean;
+    protected final String defaultValue;
+    protected final String[] optionValues;
+
+    /**
+     * Constructs new genetic RTM CLI test, for option {@code optionName} which
+     * has default value {@code defaultValue}. Test cases will use option's
+     * values passed via {@code optionValues} for verification of correct
+     * option processing.
+     *
+     * Test constructed using this ctor will be started on any cpu regardless
+     * it's architecture and supported/unsupported features.
+     *
+     * @param predicate predicate responsible for test's preconditions check
+     * @param optionName name of option to be tested
+     * @param isBoolean {@code true} if option is binary
+     * @param isExperimental {@code true} if option is experimental
+     * @param defaultValue default value of tested option
+     * @param optionValues different option values
+     */
+    public RTMGenericCommandLineOptionTest(BooleanSupplier predicate,
+            String optionName, boolean isBoolean, boolean isExperimental,
+            String defaultValue, String... optionValues) {
+        super(predicate);
+        this.optionName = optionName;
+        this.isExperimental = isExperimental;
+        this.isBoolean = isBoolean;
+        this.defaultValue = defaultValue;
+        this.optionValues = optionValues;
+        this.errorMessage = CommandLineOptionTest.
+                getUnrecognizedOptionErrorMessage(optionName);
+        this.experimentalOptionError = CommandLineOptionTest.
+                getExperimentalOptionErrorMessage(optionName);
+    }
+
+    @Override
+    public void runTestCases() throws Throwable {
+        if (Platform.isX86() || Platform.isX64()) {
+            if (Platform.isServer() && !Platform.isEmbedded()) {
+                runX86SupportedVMTestCases();
+            } else {
+                runX86UnsupportedVMTestCases();
+            }
+        } else {
+            runNonX86TestCases();
+        }
+    }
+
+    /**
+     * Runs test cases on X86 CPU if VM supports RTM locking.
+     * @throws Throwable
+     */
+    protected void runX86SupportedVMTestCases() throws Throwable {
+        runGenericX86TestCases();
+    }
+
+    /**
+     * Runs test cases on non-X86 CPU if VM does not support RTM locking.
+     * @throws Throwable
+     */
+    protected void runX86UnsupportedVMTestCases() throws Throwable {
+        runGenericX86TestCases();
+    }
+
+    /**
+     * Runs test cases on non-X86 CPU.
+     * @throws Throwable
+     */
+    protected void runNonX86TestCases() throws Throwable {
+        CommandLineOptionTest.verifySameJVMStartup(
+                new String[] { errorMessage }, null, ExitCode.FAIL,
+                prepareOptionValue(defaultValue));
+    }
+
+    /**
+     * Runs generic X86 test cases.
+     * @throws Throwable
+     */
+    protected void runGenericX86TestCases() throws Throwable {
+        verifyJVMStartup();
+        verifyOptionValues();
+    }
+
+    protected void verifyJVMStartup() throws Throwable {
+        String optionValue = prepareOptionValue(defaultValue);
+        if (isExperimental) {
+            // verify that option is experimental
+            CommandLineOptionTest.verifySameJVMStartup(
+                    new String[] { experimentalOptionError },
+                    new String[] { errorMessage }, ExitCode.FAIL,
+                    optionValue);
+            // verify that it could be passed if experimental options
+            // are unlocked
+            CommandLineOptionTest.verifySameJVMStartup(null,
+                    new String[] {
+                            experimentalOptionError,
+                            errorMessage
+                    },
+                    ExitCode.OK,
+                    CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                    optionValue);
+        } else {
+            // verify that option could be passed
+            CommandLineOptionTest.verifySameJVMStartup(null,
+                    new String[]{errorMessage}, ExitCode.OK, optionValue);
+        }
+    }
+
+    protected void verifyOptionValues() throws Throwable {
+        // verify default value
+        if (isExperimental) {
+            CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                    defaultValue,
+                    CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+        } else {
+            CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                    defaultValue);
+        }
+        // verify other specified option values
+        if (optionValues == null) {
+            return;
+        }
+
+        for (String value : optionValues) {
+            if (isExperimental) {
+                CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                        value,
+                        CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                        prepareOptionValue(value));
+            } else {
+                CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                        value, prepareOptionValue(value));
+            }
+        }
+    }
+
+    protected String prepareOptionValue(String value) {
+        if (isBoolean) {
+            return CommandLineOptionTest.prepareBooleanFlag(optionName,
+                    Boolean.valueOf(value));
+        } else {
+            return String.format("-XX:%s=%s", optionName, value);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2014, 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.List;
+import java.util.LinkedList;
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Base for all RTM-related CLI tests on options whose processing depends
+ * on UseRTMLocking value.
+ *
+ * Since UseRTMLocking option could be used when both CPU and VM supports RTM
+ * locking, this test will be skipped on all unsupported configurations.
+ */
+public abstract class RTMLockingAwareTest
+        extends RTMGenericCommandLineOptionTest {
+    protected final String warningMessage;
+    protected final String[] correctValues;
+    protected final String[] incorrectValues;
+    /**
+     * Constructs new test for option {@code optionName} that should be executed
+     * only on CPU with RTM support.
+     * Test will be executed using set of correct values from
+     * {@code correctValues} and set of incorrect values from
+     * {@code incorrectValues}.
+     *
+     * @param optionName name of option to be tested
+     * @param isBoolean {@code true} if tested option is binary
+     * @param isExperimental {@code true} if tested option is experimental
+     * @param defaultValue default value of tested option
+     * @param correctValues array with correct values, that should not emit
+     *                      {@code warningMessage} to VM output
+     * @param incorrectValues array with incorrect values, that should emit
+     *                        {@code waningMessage} to VM output
+     * @param warningMessage warning message associated with tested option
+     */
+    protected RTMLockingAwareTest(String optionName, boolean isBoolean,
+            boolean isExperimental, String defaultValue,
+            String[] correctValues, String[] incorrectValues,
+            String warningMessage) {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()),
+                optionName, isBoolean, isExperimental, defaultValue);
+        this.correctValues = correctValues;
+        this.incorrectValues = incorrectValues;
+        this.warningMessage = warningMessage;
+    }
+
+    @Override
+    protected void verifyJVMStartup() throws Throwable {
+        // Run generic sanity checks
+        super.verifyJVMStartup();
+        // Verify how option values will be processed depending on
+        // UseRTMLocking value.
+        if (correctValues != null) {
+            for (String correctValue : correctValues) {
+                // For correct values it is expected to see no warnings
+                // regardless to UseRTMLocking
+                verifyStartupWarning(correctValue, true, false);
+                verifyStartupWarning(correctValue, false, false);
+            }
+        }
+
+        if (incorrectValues != null) {
+            for (String incorrectValue : incorrectValues) {
+                // For incorrect values it is expected to see warning
+                // only with -XX:+UseRTMLocking
+                verifyStartupWarning(incorrectValue, true, true);
+                verifyStartupWarning(incorrectValue, false, false);
+            }
+        }
+    }
+
+    @Override
+    protected void verifyOptionValues() throws Throwable {
+        super.verifyOptionValues();
+        // Verify how option values will be setup after processing
+        // depending on UseRTMLocking value
+        if (correctValues != null) {
+            for (String correctValue : correctValues) {
+                // Correct value could be set up regardless to UseRTMLocking
+                verifyOptionValues(correctValue, false, correctValue);
+                verifyOptionValues(correctValue, true, correctValue);
+            }
+        }
+
+        if (incorrectValues != null) {
+            for (String incorrectValue : incorrectValues) {
+                // With -XX:+UseRTMLocking, incorrect value will be changed to
+                // default value.
+                verifyOptionValues(incorrectValue, false, incorrectValue);
+                verifyOptionValues(incorrectValue, true, defaultValue);
+            }
+        }
+    }
+
+    private void verifyStartupWarning(String value, boolean useRTMLocking,
+            boolean isWarningExpected) throws Throwable {
+        String warnings[] = new String[] { warningMessage };
+        List<String> options = new LinkedList<>();
+        options.add(CommandLineOptionTest.prepareBooleanFlag("UseRTMLocking",
+                useRTMLocking));
+
+        if (isExperimental) {
+            options.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+        }
+        options.add(prepareOptionValue(value));
+
+        CommandLineOptionTest.verifySameJVMStartup(
+                (isWarningExpected ? warnings : null),
+                (isWarningExpected ? null : warnings),
+                ExitCode.OK, options.toArray(new String[options.size()]));
+    }
+
+    private void verifyOptionValues(String value, boolean useRTMLocking,
+            String expectedValue) throws Throwable {
+        List<String> options = new LinkedList<>();
+        options.add(CommandLineOptionTest.prepareBooleanFlag("UseRTMLocking",
+                useRTMLocking));
+
+        if (isExperimental) {
+            options.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+        }
+        options.add(prepareOptionValue(value));
+
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                expectedValue, options.toArray(new String[options.size()]));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsBase.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014, 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 com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.*;
+
+import java.util.function.BooleanSupplier;
+
+public abstract class TestPrintPreciseRTMLockingStatisticsBase
+        extends RTMGenericCommandLineOptionTest {
+    protected static final String DEFAULT_VALUE = "false";
+
+    protected TestPrintPreciseRTMLockingStatisticsBase(
+            BooleanSupplier predicate) {
+        super(predicate, "PrintPreciseRTMLockingStatistics", true, false,
+                TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE);
+    }
+
+    @Override
+    protected void runNonX86TestCases() throws Throwable {
+        verifyJVMStartup();
+        verifyOptionValues();
+    }
+
+    @Override
+    protected void verifyJVMStartup() throws Throwable {
+        if (Platform.isServer()) {
+            if (!Platform.isDebugBuild()) {
+                String errorMessage = CommandLineOptionTest.
+                        getDiagnosticOptionErrorMessage(optionName);
+                // verify that option is actually diagnostic
+                CommandLineOptionTest.verifySameJVMStartup(
+                        new String[] { errorMessage }, null, ExitCode.FAIL,
+                        prepareOptionValue("true"));
+
+                CommandLineOptionTest.verifySameJVMStartup(null,
+                        new String[] { errorMessage }, ExitCode.OK,
+                        CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+                        prepareOptionValue("true"));
+            } else {
+                CommandLineOptionTest.verifySameJVMStartup(
+                        null, null, ExitCode.OK, prepareOptionValue("true"));
+            }
+        } else {
+            String errorMessage = CommandLineOptionTest.
+                    getUnrecognizedOptionErrorMessage(optionName);
+
+            CommandLineOptionTest.verifySameJVMStartup(
+                    new String[]{errorMessage}, null, ExitCode.FAIL,
+                    CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+                    prepareOptionValue("true"));
+        }
+    }
+
+    @Override
+    protected void verifyOptionValues() throws Throwable {
+        if (Platform.isServer()) {
+            // Verify default value
+            CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                    TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
+                    CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify PrintPreciseRTMLockingStatistics on CPUs with
+ *          rtm support and on VM with rtm locking support,
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI
+ *                   TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig
+ */
+
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig
+        extends TestPrintPreciseRTMLockingStatisticsBase {
+    private TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig() {
+        super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+    }
+
+    @Override
+    protected void verifyOptionValues() throws Throwable {
+        super.verifyOptionValues();
+        // verify default value
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
+                CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+                "-XX:+UseRTMLocking");
+
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
+                CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+                "-XX:-UseRTMLocking", prepareOptionValue("true"));
+
+        // verify that option could be turned on
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
+                CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+                "-XX:+UseRTMLocking", prepareOptionValue("true"));
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig()
+                .test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify PrintPreciseRTMLockingStatistics on CPUs without
+ *          rtm support and/or unsupported VM.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI
+ *                 TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig
+ */
+
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig
+        extends TestPrintPreciseRTMLockingStatisticsBase {
+    private TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig() {
+        super(new NotPredicate(new AndPredicate(new SupportedCPU(),
+                new SupportedVM())));
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig()
+                .test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify RTMAbortRatio option processing on CPU with rtm
+ *          support and on VM with rtm locking support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAbortRatioOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMAbortRatioOptionOnSupportedConfig
+ */
+
+public class TestRTMAbortRatioOptionOnSupportedConfig
+        extends RTMLockingAwareTest {
+    private static final String DEFAULT_VALUE = "50";
+
+    private TestRTMAbortRatioOptionOnSupportedConfig() {
+        super("RTMAbortRatio", false, true,
+                TestRTMAbortRatioOptionOnSupportedConfig.DEFAULT_VALUE,
+                /* correct values */
+                new String[] { "0", "20", "100" },
+                /* incorrect values */
+                new String[] { "-1", "101" },
+                RTMGenericCommandLineOptionTest.RTM_ABORT_RATIO_WARNING);
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMAbortRatioOptionOnSupportedConfig().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify RTMAbortRatio option processing on CPU without rtm
+ *          support or on VM that does not support rtm locking.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAbortRatioOptionOnUnsupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMAbortRatioOptionOnUnsupportedConfig
+ */
+
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestRTMAbortRatioOptionOnUnsupportedConfig
+        extends RTMGenericCommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "50";
+
+    private TestRTMAbortRatioOptionOnUnsupportedConfig() {
+        super(new NotPredicate(new AndPredicate(new SupportedVM(),
+                        new SupportedCPU())),
+                "RTMAbortRatio", false, true,
+                TestRTMAbortRatioOptionOnUnsupportedConfig.DEFAULT_VALUE,
+                "0", "10", "100", "200");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMAbortRatioOptionOnUnsupportedConfig().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify processing of RTMAbortThreshold option.
+ * @library /testlibrary
+ * @build TestRTMAbortThresholdOption
+ * @run main/othervm TestRTMAbortThresholdOption
+ */
+
+public class TestRTMAbortThresholdOption
+        extends RTMGenericCommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "1000";
+
+    private TestRTMAbortThresholdOption() {
+        super(Boolean.TRUE::booleanValue, "RTMAbortThreshold", false, true,
+                TestRTMAbortThresholdOption.DEFAULT_VALUE,
+                "0", "42", "100", "10000");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMAbortThresholdOption().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify processing of RTMLockingCalculationDelay option.
+ * @library /testlibrary
+ * @build TestRTMLockingCalculationDelayOption
+ * @run main/othervm TestRTMLockingCalculationDelayOption
+ */
+
+public class TestRTMLockingCalculationDelayOption
+        extends RTMGenericCommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "0";
+
+    private TestRTMLockingCalculationDelayOption() {
+        super(Boolean.TRUE::booleanValue, "RTMLockingCalculationDelay", false,
+                true, TestRTMLockingCalculationDelayOption.DEFAULT_VALUE);
+    }
+
+    public static void main(String agrs[]) throws Throwable {
+        new TestRTMLockingCalculationDelayOption().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify processing of RTMLockingThreshold option.
+ * @library /testlibrary
+ * @build TestRTMLockingThresholdOption
+ * @run main/othervm TestRTMLockingThresholdOption
+ */
+
+public class TestRTMLockingThresholdOption
+        extends RTMGenericCommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "10000";
+
+    private TestRTMLockingThresholdOption() {
+        super(Boolean.TRUE::booleanValue, "RTMLockingThreshold", false, true,
+                TestRTMLockingThresholdOption.DEFAULT_VALUE);
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMLockingThresholdOption().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify processing of RTMRetryCount option.
+ * @library /testlibrary
+ * @build TestRTMRetryCountOption
+ * @run main/othervm TestRTMRetryCountOption
+ */
+
+public class TestRTMRetryCountOption extends RTMGenericCommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "5";
+
+    private TestRTMRetryCountOption() {
+        super(Boolean.TRUE::booleanValue, "RTMRetryCount", false, false,
+                TestRTMRetryCountOption.DEFAULT_VALUE,
+                "0", "10", "100", "1000");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMRetryCountOption().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify processing of RTMSpinLoopCount option.
+ * @library /testlibrary
+ * @build TestRTMSpinLoopCountOption
+ * @run main/othervm TestRTMSpinLoopCountOption
+ */
+
+public class TestRTMSpinLoopCountOption
+        extends RTMGenericCommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "100";
+
+    private TestRTMSpinLoopCountOption() {
+        super(Boolean.TRUE::booleanValue, "RTMSpinLoopCount", false, true,
+                TestRTMSpinLoopCountOption.DEFAULT_VALUE,
+                "0", "10", "42", "1000");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMSpinLoopCountOption().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify RTMTotalCountIncrRate option processing on CPU with
+ *          rtm support and on VM with rtm locking support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMTotalCountIncrRateOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI
+ *                   TestRTMTotalCountIncrRateOptionOnSupportedConfig
+ */
+
+public class TestRTMTotalCountIncrRateOptionOnSupportedConfig
+        extends RTMLockingAwareTest {
+    private static final String DEFAULT_VALUE = "64";
+
+    private TestRTMTotalCountIncrRateOptionOnSupportedConfig() {
+        super("RTMTotalCountIncrRate", false, true,
+                TestRTMTotalCountIncrRateOptionOnSupportedConfig.DEFAULT_VALUE,
+                /* correct values */
+                new String[] { "1", "2", "128", "1024" },
+                /* incorrect values */
+                new String[] { "-1", "0", "3", "42" },
+                RTMGenericCommandLineOptionTest.RTM_COUNT_INCR_WARNING);
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMTotalCountIncrRateOptionOnSupportedConfig().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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 com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify RTMTotalCountIncrRate option processing on CPU without
+ *          rtm support and/or on VM without rtm locking support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMTotalCountIncrRateOptionOnUnsupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI
+ *                   TestRTMTotalCountIncrRateOptionOnUnsupportedConfig
+ */
+
+public class TestRTMTotalCountIncrRateOptionOnUnsupportedConfig
+        extends RTMGenericCommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "64";
+
+    private TestRTMTotalCountIncrRateOptionOnUnsupportedConfig() {
+        super(new NotPredicate(new AndPredicate(new SupportedCPU(),
+                        new SupportedVM())),
+                "RTMTotalCountIncrRate", false, true,
+                TestRTMTotalCountIncrRateOptionOnUnsupportedConfig
+                        .DEFAULT_VALUE,
+                "-1", "0", "42", "128");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMTotalCountIncrRateOptionOnUnsupportedConfig().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify UseRTMDeopt option processing on CPUs with rtm support
+ *          when rtm locking is supported by VM.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestUseRTMDeoptOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMDeoptOptionOnSupportedConfig
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMDeoptOptionOnSupportedConfig
+        extends CommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "false";
+
+    private TestUseRTMDeoptOptionOnSupportedConfig() {
+        super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+    }
+
+    @Override
+    public void runTestCases() throws Throwable {
+        // verify that option could be turned on
+        CommandLineOptionTest.verifySameJVMStartup(
+                null, null, ExitCode.OK, "-XX:+UseRTMDeopt");
+        // verify that option could be turned off
+        CommandLineOptionTest.verifySameJVMStartup(
+                null, null, ExitCode.OK, "-XX:-UseRTMDeopt");
+        // verify default value
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
+                TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE);
+        // verify default value
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
+                TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE,
+                "-XX:+UseRTMLocking");
+        // verify that option is off when UseRTMLocking is off
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
+                "false", "-XX:-UseRTMLocking", "-XX:+UseRTMDeopt");
+        // verify that option could be turned on
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
+                "true", "-XX:+UseRTMLocking", "-XX:+UseRTMDeopt");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMDeoptOptionOnSupportedConfig().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify UseRTMDeopt option processing on CPUs without rtm support
+ *          or on VMs without rtm locking support.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestUseRTMDeoptOptionOnUnsupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMDeoptOptionOnUnsupportedConfig
+ */
+
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMDeoptOptionOnUnsupportedConfig
+        extends RTMGenericCommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "false";
+
+    private TestUseRTMDeoptOptionOnUnsupportedConfig() {
+        super(new NotPredicate(new AndPredicate(new SupportedCPU(),
+                        new SupportedVM())),
+                "UseRTMDeopt", true, false,
+                TestUseRTMDeoptOptionOnUnsupportedConfig.DEFAULT_VALUE, "true");
+    }
+
+    @Override
+    protected void runX86SupportedVMTestCases() throws Throwable {
+        super.verifyJVMStartup();
+        // verify default value
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                defaultValue);
+        // verify that until RTMLocking is not used, value
+        // will be set to default false.
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                defaultValue, "-XX:+UseRTMDeopt");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMDeoptOptionOnUnsupportedConfig().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify UseRTMForStackLocks option processing on CPU with
+ *          rtm support when VM supports rtm locking.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMForStackLocksOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI
+ *                   TestUseRTMForStackLocksOptionOnSupportedConfig
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMForStackLocksOptionOnSupportedConfig
+        extends CommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "false";
+
+    private TestUseRTMForStackLocksOptionOnSupportedConfig() {
+        super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+    }
+
+    @Override
+    public void runTestCases() throws Throwable {
+        String errorMessage
+                = CommandLineOptionTest.getExperimentalOptionErrorMessage(
+                "UseRTMForStackLocks");
+        String warningMessage
+                = RTMGenericCommandLineOptionTest.RTM_FOR_STACK_LOCKS_WARNING;
+
+        CommandLineOptionTest.verifySameJVMStartup(
+                new String[] { errorMessage }, null, ExitCode.FAIL,
+                "-XX:+UseRTMForStackLocks");
+        // verify that we get a warning when trying to use rtm for stack
+        // lock, but not using rtm locking.
+        CommandLineOptionTest.verifySameJVMStartup(
+                new String[] { warningMessage }, null, ExitCode.OK,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:+UseRTMForStackLocks",
+                "-XX:-UseRTMLocking");
+        // verify that we don't get a warning when no using rtm for stack
+        // lock and not using rtm locking.
+        CommandLineOptionTest.verifySameJVMStartup(null,
+                new String[] { warningMessage }, ExitCode.OK,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:-UseRTMForStackLocks",
+                "-XX:-UseRTMLocking");
+        // verify that we don't get a warning when using rtm for stack
+        // lock and using rtm locking.
+        CommandLineOptionTest.verifySameJVMStartup(null,
+                new String[] { warningMessage }, ExitCode.OK,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:+UseRTMForStackLocks",
+                "-XX:+UseRTMLocking");
+        // verify that default value if false
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks",
+                TestUseRTMForStackLocksOptionOnSupportedConfig.DEFAULT_VALUE,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+        // verify that default value is false even with +UseRTMLocking
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks",
+                TestUseRTMForStackLocksOptionOnSupportedConfig.DEFAULT_VALUE,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:+UseRTMLocking");
+        // verify that we can turn the option on
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks",
+                "true", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:+UseRTMLocking", "-XX:+UseRTMForStackLocks");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMForStackLocksOptionOnSupportedConfig().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify UseRTMForStackLocks option processing on CPUs without
+ *          rtm support and/or on VMs without rtm locking support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMForStackLocksOptionOnUnsupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI
+ *                    TestUseRTMForStackLocksOptionOnUnsupportedConfig
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMForStackLocksOptionOnUnsupportedConfig
+        extends RTMGenericCommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "false";
+
+    private TestUseRTMForStackLocksOptionOnUnsupportedConfig() {
+        super(new NotPredicate(new AndPredicate(new SupportedCPU(),
+                        new SupportedVM())),
+                "UseRTMForStackLocks", true, true,
+                TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE,
+                "true");
+    }
+
+    @Override
+    protected void runX86SupportedVMTestCases() throws Throwable {
+        // verify that option is experimental
+        CommandLineOptionTest.verifySameJVMStartup(
+                new String[]{ experimentalOptionError },
+                null, ExitCode.FAIL, prepareOptionValue("true"));
+
+        CommandLineOptionTest.verifySameJVMStartup(
+                new String[]{ experimentalOptionError },
+                null, ExitCode.FAIL, prepareOptionValue("false"));
+
+        // verify that if we turn it on, then VM output will contain
+        // warning saying that this option could be turned on only
+        // when we use rtm locking
+        CommandLineOptionTest.verifySameJVMStartup(
+                new String[]{
+                    RTMGenericCommandLineOptionTest.RTM_FOR_STACK_LOCKS_WARNING
+                },
+                null, ExitCode.OK,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                prepareOptionValue("true")
+        );
+        // verify that options is turned off by default
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+        // verify that it could not be turned on without rtm locking
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+                TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                prepareOptionValue("true"));
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMForStackLocksOptionOnUnsupportedConfig().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify UseRTMLocking option processing on CPU with rtm support and
+ *          on VM with rtm-locking support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockingOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMLockingOptionOnSupportedConfig
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMLockingOptionOnSupportedConfig
+        extends CommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "false";
+
+    private TestUseRTMLockingOptionOnSupportedConfig() {
+        super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+    }
+
+    @Override
+    public void runTestCases() throws Throwable {
+        String unrecongnizedOption
+                =  CommandLineOptionTest.getUnrecognizedOptionErrorMessage(
+                "UseRTMLocking");
+        // verify that there are no warning or error in VM output
+        CommandLineOptionTest.verifySameJVMStartup(null,
+                new String[]{
+                        RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR,
+                        unrecongnizedOption
+                }, ExitCode.OK, "-XX:+UseRTMLocking"
+        );
+
+        CommandLineOptionTest.verifySameJVMStartup(null,
+                new String[]{
+                        RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR,
+                        unrecongnizedOption
+                }, ExitCode.OK, "-XX:-UseRTMLocking"
+        );
+        // verify that UseRTMLocking is of by default
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+                TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE);
+        // verify that we can change UseRTMLocking value
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+                TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE,
+                "-XX:-UseRTMLocking");
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+                "true", "-XX:+UseRTMLocking");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMLockingOptionOnSupportedConfig().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify UseRTMLocking option processing on CPU without
+ *          rtm support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockingOptionOnUnsupportedCPU
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMLockingOptionOnUnsupportedCPU
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMLockingOptionOnUnsupportedCPU
+        extends CommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "false";
+
+    private TestUseRTMLockingOptionOnUnsupportedCPU() {
+        super(new AndPredicate(new NotPredicate(new SupportedCPU()),
+                new SupportedVM()));
+    }
+
+    @Override
+    public void runTestCases() throws Throwable {
+        String unrecongnizedOption
+                = CommandLineOptionTest.getUnrecognizedOptionErrorMessage(
+                "UseRTMLocking");
+        String errorMessage = RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR;
+
+        if (Platform.isX86() || Platform.isX64()) {
+            // verify that we get an error when use +UseRTMLocking
+            // on unsupported CPU
+            CommandLineOptionTest.verifySameJVMStartup(
+                    new String[] { errorMessage },
+                    new String[] { unrecongnizedOption },
+                    ExitCode.FAIL, "-XX:+UseRTMLocking");
+            // verify that we can pass -UseRTMLocking without
+            // getting any error messages
+            CommandLineOptionTest.verifySameJVMStartup(
+                    null,
+                    new String[]{
+                            errorMessage,
+                            unrecongnizedOption
+                    }, ExitCode.OK, "-XX:-UseRTMLocking");
+
+            // verify that UseRTMLocking is false by default
+            CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+                    TestUseRTMLockingOptionOnUnsupportedCPU.DEFAULT_VALUE);
+        } else {
+            // verify that on non-x86 CPUs RTMLocking could not be used
+            CommandLineOptionTest.verifySameJVMStartup(
+                    new String[] { unrecongnizedOption },
+                    null, ExitCode.FAIL, "-XX:+UseRTMLocking");
+
+            CommandLineOptionTest.verifySameJVMStartup(
+                    new String[] { unrecongnizedOption },
+                    null, ExitCode.FAIL, "-XX:-UseRTMLocking");
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMLockingOptionOnUnsupportedCPU().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify UseRTMLocking option processing on CPU with rtm support
+ *          in case when VM should not support this option.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockingOptionOnUnsupportedVM
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMLockingOptionOnUnsupportedVM
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMLockingOptionOnUnsupportedVM
+        extends CommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "false";
+
+    private TestUseRTMLockingOptionOnUnsupportedVM() {
+        super(new AndPredicate(new SupportedCPU(),
+                new NotPredicate(new SupportedVM())));
+    }
+    @Override
+    public void runTestCases() throws Throwable {
+        String errorMessage
+                = RTMGenericCommandLineOptionTest.RTM_UNSUPPORTED_VM_ERROR;
+        // verify that we can't use +UseRTMLocking
+        CommandLineOptionTest.verifySameJVMStartup(
+                new String[] { errorMessage }, null, ExitCode.FAIL,
+                "-XX:+UseRTMLocking");
+        // verify that we can turn it off
+        CommandLineOptionTest.verifySameJVMStartup(null,
+                new String[] { errorMessage }, ExitCode.OK,
+                "-XX:-UseRTMLocking");
+        // verify that it is off by default
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+                TestUseRTMLockingOptionOnUnsupportedVM.DEFAULT_VALUE);
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMLockingOptionOnUnsupportedVM().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify processing of UseRTMLocking and UseBiasedLocking
+ *          options combination on CPU and VM with rtm support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockingOptionWithBiasedLocking
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMLockingOptionWithBiasedLocking
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMLockingOptionWithBiasedLocking
+        extends CommandLineOptionTest {
+    private TestUseRTMLockingOptionWithBiasedLocking() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    public void runTestCases() throws Throwable {
+        String warningMessage
+                = RTMGenericCommandLineOptionTest.RTM_BIASED_LOCKING_WARNING;
+        // verify that we will not get a warning
+        CommandLineOptionTest.verifySameJVMStartup(null,
+                new String[] { warningMessage }, ExitCode.OK,
+                "-XX:+UseRTMLocking", "-XX:-UseBiasedLocking");
+        // verify that we will get a warning
+        CommandLineOptionTest.verifySameJVMStartup(
+                new String[] { warningMessage }, null, ExitCode.OK,
+                "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking");
+        // verify that UseBiasedLocking is false when we use rtm locking
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking",
+                "false", "-XX:+UseRTMLocking");
+        // verify that we can't turn on biased locking when
+        // using rtm locking
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking",
+                "false", "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMLockingOptionWithBiasedLocking().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify processing of UseRTMXendForLockBusy option.
+ * @library /testlibrary
+ * @build TestUseRTMXendForLockBusyOption
+ * @run main/othervm TestUseRTMXendForLockBusyOption
+ */
+
+public class TestUseRTMXendForLockBusyOption
+        extends RTMGenericCommandLineOptionTest {
+    private static final String DEFAULT_VALUE = "true";
+
+    public TestUseRTMXendForLockBusyOption() {
+        super(Boolean.TRUE::booleanValue, "UseRTMXendForLockBusy", true, true,
+                TestUseRTMXendForLockBusyOption.DEFAULT_VALUE, "true");
+    }
+
+    public static void main(String agrs[]) throws Throwable {
+        new TestUseRTMXendForLockBusyOption().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that RTMAbortRatio affects amount of aborts before
+ *          deoptimization.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAbortRatio
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMAbortRatio
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * Test verifies that method will be deoptimized on high abort ratio
+ * as soon as abort ratio reaches RTMAbortRatio's value.
+ */
+public class TestRTMAbortRatio extends CommandLineOptionTest {
+    private TestRTMAbortRatio() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        verifyAbortRatio(0, false);
+        verifyAbortRatio(10, false);
+        verifyAbortRatio(50, false);
+        verifyAbortRatio(100, false);
+
+        verifyAbortRatio(0, true);
+        verifyAbortRatio(10, true);
+        verifyAbortRatio(50, true);
+        verifyAbortRatio(100, true);
+    }
+
+    private void verifyAbortRatio(int abortRatio, boolean useStackLock)
+            throws Throwable {
+        CompilableTest test = new Test();
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                test,
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+                        useStackLock),
+                "-XX:+UseRTMDeopt",
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:RTMAbortThreshold=0",
+                CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+                        10 * Test.TOTAL_ITERATIONS),
+                CommandLineOptionTest.prepareNumericFlag("RTMAbortRatio",
+                        abortRatio),
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                test.getClass().getName(),
+                Boolean.toString(!useStackLock));
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+                + "exactly one RTM locking statistics entry.");
+
+        RTMLockingStatistics lock = statistics.get(0);
+        int actualRatio;
+
+        if (lock.getTotalAborts() == 1L) {
+            actualRatio = 0;
+        } else {
+            actualRatio = (int) (lock.getTotalLocks()
+                    / (lock.getTotalAborts() - 1L));
+        }
+
+        Asserts.assertLTE(actualRatio, abortRatio, String.format(
+                "Actual abort ratio (%d) should lower or equal to "
+                + "specified (%d).", actualRatio, abortRatio));
+    }
+
+    /**
+     * Force abort after {@code Test.WARMUP_ITERATIONS} is done.
+     */
+    public static class Test implements CompilableTest {
+        private static final int TOTAL_ITERATIONS = 10000;
+        private static final int WARMUP_ITERATIONS = 1000;
+        private static final Unsafe UNSAFE = Utils.getUnsafe();
+        private final Object monitor = new Object();
+        // Following field have to be static in order to avoid escape analysis.
+        @SuppressWarnings("UnsuedDeclaration")
+        private static int field = 0;
+
+        @Override
+        public String getMethodWithLockName() {
+             return this.getClass().getName() + "::lock";
+         }
+
+        @Override
+        public String[] getMethodsToCompileNames() {
+            return new String[] {
+                    getMethodWithLockName(),
+                    Unsafe.class.getName() + "::addressSize"
+            };
+        }
+
+        public void lock(boolean abort) {
+            synchronized(monitor) {
+                if (abort) {
+                    Test.UNSAFE.addressSize();
+                }
+            }
+        }
+
+        /**
+         * Usage:
+         * Test &lt;inflate monitor&gt;
+         */
+        public static void main(String args[]) throws Throwable {
+            Asserts.assertGTE(args.length, 1, "One argument required.");
+            Test t = new Test();
+            if (Boolean.valueOf(args[0])) {
+                AbortProvoker.inflateMonitor(t.monitor);
+            }
+            for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) {
+                t.lock(i >= Test.WARMUP_ITERATIONS);
+            }
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMAbortRatio().test();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that RTMAbortThreshold option affects
+ *          amount of aborts after which abort ratio is calculated.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAbortThreshold
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMAbortThreshold
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that on RTMAbortThreshold option actually affects how soon
+ * method will be deoptimized on high abort ratio.
+ */
+public class TestRTMAbortThreshold extends CommandLineOptionTest {
+    private TestRTMAbortThreshold() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        verifyAbortThreshold(false, 1);
+        verifyAbortThreshold(false, 10);
+        verifyAbortThreshold(false, 1000);
+
+        verifyAbortThreshold(true, 1);
+        verifyAbortThreshold(true, 10);
+        verifyAbortThreshold(true, 1000);
+    }
+
+    private void verifyAbortThreshold(boolean useStackLock,
+            long abortThreshold) throws Throwable {
+        AbortProvoker provoker = AbortType.XABORT.provoker();
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                provoker,
+                "-XX:+UseRTMDeopt",
+                "-XX:RTMAbortRatio=0",
+                CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+                        abortThreshold),
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+                        useStackLock),
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                AbortProvoker.class.getName(),
+                AbortType.XABORT.toString(),
+                Boolean.toString(!useStackLock));
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+                + "exactly one RTM locking statistics entry for method "
+                + provoker.getMethodWithLockName());
+
+        Asserts.assertEQ(statistics.get(0).getTotalLocks(), abortThreshold,
+                String.format("Expected that method with rtm lock elision was"
+                        + " deoptimized after %d lock attempts",
+                        abortThreshold));
+    }
+
+    public static void main(String args[]) throws Throwable {
+         new TestRTMAbortThreshold().test();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that if we use RTMDeopt, then deoptimization
+ *          caused by reason other then rtm_state_change will reset
+ *          method's RTM state. And if we don't use RTMDeopt, then
+ *          RTM state remain the same after such deoptimization.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAfterNonRTMDeopt
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMAfterNonRTMDeopt
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * To verify that with +UseRTMDeopt method's RTM state will be
+ * changed to ProfileRTM on deoptimization unrelated to
+ * rtm_state_change following sequence of events is used:
+ * <pre>
+ *
+ *     rtm state ^
+ *               |
+ *       UseRTM  |      ******|     ******
+ *               |            |
+ *   ProfileRTM  |******|     |*****|
+ *               |      |     |     |
+ *              0-------|-----|-----|---------------------&gt; time
+ *                      |     |     \ force abort
+ *                      |     |
+ *                      |     \ force deoptimization
+ *                      |
+ *                      \ force xabort
+ * </pre>
+ * When xabort is forced by native method call method should
+ * change it's state to UseRTM, because we use RTMAbortRatio=100
+ * and low RTMLockingThreshold, so at this point actual abort
+ * ratio will be below 100% and there should be enough lock
+ * attempts to recompile method without RTM profiling.
+ */
+public class TestRTMAfterNonRTMDeopt extends CommandLineOptionTest {
+    private static final int ABORT_THRESHOLD = 1000;
+    private static final String RANGE_CHECK = "range_check";
+
+    private TestRTMAfterNonRTMDeopt() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        verifyRTMAfterDeopt(false, false);
+        verifyRTMAfterDeopt(true, false);
+
+        verifyRTMAfterDeopt(false, true);
+        verifyRTMAfterDeopt(true, true);
+    }
+
+    private void verifyRTMAfterDeopt(boolean useStackLock,
+            boolean useRTMDeopt) throws Throwable {
+        CompilableTest test = new Test();
+        String logFile = String.format("rtm_%s_stack_lock_%s_deopt.xml",
+                (useStackLock ? "use" : "no"), (useRTMDeopt ? "use" : "no"));
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                logFile,
+                test,
+                "-XX:CompileThreshold=1",
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+                        useStackLock),
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt",
+                        useRTMDeopt),
+                "-XX:RTMAbortRatio=100",
+                CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+                        TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD),
+                CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+                        TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD / 2L),
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                Test.class.getName(),
+                Boolean.toString(!useStackLock)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        int traps = RTMTestBase.firedRTMStateChangeTraps(logFile);
+
+        if (useRTMDeopt) {
+            Asserts.assertEQ(traps, 2, "Two uncommon traps with "
+                    + "reason rtm_state_change should be fired.");
+        } else {
+            Asserts.assertEQ(traps, 0, "No uncommon traps with "
+                    + "reason rtm_state_change should be fired.");
+        }
+
+        int rangeCheckTraps = RTMTestBase.firedUncommonTraps(logFile,
+                TestRTMAfterNonRTMDeopt.RANGE_CHECK);
+
+        Asserts.assertEQ(rangeCheckTraps, 1,
+                "One range_check uncommon trap should be fired.");
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        int expectedStatEntries = (useRTMDeopt ? 4 : 2);
+
+        Asserts.assertEQ(statistics.size(), expectedStatEntries,
+                String.format("VM output should contain %d RTM locking "
+                        + "statistics entries.", expectedStatEntries));
+    }
+
+    public static class Test implements CompilableTest {
+        // Following field have to be static in order to avoid escape analysis.
+        @SuppressWarnings("UnsuedDeclaration")
+        private static int field = 0;
+        private static final int ITERATIONS = 10000;
+        private static final int RANGE_CHECK_AT = ITERATIONS / 2;
+        private static final Unsafe UNSAFE = Utils.getUnsafe();
+        private final Object monitor = new Object();
+
+        @Override
+        public String getMethodWithLockName() {
+            return this.getClass().getName() + "::forceAbort";
+        }
+
+        @Override
+        public String[] getMethodsToCompileNames() {
+            return new String[] {
+                getMethodWithLockName(),
+                sun.misc.Unsafe.class.getName() + "::forceAbort"
+            };
+        }
+
+        public void forceAbort(int a[], boolean abort) {
+            try {
+                synchronized(monitor) {
+                    a[0]++;
+                    if (abort) {
+                        Test.field = Test.UNSAFE.addressSize();
+                    }
+                }
+            } catch (Throwable t) {
+                // suppress any throwables
+            }
+        }
+
+        /**
+         * Usage:
+         * Test &lt;inflate monitor&gt;
+         */
+        public static void main(String args[]) throws Throwable {
+            Test t = new Test();
+
+            if (Boolean.valueOf(args[0])) {
+                AbortProvoker.inflateMonitor(t.monitor);
+            }
+
+            int tmp[] = new int[1];
+
+            for (int i = 0; i < Test.ITERATIONS; i++ ) {
+                if (i == Test.RANGE_CHECK_AT) {
+                    t.forceAbort(new int[0], false);
+                } else {
+                    boolean isThreshold
+                            = (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD);
+                    boolean isThresholdPlusRange
+                            = (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD
+                            + Test.RANGE_CHECK_AT);
+                    t.forceAbort(tmp, isThreshold || isThresholdPlusRange);
+                }
+            }
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMAfterNonRTMDeopt().test();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that on high abort ratio method will be recompiled
+ *          without rtm locking.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMDeoptOnHighAbortRatio
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMDeoptOnHighAbortRatio
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that on high abort ratio method wil be deoptimized with
+ * <i>rtm_state_change</i> reason and after that RTM-based lock elision will not
+ * be used for that method.
+ * This test make asserts on total locks count done by compiled method,
+ * so in order to avoid issue with retriable locks -XX:RTMRetryCount=0 is used.
+ * For more details on that issue see {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestRTMDeoptOnHighAbortRatio extends CommandLineOptionTest {
+    private static final long ABORT_THRESHOLD
+            = AbortProvoker.DEFAULT_ITERATIONS / 2L;
+
+    private TestRTMDeoptOnHighAbortRatio() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        verifyDeopt(false);
+        verifyDeopt(true);
+    }
+
+    private void verifyDeopt(boolean useStackLock) throws Throwable {
+        AbortProvoker provoker = AbortType.XABORT.provoker();
+        String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+                (useStackLock ? "use" : "no"));
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                logFileName,
+                provoker,
+                "-XX:+UseRTMDeopt",
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+                        useStackLock),
+                "-XX:RTMRetryCount=0",
+                CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+                        TestRTMDeoptOnHighAbortRatio.ABORT_THRESHOLD),
+                "-XX:RTMAbortRatio=100",
+                "-XX:CompileThreshold=1",
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                AbortProvoker.class.getName(),
+                AbortType.XABORT.toString(),
+                Boolean.toString(!useStackLock)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+        Asserts.assertEQ(firedTraps, 1, "Expected to get only one "
+                + "deoptimization due to rtm state change");
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+                + "exactly one RTM locking statistics entry for method "
+                + provoker.getMethodWithLockName());
+
+        Asserts.assertEQ(statistics.get(0).getTotalLocks(),
+                TestRTMDeoptOnHighAbortRatio.ABORT_THRESHOLD,
+                "After AbortThreshold was reached, method should be"
+                + " recompiled without rtm lock eliding.");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMDeoptOnHighAbortRatio().test();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that on low abort ratio method will be recompiled.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMDeoptOnLowAbortRatio
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMDeoptOnLowAbortRatio
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * Test verifies that low abort ratio method will be deoptimized with
+ * <i>rtm_state_change</i> reason and will continue to use RTM-based lock
+ * elision after that.
+ * This test make asserts on total locks count done by compiled method,
+ * so in order to avoid issue with retriable locks -XX:RTMRetryCount=0 is used.
+ * For more details on that issue see {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestRTMDeoptOnLowAbortRatio extends CommandLineOptionTest {
+    private static final long LOCKING_THRESHOLD = 100L;
+
+    private TestRTMDeoptOnLowAbortRatio() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        verifyRTMDeopt(false);
+        verifyRTMDeopt(true);
+    }
+
+    private void verifyRTMDeopt(boolean useStackLock) throws Throwable {
+        CompilableTest test = new Test();
+        String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+                                           useStackLock ? "use" : "no");
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                logFileName,
+                test,
+                "-XX:+UseRTMDeopt",
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+                        useStackLock),
+                CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+                        TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD),
+                "-XX:RTMAbortThreshold=1",
+                "-XX:RTMAbortRatio=100",
+                "-XX:CompileThreshold=1",
+                "-XX:RTMRetryCount=0",
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                Test.class.getName(),
+                Boolean.toString(!useStackLock)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+        Asserts.assertEQ(firedTraps, 1,
+                        "Expected to get only one deoptimization due to rtm"
+                        + " state change");
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 2,
+                         "VM output should contain two RTM locking "
+                         + "statistics entries for method "
+                         + test.getMethodWithLockName());
+
+        RTMLockingStatistics statisticsBeforeDeopt = null;
+
+        for (RTMLockingStatistics s : statistics) {
+            if (s.getTotalLocks()
+                    == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD + 1L) {
+                Asserts.assertNull(statisticsBeforeDeopt,
+                        "Only one abort was expected during test run");
+                statisticsBeforeDeopt = s;
+            }
+        }
+
+        Asserts.assertNotNull(statisticsBeforeDeopt,
+                "After LockThreshold was reached, method should be recompiled "
+                + "with rtm lock eliding.");
+    }
+
+    public static class Test implements CompilableTest {
+        private static final Unsafe UNSAFE = Utils.getUnsafe();
+        private final Object monitor = new Object();
+
+        @Override
+        public String getMethodWithLockName() {
+            return this.getClass().getName() + "::forceAbort";
+        }
+
+        @Override
+        public String[] getMethodsToCompileNames() {
+            return new String[] {
+                getMethodWithLockName(),
+                sun.misc.Unsafe.class.getName() + "::addressSize"
+            };
+        }
+
+        public void forceAbort(boolean abort) {
+            synchronized(monitor) {
+                if (abort) {
+                    Test.UNSAFE.addressSize();
+                }
+            }
+        }
+
+        /**
+         * Usage:
+         * Test &lt;inflate monitor&gt;
+         */
+        public static void main(String args[]) throws Throwable {
+            Asserts.assertGTE(args.length, 1, "One argument required.");
+            Test t = new Test();
+
+            if (Boolean.valueOf(args[0])) {
+                AbortProvoker.inflateMonitor(t.monitor);
+            }
+            for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
+                t.forceAbort(
+                        i == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD);
+            }
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMDeoptOnLowAbortRatio().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that RTMLockingCalculationDelay affect when
+ *          abort ratio calculation is started.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMLockingCalculationDelay
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMLockingCalculationDelay
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that abort ratio calculation could be delayed using
+ * RTMLockingCalculationDelay option.
+ */
+public class TestRTMLockingCalculationDelay extends CommandLineOptionTest {
+    private static final boolean INFLATE_MONITOR = true;
+
+    private TestRTMLockingCalculationDelay() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        // verify that calculation will be started immediately
+        verifyLockingCalculationDelay(0, 0, true);
+
+        // verify that calculation will not be started during
+        // first 10 minutes, while test will be started immediately
+        verifyLockingCalculationDelay(600000, 0, false);
+
+        // verify that calculation will be started after a second
+        verifyLockingCalculationDelay(1000, 1000, true);
+    }
+
+    private void verifyLockingCalculationDelay(long delay, long testDelay,
+            boolean deoptExpected) throws Throwable {
+        AbortProvoker provoker = AbortType.XABORT.provoker();
+        String logFileName = String.format("rtm_delay_%d_%d.xml", delay,
+                testDelay);
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                logFileName,
+                provoker,
+                "-XX:+UseRTMDeopt",
+                CommandLineOptionTest.prepareNumericFlag(
+                        "RTMLockingCalculationDelay", delay),
+                "-XX:RTMAbortRatio=0",
+                "-XX:RTMAbortThreshold=0",
+                AbortProvoker.class.getName(),
+                AbortType.XABORT.toString(),
+                Boolean.toString(
+                        TestRTMLockingCalculationDelay.INFLATE_MONITOR),
+                Long.toString(AbortProvoker.DEFAULT_ITERATIONS),
+                Long.toString(testDelay)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        int deopts = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+        if (deoptExpected) {
+            Asserts.assertGT(deopts, 0, "At least one deoptimization due to "
+                    + "rtm_state_chage is expected");
+        } else {
+            Asserts.assertEQ(deopts, 0, "No deoptimizations due to "
+                    + "rtm_state_chage are expected");
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMLockingCalculationDelay().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that RTMLockingThreshold affects rtm state transition
+ *          ProfileRTM => UseRTM.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMLockingThreshold
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMLockingThreshold
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * Test verifies that RTMLockingThreshold option actually affects how soon
+ * method will be deoptimized on low abort ratio.
+ */
+public class TestRTMLockingThreshold extends CommandLineOptionTest {
+    private TestRTMLockingThreshold() {
+        super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+    }
+
+    /**
+     * We use non-zero abort threshold to avoid abort related to
+     * interrupts, VMM calls, etc. during first lock attempt.
+     *
+     */
+    private static final int ABORT_THRESHOLD = 10;
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        verifyLockingThreshold(0, false);
+        verifyLockingThreshold(100, false);
+        verifyLockingThreshold(1000, false);
+
+        verifyLockingThreshold(0, true);
+        verifyLockingThreshold(100, true);
+        verifyLockingThreshold(1000, true);
+    }
+
+    private void verifyLockingThreshold(int lockingThreshold,
+            boolean useStackLock) throws Throwable {
+        CompilableTest test = new Test();
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                test,
+                "-XX:CompileThreshold=1",
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+                        useStackLock),
+                "-XX:+UseRTMDeopt",
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:RTMRetryCount=0",
+                CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+                        TestRTMLockingThreshold.ABORT_THRESHOLD),
+                CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+                        lockingThreshold),
+                "-XX:RTMAbortRatio=100",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                Test.class.getName(),
+                Boolean.toString(!useStackLock),
+                Integer.toString(lockingThreshold)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 2, "VM output should contain two "
+                + "RTM locking statistics entries.");
+
+        /**
+         * We force abort on each odd iteration, so if RTMLockingThreshold==0,
+         * then we have to make 1 call without abort to avoid rtm state
+         * transition to NoRTM (otherwise actual abort ratio will be 100%),
+         * and after that make 1 call with abort to force deoptimization.
+         * This leads us to two locks for threshold 0.
+         * For other threshold values we have to make RTMLockingThreshold + 1
+         * locks if locking threshold is even, or + 0 if odd.
+         */
+        long expectedValue = lockingThreshold +
+                (lockingThreshold == 0L ? 2L : lockingThreshold % 2L);
+
+        RTMLockingStatistics statBeforeDeopt = null;
+        for (RTMLockingStatistics s : statistics) {
+            if (s.getTotalLocks() == expectedValue) {
+                Asserts.assertNull(statBeforeDeopt,
+                        "Only one statistics entry should contain aborts");
+                statBeforeDeopt = s;
+            }
+        }
+
+        Asserts.assertNotNull(statBeforeDeopt, "There should be exactly one "
+                + "statistics entry corresponding to ProfileRTM state.");
+    }
+
+    public static class Test implements CompilableTest {
+        // Following field have to be static in order to avoid escape analysis.
+        @SuppressWarnings("UnsuedDeclaration")
+        private static int field = 0;
+        private static final int TOTAL_ITERATIONS = 10000;
+        private static final Unsafe UNSAFE = Utils.getUnsafe();
+        private final Object monitor = new Object();
+
+
+        @Override
+        public String getMethodWithLockName() {
+            return this.getClass().getName() + "::lock";
+        }
+
+        @Override
+        public String[] getMethodsToCompileNames() {
+            return new String[] {
+                getMethodWithLockName(),
+                sun.misc.Unsafe.class.getName() + "::addressSize"
+            };
+        }
+
+        public void lock(boolean abort) {
+            synchronized(monitor) {
+                if (abort) {
+                    Test.field += Test.UNSAFE.addressSize();
+                }
+            }
+        }
+
+        /**
+         * Usage:
+         * Test &lt;inflate monitor&gt;
+         */
+        public static void main(String args[]) throws Throwable {
+            Asserts.assertGTE(args.length, 1, "One argument required.");
+            Test t = new Test();
+
+            if (Boolean.valueOf(args[0])) {
+                AbortProvoker.inflateMonitor(t.monitor);
+            }
+            for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) {
+                t.lock(i % 2 == 1);
+            }
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMLockingThreshold().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that RTMRetryCount affects actual amount of retries.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMRetryCount
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMRetryCount
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTMRetryCount option actually affects amount of
+ * retries on lock busy.
+ */
+public class TestRTMRetryCount extends CommandLineOptionTest {
+    /**
+     * Time in ms, during which busy lock will be locked.
+     */
+    private static final int LOCKING_TIME = 5000;
+    private static final boolean INFLATE_MONITOR = true;
+
+    private TestRTMRetryCount() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        verifyRTMRetryCount(0);
+        verifyRTMRetryCount(1);
+        verifyRTMRetryCount(5);
+        verifyRTMRetryCount(10);
+    }
+
+    private void verifyRTMRetryCount(int retryCount) throws Throwable {
+        CompilableTest busyLock = new BusyLock();
+        long expectedAborts = retryCount + 1L;
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                busyLock,
+                "-XX:-UseRTMXendForLockBusy",
+                "-XX:RTMTotalCountIncrRate=1",
+                CommandLineOptionTest.prepareNumericFlag("RTMRetryCount",
+                        retryCount),
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                BusyLock.class.getName(),
+                Boolean.toString(TestRTMRetryCount.INFLATE_MONITOR),
+                Integer.toString(TestRTMRetryCount.LOCKING_TIME)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                busyLock.getMethodWithLockName(), outputAnalyzer.getStdout());
+
+        Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+                + "exactly one rtm locking statistics entry for method "
+                + busyLock.getMethodWithLockName());
+
+        Asserts.assertEQ(statistics.get(0).getTotalAborts(), expectedAborts,
+                String.format("It is expected to get %d aborts",
+                        expectedAborts));
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMRetryCount().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that RTMSpinLoopCount affects time spent
+ *          between locking attempts.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMSpinLoopCount
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMSpinLoopCount
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTMSpinLoopCount increase time spent between retries
+ * by comparing amount of retries done with different RTMSpinLoopCount's values.
+ */
+public class TestRTMSpinLoopCount extends CommandLineOptionTest {
+    private static final int LOCKING_TIME = 1000;
+    private static final int RTM_RETRY_COUNT = 1000;
+    private static final boolean INFLATE_MONITOR = true;
+    private static final long MAX_ABORTS = RTM_RETRY_COUNT + 1L;
+    private static final int[] SPIN_LOOP_COUNTS
+            = new int[] { 0, 100, 1_000, 1_000_000, 10_000_000 };
+
+    private TestRTMSpinLoopCount() {
+        super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        long[] aborts = new long[TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length];
+        for (int i = 0; i < TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length; i++) {
+            aborts[i] = getAbortsCountOnLockBusy(
+                    TestRTMSpinLoopCount.SPIN_LOOP_COUNTS[i]);
+        }
+
+        for (int i = 1; i < aborts.length; i++) {
+            Asserts.assertLTE(aborts[i], aborts[i - 1], "Increased spin loop "
+                    + "count should not increase retries count.");
+        }
+    }
+
+    private long getAbortsCountOnLockBusy(int spinLoopCount) throws Throwable {
+        CompilableTest test = new BusyLock();
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                test,
+                CommandLineOptionTest.prepareNumericFlag("RTMRetryCount",
+                        TestRTMSpinLoopCount.RTM_RETRY_COUNT),
+                CommandLineOptionTest.prepareNumericFlag("RTMSpinLoopCount",
+                        spinLoopCount),
+                "-XX:-UseRTMXendForLockBusy",
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                BusyLock.class.getName(),
+                Boolean.toString(TestRTMSpinLoopCount.INFLATE_MONITOR),
+                Integer.toString(TestRTMSpinLoopCount.LOCKING_TIME)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 1,
+                "VM output should contain exactly one entry for method "
+                 + test.getMethodWithLockName());
+
+        RTMLockingStatistics lock = statistics.get(0);
+
+        Asserts.assertLTE(lock.getTotalAborts(),
+                TestRTMSpinLoopCount.MAX_ABORTS, String.format("Total aborts "
+                        + "count (%d) should be less or equal to %d",
+                        lock.getTotalAborts(),
+                        TestRTMSpinLoopCount.MAX_ABORTS));
+
+        return lock.getTotalAborts();
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMSpinLoopCount().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that RTMTotalCountIncrRate option affects
+ *          RTM locking statistics.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMTotalCountIncrRate
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestRTMTotalCountIncrRate
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that with RTMTotalCountIncrRate=1 RTM locking statistics
+ * contains precise information abort attempted locks and that with other values
+ * statistics contains information abort non-zero locking attempts.
+ * Since assert done for RTMTotalCountIncrRate=1 is pretty strict, test uses
+ * -XX:RTMRetryCount=0 to avoid issue with retriable aborts. For more details on
+ * that issue see {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestRTMTotalCountIncrRate extends CommandLineOptionTest {
+    private TestRTMTotalCountIncrRate() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        verifyLocksCount(1, false);
+        verifyLocksCount(64, false);
+        verifyLocksCount(128, false);
+        verifyLocksCount(1, true);
+        verifyLocksCount(64, true);
+        verifyLocksCount(128, true);
+    }
+
+    private void verifyLocksCount(int incrRate, boolean useStackLock)
+            throws Throwable{
+        CompilableTest test = new Test();
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                test,
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+                        useStackLock),
+                CommandLineOptionTest.prepareNumericFlag(
+                        "RTMTotalCountIncrRate", incrRate),
+                "-XX:RTMRetryCount=0",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                Test.class.getName(),
+                Boolean.toString(!useStackLock)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+                + "exactly one RTM locking statistics entry for method "
+                + test.getMethodWithLockName());
+
+        RTMLockingStatistics lock = statistics.get(0);
+        if (incrRate == 1) {
+            Asserts.assertEQ(lock.getTotalLocks(), Test.TOTAL_ITERATIONS,
+                    "Total locks should be exactly the same as amount of "
+                    + "iterations.");
+        } else {
+            Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM statistics "
+                    + "should contain information for at least on lock.");
+        }
+    }
+
+    public static class Test implements CompilableTest {
+        private static final long TOTAL_ITERATIONS = 10000L;
+        private final Object monitor = new Object();
+        // Following field have to be static in order to avoid escape analysis.
+        @SuppressWarnings("UnsuedDeclaration")
+        private static int field = 0;
+
+        @Override
+        public String getMethodWithLockName() {
+            return this.getClass().getName() + "::lock";
+        }
+
+        @Override
+        public String[] getMethodsToCompileNames() {
+            return new String[] {
+                getMethodWithLockName()
+            };
+        }
+
+        public void lock() {
+            synchronized(monitor) {
+                Test.field++;
+            }
+        }
+
+        /**
+         * Usage:
+         * Test &lt;inflate monitor&gt;
+         */
+        public static void main(String args[]) throws Throwable {
+            Asserts.assertGTE(args.length, 1, "One argument required.");
+            Test test = new Test();
+
+            if (Boolean.valueOf(args[0])) {
+                AbortProvoker.inflateMonitor(test.monitor);
+            }
+            for (long i = 0L; i < Test.TOTAL_ITERATIONS; i++) {
+                test.lock();
+            }
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestRTMTotalCountIncrRate().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that rtm locking is used for stack locks before
+ *          inflation and after it used for inflated locks.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMAfterLockInflation
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMAfterLockInflation
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTM is used after lock inflation by executing compiled
+ * method with RTM-based lock elision using stack lock first, then that lock
+ * is inflated and the same compiled method invoked again.
+ *
+ * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times before
+ * lock inflation and the same amount of times after inflation.
+ * As a result total locks count should be equal to
+ * {@code 2*AbortProvoker.DEFAULT_ITERATIONS}.
+ * It is a pretty strict assertion which could fail if some retriable abort
+ * happened: it could be {@code AbortType.RETRIABLE} or
+ * {@code AbortType.MEM_CONFLICT}, but unfortunately abort can has both these
+ * reasons simultaneously. In order to avoid false negative failures related
+ * to incorrect aborts counting, -XX:RTMRetryCount=0 is used.
+ */
+public class TestUseRTMAfterLockInflation extends CommandLineOptionTest {
+    private static final long EXPECTED_LOCKS
+            = 2L * AbortProvoker.DEFAULT_ITERATIONS;
+
+    private TestUseRTMAfterLockInflation() {
+        super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        AbortProvoker provoker = AbortType.XABORT.provoker();
+        long totalLocksCount = 0;
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                provoker,
+                "-XX:+UseRTMForStackLocks",
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:RTMRetryCount=0",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                Test.class.getName(),
+                AbortType.XABORT.toString());
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 2,
+                "VM output should contain two rtm locking statistics entries "
+                + "for method " + provoker.getMethodWithLockName());
+
+        for (RTMLockingStatistics s : statistics) {
+            totalLocksCount += s.getTotalLocks();
+        }
+
+        Asserts.assertEQ(totalLocksCount,
+                TestUseRTMAfterLockInflation.EXPECTED_LOCKS,
+                "Total lock count should be greater or equal to "
+                + TestUseRTMAfterLockInflation.EXPECTED_LOCKS);
+    }
+
+    public static class Test {
+
+        /**
+         * Usage:
+         * Test &lt;provoker type&gt;
+         */
+        public static void main(String args[]) throws Throwable {
+            Asserts.assertGT(args.length, 0,
+                    "AbortType name is expected as first argument.");
+
+            AbortProvoker provoker
+                    = AbortType.lookup(Integer.valueOf(args[0])).provoker();
+            for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
+                provoker.forceAbort();
+            }
+            provoker.inflateMonitor();
+            for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
+                provoker.forceAbort();
+            }
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMAfterLockInflation().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that UseRTMDeopt affects uncommon trap installation in
+ *          copmpiled methods with synchronized block.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMDeopt
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMDeopt
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that usage of UseRTMDeopt option affects uncommon traps usage
+ * for methods that use locking.
+ */
+public class TestUseRTMDeopt extends CommandLineOptionTest {
+    private TestUseRTMDeopt() {
+        super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        verifyUseRTMDeopt(false);
+        verifyUseRTMDeopt(true);
+    }
+
+    private void verifyUseRTMDeopt(boolean useRTMDeopt) throws Throwable {
+        AbortProvoker provoker = AbortType.XABORT.provoker();
+        String logFileName = String.format("rtm_%s_deopt.xml",
+                useRTMDeopt ? "use" : "no");
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                logFileName,
+                provoker,
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt",
+                        useRTMDeopt),
+                AbortProvoker.class.getName(),
+                AbortType.XABORT.toString()
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        int expectedUncommonTraps = useRTMDeopt ? 1 : 0;
+        int installedUncommonTraps
+                = RTMTestBase.installedRTMStateChangeTraps(logFileName);
+
+        Asserts.assertEQ(expectedUncommonTraps, installedUncommonTraps,
+                String.format("Expected to find %d uncommon traps "
+                              + "installed with reason rtm_state_change.",
+                        expectedUncommonTraps));
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMDeopt().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that rtm locking is used for inflated locks.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMForInflatedLocks
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMForInflatedLocks
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTM-based lock elision could be used for inflated locks
+ * by calling compiled method that use RTM-based lock elision and using
+ * manually inflated lock.
+ * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times,
+ * so total locks count should be the same.
+ * This test could also be affected by retriable aborts, so -XX:RTMRetryCount=0
+ * is used. For more information abort that issue see
+ * {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestUseRTMForInflatedLocks extends CommandLineOptionTest {
+    private TestUseRTMForInflatedLocks() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        AbortProvoker provoker = AbortType.XABORT.provoker();
+        RTMLockingStatistics lock;
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                provoker,
+                "-XX:-UseRTMForStackLocks",
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:RTMRetryCount=0",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                AbortProvoker.class.getName(),
+                AbortType.XABORT.toString());
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 1,
+                "VM output should contain exactly one rtm locking statistics "
+                + "entry for method " + provoker.getMethodWithLockName());
+
+        lock = statistics.get(0);
+        Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
+                "Total lock count should be greater or equal to "
+                + AbortProvoker.DEFAULT_ITERATIONS);
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMForInflatedLocks().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that rtm locking is used for stack locks.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMForStackLocks
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMForStackLocks
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTM-based lock elision could be used for stack locks
+ * by calling compiled method that use RTM-based lock elision and using
+ * stack lock.
+ * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times,
+ * so total locks count should be the same.
+ * This test could also be affected by retriable aborts, so -XX:RTMRetryCount=0
+ * is used. For more information abort that issue see
+ * {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestUseRTMForStackLocks extends CommandLineOptionTest {
+    private static final boolean INFLATE_MONITOR = false;
+
+    private TestUseRTMForStackLocks() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        AbortProvoker provoker = AbortType.XABORT.provoker();
+        RTMLockingStatistics lock;
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                provoker,
+                "-XX:+UseRTMForStackLocks",
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:RTMRetryCount=0",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                AbortProvoker.class.getName(),
+                AbortType.XABORT.toString(),
+                Boolean.toString(TestUseRTMForStackLocks.INFLATE_MONITOR));
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 1,
+                "VM output should contain exactly one rtm locking statistics "
+                + "entry for method " + provoker.getMethodWithLockName());
+
+        lock = statistics.get(0);
+        Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
+                "Total locks count should be greater or equal to "
+                + AbortProvoker.DEFAULT_ITERATIONS);
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMForStackLocks().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that UseRTMXendForLockBusy option affects
+ *          method behaviour if lock is busy.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMXendForLockBusy
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMXendForLockBusy
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that with +UseRTMXendForLockBusy there will be no aborts
+ * forced by the test.
+ */
+public class TestUseRTMXendForLockBusy extends CommandLineOptionTest {
+    private final static int LOCKING_TIME = 5000;
+
+    private TestUseRTMXendForLockBusy() {
+        super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+    }
+
+    @Override
+    protected void runTestCases() throws Throwable {
+        // inflated lock, xabort on lock busy
+        verifyXendForLockBusy(true, false);
+        // inflated lock, xend on lock busy
+        verifyXendForLockBusy(true, true);
+        // stack lock, xabort on lock busy
+        verifyXendForLockBusy(false, false);
+        // stack lock, xend on lock busy
+        verifyXendForLockBusy(false, true);
+    }
+
+    private void verifyXendForLockBusy(boolean inflateMonitor,
+            boolean useXend) throws Throwable {
+        CompilableTest test = new BusyLock();
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                test,
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+                        inflateMonitor),
+                CommandLineOptionTest.prepareBooleanFlag(
+                        "UseRTMXendForLockBusy",
+                        useXend),
+                "-XX:RTMRetryCount=0",
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                BusyLock.class.getName(),
+                Boolean.toString(inflateMonitor),
+                Integer.toString(TestUseRTMXendForLockBusy.LOCKING_TIME)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+                + "exactly one rtm locking statistics entry for method "
+                + test.getMethodWithLockName());
+
+        long aborts = statistics.get(0).getAborts(AbortType.XABORT);
+
+        if (useXend) {
+            Asserts.assertEQ(aborts, 0L,
+                    "Expected to get no aborts on busy lock");
+        } else {
+            Asserts.assertGT(aborts, 0L,
+                    "Expected to get at least one abort on busy lock");
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMXendForLockBusy().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that NoRTMLockEliding option could be applied to
+ *          specified method and that such method will not use rtm.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestNoRTMLockElidingOption
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestNoRTMLockElidingOption
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that method tagged with option <i>NoRTMLockElidingOption</i>
+ * will not use RTM-based lock elision.
+ * Test invokes compiled method and checks that no deoptimization with
+ * <i>rtm_state_change</i> reason had happened and that that VM output
+ * does not contain RTM locking statistics for compiled method.
+ */
+public class TestNoRTMLockElidingOption extends CommandLineOptionTest {
+    private TestNoRTMLockElidingOption() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    public void runTestCases() throws Throwable {
+        verifyOption(false);
+        verifyOption(true);
+    }
+
+    public void verifyOption(boolean useStackLock) throws Throwable {
+        AbortProvoker provoker = AbortType.XABORT.provoker();
+        String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+                (useStackLock ? "use" : "no"));
+        String methodOption = String.format("-XX:CompileCommand=option," +
+                "%s,NoRTMLockEliding", provoker.getMethodWithLockName());
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                logFileName,
+                provoker,
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+                        useStackLock),
+                methodOption,
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:+UseRTMDeopt",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                AbortProvoker.class.getName(),
+                AbortType.XABORT.toString(),
+                Boolean.toString(!useStackLock)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+        Asserts.assertEQ(firedTraps, 0,
+                "No deoptimizations with rtm_state_change reason are expected");
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 0,
+                "VM output should not contain RTM locking statistics entries "
+                + "for method " + provoker.getMethodWithLockName());
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestNoRTMLockElidingOption().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that UseRTMLockEliding option could be applied to
+ *          specified method and that such method will not be deoptimized
+ *          on high abort ratio.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockElidingOption
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestUseRTMLockElidingOption
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that method tagged with option <i>UseRTMLockElidingOption</i>
+ * will use RTM-based lock elision, but will be never deoptimized with
+ * <i>rtm_state_change reason</i>.
+ * Test invokes compiled method and checks that no deoptimization with
+ * <i>rtm_state_change</i> reason had happened and that that VM output
+ * contains RTM locking statistics for compiled method and that total locks
+ * count equals to method's invocations.
+ * Since last assert is pretty strict, test uses -XX:RTMRetryCount=0 in order
+ * to avoid issue with retriable aborts described in
+ * {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestUseRTMLockElidingOption extends CommandLineOptionTest {
+    private TestUseRTMLockElidingOption() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    public void runTestCases() throws Throwable {
+        verifyOption(false);
+        verifyOption(true);
+    }
+
+    public void verifyOption(boolean useStackLock) throws Throwable {
+        AbortProvoker provoker = AbortType.XABORT.provoker();
+        String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+                (useStackLock ? "use" : "no"));
+        String methodOption = String.format("-XX:CompileCommand=option," +
+                "%s,UseRTMLockEliding", provoker.getMethodWithLockName());
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                logFileName,
+                provoker,
+                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+                        useStackLock),
+                methodOption,
+                "-XX:RTMTotalCountIncrRate=1",
+                "-XX:RTMRetryCount=0",
+                "-XX:+UseRTMDeopt",
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                provoker.getClass().getName(),
+                AbortType.XABORT.toString(),
+                Boolean.toString(!useStackLock)
+        );
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+        Asserts.assertEQ(firedTraps, 0,
+                "Method deoptimization with rtm_state_change is unexpected");
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 1,
+                "VM output should contain exactly one RTM locking "
+                + "statistics entry for method "
+                + provoker.getMethodWithLockName());
+
+        RTMLockingStatistics lock = statistics.get(0);
+
+        Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
+                "Expected to get total locks count equal to total amount of "
+                + "lock attempts.");
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestUseRTMLockElidingOption().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014, 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 8031320
+ * @summary Verify that rtm locking statistics contain proper information
+ *          on overall aborts and locks count and count of aborts of
+ *          different types. Test also verify that VM output does not
+ *          contain rtm locking statistics when it should not.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestPrintPreciseRTMLockingStatistics
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ *                   -XX:+WhiteBoxAPI TestPrintPreciseRTMLockingStatistics
+ */
+
+import java.util.*;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that VM output does not contain RTM locking statistics when it
+ * should not (when PrintPreciseRTMLockingStatistics is off) and that with
+ * -XX:+PrintPreciseRTMLockingStatistics locking statistics contains sane
+ * total locks and aborts count as well as for specific abort types.
+ */
+public class TestPrintPreciseRTMLockingStatistics
+        extends CommandLineOptionTest {
+    private TestPrintPreciseRTMLockingStatistics() {
+        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+    }
+
+    @Override
+    public void runTestCases() throws Throwable {
+        verifyNoStatistics();
+        verifyStatistics();
+    }
+
+    // verify that VM output does not contain
+    // rtm locking statistics
+    private void verifyNoStatistics() throws Throwable {
+        verifyNoStatistics(AbortType.XABORT);
+
+        verifyNoStatistics(AbortType.XABORT,
+                "-XX:-PrintPreciseRTMLockingStatistics");
+
+        verifyNoStatistics(AbortType.XABORT, "-XX:-UseRTMLocking",
+                "-XX:+PrintPreciseRTMLockingStatistics");
+    }
+
+    // verify that rtm locking statistics contain information
+    // about each type of aborts
+    private void verifyStatistics() throws Throwable {
+        verifyAbortsCount(AbortType.XABORT);
+        verifyAbortsCount(AbortType.MEM_CONFLICT);
+        verifyAbortsCount(AbortType.BUF_OVERFLOW);
+        verifyAbortsCount(AbortType.NESTED_ABORT);
+    }
+
+    private void verifyNoStatistics(AbortType abortProvokerType,
+            String... vmOpts) throws Throwable {
+        AbortProvoker provoker = abortProvokerType.provoker();
+        List<String> finalVMOpts = new LinkedList<>();
+        Collections.addAll(finalVMOpts, vmOpts);
+        Collections.addAll(finalVMOpts, AbortProvoker.class.getName(),
+                abortProvokerType.toString());
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(provoker,
+                finalVMOpts.toArray(new String[finalVMOpts.size()]));
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                outputAnalyzer.getOutput());
+
+        Asserts.assertEQ(statistics.size(), 0, "VM output should not contain "
+                + "any RTM locking statistics");
+    }
+
+    private void verifyAbortsCount(AbortType abortType) throws Throwable {
+        AbortProvoker provoker = abortType.provoker();
+
+        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+                provoker,
+                "-XX:+PrintPreciseRTMLockingStatistics",
+                AbortProvoker.class.getName(),
+                abortType.toString());
+
+        outputAnalyzer.shouldHaveExitValue(0);
+
+        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+                provoker.getMethodWithLockName(),outputAnalyzer.getOutput());
+
+        Asserts.assertGT(statistics.size(), 0, "VM output should contain one "
+                + "rtm locking statistics entry for method "
+                + provoker.getMethodWithLockName());
+
+        RTMLockingStatistics lock = statistics.get(0);
+
+        Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM locking statistics "
+                + "should contain non zero total locks count");
+
+        Asserts.assertGT(lock.getTotalAborts(), 0L,
+                "RTM locking statistics should contain non zero total aborts "
+                + "count");
+
+        Asserts.assertGT(lock.getAborts(abortType), 0L, String.format(
+                "RTM locking statistics should contain non zero aborts count "
+                + "for abort reason %s", abortType));
+    }
+
+    public static void main(String args[]) throws Throwable {
+        new TestPrintPreciseRTMLockingStatistics().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import java.util.Objects;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.Utils;
+import sun.misc.Unsafe;
+
+/**
+ * Base class for different transactional execution abortion
+ * provokers aimed to force abort due to specified reason.
+ */
+public abstract class AbortProvoker implements CompilableTest {
+    public static final long DEFAULT_ITERATIONS = 10000L;
+    /**
+     * Inflates monitor associated with object {@code monitor}.
+     * Inflation is forced by entering the same monitor from
+     * two different threads.
+     *
+     * @param monitor monitor to be inflated.
+     * @return inflated monitor.
+     * @throws Exception if something went wrong.
+     */
+    public static Object inflateMonitor(Object monitor) throws Exception {
+        Unsafe unsafe = Utils.getUnsafe();
+        CyclicBarrier barrier = new CyclicBarrier(2);
+
+        Runnable inflatingRunnable = () -> {
+            unsafe.monitorEnter(monitor);
+            try {
+                barrier.await();
+                barrier.await();
+            } catch (InterruptedException | BrokenBarrierException e) {
+                throw new RuntimeException(
+                        "Synchronization issue occurred.", e);
+            } finally {
+                unsafe.monitorExit(monitor);
+            }
+        };
+
+        Thread t = new Thread(inflatingRunnable);
+        t.start();
+        // Wait until thread t enters the monitor.
+        barrier.await();
+        // At this point monitor will be owned by thread t,
+        // so our attempt to enter the same monitor will force
+        // monitor inflation.
+        Asserts.assertFalse(unsafe.tryMonitorEnter(monitor),
+                            "Not supposed to enter the monitor first");
+        barrier.await();
+        t.join();
+        return monitor;
+    }
+
+
+    /**
+     * Get instance of specified AbortProvoker, inflate associated monitor
+     * if needed and then invoke forceAbort method in a loop.
+     *
+     * Usage:
+     * AbortProvoker &lt;AbortType name&gt; [&lt;inflate monitor&gt
+     * [&lt;iterations&gt; [ &lt;delay&gt;]]]
+     *
+     *  Default parameters are:
+     *  <ul>
+     *  <li>inflate monitor = <b>true</b></li>
+     *  <li>iterations = {@code AbortProvoker.DEFAULT_ITERATIONS}</li>
+     *  <li>delay = <b>0</b></li>
+     *  </ul>
+     */
+    public static void main(String args[]) throws Throwable {
+        Asserts.assertGT(args.length, 0, "At least one argument is required.");
+
+        AbortType abortType = AbortType.lookup(Integer.valueOf(args[0]));
+        boolean monitorShouldBeInflated = true;
+        long iterations = AbortProvoker.DEFAULT_ITERATIONS;
+
+        if (args.length > 1) {
+            monitorShouldBeInflated = Boolean.valueOf(args[1]);
+
+            if (args.length > 2) {
+                iterations = Long.valueOf(args[2]);
+
+                if (args.length > 3) {
+                    Thread.sleep(Integer.valueOf(args[3]));
+                }
+            }
+        }
+
+        AbortProvoker provoker = abortType.provoker();
+
+        if (monitorShouldBeInflated) {
+            provoker.inflateMonitor();
+        }
+
+        for (long i = 0; i < iterations; i++) {
+            provoker.forceAbort();
+        }
+    }
+
+    protected final Object monitor;
+
+    protected AbortProvoker() {
+        this(new Object());
+    }
+
+    protected AbortProvoker(Object monitor) {
+        this.monitor = Objects.requireNonNull(monitor);
+    }
+
+    /**
+     * Inflates monitor used by this AbortProvoker instance.
+     * @throws Exception
+     */
+    public void inflateMonitor() throws Exception {
+        AbortProvoker.inflateMonitor(monitor);
+    }
+
+    /**
+     * Forces transactional execution abortion.
+     */
+    public abstract void forceAbort();
+
+    /**
+     * Returns names of all methods that have to be compiled
+     * in order to successfully force transactional execution
+     * abortion.
+     *
+     * @return array with methods' names that have to be compiled.
+     */
+    @Override
+    public String[] getMethodsToCompileNames() {
+        return new String[] { getMethodWithLockName() };
+    }
+
+    /**
+     * Returns name of the method that will contain monitor whose locking
+     * will be elided using transactional execution.
+     *
+     * @return name of the method that will contain elided lock.
+     */
+    @Override
+    public String getMethodWithLockName() {
+        return this.getClass().getName() + "::forceAbort";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/AbortType.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import com.oracle.java.testlibrary.Asserts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Type of transactional execution abort.
+ * For more details on different abort types please see
+ * shared/vm/runtime/rtmLocking.hpp
+ */
+public enum AbortType {
+    XABORT(0),
+    RETRIABLE(1),
+    MEM_CONFLICT(2),
+    BUF_OVERFLOW(3),
+    DEBUG_BREAKPOINT(4),
+    NESTED_ABORT(5);
+
+    private final int type;
+    private static final Map<Integer, AbortType> LOOKUP_MAP = new HashMap<>();
+
+    static {
+        for (AbortType abortType : AbortType.values()) {
+            Asserts.assertFalse(LOOKUP_MAP.containsKey(abortType.type),
+                    "Abort type values should be unique.");
+            LOOKUP_MAP.put(abortType.type, abortType);
+        }
+    }
+
+    private AbortType(int type) {
+        this.type = type;
+    }
+
+    /**
+     * Returns AbortProvoker for aborts represented by this abort type.
+     *
+     * @return an AbortProvoker instance
+     */
+    public AbortProvoker provoker() {
+        return AbortType.createNewProvoker(this);
+    }
+
+    public static AbortType lookup(int type) {
+        Asserts.assertLT(type, AbortType.values().length,
+                "Unknown abort type.");
+        return LOOKUP_MAP.get(type);
+    }
+
+    /**
+     * Returns transaction execution abort provoker for specified abortion type.
+     *
+     * @param type a type of abort which will be forced by returned
+     *             AbortProvoker instance.
+     * @return AbortProvoker instance that will force abort of specified type
+     * @throws RuntimeException if there is no provoker for specified type
+     */
+    private static AbortProvoker createNewProvoker(AbortType type) {
+        switch (type) {
+            case XABORT:
+                return new XAbortProvoker();
+            case MEM_CONFLICT:
+                return new MemoryConflictProvoker();
+            case BUF_OVERFLOW:
+                return new BufferOverflowProvoker();
+            case NESTED_ABORT:
+                return new NestedAbortProvoker();
+            default:
+                throw new RuntimeException("No provoker exists for type "
+                        + type.name());
+        }
+    }
+
+    @Override
+    public String toString() {
+        return Integer.toString(type);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/BufferOverflowProvoker.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+/**
+ * In order to provoke transactional execution abort due to
+ * internal's buffer overflow BufferOverflowProvoker modifies
+ * 1MB of BYTES during single transaction.
+ */
+class BufferOverflowProvoker extends AbortProvoker {
+    /**
+     * To force buffer overflow abort we modify memory region with
+     * size more then L1d cache size.
+     */
+    private static final int MORE_THAN_L1D_SIZE = 1024 * 1024;
+    private static final byte[] DATA = new byte[MORE_THAN_L1D_SIZE];
+
+    @Override
+    public void forceAbort() {
+        synchronized(monitor) {
+            for (int i = 0; i < BufferOverflowProvoker.DATA.length; i++) {
+                BufferOverflowProvoker.DATA[i]++;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import com.oracle.java.testlibrary.Utils;
+import sun.misc.Unsafe;
+
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+/**
+ * Test case for busy lock scenario.
+ * One thread enters the monitor and sleep for a while.
+ * Another thread is blocked on the same monitor.
+ */
+public class BusyLock implements CompilableTest, Runnable {
+    private static final int DEFAULT_TIMEOUT = 1000;
+    private final CyclicBarrier barrier;
+
+    // Following field have to be static in order to avoid escape analysis.
+    @SuppressWarnings("UnsuedDeclaration")
+    private static int field = 0;
+    private static final Unsafe UNSAFE = Utils.getUnsafe();
+    protected final Object monitor;
+    protected final int timeout;
+
+    public BusyLock() {
+        this(BusyLock.DEFAULT_TIMEOUT);
+    }
+
+    public BusyLock(int timeout) {
+        this.timeout = timeout;
+        this.monitor = new Object();
+        this.barrier = new CyclicBarrier(2);
+    }
+
+    @Override
+    public void run() {
+        try {
+            // wait until forceAbort leave monitor
+            barrier.await();
+            if (UNSAFE.tryMonitorEnter(monitor)) {
+                try {
+                    barrier.await();
+                    Thread.sleep(timeout);
+                } finally {
+                    UNSAFE.monitorExit(monitor);
+                }
+            } else {
+                throw new RuntimeException("Monitor should be entered by " +
+                                           "::run() first.");
+            }
+        } catch (InterruptedException | BrokenBarrierException e) {
+            throw new RuntimeException("Synchronization error happened.", e);
+        }
+    }
+
+    public void test() {
+        try {
+            barrier.await();
+            // wait until monitor is locked by a ::run method
+            barrier.await();
+        } catch (InterruptedException | BrokenBarrierException e) {
+            throw new RuntimeException("Synchronization error happened.", e);
+        }
+        synchronized(monitor) {
+            BusyLock.field++;
+        }
+    }
+
+    @Override
+    public String getMethodWithLockName() {
+        return this.getClass().getName() + "::test";
+    }
+
+    @Override
+    public String[] getMethodsToCompileNames() {
+        return new String[] { getMethodWithLockName() };
+    }
+
+    /**
+     * Usage:
+     * BusyLock [ &lt;inflate monitor&gt; [ &lt;timeout&gt; ] ]
+     *
+     * Default values are:
+     * <ul>
+     *     <li>inflate monitor = {@code true}</li>
+     *     <li>timeout = {@code BusyLock.DEFAULT_TIMEOUT}</li>
+     * </ul>
+     */
+    public static void main(String args[]) throws Exception {
+        int timeoutValue = BusyLock.DEFAULT_TIMEOUT;
+        boolean inflateMonitor = true;
+
+        if (args.length > 0 ) {
+            inflateMonitor = Boolean.valueOf(args[0]);
+
+            if (args.length > 1) {
+                timeoutValue = Integer.valueOf(args[1]);
+            }
+        }
+
+        BusyLock busyLock = new BusyLock(timeoutValue);
+
+        if (inflateMonitor) {
+            AbortProvoker.inflateMonitor(busyLock.monitor);
+        }
+
+        Thread t = new Thread(busyLock);
+        t.start();
+        busyLock.test();
+        t.join();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/CompilableTest.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+/**
+ * Interface for test scenarios that contain methods
+ * that should be compiled.
+ */
+public interface CompilableTest {
+    /**
+     * @return array with methods' names that should be compiled.
+     */
+    String[] getMethodsToCompileNames();
+
+    /**
+     * @return name of method with RTM-elided lock.
+     */
+    String getMethodWithLockName();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+/**
+ * To force transactional execution abort due to memory conflict
+ * one thread should access memory region from transactional region
+ * while another thread should modify the same memory region.
+ * Since this scenario is based on the race condition between threads
+ * you should not expect some particular amount of aborts.
+ */
+class MemoryConflictProvoker extends AbortProvoker {
+    // Following field have to be static in order to avoid escape analysis.
+    @SuppressWarnings("UnsuedDeclaration")
+    private static int field = 0;
+    private static final int INNER_ITERATIONS = 10000;
+    private final CyclicBarrier barrier;
+    /**
+     * This thread will access and modify memory region
+     * from outside of the transaction.
+     */
+    private final Runnable conflictingThread;
+
+    public MemoryConflictProvoker() {
+        this(new Object());
+    }
+
+    public MemoryConflictProvoker(Object monitor) {
+        super(monitor);
+        barrier = new CyclicBarrier(2);
+        conflictingThread = () -> {
+            try {
+                barrier.await();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+            for (int i = 0; i < MemoryConflictProvoker.INNER_ITERATIONS; i++) {
+                MemoryConflictProvoker.field++;
+            }
+        };
+    }
+
+    /**
+     * Accesses and modifies memory region from within the transaction.
+     */
+    public void transactionalRegion() {
+        try {
+            barrier.await();
+        } catch (InterruptedException | BrokenBarrierException e) {
+            throw new RuntimeException(e);
+        }
+        for (int i = 0; i < MemoryConflictProvoker.INNER_ITERATIONS; i++) {
+            synchronized(monitor) {
+                MemoryConflictProvoker.field--;
+            }
+        }
+    }
+
+    @Override
+    public void forceAbort() {
+        try {
+            Thread t = new Thread(conflictingThread);
+            t.start();
+            transactionalRegion();
+            t.join();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public String getMethodWithLockName() {
+        return this.getClass().getName() + "::transactionalRegion";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/NestedAbortProvoker.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import java.util.Arrays;
+
+/**
+ * In order to force nested transaction abort NestedAbortProvoker
+ * invoke BufferOverflowProvoker from transactional region.
+ */
+class NestedAbortProvoker extends AbortProvoker {
+    // Following field have to be static in order to avoid escape analysis.
+    @SuppressWarnings("UnsuedDeclaration")
+    private static int field = 0;
+    private final AbortProvoker nestedAbortProvoker;
+
+    public NestedAbortProvoker() {
+        this.nestedAbortProvoker = new XAbortProvoker(monitor);
+    }
+
+    @Override
+    public void forceAbort() {
+        synchronized(monitor) {
+            NestedAbortProvoker.field++;
+            nestedAbortProvoker.forceAbort();
+            NestedAbortProvoker.field--;
+        }
+    }
+
+    @Override
+    public String[] getMethodsToCompileNames() {
+        String nestedProvokerMethods[]
+                = nestedAbortProvoker.getMethodsToCompileNames();
+        String methods[] = Arrays.copyOf(nestedProvokerMethods,
+                nestedProvokerMethods.length + 1);
+        methods[methods.length - 1] = getMethodWithLockName();
+        return methods;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/RTMLockingStatistics.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import java.util.EnumMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Wrapper for +UsePreciseRTMLockingStatistics output.
+ *
+ * Example of locking statistics:
+ *
+ * java/lang/ClassLoader.loadClass@7
+ * # rtm locks total (estimated): 0
+ * # rtm lock aborts  : 13
+ * # rtm lock aborts 0: 12
+ * # rtm lock aborts 1: 0
+ * # rtm lock aborts 2: 0
+ * # rtm lock aborts 3: 0
+ * # rtm lock aborts 4: 0
+ * # rtm lock aborts 5: 0
+ */
+public class RTMLockingStatistics {
+    /**
+     * Pattern for aborts per abort type entries.
+     */
+    private static final Pattern ABORT_PATTERN;
+
+    /**
+     * Pattern for whole statistics.
+     */
+    private static final Pattern RTM_LOCKING_STATISTICS_PATTERN;
+
+    static {
+        String abortRe
+                = "# rtm lock aborts\\s+(?<type>[0-9]+):\\s(?<count>[0-9]+)";
+
+        ABORT_PATTERN = Pattern.compile(abortRe);
+        RTM_LOCKING_STATISTICS_PATTERN = Pattern.compile(
+                "(?<className>[^.\n]+)\\." +
+                "(?<methodName>[^@\n]+)@(?<bci>[0-9]+)\n" +
+                "# rtm locks total \\(estimated\\):\\s*" +
+                "(?<totalLocks>[0-9]+)\n" +
+                "# rtm lock aborts\\s+:\\s*(?<totalAborts>[0-9]+)\n" +
+                "(?<abortStats>(" + abortRe + "\n)+)");
+    }
+
+    private final long totalLocks;
+    private final long totalAborts;
+    private final String className;
+    private final String methodName;
+    private final int bci;
+    private final Map<AbortType, Long> aborts = new EnumMap<>(AbortType.class);
+
+    /**
+     * Constructs RTMLockingStatistics from matcher captured statistics entry.
+     * @param matcher Matcher captured statistics entry.
+     */
+    private RTMLockingStatistics(Matcher matcher) {
+        className = matcher.group("className");
+        methodName = matcher.group("methodName");
+        bci = Integer.valueOf(matcher.group("bci"));
+        totalLocks = Long.valueOf(matcher.group("totalLocks"));
+        totalAborts = Long.valueOf(matcher.group("totalAborts"));
+
+        Matcher abortMatcher = ABORT_PATTERN.matcher(matcher.
+                group("abortStats"));
+
+        while (abortMatcher.find()) {
+            int type = Integer.valueOf(abortMatcher.group("type"));
+            long count = Long.valueOf(abortMatcher.group("count"));
+            setAborts(AbortType.lookup(type), count);
+        }
+    }
+
+
+    /**
+     * Parses string and return all founded RTM locking statistics entries.
+     *
+     * @param str the string to be parsed.
+     * @return list with all founded RTM locking statistics entries or
+     *         empty list if nothing was found.
+     */
+    public static List<RTMLockingStatistics> fromString(String str) {
+        List<RTMLockingStatistics> statistics = new LinkedList<>();
+        Matcher matcher = RTM_LOCKING_STATISTICS_PATTERN.matcher(str);
+
+        while (matcher.find()) {
+            RTMLockingStatistics lock = new RTMLockingStatistics(matcher);
+            statistics.add(lock);
+        }
+
+        return statistics;
+    }
+
+    /**
+     * Parses string and return all founded RTM locking statistics entries
+     * for locks in method {@code methodName}.
+     *
+     * @param methodName a name of the method for locks from which statistics
+     *                   should be gathered.
+     * @param str the string to be parsed.
+     * @return list with all founded RTM locking statistics entries or
+     *         empty list if nothing was found.
+     */
+    public static List<RTMLockingStatistics> fromString(String methodName,
+            String str) {
+        String formattedMethodName = formatMethodName(methodName);
+
+        List<RTMLockingStatistics> statisticsForMethod = new LinkedList<>();
+        for (RTMLockingStatistics statistics : fromString(str)) {
+            if (statistics.getLockName().startsWith(formattedMethodName)) {
+                statisticsForMethod.add(statistics);
+            }
+        }
+        return statisticsForMethod;
+    }
+
+    /**
+     * Formats method's name so it will have the same format as
+     * in rtm locking statistics.
+     *
+     * <pre>
+     * Example:
+     * com/example/Klass::method =&gt; com/example/Klass.method
+     * com/example/Klass.method  =&gt; com/example/Klass.method
+     * com.example.Klass::method =&gt; com/example/Klass.method
+     * com.example.Klass.method  =&gt; com/example/Klass.method
+     * </pre>
+     *
+     * @param methodName method's name that should be formatted.
+     * @return formatted method's name.
+     */
+    private static String formatMethodName(String methodName) {
+        String m[];
+        if (methodName.contains("::")) {
+            m = methodName.split("::");
+        } else {
+            int splitAt = methodName.lastIndexOf('.');
+            m = new String[2];
+            m[0] = methodName.substring(0, splitAt);
+            m[1] = methodName.substring(splitAt + 1);
+        }
+        return String.format("%s.%s", m[0].replaceAll("\\.", "/"), m[1]);
+    }
+
+    /**
+     * Returns name of lock for which this statistics was collected.
+     * Lock name has following format:
+     * &lt;class name&gt;.&lt;method name&gt;@&lt;bci&gt;
+     *
+     * @return name of lock.
+     */
+    public String getLockName() {
+        return String.format("%s.%s@%d", className, methodName, bci);
+    }
+
+    /**
+     * Returns aborts count for specified abort type.
+     *
+     * @param type an abort type.
+     * @return count of aborts.
+     */
+    public long getAborts(AbortType type) {
+        return aborts.getOrDefault(type, 0L);
+    }
+
+    /**
+     * Sets aborts count for specified abort type.
+     *
+     * @param type an abort type.
+     * @param count count of aborts.
+     */
+    public void setAborts(AbortType type, long count) {
+        aborts.put(type, count);
+    }
+
+    public long getTotalLocks() {
+        return totalLocks;
+    }
+
+    public long getTotalAborts() {
+        return totalAborts;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append(getLockName()).append('\n');
+        builder.append(String.format("# rtm locks total (estimated): %d\n",
+                getTotalLocks()));
+        builder.append(String.format("# rtm lock aborts: %d\n",
+                getTotalLocks()));
+
+        for (AbortType type : AbortType.values()) {
+            builder.append(String.format("# rtm lock aborts %s %d\n",
+                    type.toString(), getAborts(type)));
+        }
+        return builder.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.Utils;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+
+/**
+ * Auxiliary methods used for RTM testing.
+ */
+public class RTMTestBase {
+    private static final String RTM_STATE_CHANGE_REASON = "rtm_state_change";
+    /**
+     * We don't parse compilation log as XML-document and use regular
+     * expressions instead, because in some cases it could be
+     * malformed.
+     */
+    private static final String FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE
+            = "<uncommon_trap thread='[0-9]+' reason='%s'";
+    private static final String INSTALLED_UNCOMMON_TRAP_PATTERN_TEMPLATE
+            = "<uncommon_trap bci='[0-9]+' reason='%s'";
+
+    /**
+     * Executes RTM test in a new JVM started with {@code options} cli options.
+     *
+     * @param test test case to execute.
+     * @param options additional options for VM
+     * @throws Exception when something went wrong.
+     */
+    public static OutputAnalyzer executeRTMTest(CompilableTest test,
+            String... options) throws Exception {
+        ProcessBuilder processBuilder
+                = ProcessTools.createJavaProcessBuilder(
+                RTMTestBase.prepareTestOptions(test, options));
+        OutputAnalyzer outputAnalyzer
+                = new OutputAnalyzer(processBuilder.start());
+        System.out.println(outputAnalyzer.getOutput());
+        return outputAnalyzer;
+    }
+
+    /**
+     * Executes test case and save compilation log to {@code logFileName}.
+     *
+     * @param logFileName a name of compilation log file
+     * @param test a test case to execute case to execute
+     * @param options additional options to VM
+     * @return OutputAnalyzer for started test case
+     * @throws Exception when something went wrong
+     */
+    public static OutputAnalyzer executeRTMTest(String logFileName,
+            CompilableTest test, String... options) throws Exception {
+        ProcessBuilder processBuilder
+                = ProcessTools.createJavaProcessBuilder(
+                RTMTestBase.prepareTestOptions(logFileName, test, options));
+        OutputAnalyzer outputAnalyzer
+                = new OutputAnalyzer(processBuilder.start());
+
+        System.out.println(outputAnalyzer.getOutput());
+
+        return outputAnalyzer;
+    }
+
+    /**
+     * Finds count of uncommon traps with reason {@code reason} installed
+     * during compilation.
+     *
+     * @param compilationLogFile a path to file with LogCompilation output.
+     * @param reason reason of installed uncommon traps.
+     * @return count of installed uncommon traps with reason {@code reason}.
+     * @throws IOException
+     */
+    public static int installedUncommonTraps(String compilationLogFile,
+            String reason)throws IOException {
+        String pattern = String.format(
+                RTMTestBase.INSTALLED_UNCOMMON_TRAP_PATTERN_TEMPLATE,
+                reason);
+        return RTMTestBase.findTraps(compilationLogFile, pattern);
+    }
+
+    /**
+     * Finds count of uncommon traps with reason <i>rtm_state_change</i>
+     * installed during compilation.
+     *
+     * @param compilationLogFile a path to file with LogCompilation output.
+     * @return count of installed uncommon traps with reason
+     *         <i>rtm_state_change</i>.
+     * @throws IOException
+     */
+    public static int installedRTMStateChangeTraps(String compilationLogFile)
+            throws IOException {
+        return RTMTestBase.installedUncommonTraps(compilationLogFile,
+                RTMTestBase.RTM_STATE_CHANGE_REASON);
+    }
+
+    /**
+     * Finds count of fired uncommon traps with reason {@code reason}.
+     *
+     * @param compilationLogFile a path to file with LogCompilation output.
+     * @param reason a reason of fired uncommon traps.
+     * @return count of fired uncommon traps with reason {@code reason}.
+     * @throws IOException
+     */
+    public static int firedUncommonTraps(String compilationLogFile,
+            String reason) throws IOException {
+        String pattern = String.format(
+                RTMTestBase.FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE,
+                reason);
+        return RTMTestBase.findTraps(compilationLogFile, pattern);
+    }
+
+    /**
+     * Finds count of fired uncommon traps with reason <i>rtm_state_change</i>.
+     *
+     * @param compilationLogFile a path to file with LogCompilation output.
+     * @return count of fired uncommon traps with reason
+     *         <i>rtm_state_change</i>.
+     * @throws IOException
+     */
+    public static int firedRTMStateChangeTraps(String compilationLogFile)
+            throws IOException {
+        return RTMTestBase.firedUncommonTraps(compilationLogFile,
+                RTMTestBase.RTM_STATE_CHANGE_REASON);
+    }
+
+    /**
+     * Finds count of uncommon traps that matches regular
+     * expression in {@code re}.
+     *
+     * @param compilationLogFile a path to file with LogCompilation output.
+     * @param re regular expression to match uncommon traps.
+     * @throws IOException
+     */
+    private static int findTraps(String compilationLogFile, String re)
+            throws IOException {
+        String compilationLog = RTMTestBase.fileAsString(compilationLogFile);
+        Pattern pattern = Pattern.compile(re);
+        Matcher matcher = pattern.matcher(compilationLog);
+        int traps = 0;
+        while (matcher.find()) {
+            traps++;
+        }
+        return traps;
+    }
+
+    /**
+     * Returns file's content as a string.
+     *
+     * @param path a path to file to operate on.
+     * @return string with content of file.
+     * @throws IOException
+     */
+    private static String fileAsString(String path) throws IOException {
+        byte[] fileAsBytes = Files.readAllBytes(Paths.get(path));
+        return new String(fileAsBytes);
+    }
+
+    /**
+     * Prepares VM options for test execution.
+     * This method get test java options, filter out all RTM-related options,
+     * adds CompileCommand=compileonly,method_name options for each method
+     * from {@code methodToCompile} and finally appends all {@code vmOpts}.
+     *
+     * @param test test case whose methods that should be compiled.
+     *             If {@code null} then no additional <i>compileonly</i>
+     *             commands will be added to VM options.
+     * @param vmOpts additional options to pass to VM.
+     * @return Array with VM options.
+     */
+    private static String[] prepareTestOptions(CompilableTest test,
+            String... vmOpts) {
+        return RTMTestBase.prepareFilteredTestOptions(test, null, vmOpts);
+    }
+
+    /**
+     * Prepares VM options for test execution.
+     * This method get test java options, filter out all RTM-related options
+     * and all options that matches regexps in {@code additionalFilters},
+     * adds CompileCommand=compileonly,method_name options for each method
+     * from {@code methodToCompile} and finally appends all {@code vmOpts}.
+     *
+     * @param test test case whose methods that should be compiled.
+     *             If {@code null} then no additional <i>compileonly</i>
+     *             commands will be added to VM options.
+     * @param additionalFilters array with regular expression that will be
+     *                          used to filter out test java options.
+     *                          If {@code null} then no additional filters
+     *                          will be used.
+     * @param vmOpts additional options to pass to VM.
+     * @return array with VM options.
+     */
+    private static String[] prepareFilteredTestOptions(CompilableTest test,
+            String[] additionalFilters, String... vmOpts) {
+        List<String> finalVMOpts = new LinkedList<>();
+        String[] filters;
+
+        if (additionalFilters != null) {
+            filters = Arrays.copyOf(additionalFilters,
+                    additionalFilters.length + 1);
+        } else {
+            filters = new String[1];
+        }
+
+        filters[filters.length - 1] = "RTM";
+        String[] filteredVMOpts = Utils.getFilteredTestJavaOpts(filters);
+        Collections.addAll(finalVMOpts, filteredVMOpts);
+        Collections.addAll(finalVMOpts, "-Xcomp", "-server",
+                "-XX:-TieredCompilation", "-XX:+UseRTMLocking",
+                CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+
+        if (test != null) {
+            for (String method : test.getMethodsToCompileNames()) {
+                finalVMOpts.add("-XX:CompileCommand=compileonly," + method);
+            }
+        }
+        Collections.addAll(finalVMOpts, vmOpts);
+        return finalVMOpts.toArray(new String[finalVMOpts.size()]);
+    }
+
+    /**
+     * Adds additional options for VM required for successful execution of test.
+     *
+     * @param logFileName a name of compilation log file
+     * @param test a test case to execute
+     * @param options additional options to VM
+     * @return an array with VM options
+     */
+    private static String[] prepareTestOptions(String logFileName,
+            CompilableTest test, String... options) {
+        String[] preparedOptions = RTMTestBase.prepareFilteredTestOptions(
+                test,
+                new String[] {
+                        "LogCompilation",
+                        "LogFile"
+                });
+        List<String> updatedOptions = new LinkedList<>();
+        Collections.addAll(updatedOptions, preparedOptions);
+        Collections.addAll(updatedOptions,
+                "-XX:+LogCompilation",
+                "-XX:LogFile=" + logFileName);
+        Collections.addAll(updatedOptions, options);
+
+        return updatedOptions.toArray(new String[updatedOptions.size()]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import com.oracle.java.testlibrary.Utils;
+import sun.misc.Unsafe;
+
+/**
+ * Current RTM locking implementation force transaction abort
+ * before native method call by explicit xabort(0) call.
+ */
+class XAbortProvoker extends AbortProvoker {
+    // Following field have to be static in order to avoid escape analysis.
+    @SuppressWarnings("UnsuedDeclaration")
+    private static int field = 0;
+    private static final Unsafe UNSAFE = Utils.getUnsafe();
+
+    public XAbortProvoker() {
+        this(new Object());
+    }
+
+    public XAbortProvoker(Object monitor) {
+        super(monitor);
+    }
+
+    @Override
+    public void forceAbort() {
+        synchronized(monitor) {
+            XAbortProvoker.field = UNSAFE.addressSize();
+        }
+    }
+
+    @Override
+    public String[] getMethodsToCompileNames() {
+        return new String[] {
+                getMethodWithLockName(),
+                Unsafe.class.getName() + "::addressSize"
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedCPU.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, 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 rtm.predicate;
+
+import sun.hotspot.cpuinfo.CPUInfo;
+
+import java.util.function.BooleanSupplier;
+
+public class SupportedCPU implements BooleanSupplier {
+    @Override
+    public boolean getAsBoolean() {
+        return CPUInfo.hasFeature("rtm");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedVM.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, 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 rtm.predicate;
+
+import com.oracle.java.testlibrary.Platform;
+
+import java.util.function.BooleanSupplier;
+
+public class SupportedVM implements BooleanSupplier {
+    @Override
+    public boolean getAsBoolean() {
+        return Platform.isServer() && !Platform.isEmbedded();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/CorrectnessTest.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2014, 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 CorrectnessTest
+ * @bug 8038418
+ * @library /testlibrary /testlibrary/whitebox
+ * @compile execution/TypeConflict.java execution/TypeProfile.java
+ *          execution/MethodHandleDelegate.java
+ * @build CorrectnessTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation
+ *                   -XX:CompileCommand=exclude,execution/*::methodNotToCompile
+ *                   -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType
+ *                   CorrectnessTest RETURN
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation
+ *                   -XX:CompileCommand=exclude,execution/*::methodNotToCompile
+ *                   -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType
+ *                   CorrectnessTest PARAMETERS
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation
+ *                   -XX:CompileCommand=exclude,execution/*::methodNotToCompile
+ *                   -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType
+ *                   CorrectnessTest ARGUMENTS
+ * @summary Tests correctness of type usage with type profiling and speculations
+ */
+
+import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.Platform;
+import execution.Execution;
+import execution.MethodHandleDelegate;
+import execution.TypeConflict;
+import execution.TypeProfile;
+import hierarchies.*;
+import scenarios.*;
+import sun.hotspot.WhiteBox;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiFunction;
+
+public class CorrectnessTest {
+    private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+    public static void main(String[] args) {
+        if (!Platform.isServer()) {
+            System.out.println("ALL TESTS SKIPPED");
+        }
+        Asserts.assertGTE(args.length, 1);
+        ProfilingType profilingType = ProfilingType.valueOf(args[0]);
+        if (runTests(profilingType)) {
+            System.out.println("ALL TESTS PASSED");
+        } else {
+            throw new RuntimeException("SOME TESTS FAILED");
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static boolean runTests(ProfilingType profilingType) {
+        boolean result = true;
+
+        List<Execution> executionList = new ArrayList<>();
+        executionList.add(new TypeConflict());
+        executionList.add(new TypeProfile());
+        for (int i = 0, n = executionList.size(); i < n; i++) {
+            executionList.add(new MethodHandleDelegate(executionList.get(i)));
+        }
+
+        List<TypeHierarchy> hierarchyList = new ArrayList<>();
+        hierarchyList.add(new DefaultMethodInterface.Hierarchy());
+        hierarchyList.add(new DefaultMethodInterface2.Hierarchy());
+        hierarchyList.add(new Linear.Hierarchy());
+        hierarchyList.add(new Linear2.Hierarchy());
+        hierarchyList.add(new OneRank.Hierarchy());
+        for (int i = 0, n = hierarchyList.size(); i < n; i++) {
+            hierarchyList.add(new NullableType(hierarchyList.get(i)));
+        }
+
+        List<BiFunction<ProfilingType, TypeHierarchy, Scenario<?, ?>>> testCasesConstructors
+                = new ArrayList<>();
+        testCasesConstructors.add(ArrayCopy::new);
+        testCasesConstructors.add(ArrayReferenceStore::new);
+        testCasesConstructors.add(ClassIdentity::new);
+        testCasesConstructors.add(ClassInstanceOf::new);
+        testCasesConstructors.add(ClassIsInstance::new);
+        testCasesConstructors.add(ReceiverAtInvokes::new);
+        testCasesConstructors.add(CheckCast::new);
+
+        for (TypeHierarchy hierarchy : hierarchyList) {
+            for (BiFunction<ProfilingType, TypeHierarchy, Scenario<?, ?>> constructor : testCasesConstructors) {
+                for (Execution execution : executionList) {
+                    Scenario<?, ?> scenario = constructor.apply(profilingType, hierarchy);
+                    if (scenario.isApplicable()) {
+                        result &= executeTest(hierarchy, execution, scenario);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Executes test case
+     *
+     * @param hierarchy type hierarchy for the test
+     * @param execution execution scenario
+     * @param scenario  test scenario executed with given Execution
+     */
+    private static boolean executeTest(TypeHierarchy hierarchy, Execution execution, Scenario<?, ?> scenario) {
+        boolean testCaseResult = false;
+        String testName = hierarchy.getClass().getName() + " :: " + scenario.getName() + " @ " + execution.getName();
+        clearAllMethodsState(scenario.getClass());
+        try {
+            execution.execute(scenario);
+            testCaseResult = true;
+        } catch (Exception e) {
+            System.err.println(testName + " failed with exception " + e);
+            e.printStackTrace();
+        }
+        System.out.println((testCaseResult ? "PASSED: " : "FAILED: ") + testName);
+        return testCaseResult;
+    }
+
+    private static void clearAllMethodsState(Class aClass) {
+        while (aClass != null) {
+            for (Method m : aClass.getDeclaredMethods()) {
+                WHITE_BOX.clearMethodState(m);
+            }
+            aClass = aClass.getSuperclass();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/OffTest.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, 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 CorrectnessTest
+ * @bug 8038418
+ * @library /testlibrary /testlibrary/whitebox
+ * @compile execution/TypeConflict.java execution/TypeProfile.java
+ *          execution/MethodHandleDelegate.java
+ * @build CorrectnessTest
+ * @build OffTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/timeout=1200 OffTest
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+import scenarios.ProfilingType;
+
+import java.util.Random;
+
+public class OffTest {
+    private static final String[] OPTIONS = {
+            "-Xbootclasspath/a:.",
+            "-XX:+IgnoreUnrecognizedVMOptions",
+            "-XX:+UnlockExperimentalVMOptions",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+WhiteBoxAPI",
+            "-XX:CompileCommand=exclude,execution/*::methodNotToCompile",
+            "-XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType",
+            "", // -XX:TypeProfileLevel=?
+            "", // -XX:?UseTypeSpeculation
+            CorrectnessTest.class.getName(),
+            "", // ProfilingType.name()
+    };
+
+    private static final String TYPE_PROFILE_LEVEL = "TypeProfileLevel";
+    private static final String USE_TYPE_SPECULATION = "UseTypeSpeculation";
+    private static final int TYPE_PROFILE_LEVEL_LENGTH = 3;
+    private static final int TYPE_PROFILE_LEVEL_BOUND = 3;
+    private static final int DEFAULT_COUNT = 10;
+    private static final int PROFILING_TYPE_INDEX = OPTIONS.length - 1;
+    private static final int TYPE_PROFILE_INDEX = OPTIONS.length - 4;
+    private static final int USE_TYPE_SPECULATION_INDEX = OPTIONS.length - 3;
+    private static final Random RNG;
+
+    static {
+        String str = System.getProperty("seed");
+        long seed = str != null ? Long.parseLong(str) : new Random().nextLong();
+        RNG = new Random(seed);
+        System.out.printf("-Dseed=%d%n", seed);
+    }
+
+    public static void main(String[] args) throws Exception {
+        int count = DEFAULT_COUNT;
+        if (args.length > 0) {
+            count = Integer.parseInt(args[0]) ;
+        }
+        for (int i = 0; i < count; ++i) {
+            runTest();
+        }
+    }
+
+    private static void runTest() throws Exception {
+        String useTypeSpeculation = "-XX:" + (RNG.nextBoolean() ? "+" : "-") +  USE_TYPE_SPECULATION;
+        String typeProfileLevel = "-XX:" + TYPE_PROFILE_LEVEL + "=" + randomTypeProfileLevel();
+        ProfilingType type = randomProfileType();
+        OPTIONS[TYPE_PROFILE_INDEX] = typeProfileLevel;
+        OPTIONS[USE_TYPE_SPECULATION_INDEX] = useTypeSpeculation;
+        OPTIONS[PROFILING_TYPE_INDEX] = type.name();
+        ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(/* addTestVmOptions= */ true, OPTIONS);
+        OutputAnalyzer outputAnalyzer = new OutputAnalyzer(processBuilder.start());
+        outputAnalyzer.shouldHaveExitValue(0);
+    }
+
+    private static ProfilingType randomProfileType() {
+        ProfilingType[] value = ProfilingType.values();
+        return value[RNG.nextInt(value.length)];
+    }
+
+    private static String randomTypeProfileLevel() {
+        StringBuilder stringBuilder = new StringBuilder();
+        for (int i = 0; i < TYPE_PROFILE_LEVEL_LENGTH; ++i) {
+            stringBuilder.append(RNG.nextInt(TYPE_PROFILE_LEVEL_BOUND));
+        }
+        return stringBuilder.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/execution/Execution.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, 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 execution;
+
+import hierarchies.TypeHierarchy;
+import scenarios.Scenario;
+
+/**
+ * Execution scenario represents test methods execution type.
+ * @param <T> parameter type
+ * @param <R> result Type
+ */
+public interface Execution<T extends TypeHierarchy.I, R> {
+    /**
+     * Executes the test code of the given scenario
+     * See {@link scenarios.Scenario#run(T)}
+     *
+     * @param scenario test scenario
+     */
+    void execute(Scenario<T, R> scenario);
+
+    default String getName() {
+        return this.getClass().getName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/execution/MethodHandleDelegate.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014, 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 execution;
+
+import hierarchies.TypeHierarchy;
+import scenarios.Scenario;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+/**
+ * Executes test scenario using {@link MethodHandle#invoke(Object...)}.
+ * Delegates execution to the given {@link Execution} by creating
+ * new test scenario, see {@link Scenario}
+ */
+public class MethodHandleDelegate<T  extends TypeHierarchy.I, R> implements Execution<T, R> {
+    private final Execution<T, R> delegate;
+
+    public MethodHandleDelegate(Execution<T, R> delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public void execute(Scenario<T, R> scenario) {
+        delegate.execute(new MHScenario<T, R>(scenario));
+    }
+
+    @Override
+    public String getName() {
+        return "MethodHandleDelegate # " + delegate.getName();
+    }
+
+    private static class MHScenario<T extends TypeHierarchy.I, R> extends Scenario<T, R> {
+        private final Scenario<T, R> scenario;
+        private static final MethodHandle METHOD_HANDLE_RUN;
+
+        static {
+            MethodHandles.Lookup lookup = MethodHandles.lookup();
+            MethodType methodType = MethodType.methodType(Object.class, TypeHierarchy.I.class);
+
+            try {
+                METHOD_HANDLE_RUN = lookup.findVirtual(Scenario.class, "run", methodType);
+            } catch (NoSuchMethodException | IllegalAccessException e) {
+                System.err.println("Failed to get target method run() with " + e);
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+        }
+
+        /**
+         * Constructor
+         *
+         * @param scenario test scenario to be executed
+         */
+        private MHScenario(Scenario<T, R> scenario) {
+            super("MethodHandle::" + scenario.getName(), scenario.profilingType, scenario.hierarchy);
+            this.scenario = scenario;
+        }
+
+        /**
+         * Runs {@link Scenario#run(T)} with {@link MethodHandle#invoke(Object...)}
+         *
+         * @param t subject of the test
+         * @return  result of the underlying {@link Scenario#run(T)} invocation
+         */
+        @SuppressWarnings("unchecked")
+        @Override
+        public R run(T t) {
+            try {
+                return (R) METHOD_HANDLE_RUN.invoke(scenario, t);
+            } catch (Throwable thr) {
+                System.err.println(scenario.getName()
+                        + " failed to invoke target method run() with " + thr);
+                throw new RuntimeException("Invocation failed", thr);
+            }
+        }
+
+        @Override
+        public void check(R r, T t) {
+            scenario.check(r, t);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/execution/TypeConflict.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014, 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 execution;
+
+import hierarchies.TypeHierarchy;
+import scenarios.Scenario;
+
+/**
+ *  Type profiling conflict execution scenario. The main goal is
+ *  to make compiler profile and compile methods with different types.
+ *  Scenario tests guards by passing conflicting types (incompatible
+ *  for the profiled data).
+ */
+public class TypeConflict<T extends TypeHierarchy.I, R> implements Execution<T, R> {
+    /** Test methods execution number to make profile  */
+    private final static int POLLUTION_THRESHOLD = 5000;
+    /** Test methods execution number to make it profiled and compiled*/
+    private final static int PROFILE_THRESHOLD = 20000;
+
+    @Override
+    public void execute(Scenario<T, R> scenario) {
+        T base = scenario.getProfiled();
+        T incompatible = scenario.getConflict();
+
+        // pollute profile by passing different types
+        R baseResult = null;
+        R incResult = null;
+        for (int i = 0; i < POLLUTION_THRESHOLD; i++) {
+            baseResult = methodNotToCompile(scenario, base);
+            incResult = methodNotToCompile(scenario, incompatible);
+        }
+        scenario.check(baseResult, base);
+        scenario.check(incResult, incompatible);
+
+        // profile and compile
+        R result = null;
+        for (int i = 0; i < PROFILE_THRESHOLD; i++) {
+            result = methodNotToCompile(scenario, base);
+        }
+        scenario.check(result, base);
+
+        // pass another type to make guard work and recompile
+        for (int i = 0; i < PROFILE_THRESHOLD; i++) {
+            result = methodNotToCompile(scenario, incompatible);
+        }
+        scenario.check(result, incompatible);
+    }
+
+    private R methodNotToCompile(Scenario<T, R> scenario, T t) {
+        return scenario.run(t);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/execution/TypeProfile.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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 execution;
+
+import hierarchies.TypeHierarchy;
+import scenarios.Scenario;
+
+/**
+ * Profile type execution scenario. Executes tester method
+ * in a loop without any manipulation with types or instances.
+ */
+public class TypeProfile<T extends TypeHierarchy.I, R> implements Execution<T, R> {
+    /** Number of test method execution to make it profiled and compiled */
+    private final static int PROFILE_THRESHOLD = 100000;
+
+    /**
+     * Makes scenario code be profiled and compiled
+     * @param scenario Test scenario
+     */
+    @Override
+    public void execute(Scenario<T, R> scenario) {
+        R result = null;
+        T prof = scenario.getProfiled();
+        T confl = scenario.getConflict();
+
+        for (int i = 0; i < PROFILE_THRESHOLD; i++) {
+            result = methodNotToCompile(scenario, prof);
+        }
+        scenario.check(result, prof);
+
+        result = methodNotToCompile(scenario, confl);
+        scenario.check(result, confl);
+    }
+
+    protected R methodNotToCompile(Scenario<T, R> scenario, T t) {
+        return scenario.run(t);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class DefaultMethodInterface {
+    private DefaultMethodInterface() {
+    }
+
+    public static class Hierarchy
+            extends TypeHierarchy<DefaultMethodInterface.A, DefaultMethodInterface.B> {
+        public Hierarchy() {
+            super(new DefaultMethodInterface.A(), new DefaultMethodInterface.B(),
+                    DefaultMethodInterface.A.class, DefaultMethodInterface.B.class);
+        }
+    }
+
+    public static interface I2 extends TypeHierarchy.I {
+        default int m() {
+            return TypeHierarchy.ANSWER;
+        }
+    }
+
+    public static class A implements I2 {
+        // use default method from I2
+    }
+
+    public static class B extends A {
+        @Override
+        public int m() {
+            return TypeHierarchy.YEAR;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface2.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class DefaultMethodInterface2 {
+    private DefaultMethodInterface2() {
+    }
+
+    public static class Hierarchy
+            extends TypeHierarchy<TypeHierarchy.A, DefaultMethodInterface2.B> {
+        public Hierarchy() {
+            super(new TypeHierarchy.A(), new DefaultMethodInterface2.B(),
+                    TypeHierarchy.A.class, DefaultMethodInterface2.B.class);
+        }
+    }
+
+    public static interface I2 extends TypeHierarchy.I {
+        default int m() {
+            return TypeHierarchy.ANSWER;
+        }
+    }
+
+    public static class B implements I2 {
+        // default method I2.m()
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/Linear.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class Linear {
+    private Linear() {
+    }
+
+    public static class Hierarchy extends TypeHierarchy<TypeHierarchy.A, Linear.B> {
+        public Hierarchy() {
+            super(new TypeHierarchy.A(), new Linear.B(),
+                    TypeHierarchy.A.class, Linear.B.class);
+        }
+    }
+
+    public static class B extends TypeHierarchy.A {
+        @Override
+        public int m() {
+            return TypeHierarchy.YEAR;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/Linear2.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class Linear2 {
+    private Linear2() {
+    }
+
+    public static class Hierarchy extends TypeHierarchy<TypeHierarchy.A, Linear2.B> {
+        public Hierarchy() {
+            super(new A(), new Linear2.B(),
+                    A.class, Linear2.B.class);
+        }
+    }
+
+    public static interface I2 {
+        int m();
+    }
+
+    public static class B extends TypeHierarchy.A implements Linear2.I2 {
+        @Override
+        public int m() {
+            return TypeHierarchy.YEAR;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/NullableType.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class NullableType<M extends TypeHierarchy.I, N extends TypeHierarchy.I>
+        extends TypeHierarchy<M, N> {
+
+    public NullableType(TypeHierarchy<M, N> delegate) {
+        super(delegate.getM(), null,
+                delegate.getClassM(), delegate.getClassN());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/OneRank.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class OneRank {
+    private OneRank() {
+    }
+
+    public static class Hierarchy extends TypeHierarchy<TypeHierarchy.A, OneRank.B> {
+        public Hierarchy() {
+            super(new TypeHierarchy.A(), new OneRank.B(),
+                    TypeHierarchy.A.class, OneRank.B.class);
+        }
+    }
+
+    public static class B implements TypeHierarchy.I {
+        @Override
+        public int m() {
+            return TypeHierarchy.YEAR;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/TypeHierarchy.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+/**
+ * Type hierarchy contains classes the type profiling and speculation are tested with
+ */
+public abstract class TypeHierarchy<M extends TypeHierarchy.I, N extends TypeHierarchy.I> {
+    // Magic numbers
+    public static final int ANSWER = 42;
+    public static final int TEMP = 451;
+    public static final int YEAR = 1984;
+
+    private final M m;
+    private final N n;
+    private final Class<M> classM;
+    private final Class<N> classN;
+
+    protected TypeHierarchy(M m, N n, Class<M> classM, Class<N> classN) {
+        this.m = m;
+        this.n = n;
+        this.classM = classM;
+        this.classN = classN;
+    }
+
+    public final M getM() {
+        return m;
+    }
+
+    public final N getN() {
+        return n;
+    }
+
+    public final Class<M> getClassM() {
+        return classM;
+    }
+
+    public final Class<N> getClassN() {
+        return classN;
+    }
+
+    public interface I {
+        int m();
+    }
+
+    public static class A implements I {
+        @Override
+        public int m() {
+            return TypeHierarchy.ANSWER;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayCopy.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import hierarchies.TypeHierarchy;
+
+import java.util.Arrays;
+
+/**
+ * Tests System.arraycopy()
+ */
+public class ArrayCopy extends ArrayScenario {
+    public ArrayCopy(ProfilingType profilingType,
+                     TypeHierarchy<? extends TypeHierarchy.I, ? extends TypeHierarchy.I> hierarchy) {
+        super("ArrayCopy", profilingType, hierarchy);
+    }
+
+    /**
+     * @param obj is used to fill arrays
+     * @return the same obj
+     */
+    @Override
+    public TypeHierarchy.I run(TypeHierarchy.I obj) {
+        switch (profilingType) {
+            case RETURN:
+                TypeHierarchy.I t = collectReturnType(obj);
+                Arrays.fill(array, t);
+                System.arraycopy(array, 0, matrix[0], 0, array.length);
+                return array[0];
+            case ARGUMENTS:
+                field = obj;
+                Arrays.fill(array, field);
+                System.arraycopy(array, 0, matrix[0], 0, array.length);
+                return array[0];
+            case PARAMETERS:
+                Arrays.fill(array, obj);
+                System.arraycopy(array, 0, matrix[0], 0, array.length);
+                return array[0];
+        }
+        throw new RuntimeException("Should not reach here");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayReferenceStore.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import hierarchies.TypeHierarchy;
+
+import java.util.Arrays;
+
+/**
+ * Tests aastore bytecode
+ */
+public class ArrayReferenceStore extends ArrayScenario {
+    public ArrayReferenceStore(ProfilingType profilingType,
+                               TypeHierarchy<? extends TypeHierarchy.I, ? extends TypeHierarchy.I> hierarchy) {
+        super("ArrayReferenceStore", profilingType, hierarchy);
+    }
+
+    /**
+     * @param obj is used to fill arrays
+     * @return obj
+     */
+    @Override
+    public TypeHierarchy.I run(TypeHierarchy.I obj) {
+        switch (profilingType) {
+            case RETURN:
+                TypeHierarchy.I t = collectReturnType(obj);
+                Arrays.fill(array, t);
+                matrix[0] = array;
+                return matrix[0][0];
+            case ARGUMENTS:
+                field = obj;
+                Arrays.fill(array, field);
+                matrix[0] = array;
+                return matrix[0][0];
+            case PARAMETERS:
+                Arrays.fill(array, obj);
+                matrix[0] = array;
+                return matrix[0][0];
+        }
+        throw new RuntimeException("Should not reach here");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayScenario.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
+/**
+ *  Base class for array scenarios
+ */
+public abstract class ArrayScenario extends Scenario<TypeHierarchy.I, TypeHierarchy.I> {
+    protected final TypeHierarchy.I[] array;
+    protected final TypeHierarchy.I[][] matrix;
+
+    protected ArrayScenario(String name, ProfilingType profilingType,
+                            TypeHierarchy<? extends TypeHierarchy.I, ? extends TypeHierarchy.I> hierarchy) {
+        super(name, profilingType, hierarchy);
+        final int x = 20;
+        final int y = 10;
+
+        TypeHierarchy.I prof = hierarchy.getM();
+        TypeHierarchy.I confl = hierarchy.getN();
+
+        this.array = (TypeHierarchy.I[]) Array.newInstance(hierarchy.getClassM(), y);
+        Arrays.fill(array, prof);
+
+        this.matrix = (TypeHierarchy.I[][]) Array.newInstance(hierarchy.getClassM(), x, y);
+        for (int i = 0; i < x; i++) {
+            this.matrix[i] = this.array;
+        }
+
+        Asserts.assertEquals(array.length, matrix[0].length, "Invariant");
+    }
+
+    @Override
+    public boolean isApplicable() {
+        return hierarchy.getClassM().isAssignableFrom(hierarchy.getClassN());
+    }
+
+    @Override
+    public void check(TypeHierarchy.I res, TypeHierarchy.I orig) {
+        Asserts.assertEquals(res, orig, "Check failed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/CheckCast.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+import java.util.Objects;
+
+/**
+ * Checkcast scenario
+ * @param <T> profiling parameter
+ */
+public class CheckCast<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
+    public CheckCast(ProfilingType profilingType, TypeHierarchy<? extends T, ? extends T> hierarchy) {
+        super("CheckCast", profilingType, hierarchy);
+    }
+
+    /**
+     * Returns type profiling.
+     * @param obj is a profiled parameter for the test
+     * @return parameter casted to the type R
+     */
+    @Override
+    public Integer run(T obj) {
+        switch (profilingType) {
+            case RETURN:
+                T t = collectReturnType(obj);
+                if (t != null) {
+                    return t.m();
+                }
+                return null;
+            case ARGUMENTS:
+                field = obj;
+                if (field != null) {
+                    return field.m();
+                }
+                return null;
+            case PARAMETERS:
+                if (obj != null) {
+                    return obj.m();
+                }
+                return null;
+        }
+        throw new RuntimeException("Should not reach here");
+    }
+
+    @Override
+    public void check(Integer result, T orig) {
+        if (result != null || orig != null) {
+            Objects.requireNonNull(result);
+            Objects.requireNonNull(orig);
+            Asserts.assertEquals(result, orig.m(), "Results mismatch");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ClassIdentity.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+/**
+ * Tests pattern: if (a.getClass() == D.class)
+ */
+public class ClassIdentity<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
+    public ClassIdentity(ProfilingType profilingType,
+                         TypeHierarchy<? extends T, ? extends T> hierarchy) {
+        super("ClassIdentity", profilingType, hierarchy);
+    }
+
+    @Override
+    public boolean isApplicable() {
+        return hierarchy.getM() != null && hierarchy.getN() != null;
+    }
+
+    @Override
+    public Integer run(T obj) {
+        switch (profilingType) {
+            case RETURN:
+                T t = collectReturnType(obj);
+                if (t.getClass() == TypeHierarchy.A.class) {
+                    return inlinee(t);
+                }
+                return TypeHierarchy.TEMP;
+            case ARGUMENTS:
+                field = obj;
+                if (field.getClass() == TypeHierarchy.A.class) {
+                    return inlinee(field);
+                }
+                return TypeHierarchy.TEMP;
+            case PARAMETERS:
+                if (obj.getClass() == TypeHierarchy.A.class) {
+                    return inlinee(obj);
+                }
+                return TypeHierarchy.TEMP;
+        }
+        throw new RuntimeException("Should not reach here");
+    }
+
+    public int inlinee(T obj) {
+        return obj.m();
+    }
+
+    @Override
+    public void check(Integer result, T orig) {
+        if (orig.getClass() == TypeHierarchy.A.class) {
+            Asserts.assertEquals(result, orig.m(),
+                    "Results are not equal for TypeHierarchy.A.class");
+        } else {
+            Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ClassInstanceOf.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+/**
+ * Tests instanceof
+ */
+public class ClassInstanceOf<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
+    public ClassInstanceOf(ProfilingType profilingType,
+                           TypeHierarchy<? extends T, ? extends T> hierarchy) {
+        super("ClassInstanceOf", profilingType, hierarchy);
+    }
+
+    @Override
+    public Integer run(T obj) {
+        switch (profilingType) {
+            case RETURN:
+                T t = collectReturnType(obj);
+                if (t instanceof TypeHierarchy.A) {
+                    return inlinee(t);
+                }
+                return TypeHierarchy.TEMP;
+            case ARGUMENTS:
+                field = obj;
+                if (field instanceof TypeHierarchy.A) {
+                    return inlinee(field);
+                }
+                return TypeHierarchy.TEMP;
+            case PARAMETERS:
+                if (obj instanceof TypeHierarchy.A) {
+                    return inlinee(obj);
+                }
+                return TypeHierarchy.TEMP;
+        }
+        throw new RuntimeException("Should not reach here");
+    }
+
+    public int inlinee(T obj) {
+        return obj.m();
+    }
+
+    @Override
+    public void check(Integer result, T orig) {
+        if (orig instanceof TypeHierarchy.A) {
+            Asserts.assertEquals(result, orig.m(), "Results are not equal for TypeHierarchy.A");
+        } else {
+            Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ClassIsInstance.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+/**
+ * Tests {@link Class#isInstance(Object)}
+ */
+public class ClassIsInstance<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
+    private final Class<?> baseClass;
+
+    public ClassIsInstance(ProfilingType profilingType,
+                           TypeHierarchy<? extends T, ? extends T> hierarchy) {
+        super("ClassIsInstance", profilingType, hierarchy);
+        this.baseClass = hierarchy.getClassM();
+    }
+
+    @Override
+    public Integer run(T obj) {
+        switch (profilingType) {
+            case RETURN:
+                T t = collectReturnType(obj);
+                if (baseClass.isInstance(t)) {
+                    return inlinee(t);
+                }
+                return TypeHierarchy.TEMP;
+            case ARGUMENTS:
+                field = obj;
+                if (baseClass.isInstance(field)) {
+                    return inlinee(field);
+                }
+                return TypeHierarchy.TEMP;
+            case PARAMETERS:
+                if (baseClass.isInstance(obj)) {
+                    return inlinee(obj);
+                }
+                return TypeHierarchy.TEMP;
+        }
+        throw new RuntimeException("Should not reach here");
+    }
+
+    public int inlinee(T obj) {
+        return obj.m();
+    }
+
+    @Override
+    public void check(Integer result, T orig) {
+        if (baseClass.isInstance(orig)) {
+            Asserts.assertEquals(result, orig.m(), "Results are not equal for base class");
+        } else {
+            Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ProfilingType.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+public enum ProfilingType {
+    /** type profiling of return values of reference types from an invoke */
+    RETURN,
+    /** type profiling for reference parameters on method entries */
+    PARAMETERS,
+    /** type profiling for reference arguments at an invoke */
+    ARGUMENTS,
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ReceiverAtInvokes.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+/**
+ * Receiver at invokes profiling and speculation
+ *
+ * @param <T> parameter to be returned
+ */
+public class ReceiverAtInvokes<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
+    public ReceiverAtInvokes(ProfilingType profilingType,
+                             TypeHierarchy<? extends T, ? extends T> hierarchy) {
+        super("ReceiverAtInvokes", profilingType, hierarchy);
+    }
+
+    @Override
+    public boolean isApplicable() {
+        return hierarchy.getM() != null && hierarchy.getN() != null;
+    }
+
+    /**
+     * Receiver profiling
+     *
+     * @param obj is a profiled parameter for the test
+     * @return parameter casted to the type R
+     */
+    @Override
+    public Integer run(T obj) {
+        switch (profilingType) {
+            case RETURN:
+                T t = collectReturnType(obj);
+                return inlinee(t);
+            case ARGUMENTS:
+                field = obj;
+                return inlinee(field);
+            case PARAMETERS:
+                return inlinee(obj);
+        }
+        throw new RuntimeException("Should not reach here");
+    }
+
+    private Integer inlinee(T obj) {
+        return obj.m(); // should be inlined
+    }
+
+    @Override
+    public void check(Integer result, T orig) {
+        Asserts.assertEquals(result, orig.m(), "Results mismatch");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/Scenario.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import hierarchies.TypeHierarchy;
+
+/**
+ * Test scenario
+ *
+ * @param <T> parameter type
+ * @param <R> result type
+ */
+public abstract class Scenario<T extends TypeHierarchy.I, R> {
+
+    private final String name;
+    public final ProfilingType profilingType;
+    public final TypeHierarchy <? extends T, ? extends T> hierarchy;
+    protected volatile T field;
+
+    /**
+     * Constructor
+     *
+     * @param name          scenario name
+     * @param profilingType tested profiling type
+     * @param hierarchy     type hierarchy
+     */
+    protected Scenario(String name, ProfilingType profilingType,
+                       TypeHierarchy<? extends T, ? extends T> hierarchy) {
+        this.profilingType = profilingType;
+        this.name = name + " # " + profilingType.name();
+        this.hierarchy = hierarchy;
+    }
+
+    /**
+     * Returns the object which should be used as a parameter
+     * for the methods used for profile data
+     *
+     * @return profiled type object
+     */
+    public T getProfiled() {
+        return hierarchy.getM();
+    }
+
+    /**
+     * Returns the object which makes a conflict for a profiled data
+     * when passed instead of {@linkplain Scenario#getProfiled}
+     *
+     * @return incompatible to profiled object
+     */
+    public T getConflict() {
+        return hierarchy.getN();
+    }
+
+    /**
+     * @return scenario name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /** Is this scenario applicable for a hierarchy it was constructed with */
+    public boolean isApplicable() {
+        return true;
+    }
+
+    /**
+     * Runs test scenario
+     *
+     * @param t subject of the test
+     * @return  result of the test invocation
+     */
+    public abstract R run(T t);
+
+    /** Used for a return type profiling */
+    protected final T collectReturnType(T t) {
+        return t;
+    }
+
+    /**
+     * Checks the result for R and T
+     *
+     * @param r result
+     * @param t original
+     * @throws java.lang.RuntimeException on result mismatch
+     */
+    public abstract void check(R r, T t);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,268 @@
+/*
+ * 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 8032410
+ * @summary Stack overflow at deoptimization doesn't release owned monitors
+ * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangMonitorOwned::m1 -XX:CompileCommand=exclude,TestStackBangMonitorOwned::m2 -Xss256K -XX:-UseOnStackReplacement TestStackBangMonitorOwned
+ *
+ */
+public class TestStackBangMonitorOwned {
+
+    static class UnloadedClass1 {
+        volatile int field;
+    }
+
+    static Object m1(boolean deopt) {
+        long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12,
+        l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24,
+        l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36,
+        l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47, l48,
+        l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60,
+        l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72,
+        l73, l74, l75, l76, l77, l78, l79, l80, l81, l82, l83, l84,
+        l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96,
+        l97, l98, l99, l100, l101, l102, l103, l104, l105, l106, l107,
+        l108, l109, l110, l111, l112, l113, l114, l115, l116, l117,
+        l118, l119, l120, l121, l122, l123, l124, l125, l126, l127,
+        l128, l129, l130, l131, l132, l133, l134, l135, l136, l137,
+        l138, l139, l140, l141, l142, l143, l144, l145, l146, l147,
+        l148, l149, l150, l151, l152, l153, l154, l155, l156, l157,
+        l158, l159, l160, l161, l162, l163, l164, l165, l166, l167,
+        l168, l169, l170, l171, l172, l173, l174, l175, l176, l177,
+        l178, l179, l180, l181, l182, l183, l184, l185, l186, l187,
+        l188, l189, l190, l191, l192, l193, l194, l195, l196, l197,
+        l198, l199, l200, l201, l202, l203, l204, l205, l206, l207,
+        l208, l209, l210, l211, l212, l213, l214, l215, l216, l217,
+        l218, l219, l220, l221, l222, l223, l224, l225, l226, l227,
+        l228, l229, l230, l231, l232, l233, l234, l235, l236, l237,
+        l238, l239, l240, l241, l242, l243, l244, l245, l246, l247,
+        l248, l249, l250, l251, l252, l253, l254, l255, l256, l257,
+        l258, l259, l260, l261, l262, l263, l264, l265, l266, l267,
+        l268, l269, l270, l271, l272, l273, l274, l275, l276, l277,
+        l278, l279, l280, l281, l282, l283, l284, l285, l286, l287,
+        l288, l289, l290, l291, l292, l293, l294, l295, l296, l297,
+        l298, l299, l300, l301, l302, l303, l304, l305, l306, l307,
+        l308, l309, l310, l311, l312, l313, l314, l315, l316, l317,
+        l318, l319, l320, l321, l322, l323, l324, l325, l326, l327,
+        l328, l329, l330, l331, l332, l333, l334, l335, l336, l337,
+        l338, l339, l340, l341, l342, l343, l344, l345, l346, l347,
+        l348, l349, l350, l351, l352, l353, l354, l355, l356, l357,
+        l358, l359, l360, l361, l362, l363, l364, l365, l366, l367,
+        l368, l369, l370, l371, l372, l373, l374, l375, l376, l377,
+        l378, l379, l380, l381, l382, l383, l384, l385, l386, l387,
+        l388, l389, l390, l391, l392, l393, l394, l395, l396, l397,
+        l398, l399, l400, l401, l402, l403, l404, l405, l406, l407,
+        l408, l409, l410, l411, l412, l413, l414, l415, l416, l417,
+        l418, l419, l420, l421, l422, l423, l424, l425, l426, l427,
+        l428, l429, l430, l431, l432, l433, l434, l435, l436, l437,
+        l438, l439, l440, l441, l442, l443, l444, l445, l446, l447,
+        l448, l449, l450, l451, l452, l453, l454, l455, l456, l457,
+        l458, l459, l460, l461, l462, l463, l464, l465, l466, l467,
+        l468, l469, l470, l471, l472, l473, l474, l475, l476, l477,
+        l478, l479, l480, l481, l482, l483, l484, l485, l486, l487,
+        l488, l489, l490, l491, l492, l493, l494, l495, l496, l497,
+        l498, l499, l500, l501, l502, l503, l504, l505, l506, l507,
+        l508, l509, l510, l511;
+
+        long ll0, ll1, ll2, ll3, ll4, ll5, ll6, ll7, ll8, ll9, ll10, ll11, ll12,
+        ll13, ll14, ll15, ll16, ll17, ll18, ll19, ll20, ll21, ll22, ll23, ll24,
+        ll25, ll26, ll27, ll28, ll29, ll30, ll31, ll32, ll33, ll34, ll35, ll36,
+        ll37, ll38, ll39, ll40, ll41, ll42, ll43, ll44, ll45, ll46, ll47, ll48,
+        ll49, ll50, ll51, ll52, ll53, ll54, ll55, ll56, ll57, ll58, ll59, ll60,
+        ll61, ll62, ll63, ll64, ll65, ll66, ll67, ll68, ll69, ll70, ll71, ll72,
+        ll73, ll74, ll75, ll76, ll77, ll78, ll79, ll80, ll81, ll82, ll83, ll84,
+        ll85, ll86, ll87, ll88, ll89, ll90, ll91, ll92, ll93, ll94, ll95, ll96,
+        ll97, ll98, ll99, ll100, ll101, ll102, ll103, ll104, ll105, ll106, ll107,
+        ll108, ll109, ll110, ll111, ll112, ll113, ll114, ll115, ll116, ll117,
+        ll118, ll119, ll120, ll121, ll122, ll123, ll124, ll125, ll126, ll127,
+        ll128, ll129, ll130, ll131, ll132, ll133, ll134, ll135, ll136, ll137,
+        ll138, ll139, ll140, ll141, ll142, ll143, ll144, ll145, ll146, ll147,
+        ll148, ll149, ll150, ll151, ll152, ll153, ll154, ll155, ll156, ll157,
+        ll158, ll159, ll160, ll161, ll162, ll163, ll164, ll165, ll166, ll167,
+        ll168, ll169, ll170, ll171, ll172, ll173, ll174, ll175, ll176, ll177,
+        ll178, ll179, ll180, ll181, ll182, ll183, ll184, ll185, ll186, ll187,
+        ll188, ll189, ll190, ll191, ll192, ll193, ll194, ll195, ll196, ll197,
+        ll198, ll199, ll200, ll201, ll202, ll203, ll204, ll205, ll206, ll207,
+        ll208, ll209, ll210, ll211, ll212, ll213, ll214, ll215, ll216, ll217,
+        ll218, ll219, ll220, ll221, ll222, ll223, ll224, ll225, ll226, ll227,
+        ll228, ll229, ll230, ll231, ll232, ll233, ll234, ll235, ll236, ll237,
+        ll238, ll239, ll240, ll241, ll242, ll243, ll244, ll245, ll246, ll247,
+        ll248, ll249, ll250, ll251, ll252, ll253, ll254, ll255, ll256, ll257,
+        ll258, ll259, ll260, ll261, ll262, ll263, ll264, ll265, ll266, ll267,
+        ll268, ll269, ll270, ll271, ll272, ll273, ll274, ll275, ll276, ll277,
+        ll278, ll279, ll280, ll281, ll282, ll283, ll284, ll285, ll286, ll287,
+        ll288, ll289, ll290, ll291, ll292, ll293, ll294, ll295, ll296, ll297,
+        ll298, ll299, ll300, ll301, ll302, ll303, ll304, ll305, ll306, ll307,
+        ll308, ll309, ll310, ll311, ll312, ll313, ll314, ll315, ll316, ll317,
+        ll318, ll319, ll320, ll321, ll322, ll323, ll324, ll325, ll326, ll327,
+        ll328, ll329, ll330, ll331, ll332, ll333, ll334, ll335, ll336, ll337,
+        ll338, ll339, ll340, ll341, ll342, ll343, ll344, ll345, ll346, ll347,
+        ll348, ll349, ll350, ll351, ll352, ll353, ll354, ll355, ll356, ll357,
+        ll358, ll359, ll360, ll361, ll362, ll363, ll364, ll365, ll366, ll367,
+        ll368, ll369, ll370, ll371, ll372, ll373, ll374, ll375, ll376, ll377,
+        ll378, ll379, ll380, ll381, ll382, ll383, ll384, ll385, ll386, ll387,
+        ll388, ll389, ll390, ll391, ll392, ll393, ll394, ll395, ll396, ll397,
+        ll398, ll399, ll400, ll401, ll402, ll403, ll404, ll405, ll406, ll407,
+        ll408, ll409, ll410, ll411, ll412, ll413, ll414, ll415, ll416, ll417,
+        ll418, ll419, ll420, ll421, ll422, ll423, ll424, ll425, ll426, ll427,
+        ll428, ll429, ll430, ll431, ll432, ll433, ll434, ll435, ll436, ll437,
+        ll438, ll439, ll440, ll441, ll442, ll443, ll444, ll445, ll446, ll447,
+        ll448, ll449, ll450, ll451, ll452, ll453, ll454, ll455, ll456, ll457,
+        ll458, ll459, ll460, ll461, ll462, ll463, ll464, ll465, ll466, ll467,
+        ll468, ll469, ll470, ll471, ll472, ll473, ll474, ll475, ll476, ll477,
+        ll478, ll479, ll480, ll481, ll482, ll483, ll484, ll485, ll486, ll487,
+        ll488, ll489, ll490, ll491, ll492, ll493, ll494, ll495, ll496, ll497,
+        ll498, ll499, ll500, ll501, ll502, ll503, ll504, ll505, ll506, ll507,
+        ll508, ll509, ll510, ll511;
+
+        if (deopt) {
+            method_entered = true;
+            synchronized(monitor) {
+                do_monitor_acquire = true;
+                UnloadedClass1 res = new UnloadedClass1(); // forces deopt with c2
+                res.field = 0; //forced deopt with c1
+                return res;
+            }
+        }
+        return null;
+    }
+
+    static boolean m2(boolean deopt) {
+        long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12,
+        l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24,
+        l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36,
+        l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47, l48,
+        l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60,
+        l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72,
+        l73, l74, l75, l76, l77, l78, l79, l80, l81, l82, l83, l84,
+        l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96,
+        l97, l98, l99, l100, l101, l102, l103, l104, l105, l106, l107,
+        l108, l109, l110, l111, l112, l113, l114, l115, l116, l117,
+        l118, l119, l120, l121, l122, l123, l124, l125, l126, l127,
+        l128, l129, l130, l131, l132, l133, l134, l135, l136, l137,
+        l138, l139, l140, l141, l142, l143, l144, l145, l146, l147,
+        l148, l149, l150, l151, l152, l153, l154, l155, l156, l157,
+        l158, l159, l160, l161, l162, l163, l164, l165, l166, l167,
+        l168, l169, l170, l171, l172, l173, l174, l175, l176, l177,
+        l178, l179, l180, l181, l182, l183, l184, l185, l186, l187,
+        l188, l189, l190, l191, l192, l193, l194, l195, l196, l197,
+        l198, l199, l200, l201, l202, l203, l204, l205, l206, l207,
+        l208, l209, l210, l211, l212, l213, l214, l215, l216, l217,
+        l218, l219, l220, l221, l222, l223, l224, l225, l226, l227,
+        l228, l229, l230, l231, l232, l233, l234, l235, l236, l237,
+        l238, l239, l240, l241, l242, l243, l244, l245, l246, l247,
+        l248, l249, l250, l251, l252, l253, l254, l255, l256, l257,
+        l258, l259, l260, l261, l262, l263, l264, l265, l266, l267,
+        l268, l269, l270, l271, l272, l273, l274, l275, l276, l277,
+        l278, l279, l280, l281, l282, l283, l284, l285, l286, l287,
+        l288, l289, l290, l291, l292, l293, l294, l295, l296, l297,
+        l298, l299, l300, l301, l302, l303, l304, l305, l306, l307,
+        l308, l309, l310, l311, l312, l313, l314, l315, l316, l317,
+        l318, l319, l320, l321, l322, l323, l324, l325, l326, l327,
+        l328, l329, l330, l331, l332, l333, l334, l335, l336, l337,
+        l338, l339, l340, l341, l342, l343, l344, l345, l346, l347,
+        l348, l349, l350, l351, l352, l353, l354, l355, l356, l357,
+        l358, l359, l360, l361, l362, l363, l364, l365, l366, l367,
+        l368, l369, l370, l371, l372, l373, l374, l375, l376, l377,
+        l378, l379, l380, l381, l382, l383, l384, l385, l386, l387,
+        l388, l389, l390, l391, l392, l393, l394, l395, l396, l397,
+        l398, l399, l400, l401, l402, l403, l404, l405, l406, l407,
+        l408, l409, l410, l411, l412, l413, l414, l415, l416, l417,
+        l418, l419, l420, l421, l422, l423, l424, l425, l426, l427,
+        l428, l429, l430, l431, l432, l433, l434, l435, l436, l437,
+        l438, l439, l440, l441, l442, l443, l444, l445, l446, l447,
+        l448, l449, l450, l451, l452, l453, l454, l455, l456, l457,
+        l458, l459, l460, l461, l462, l463, l464, l465, l466, l467,
+        l468, l469, l470, l471, l472, l473, l474, l475, l476, l477,
+        l478, l479, l480, l481, l482, l483, l484, l485, l486, l487,
+        l488, l489, l490, l491, l492, l493, l494, l495, l496, l497,
+        l498, l499, l500, l501, l502, l503, l504, l505, l506, l507,
+        l508, l509, l510, l511;
+
+        boolean do_m3 = false;
+        try {
+            do_m3 = m2(deopt);
+        } catch (StackOverflowError e) {
+            return true;
+        }
+        if (do_m3) {
+            try {
+                m1(deopt);
+            } catch (StackOverflowError e) {}
+        }
+        return false;
+    }
+
+    // Used for synchronization betwen threads
+    static volatile boolean thread_started = false;
+    static volatile boolean do_monitor_acquire = false;
+    static volatile boolean monitor_acquired = false;
+    static volatile boolean method_entered = false;
+
+    static Object monitor = new Object();
+
+    static public void main(String[] args) {
+        // get m1 compiled
+        for (int i = 0; i < 20000; i++) {
+            m1(false);
+        }
+
+        Thread thread = new Thread() {
+            public void run() {
+                thread_started = true;
+                while(!do_monitor_acquire);
+                System.out.println("Ok to try to acquire the lock");
+                synchronized(monitor) {
+                    monitor_acquired = true;
+                }
+            }
+        };
+
+        thread.setDaemon(true);
+        thread.start();
+
+        while(!thread_started);
+
+        m2(true);
+
+        if (!method_entered) {
+            System.out.println("TEST PASSED");
+            return;
+        }
+
+        for (int i = 0; i < 10; i++) {
+            System.out.println("Is lock acquired?");
+            if (monitor_acquired) {
+                System.out.println("TEST PASSED");
+                return;
+            }
+            try {
+                Thread.sleep(10000);
+            } catch(InterruptedException ie) {
+            }
+        }
+        System.out.println("TEST FAILED");
+    }
+}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Thu Apr 17 13:50:26 2014 -0400
@@ -30,13 +30,25 @@
     private static final String osArch      = System.getProperty("os.arch");
     private static final String vmName      = System.getProperty("java.vm.name");
 
-     public static boolean isClient() {
-         return vmName.endsWith(" Client VM");
-     }
+    public static boolean isClient() {
+        return vmName.endsWith(" Client VM");
+    }
+
+    public static boolean isServer() {
+        return vmName.endsWith(" Server VM");
+    }
 
-     public static boolean isServer() {
-         return vmName.endsWith(" Server VM");
-     }
+    public static boolean isGraal() {
+        return vmName.endsWith(" Graal VM");
+    }
+
+    public static boolean isMinimal() {
+        return vmName.endsWith(" Minimal VM");
+    }
+
+    public static boolean isEmbedded() {
+        return vmName.contains("Embedded");
+    }
 
     public static boolean is32bit() {
         return dataModel.equals("32");
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java	Thu Apr 17 13:50:26 2014 -0400
@@ -145,18 +145,15 @@
     return createJavaProcessBuilder(false, command);
   }
 
-  public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmOptions, String... command) throws Exception {
+  public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions, String... command) throws Exception {
     String javapath = JDKToolFinder.getJDKTool("java");
 
     ArrayList<String> args = new ArrayList<>();
     args.add(javapath);
     Collections.addAll(args, getPlatformSpecificVMArgs());
 
-    if (addTestVmOptions) {
-      String vmopts = System.getProperty("test.vm.opts");
-      if (vmopts != null && vmopts.length() > 0) {
-        Collections.addAll(args, vmopts.split("\\s"));
-      }
+    if (addTestVmAndJavaOptions) {
+      Collections.addAll(args, Utils.getTestJavaOpts());
     }
 
     Collections.addAll(args, command);
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java	Thu Apr 17 13:50:26 2014 -0400
@@ -38,6 +38,8 @@
 import java.util.Collections;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
+import java.lang.reflect.Field;
+import sun.misc.Unsafe;
 
 /**
  * Common library for various test helper functions.
@@ -59,6 +61,8 @@
      */
     public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim();
 
+    private static Unsafe unsafe = null;
+
     /**
     * Returns the value of 'test.timeout.factor' system property
     * converted to {@code double}.
@@ -109,10 +113,10 @@
 
     /**
      * Returns the default JTReg arguments for a jvm running a test without
-     * options that matches regular expresions in {@code filters}.
+     * options that matches regular expressions in {@code filters}.
      * This is the combination of JTReg arguments test.vm.opts and test.java.opts.
      * @param filters Regular expressions used to filter out options.
-     * @return An array of options, or an empty array if no opptions.
+     * @return An array of options, or an empty array if no options.
      */
     public static String[] getFilteredTestJavaOpts(String... filters) {
         String options[] = getTestJavaOpts();
@@ -294,4 +298,38 @@
         return output;
     }
 
+    /**
+     * @return Unsafe instance.
+     */
+    public static synchronized Unsafe getUnsafe() {
+        if (unsafe == null) {
+            try {
+                Field f = Unsafe.class.getDeclaredField("theUnsafe");
+                f.setAccessible(true);
+                unsafe = (Unsafe) f.get(null);
+            } catch (NoSuchFieldException | IllegalAccessException e) {
+                throw new RuntimeException("Unable to get Unsafe instance.", e);
+            }
+        }
+        return unsafe;
+    }
+    private static final char[] hexArray = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+    /**
+     * Returns hex view of byte array
+     *
+     * @param bytes byte array to process
+     * @return Space separated hexadecimal string representation of bytes
+     */
+
+    public static String toHexString(byte[] bytes) {
+        char[] hexView = new char[bytes.length * 3];
+        int i = 0;
+        for (byte b : bytes) {
+            hexView[i++] = hexArray[(b >> 4) & 0x0F];
+            hexView[i++] = hexArray[b & 0x0F];
+            hexView[i++] = ' ';
+        }
+        return new String(hexView);
+    }
 }
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java	Thu Apr 17 13:50:26 2014 -0400
@@ -23,22 +23,16 @@
 
 package com.oracle.java.testlibrary.cli;
 
-import sun.hotspot.cpuinfo.CPUInfo;
-import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.predicate.CPUSpecificPredicate;
 
 /**
  * Base class for command line options tests that
  * requires specific CPU arch or specific CPU features.
  */
 public abstract class CPUSpecificCommandLineOptionTest
-              extends CommandLineOptionTest {
-
-    private String cpuArchPattern;
-    private String supportedCPUFeatures[];
-    private String unsupportedCPUFeatures[];
-
+        extends CommandLineOptionTest {
     /**
-     * Create new CPU specific test instance that does not
+     * Creates new CPU specific test instance that does not
      * require any CPU features.
      *
      * @param cpuArchPattern Regular expression that should
@@ -49,62 +43,23 @@
     }
 
     /**
-     * Create new CPU specific test instance that does not
+     * Creates new CPU specific test instance that does not
      * require from CPU support of {@code supportedCPUFeatures} features
      * and no support of {@code unsupportedCPUFeatures}.
      *
      * @param cpuArchPattern Regular expression that should
      *                       match os.arch.
      * @param supportedCPUFeatures Array with names of features that
-     *                             should be supported by CPU. If <b>null</b>,
+     *                             should be supported by CPU. If {@code null},
      *                             then no features have to be supported.
      * @param unsupportedCPUFeatures Array with names of features that
      *                               should not be supported by CPU.
-     *                               If <b>null</b>, then CPU may support any
+     *                               If {@code null}, then CPU may support any
      *                               features.
      */
     public CPUSpecificCommandLineOptionTest(String cpuArchPattern,
-                                            String supportedCPUFeatures[],
-                                            String unsupportedCPUFeatures[]) {
-        this.cpuArchPattern = cpuArchPattern;
-        this.supportedCPUFeatures = supportedCPUFeatures;
-        this.unsupportedCPUFeatures = unsupportedCPUFeatures;
-    }
-
-    /**
-     * Check that CPU on test box has appropriate architecture, support all
-     * required features and does not support all features that should not be
-     * supported.
-     *
-     * @return <b>true</b> if CPU on test box fulfill all requirements.
-     */
-    @Override
-    public boolean checkPreconditions() {
-        if (!Platform.getOsArch().matches(cpuArchPattern)) {
-            System.out.println("CPU arch does not match " + cpuArchPattern);
-            return false;
-        }
-
-        if (supportedCPUFeatures != null) {
-            for (String feature : supportedCPUFeatures) {
-                if (!CPUInfo.hasFeature(feature)) {
-                    System.out.println("CPU does not support " + feature +
-                                       " feature");
-                    return false;
-                }
-            }
-        }
-
-        if (unsupportedCPUFeatures != null) {
-            for (String feature : unsupportedCPUFeatures) {
-                if (CPUInfo.hasFeature(feature)) {
-                    System.out.println("CPU support " + feature + " feature");
-                    return false;
-                }
-            }
-        }
-
-        return true;
+            String supportedCPUFeatures[], String unsupportedCPUFeatures[]) {
+        super(new CPUSpecificPredicate(cpuArchPattern, supportedCPUFeatures,
+                unsupportedCPUFeatures));
     }
 }
-
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java	Tue Apr 15 19:03:51 2014 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java	Thu Apr 17 13:50:26 2014 -0400
@@ -26,6 +26,7 @@
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.function.BooleanSupplier;
 
 import com.oracle.java.testlibrary.*;
 
@@ -33,34 +34,71 @@
  * Base class for command line option tests.
  */
 public abstract class CommandLineOptionTest {
-
-    public static final String UNRECOGNIZED_OPTION_ERROR_FORMAT =
-        "Unrecognized VM option '[+-]?%s'";
-
-    public static final String printFlagsFinalFormat = "%s\\s*:?=\\s*%s";
+    public static final String UNLOCK_DIAGNOSTIC_VM_OPTIONS
+            = "-XX:+UnlockDiagnosticVMOptions";
+    public static final String UNLOCK_EXPERIMENTAL_VM_OPTIONS
+            = "-XX:+UnlockExperimentalVMOptions";
+    protected static final String UNRECOGNIZED_OPTION_ERROR_FORMAT
+            = "Unrecognized VM option '[+-]?%s(=.*)?'";
+    protected static final String EXPERIMENTAL_OPTION_ERROR_FORMAT
+            = "VM option '%s' is experimental and must be enabled via "
+            + "-XX:\\+UnlockExperimentalVMOptions.";
+    protected static final String DIAGNOSTIC_OPTION_ERROR_FORMAT
+            = " VM option '%s' is diagnostic and must be enabled via "
+            + "-XX:\\+UnlockDiagnosticVMOptions.";
+    private static final String PRINT_FLAGS_FINAL_FORMAT = "%s\\s*:?=\\s*%s";
 
     /**
-     * Verify that JVM startup behaviour matches our expectations.
+     * Verifies that JVM startup behaviour matches our expectations.
      *
-     * @param option The option that should be passed to JVM
-     * @param excpectedMessages Array of patterns that should occur
-     *                          in JVM output. If <b>null</b> then
+     * @param option an option that should be passed to JVM
+     * @param expectedMessages an array of patterns that should occur
+     *                          in JVM output. If {@code null} then
      *                          JVM output could be empty.
-     * @param unexpectedMessages Array of patterns that should not
-     *                           occur in JVM output. If <b>null</b> then
-     *                          JVM output could be empty.
+     * @param unexpectedMessages an array of patterns that should not
+     *                           occur in JVM output. If {@code null} then
+     *                           JVM output could be empty.
      * @param exitCode expected exit code.
      * @throws Throwable if verification fails or some other issues occur.
      */
     public static void verifyJVMStartup(String option,
-                                        String expectedMessages[],
-                                        String unexpectedMessages[],
-                                        ExitCode exitCode)
-                                 throws Throwable {
+            String expectedMessages[], String unexpectedMessages[],
+            ExitCode exitCode) throws Throwable {
+        CommandLineOptionTest.verifyJVMStartup(expectedMessages,
+                unexpectedMessages, exitCode, false, option);
+    }
 
-        OutputAnalyzer outputAnalyzer =
-            ProcessTools.executeTestJvm(option, "-version");
+    /**
+     * Verifies that JVM startup behaviour matches our expectations.
+     *
+     * @param expectedMessages an array of patterns that should occur
+     *                         in JVM output. If {@code null} then
+     *                         JVM output could be empty.
+     * @param unexpectedMessages an array of patterns that should not
+     *                           occur in JVM output. If {@code null} then
+     *                           JVM output could be empty.
+     * @param exitCode expected exit code.
+     * @param addTestVMOptions if {@code true} then test VM options will be
+     *                         passed to VM.
+     * @param options options that should be passed to VM in addition to mode
+     *                flag.
+     * @throws Throwable if verification fails or some other issues occur.
+     */
+    public static void verifyJVMStartup(String expectedMessages[],
+            String unexpectedMessages[], ExitCode exitCode,
+            boolean addTestVMOptions, String... options) throws Throwable {
+        List<String> finalOptions = new ArrayList<>();
+        if (addTestVMOptions) {
+            Collections.addAll(finalOptions, Utils.getTestJavaOpts());
+        }
+        Collections.addAll(finalOptions, options);
+        finalOptions.add("-version");
 
+        ProcessBuilder processBuilder
+                = ProcessTools.createJavaProcessBuilder(finalOptions.toArray(
+                new String[finalOptions.size()]));
+        OutputAnalyzer outputAnalyzer
+                = new OutputAnalyzer(processBuilder.start());
         outputAnalyzer.shouldHaveExitValue(exitCode.value);
 
         if (expectedMessages != null) {
@@ -77,97 +115,216 @@
     }
 
     /**
-     * Verify that value of specified JVM option is the same as
+     * Verifies that JVM startup behaviour matches our expectations when type
+     * of newly started VM is the same as the type of current.
+     *
+     * @param expectedMessages an array of patterns that should occur
+     *                         in JVM output. If {@code null} then
+     *                         JVM output could be empty.
+     * @param unexpectedMessages an array of patterns that should not
+     *                           occur in JVM output. If {@code null} then
+     *                           JVM output could be empty.
+     * @param exitCode expected exit code.
+     * @param options options that should be passed to VM in addition to mode
+     *                flag.
+     * @throws Throwable if verification fails or some other issues occur.
+     */
+    public static void verifySameJVMStartup(String expectedMessages[],
+            String unexpectedMessages[], ExitCode exitCode, String... options)
+            throws  Throwable {
+        List<String> finalOptions = new ArrayList<>();
+        finalOptions.add(CommandLineOptionTest.getVMTypeOption());
+        Collections.addAll(finalOptions, options);
+
+        CommandLineOptionTest.verifyJVMStartup(expectedMessages,
+                unexpectedMessages, exitCode, false,
+                finalOptions.toArray(new String[finalOptions.size()]));
+    }
+
+    /**
+     * Verifies that value of specified JVM option is the same as
      * expected value.
      * This method filter out option with {@code optionName}
      * name from test java options.
      *
-     * @param optionName Name of tested option.
-     * @param expectedValue Expected value of tested option.
-     * @param additionalVMOpts Additonal options that should be
+     * @param optionName a name of tested option.
+     * @param expectedValue expected value of tested option.
+     * @param additionalVMOpts additional options that should be
      *                         passed to JVM.
      * @throws Throwable if verification fails or some other issues occur.
      */
     public static void verifyOptionValue(String optionName,
-                                         String expectedValue,
-                                         String... additionalVMOpts)
-                                  throws Throwable {
+            String expectedValue, String... additionalVMOpts) throws Throwable {
         verifyOptionValue(optionName, expectedValue, true, additionalVMOpts);
     }
 
     /**
-     * Verify that value of specified JVM option is the same as
+     * Verifies that value of specified JVM option is the same as
      * expected value.
      * This method filter out option with {@code optionName}
      * name from test java options.
      *
-     * @param optionName Name of tested option.
-     * @param expectedValue Expected value of tested option.
-     * @param addTestVmOptions If <b>true</b>, then test VM options
+     * @param optionName a name of tested option.
+     * @param expectedValue expected value of tested option.
+     * @param addTestVmOptions if {@code true}, then test VM options
      *                         will be used.
-     * @param additionalVMOpts Additonal options that should be
+     * @param additionalVMOpts additional options that should be
      *                         passed to JVM.
-     * @throws Throwable if verification fails or some other issues occur.
+     * @throws Throwable if verification fails or some other issues
+     *                          occur.
      */
     public static void verifyOptionValue(String optionName,
-                                         String expectedValue,
-                                         boolean addTestVmOptions,
-                                         String... additionalVMOpts)
-                                  throws Throwable {
-
-        List<String> vmOpts = new ArrayList<String>();
+            String expectedValue, boolean addTestVmOptions,
+            String... additionalVMOpts) throws Throwable {
+        List<String> vmOpts = new ArrayList<>();
 
         if (addTestVmOptions) {
             Collections.addAll(vmOpts,
                                Utils.getFilteredTestJavaOpts(optionName));
         }
         Collections.addAll(vmOpts, additionalVMOpts);
-        Collections.addAll(vmOpts, new String[] {
-                "-XX:+PrintFlagsFinal",
-                "-version"
-            });
+        Collections.addAll(vmOpts, "-XX:+PrintFlagsFinal", "-version");
 
-        ProcessBuilder processBuilder =
-            ProcessTools.
-            createJavaProcessBuilder(vmOpts.
-                                     toArray(new String[vmOpts.size()]));
+        ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+                vmOpts.toArray(new String[vmOpts.size()]));
 
-        OutputAnalyzer outputAnalyzer =
-            new OutputAnalyzer(processBuilder.start());
+        OutputAnalyzer outputAnalyzer
+                = new OutputAnalyzer(processBuilder.start());
 
         outputAnalyzer.shouldHaveExitValue(0);
-        outputAnalyzer.shouldMatch(String.
-                                   format(printFlagsFinalFormat,
-                                          optionName,
-                                          expectedValue));
+        outputAnalyzer.shouldMatch(String.format(
+                CommandLineOptionTest.PRINT_FLAGS_FINAL_FORMAT,
+                optionName, expectedValue));
+    }
+
+    /**
+     * Verifies that value of specified JVM when type of newly started VM
+     * is the same as the type of current.
+     * This method filter out option with {@code optionName}
+     * name from test java options.
+     * Only mode flag will be passed to VM in addition to
+     * {@code additionalVMOpts}
+     *
+     * @param optionName name of tested option.
+     * @param expectedValue expected value of tested option.
+     * @param additionalVMOpts additional options that should be
+     *                         passed to JVM.
+     * @throws Throwable if verification fails or some other issues occur.
+     */
+    public static void verifyOptionValueForSameVM(String optionName,
+            String expectedValue, String... additionalVMOpts) throws Throwable {
+        List<String> finalOptions = new ArrayList<>();
+        finalOptions.add(CommandLineOptionTest.getVMTypeOption());
+        Collections.addAll(finalOptions, additionalVMOpts);
+
+        CommandLineOptionTest.verifyOptionValue(optionName, expectedValue,
+                false, finalOptions.toArray(new String[finalOptions.size()]));
+    }
+
+    /**
+     * Prepares boolean command line flag with name {@code name} according
+     * to it's {@code value}.
+     *
+     * @param name the name of option to be prepared
+     * @param value the value of option
+     * @return prepared command line flag
+     */
+    public static String prepareBooleanFlag(String name, boolean value) {
+        return String.format("-XX:%c%s", (value ? '+' : '-'), name);
+    }
+
+    /**
+     * Prepares numeric command line flag with name {@code name} by setting
+     * it's value to {@code value}.
+     *
+     * @param name the name of option to be prepared
+     * @param value the value of option
+     * @return prepared command line flag
+     */
+    public static String prepareNumericFlag(String name, Number value) {
+        return String.format("-XX:%s=%s", name, value.toString());
     }
 
+    /**
+     * Returns message that should occur in VM output if option
+     * {@code optionName} if unrecognized.
+     *
+     * @param optionName the name of option for which message should be returned
+     * @return message saying that option {@code optionName} is unrecognized
+     */
+    public static String getUnrecognizedOptionErrorMessage(String optionName) {
+        return String.format(
+                CommandLineOptionTest.UNRECOGNIZED_OPTION_ERROR_FORMAT,
+                optionName);
+    }
+
+    /**
+     * Returns message that should occur in VM output if option
+     * {@code optionName} is experimental and
+     * -XX:+UnlockExperimentalVMOptions was not passed to VM.
+     *
+     * @param optionName the name of option for which message should be returned
+     * @return message saying that option {@code optionName} is experimental
+     */
+    public static String getExperimentalOptionErrorMessage(String optionName) {
+        return String.format(
+                CommandLineOptionTest.EXPERIMENTAL_OPTION_ERROR_FORMAT,
+                optionName);
+    }
 
     /**
-     * Run command line option test.
+     * Returns message that should occur in VM output if option
+     * {@code optionName} is diagnostic and -XX:+UnlockDiagnosticVMOptions
+     * was not passed to VM.
      *
-     * @throws Throwable if test failed.
+     * @param optionName the name of option for which message should be returned
+     * @return message saying that option {@code optionName} is diganostic
+     */
+    public static String getDiagnosticOptionErrorMessage(String optionName) {
+        return String.format(
+                CommandLineOptionTest.DIAGNOSTIC_OPTION_ERROR_FORMAT,
+                optionName);
+    }
+
+    /**
+     * @return option required to start a new VM with the same type as current.
+     * @throws RuntimeException when VM type is unknown.
+     */
+    private static String getVMTypeOption() {
+        if (Platform.isServer()) {
+            return "-server";
+        } else if (Platform.isClient()) {
+            return "-client";
+        } else if (Platform.isMinimal()) {
+            return "-minimal";
+        } else if (Platform.isGraal()) {
+            return "-graal";
+        }
+        throw new RuntimeException("Unknown VM mode.");
+    }
+
+    private final BooleanSupplier predicate;
+
+    /**
+     * Constructs new CommandLineOptionTest that will be executed only if
+     * predicate {@code predicate} return {@code true}.
+     * @param predicate a predicate responsible for test's preconditions check.
+     */
+    public CommandLineOptionTest(BooleanSupplier predicate) {
+        this.predicate = predicate;
+    }
+
+    /**
+     * Runs command line option test.
      */
     public final void test() throws Throwable {
-        if (checkPreconditions()) {
+        if (predicate.getAsBoolean()) {
             runTestCases();
         }
     }
 
     /**
-     * Check that all preconditions for test execution are met.
-     *
-     * @return <b>true</b> if test could be executed.
+     * @throws Throwable if some issue happened during test cases execution.
      */
-    public boolean checkPreconditions() {
-        return true;
-    }
-
-    /**
-     * Run test cases.
-     *
-     * @throws Throwable if test failed.
-     */
-    public abstract void runTestCases() throws Throwable;
+    protected abstract void runTestCases() throws Throwable;
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/AndPredicate.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 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.cli.predicate;
+
+import java.util.function.BooleanSupplier;
+
+public class AndPredicate implements BooleanSupplier {
+    private final BooleanSupplier a;
+    private final BooleanSupplier b;
+
+    public AndPredicate(BooleanSupplier a, BooleanSupplier b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    @Override
+    public boolean getAsBoolean() {
+        return a.getAsBoolean() && b.getAsBoolean();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/CPUSpecificPredicate.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 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.cli.predicate;
+
+import com.oracle.java.testlibrary.Platform;
+import sun.hotspot.cpuinfo.CPUInfo;
+
+import java.util.function.BooleanSupplier;
+
+public class CPUSpecificPredicate implements BooleanSupplier {
+    private final String cpuArchPattern;
+    private final String supportedCPUFeatures[];
+    private final String unsupportedCPUFeatures[];
+
+    public CPUSpecificPredicate(String cpuArchPattern,
+            String supportedCPUFeatures[],
+            String unsupportedCPUFeatures[]) {
+        this.cpuArchPattern = cpuArchPattern;
+        this.supportedCPUFeatures = supportedCPUFeatures;
+        this.unsupportedCPUFeatures = unsupportedCPUFeatures;
+    }
+
+    @Override
+    public boolean getAsBoolean() {
+        if (!Platform.getOsArch().matches(cpuArchPattern)) {
+            System.out.println("CPU arch does not match " + cpuArchPattern);
+            return false;
+        }
+
+        if (supportedCPUFeatures != null) {
+            for (String feature : supportedCPUFeatures) {
+                if (!CPUInfo.hasFeature(feature)) {
+                    System.out.println("CPU does not support " + feature
+                            + " feature");
+                    return false;
+                }
+            }
+        }
+
+        if (unsupportedCPUFeatures != null) {
+            for (String feature : unsupportedCPUFeatures) {
+                if (CPUInfo.hasFeature(feature)) {
+                    System.out.println("CPU support " + feature + " feature");
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/NotPredicate.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, 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.cli.predicate;
+
+import java.util.function.BooleanSupplier;
+
+public class NotPredicate implements BooleanSupplier {
+    private final BooleanSupplier s;
+
+    public NotPredicate(BooleanSupplier s) {
+        this.s = s;
+    }
+
+    @Override
+    public boolean getAsBoolean() {
+        return !s.getAsBoolean();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/OrPredicate.java	Thu Apr 17 13:50:26 2014 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014, 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.cli.predicate;
+
+import java.util.function.BooleanSupplier;
+
+public class OrPredicate implements BooleanSupplier {
+    private final BooleanSupplier a;
+    private final BooleanSupplier b;
+
+    public OrPredicate(BooleanSupplier a, BooleanSupplier b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    @Override
+    public boolean getAsBoolean() {
+        return a.getAsBoolean() || b.getAsBoolean();
+    }
+}