changeset 7862:2d6136f5356d

Merge
author dlong
date Thu, 22 Jan 2015 18:23:54 -0500
parents 94e55273f450 cbd0cbb0deed
children f5861966e52b
files
diffstat 54 files changed, 618 insertions(+), 245 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -1374,6 +1374,7 @@
 }
 
 void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocation_count,
+                                                                Register method_counters,
                                                                 Register Rtmp,
                                                                 Label &profile_continue) {
   assert(ProfileInterpreter, "must be profiling interpreter");
@@ -1386,9 +1387,8 @@
   br_notnull_short(ImethodDataPtr, Assembler::pn, done);
 
   // Test to see if we should create a method data oop
-  AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit);
-  sethi(profile_limit, Rtmp);
-  ld(Rtmp, profile_limit.low10(), Rtmp);
+  Address profile_limit(method_counters, MethodCounters::interpreter_profile_limit_offset());
+  ld(profile_limit, Rtmp);
   cmp(invocation_count, Rtmp);
   // Use long branches because call_VM() code and following code generated by
   // test_backedge_count_for_osr() is large in debug VM.
@@ -2375,6 +2375,7 @@
 
 #ifndef CC_INTERP
 void InterpreterMacroAssembler::test_backedge_count_for_osr( Register backedge_count,
+                                                             Register method_counters,
                                                              Register branch_bcp,
                                                              Register Rtmp ) {
   Label did_not_overflow;
@@ -2382,8 +2383,8 @@
   assert_different_registers(backedge_count, Rtmp, branch_bcp);
   assert(UseOnStackReplacement,"Must UseOnStackReplacement to test_backedge_count_for_osr");
 
-  AddressLiteral limit(&InvocationCounter::InterpreterBackwardBranchLimit);
-  load_contents(limit, Rtmp);
+  Address limit(method_counters, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset()));
+  ld(limit, Rtmp);
   cmp_and_br_short(backedge_count, Rtmp, Assembler::lessUnsigned, Assembler::pt, did_not_overflow);
 
   // When ProfileInterpreter is on, the backedge_count comes from the
@@ -2500,17 +2501,13 @@
 
 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
+                                                        int increment, Address mask_addr,
                                                         Register scratch1, Register scratch2,
                                                         Condition cond, Label *where) {
   ld(counter_addr, scratch1);
   add(scratch1, increment, scratch1);
-  if (is_simm13(mask)) {
-    andcc(scratch1, mask, G0);
-  } else {
-    set(mask, scratch2);
-    andcc(scratch1, scratch2,  G0);
-  }
+  ld(mask_addr, scratch2);
+  andcc(scratch1, scratch2,  G0);
   br(cond, false, Assembler::pn, *where);
   delayed()->st(scratch1, counter_addr);
 }
--- a/src/cpu/sparc/vm/interp_masm_sparc.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -267,7 +267,7 @@
   void increment_invocation_counter( Register Rcounters, Register Rtmp, Register Rtmp2 );
   void increment_backedge_counter( Register Rcounters, Register Rtmp, Register Rtmp2 );
 #ifndef CC_INTERP
-  void test_backedge_count_for_osr( Register backedge_count, Register branch_bcp, Register Rtmp );
+  void test_backedge_count_for_osr(Register backedge_count, Register method_counters, Register branch_bcp, Register Rtmp );
 
 #endif /* CC_INTERP */
   // Object locking
@@ -280,7 +280,7 @@
   void set_method_data_pointer_for_bcp();
   void test_method_data_pointer(Label& zero_continue);
   void verify_method_data_pointer();
-  void test_invocation_counter_for_mdp(Register invocation_count, Register Rtmp, Label &profile_continue);
+  void test_invocation_counter_for_mdp(Register invocation_count, Register method_counters, Register Rtmp, Label &profile_continue);
 
   void set_mdp_data_at(int constant, Register value);
   void increment_mdp_data_at(Address counter, Register bumped_count,
@@ -291,7 +291,7 @@
                              Register bumped_count, Register scratch2,
                              bool decrement = false);
   void increment_mask_and_jump(Address counter_addr,
-                               int increment, int mask,
+                               int increment, Address mask_addr,
                                Register scratch1, Register scratch2,
                                Condition cond, Label *where);
   void set_mdp_flag_at(int flag_constant, Register scratch);
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -282,12 +282,11 @@
 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
   // Note: In tiered we increment either counters in MethodCounters* or in
   // MDO depending if we're profiling or not.
-  const Register Rcounters = G3_scratch;
+  const Register G3_method_counters = G3_scratch;
   Label done;
 
   if (TieredCompilation) {
     const int increment = InvocationCounter::count_increment;
-    const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
     Label no_mdo;
     if (ProfileInterpreter) {
       // If no method data exists, go to profile_continue.
@@ -297,6 +296,7 @@
       Address mdo_invocation_counter(G4_scratch,
                                      in_bytes(MethodData::invocation_counter_offset()) +
                                      in_bytes(InvocationCounter::counter_offset()));
+      Address mask(G4_scratch, in_bytes(MethodData::invoke_mask_offset()));
       __ increment_mask_and_jump(mdo_invocation_counter, increment, mask,
                                  G3_scratch, Lscratch,
                                  Assembler::zero, overflow);
@@ -305,20 +305,21 @@
 
     // Increment counter in MethodCounters*
     __ bind(no_mdo);
-    Address invocation_counter(Rcounters,
+    Address invocation_counter(G3_method_counters,
             in_bytes(MethodCounters::invocation_counter_offset()) +
             in_bytes(InvocationCounter::counter_offset()));
-    __ get_method_counters(Lmethod, Rcounters, done);
+    __ get_method_counters(Lmethod, G3_method_counters, done);
+    Address mask(G3_method_counters, in_bytes(MethodCounters::invoke_mask_offset()));
     __ increment_mask_and_jump(invocation_counter, increment, mask,
                                G4_scratch, Lscratch,
                                Assembler::zero, overflow);
     __ bind(done);
-  } else {
+  } else { // not TieredCompilation
     // Update standard invocation counters
-    __ get_method_counters(Lmethod, Rcounters, done);
-    __ increment_invocation_counter(Rcounters, O0, G4_scratch);
+    __ get_method_counters(Lmethod, G3_method_counters, done);
+    __ increment_invocation_counter(G3_method_counters, O0, G4_scratch);
     if (ProfileInterpreter) {
-      Address interpreter_invocation_counter(Rcounters,
+      Address interpreter_invocation_counter(G3_method_counters,
             in_bytes(MethodCounters::interpreter_invocation_counter_offset()));
       __ ld(interpreter_invocation_counter, G4_scratch);
       __ inc(G4_scratch);
@@ -327,16 +328,16 @@
 
     if (ProfileInterpreter && profile_method != NULL) {
       // Test to see if we should create a method data oop
-      AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit);
-      __ load_contents(profile_limit, G3_scratch);
-      __ cmp_and_br_short(O0, G3_scratch, Assembler::lessUnsigned, Assembler::pn, *profile_method_continue);
+      Address profile_limit(G3_method_counters, in_bytes(MethodCounters::interpreter_profile_limit_offset()));
+      __ ld(profile_limit, G1_scratch);
+      __ cmp_and_br_short(O0, G1_scratch, Assembler::lessUnsigned, Assembler::pn, *profile_method_continue);
 
       // if no method data exists, go to profile_method
       __ test_method_data_pointer(*profile_method);
     }
 
-    AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit);
-    __ load_contents(invocation_limit, G3_scratch);
+    Address invocation_limit(G3_method_counters, in_bytes(MethodCounters::interpreter_invocation_limit_offset()));
+    __ ld(invocation_limit, G3_scratch);
     __ cmp(O0, G3_scratch);
     __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); // Far distance
     __ delayed()->nop();
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -1599,13 +1599,12 @@
     // Bump bytecode pointer by displacement (take the branch)
     __ delayed()->add( O1_disp, Lbcp, Lbcp );     // add to bc addr
 
-    const Register Rcounters = G3_scratch;
-    __ get_method_counters(Lmethod, Rcounters, Lforward);
+    const Register G3_method_counters = G3_scratch;
+    __ get_method_counters(Lmethod, G3_method_counters, Lforward);
 
     if (TieredCompilation) {
       Label Lno_mdo, Loverflow;
       int increment = InvocationCounter::count_increment;
-      int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
       if (ProfileInterpreter) {
         // If no method data exists, go to profile_continue.
         __ ld_ptr(Lmethod, Method::method_data_offset(), G4_scratch);
@@ -1614,6 +1613,7 @@
         // Increment backedge counter in the MDO
         Address mdo_backedge_counter(G4_scratch, in_bytes(MethodData::backedge_counter_offset()) +
                                                  in_bytes(InvocationCounter::counter_offset()));
+        Address mask(G4_scratch, in_bytes(MethodData::backedge_mask_offset()));
         __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, O0,
                                    Assembler::notZero, &Lforward);
         __ ba_short(Loverflow);
@@ -1621,9 +1621,10 @@
 
       // If there's no MDO, increment counter in MethodCounters*
       __ bind(Lno_mdo);
-      Address backedge_counter(Rcounters,
+      Address backedge_counter(G3_method_counters,
               in_bytes(MethodCounters::backedge_counter_offset()) +
               in_bytes(InvocationCounter::counter_offset()));
+      Address mask(G3_method_counters, in_bytes(MethodCounters::backedge_mask_offset()));
       __ increment_mask_and_jump(backedge_counter, increment, mask, G4_scratch, O0,
                                  Assembler::notZero, &Lforward);
       __ bind(Loverflow);
@@ -1663,18 +1664,19 @@
       __ jmp(O2, G0);
       __ delayed()->nop();
 
-    } else {
+    } else { // not TieredCompilation
       // Update Backedge branch separately from invocations
       const Register G4_invoke_ctr = G4;
-      __ increment_backedge_counter(Rcounters, G4_invoke_ctr, G1_scratch);
+      __ increment_backedge_counter(G3_method_counters, G4_invoke_ctr, G1_scratch);
       if (ProfileInterpreter) {
-        __ test_invocation_counter_for_mdp(G4_invoke_ctr, G3_scratch, Lforward);
+        __ test_invocation_counter_for_mdp(G4_invoke_ctr, G3_method_counters, G1_scratch, Lforward);
         if (UseOnStackReplacement) {
-          __ test_backedge_count_for_osr(O2_bumped_count, l_cur_bcp, G3_scratch);
+
+          __ test_backedge_count_for_osr(O2_bumped_count, G3_method_counters, l_cur_bcp, G1_scratch);
         }
       } else {
         if (UseOnStackReplacement) {
-          __ test_backedge_count_for_osr(G4_invoke_ctr, l_cur_bcp, G3_scratch);
+          __ test_backedge_count_for_osr(G4_invoke_ctr, G3_method_counters, l_cur_bcp, G1_scratch);
         }
       }
     }
--- a/src/cpu/x86/vm/interp_masm_x86_32.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -1360,7 +1360,7 @@
 
 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
+                                                        int increment, Address mask,
                                                         Register scratch, bool preloaded,
                                                         Condition cond, Label* where) {
   if (!preloaded) {
--- a/src/cpu/x86/vm/interp_masm_x86_32.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -182,7 +182,7 @@
   void increment_mdp_data_at(Register mdp_in, Register reg, int constant,
                              bool decrement = false);
   void increment_mask_and_jump(Address counter_addr,
-                               int increment, int mask,
+                               int increment, Address mask,
                                Register scratch, bool preloaded,
                                Condition cond, Label* where);
   void set_mdp_flag_at(Register mdp_in, int flag_constant);
--- a/src/cpu/x86/vm/interp_masm_x86_64.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -1426,7 +1426,7 @@
 
 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
+                                                        int increment, Address mask,
                                                         Register scratch, bool preloaded,
                                                         Condition cond, Label* where) {
   if (!preloaded) {
--- a/src/cpu/x86/vm/interp_masm_x86_64.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/x86/vm/interp_masm_x86_64.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -191,7 +191,7 @@
   void increment_mdp_data_at(Register mdp_in, Register reg, int constant,
                              bool decrement = false);
   void increment_mask_and_jump(Address counter_addr,
-                               int increment, int mask,
+                               int increment, Address mask,
                                Register scratch, bool preloaded,
                                Condition cond, Label* where);
   void set_mdp_flag_at(Register mdp_in, int flag_constant);
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -346,7 +346,6 @@
   // depending if we're profiling or not.
   if (TieredCompilation) {
     int increment = InvocationCounter::count_increment;
-    int mask = ((1 << Tier0InvokeNotifyFreqLog)  - 1) << InvocationCounter::count_shift;
     Label no_mdo;
     if (ProfileInterpreter) {
       // Are we profiling?
@@ -356,6 +355,7 @@
       // Increment counter in the MDO
       const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) +
                                                 in_bytes(InvocationCounter::counter_offset()));
+      const Address mask(rax, in_bytes(MethodData::invoke_mask_offset()));
       __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
       __ jmp(done);
     }
@@ -366,11 +366,12 @@
                   InvocationCounter::counter_offset());
 
     __ get_method_counters(rbx, rax, done);
+    const Address mask(rax, in_bytes(MethodCounters::invoke_mask_offset()));
     __ increment_mask_and_jump(invocation_counter, increment, mask,
                                rcx, false, Assembler::zero, overflow);
     __ bind(done);
-  } else {
-    const Address backedge_counter  (rax,
+  } else { // not TieredCompilation
+    const Address backedge_counter(rax,
                   MethodCounters::backedge_counter_offset() +
                   InvocationCounter::counter_offset());
     const Address invocation_counter(rax,
@@ -400,16 +401,16 @@
 
     if (ProfileInterpreter && profile_method != NULL) {
       // Test to see if we should create a method data oop
-      __ cmp32(rcx,
-               ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit));
+      __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+      __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
       __ jcc(Assembler::less, *profile_method_continue);
 
       // if no method data exists, go to profile_method
       __ test_method_data_pointer(rax, *profile_method);
     }
 
-    __ cmp32(rcx,
-             ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
+    __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+    __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_invocation_limit_offset())));
     __ jcc(Assembler::aboveEqual, *overflow);
     __ bind(done);
   }
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -299,7 +299,6 @@
   // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not.
   if (TieredCompilation) {
     int increment = InvocationCounter::count_increment;
-    int mask = ((1 << Tier0InvokeNotifyFreqLog)  - 1) << InvocationCounter::count_shift;
     Label no_mdo;
     if (ProfileInterpreter) {
       // Are we profiling?
@@ -309,6 +308,7 @@
       // Increment counter in the MDO
       const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) +
                                                 in_bytes(InvocationCounter::counter_offset()));
+      const Address mask(rax, in_bytes(MethodData::invoke_mask_offset()));
       __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
       __ jmp(done);
     }
