diff --git a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp index 7d9aecb310f..f1087dbc02c 100644 --- a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2013 SAP AG. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 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 @@ -284,19 +284,20 @@ class Assembler : public AbstractAssembler { MTCTR_OPCODE = (MTSPR_OPCODE | 9 << SPR_0_4_SHIFT), MFCTR_OPCODE = (MFSPR_OPCODE | 9 << SPR_0_4_SHIFT), - MTTFHAR_OPCODE = (MTSPR_OPCODE | 128 << SPR_0_4_SHIFT), - MFTFHAR_OPCODE = (MFSPR_OPCODE | 128 << SPR_0_4_SHIFT), - MTTFIAR_OPCODE = (MTSPR_OPCODE | 129 << SPR_0_4_SHIFT), - MFTFIAR_OPCODE = (MFSPR_OPCODE | 129 << SPR_0_4_SHIFT), - MTTEXASR_OPCODE = (MTSPR_OPCODE | 130 << SPR_0_4_SHIFT), - MFTEXASR_OPCODE = (MFSPR_OPCODE | 130 << SPR_0_4_SHIFT), - MTTEXASRU_OPCODE = (MTSPR_OPCODE | 131 << SPR_0_4_SHIFT), - MFTEXASRU_OPCODE = (MFSPR_OPCODE | 131 << SPR_0_4_SHIFT), + // Attention: Higher and lower half are inserted in reversed order. + MTTFHAR_OPCODE = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT), + MFTFHAR_OPCODE = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT), + MTTFIAR_OPCODE = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 1 << SPR_0_4_SHIFT), + MFTFIAR_OPCODE = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 1 << SPR_0_4_SHIFT), + MTTEXASR_OPCODE = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 2 << SPR_0_4_SHIFT), + MFTEXASR_OPCODE = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 2 << SPR_0_4_SHIFT), + MTTEXASRU_OPCODE = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 3 << SPR_0_4_SHIFT), + MFTEXASRU_OPCODE = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 3 << SPR_0_4_SHIFT), - MTVRSAVE_OPCODE = (MTSPR_OPCODE | 256 << SPR_0_4_SHIFT), - MFVRSAVE_OPCODE = (MFSPR_OPCODE | 256 << SPR_0_4_SHIFT), + MTVRSAVE_OPCODE = (MTSPR_OPCODE | 8 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT), + MFVRSAVE_OPCODE = (MFSPR_OPCODE | 8 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT), - MFTB_OPCODE = (MFSPR_OPCODE | 268 << SPR_0_4_SHIFT), + MFTB_OPCODE = (MFSPR_OPCODE | 8 << SPR_5_9_SHIFT | 12 << SPR_0_4_SHIFT), MTCRF_OPCODE = (31u << OPCODE_SHIFT | 144u << 1), MFCR_OPCODE = (31u << OPCODE_SHIFT | 19u << 1), @@ -1494,6 +1495,26 @@ class Assembler : public AbstractAssembler { inline void mftexasr(Register d); inline void mftexasru(Register d); + // TEXASR bit description + enum transaction_failure_reason { + // Upper half (TEXASRU): + tm_failure_persistent = 7, // The failure is likely to recur on each execution. + tm_disallowed = 8, // The instruction is not permitted. + tm_nesting_of = 9, // The maximum transaction level was exceeded. + tm_footprint_of = 10, // The tracking limit for transactional storage accesses was exceeded. + tm_self_induced_cf = 11, // A self-induced conflict occurred in Suspended state. + tm_non_trans_cf = 12, // A conflict occurred with a non-transactional access by another processor. + tm_trans_cf = 13, // A conflict occurred with another transaction. + tm_translation_cf = 14, // A conflict occurred with a TLB invalidation. + tm_inst_fetch_cf = 16, // An instruction fetch was performed from a block that was previously written transactionally. + tm_tabort = 31, // Termination was caused by the execution of an abort instruction. + // Lower half: + tm_suspended = 32, // Failure was recorded in Suspended state. + tm_failure_summary = 36, // Failure has been detected and recorded. + tm_tfiar_exact = 37, // Value in the TFIAR is exact. + tm_rot = 38, // Rollback-only transaction. + }; + // PPC 1, section 2.4.1 Branch Instructions inline void b( address a, relocInfo::relocType rt = relocInfo::none); inline void b( Label& L); @@ -1581,6 +1602,7 @@ class Assembler : public AbstractAssembler { inline void bnectrl(ConditionRegister crx, relocInfo::relocType rt = relocInfo::none); // condition register logic instructions + // NOTE: There's a preferred form: d and s2 should point into the same condition register. inline void crand( int d, int s1, int s2); inline void crnand(int d, int s1, int s2); inline void cror( int d, int s1, int s2); @@ -1590,6 +1612,19 @@ class Assembler : public AbstractAssembler { inline void crandc(int d, int s1, int s2); inline void crorc( int d, int s1, int s2); + // More convenient version. + int condition_register_bit(ConditionRegister cr, Condition c) { + return 4 * (int)(intptr_t)cr + c; + } + void crand( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc); + void crnand(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc); + void cror( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc); + void crxor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc); + void crnor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc); + void creqv( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc); + void crandc(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc); + void crorc( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc); + // icache and dcache related instructions inline void icbi( Register s1, Register s2); //inline void dcba(Register s1, Register s2); // Instruction for embedded processor only. @@ -1673,6 +1708,10 @@ class Assembler : public AbstractAssembler { inline void smt_prio_low(); inline void smt_prio_medium_low(); inline void smt_prio_medium(); + // >= Power7 + inline void smt_yield(); + inline void smt_mdoio(); + inline void smt_mdoom(); // trap instructions inline void twi_0(Register a); // for load with acquire semantics use load+twi_0+isync (trap can't occur) @@ -1958,6 +1997,7 @@ class Assembler : public AbstractAssembler { inline void tbeginrot_(); // R=1 Rollback-Only Transaction inline void tend_(); // A=0 inline void tendall_(); // A=1 + inline void tabort_(); inline void tabort_(Register a); inline void tabortwc_(int t, Register a, Register b); inline void tabortwci_(int t, Register a, int si); @@ -1967,6 +2007,10 @@ class Assembler : public AbstractAssembler { inline void tresume_(); // tsr with L=1 inline void tcheck(int f); + static bool is_tbegin(int x) { + return TBEGIN_OPCODE == (x & (0x3f << OPCODE_SHIFT | 0x3ff << 1)); + } + // The following encoders use r0 as second operand. These instructions // read r0 as '0'. inline void lwzx( Register d, Register s2); diff --git a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp index b4a7370994d..5493f124371 100644 --- a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2014 SAP AG. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 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 @@ -453,6 +453,48 @@ inline void Assembler::creqv( int d, int s1, int s2) { emit_int32(CREQV_OPCODE inline void Assembler::crandc(int d, int s1, int s2) { emit_int32(CRANDC_OPCODE | bt(d) | ba(s1) | bb(s2)); } inline void Assembler::crorc( int d, int s1, int s2) { emit_int32(CRORC_OPCODE | bt(d) | ba(s1) | bb(s2)); } +// More convenient version. +inline void Assembler::crand( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) { + int dst_bit = condition_register_bit(crdst, cdst), + src_bit = condition_register_bit(crsrc, csrc); + crand(dst_bit, src_bit, dst_bit); +} +inline void Assembler::crnand(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) { + int dst_bit = condition_register_bit(crdst, cdst), + src_bit = condition_register_bit(crsrc, csrc); + crnand(dst_bit, src_bit, dst_bit); +} +inline void Assembler::cror( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) { + int dst_bit = condition_register_bit(crdst, cdst), + src_bit = condition_register_bit(crsrc, csrc); + cror(dst_bit, src_bit, dst_bit); +} +inline void Assembler::crxor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) { + int dst_bit = condition_register_bit(crdst, cdst), + src_bit = condition_register_bit(crsrc, csrc); + crxor(dst_bit, src_bit, dst_bit); +} +inline void Assembler::crnor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) { + int dst_bit = condition_register_bit(crdst, cdst), + src_bit = condition_register_bit(crsrc, csrc); + crnor(dst_bit, src_bit, dst_bit); +} +inline void Assembler::creqv( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) { + int dst_bit = condition_register_bit(crdst, cdst), + src_bit = condition_register_bit(crsrc, csrc); + creqv(dst_bit, src_bit, dst_bit); +} +inline void Assembler::crandc(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) { + int dst_bit = condition_register_bit(crdst, cdst), + src_bit = condition_register_bit(crsrc, csrc); + crandc(dst_bit, src_bit, dst_bit); +} +inline void Assembler::crorc( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) { + int dst_bit = condition_register_bit(crdst, cdst), + src_bit = condition_register_bit(crsrc, csrc); + crorc(dst_bit, src_bit, dst_bit); +} + // Conditional move (>= Power7) inline void Assembler::isel(Register d, ConditionRegister cr, Condition cc, bool inv, Register a, Register b) { if (b == noreg) { @@ -516,6 +558,10 @@ inline void Assembler::smt_prio_medium_low() { Assembler::or_unchecked(R6, R6, inline void Assembler::smt_prio_medium() { Assembler::or_unchecked(R2, R2, R2); } inline void Assembler::smt_prio_medium_high() { Assembler::or_unchecked(R5, R5, R5); } inline void Assembler::smt_prio_high() { Assembler::or_unchecked(R3, R3, R3); } +// >= Power7 +inline void Assembler::smt_yield() { Assembler::or_unchecked(R27, R27, R27); } +inline void Assembler::smt_mdoio() { Assembler::or_unchecked(R29, R29, R29); } +inline void Assembler::smt_mdoom() { Assembler::or_unchecked(R30, R30, R30); } inline void Assembler::twi_0(Register a) { twi_unchecked(0, a, 0);} @@ -778,7 +824,8 @@ inline void Assembler::tbegin_() { emit_int32( TB inline void Assembler::tbeginrot_() { emit_int32( TBEGIN_OPCODE | /*R=1*/ 1u << (31-10) | rc(1)); } inline void Assembler::tend_() { emit_int32( TEND_OPCODE | rc(1)); } inline void Assembler::tendall_() { emit_int32( TEND_OPCODE | /*A=1*/ 1u << (31-6) | rc(1)); } -inline void Assembler::tabort_(Register a) { emit_int32( TABORT_OPCODE | ra(a) | rc(1)); } +inline void Assembler::tabort_() { emit_int32( TABORT_OPCODE | rc(1)); } +inline void Assembler::tabort_(Register a) { assert(a != R0, "r0 not allowed"); emit_int32( TABORT_OPCODE | ra(a) | rc(1)); } inline void Assembler::tabortwc_(int t, Register a, Register b) { emit_int32( TABORTWC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); } inline void Assembler::tabortwci_(int t, Register a, int si) { emit_int32( TABORTWCI_OPCODE | to(t) | ra(a) | sh1620(si) | rc(1)); } inline void Assembler::tabortdc_(int t, Register a, Register b) { emit_int32( TABORTDC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); } diff --git a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp index dec0d9732a8..9cb22c11433 100644 --- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp +++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2014 SAP AG. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 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 @@ -1712,7 +1712,7 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, Register mdo_addr andi_(R0, klass, TypeEntries::type_unknown); // Already unknown. Nothing to do anymore. //bne(CCR0, do_nothing); - crorc(/*CCR0 eq*/2, /*CCR1 eq*/4+2, /*CCR0 eq*/2); // cr0 eq = cr1 eq or cr0 ne + crorc(CCR0, Assembler::equal, CCR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne beq(CCR0, do_nothing); clrrdi_(R0, tmp, exact_log2(-TypeEntries::type_mask)); @@ -1826,9 +1826,9 @@ void InterpreterMacroAssembler::profile_return_type(Register ret, Register tmp1, lbz(tmp2, Method::intrinsic_id_offset_in_bytes(), R19_method); cmpwi(CCR0, tmp1, Bytecodes::_invokedynamic); cmpwi(CCR1, tmp1, Bytecodes::_invokehandle); - cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); + cror(CCR0, Assembler::equal, CCR1, Assembler::equal); cmpwi(CCR1, tmp2, vmIntrinsics::_compiledLambdaForm); - cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); + cror(CCR0, Assembler::equal, CCR1, Assembler::equal); bne(CCR0, profile_continue); } diff --git a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp index 0f8c752cacc..43258ce2a9a 100644 --- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2014 SAP AG. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 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 @@ -1079,7 +1079,7 @@ class StubGenerator: public StubCodeGenerator { __ sldi(tmp2, R5_ARG3, log2_elem_size); // size in bytes __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison! __ cmpld(CCR1, tmp1, tmp2); - __ crand(/*CCR0 lt*/0, /*CCR1 lt*/4+0, /*CCR0 lt*/0); + __ crand(CCR0, Assembler::less, CCR1, Assembler::less); __ blt(CCR0, l_overlap); // Src before dst and distance smaller than size. // need to copy forwards diff --git a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp index 2a58b36d420..432a96d8268 100644 --- a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp @@ -264,11 +264,11 @@ void TemplateInterpreterGenerator::generate_counter_incr(Label* overflow, Label* __ cmpdi(CCR0, Rmdo, 0); __ beq(CCR0, no_mdo); - // Increment backedge counter in the MDO. - const int mdo_bc_offs = in_bytes(MethodData::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset()); - __ lwz(Rscratch2, mdo_bc_offs, Rmdo); + // Increment invocation counter in the MDO. + const int mdo_ic_offs = in_bytes(MethodData::invocation_counter_offset()) + in_bytes(InvocationCounter::counter_offset()); + __ lwz(Rscratch2, mdo_ic_offs, Rmdo); __ addi(Rscratch2, Rscratch2, increment); - __ stw(Rscratch2, mdo_bc_offs, Rmdo); + __ stw(Rscratch2, mdo_ic_offs, Rmdo); __ load_const_optimized(Rscratch1, mask, R0); __ and_(Rscratch1, Rscratch2, Rscratch1); __ bne(CCR0, done); @@ -276,12 +276,12 @@ void TemplateInterpreterGenerator::generate_counter_incr(Label* overflow, Label* } // Increment counter in MethodCounters*. - const int mo_bc_offs = in_bytes(MethodCounters::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset()); + const int mo_ic_offs = in_bytes(MethodCounters::invocation_counter_offset()) + in_bytes(InvocationCounter::counter_offset()); __ bind(no_mdo); __ get_method_counters(R19_method, R3_counters, done); - __ lwz(Rscratch2, mo_bc_offs, R3_counters); + __ lwz(Rscratch2, mo_ic_offs, R3_counters); __ addi(Rscratch2, Rscratch2, increment); - __ stw(Rscratch2, mo_bc_offs, R3_counters); + __ stw(Rscratch2, mo_ic_offs, R3_counters); __ load_const_optimized(Rscratch1, mask, R0); __ and_(Rscratch1, Rscratch2, Rscratch1); __ beq(CCR0, *overflow); diff --git a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp index 40cd339c2c0..69c1e0d1be1 100644 --- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp +++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * Copyright 2013, 2014 SAP AG. All rights reserved. + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2013, 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 @@ -335,11 +335,11 @@ void TemplateTable::ldc(bool wide) { __ cmpwi(CCR0, Rscratch2, JVM_CONSTANT_UnresolvedClass); // Unresolved class? __ cmpwi(CCR1, Rscratch2, JVM_CONSTANT_UnresolvedClassInError); // Unresolved class in error state? - __ cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); + __ cror(CCR0, Assembler::equal, CCR1, Assembler::equal); // Resolved class - need to call vm to get java mirror of the class. __ cmpwi(CCR1, Rscratch2, JVM_CONSTANT_Class); - __ crnor(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); // Neither resolved class nor unresolved case from above? + __ crnor(CCR0, Assembler::equal, CCR1, Assembler::equal); // Neither resolved class nor unresolved case from above? __ beq(CCR0, notClass); __ li(R4, wide ? 1 : 0); @@ -2611,7 +2611,7 @@ void TemplateTable::jvmti_post_field_mod(Register Rcache, Register Rscratch, boo __ cmpwi(CCR0, Rflags, ltos); __ cmpwi(CCR1, Rflags, dtos); __ addi(base, R15_esp, Interpreter::expr_offset_in_bytes(1)); - __ crnor(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); + __ crnor(CCR0, Assembler::equal, CCR1, Assembler::equal); __ beq(CCR0, is_one_slot); __ addi(base, R15_esp, Interpreter::expr_offset_in_bytes(2)); __ bind(is_one_slot); @@ -3563,7 +3563,7 @@ void TemplateTable::_new() { // Make sure klass does not have has_finalizer, or is abstract, or interface or java/lang/Class. __ andi_(R0, Rinstance_size, Klass::_lh_instance_slow_path_bit); // slow path bit equals 0? - __ crnand(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); // slow path bit set or not fully initialized? + __ crnand(CCR0, Assembler::equal, CCR1, Assembler::equal); // slow path bit set or not fully initialized? __ beq(CCR0, Lslow_case); // -------------------------------------------------------------------------- diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index a6a5b43c07b..24587840f98 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -3184,7 +3184,24 @@ void MacroAssembler::pow_or_exp(bool is_exp, int num_fpu_regs_in_use) { jmp(done); } else { // Stack: X Y - Label x_negative, y_odd; + Label x_negative, y_not_2; + + static double two = 2.0; + ExternalAddress two_addr((address)&two); + + // constant maybe too far on 64 bit + lea(tmp2, two_addr); + fld_d(Address(tmp2, 0)); // Stack: 2 X Y + fcmp(tmp, 2, true, false); // Stack: X Y + jcc(Assembler::parity, y_not_2); + jcc(Assembler::notEqual, y_not_2); + + fxch(); fpop(); // Stack: X + fmul(0); // Stack: X*X + + jmp(done); + + bind(y_not_2); fldz(); // Stack: 0 X Y fcmp(tmp, 1, true, false); // Stack: X Y diff --git a/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp b/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp index 60969caa962..4e7e702ad66 100644 --- a/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp +++ b/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007, 2008, 2011 Red Hat, Inc. + * Copyright 2007, 2008, 2011, 2015, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -237,7 +237,13 @@ inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { // operation. Note that some platforms only support this with the // limitation that the only valid value to store is the immediate // constant 1. There is a test for this in JNI_CreateJavaVM(). - return __sync_lock_test_and_set (dest, exchange_value); + jint result = __sync_lock_test_and_set (dest, exchange_value); + // All atomic operations are expected to be full memory barriers + // (see atomic.hpp). However, __sync_lock_test_and_set is not + // a full memory barrier, but an acquire barrier. Hence, this added + // barrier. + __sync_synchronize(); + return result; #endif // M68K #endif // ARM } @@ -250,7 +256,9 @@ inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, #ifdef M68K return m68k_lock_test_and_set(dest, exchange_value); #else - return __sync_lock_test_and_set (dest, exchange_value); + intptr_t result = __sync_lock_test_and_set (dest, exchange_value); + __sync_synchronize(); + return result; #endif // M68K #endif // ARM } diff --git a/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp index d9df41034d4..266c950422b 100644 --- a/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp +++ b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007, 2008, 2011 Red Hat, Inc. + * Copyright 2007, 2008, 2011, 2015, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -231,7 +231,13 @@ inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { // operation. Note that some platforms only support this with the // limitation that the only valid value to store is the immediate // constant 1. There is a test for this in JNI_CreateJavaVM(). - return __sync_lock_test_and_set (dest, exchange_value); + jint result = __sync_lock_test_and_set (dest, exchange_value); + // All atomic operations are expected to be full memory barriers + // (see atomic.hpp). However, __sync_lock_test_and_set is not + // a full memory barrier, but an acquire barrier. Hence, this added + // barrier. + __sync_synchronize(); + return result; #endif // M68K #endif // ARM } @@ -244,7 +250,9 @@ inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, #ifdef M68K return m68k_lock_test_and_set(dest, exchange_value); #else - return __sync_lock_test_and_set (dest, exchange_value); + intptr_t result = __sync_lock_test_and_set (dest, exchange_value); + __sync_synchronize(); + return result; #endif // M68K #endif // ARM } diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 2b22da1f705..4f0def89a20 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -252,7 +252,7 @@ CompileTask* CompileTask::allocate() { } else { task = new CompileTask(); DEBUG_ONLY(_num_allocated_tasks++;) - assert (_num_allocated_tasks < 10000, "Leaking compilation tasks?"); + assert (WhiteBoxAPI || _num_allocated_tasks < 10000, "Leaking compilation tasks?"); task->set_next(NULL); task->set_is_free(true); } diff --git a/hotspot/src/share/vm/compiler/compilerOracle.cpp b/hotspot/src/share/vm/compiler/compilerOracle.cpp index b733305666b..a6351be1783 100644 --- a/hotspot/src/share/vm/compiler/compilerOracle.cpp +++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp @@ -105,7 +105,6 @@ class MethodMatcher : public CHeapObj { tty->print("."); print_symbol(method_name(), _method_mode); if (signature() != NULL) { - tty->print(" "); signature()->print_symbol_on(tty); } } @@ -467,43 +466,85 @@ static OracleCommand parse_command_name(const char * line, int* bytes_read) { return UnknownCommand; } - static void usage() { - tty->print_cr(" CompileCommand and the CompilerOracle allows simple control over"); - tty->print_cr(" what's allowed to be compiled. The standard supported directives"); - tty->print_cr(" are exclude and compileonly. The exclude directive stops a method"); - tty->print_cr(" from being compiled and compileonly excludes all methods except for"); - tty->print_cr(" the ones mentioned by compileonly directives. The basic form of"); - tty->print_cr(" all commands is a command name followed by the name of the method"); - tty->print_cr(" in one of two forms: the standard class file format as in"); - tty->print_cr(" class/name.methodName or the PrintCompilation format"); - tty->print_cr(" class.name::methodName. The method name can optionally be followed"); - tty->print_cr(" by a space then the signature of the method in the class file"); - tty->print_cr(" format. Otherwise the directive applies to all methods with the"); - tty->print_cr(" same name and class regardless of signature. Leading and trailing"); - tty->print_cr(" *'s in the class and/or method name allows a small amount of"); - tty->print_cr(" wildcarding. "); tty->cr(); - tty->print_cr(" Examples:"); + tty->print_cr("The CompileCommand option enables the user of the JVM to control specific"); + tty->print_cr("behavior of the dynamic compilers. Many commands require a pattern that defines"); + tty->print_cr("the set of methods the command shall be applied to. The CompileCommand"); + tty->print_cr("option provides the following commands:"); tty->cr(); - tty->print_cr(" exclude java/lang/StringBuffer.append"); - tty->print_cr(" compileonly java/lang/StringBuffer.toString ()Ljava/lang/String;"); - tty->print_cr(" exclude java/lang/String*.*"); - tty->print_cr(" exclude *.toString"); -} + tty->print_cr(" break, - debug breakpoint in compiler and in generated code"); + tty->print_cr(" print, - print assembly"); + tty->print_cr(" exclude, - don't compile or inline"); + tty->print_cr(" inline, - always inline"); + tty->print_cr(" dontinline, - don't inline"); + tty->print_cr(" compileonly, - compile only"); + tty->print_cr(" log, - log compilation"); + tty->print_cr(" option,,