@@ -318,10 +318,11 @@
                   MethodCounters::invocation_counter_offset() +
                   InvocationCounter::counter_offset());
     __ get_method_counters(rbx, rax, done);
+    const Address mask(rax, in_bytes(MethodCounters::invoke_mask_offset()));
     __ increment_mask_and_jump(invocation_counter, increment, mask, rcx,
                                false, Assembler::zero, overflow);
     __ bind(done);
-  } else {
+  } else { // not TieredCompilation
     const Address backedge_counter(rax,
                   MethodCounters::backedge_counter_offset() +
                   InvocationCounter::counter_offset());
@@ -350,14 +351,16 @@
 
     if (ProfileInterpreter && profile_method != NULL) {
       // Test to see if we should create a method data oop
-      __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit));
+      __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+      __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
       __ jcc(Assembler::less, *profile_method_continue);
 
       // if no method data exists, go to profile_method
       __ test_method_data_pointer(rax, *profile_method);
     }
 
-    __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
+    __ movptr(rax, Address(rbx, Method::method_counters_offset()));
+    __ cmp32(rcx, Address(rax, in_bytes(MethodCounters::interpreter_invocation_limit_offset())));
     __ jcc(Assembler::aboveEqual, *overflow);
     __ bind(done);
   }
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -1621,7 +1621,6 @@
     if (TieredCompilation) {
       Label no_mdo;
       int increment = InvocationCounter::count_increment;
-      int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
       if (ProfileInterpreter) {
         // Are we profiling?
         __ movptr(rbx, Address(rcx, in_bytes(Method::method_data_offset())));
@@ -1630,6 +1629,7 @@
         // Increment the MDO backedge counter
         const Address mdo_backedge_counter(rbx, in_bytes(MethodData::backedge_counter_offset()) +
                                                 in_bytes(InvocationCounter::counter_offset()));
+        const Address mask(rbx, in_bytes(MethodData::backedge_mask_offset()));
         __ increment_mask_and_jump(mdo_backedge_counter, increment, mask,
                                    rax, false, Assembler::zero, &backedge_counter_overflow);
         __ jmp(dispatch);
@@ -1637,9 +1637,10 @@
       __ bind(no_mdo);
       // Increment backedge counter in MethodCounters*
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
+      const Address mask(rcx, in_bytes(MethodCounters::backedge_mask_offset()));
       __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask,
                                  rax, false, Assembler::zero, &backedge_counter_overflow);
-    } else {
+    } else { // not TieredCompilation
       // increment counter
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
       __ movl(rax, Address(rcx, be_offset));        // load backedge counter
@@ -1653,8 +1654,7 @@
 
       if (ProfileInterpreter) {
         // Test to see if we should create a method data oop
-        __ cmp32(rax,
-                 ExternalAddress((address) &InvocationCounter::InterpreterProfileLimit));
+        __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
         __ jcc(Assembler::less, dispatch);
 
         // if no method data exists, go to profile method
@@ -1662,8 +1662,7 @@
 
         if (UseOnStackReplacement) {
           // check for overflow against rbx, which is the MDO taken count
-          __ cmp32(rbx,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rbx, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::below, dispatch);
 
           // When ProfileInterpreter is on, the backedge_count comes from the
@@ -1678,8 +1677,7 @@
       } else {
         if (UseOnStackReplacement) {
           // check for overflow against rax, which is the sum of the counters
-          __ cmp32(rax,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::aboveEqual, backedge_counter_overflow);
 
         }
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -1642,7 +1642,6 @@
     if (TieredCompilation) {
       Label no_mdo;
       int increment = InvocationCounter::count_increment;
-      int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
       if (ProfileInterpreter) {
         // Are we profiling?
         __ movptr(rbx, Address(rcx, in_bytes(Method::method_data_offset())));
@@ -1651,6 +1650,7 @@
         // Increment the MDO backedge counter
         const Address mdo_backedge_counter(rbx, in_bytes(MethodData::backedge_counter_offset()) +
                                            in_bytes(InvocationCounter::counter_offset()));
+        const Address mask(rbx, in_bytes(MethodData::backedge_mask_offset()));
         __ increment_mask_and_jump(mdo_backedge_counter, increment, mask,
                                    rax, false, Assembler::zero, &backedge_counter_overflow);
         __ jmp(dispatch);
@@ -1658,9 +1658,10 @@
       __ bind(no_mdo);
       // Increment backedge counter in MethodCounters*
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
+         const Address mask(rcx, in_bytes(MethodCounters::backedge_mask_offset()));
       __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask,
                                  rax, false, Assembler::zero, &backedge_counter_overflow);
-    } else {
+    } else { // not TieredCompilation
       // increment counter
       __ movptr(rcx, Address(rcx, Method::method_counters_offset()));
       __ movl(rax, Address(rcx, be_offset));        // load backedge counter
@@ -1674,8 +1675,7 @@
 
       if (ProfileInterpreter) {
         // Test to see if we should create a method data oop
-        __ cmp32(rax,
-                 ExternalAddress((address) &InvocationCounter::InterpreterProfileLimit));
+        __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_profile_limit_offset())));
         __ jcc(Assembler::less, dispatch);
 
         // if no method data exists, go to profile method
@@ -1683,8 +1683,7 @@
 
         if (UseOnStackReplacement) {
           // check for overflow against ebx which is the MDO taken count
-          __ cmp32(rbx,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rbx, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::below, dispatch);
 
           // When ProfileInterpreter is on, the backedge_count comes
@@ -1702,8 +1701,7 @@
         if (UseOnStackReplacement) {
           // check for overflow against eax, which is the sum of the
           // counters
-          __ cmp32(rax,
-                   ExternalAddress((address) &InvocationCounter::InterpreterBackwardBranchLimit));
+          __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
           __ jcc(Assembler::aboveEqual, backedge_counter_overflow);
 
         }
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -32,6 +32,7 @@
 #include "ci/ciArrayKlass.hpp"
 #include "ci/ciInstance.hpp"
 #include "ci/ciObjArray.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/vm_version.hpp"
@@ -3351,7 +3352,12 @@
   if (!x->inlinee()->is_accessor()) {
     CodeEmitInfo* info = state_for(x, x->state(), true);
     // Notify the runtime very infrequently only to take care of counter overflows
-    increment_event_counter_impl(info, x->inlinee(), (1 << Tier23InlineeNotifyFreqLog) - 1, InvocationEntryBci, false, true);
+    int freq_log = Tier23InlineeNotifyFreqLog;
+    double scale;
+    if (_method->has_option_value("CompileThresholdScaling", scale)) {
+      freq_log = Arguments::scaled_freq_log(freq_log, scale);
+    }
+    increment_event_counter_impl(info, x->inlinee(), right_n_bits(freq_log), InvocationEntryBci, false, true);
   }
 }
 
@@ -3366,7 +3372,11 @@
     ShouldNotReachHere();
   }
   // Increment the appropriate invocation/backedge counter and notify the runtime.
-  increment_event_counter_impl(info, info->scope()->method(), (1 << freq_log) - 1, bci, backedge, true);
+  double scale;
+  if (_method->has_option_value("CompileThresholdScaling", scale)) {
+    freq_log = Arguments::scaled_freq_log(freq_log, scale);
+  }
+  increment_event_counter_impl(info, info->scope()->method(), right_n_bits(freq_log), bci, backedge, true);
 }
 
 void LIRGenerator::decrement_age(CodeEmitInfo* info) {
--- a/src/share/vm/compiler/compileBroker.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/compiler/compileBroker.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -1470,7 +1470,9 @@
 
   // The method may be explicitly excluded by the user.
   bool quietly;
-  if (CompilerOracle::should_exclude(method, quietly)) {
+  double scale;
+  if (CompilerOracle::should_exclude(method, quietly)
+      || (CompilerOracle::has_option_value(method, "CompileThresholdScaling", scale) && scale == 0)) {
     if (!quietly) {
       // This does not happen quietly...
       ResourceMark rm;
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -53,7 +53,7 @@
 /*
  * USELABELS - If using GCC, then use labels for the opcode dispatching
  * rather -then a switch statement. This improves performance because it
- * gives us the oportunity to have the instructions that calculate the
+ * gives us the opportunity to have the instructions that calculate the
  * next opcode to jump to be intermixed with the rest of the instructions
  * that implement the opcode (see UPDATE_PC_AND_TOS_AND_CONTINUE macro).
  */
--- a/src/share/vm/interpreter/invocationCounter.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/interpreter/invocationCounter.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -36,7 +36,7 @@
 // Implementation notes: For space reasons, state & counter are both encoded in one word,
 // The state is encoded using some of the least significant bits, the counter is using the
 // more significant bits. The counter is incremented before a method is activated and an
-// action is triggered when when count() > limit().
+// action is triggered when count() > limit().
 
 class InvocationCounter VALUE_OBJ_CLASS_SPEC {
   friend class VMStructs;
@@ -48,7 +48,6 @@
     number_of_state_bits = 2,
     number_of_carry_bits = 1,
     number_of_noncount_bits = number_of_state_bits + number_of_carry_bits,
-    number_of_count_bits = BitsPerInt - number_of_noncount_bits,
     state_limit          = nth_bit(number_of_state_bits),
     count_grain          = nth_bit(number_of_state_bits + number_of_carry_bits),
     carry_mask           = right_n_bits(number_of_carry_bits) << number_of_state_bits,
@@ -68,6 +67,7 @@
     count_increment      = count_grain,          // use this value to increment the 32bit _counter word
     count_mask_value     = count_mask,           // use this value to mask the backedge counter
     count_shift          = number_of_noncount_bits,
+    number_of_count_bits = BitsPerInt - number_of_noncount_bits,
     count_limit          = nth_bit(number_of_count_bits - 1)
   };
 
--- a/src/share/vm/oops/method.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/oops/method.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -412,15 +412,14 @@
   }
 
   methodHandle mh(m);
-  ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
-  MethodCounters* counters = MethodCounters::allocate(loader_data, THREAD);
+  MethodCounters* counters = MethodCounters::allocate(mh, THREAD);
   if (HAS_PENDING_EXCEPTION) {
     CompileBroker::log_metaspace_failure();
     ClassLoaderDataGraph::set_metaspace_oom(true);
     return NULL;   // return the exception (which is cleared)
   }
   if (!mh->init_method_counters(counters)) {
-    MetadataFactory::free_metadata(loader_data, counters);
+    MetadataFactory::free_metadata(mh->method_holder()->class_loader_data(), counters);
   }
   return mh->method_counters();
 }
--- a/src/share/vm/oops/methodCounters.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/oops/methodCounters.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -23,10 +23,11 @@
  */
 #include "precompiled.hpp"
 #include "oops/methodCounters.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/handles.inline.hpp"
 
-MethodCounters* MethodCounters::allocate(ClassLoaderData* loader_data, TRAPS) {
-  return new(loader_data, size(), false, MetaspaceObj::MethodCountersType, THREAD) MethodCounters();
+MethodCounters* MethodCounters::allocate(methodHandle mh, TRAPS) {
+  ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
+  return new(loader_data, size(), false, MetaspaceObj::MethodCountersType, THREAD) MethodCounters(mh);
 }
 
 void MethodCounters::clear_counters() {
--- a/src/share/vm/oops/methodCounters.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/oops/methodCounters.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -26,7 +26,9 @@
 #define SHARE_VM_OOPS_METHODCOUNTERS_HPP
 
 #include "oops/metadata.hpp"
+#include "compiler/compilerOracle.hpp"
 #include "interpreter/invocationCounter.hpp"
+#include "runtime/arguments.hpp"
 
 class MethodCounters: public MetaspaceObj {
  friend class VMStructs;
@@ -45,7 +47,11 @@
   // 3. (INT_MIN..0]                  - method is hot and will deopt and get
   //                                    recompiled without the counters
   int               _nmethod_age;
-
+  int               _interpreter_invocation_limit;        // per-method InterpreterInvocationLimit
+  int               _interpreter_backward_branch_limit;   // per-method InterpreterBackwardBranchLimit
+  int               _interpreter_profile_limit;           // per-method InterpreterProfileLimit
+  int               _invoke_mask;                         // per-method Tier0InvokeNotifyFreqLog
+  int               _backedge_mask;                       // per-method Tier0BackedgeNotifyFreqLog
 #ifdef TIERED
   float             _rate;                        // Events (invocation and backedge counter increments) per millisecond
   jlong             _prev_time;                   // Previous time the rate was acquired
@@ -53,15 +59,15 @@
   u1                _highest_osr_comp_level;      // Same for OSR level
 #endif
 
-  MethodCounters() : _interpreter_invocation_count(0),
-                     _interpreter_throwout_count(0),
-                     _number_of_breakpoints(0),
-                     _nmethod_age(INT_MAX)
+  MethodCounters(methodHandle mh) : _interpreter_invocation_count(0),
+                                    _interpreter_throwout_count(0),
+                                    _number_of_breakpoints(0),
+                                    _nmethod_age(INT_MAX)
 #ifdef TIERED
-                   , _rate(0),
-                     _prev_time(0),
-                     _highest_comp_level(0),
-                     _highest_osr_comp_level(0)
+                                 , _rate(0),
+                                   _prev_time(0),
+                                   _highest_comp_level(0),
+                                   _highest_osr_comp_level(0)
 #endif
   {
     invocation_counter()->init();
@@ -70,10 +76,28 @@
     if (StressCodeAging) {
       set_nmethod_age(HotMethodDetectionLimit);
     }
+
+    // Set per-method thresholds.
+    double scale = 1.0;
+    CompilerOracle::has_option_value(mh, "CompileThresholdScaling", scale);
+
+    int compile_threshold = Arguments::scaled_compile_threshold(CompileThreshold, scale);
+    _interpreter_invocation_limit = compile_threshold << InvocationCounter::count_shift;
+    if (ProfileInterpreter) {
+      // If interpreter profiling is enabled, the backward branch limit
+      // is compared against the method data counter rather than an invocation
+      // counter, therefore no shifting of bits is required.
+      _interpreter_backward_branch_limit = (compile_threshold * (OnStackReplacePercentage - InterpreterProfilePercentage)) / 100;
+    } else {
+      _interpreter_backward_branch_limit = ((compile_threshold * OnStackReplacePercentage) / 100) << InvocationCounter::count_shift;
+    }
+    _interpreter_profile_limit = ((compile_threshold * InterpreterProfilePercentage) / 100) << InvocationCounter::count_shift;
+    _invoke_mask = right_n_bits(Arguments::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
+    _backedge_mask = right_n_bits(Arguments::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
   }
 
  public:
-  static MethodCounters* allocate(ClassLoaderData* loader_data, TRAPS);
+  static MethodCounters* allocate(methodHandle mh, TRAPS);
 
   void deallocate_contents(ClassLoaderData* loader_data) {}
   DEBUG_ONLY(bool on_stack() { return false; })  // for template
@@ -161,5 +185,24 @@
     return offset_of(MethodCounters, _interpreter_invocation_count);
   }
 
+  static ByteSize interpreter_invocation_limit_offset() {
+    return byte_offset_of(MethodCounters, _interpreter_invocation_limit);
+  }
+
+  static ByteSize interpreter_backward_branch_limit_offset() {
+    return byte_offset_of(MethodCounters, _interpreter_backward_branch_limit);
+  }
+
+  static ByteSize interpreter_profile_limit_offset() {
+    return byte_offset_of(MethodCounters, _interpreter_profile_limit);
+  }
+
+  static ByteSize invoke_mask_offset() {
+    return byte_offset_of(MethodCounters, _invoke_mask);
+  }
+
+  static ByteSize backedge_mask_offset() {
+    return byte_offset_of(MethodCounters, _backedge_mask);
+  }
 };
 #endif //SHARE_VM_OOPS_METHODCOUNTERS_HPP
--- a/src/share/vm/oops/methodData.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/oops/methodData.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -31,6 +31,7 @@
 #include "memory/heapInspection.hpp"
 #include "oops/methodData.hpp"
 #include "prims/jvmtiRedefineClasses.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/deoptimization.hpp"
 #include "runtime/handles.inline.hpp"
@@ -1131,6 +1132,13 @@
   _backedge_counter.init();
   _invocation_counter_start = 0;
   _backedge_counter_start = 0;
+
+  // Set per-method invoke- and backedge mask.
+  double scale = 1.0;
+  CompilerOracle::has_option_value(_method, "CompileThresholdScaling", scale);
+  _invoke_mask = right_n_bits(Arguments::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
+  _backedge_mask = right_n_bits(Arguments::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
+
   _tenure_traps = 0;
   _num_loops = 0;
   _num_blocks = 0;
--- a/src/share/vm/oops/methodData.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/oops/methodData.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -2088,6 +2088,8 @@
   int               _invocation_counter_start;
   int               _backedge_counter_start;
   uint              _tenure_traps;
+  int               _invoke_mask;      // per-method Tier0InvokeNotifyFreqLog
+  int               _backedge_mask;    // per-method Tier0BackedgeNotifyFreqLog
 
 #if INCLUDE_RTM_OPT
   // State of RTM code generation during compilation of the method
@@ -2447,10 +2449,19 @@
   static ByteSize invocation_counter_offset() {
     return byte_offset_of(MethodData, _invocation_counter);
   }
+
   static ByteSize backedge_counter_offset() {
     return byte_offset_of(MethodData, _backedge_counter);
   }
 
+  static ByteSize invoke_mask_offset() {
+    return byte_offset_of(MethodData, _invoke_mask);
+  }
+
+  static ByteSize backedge_mask_offset() {
+    return byte_offset_of(MethodData, _backedge_mask);
+  }
+
   static ByteSize parameters_type_data_di_offset() {
     return byte_offset_of(MethodData, _parameters_type_data_di);
   }
--- a/src/share/vm/opto/chaitin.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/chaitin.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -582,6 +582,9 @@
   // Peephole remove copies
   post_allocate_copy_removal();
 
+  // Merge multidefs if multiple defs representing the same value are used in a single block.
+  merge_multidefs();
+
 #ifdef ASSERT
   // Veify the graph after RA.
   verify(&live_arena);
--- a/src/share/vm/opto/chaitin.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/chaitin.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -681,6 +681,32 @@
   // Extend the node to LRG mapping
   void add_reference( const Node *node, const Node *old_node);
 
+  // Record the first use of a def in the block for a register.
+  class RegDefUse {
+    Node* _def;
+    Node* _first_use;
+  public:
+    RegDefUse() : _def(NULL), _first_use(NULL) { }
+    Node* def() const       { return _def;       }
+    Node* first_use() const { return _first_use; }
+
+    void update(Node* def, Node* use) {
+      if (_def != def) {
+        _def = def;
+        _first_use = use;
+      }
+    }
+    void clear() {
+      _def = NULL;
+      _first_use = NULL;
+    }
+  };
+  typedef GrowableArray<RegDefUse> RegToDefUseMap;
+  int possibly_merge_multidef(Node *n, uint k, Block *block, RegToDefUseMap& reg2defuse);
+
+  // Merge nodes that are a part of a multidef lrg and produce the same value within a block.
+  void merge_multidefs();
+
 private:
 
   static int _final_loads, _final_stores, _final_copies, _final_memoves;
--- a/src/share/vm/opto/doCall.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/doCall.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -94,7 +94,7 @@
   if (log != NULL) {
     int rid = (receiver_count >= 0)? log->identify(profile.receiver(0)): -1;
     int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1;
-    log->begin_elem("call method='%d' count='%d' prof_factor='%g'",
+    log->begin_elem("call method='%d' count='%d' prof_factor='%f'",
                     log->identify(callee), site_count, prof_factor);
     if (call_does_dispatch)  log->print(" virtual='1'");
     if (allow_inline)     log->print(" inline='1'");
--- a/src/share/vm/opto/escape.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/escape.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -2010,14 +2010,9 @@
         bt = field->layout_type();
       } else {
         // Check for unsafe oop field access
-        for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-          int opcode = n->fast_out(i)->Opcode();
-          if (opcode == Op_StoreP || opcode == Op_LoadP ||
-              opcode == Op_StoreN || opcode == Op_LoadN) {
-            bt = T_OBJECT;
-            (*unsafe) = true;
-            break;
-          }
+        if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
+          bt = T_OBJECT;
+          (*unsafe) = true;
         }
       }
     } else if (adr_type->isa_aryptr()) {
@@ -2031,13 +2026,8 @@
       }
     } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
       // Allocation initialization, ThreadLocal field access, unsafe access
-      for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-        int opcode = n->fast_out(i)->Opcode();
-        if (opcode == Op_StoreP || opcode == Op_LoadP ||
-            opcode == Op_StoreN || opcode == Op_LoadN) {
-          bt = T_OBJECT;
-          break;
-        }
+      if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
+        bt = T_OBJECT;
       }
     }
   }
@@ -3092,13 +3082,7 @@
         continue;
     } else if (n->Opcode() == Op_EncodeISOArray) {
       // get the memory projection
-      for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-        Node *use = n->fast_out(i);
-        if (use->Opcode() == Op_SCMemProj) {
-          n = use;
-          break;
-        }
-      }
+      n = n->find_out_with(Op_SCMemProj);
       assert(n->Opcode() == Op_SCMemProj, "memory projection required");
     } else {
       assert(n->is_Mem(), "memory node required.");
@@ -3122,13 +3106,7 @@
         continue;  // don't push users
       } else if (n->is_LoadStore()) {
         // get the memory projection
-        for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-          Node *use = n->fast_out(i);
-          if (use->Opcode() == Op_SCMemProj) {
-            n = use;
-            break;
-          }
-        }
+        n = n->find_out_with(Op_SCMemProj);
         assert(n->Opcode() == Op_SCMemProj, "memory projection required");
       }
     }
--- a/src/share/vm/opto/ifg.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/ifg.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -535,12 +535,8 @@
       // The method add_input_to_liveout() keeps such nodes alive (put them on liveout list)
       // when it sees SCMemProj node in a block. Unfortunately SCMemProj node could be placed
       // in block in such order that KILL MachProj nodes are processed first.
-      uint cnt = def->outcnt();
-      for (uint i = 0; i < cnt; i++) {
-        Node* proj = def->raw_out(i);
-        if (proj->Opcode() == Op_SCMemProj) {
-          return false;
-        }
+      if (def->has_out_with(Op_SCMemProj)) {
+        return false;
       }
     }
     b->remove_node(location);
--- a/src/share/vm/opto/loopTransform.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/loopTransform.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -2057,10 +2057,9 @@
   }
   Node *main_cmp = main_bol->in(1);
   if( main_cmp->outcnt() > 1 ) { // CmpNode shared?
-    _igvn.hash_delete(main_bol);
     main_cmp = main_cmp->clone();// Clone a private CmpNode
     register_new_node( main_cmp, main_cle->in(0) );
-    main_bol->set_req(1,main_cmp);
+    _igvn.replace_input_of(main_bol, 1, main_cmp);
   }
   // Hack the now-private loop bounds
   _igvn.replace_input_of(main_cmp, 2, main_limit);
--- a/src/share/vm/opto/machnode.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/machnode.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -616,6 +616,29 @@
 #endif
 };
 
+// MachMergeNode is similar to a PhiNode in a sense it merges multiple values,
+// however it doesn't have a control input and is more like a MergeMem.
+// It is inserted after the register allocation is done to ensure that nodes use single
+// definition of a multidef lrg in a block.
+class MachMergeNode : public MachIdealNode {
+public:
+  MachMergeNode(Node *n1) {
+    init_class_id(Class_MachMerge);
+    add_req(NULL);
+    add_req(n1);
+  }
+  virtual const RegMask &out_RegMask() const { return in(1)->out_RegMask(); }
+  virtual const RegMask &in_RegMask(uint idx) const { return in(1)->in_RegMask(idx); }
+  virtual const class Type *bottom_type() const { return in(1)->bottom_type(); }
+  virtual uint ideal_reg() const { return bottom_type()->ideal_reg(); }
+  virtual uint oper_input_base() const { return 1; }
+  virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { }
+  virtual uint size(PhaseRegAlloc *ra_) const { return 0; }
+#ifndef PRODUCT
+  virtual const char *Name() const { return "MachMerge"; }
+#endif
+};
+
 //------------------------------MachBranchNode--------------------------------
 // Abstract machine branch Node
 class MachBranchNode : public MachIdealNode {
--- a/src/share/vm/opto/macro.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/macro.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -258,14 +258,7 @@
     // Search for CastP2X->Xor->URShift->Cmp path which
     // checks if the store done to a different from the value's region.
     // And replace Cmp with #0 (false) to collapse G1 post barrier.
-    Node* xorx = NULL;
-    for (DUIterator_Fast imax, i = p2x->fast_outs(imax); i < imax; i++) {
-      Node* u = p2x->fast_out(i);
-      if (u->Opcode() == Op_XorX) {
-        xorx = u;
-        break;
-      }
-    }
+    Node* xorx = p2x->find_out_with(Op_XorX);
     assert(xorx != NULL, "missing G1 post barrier");
     Node* shift = xorx->unique_out();
     Node* cmpx = shift->unique_out();
--- a/src/share/vm/opto/memnode.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/memnode.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -2609,7 +2609,6 @@
     return false; // if not a distinct instance, there may be aliases of the address
   for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) {
     Node *use = adr->fast_out(i);
-    int opc = use->Opcode();
     if (use->is_Load() || use->is_LoadStore()) {
       return false;
     }
--- a/src/share/vm/opto/node.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/node.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -881,6 +881,34 @@
     return (Node*) this;
 }
 
+// Find out of current node that matches opcode.
+Node* Node::find_out_with(int opcode) {
+  for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
+    Node* use = fast_out(i);
+    if (use->Opcode() == opcode) {
+      return use;
+    }
+  }
+  return NULL;
+}
+
+// Return true if the current node has an out that matches opcode.
+bool Node::has_out_with(int opcode) {
+  return (find_out_with(opcode) != NULL);
+}
+
+// Return true if the current node has an out that matches any of the opcodes.
+bool Node::has_out_with(int opcode1, int opcode2, int opcode3, int opcode4) {
+  for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
+      int opcode = fast_out(i)->Opcode();
+      if (opcode == opcode1 || opcode == opcode2 || opcode == opcode3 || opcode == opcode4) {
+        return true;
+      }
+  }
+  return false;
+}
+
+
 //---------------------------uncast_helper-------------------------------------
 Node* Node::uncast_helper(const Node* p) {
 #ifdef ASSERT
--- a/src/share/vm/opto/node.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/node.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -98,6 +98,7 @@
 class MachSafePointNode;
 class MachSpillCopyNode;
 class MachTempNode;
+class MachMergeNode;
 class Matcher;
 class MemBarNode;
 class MemBarStoreStoreNode;
@@ -436,6 +437,13 @@
     return (this->uncast() == n->uncast());
   }
 
+  // Find out of current node that matches opcode.
+  Node* find_out_with(int opcode);
+  // Return true if the current node has an out that matches opcode.
+  bool has_out_with(int opcode);
+  // Return true if the current node has an out that matches any of the opcodes.
+  bool has_out_with(int opcode1, int opcode2, int opcode3, int opcode4);
+
 private:
   static Node* uncast_helper(const Node* n);
 
@@ -507,18 +515,25 @@
 
 //----------------- Other Node Properties
 
-  // Generate class id for some ideal nodes to avoid virtual query
-  // methods is_<Node>().
-  // Class id is the set of bits corresponded to the node class and all its
-  // super classes so that queries for super classes are also valid.
-  // Subclasses of the same super class have different assigned bit
-  // (the third parameter in the macro DEFINE_CLASS_ID).
-  // Classes with deeper hierarchy are declared first.
-  // Classes with the same hierarchy depth are sorted by usage frequency.
+  // Generate class IDs for (some) ideal nodes so that it is possible to determine
+  // the type of a node using a non-virtual method call (the method is_<Node>() below).
   //
-  // The query method masks the bits to cut off bits of subclasses
-  // and then compare the result with the class id
-  // (see the macro DEFINE_CLASS_QUERY below).
+  // A class ID of an ideal node is a set of bits. In a class ID, a single bit determines
+  // the type of the node the ID represents; another subset of an ID's bits are reserved
+  // for the superclasses of the node represented by the ID.
+  //
+  // By design, if A is a supertype of B, A.is_B() returns true and B.is_A()
+  // returns false. A.is_A() returns true.
+  //
+  // If two classes, A and B, have the same superclass, a different bit of A's class id
+  // is reserved for A's type than for B's type. That bit is specified by the third
+  // parameter in the macro DEFINE_CLASS_ID.
+  //
+  // By convention, classes with deeper hierarchy are declared first. Moreover,
+  // classes with the same hierarchy depth are sorted by usage frequency.
+  //
+  // The query method masks the bits to cut off bits of subclasses and then compares
+  // the result with the class id (see the macro DEFINE_CLASS_QUERY below).
   //
   //  Class_MachCall=30, ClassMask_MachCall=31
   // 12               8               4               0
@@ -592,6 +607,7 @@
       DEFINE_CLASS_ID(MachTemp,         Mach, 3)
       DEFINE_CLASS_ID(MachConstantBase, Mach, 4)
       DEFINE_CLASS_ID(MachConstant,     Mach, 5)
+      DEFINE_CLASS_ID(MachMerge,        Mach, 6)
 
     DEFINE_CLASS_ID(Type,  Node, 2)
       DEFINE_CLASS_ID(Phi,   Type, 0)
@@ -763,6 +779,7 @@
   DEFINE_CLASS_QUERY(MachSafePoint)
   DEFINE_CLASS_QUERY(MachSpillCopy)
   DEFINE_CLASS_QUERY(MachTemp)
+  DEFINE_CLASS_QUERY(MachMerge)
   DEFINE_CLASS_QUERY(Mem)
   DEFINE_CLASS_QUERY(MemBar)
   DEFINE_CLASS_QUERY(MemBarStoreStore)
--- a/src/share/vm/opto/parse1.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/parse1.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -441,7 +441,7 @@
 
   CompileLog* log = C->log();
   if (log != NULL) {
-    log->begin_head("parse method='%d' uses='%g'",
+    log->begin_head("parse method='%d' uses='%f'",
                     log->identify(parse_method), expected_uses);
     if (depth() == 1 && C->is_osr_compilation()) {
       log->print(" osr_bci='%d'", C->entry_bci());
--- a/src/share/vm/opto/parse2.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/parse2.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -832,7 +832,7 @@
       sprintf(prob_str_buf, "%g", prob);
       prob_str = prob_str_buf;
     }
-    C->log()->elem("branch target_bci='%d' taken='%d' not_taken='%d' cnt='%g' prob='%s'",
+    C->log()->elem("branch target_bci='%d' taken='%d' not_taken='%d' cnt='%f' prob='%s'",
                    iter().get_dest(), taken, not_taken, cnt, prob_str);
   }
   return prob;
--- a/src/share/vm/opto/phase.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/phase.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -110,6 +110,7 @@
     tty->print_cr ("         Compute Liveness:    %7.3f s", timers[_t_computeLive].seconds());
     tty->print_cr ("         Regalloc Split:      %7.3f s", timers[_t_regAllocSplit].seconds());
     tty->print_cr ("         Postalloc Copy Rem:  %7.3f s", timers[_t_postAllocCopyRemoval].seconds());
+    tty->print_cr ("         Merge multidefs:     %7.3f s", timers[_t_mergeMultidefs].seconds());
     tty->print_cr ("         Fixup Spills:        %7.3f s", timers[_t_fixupSpills].seconds());
     tty->print_cr ("         Compact:             %7.3f s", timers[_t_chaitinCompact].seconds());
     tty->print_cr ("         Coalesce 1:          %7.3f s", timers[_t_chaitinCoalesce1].seconds());
@@ -126,6 +127,7 @@
        timers[_t_computeLive].seconds() +
        timers[_t_regAllocSplit].seconds() +
        timers[_t_postAllocCopyRemoval].seconds() +
+       timers[_t_mergeMultidefs].seconds() +
        timers[_t_fixupSpills].seconds() +
        timers[_t_chaitinCompact].seconds() +
        timers[_t_chaitinCoalesce1].seconds() +
--- a/src/share/vm/opto/phase.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/phase.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -88,6 +88,7 @@
       _t_computeLive,
       _t_regAllocSplit,
       _t_postAllocCopyRemoval,
+      _t_mergeMultidefs,
       _t_fixupSpills,
       _t_chaitinCompact,
       _t_chaitinCoalesce1,
--- a/src/share/vm/opto/postaloc.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/postaloc.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -263,20 +263,6 @@
   // intermediate copies might be illegal, i.e., value is stored down to stack
   // then reloaded BUT survives in a register the whole way.
   Node *val = skip_copies(n->in(k));
-
-  if (val == x && nk_idx != 0 &&
-      regnd[nk_reg] != NULL && regnd[nk_reg] != x &&
-      _lrg_map.live_range_id(x) == _lrg_map.live_range_id(regnd[nk_reg])) {
-    // When rematerialzing nodes and stretching lifetimes, the
-    // allocator will reuse the original def for multidef LRG instead
-    // of the current reaching def because it can't know it's safe to
-    // do so.  After allocation completes if they are in the same LRG
-    // then it should use the current reaching def instead.
-    n->set_req(k, regnd[nk_reg]);
-    blk_adjust += yank_if_dead(val, current_block, &value, &regnd);
-    val = skip_copies(n->in(k));
-  }
-
   if (val == x) return blk_adjust; // No progress?
 
   int n_regs = RegMask::num_registers(val->ideal_reg());
@@ -382,6 +368,94 @@
   return false;
 }
 
+// The algorithms works as follows:
+// We traverse the block top to bottom. possibly_merge_multidef() is invoked for every input edge k
+// of the instruction n. We check to see if the input is a multidef lrg. If it is, we record the fact that we've
+// seen a definition (coming as an input) and add that fact to the reg2defuse array. The array maps registers to their
+// current reaching definitions (we track only multidefs though). With each definition we also associate the first
+// instruction we saw use it. If we encounter the situation when we observe an def (an input) that is a part of the
+// same lrg but is different from the previous seen def we merge the two with a MachMerge node and substitute
+// all the uses that we've seen so far to use the merge. After that we keep replacing the new defs in the same lrg
+// as they get encountered with the merge node and keep adding these defs to the merge inputs.
+void PhaseChaitin::merge_multidefs() {
+  Compile::TracePhase tp("mergeMultidefs", &timers[_t_mergeMultidefs]);
+  ResourceMark rm;
+  // Keep track of the defs seen in registers and collect their uses in the block.
+  RegToDefUseMap reg2defuse(_max_reg, _max_reg, RegDefUse());
+  for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+    Block* block = _cfg.get_block(i);
+    for (uint j = 1; j < block->number_of_nodes(); j++) {
+      Node* n = block->get_node(j);
+      if (n->is_Phi()) continue;
+      for (uint k = 1; k < n->req(); k++) {
+        j += possibly_merge_multidef(n, k, block, reg2defuse);
+      }
+      // Null out the value produced by the instruction itself, since we're only interested in defs
+      // implicitly defined by the uses. We are actually interested in tracking only redefinitions
+      // of the multidef lrgs in the same register. For that matter it's enough to track changes in
+      // the base register only and ignore other effects of multi-register lrgs and fat projections.
+      // It is also ok to ignore defs coming from singledefs. After an implicit overwrite by one of
+      // those our register is guaranteed to be used by another lrg and we won't attempt to merge it.
+      uint lrg = _lrg_map.live_range_id(n);
+      if (lrg > 0 && lrgs(lrg).is_multidef()) {
+        OptoReg::Name reg = lrgs(lrg).reg();
+        reg2defuse.at(reg).clear();
+      }
+    }
+    // Clear reg->def->use tracking for the next block
+    for (int j = 0; j < reg2defuse.length(); j++) {
+      reg2defuse.at(j).clear();
+    }
+  }
+}
+
+int PhaseChaitin::possibly_merge_multidef(Node *n, uint k, Block *block, RegToDefUseMap& reg2defuse) {
+  int blk_adjust = 0;
+
+  uint lrg = _lrg_map.live_range_id(n->in(k));
+  if (lrg > 0 && lrgs(lrg).is_multidef()) {
+    OptoReg::Name reg = lrgs(lrg).reg();
+
+    Node* def = reg2defuse.at(reg).def();
+    if (def != NULL && lrg == _lrg_map.live_range_id(def) && def != n->in(k)) {
+      // Same lrg but different node, we have to merge.
+      MachMergeNode* merge;
+      if (def->is_MachMerge()) { // is it already a merge?
+        merge = def->as_MachMerge();
+      } else {
+        merge = new MachMergeNode(def);
+
+        // Insert the merge node into the block before the first use.
+        uint use_index = block->find_node(reg2defuse.at(reg).first_use());
+        block->insert_node(merge, use_index++);
+
+        // Let the allocator know about the new node, use the same lrg
+        _lrg_map.extend(merge->_idx, lrg);
+        blk_adjust++;
+
+        // Fixup all the uses (there is at least one) that happened between the first
+        // use and before the current one.
+        for (; use_index < block->number_of_nodes(); use_index++) {
+          Node* use = block->get_node(use_index);
+          if (use == n) {
+            break;
+          }
+          use->replace_edge(def, merge);
+        }
+      }
+      if (merge->find_edge(n->in(k)) == -1) {
+        merge->add_req(n->in(k));
+      }
+      n->set_req(k, merge);
+    }
+
+    // update the uses
+    reg2defuse.at(reg).update(n->in(k), n);
+  }
+
+  return blk_adjust;
+}
+
 
 //------------------------------post_allocate_copy_removal---------------------
 // Post-Allocation peephole copy removal.  We do this in 1 pass over the
--- a/src/share/vm/opto/stringopts.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/opto/stringopts.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -1507,10 +1507,12 @@
       }
       case StringConcat::StringMode: {
         const Type* type = kit.gvn().type(arg);
+        Node* count = NULL;
         if (type == TypePtr::NULL_PTR) {
           // replace the argument with the null checked version
           arg = null_string;
           sc->set_argument(argi, arg);
+          count = kit.load_String_length(kit.control(), arg);
         } else if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
           // s = s != null ? s : "null";
           // length = length + (s.count - s.offset);
@@ -1533,10 +1535,13 @@
           // replace the argument with the null checked version
           arg = phi;
           sc->set_argument(argi, arg);
+          count = kit.load_String_length(kit.control(), arg);
+        } else {
+          // A corresponding nullcheck will be connected during IGVN MemNode::Ideal_common_DU_postCCP
+          // kit.control might be a different test, that can be hoisted above the actual nullcheck
+          // in case, that the control input is not null, Ideal_common_DU_postCCP will not look for a nullcheck.
+          count = kit.load_String_length(NULL, arg);
         }
-
-        Node* count = kit.load_String_length(kit.control(), arg);
-
         length = __ AddI(length, count);
         string_sizes->init_req(argi, NULL);
         break;
--- a/src/share/vm/runtime/advancedThresholdPolicy.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -155,7 +155,7 @@
   if (mdo != NULL) {
     int i = mdo->invocation_count_delta();
     int b = mdo->backedge_count_delta();
-    return call_predicate_helper<CompLevel_full_profile>(i, b, 1);
+    return call_predicate_helper<CompLevel_full_profile>(i, b, 1, method);
   }
   return false;
 }
@@ -229,32 +229,32 @@
 // Tier?LoadFeedback is basically a coefficient that determines of
 // how many methods per compiler thread can be in the queue before
 // the threshold values double.
-bool AdvancedThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level) {
+bool AdvancedThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level, Method* method) {
   switch(cur_level) {
   case CompLevel_none:
   case CompLevel_limited_profile: {
     double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
-    return loop_predicate_helper<CompLevel_none>(i, b, k);
+    return loop_predicate_helper<CompLevel_none>(i, b, k, method);
   }
   case CompLevel_full_profile: {
     double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
-    return loop_predicate_helper<CompLevel_full_profile>(i, b, k);
+    return loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
   }
   default:
     return true;
   }
 }
 
-bool AdvancedThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level) {
+bool AdvancedThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Method* method) {
   switch(cur_level) {
   case CompLevel_none:
   case CompLevel_limited_profile: {
     double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
-    return call_predicate_helper<CompLevel_none>(i, b, k);
+    return call_predicate_helper<CompLevel_none>(i, b, k, method);
   }
   case CompLevel_full_profile: {
     double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
-    return call_predicate_helper<CompLevel_full_profile>(i, b, k);
+    return call_predicate_helper<CompLevel_full_profile>(i, b, k, method);
   }
   default:
     return true;
@@ -271,7 +271,7 @@
     int i = method->invocation_count();
     int b = method->backedge_count();
     double k = Tier0ProfilingStartPercentage / 100.0;
-    return call_predicate_helper<CompLevel_none>(i, b, k) || loop_predicate_helper<CompLevel_none>(i, b, k);
+    return call_predicate_helper<CompLevel_none>(i, b, k, method) || loop_predicate_helper<CompLevel_none>(i, b, k, method);
   }
   return false;
 }
@@ -348,7 +348,7 @@
       // If we were at full profile level, would we switch to full opt?
       if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
         next_level = CompLevel_full_optimization;
-      } else if ((this->*p)(i, b, cur_level)) {
+      } else if ((this->*p)(i, b, cur_level, method)) {
         // C1-generated fully profiled code is about 30% slower than the limited profile
         // code that has only invocation and backedge counters. The observation is that
         // if C2 queue is large enough we can spend too much time in the fully profiled code
@@ -374,7 +374,7 @@
           if (mdo->would_profile()) {
             if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
                                      Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
-                                     (this->*p)(i, b, cur_level))) {
+                                     (this->*p)(i, b, cur_level, method))) {
               next_level = CompLevel_full_profile;
             }
           } else {
@@ -390,7 +390,7 @@
           if (mdo->would_profile()) {
             int mdo_i = mdo->invocation_count_delta();
             int mdo_b = mdo->backedge_count_delta();
-            if ((this->*p)(mdo_i, mdo_b, cur_level)) {
+            if ((this->*p)(mdo_i, mdo_b, cur_level, method)) {
               next_level = CompLevel_full_optimization;
             }
           } else {
--- a/src/share/vm/runtime/advancedThresholdPolicy.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/runtime/advancedThresholdPolicy.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -84,7 +84,7 @@
  *   invocation and backedge notifications. Basically every n-th invocation or backedge a mutator thread
  *   makes a call into the runtime.
  *
- * - Tier?CompileThreshold, Tier?BackEdgeThreshold, Tier?MinInvocationThreshold control
+ * - Tier?InvocationThreshold, Tier?CompileThreshold, Tier?BackEdgeThreshold, Tier?MinInvocationThreshold control
  *   compilation thresholds.
  *   Level 2 thresholds are not used and are provided for option-compatibility and potential future use.
  *   Other thresholds work as follows:
@@ -100,7 +100,9 @@
  *   The same predicate is used to control the transition from level 3 to level 4 (C2). It should be
  *   noted though that the thresholds are relative. Moreover i and b for the 0->3 transition come
  *   from Method* and for 3->4 transition they come from MDO (since profiled invocations are
- *   counted separately).
+ *   counted separately). Finally, if a method does not contain anything worth profiling, a transition
+ *   from level 3 to level 4 occurs without considering thresholds (e.g., with fewer invocations than
+ *   what is specified by Tier4InvocationThreshold).
  *
  *   OSR transitions are controlled simply with b > TierXBackEdgeThreshold * s predicates.
  *
@@ -164,9 +166,9 @@
   // Call and loop predicates determine whether a transition to a higher compilation
   // level should be performed (pointers to predicate functions are passed to common().
   // Predicates also take compiler load into account.
-  typedef bool (AdvancedThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level);
-  bool call_predicate(int i, int b, CompLevel cur_level);
-  bool loop_predicate(int i, int b, CompLevel cur_level);
+  typedef bool (AdvancedThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level, Method* method);
+  bool call_predicate(int i, int b, CompLevel cur_level, Method* method);
+  bool loop_predicate(int i, int b, CompLevel cur_level, Method* method);
   // Common transition function. Given a predicate determines if a method should transition to another level.
   CompLevel common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback = false);
   // Transition functions.
--- a/src/share/vm/runtime/arguments.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/runtime/arguments.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -1126,16 +1126,35 @@
 }
 #endif
 
-// Returns threshold scaled with CompileThresholdScaling
-intx Arguments::get_scaled_compile_threshold(intx threshold) {
-  return (intx)(threshold * CompileThresholdScaling);
+intx Arguments::scaled_compile_threshold(intx threshold, double scale) {
+  if (scale == 1.0 || scale < 0.0) {
+    return threshold;
+  } else {
+    return (intx)(threshold * scale);
+  }
 }
 
 // Returns freq_log scaled with CompileThresholdScaling
-intx Arguments::get_scaled_freq_log(intx freq_log) {
-  intx scaled_freq = get_scaled_compile_threshold((intx)1 << freq_log);
-  if (scaled_freq == 0) {
-    return 0;
+intx Arguments::scaled_freq_log(intx freq_log, double scale) {
+  // Check if scaling is necessary or negative value was specified.
+  if (scale == 1.0 || scale < 0.0) {
+    return freq_log;
+  }
+
+  // Check value to avoid calculating log2 of 0.
+  if (scale == 0.0) {
+    return 1;
+  }
+
+  intx scaled_freq = scaled_compile_threshold((intx)1 << freq_log, scale);
+  // Determine the maximum notification frequency value currently supported.
+  // The largest mask value that the interpreter/C1 can handle is
+  // of length InvocationCounter::number_of_count_bits. Mask values are always
+  // one bit shorter then the value of the notification frequency. Set
+  // max_freq_bits accordingly.
+  intx max_freq_bits = InvocationCounter::number_of_count_bits + 1;
+  if (scaled_freq > nth_bit(max_freq_bits)) {
+    return max_freq_bits;
   } else {
     return log2_intptr(scaled_freq);
   }
@@ -1180,31 +1199,36 @@
     Tier3InvokeNotifyFreqLog = 0;
     Tier4InvocationThreshold = 0;
   }
+
+  if (CompileThresholdScaling < 0) {
+    vm_exit_during_initialization("Negative value specified for CompileThresholdScaling", NULL);
+  }
+
   // Scale tiered compilation thresholds
   if (!FLAG_IS_DEFAULT(CompileThresholdScaling)) {
-    FLAG_SET_ERGO(intx, Tier0InvokeNotifyFreqLog, get_scaled_freq_log(Tier0InvokeNotifyFreqLog));
-    FLAG_SET_ERGO(intx, Tier0BackedgeNotifyFreqLog, get_scaled_freq_log(Tier0BackedgeNotifyFreqLog));
-
-    FLAG_SET_ERGO(intx, Tier3InvocationThreshold, get_scaled_compile_threshold(Tier3InvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier3MinInvocationThreshold, get_scaled_compile_threshold(Tier3MinInvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier3CompileThreshold, get_scaled_compile_threshold(Tier3CompileThreshold));
-    FLAG_SET_ERGO(intx, Tier3BackEdgeThreshold, get_scaled_compile_threshold(Tier3BackEdgeThreshold));
+    FLAG_SET_ERGO(intx, Tier0InvokeNotifyFreqLog, scaled_freq_log(Tier0InvokeNotifyFreqLog));
+    FLAG_SET_ERGO(intx, Tier0BackedgeNotifyFreqLog, scaled_freq_log(Tier0BackedgeNotifyFreqLog));
+
+    FLAG_SET_ERGO(intx, Tier3InvocationThreshold, scaled_compile_threshold(Tier3InvocationThreshold));
+    FLAG_SET_ERGO(intx, Tier3MinInvocationThreshold, scaled_compile_threshold(Tier3MinInvocationThreshold));
+    FLAG_SET_ERGO(intx, Tier3CompileThreshold, scaled_compile_threshold(Tier3CompileThreshold));
+    FLAG_SET_ERGO(intx, Tier3BackEdgeThreshold, scaled_compile_threshold(Tier3BackEdgeThreshold));
 
     // Tier2{Invocation,MinInvocation,Compile,Backedge}Threshold should be scaled here
     // once these thresholds become supported.
 
-    FLAG_SET_ERGO(intx, Tier2InvokeNotifyFreqLog, get_scaled_freq_log(Tier2InvokeNotifyFreqLog));
-    FLAG_SET_ERGO(intx, Tier2BackedgeNotifyFreqLog, get_scaled_freq_log(Tier2BackedgeNotifyFreqLog));
-
-    FLAG_SET_ERGO(intx, Tier3InvokeNotifyFreqLog, get_scaled_freq_log(Tier3InvokeNotifyFreqLog));
-    FLAG_SET_ERGO(intx, Tier3BackedgeNotifyFreqLog, get_scaled_freq_log(Tier3BackedgeNotifyFreqLog));
-
-    FLAG_SET_ERGO(intx, Tier23InlineeNotifyFreqLog, get_scaled_freq_log(Tier23InlineeNotifyFreqLog));
-
-    FLAG_SET_ERGO(intx, Tier4InvocationThreshold, get_scaled_compile_threshold(Tier4InvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier4MinInvocationThreshold, get_scaled_compile_threshold(Tier4MinInvocationThreshold));
-    FLAG_SET_ERGO(intx, Tier4CompileThreshold, get_scaled_compile_threshold(Tier4CompileThreshold));
-    FLAG_SET_ERGO(intx, Tier4BackEdgeThreshold, get_scaled_compile_threshold(Tier4BackEdgeThreshold));
+    FLAG_SET_ERGO(intx, Tier2InvokeNotifyFreqLog, scaled_freq_log(Tier2InvokeNotifyFreqLog));
+    FLAG_SET_ERGO(intx, Tier2BackedgeNotifyFreqLog, scaled_freq_log(Tier2BackedgeNotifyFreqLog));
+
+    FLAG_SET_ERGO(intx, Tier3InvokeNotifyFreqLog, scaled_freq_log(Tier3InvokeNotifyFreqLog));
+    FLAG_SET_ERGO(intx, Tier3BackedgeNotifyFreqLog, scaled_freq_log(Tier3BackedgeNotifyFreqLog));
+
+    FLAG_SET_ERGO(intx, Tier23InlineeNotifyFreqLog, scaled_freq_log(Tier23InlineeNotifyFreqLog));
+
+    FLAG_SET_ERGO(intx, Tier4InvocationThreshold, scaled_compile_threshold(Tier4InvocationThreshold));
+    FLAG_SET_ERGO(intx, Tier4MinInvocationThreshold, scaled_compile_threshold(Tier4MinInvocationThreshold));
+    FLAG_SET_ERGO(intx, Tier4CompileThreshold, scaled_compile_threshold(Tier4CompileThreshold));
+    FLAG_SET_ERGO(intx, Tier4BackEdgeThreshold, scaled_compile_threshold(Tier4BackEdgeThreshold));
   }
 }
 
@@ -3456,7 +3480,7 @@
   }
 
   if ((TieredCompilation && CompileThresholdScaling == 0)
-      || (!TieredCompilation && get_scaled_compile_threshold(CompileThreshold) == 0)) {
+      || (!TieredCompilation && scaled_compile_threshold(CompileThreshold) == 0)) {
     set_mode_flags(_int);
   }
 
@@ -3896,7 +3920,7 @@
     }
     // Scale CompileThreshold
     if (!FLAG_IS_DEFAULT(CompileThresholdScaling)) {
-      FLAG_SET_ERGO(intx, CompileThreshold, get_scaled_compile_threshold(CompileThreshold));
+      FLAG_SET_ERGO(intx, CompileThreshold, scaled_compile_threshold(CompileThreshold));
     }
   }
 
--- a/src/share/vm/runtime/arguments.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/runtime/arguments.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -328,9 +328,6 @@
   static bool _ClipInlining;
   static bool _CIDynamicCompilePriority;
 
-  // Scale compile thresholds
-  static intx get_scaled_compile_threshold(intx threshold);
-  static intx get_scaled_freq_log(intx freq_log);
   // Tiered
   static void set_tiered_flags();
   static int  get_min_number_of_compiler_threads();
@@ -452,6 +449,18 @@
   static char*  SharedArchivePath;
 
  public:
+  // Scale compile thresholds
+  // Returns threshold scaled with CompileThresholdScaling
+  static intx scaled_compile_threshold(intx threshold, double scale);
+  static intx scaled_compile_threshold(intx threshold) {
+    return scaled_compile_threshold(threshold, CompileThresholdScaling);
+  }
+  // Returns freq_log scaled with CompileThresholdScaling
+  static intx scaled_freq_log(intx freq_log, double scale);
+  static intx scaled_freq_log(intx freq_log) {
+    return scaled_freq_log(freq_log, CompileThresholdScaling);
+  }
+
   // Parses the arguments, first phase
   static jint parse(const JavaVMInitArgs* args);
   // Apply ergonomics
--- a/src/share/vm/runtime/globals.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/runtime/globals.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -2477,7 +2477,7 @@
           "Number of compiler threads to run")                              \
                                                                             \
   product(intx, CompilationPolicyChoice, 0,                                 \
-          "which compilation policy (0/1)")                                 \
+          "which compilation policy (0-3)")                                 \
                                                                             \
   develop(bool, UseStackBanging, true,                                      \
           "use stack banging for stack overflow checks (required for "      \
@@ -3528,7 +3528,16 @@
                                                                             \
   product(double, CompileThresholdScaling, 1.0,                             \
           "Factor to control when first compilation happens "               \
-          "(both with and without tiered compilation)")                     \
+          "(both with and without tiered compilation): "                    \
+          "values greater than 1.0 delay counter overflow, "                \
+          "values between 0 and 1.0 rush counter overflow, "                \
+          "value of 1.0 leave compilation thresholds unchanged "            \
+          "value of 0.0 is equivalent to -Xint. "                           \
+          ""                                                                \
+          "Flag can be set as per-method option. "                          \
+          "If a value is specified for a method, compilation thresholds "   \
+          "for that method are scaled by both the value of the global flag "\
+          "and the value of the per-method flag.")                          \
                                                                             \
   product(intx, Tier0InvokeNotifyFreqLog, 7,                                \
           "Interpreter (tier 0) invocation notification frequency")         \
--- a/src/share/vm/runtime/simpleThresholdPolicy.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/runtime/simpleThresholdPolicy.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -257,28 +257,28 @@
 // Call and loop predicates determine whether a transition to a higher
 // compilation level should be performed (pointers to predicate functions
 // are passed to common() transition function).
-bool SimpleThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level) {
+bool SimpleThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level, Method* method) {
   switch(cur_level) {
   case CompLevel_none:
   case CompLevel_limited_profile: {
-    return loop_predicate_helper<CompLevel_none>(i, b, 1.0);
+    return loop_predicate_helper<CompLevel_none>(i, b, 1.0, method);
   }
   case CompLevel_full_profile: {
-    return loop_predicate_helper<CompLevel_full_profile>(i, b, 1.0);
+    return loop_predicate_helper<CompLevel_full_profile>(i, b, 1.0, method);
   }
   default:
     return true;
   }
 }
 
-bool SimpleThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level) {
+bool SimpleThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Method* method) {
   switch(cur_level) {
   case CompLevel_none:
   case CompLevel_limited_profile: {
-    return call_predicate_helper<CompLevel_none>(i, b, 1.0);
+    return call_predicate_helper<CompLevel_none>(i, b, 1.0, method);
   }
   case CompLevel_full_profile: {
-    return call_predicate_helper<CompLevel_full_profile>(i, b, 1.0);
+    return call_predicate_helper<CompLevel_full_profile>(i, b, 1.0, method);
   }
   default:
     return true;
@@ -293,8 +293,8 @@
     int i = mdo->invocation_count();
     int b = mdo->backedge_count();
     double k = ProfileMaturityPercentage / 100.0;
-    return call_predicate_helper<CompLevel_full_profile>(i, b, k) ||
-           loop_predicate_helper<CompLevel_full_profile>(i, b, k);
+    return call_predicate_helper<CompLevel_full_profile>(i, b, k, method) ||
+           loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
   }
   return false;
 }
@@ -313,7 +313,7 @@
       // If we were at full profile level, would we switch to full opt?
       if (common(p, method, CompLevel_full_profile) == CompLevel_full_optimization) {
         next_level = CompLevel_full_optimization;
-      } else if ((this->*p)(i, b, cur_level)) {
+      } else if ((this->*p)(i, b, cur_level, method)) {
         next_level = CompLevel_full_profile;
       }
       break;
@@ -325,7 +325,7 @@
           if (mdo->would_profile()) {
             int mdo_i = mdo->invocation_count_delta();
             int mdo_b = mdo->backedge_count_delta();
-            if ((this->*p)(mdo_i, mdo_b, cur_level)) {
+            if ((this->*p)(mdo_i, mdo_b, cur_level, method)) {
               next_level = CompLevel_full_optimization;
             }
           } else {
--- a/src/share/vm/runtime/simpleThresholdPolicy.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/runtime/simpleThresholdPolicy.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -43,9 +43,9 @@
   // Call and loop predicates determine whether a transition to a higher compilation
   // level should be performed (pointers to predicate functions are passed to common_TF().
   // Predicates also take compiler load into account.
-  typedef bool (SimpleThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level);
-  bool call_predicate(int i, int b, CompLevel cur_level);
-  bool loop_predicate(int i, int b, CompLevel cur_level);
+  typedef bool (SimpleThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level, Method* method);
+  bool call_predicate(int i, int b, CompLevel cur_level, Method* method);
+  bool loop_predicate(int i, int b, CompLevel cur_level, Method* method);
   // Common transition function. Given a predicate determines if a method should transition to another level.
   CompLevel common(Predicate p, Method* method, CompLevel cur_level);
   // Transition functions.
@@ -76,8 +76,8 @@
 
   // Predicate helpers are used by .*_predicate() methods as well as others.
   // They check the given counter values, multiplied by the scale against the thresholds.
-  template<CompLevel level> static inline bool call_predicate_helper(int i, int b, double scale);
-  template<CompLevel level> static inline bool loop_predicate_helper(int i, int b, double scale);
+  template<CompLevel level> static inline bool call_predicate_helper(int i, int b, double scale, Method* method);
+  template<CompLevel level> static inline bool loop_predicate_helper(int i, int b, double scale, Method* method);
 
   // Get a compilation level for a given method.
   static CompLevel comp_level(Method* method) {
--- a/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -25,8 +25,14 @@
 #ifndef SHARE_VM_RUNTIME_SIMPLETHRESHOLDPOLICY_INLINE_HPP
 #define SHARE_VM_RUNTIME_SIMPLETHRESHOLDPOLICY_INLINE_HPP
 
+#include "compiler/compilerOracle.hpp"
+
 template<CompLevel level>
-bool SimpleThresholdPolicy::call_predicate_helper(int i, int b, double scale) {
+bool SimpleThresholdPolicy::call_predicate_helper(int i, int b, double scale, Method* method) {
+  double threshold_scaling;
+  if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
+    scale *= threshold_scaling;
+  }
   switch(level) {
   case CompLevel_none:
   case CompLevel_limited_profile:
@@ -40,7 +46,11 @@
 }
 
 template<CompLevel level>
-bool SimpleThresholdPolicy::loop_predicate_helper(int i, int b, double scale) {
+bool SimpleThresholdPolicy::loop_predicate_helper(int i, int b, double scale, Method* method) {
+  double threshold_scaling;
+  if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
+    scale *= threshold_scaling;
+  }
   switch(level) {
   case CompLevel_none:
   case CompLevel_limited_profile:
--- a/src/share/vm/runtime/vmStructs.cpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/runtime/vmStructs.cpp	Thu Jan 22 18:23:54 2015 -0500
@@ -351,11 +351,18 @@
   nonstatic_field(MethodData,           _arg_stack,                                    intx)                                  \
   nonstatic_field(MethodData,           _arg_returned,                                 intx)                                  \
   nonstatic_field(MethodData,           _tenure_traps,                                 uint)                                  \
+  nonstatic_field(MethodData,           _invoke_mask,                                  int)                                   \
+  nonstatic_field(MethodData,           _backedge_mask,                                int)                                   \
   nonstatic_field(DataLayout,           _header._struct._tag,                          u1)                                    \
   nonstatic_field(DataLayout,           _header._struct._flags,                        u1)                                    \
   nonstatic_field(DataLayout,           _header._struct._bci,                          u2)                                    \
   nonstatic_field(DataLayout,           _cells[0],                                     intptr_t)                              \
   nonstatic_field(MethodCounters,       _nmethod_age,                                  int)                                   \
+  nonstatic_field(MethodCounters,       _interpreter_invocation_limit,                 int)                                   \
+  nonstatic_field(MethodCounters,       _interpreter_backward_branch_limit,            int)                                   \
+  nonstatic_field(MethodCounters,       _interpreter_profile_limit,                    int)                                   \
+  nonstatic_field(MethodCounters,       _invoke_mask,                                  int)                                   \
+  nonstatic_field(MethodCounters,       _backedge_mask,                                int)                                   \
   nonstatic_field(MethodCounters,       _interpreter_invocation_count,                 int)                                   \
   nonstatic_field(MethodCounters,       _interpreter_throwout_count,                   u2)                                    \
   nonstatic_field(MethodCounters,       _number_of_breakpoints,                        u2)                                    \
--- a/src/share/vm/utilities/globalDefinitions.hpp	Thu Jan 22 12:26:26 2015 +0100
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Thu Jan 22 18:23:54 2015 -0500
@@ -1142,17 +1142,18 @@
   return ((x != NoLongBits) && (mask_long_bits(x, x - 1) == NoLongBits));
 }
 
-//* largest i such that 2^i <= x
-//  A negative value of 'x' will return '31'
+// Returns largest i such that 2^i <= x.
+// If x < 0, the function returns 31 on a 32-bit machine and 63 on a 64-bit machine.
+// If x == 0, the function returns -1.
 inline int log2_intptr(intptr_t x) {
   int i = -1;
-  uintptr_t p =  1;
+  uintptr_t p = 1;
   while (p != 0 && p <= (uintptr_t)x) {
     // p = 2^(i+1) && p <= x (i.e., 2^(i+1) <= x)
     i++; p *= 2;
   }
   // p = 2^(i+1) && x < p (i.e., 2^i <= x < 2^(i+1))
-  // (if p = 0 then overflow occurred and i = 31)
+  // If p = 0, overflow has occurred and i = 31 or i = 63 (depending on the machine word size).
   return i;
 }
 
--- a/test/compiler/arguments/CheckCompileThresholdScaling.java	Thu Jan 22 12:26:26 2015 +0100
+++ b/test/compiler/arguments/CheckCompileThresholdScaling.java	Thu Jan 22 18:23:54 2015 -0500
@@ -54,7 +54,7 @@
     //
     // Tier0InvokeNotifyFreqLog, Tier0BackedgeNotifyFreqLog,
     // Tier3InvocationThreshold, Tier3MinInvocationThreshold,
-    // Tier3CompileThreshold, and Tier3BackEdgeThreshold,
+    // Tier3CompileThreshold, Tier3BackEdgeThreshold,
     // Tier2InvokeNotifyFreqLog, Tier2BackedgeNotifyFreqLog,
     // Tier3InvokeNotifyFreqLog, Tier3BackedgeNotifyFreqLog,
     // Tier23InlineeNotifyFreqLog, Tier4InvocationThreshold,
--- a/test/compiler/codecache/jmx/PoolsIndependenceTest.java	Thu Jan 22 12:26:26 2015 +0100
+++ b/test/compiler/codecache/jmx/PoolsIndependenceTest.java	Thu Jan 22 18:23:54 2015 -0500
@@ -98,11 +98,13 @@
             return false;
         });
         for (BlobType bt : BlobType.getAvailable()) {
-            int expectedNotificationsAmount = bt.equals(btype) ? 1 : 0;
-            Asserts.assertEQ(counters.get(bt.getMemoryPool().getName()).get(),
-                    expectedNotificationsAmount, String.format("Unexpected "
-                            + "amount of notifications for pool: %s",
-                            bt.getMemoryPool().getName()));
+            if (CodeCacheUtils.isCodeHeapPredictable(bt)) {
+                int expectedNotificationsAmount = bt.equals(btype) ? 1 : 0;
+                Asserts.assertEQ(counters.get(bt.getMemoryPool().getName()).get(),
+                        expectedNotificationsAmount, String.format("Unexpected "
+                                + "amount of notifications for pool: %s",
+                                bt.getMemoryPool().getName()));
+            }
         }
         try {
             ((NotificationEmitter) ManagementFactory.getMemoryMXBean()).
--- a/test/compiler/codecache/jmx/ThresholdNotificationsTest.java	Thu Jan 22 12:26:26 2015 +0100
+++ b/test/compiler/codecache/jmx/ThresholdNotificationsTest.java	Thu Jan 22 18:23:54 2015 -0500
@@ -52,7 +52,9 @@
 
     public static void main(String[] args) {
         for (BlobType bt : BlobType.getAvailable()) {
-            new ThresholdNotificationsTest(bt).runTest();
+            if (CodeCacheUtils.isCodeHeapPredictable(bt)) {
+                new ThresholdNotificationsTest(bt).runTest();
+            }
         }
     }
 
--- a/test/compiler/loopopts/7052494/Test7052494.java	Thu Jan 22 12:26:26 2015 +0100
+++ b/test/compiler/loopopts/7052494/Test7052494.java	Thu Jan 22 18:23:54 2015 -0500
@@ -25,7 +25,6 @@
 /**
  * @test
  * @bug 7052494
- * @ignore 7154567
  * @summary Eclipse test fails on JDK 7 b142
  *
  * @run main/othervm -Xbatch Test7052494
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/stringopts/TestOptimizeStringConcat.java	Thu Jan 22 18:23:54 2015 -0500
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2015 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 8068909
+ * @key regression
+ * @summary test that string optimizations produce code, that doesn't lead to a crash.
+ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestOptimizeStringConcat
+ * @author axel.siebenborn@sap.com
+ */
+public class TestOptimizeStringConcat {
+
+    static boolean checkArgumentSyntax(String value, String allowedchars, String notallowedchars, String logmsg) {
+        String rc = null;
+
+        int maxchar = 99999;
+        int minchar = 1;
+        if ((allowedchars != null && notallowedchars != null) || minchar > maxchar) {
+            rc = "internal error";
+        } else {
+            if (value == null) {
+                rc = "the value null is not allowed, it is missing";
+            } else if (value != null && minchar > 0 && value.trim().equals("")) {
+                rc = "the value must not be empty";
+            } else if (value != null) {
+                if (value.length() < minchar || value.length() > maxchar) {
+                    if (rc == null) {
+                        rc = "the value length must be between +minchar+ and +maxchar";
+                    }
+                }
+                char[] _value = value.toCharArray();
+                boolean dotfound = false;
+                int i = 1;
+                if (_value[i] == '.' && !dotfound) {
+                    dotfound = true;
+                } else if (allowedchars != null && allowedchars.indexOf(_value[i]) == -1) {
+                    if (rc == null) {
+                        rc = "the value contains an illegal character: '" + _value[i] + "', only following characters are allowed: '+allowedchars+'";
+                    } else {
+                        rc += " / the value contains an illegal character: '" + _value[i] + "', only following characters are allowed: '+allowedchars+'";
+                    }
+                } else if (notallowedchars != null && notallowedchars.indexOf(_value[i]) != -1) {
+                    if (rc == null) {
+                        rc = "the value contains an illegal character: '" + _value[i] + "', following characters are not allowed '+notallowedchars+'";
+                    } else {
+                        rc += " / the value contains an illegal character: '" + _value[i] + "', following characters are not allowed '+notallowedchars+'";
+                    }
+                }
+            }
+        }
+
+        if (rc != null) {
+            System.out.println(logmsg + " ==> " + rc);
+            return false;
+        }
+        return true;
+    }
+
+    public static void main(String[] args) {
+        boolean failed = false;
+        for (int i = 0; i < 10000; i++) {
+            failed |= !checkArgumentSyntax("theName", null, "\"<&", "Error consistencyCheck: name in component definition");
+            failed |= !checkArgumentSyntax(null, null, "\"<&", "Error consistencyCheck: name in component definition");
+            failed |= !checkArgumentSyntax("42", "0123456789.", null, "Error consistencyCheck: counter in component definition");
+        }
+        System.out.println(failed);
+    }
+}
--- a/test/serviceability/dcmd/compiler/CompilerQueueTest.java	Thu Jan 22 12:26:26 2015 +0100
+++ b/test/serviceability/dcmd/compiler/CompilerQueueTest.java	Thu Jan 22 18:23:54 2015 -0500
@@ -25,6 +25,7 @@
  * @test CompilerQueueTest
  * @bug 8054889
  * @library ..
+ * @ignore 8069160
  * @build DcmdUtil CompilerQueueTest
  * @run main CompilerQueueTest
  * @run main/othervm -XX:-TieredCompilation CompilerQueueTest