# HG changeset patch # User kvn # Date 1348852589 25200 # Node ID f2e12eb74117c917c0bb264694c02de4a6a15a10 # Parent 15fba4382765ab14eae6d75188d289b137facb62# Parent 69fb89ec6fa79472697e92cd16b5505c370dfcee Merge diff -r 15fba4382765 -r f2e12eb74117 make/windows/makefiles/projectcreator.make --- a/make/windows/makefiles/projectcreator.make Fri Sep 28 14:14:25 2012 +0200 +++ b/make/windows/makefiles/projectcreator.make Fri Sep 28 10:16:29 2012 -0700 @@ -29,12 +29,11 @@ # HOTSPOTRELEASEBINDEST, or HOTSPOTDEBUGBINDEST environment variables. ProjectCreatorSources=\ - $(WorkSpace)\src\share\tools\ProjectCreator\DirectoryTree.java \ - $(WorkSpace)\src\share\tools\ProjectCreator\DirectoryTreeNode.java \ - $(WorkSpace)\src\share\tools\ProjectCreator\FileFormatException.java \ $(WorkSpace)\src\share\tools\ProjectCreator\ProjectCreator.java \ + $(WorkSpace)\src\share\tools\ProjectCreator\FileTreeCreator.java \ + $(WorkSpace)\src\share\tools\ProjectCreator\FileTreeCreatorVC7.java \ + $(WorkSpace)\src\share\tools\ProjectCreator\FileTreeCreatorVC10.java \ $(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatform.java \ - $(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC6.java \ $(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC7.java \ $(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC8.java \ $(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC9.java \ @@ -57,10 +56,24 @@ -relativeInclude src\os_cpu\windows_$(Platform_arch)\vm \ -relativeInclude src\cpu\$(Platform_arch)\vm \ -absoluteInclude $(HOTSPOTBUILDSPACE)/%f/generated \ - -ignorePath $(HOTSPOTBUILDSPACE)/%f/generated \ - -ignorePath src\share\vm\adlc \ - -ignorePath src\share\vm\shark \ - -ignorePath posix + -relativeSrcInclude src \ + -absoluteSrcInclude $(HOTSPOTBUILDSPACE) \ + -ignorePath $(HOTSPOTBUILDSPACE) \ + -ignorePath launcher \ + -ignorePath share\vm\adlc \ + -ignorePath share\vm\shark \ + -ignorePath share\tools \ + -ignorePath solaris \ + -ignorePath posix \ + -ignorePath sparc \ + -ignorePath linux \ + -ignorePath bsd \ + -ignorePath osx \ + -ignorePath arm \ + -ignorePath ppc \ + -ignorePath zero \ + -hidePath .hg + # This is referenced externally by both the IDE and batch builds ProjectCreatorOptions= @@ -84,6 +97,7 @@ $(ProjectCreatorIDEOptions) \ -sourceBase $(HOTSPOTWORKSPACE) \ -buildBase $(HOTSPOTBUILDSPACE)\%f\%b \ + -buildSpace $(HOTSPOTBUILDSPACE) \ -startAt src \ -compiler $(VcVersion) \ -projectFileName $(HOTSPOTBUILDSPACE)\$(ProjectFile) \ @@ -103,6 +117,7 @@ -define TARGET_OS_ARCH_windows_x86 \ -define TARGET_OS_FAMILY_windows \ -define TARGET_COMPILER_visCPP \ + -define INCLUDE_TRACE \ $(ProjectCreatorIncludesPRIVATE) # Add in build-specific options @@ -125,9 +140,13 @@ !endif ProjectCreatorIDEOptionsIgnoreCompiler1=\ + -ignorePath_TARGET compiler1 \ + -ignorePath_TARGET tiered \ -ignorePath_TARGET c1_ ProjectCreatorIDEOptionsIgnoreCompiler2=\ + -ignorePath_TARGET compiler2 \ + -ignorePath_TARGET tiered \ -ignorePath_TARGET src/share/vm/opto \ -ignorePath_TARGET src/share/vm/libadt \ -ignorePath_TARGET adfiles \ @@ -209,6 +228,7 @@ ################################################## ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_compiler1 COMPILER1 \ + -ignorePath_compiler1 core \ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1) ################################################## @@ -217,18 +237,19 @@ #NOTE! This list must be kept in sync with GENERATED_NAMES in adlc.make. ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_compiler2 COMPILER2 \ + -ignorePath_compiler2 core \ -additionalFile_compiler2 $(Platform_arch_model).ad \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model).cpp \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model).hpp \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_clone.cpp \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_expand.cpp \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_format.cpp \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_gen.cpp \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_misc.cpp \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_peephole.cpp \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_pipeline.cpp \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles adGlobals_$(Platform_arch_model).hpp \ - -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles dfa_$(Platform_arch_model).cpp \ + -additionalFile_compiler2 ad_$(Platform_arch_model).cpp \ + -additionalFile_compiler2 ad_$(Platform_arch_model).hpp \ + -additionalFile_compiler2 ad_$(Platform_arch_model)_clone.cpp \ + -additionalFile_compiler2 ad_$(Platform_arch_model)_expand.cpp \ + -additionalFile_compiler2 ad_$(Platform_arch_model)_format.cpp \ + -additionalFile_compiler2 ad_$(Platform_arch_model)_gen.cpp \ + -additionalFile_compiler2 ad_$(Platform_arch_model)_misc.cpp \ + -additionalFile_compiler2 ad_$(Platform_arch_model)_peephole.cpp \ + -additionalFile_compiler2 ad_$(Platform_arch_model)_pipeline.cpp \ + -additionalFile_compiler2 adGlobals_$(Platform_arch_model).hpp \ + -additionalFile_compiler2 dfa_$(Platform_arch_model).cpp \ $(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=compiler2) # Add in the jvmti (JSR-163) options @@ -237,8 +258,8 @@ # code merge was done correctly (@see jvmti.make and jvmtiEnvFill.java). # If so, they would then check it in as a new version of jvmtiEnv.cpp. ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ - -additionalGeneratedFile $(HOTSPOTBUILDSPACE)/%f/generated/jvmtifiles jvmtiEnv.hpp \ - -additionalGeneratedFile $(HOTSPOTBUILDSPACE)/%f/generated/jvmtifiles jvmtiEnter.cpp \ - -additionalGeneratedFile $(HOTSPOTBUILDSPACE)/%f/generated/jvmtifiles jvmtiEnterTrace.cpp \ - -additionalGeneratedFile $(HOTSPOTBUILDSPACE)/%f/generated/jvmtifiles jvmti.h \ - -additionalGeneratedFile $(HOTSPOTBUILDSPACE)/%f/generated/jvmtifiles bytecodeInterpreterWithChecks.cpp + -additionalFile jvmtiEnv.hpp \ + -additionalFile jvmtiEnter.cpp \ + -additionalFile jvmtiEnterTrace.cpp \ + -additionalFile jvmti.h \ + -additionalFile bytecodeInterpreterWithChecks.cpp diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/assembler_sparc.cpp --- a/src/cpu/sparc/vm/assembler_sparc.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -725,24 +725,6 @@ } -// Convert to C varargs format -void MacroAssembler::set_varargs( Argument inArg, Register d ) { - // spill register-resident args to their memory slots - // (SPARC calling convention requires callers to have already preallocated these) - // Note that the inArg might in fact be an outgoing argument, - // if a leaf routine or stub does some tricky argument shuffling. - // This routine must work even though one of the saved arguments - // is in the d register (e.g., set_varargs(Argument(0, false), O0)). - for (Argument savePtr = inArg; - savePtr.is_register(); - savePtr = savePtr.successor()) { - st_ptr(savePtr.as_register(), savePtr.address_in_frame()); - } - // return the address of the first memory slot - Address a = inArg.address_in_frame(); - add(a.base(), a.disp(), d); -} - // Conditional breakpoint (for assertion checks in assembly code) void MacroAssembler::breakpoint_trap(Condition c, CC cc) { trap(c, cc, G0, ST_RESERVED_FOR_USER_0); @@ -2943,6 +2925,20 @@ assert(itable_index.is_constant() || itable_index.as_register() == method_result, "caller must use same register for non-constant itable index as for method"); + Label L_no_such_interface_restore; + bool did_save = false; + if (scan_temp == noreg || sethi_temp == noreg) { + Register recv_2 = recv_klass->is_global() ? recv_klass : L0; + Register intf_2 = intf_klass->is_global() ? intf_klass : L1; + assert(method_result->is_global(), "must be able to return value"); + scan_temp = L2; + sethi_temp = L3; + save_frame_and_mov(0, recv_klass, recv_2, intf_klass, intf_2); + recv_klass = recv_2; + intf_klass = intf_2; + did_save = true; + } + // Compute start of first itableOffsetEntry (which is at the end of the vtable) int vtable_base = InstanceKlass::vtable_start_offset() * wordSize; int scan_step = itableOffsetEntry::size() * wordSize; @@ -2981,7 +2977,7 @@ // result = (klass + scan->offset() + itable_index); // } // } - Label search, found_method; + Label L_search, L_found_method; for (int peel = 1; peel >= 0; peel--) { // %%%% Could load both offset and interface in one ldx, if they were @@ -2991,23 +2987,23 @@ // Check that this entry is non-null. A null entry means that // the receiver class doesn't implement the interface, and wasn't the // same as when the caller was compiled. - bpr(Assembler::rc_z, false, Assembler::pn, method_result, L_no_such_interface); + bpr(Assembler::rc_z, false, Assembler::pn, method_result, did_save ? L_no_such_interface_restore : L_no_such_interface); delayed()->cmp(method_result, intf_klass); if (peel) { - brx(Assembler::equal, false, Assembler::pt, found_method); + brx(Assembler::equal, false, Assembler::pt, L_found_method); } else { - brx(Assembler::notEqual, false, Assembler::pn, search); + brx(Assembler::notEqual, false, Assembler::pn, L_search); // (invert the test to fall through to found_method...) } delayed()->add(scan_temp, scan_step, scan_temp); if (!peel) break; - bind(search); + bind(L_search); } - bind(found_method); + bind(L_found_method); // Got a hit. int ito_offset = itableOffsetEntry::offset_offset_in_bytes(); @@ -3015,6 +3011,18 @@ ito_offset -= scan_step; lduw(scan_temp, ito_offset, scan_temp); ld_ptr(recv_klass, scan_temp, method_result); + + if (did_save) { + Label L_done; + ba(L_done); + delayed()->restore(); + + bind(L_no_such_interface_restore); + ba(L_no_such_interface); + delayed()->restore(); + + bind(L_done); + } } diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/assembler_sparc.hpp --- a/src/cpu/sparc/vm/assembler_sparc.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -2428,9 +2428,6 @@ static void test(); #endif - // convert an incoming arglist to varargs format; put the pointer in d - void set_varargs( Argument a, Register d ); - int total_frame_size_in_bytes(int extraWords); // used when extraWords known statically diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/assembler_sparc.inline.hpp --- a/src/cpu/sparc/vm/assembler_sparc.inline.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/assembler_sparc.inline.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -347,7 +347,11 @@ inline void Assembler::swap( Register s1, Register s2, Register d) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::swap( Register s1, int simm13a, Register d) { v9_dep(); emit_data( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::swap( Address& a, Register d, int offset ) { relocate(a.rspec(offset)); swap( a.base(), a.disp() + offset, d ); } +inline void Assembler::swap( Address& a, Register d, int offset ) { + relocate(a.rspec(offset)); + if (a.has_index()) { assert(offset == 0, ""); swap( a.base(), a.index(), d ); } + else { swap( a.base(), a.disp() + offset, d ); } +} // Use the right loads/stores for the platform diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -1315,7 +1315,13 @@ Address LIR_Assembler::as_Address(LIR_Address* addr) { Register reg = addr->base()->as_register(); - return Address(reg, addr->disp()); + LIR_Opr index = addr->index(); + if (index->is_illegal()) { + return Address(reg, addr->disp()); + } else { + assert (addr->disp() == 0, "unsupported address mode"); + return Address(reg, index->as_pointer_register()); + } } @@ -3438,7 +3444,28 @@ } } - - +void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp) { + LIR_Address* addr = src->as_address_ptr(); + + assert(data == dest, "swap uses only 2 operands"); + assert (code == lir_xchg, "no xadd on sparc"); + + if (data->type() == T_INT) { + __ swap(as_Address(addr), data->as_register()); + } else if (data->is_oop()) { + Register obj = data->as_register(); + Register narrow = tmp->as_register(); +#ifdef _LP64 + assert(UseCompressedOops, "swap is 32bit only"); + __ encode_heap_oop(obj, narrow); + __ swap(as_Address(addr), narrow); + __ decode_heap_oop(narrow, obj); +#else + __ swap(as_Address(addr), obj); +#endif + } else { + ShouldNotReachHere(); + } +} #undef __ diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -1204,3 +1204,58 @@ __ load(addr, dst); } } + +void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { + BasicType type = x->basic_type(); + LIRItem src(x->object(), this); + LIRItem off(x->offset(), this); + LIRItem value(x->value(), this); + + src.load_item(); + value.load_item(); + off.load_nonconstant(); + + LIR_Opr dst = rlock_result(x, type); + LIR_Opr data = value.result(); + bool is_obj = (type == T_ARRAY || type == T_OBJECT); + LIR_Opr offset = off.result(); + + if (data != dst) { + __ move(data, dst); + data = dst; + } + + assert (!x->is_add() && (type == T_INT || (is_obj LP64_ONLY(&& UseCompressedOops))), "unexpected type"); + LIR_Address* addr; + if (offset->is_constant()) { + +#ifdef _LP64 + jlong l = offset->as_jlong(); + assert((jlong)((jint)l) == l, "offset too large for constant"); + jint c = (jint)l; +#else + jint c = offset->as_jint(); +#endif + addr = new LIR_Address(src.result(), c, type); + } else { + addr = new LIR_Address(src.result(), offset, type); + } + + LIR_Opr tmp = LIR_OprFact::illegalOpr; + LIR_Opr ptr = LIR_OprFact::illegalOpr; + + if (is_obj) { + // Do the pre-write barrier, if any. + // barriers on sparc don't work with a base + index address + tmp = FrameMap::G3_opr; + ptr = new_pointer_register(); + __ add(src.result(), off.result(), ptr); + pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */, + true /* do_load */, false /* patch */, NULL); + } + __ xchg(LIR_OprFact::address(addr), data, dst, tmp); + if (is_obj) { + // Seems to be a precise address + post_barrier(ptr, data); + } +} diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/interp_masm_sparc.cpp --- a/src/cpu/sparc/vm/interp_masm_sparc.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -1395,12 +1395,17 @@ AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit); sethi(profile_limit, Rtmp); ld(Rtmp, profile_limit.low10(), Rtmp); - cmp_and_br_short(invocation_count, Rtmp, Assembler::lessUnsigned, Assembler::pn, profile_continue); + 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. + br(Assembler::lessUnsigned, false, Assembler::pn, profile_continue); + delayed()->nop(); // Build it now. call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method)); set_method_data_pointer_for_bcp(); - ba_short(profile_continue); + ba(profile_continue); + delayed()->nop(); bind(done); } diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/methodHandles_sparc.cpp --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -121,6 +121,7 @@ void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp, bool for_compiler_entry) { assert(method == G5_method, "interpreter calling convention"); + assert_different_registers(method, target, temp); if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) { Label run_compiled_code; @@ -153,19 +154,19 @@ BLOCK_COMMENT("jump_to_lambda_form {"); // This is the initial entry point of a lazy method handle. // After type checking, it picks up the invoker from the LambdaForm. - assert_different_registers(recv, method_temp, temp2, temp3); + assert_different_registers(recv, method_temp, temp2); // temp3 is only passed on assert(method_temp == G5_method, "required register for loading method"); //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); }); // Load the invoker, as MH -> MH.form -> LF.vmentry __ verify_oop(recv); - __ load_heap_oop(Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), method_temp); + __ load_heap_oop(Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), method_temp); __ verify_oop(method_temp); - __ load_heap_oop(Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), method_temp); + __ load_heap_oop(Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), method_temp); __ verify_oop(method_temp); // the following assumes that a Method* is normally compressed in the vmtarget field: - __ ld_ptr(Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())), method_temp); + __ ld_ptr( Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())), method_temp); if (VerifyMethodHandles && !for_compiler_entry) { // make sure recv is already on stack @@ -303,25 +304,25 @@ Register member_reg, bool for_compiler_entry) { assert(is_signature_polymorphic(iid), "expected invoke iid"); - // temps used in this code are not used in *either* compiled or interpreted calling sequences Register temp1 = (for_compiler_entry ? G1_scratch : O1); - Register temp2 = (for_compiler_entry ? G4_scratch : O4); - Register temp3 = G3_scratch; - Register temp4 = (for_compiler_entry ? noreg : O2); + Register temp2 = (for_compiler_entry ? G3_scratch : O2); + Register temp3 = (for_compiler_entry ? G4_scratch : O3); + Register temp4 = (for_compiler_entry ? noreg : O4); if (for_compiler_entry) { assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic ? noreg : O0), "only valid assignment"); - assert_different_registers(temp1, O0, O1, O2, O3, O4, O5); - assert_different_registers(temp2, O0, O1, O2, O3, O4, O5); - assert_different_registers(temp3, O0, O1, O2, O3, O4, O5); - assert_different_registers(temp4, O0, O1, O2, O3, O4, O5); + assert_different_registers(temp1, O0, O1, O2, O3, O4, O5); + assert_different_registers(temp2, O0, O1, O2, O3, O4, O5); + assert_different_registers(temp3, O0, O1, O2, O3, O4, O5); + assert_different_registers(temp4, O0, O1, O2, O3, O4, O5); + } else { + assert_different_registers(temp1, temp2, temp3, temp4, O5_savedSP); // don't trash lastSP } if (receiver_reg != noreg) assert_different_registers(temp1, temp2, temp3, temp4, receiver_reg); if (member_reg != noreg) assert_different_registers(temp1, temp2, temp3, temp4, member_reg); - if (!for_compiler_entry) assert_different_registers(temp1, temp2, temp3, temp4, O5_savedSP); // don't trash lastSP if (iid == vmIntrinsics::_invokeBasic) { // indirect through MH.form.vmentry.vmtarget - jump_to_lambda_form(_masm, receiver_reg, G5_method, temp2, temp3, for_compiler_entry); + jump_to_lambda_form(_masm, receiver_reg, G5_method, temp1, temp2, for_compiler_entry); } else { // The method is a member invoker used by direct method handles. @@ -378,24 +379,22 @@ // member_reg - MemberName that was the trailing argument // temp1_recv_klass - klass of stacked receiver, if needed // O5_savedSP - interpreter linkage (if interpreted) - // O0..O7,G1,G4 - compiler arguments (if compiled) + // O0..O5 - compiler arguments (if compiled) - bool method_is_live = false; + Label L_incompatible_class_change_error; switch (iid) { case vmIntrinsics::_linkToSpecial: if (VerifyMethodHandles) { - verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); + verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp2); } __ ld_ptr(member_vmtarget, G5_method); - method_is_live = true; break; case vmIntrinsics::_linkToStatic: if (VerifyMethodHandles) { - verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); + verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp2); } __ ld_ptr(member_vmtarget, G5_method); - method_is_live = true; break; case vmIntrinsics::_linkToVirtual: @@ -404,7 +403,7 @@ // minus the CP setup and profiling: if (VerifyMethodHandles) { - verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3); + verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp2); } // pick out the vtable index from the MemberName, and then we can discard it: @@ -423,7 +422,6 @@ // get target Method* & entry point __ lookup_virtual_method(temp1_recv_klass, temp2_index, G5_method); - method_is_live = true; break; } @@ -432,13 +430,13 @@ // same as TemplateTable::invokeinterface // (minus the CP setup and profiling, with different argument motion) if (VerifyMethodHandles) { - verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3); + verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp2); } - Register temp3_intf = temp3; - __ load_heap_oop(member_clazz, temp3_intf); - load_klass_from_Class(_masm, temp3_intf, temp2, temp4); - __ verify_klass_ptr(temp3_intf); + Register temp2_intf = temp2; + __ load_heap_oop(member_clazz, temp2_intf); + load_klass_from_Class(_masm, temp2_intf, temp3, temp4); + __ verify_klass_ptr(temp2_intf); Register G5_index = G5_method; __ ld_ptr(member_vmindex, G5_index); @@ -450,37 +448,34 @@ } // given intf, index, and recv klass, dispatch to the implementation method - Label L_no_such_interface; - Register no_sethi_temp = noreg; - __ lookup_interface_method(temp1_recv_klass, temp3_intf, + __ lookup_interface_method(temp1_recv_klass, temp2_intf, // note: next two args must be the same: G5_index, G5_method, - temp2, no_sethi_temp, - L_no_such_interface); - - __ verify_method_ptr(G5_method); - jump_from_method_handle(_masm, G5_method, temp2, temp3, for_compiler_entry); - - __ bind(L_no_such_interface); - AddressLiteral icce(StubRoutines::throw_IncompatibleClassChangeError_entry()); - __ jump_to(icce, temp3); - __ delayed()->nop(); + temp3, temp4, + L_incompatible_class_change_error); break; } default: - fatal(err_msg("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid))); + fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid))); break; } - if (method_is_live) { - // live at this point: G5_method, O5_savedSP (if interpreted) + // Live at this point: + // G5_method + // O5_savedSP (if interpreted) - // After figuring out which concrete method to call, jump into it. - // Note that this works in the interpreter with no data motion. - // But the compiled version will require that rcx_recv be shifted out. - __ verify_method_ptr(G5_method); - jump_from_method_handle(_masm, G5_method, temp1, temp3, for_compiler_entry); + // After figuring out which concrete method to call, jump into it. + // Note that this works in the interpreter with no data motion. + // But the compiled version will require that rcx_recv be shifted out. + __ verify_method_ptr(G5_method); + jump_from_method_handle(_masm, G5_method, temp1, temp2, for_compiler_entry); + + if (iid == vmIntrinsics::_linkToInterface) { + __ BIND(L_incompatible_class_change_error); + AddressLiteral icce(StubRoutines::throw_IncompatibleClassChangeError_entry()); + __ jump_to(icce, temp1); + __ delayed()->nop(); } } } diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/sharedRuntime_sparc.cpp --- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -313,6 +313,14 @@ } +// Is vector's size (in bytes) bigger than a size saved by default? +// 8 bytes FP registers are saved by default on SPARC. +bool SharedRuntime::is_wide_vector(int size) { + // Note, MaxVectorSize == 8 on SPARC. + assert(size <= 8, err_msg_res("%d bytes vectors are not supported", size)); + return size > 8; +} + // The java_calling_convention describes stack locations as ideal slots on // a frame with no abi restrictions. Since we must observe abi restrictions // (like the placement of the register window) the slots must be biased by @@ -364,9 +372,9 @@ // --------------------------------------------------------------------------- // The compiled Java calling convention. The Java convention always passes // 64-bit values in adjacent aligned locations (either registers or stack), -// floats in float registers and doubles in aligned float pairs. Values are -// packed in the registers. There is no backing varargs store for values in -// registers. In the 32-bit build, longs are passed in G1 and G4 (cannot be +// floats in float registers and doubles in aligned float pairs. There is +// no backing varargs store for values in registers. +// In the 32-bit build, longs are passed on the stack (cannot be // passed in I's, because longs in I's get their heads chopped off at // interrupt). int SharedRuntime::java_calling_convention(const BasicType *sig_bt, @@ -375,76 +383,13 @@ int is_outgoing) { assert(F31->as_VMReg()->is_reg(), "overlapping stack/register numbers"); - // Convention is to pack the first 6 int/oop args into the first 6 registers - // (I0-I5), extras spill to the stack. Then pack the first 8 float args - // into F0-F7, extras spill to the stack. Then pad all register sets to - // align. Then put longs and doubles into the same registers as they fit, - // else spill to the stack. const int int_reg_max = SPARC_ARGS_IN_REGS_NUM; const int flt_reg_max = 8; - // - // Where 32-bit 1-reg longs start being passed - // In tiered we must pass on stack because c1 can't use a "pair" in a single reg. - // So make it look like we've filled all the G regs that c2 wants to use. - Register g_reg = TieredCompilation ? noreg : G1; - - // Count int/oop and float args. See how many stack slots we'll need and - // where the longs & doubles will go. - int int_reg_cnt = 0; - int flt_reg_cnt = 0; - // int stk_reg_pairs = frame::register_save_words*(wordSize>>2); - // int stk_reg_pairs = SharedRuntime::out_preserve_stack_slots(); - int stk_reg_pairs = 0; - for (int i = 0; i < total_args_passed; i++) { - switch (sig_bt[i]) { - case T_LONG: // LP64, longs compete with int args - assert(sig_bt[i+1] == T_VOID, ""); -#ifdef _LP64 - if (int_reg_cnt < int_reg_max) int_reg_cnt++; -#endif - break; - case T_OBJECT: - case T_ARRAY: - case T_ADDRESS: // Used, e.g., in slow-path locking for the lock's stack address - if (int_reg_cnt < int_reg_max) int_reg_cnt++; -#ifndef _LP64 - else stk_reg_pairs++; -#endif - break; - case T_INT: - case T_SHORT: - case T_CHAR: - case T_BYTE: - case T_BOOLEAN: - if (int_reg_cnt < int_reg_max) int_reg_cnt++; - else stk_reg_pairs++; - break; - case T_FLOAT: - if (flt_reg_cnt < flt_reg_max) flt_reg_cnt++; - else stk_reg_pairs++; - break; - case T_DOUBLE: - assert(sig_bt[i+1] == T_VOID, ""); - break; - case T_VOID: - break; - default: - ShouldNotReachHere(); - } - } - - // This is where the longs/doubles start on the stack. - stk_reg_pairs = (stk_reg_pairs+1) & ~1; // Round - - int flt_reg_pairs = (flt_reg_cnt+1) & ~1; - - // int stk_reg = frame::register_save_words*(wordSize>>2); - // int stk_reg = SharedRuntime::out_preserve_stack_slots(); - int stk_reg = 0; + int int_reg = 0; int flt_reg = 0; - - // Now do the signature layout + int slot = 0; + for (int i = 0; i < total_args_passed; i++) { switch (sig_bt[i]) { case T_INT: @@ -461,11 +406,14 @@ Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++); regs[i].set1(r->as_VMReg()); } else { - regs[i].set1(VMRegImpl::stack2reg(stk_reg++)); + regs[i].set1(VMRegImpl::stack2reg(slot++)); } break; #ifdef _LP64 + case T_LONG: + assert(sig_bt[i+1] == T_VOID, "expecting VOID in other half"); + // fall-through case T_OBJECT: case T_ARRAY: case T_ADDRESS: // Used, e.g., in slow-path locking for the lock's stack address @@ -473,78 +421,57 @@ Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++); regs[i].set2(r->as_VMReg()); } else { - regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs)); - stk_reg_pairs += 2; + slot = round_to(slot, 2); // align + regs[i].set2(VMRegImpl::stack2reg(slot)); + slot += 2; } break; -#endif // _LP64 - +#else case T_LONG: assert(sig_bt[i+1] == T_VOID, "expecting VOID in other half"); -#ifdef _LP64 - if (int_reg < int_reg_max) { - Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++); - regs[i].set2(r->as_VMReg()); - } else { - regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs)); - stk_reg_pairs += 2; - } -#else -#ifdef COMPILER2 - // For 32-bit build, can't pass longs in O-regs because they become - // I-regs and get trashed. Use G-regs instead. G1 and G4 are almost - // spare and available. This convention isn't used by the Sparc ABI or - // anywhere else. If we're tiered then we don't use G-regs because c1 - // can't deal with them as a "pair". (Tiered makes this code think g's are filled) - // G0: zero - // G1: 1st Long arg - // G2: global allocated to TLS - // G3: used in inline cache check - // G4: 2nd Long arg - // G5: used in inline cache check - // G6: used by OS - // G7: used by OS - - if (g_reg == G1) { - regs[i].set2(G1->as_VMReg()); // This long arg in G1 - g_reg = G4; // Where the next arg goes - } else if (g_reg == G4) { - regs[i].set2(G4->as_VMReg()); // The 2nd long arg in G4 - g_reg = noreg; // No more longs in registers - } else { - regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs)); - stk_reg_pairs += 2; - } -#else // COMPILER2 - regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs)); - stk_reg_pairs += 2; -#endif // COMPILER2 -#endif // _LP64 + // On 32-bit SPARC put longs always on the stack to keep the pressure off + // integer argument registers. They should be used for oops. + slot = round_to(slot, 2); // align + regs[i].set2(VMRegImpl::stack2reg(slot)); + slot += 2; +#endif break; case T_FLOAT: - if (flt_reg < flt_reg_max) regs[i].set1(as_FloatRegister(flt_reg++)->as_VMReg()); - else regs[i].set1(VMRegImpl::stack2reg(stk_reg++)); + if (flt_reg < flt_reg_max) { + FloatRegister r = as_FloatRegister(flt_reg++); + regs[i].set1(r->as_VMReg()); + } else { + regs[i].set1(VMRegImpl::stack2reg(slot++)); + } break; + case T_DOUBLE: assert(sig_bt[i+1] == T_VOID, "expecting half"); - if (flt_reg_pairs + 1 < flt_reg_max) { - regs[i].set2(as_FloatRegister(flt_reg_pairs)->as_VMReg()); - flt_reg_pairs += 2; + if (round_to(flt_reg, 2) + 1 < flt_reg_max) { + flt_reg = round_to(flt_reg, 2); // align + FloatRegister r = as_FloatRegister(flt_reg); + regs[i].set2(r->as_VMReg()); + flt_reg += 2; } else { - regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs)); - stk_reg_pairs += 2; + slot = round_to(slot, 2); // align + regs[i].set2(VMRegImpl::stack2reg(slot)); + slot += 2; } break; - case T_VOID: regs[i].set_bad(); break; // Halves of longs & doubles + + case T_VOID: + regs[i].set_bad(); // Halves of longs & doubles + break; + default: - ShouldNotReachHere(); + fatal(err_msg_res("unknown basic type %d", sig_bt[i])); + break; } } // retun the amount of stack space these arguments will need. - return stk_reg_pairs; - + return slot; } // Helper class mostly to avoid passing masm everywhere, and handle @@ -601,8 +528,7 @@ Label L; __ ld_ptr(G5_method, in_bytes(Method::code_offset()), G3_scratch); __ br_null(G3_scratch, false, Assembler::pt, L); - // Schedule the branch target address early. - __ delayed()->ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), G3_scratch); + __ delayed()->nop(); // Call into the VM to patch the caller, then jump to compiled callee __ save_frame(4); // Args in compiled layout; do not blow them @@ -645,7 +571,6 @@ __ ldx(FP, -8 + STACK_BIAS, G1); __ ldx(FP, -16 + STACK_BIAS, G4); __ mov(L5, G5_method); - __ ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), G3_scratch); #endif /* _LP64 */ __ restore(); // Restore args @@ -726,7 +651,7 @@ int comp_args_on_stack, // VMRegStackSlots const BasicType *sig_bt, const VMRegPair *regs, - Label& skip_fixup) { + Label& L_skip_fixup) { // Before we get into the guts of the C2I adapter, see if we should be here // at all. We've come from compiled code and are attempting to jump to the @@ -747,7 +672,7 @@ patch_callers_callsite(); - __ bind(skip_fixup); + __ bind(L_skip_fixup); // Since all args are passed on the stack, total_args_passed*wordSize is the // space we need. Add in varargs area needed by the interpreter. Round up @@ -757,46 +682,18 @@ (frame::varargs_offset - frame::register_save_words)*wordSize; const int extraspace = round_to(arg_size + varargs_area, 2*wordSize); - int bias = STACK_BIAS; + const int bias = STACK_BIAS; const int interp_arg_offset = frame::varargs_offset*wordSize + (total_args_passed-1)*Interpreter::stackElementSize; - Register base = SP; - -#ifdef _LP64 - // In the 64bit build because of wider slots and STACKBIAS we can run - // out of bits in the displacement to do loads and stores. Use g3 as - // temporary displacement. - if (!Assembler::is_simm13(extraspace)) { - __ set(extraspace, G3_scratch); - __ sub(SP, G3_scratch, SP); - } else { - __ sub(SP, extraspace, SP); - } + const Register base = SP; + + // Make some extra space on the stack. + __ sub(SP, __ ensure_simm13_or_reg(extraspace, G3_scratch), SP); set_Rdisp(G3_scratch); -#else - __ sub(SP, extraspace, SP); -#endif // _LP64 - - // First write G1 (if used) to where ever it must go - for (int i=0; ias_VMReg()) { - if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) { - store_c2i_object(G1_scratch, base, st_off); - } else if (sig_bt[i] == T_LONG) { - assert(!TieredCompilation, "should not use register args for longs"); - store_c2i_long(G1_scratch, base, st_off, false); - } else { - store_c2i_int(G1_scratch, base, st_off); - } - } - } - - // Now write the args into the outgoing interpreter space - for (int i=0; iis_valid(), ""); continue; } - // Skip G1 if found as we did it first in order to free it up - if (r_1 == G1_scratch->as_VMReg()) { - continue; - } -#ifdef ASSERT - bool G1_forced = false; -#endif // ASSERT if (r_1->is_stack()) { // Pretend stack targets are loaded into G1 -#ifdef _LP64 - Register ld_off = Rdisp; - __ set(reg2offset(r_1) + extraspace + bias, ld_off); -#else - int ld_off = reg2offset(r_1) + extraspace + bias; -#endif // _LP64 -#ifdef ASSERT - G1_forced = true; -#endif // ASSERT + RegisterOrConstant ld_off = reg2offset(r_1) + extraspace + bias; + ld_off = __ ensure_simm13_or_reg(ld_off, Rdisp); r_1 = G1_scratch->as_VMReg();// as part of the load/store shuffle if (!r_2->is_valid()) __ ld (base, ld_off, G1_scratch); else __ ldx(base, ld_off, G1_scratch); @@ -831,11 +714,6 @@ if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) { store_c2i_object(r, base, st_off); } else if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { -#ifndef _LP64 - if (TieredCompilation) { - assert(G1_forced || sig_bt[i] != T_LONG, "should not use register args for longs"); - } -#endif // _LP64 store_c2i_long(r, base, st_off, r_2->is_stack()); } else { store_c2i_int(r, base, st_off); @@ -851,19 +729,12 @@ } } -#ifdef _LP64 - // Need to reload G3_scratch, used for temporary displacements. + // Load the interpreter entry point. __ ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), G3_scratch); // Pass O5_savedSP as an argument to the interpreter. // The interpreter will restore SP to this value before returning. - __ set(extraspace, G1); - __ add(SP, G1, O5_savedSP); -#else - // Pass O5_savedSP as an argument to the interpreter. - // The interpreter will restore SP to this value before returning. - __ add(SP, extraspace, O5_savedSP); -#endif // _LP64 + __ add(SP, __ ensure_simm13_or_reg(extraspace, G1), O5_savedSP); __ mov((frame::varargs_offset)*wordSize - 1*Interpreter::stackElementSize+bias+BytesPerWord, G1); @@ -971,7 +842,6 @@ // Outputs: // G2_thread - TLS - // G1, G4 - Outgoing long args in 32-bit build // O0-O5 - Outgoing args in compiled layout // O6 - Adjusted or restored SP // O7 - Valid return address @@ -1016,10 +886,10 @@ // +--------------+ <--- start of outgoing args // | pad, align | | // +--------------+ | - // | ints, floats | |---Outgoing stack args, packed low. - // +--------------+ | First few args in registers. - // : doubles : | - // | longs | | + // | ints, longs, | | + // | floats, | |---Outgoing stack args. + // : doubles : | First few args in registers. + // | | | // +--------------+ <--- SP' + 16*wordsize // | | // : window : @@ -1033,7 +903,6 @@ // Cut-out for having no stack args. Since up to 6 args are passed // in registers, we will commonly have no stack args. if (comp_args_on_stack > 0) { - // Convert VMReg stack slots to words. int comp_words_on_stack = round_to(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord; // Round up to miminum stack alignment, in wordSize @@ -1044,13 +913,9 @@ __ sub(SP, (comp_words_on_stack)*wordSize, SP); } - // Will jump to the compiled code just as if compiled code was doing it. - // Pre-load the register-jump target early, to schedule it better. - __ ld_ptr(G5_method, in_bytes(Method::from_compiled_offset()), G3); - // Now generate the shuffle code. Pick up all register args and move the // rest through G1_scratch. - for (int i=0; iis_FloatRegister(), ""); if (!r_2->is_valid()) { - __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_1->as_FloatRegister()); + __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_1->as_FloatRegister()); } else { #ifdef _LP64 // In V9, doubles are given 2 64-bit slots in the interpreter, but the @@ -1104,11 +968,11 @@ // spare float register. RegisterOrConstant slot = (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) ? next_arg_slot(ld_off) : arg_slot(ld_off); - __ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister()); + __ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister()); #else // Need to marshal 64-bit value from misaligned Lesp loads __ ldf(FloatRegisterImpl::S, Gargs, next_arg_slot(ld_off), r_1->as_FloatRegister()); - __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_2->as_FloatRegister()); + __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_2->as_FloatRegister()); #endif } } @@ -1124,76 +988,35 @@ else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, slot); } } - bool made_space = false; -#ifndef _LP64 - // May need to pick up a few long args in G1/G4 - bool g4_crushed = false; - bool g3_crushed = false; - for (int i=0; iis_Register() && regs[i].second()->is_valid()) { - // Load in argument order going down - int ld_off = (total_args_passed-i)*Interpreter::stackElementSize; - // Need to marshal 64-bit value from misaligned Lesp loads - Register r = regs[i].first()->as_Register()->after_restore(); - if (r == G1 || r == G4) { - assert(!g4_crushed, "ordering problem"); - if (r == G4){ - g4_crushed = true; - __ lduw(Gargs, arg_slot(ld_off) , G3_scratch); // Load lo bits - __ ld (Gargs, next_arg_slot(ld_off), r); // Load hi bits - } else { - // better schedule this way - __ ld (Gargs, next_arg_slot(ld_off), r); // Load hi bits - __ lduw(Gargs, arg_slot(ld_off) , G3_scratch); // Load lo bits - } - g3_crushed = true; - __ sllx(r, 32, r); - __ or3(G3_scratch, r, r); - } else { - assert(r->is_out(), "longs passed in two O registers"); - __ ld (Gargs, arg_slot(ld_off) , r->successor()); // Load lo bits - __ ld (Gargs, next_arg_slot(ld_off), r); // Load hi bits - } - } - } -#endif // Jump to the compiled code just as if compiled code was doing it. - // -#ifndef _LP64 - if (g3_crushed) { - // Rats load was wasted, at least it is in cache... - __ ld_ptr(G5_method, Method::from_compiled_offset(), G3); - } -#endif /* _LP64 */ - - // 6243940 We might end up in handle_wrong_method if - // the callee is deoptimized as we race thru here. If that - // happens we don't want to take a safepoint because the - // caller frame will look interpreted and arguments are now - // "compiled" so it is much better to make this transition - // invisible to the stack walking code. Unfortunately if - // we try and find the callee by normal means a safepoint - // is possible. So we stash the desired callee in the thread - // and the vm will find there should this case occur. - Address callee_target_addr(G2_thread, JavaThread::callee_target_offset()); - __ st_ptr(G5_method, callee_target_addr); - - if (StressNonEntrant) { - // Open a big window for deopt failure - __ save_frame(0); - __ mov(G0, L0); - Label loop; - __ bind(loop); - __ sub(L0, 1, L0); - __ br_null_short(L0, Assembler::pt, loop); - - __ restore(); - } - - - __ jmpl(G3, 0, G0); - __ delayed()->nop(); + __ ld_ptr(G5_method, in_bytes(Method::from_compiled_offset()), G3); + + // 6243940 We might end up in handle_wrong_method if + // the callee is deoptimized as we race thru here. If that + // happens we don't want to take a safepoint because the + // caller frame will look interpreted and arguments are now + // "compiled" so it is much better to make this transition + // invisible to the stack walking code. Unfortunately if + // we try and find the callee by normal means a safepoint + // is possible. So we stash the desired callee in the thread + // and the vm will find there should this case occur. + Address callee_target_addr(G2_thread, JavaThread::callee_target_offset()); + __ st_ptr(G5_method, callee_target_addr); + + if (StressNonEntrant) { + // Open a big window for deopt failure + __ save_frame(0); + __ mov(G0, L0); + Label loop; + __ bind(loop); + __ sub(L0, 1, L0); + __ br_null_short(L0, Assembler::pt, loop); + __ restore(); + } + + __ jmpl(G3, 0, G0); + __ delayed()->nop(); } // --------------------------------------------------------------- @@ -1221,28 +1044,17 @@ // compiled code, which relys solely on SP and not FP, get sick). address c2i_unverified_entry = __ pc(); - Label skip_fixup; + Label L_skip_fixup; { -#if !defined(_LP64) && defined(COMPILER2) - Register R_temp = L0; // another scratch register -#else - Register R_temp = G1; // another scratch register -#endif + Register R_temp = G1; // another scratch register AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub()); __ verify_oop(O0); __ load_klass(O0, G3_scratch); -#if !defined(_LP64) && defined(COMPILER2) - __ save(SP, -frame::register_save_words*wordSize, SP); __ ld_ptr(G5_method, CompiledICHolder::holder_klass_offset(), R_temp); __ cmp(G3_scratch, R_temp); - __ restore(); -#else - __ ld_ptr(G5_method, CompiledICHolder::holder_klass_offset(), R_temp); - __ cmp(G3_scratch, R_temp); -#endif Label ok, ok2; __ brx(Assembler::equal, false, Assembler::pt, ok); @@ -1256,8 +1068,8 @@ // the call site corrected. __ ld_ptr(G5_method, in_bytes(Method::code_offset()), G3_scratch); __ bind(ok2); - __ br_null(G3_scratch, false, Assembler::pt, skip_fixup); - __ delayed()->ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), G3_scratch); + __ br_null(G3_scratch, false, Assembler::pt, L_skip_fixup); + __ delayed()->nop(); __ jump_to(ic_miss, G3_scratch); __ delayed()->nop(); @@ -1265,7 +1077,7 @@ address c2i_entry = __ pc(); - agen.gen_c2i_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup); + agen.gen_c2i_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs, L_skip_fixup); __ flush(); return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry); @@ -1985,12 +1797,12 @@ } static void verify_oop_args(MacroAssembler* masm, - int total_args_passed, + methodHandle method, const BasicType* sig_bt, const VMRegPair* regs) { Register temp_reg = G5_method; // not part of any compiled calling seq if (VerifyOops) { - for (int i = 0; i < total_args_passed; i++) { + for (int i = 0; i < method->size_of_parameters(); i++) { if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) { VMReg r = regs[i].first(); @@ -2009,35 +1821,32 @@ } static void gen_special_dispatch(MacroAssembler* masm, - int total_args_passed, - int comp_args_on_stack, - vmIntrinsics::ID special_dispatch, + methodHandle method, const BasicType* sig_bt, const VMRegPair* regs) { - verify_oop_args(masm, total_args_passed, sig_bt, regs); + verify_oop_args(masm, method, sig_bt, regs); + vmIntrinsics::ID iid = method->intrinsic_id(); // Now write the args into the outgoing interpreter space bool has_receiver = false; Register receiver_reg = noreg; int member_arg_pos = -1; Register member_reg = noreg; - int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(special_dispatch); + int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid); if (ref_kind != 0) { - member_arg_pos = total_args_passed - 1; // trailing MemberName argument + member_arg_pos = method->size_of_parameters() - 1; // trailing MemberName argument member_reg = G5_method; // known to be free at this point has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); - } else if (special_dispatch == vmIntrinsics::_invokeBasic) { + } else if (iid == vmIntrinsics::_invokeBasic) { has_receiver = true; } else { - fatal(err_msg("special_dispatch=%d", special_dispatch)); + fatal(err_msg_res("unexpected intrinsic id %d", iid)); } if (member_reg != noreg) { // Load the member_arg into register, if necessary. - assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob"); - assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object"); + SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs); VMReg r = regs[member_arg_pos].first(); - assert(r->is_valid(), "bad member arg"); if (r->is_stack()) { RegisterOrConstant ld_off = reg2offset(r) + STACK_BIAS; ld_off = __ ensure_simm13_or_reg(ld_off, member_reg); @@ -2050,7 +1859,7 @@ if (has_receiver) { // Make sure the receiver is loaded into a register. - assert(total_args_passed > 0, "oob"); + assert(method->size_of_parameters() > 0, "oob"); assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object"); VMReg r = regs[0].first(); assert(r->is_valid(), "bad receiver arg"); @@ -2058,7 +1867,7 @@ // Porting note: This assumes that compiled calling conventions always // pass the receiver oop in a register. If this is not true on some // platform, pick a temp and load the receiver from stack. - assert(false, "receiver always in a register"); + fatal("receiver always in a register"); receiver_reg = G3_scratch; // known to be free at this point RegisterOrConstant ld_off = reg2offset(r) + STACK_BIAS; ld_off = __ ensure_simm13_or_reg(ld_off, member_reg); @@ -2070,7 +1879,7 @@ } // Figure out which address we are really jumping to: - MethodHandles::generate_method_handle_dispatch(masm, special_dispatch, + MethodHandles::generate_method_handle_dispatch(masm, iid, receiver_reg, member_reg, /*for_compiler_entry:*/ true); } @@ -2103,11 +1912,9 @@ // transition back to thread_in_Java // return to caller // -nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm, +nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, methodHandle method, int compile_id, - int total_in_args, - int comp_args_on_stack, // in VMRegStackSlots BasicType* in_sig_bt, VMRegPair* in_regs, BasicType ret_type) { @@ -2116,9 +1923,7 @@ intptr_t start = (intptr_t)__ pc(); int vep_offset = ((intptr_t)__ pc()) - start; gen_special_dispatch(masm, - total_in_args, - comp_args_on_stack, - method->intrinsic_id(), + method, in_sig_bt, in_regs); int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period @@ -2220,6 +2025,7 @@ // we convert the java signature to a C signature by inserting // the hidden arguments as arg[0] and possibly arg[1] (static method) + const int total_in_args = method->size_of_parameters(); int total_c_args = total_in_args; int total_save_slots = 6 * VMRegImpl::slots_per_word; if (!is_critical_native) { @@ -3936,7 +3742,7 @@ // the 64-bit %o's, then do a save, then fixup the caller's SP (our FP). // Tricky, tricky, tricky... -SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) { +SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) { assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before"); // allocate space for the code @@ -3954,6 +3760,7 @@ int start = __ offset(); + bool cause_return = (poll_type == POLL_AT_RETURN); // If this causes a return before the processing, then do a "restore" if (cause_return) { __ restore(); diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/sparc.ad --- a/src/cpu/sparc/vm/sparc.ad Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/sparc.ad Fri Sep 28 10:16:29 2012 -0700 @@ -1838,6 +1838,12 @@ case Op_PopCountL: if (!UsePopCountInstruction) return false; + case Op_CompareAndSwapL: +#ifdef _LP64 + case Op_CompareAndSwapP: +#endif + if (!VM_Version::supports_cx8()) + return false; break; } @@ -7199,6 +7205,7 @@ // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them instruct compareAndSwapL_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ + predicate(VM_Version::supports_cx8()); match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); effect( USE mem_ptr, KILL ccr, KILL tmp1); format %{ @@ -7230,6 +7237,9 @@ %} instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ +#ifdef _LP64 + predicate(VM_Version::supports_cx8()); +#endif match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); effect( USE mem_ptr, KILL ccr, KILL tmp1); format %{ @@ -7264,6 +7274,38 @@ ins_pipe( long_memory_op ); %} +instruct xchgI( memory mem, iRegI newval) %{ + match(Set newval (GetAndSetI mem newval)); + format %{ "SWAP [$mem],$newval" %} + size(4); + ins_encode %{ + __ swap($mem$$Address, $newval$$Register); + %} + ins_pipe( long_memory_op ); +%} + +#ifndef _LP64 +instruct xchgP( memory mem, iRegP newval) %{ + match(Set newval (GetAndSetP mem newval)); + format %{ "SWAP [$mem],$newval" %} + size(4); + ins_encode %{ + __ swap($mem$$Address, $newval$$Register); + %} + ins_pipe( long_memory_op ); +%} +#endif + +instruct xchgN( memory mem, iRegN newval) %{ + match(Set newval (GetAndSetN mem newval)); + format %{ "SWAP [$mem],$newval" %} + size(4); + ins_encode %{ + __ swap($mem$$Address, $newval$$Register); + %} + ins_pipe( long_memory_op ); +%} + //--------------------- // Subtraction Instructions // Register Subtraction diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/vm_version_sparc.cpp --- a/src/cpu/sparc/vm/vm_version_sparc.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/vm_version_sparc.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -96,6 +96,7 @@ UseSSE = 0; // Only on x86 and x64 _supports_cx8 = has_v9(); + _supports_atomic_getset4 = true; // swap instruction if (is_niagara()) { // Indirect branch is the same cost as direct @@ -338,7 +339,11 @@ unsigned int VM_Version::calc_parallel_worker_threads() { unsigned int result; - if (is_niagara_plus()) { + if (is_M_series()) { + // for now, use same gc thread calculation for M-series as for niagara-plus + // in future, we may want to tweak parameters for nof_parallel_worker_thread + result = nof_parallel_worker_threads(5, 16, 8); + } else if (is_niagara_plus()) { result = nof_parallel_worker_threads(5, 16, 8); } else { result = nof_parallel_worker_threads(5, 8, 8); diff -r 15fba4382765 -r f2e12eb74117 src/cpu/sparc/vm/vm_version_sparc.hpp --- a/src/cpu/sparc/vm/vm_version_sparc.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/sparc/vm/vm_version_sparc.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,6 +124,8 @@ // Returns true if the platform is in the niagara line (T series) // and newer than the niagara1. static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); } + + static bool is_M_series() { return is_M_family(_features); } static bool is_T4() { return is_T_family(_features) && has_cbcond(); } // Fujitsu SPARC64 diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/assembler_x86.cpp --- a/src/cpu/x86/vm/assembler_x86.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/assembler_x86.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -3496,6 +3496,33 @@ emit_byte(0x01); } +void Assembler::vinsertf128h(XMMRegister dst, Address src) { + assert(VM_Version::supports_avx(), ""); + InstructionMark im(this); + bool vector256 = true; + assert(dst != xnoreg, "sanity"); + int dst_enc = dst->encoding(); + // swap src<->dst for encoding + vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256); + emit_byte(0x18); + emit_operand(dst, src); + // 0x01 - insert into upper 128 bits + emit_byte(0x01); +} + +void Assembler::vextractf128h(Address dst, XMMRegister src) { + assert(VM_Version::supports_avx(), ""); + InstructionMark im(this); + bool vector256 = true; + assert(src != xnoreg, "sanity"); + int src_enc = src->encoding(); + vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256); + emit_byte(0x19); + emit_operand(src, dst); + // 0x01 - extract from upper 128 bits + emit_byte(0x01); +} + void Assembler::vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src) { assert(VM_Version::supports_avx2(), ""); bool vector256 = true; @@ -3507,6 +3534,33 @@ emit_byte(0x01); } +void Assembler::vinserti128h(XMMRegister dst, Address src) { + assert(VM_Version::supports_avx2(), ""); + InstructionMark im(this); + bool vector256 = true; + assert(dst != xnoreg, "sanity"); + int dst_enc = dst->encoding(); + // swap src<->dst for encoding + vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256); + emit_byte(0x38); + emit_operand(dst, src); + // 0x01 - insert into upper 128 bits + emit_byte(0x01); +} + +void Assembler::vextracti128h(Address dst, XMMRegister src) { + assert(VM_Version::supports_avx2(), ""); + InstructionMark im(this); + bool vector256 = true; + assert(src != xnoreg, "sanity"); + int src_enc = src->encoding(); + vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256); + emit_byte(0x39); + emit_operand(src, dst); + // 0x01 - extract from upper 128 bits + emit_byte(0x01); +} + void Assembler::vzeroupper() { assert(VM_Version::supports_avx(), ""); (void)vex_prefix_and_encode(xmm0, xmm0, xmm0, VEX_SIMD_NONE); @@ -8907,11 +8961,9 @@ pusha(); // if we are coming from c1, xmm registers may be live - if (UseSSE >= 1) { - subptr(rsp, sizeof(jdouble)* LP64_ONLY(16) NOT_LP64(8)); - } int off = 0; if (UseSSE == 1) { + subptr(rsp, sizeof(jdouble)*8); movflt(Address(rsp,off++*sizeof(jdouble)),xmm0); movflt(Address(rsp,off++*sizeof(jdouble)),xmm1); movflt(Address(rsp,off++*sizeof(jdouble)),xmm2); @@ -8921,23 +8973,50 @@ movflt(Address(rsp,off++*sizeof(jdouble)),xmm6); movflt(Address(rsp,off++*sizeof(jdouble)),xmm7); } else if (UseSSE >= 2) { - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm0); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm1); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm2); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm3); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm4); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm5); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm6); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm7); +#ifdef COMPILER2 + if (MaxVectorSize > 16) { + assert(UseAVX > 0, "256bit vectors are supported only with AVX"); + // Save upper half of YMM registes + subptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8)); + vextractf128h(Address(rsp, 0),xmm0); + vextractf128h(Address(rsp, 16),xmm1); + vextractf128h(Address(rsp, 32),xmm2); + vextractf128h(Address(rsp, 48),xmm3); + vextractf128h(Address(rsp, 64),xmm4); + vextractf128h(Address(rsp, 80),xmm5); + vextractf128h(Address(rsp, 96),xmm6); + vextractf128h(Address(rsp,112),xmm7); #ifdef _LP64 - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm8); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm9); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm10); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm11); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm12); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm13); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm14); - movdbl(Address(rsp,off++*sizeof(jdouble)),xmm15); + vextractf128h(Address(rsp,128),xmm8); + vextractf128h(Address(rsp,144),xmm9); + vextractf128h(Address(rsp,160),xmm10); + vextractf128h(Address(rsp,176),xmm11); + vextractf128h(Address(rsp,192),xmm12); + vextractf128h(Address(rsp,208),xmm13); + vextractf128h(Address(rsp,224),xmm14); + vextractf128h(Address(rsp,240),xmm15); +#endif + } +#endif + // Save whole 128bit (16 bytes) XMM regiters + subptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8)); + movdqu(Address(rsp,off++*16),xmm0); + movdqu(Address(rsp,off++*16),xmm1); + movdqu(Address(rsp,off++*16),xmm2); + movdqu(Address(rsp,off++*16),xmm3); + movdqu(Address(rsp,off++*16),xmm4); + movdqu(Address(rsp,off++*16),xmm5); + movdqu(Address(rsp,off++*16),xmm6); + movdqu(Address(rsp,off++*16),xmm7); +#ifdef _LP64 + movdqu(Address(rsp,off++*16),xmm8); + movdqu(Address(rsp,off++*16),xmm9); + movdqu(Address(rsp,off++*16),xmm10); + movdqu(Address(rsp,off++*16),xmm11); + movdqu(Address(rsp,off++*16),xmm12); + movdqu(Address(rsp,off++*16),xmm13); + movdqu(Address(rsp,off++*16),xmm14); + movdqu(Address(rsp,off++*16),xmm15); #endif } @@ -9015,28 +9094,52 @@ movflt(xmm5, Address(rsp,off++*sizeof(jdouble))); movflt(xmm6, Address(rsp,off++*sizeof(jdouble))); movflt(xmm7, Address(rsp,off++*sizeof(jdouble))); + addptr(rsp, sizeof(jdouble)*8); } else if (UseSSE >= 2) { - movdbl(xmm0, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm1, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm2, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm3, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm4, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm5, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm6, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm7, Address(rsp,off++*sizeof(jdouble))); + // Restore whole 128bit (16 bytes) XMM regiters + movdqu(xmm0, Address(rsp,off++*16)); + movdqu(xmm1, Address(rsp,off++*16)); + movdqu(xmm2, Address(rsp,off++*16)); + movdqu(xmm3, Address(rsp,off++*16)); + movdqu(xmm4, Address(rsp,off++*16)); + movdqu(xmm5, Address(rsp,off++*16)); + movdqu(xmm6, Address(rsp,off++*16)); + movdqu(xmm7, Address(rsp,off++*16)); #ifdef _LP64 - movdbl(xmm8, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm9, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm10, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm11, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm12, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm13, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm14, Address(rsp,off++*sizeof(jdouble))); - movdbl(xmm15, Address(rsp,off++*sizeof(jdouble))); + movdqu(xmm8, Address(rsp,off++*16)); + movdqu(xmm9, Address(rsp,off++*16)); + movdqu(xmm10, Address(rsp,off++*16)); + movdqu(xmm11, Address(rsp,off++*16)); + movdqu(xmm12, Address(rsp,off++*16)); + movdqu(xmm13, Address(rsp,off++*16)); + movdqu(xmm14, Address(rsp,off++*16)); + movdqu(xmm15, Address(rsp,off++*16)); #endif - } - if (UseSSE >= 1) { - addptr(rsp, sizeof(jdouble)* LP64_ONLY(16) NOT_LP64(8)); + addptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8)); +#ifdef COMPILER2 + if (MaxVectorSize > 16) { + // Restore upper half of YMM registes. + vinsertf128h(xmm0, Address(rsp, 0)); + vinsertf128h(xmm1, Address(rsp, 16)); + vinsertf128h(xmm2, Address(rsp, 32)); + vinsertf128h(xmm3, Address(rsp, 48)); + vinsertf128h(xmm4, Address(rsp, 64)); + vinsertf128h(xmm5, Address(rsp, 80)); + vinsertf128h(xmm6, Address(rsp, 96)); + vinsertf128h(xmm7, Address(rsp,112)); +#ifdef _LP64 + vinsertf128h(xmm8, Address(rsp,128)); + vinsertf128h(xmm9, Address(rsp,144)); + vinsertf128h(xmm10, Address(rsp,160)); + vinsertf128h(xmm11, Address(rsp,176)); + vinsertf128h(xmm12, Address(rsp,192)); + vinsertf128h(xmm13, Address(rsp,208)); + vinsertf128h(xmm14, Address(rsp,224)); + vinsertf128h(xmm15, Address(rsp,240)); +#endif + addptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8)); + } +#endif } popa(); } diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/assembler_x86.hpp --- a/src/cpu/x86/vm/assembler_x86.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/assembler_x86.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -1743,6 +1743,12 @@ void vinsertf128h(XMMRegister dst, XMMRegister nds, XMMRegister src); void vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src); + // Load/store high 128bit of YMM registers which does not destroy other half. + void vinsertf128h(XMMRegister dst, Address src); + void vinserti128h(XMMRegister dst, Address src); + void vextractf128h(Address dst, XMMRegister src); + void vextracti128h(Address dst, XMMRegister src); + // AVX instruction which is used to clear upper 128 bits of YMM registers and // to avoid transaction penalty between AVX and SSE states. There is no // penalty if legacy SSE instructions are encoded using VEX prefix because diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/c1_LIRAssembler_x86.cpp --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -3794,5 +3794,49 @@ // do nothing for now } +void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp) { + assert(data == dest, "xchg/xadd uses only 2 operands"); + + if (data->type() == T_INT) { + if (code == lir_xadd) { + if (os::is_MP()) { + __ lock(); + } + __ xaddl(as_Address(src->as_address_ptr()), data->as_register()); + } else { + __ xchgl(data->as_register(), as_Address(src->as_address_ptr())); + } + } else if (data->is_oop()) { + assert (code == lir_xchg, "xadd for oops"); + Register obj = data->as_register(); +#ifdef _LP64 + if (UseCompressedOops) { + __ encode_heap_oop(obj); + __ xchgl(obj, as_Address(src->as_address_ptr())); + __ decode_heap_oop(obj); + } else { + __ xchgptr(obj, as_Address(src->as_address_ptr())); + } +#else + __ xchgl(obj, as_Address(src->as_address_ptr())); +#endif + } else if (data->type() == T_LONG) { +#ifdef _LP64 + assert(data->as_register_lo() == data->as_register_hi(), "should be a single register"); + if (code == lir_xadd) { + if (os::is_MP()) { + __ lock(); + } + __ xaddq(as_Address(src->as_address_ptr()), data->as_register_lo()); + } else { + __ xchgq(data->as_register_lo(), as_Address(src->as_address_ptr())); + } +#else + ShouldNotReachHere(); +#endif + } else { + ShouldNotReachHere(); + } +} #undef __ diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/c1_LIRGenerator_x86.cpp --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -753,9 +753,24 @@ LIR_Opr addr = new_pointer_register(); LIR_Address* a; if(offset.result()->is_constant()) { +#ifdef _LP64 + jlong c = offset.result()->as_jlong(); + if ((jlong)((jint)c) == c) { + a = new LIR_Address(obj.result(), + (jint)c, + as_BasicType(type)); + } else { + LIR_Opr tmp = new_register(T_LONG); + __ move(offset.result(), tmp); + a = new LIR_Address(obj.result(), + tmp, + as_BasicType(type)); + } +#else a = new LIR_Address(obj.result(), - NOT_LP64(offset.result()->as_constant_ptr()->as_jint()) LP64_ONLY((int)offset.result()->as_constant_ptr()->as_jlong()), + offset.result()->as_jint(), as_BasicType(type)); +#endif } else { a = new LIR_Address(obj.result(), offset.result(), @@ -1345,3 +1360,57 @@ } } } + +void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { + BasicType type = x->basic_type(); + LIRItem src(x->object(), this); + LIRItem off(x->offset(), this); + LIRItem value(x->value(), this); + + src.load_item(); + value.load_item(); + off.load_nonconstant(); + + LIR_Opr dst = rlock_result(x, type); + LIR_Opr data = value.result(); + bool is_obj = (type == T_ARRAY || type == T_OBJECT); + LIR_Opr offset = off.result(); + + assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type"); + LIR_Address* addr; + if (offset->is_constant()) { +#ifdef _LP64 + jlong c = offset->as_jlong(); + if ((jlong)((jint)c) == c) { + addr = new LIR_Address(src.result(), (jint)c, type); + } else { + LIR_Opr tmp = new_register(T_LONG); + __ move(offset, tmp); + addr = new LIR_Address(src.result(), tmp, type); + } +#else + addr = new LIR_Address(src.result(), offset->as_jint(), type); +#endif + } else { + addr = new LIR_Address(src.result(), offset, type); + } + + if (data != dst) { + __ move(data, dst); + data = dst; + } + if (x->is_add()) { + __ xadd(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr); + } else { + if (is_obj) { + // Do the pre-write barrier, if any. + pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */, + true /* do_load */, false /* patch */, NULL); + } + __ xchg(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr); + if (is_obj) { + // Seems to be a precise address + post_barrier(LIR_OprFact::address(addr), data); + } + } +} diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/methodHandles_x86.cpp --- a/src/cpu/x86/vm/methodHandles_x86.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -327,10 +327,11 @@ assert_different_registers(temp3, rcx, rdx); } #endif + else { + assert_different_registers(temp1, temp2, temp3, saved_last_sp_register()); // don't trash lastSP + } assert_different_registers(temp1, temp2, temp3, receiver_reg); assert_different_registers(temp1, temp2, temp3, member_reg); - if (!for_compiler_entry) - assert_different_registers(temp1, temp2, temp3, saved_last_sp_register()); // don't trash lastSP if (iid == vmIntrinsics::_invokeBasic) { // indirect through MH.form.vmentry.vmtarget @@ -392,14 +393,13 @@ // rsi/r13 - interpreter linkage (if interpreted) // rcx, rdx, rsi, rdi, r8, r8 - compiler arguments (if compiled) - bool method_is_live = false; + Label L_incompatible_class_change_error; switch (iid) { case vmIntrinsics::_linkToSpecial: if (VerifyMethodHandles) { verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); } __ movptr(rbx_method, member_vmtarget); - method_is_live = true; break; case vmIntrinsics::_linkToStatic: @@ -407,7 +407,6 @@ verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); } __ movptr(rbx_method, member_vmtarget); - method_is_live = true; break; case vmIntrinsics::_linkToVirtual: @@ -436,7 +435,6 @@ // get target Method* & entry point __ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method); - method_is_live = true; break; } @@ -464,35 +462,32 @@ } // given intf, index, and recv klass, dispatch to the implementation method - Label L_no_such_interface; __ lookup_interface_method(temp1_recv_klass, temp3_intf, // note: next two args must be the same: rbx_index, rbx_method, temp2, - L_no_such_interface); - - __ verify_method_ptr(rbx_method); - jump_from_method_handle(_masm, rbx_method, temp2, for_compiler_entry); - __ hlt(); - - __ bind(L_no_such_interface); - __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); + L_incompatible_class_change_error); break; } default: - fatal(err_msg("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid))); + fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid))); break; } - if (method_is_live) { - // live at this point: rbx_method, rsi/r13 (if interpreted) + // Live at this point: + // rbx_method + // rsi/r13 (if interpreted) - // After figuring out which concrete method to call, jump into it. - // Note that this works in the interpreter with no data motion. - // But the compiled version will require that rcx_recv be shifted out. - __ verify_method_ptr(rbx_method); - jump_from_method_handle(_masm, rbx_method, temp1, for_compiler_entry); + // After figuring out which concrete method to call, jump into it. + // Note that this works in the interpreter with no data motion. + // But the compiled version will require that rcx_recv be shifted out. + __ verify_method_ptr(rbx_method); + jump_from_method_handle(_masm, rbx_method, temp1, for_compiler_entry); + + if (iid == vmIntrinsics::_linkToInterface) { + __ bind(L_incompatible_class_change_error); + __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); } } } diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -46,11 +46,11 @@ const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size; class RegisterSaver { - enum { FPU_regs_live = 8 /*for the FPU stack*/+8/*eight more for XMM registers*/ }; // Capture info about frame layout +#define DEF_XMM_OFFS(regnum) xmm ## regnum ## _off = xmm_off + (regnum)*16/BytesPerInt, xmm ## regnum ## H_off enum layout { fpu_state_off = 0, - fpu_state_end = fpu_state_off+FPUStateSizeInWords-1, + fpu_state_end = fpu_state_off+FPUStateSizeInWords, st0_off, st0H_off, st1_off, st1H_off, st2_off, st2H_off, @@ -59,16 +59,16 @@ st5_off, st5H_off, st6_off, st6H_off, st7_off, st7H_off, - - xmm0_off, xmm0H_off, - xmm1_off, xmm1H_off, - xmm2_off, xmm2H_off, - xmm3_off, xmm3H_off, - xmm4_off, xmm4H_off, - xmm5_off, xmm5H_off, - xmm6_off, xmm6H_off, - xmm7_off, xmm7H_off, - flags_off, + xmm_off, + DEF_XMM_OFFS(0), + DEF_XMM_OFFS(1), + DEF_XMM_OFFS(2), + DEF_XMM_OFFS(3), + DEF_XMM_OFFS(4), + DEF_XMM_OFFS(5), + DEF_XMM_OFFS(6), + DEF_XMM_OFFS(7), + flags_off = xmm7_off + 16/BytesPerInt + 1, // 16-byte stack alignment fill word rdi_off, rsi_off, ignore_off, // extra copy of rbp, @@ -83,13 +83,13 @@ rbp_off, return_off, // slot for return address reg_save_size }; - + enum { FPU_regs_live = flags_off - fpu_state_end }; public: static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, - int* total_frame_words, bool verify_fpu = true); - static void restore_live_registers(MacroAssembler* masm); + int* total_frame_words, bool verify_fpu = true, bool save_vectors = false); + static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false); static int rax_offset() { return rax_off; } static int rbx_offset() { return rbx_off; } @@ -113,9 +113,20 @@ }; OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, - int* total_frame_words, bool verify_fpu) { - - int frame_size_in_bytes = (reg_save_size + additional_frame_words) * wordSize; + int* total_frame_words, bool verify_fpu, bool save_vectors) { + int vect_words = 0; +#ifdef COMPILER2 + if (save_vectors) { + assert(UseAVX > 0, "256bit vectors are supported only with AVX"); + assert(MaxVectorSize == 32, "only 256bit vectors are supported now"); + // Save upper half of YMM registes + vect_words = 8 * 16 / wordSize; + additional_frame_words += vect_words; + } +#else + assert(!save_vectors, "vectors are generated only by C2"); +#endif + int frame_size_in_bytes = (reg_save_size + additional_frame_words) * wordSize; int frame_words = frame_size_in_bytes / wordSize; *total_frame_words = frame_words; @@ -129,7 +140,7 @@ __ enter(); __ pusha(); __ pushf(); - __ subptr(rsp,FPU_regs_live*sizeof(jdouble)); // Push FPU registers space + __ subptr(rsp,FPU_regs_live*wordSize); // Push FPU registers space __ push_FPU_state(); // Save FPU state & init if (verify_fpu) { @@ -183,14 +194,28 @@ __ movflt(Address(rsp,xmm6_off*wordSize),xmm6); __ movflt(Address(rsp,xmm7_off*wordSize),xmm7); } else if( UseSSE >= 2 ) { - __ movdbl(Address(rsp,xmm0_off*wordSize),xmm0); - __ movdbl(Address(rsp,xmm1_off*wordSize),xmm1); - __ movdbl(Address(rsp,xmm2_off*wordSize),xmm2); - __ movdbl(Address(rsp,xmm3_off*wordSize),xmm3); - __ movdbl(Address(rsp,xmm4_off*wordSize),xmm4); - __ movdbl(Address(rsp,xmm5_off*wordSize),xmm5); - __ movdbl(Address(rsp,xmm6_off*wordSize),xmm6); - __ movdbl(Address(rsp,xmm7_off*wordSize),xmm7); + // Save whole 128bit (16 bytes) XMM regiters + __ movdqu(Address(rsp,xmm0_off*wordSize),xmm0); + __ movdqu(Address(rsp,xmm1_off*wordSize),xmm1); + __ movdqu(Address(rsp,xmm2_off*wordSize),xmm2); + __ movdqu(Address(rsp,xmm3_off*wordSize),xmm3); + __ movdqu(Address(rsp,xmm4_off*wordSize),xmm4); + __ movdqu(Address(rsp,xmm5_off*wordSize),xmm5); + __ movdqu(Address(rsp,xmm6_off*wordSize),xmm6); + __ movdqu(Address(rsp,xmm7_off*wordSize),xmm7); + } + + if (vect_words > 0) { + assert(vect_words*wordSize == 128, ""); + __ subptr(rsp, 128); // Save upper half of YMM registes + __ vextractf128h(Address(rsp, 0),xmm0); + __ vextractf128h(Address(rsp, 16),xmm1); + __ vextractf128h(Address(rsp, 32),xmm2); + __ vextractf128h(Address(rsp, 48),xmm3); + __ vextractf128h(Address(rsp, 64),xmm4); + __ vextractf128h(Address(rsp, 80),xmm5); + __ vextractf128h(Address(rsp, 96),xmm6); + __ vextractf128h(Address(rsp,112),xmm7); } // Set an oopmap for the call site. This oopmap will map all @@ -253,10 +278,20 @@ } -void RegisterSaver::restore_live_registers(MacroAssembler* masm) { - +void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) { // Recover XMM & FPU state - if( UseSSE == 1 ) { + int additional_frame_bytes = 0; +#ifdef COMPILER2 + if (restore_vectors) { + assert(UseAVX > 0, "256bit vectors are supported only with AVX"); + assert(MaxVectorSize == 32, "only 256bit vectors are supported now"); + additional_frame_bytes = 128; + } +#else + assert(!restore_vectors, "vectors are generated only by C2"); +#endif + if (UseSSE == 1) { + assert(additional_frame_bytes == 0, ""); __ movflt(xmm0,Address(rsp,xmm0_off*wordSize)); __ movflt(xmm1,Address(rsp,xmm1_off*wordSize)); __ movflt(xmm2,Address(rsp,xmm2_off*wordSize)); @@ -265,18 +300,33 @@ __ movflt(xmm5,Address(rsp,xmm5_off*wordSize)); __ movflt(xmm6,Address(rsp,xmm6_off*wordSize)); __ movflt(xmm7,Address(rsp,xmm7_off*wordSize)); - } else if( UseSSE >= 2 ) { - __ movdbl(xmm0,Address(rsp,xmm0_off*wordSize)); - __ movdbl(xmm1,Address(rsp,xmm1_off*wordSize)); - __ movdbl(xmm2,Address(rsp,xmm2_off*wordSize)); - __ movdbl(xmm3,Address(rsp,xmm3_off*wordSize)); - __ movdbl(xmm4,Address(rsp,xmm4_off*wordSize)); - __ movdbl(xmm5,Address(rsp,xmm5_off*wordSize)); - __ movdbl(xmm6,Address(rsp,xmm6_off*wordSize)); - __ movdbl(xmm7,Address(rsp,xmm7_off*wordSize)); + } else if (UseSSE >= 2) { +#define STACK_ADDRESS(x) Address(rsp,(x)*wordSize + additional_frame_bytes) + __ movdqu(xmm0,STACK_ADDRESS(xmm0_off)); + __ movdqu(xmm1,STACK_ADDRESS(xmm1_off)); + __ movdqu(xmm2,STACK_ADDRESS(xmm2_off)); + __ movdqu(xmm3,STACK_ADDRESS(xmm3_off)); + __ movdqu(xmm4,STACK_ADDRESS(xmm4_off)); + __ movdqu(xmm5,STACK_ADDRESS(xmm5_off)); + __ movdqu(xmm6,STACK_ADDRESS(xmm6_off)); + __ movdqu(xmm7,STACK_ADDRESS(xmm7_off)); +#undef STACK_ADDRESS + } + if (restore_vectors) { + // Restore upper half of YMM registes. + assert(additional_frame_bytes == 128, ""); + __ vinsertf128h(xmm0, Address(rsp, 0)); + __ vinsertf128h(xmm1, Address(rsp, 16)); + __ vinsertf128h(xmm2, Address(rsp, 32)); + __ vinsertf128h(xmm3, Address(rsp, 48)); + __ vinsertf128h(xmm4, Address(rsp, 64)); + __ vinsertf128h(xmm5, Address(rsp, 80)); + __ vinsertf128h(xmm6, Address(rsp, 96)); + __ vinsertf128h(xmm7, Address(rsp,112)); + __ addptr(rsp, additional_frame_bytes); } __ pop_FPU_state(); - __ addptr(rsp, FPU_regs_live*sizeof(jdouble)); // Pop FPU registers + __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers __ popf(); __ popa(); @@ -308,6 +358,13 @@ __ addptr(rsp, return_off * wordSize); } +// Is vector's size (in bytes) bigger than a size saved by default? +// 16 bytes XMM registers are saved by default using SSE2 movdqu instructions. +// Note, MaxVectorSize == 0 with UseSSE < 2 and vectors are not generated. +bool SharedRuntime::is_wide_vector(int size) { + return size > 16; +} + // The java_calling_convention describes stack locations as ideal slots on // a frame with no abi restrictions. Since we must observe abi restrictions // (like the placement of the register window) the slots must be biased by @@ -1346,12 +1403,12 @@ } static void verify_oop_args(MacroAssembler* masm, - int total_args_passed, + methodHandle method, const BasicType* sig_bt, const VMRegPair* regs) { Register temp_reg = rbx; // not part of any compiled calling seq if (VerifyOops) { - for (int i = 0; i < total_args_passed; i++) { + for (int i = 0; i < method->size_of_parameters(); i++) { if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) { VMReg r = regs[i].first(); @@ -1368,35 +1425,32 @@ } static void gen_special_dispatch(MacroAssembler* masm, - int total_args_passed, - int comp_args_on_stack, - vmIntrinsics::ID special_dispatch, + methodHandle method, const BasicType* sig_bt, const VMRegPair* regs) { - verify_oop_args(masm, total_args_passed, sig_bt, regs); + verify_oop_args(masm, method, sig_bt, regs); + vmIntrinsics::ID iid = method->intrinsic_id(); // Now write the args into the outgoing interpreter space bool has_receiver = false; Register receiver_reg = noreg; int member_arg_pos = -1; Register member_reg = noreg; - int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(special_dispatch); + int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid); if (ref_kind != 0) { - member_arg_pos = total_args_passed - 1; // trailing MemberName argument + member_arg_pos = method->size_of_parameters() - 1; // trailing MemberName argument member_reg = rbx; // known to be free at this point has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); - } else if (special_dispatch == vmIntrinsics::_invokeBasic) { + } else if (iid == vmIntrinsics::_invokeBasic) { has_receiver = true; } else { - guarantee(false, err_msg("special_dispatch=%d", special_dispatch)); + fatal(err_msg_res("unexpected intrinsic id %d", iid)); } if (member_reg != noreg) { // Load the member_arg into register, if necessary. - assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob"); - assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object"); + SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs); VMReg r = regs[member_arg_pos].first(); - assert(r->is_valid(), "bad member arg"); if (r->is_stack()) { __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); } else { @@ -1407,7 +1461,7 @@ if (has_receiver) { // Make sure the receiver is loaded into a register. - assert(total_args_passed > 0, "oob"); + assert(method->size_of_parameters() > 0, "oob"); assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object"); VMReg r = regs[0].first(); assert(r->is_valid(), "bad receiver arg"); @@ -1415,7 +1469,7 @@ // Porting note: This assumes that compiled calling conventions always // pass the receiver oop in a register. If this is not true on some // platform, pick a temp and load the receiver from stack. - assert(false, "receiver always in a register"); + fatal("receiver always in a register"); receiver_reg = rcx; // known to be free at this point __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); } else { @@ -1425,7 +1479,7 @@ } // Figure out which address we are really jumping to: - MethodHandles::generate_method_handle_dispatch(masm, special_dispatch, + MethodHandles::generate_method_handle_dispatch(masm, iid, receiver_reg, member_reg, /*for_compiler_entry:*/ true); } @@ -1461,8 +1515,6 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, methodHandle method, int compile_id, - int total_in_args, - int comp_args_on_stack, BasicType* in_sig_bt, VMRegPair* in_regs, BasicType ret_type) { @@ -1471,9 +1523,7 @@ intptr_t start = (intptr_t)__ pc(); int vep_offset = ((intptr_t)__ pc()) - start; gen_special_dispatch(masm, - total_in_args, - comp_args_on_stack, - method->intrinsic_id(), + method, in_sig_bt, in_regs); int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period @@ -1506,6 +1556,7 @@ // we convert the java signature to a C signature by inserting // the hidden arguments as arg[0] and possibly arg[1] (static method) + const int total_in_args = method->size_of_parameters(); int total_c_args = total_in_args; if (!is_critical_native) { total_c_args += 1; @@ -2738,7 +2789,6 @@ return 0; } - //------------------------------generate_deopt_blob---------------------------- void SharedRuntime::generate_deopt_blob() { // allocate space for the code @@ -3276,7 +3326,7 @@ // setup oopmap, and calls safepoint code to stop the compiled code for // a safepoint. // -SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) { +SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) { // Account for thread arg in our frame const int additional_words = 1; @@ -3296,17 +3346,18 @@ const Register java_thread = rdi; // callee-saved for VC++ address start = __ pc(); address call_pc = NULL; - + bool cause_return = (poll_type == POLL_AT_RETURN); + bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP); // If cause_return is true we are at a poll_return and there is // the return address on the stack to the caller on the nmethod // that is safepoint. We can leave this return on the stack and // effectively complete the return and safepoint in the caller. // Otherwise we push space for a return address that the safepoint // handler will install later to make the stack walking sensible. - if( !cause_return ) - __ push(rbx); // Make room for return address (or push it again) - - map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false); + if (!cause_return) + __ push(rbx); // Make room for return address (or push it again) + + map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false, save_vectors); // The following is basically a call_VM. However, we need the precise // address of the call in order to generate an oopmap. Hence, we do all the @@ -3318,7 +3369,7 @@ __ set_last_Java_frame(java_thread, noreg, noreg, NULL); // if this was not a poll_return then we need to correct the return address now. - if( !cause_return ) { + if (!cause_return) { __ movptr(rax, Address(java_thread, JavaThread::saved_exception_pc_offset())); __ movptr(Address(rbp, wordSize), rax); } @@ -3346,15 +3397,14 @@ __ jcc(Assembler::equal, noException); // Exception pending - - RegisterSaver::restore_live_registers(masm); + RegisterSaver::restore_live_registers(masm, save_vectors); __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); __ bind(noException); // Normal exit, register restoring and exit - RegisterSaver::restore_live_registers(masm); + RegisterSaver::restore_live_registers(masm, save_vectors); __ ret(0); diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -116,8 +116,8 @@ }; public: - static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words); - static void restore_live_registers(MacroAssembler* masm); + static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors = false); + static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false); // Offsets into the register save area // Used by deoptimization when it is managing result register @@ -134,7 +134,19 @@ static void restore_result_registers(MacroAssembler* masm); }; -OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words) { +OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) { + int vect_words = 0; +#ifdef COMPILER2 + if (save_vectors) { + assert(UseAVX > 0, "256bit vectors are supported only with AVX"); + assert(MaxVectorSize == 32, "only 256bit vectors are supported now"); + // Save upper half of YMM registes + vect_words = 16 * 16 / wordSize; + additional_frame_words += vect_words; + } +#else + assert(!save_vectors, "vectors are generated only by C2"); +#endif // Always make the frame size 16-byte aligned int frame_size_in_bytes = round_to(additional_frame_words*wordSize + @@ -155,6 +167,27 @@ __ enter(); // rsp becomes 16-byte aligned here __ push_CPU_state(); // Push a multiple of 16 bytes + + if (vect_words > 0) { + assert(vect_words*wordSize == 256, ""); + __ subptr(rsp, 256); // Save upper half of YMM registes + __ vextractf128h(Address(rsp, 0),xmm0); + __ vextractf128h(Address(rsp, 16),xmm1); + __ vextractf128h(Address(rsp, 32),xmm2); + __ vextractf128h(Address(rsp, 48),xmm3); + __ vextractf128h(Address(rsp, 64),xmm4); + __ vextractf128h(Address(rsp, 80),xmm5); + __ vextractf128h(Address(rsp, 96),xmm6); + __ vextractf128h(Address(rsp,112),xmm7); + __ vextractf128h(Address(rsp,128),xmm8); + __ vextractf128h(Address(rsp,144),xmm9); + __ vextractf128h(Address(rsp,160),xmm10); + __ vextractf128h(Address(rsp,176),xmm11); + __ vextractf128h(Address(rsp,192),xmm12); + __ vextractf128h(Address(rsp,208),xmm13); + __ vextractf128h(Address(rsp,224),xmm14); + __ vextractf128h(Address(rsp,240),xmm15); + } if (frame::arg_reg_save_area_bytes != 0) { // Allocate argument register save area __ subptr(rsp, frame::arg_reg_save_area_bytes); @@ -167,112 +200,111 @@ OopMapSet *oop_maps = new OopMapSet(); OopMap* map = new OopMap(frame_size_in_slots, 0); - map->set_callee_saved(VMRegImpl::stack2reg( rax_off + additional_frame_slots), rax->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( rcx_off + additional_frame_slots), rcx->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( rdx_off + additional_frame_slots), rdx->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( rbx_off + additional_frame_slots), rbx->as_VMReg()); + +#define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_slots) + + map->set_callee_saved(STACK_OFFSET( rax_off ), rax->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( rcx_off ), rcx->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( rdx_off ), rdx->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( rbx_off ), rbx->as_VMReg()); // rbp location is known implicitly by the frame sender code, needs no oopmap // and the location where rbp was saved by is ignored - map->set_callee_saved(VMRegImpl::stack2reg( rsi_off + additional_frame_slots), rsi->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( rdi_off + additional_frame_slots), rdi->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( r8_off + additional_frame_slots), r8->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( r9_off + additional_frame_slots), r9->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( r10_off + additional_frame_slots), r10->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( r11_off + additional_frame_slots), r11->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( r12_off + additional_frame_slots), r12->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( r13_off + additional_frame_slots), r13->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( r14_off + additional_frame_slots), r14->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg( r15_off + additional_frame_slots), r15->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm0_off + additional_frame_slots), xmm0->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm1_off + additional_frame_slots), xmm1->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm2_off + additional_frame_slots), xmm2->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm3_off + additional_frame_slots), xmm3->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm4_off + additional_frame_slots), xmm4->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm5_off + additional_frame_slots), xmm5->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm6_off + additional_frame_slots), xmm6->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm7_off + additional_frame_slots), xmm7->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm8_off + additional_frame_slots), xmm8->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm9_off + additional_frame_slots), xmm9->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm10_off + additional_frame_slots), xmm10->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm11_off + additional_frame_slots), xmm11->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm12_off + additional_frame_slots), xmm12->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm13_off + additional_frame_slots), xmm13->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm14_off + additional_frame_slots), xmm14->as_VMReg()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm15_off + additional_frame_slots), xmm15->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( rsi_off ), rsi->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( rdi_off ), rdi->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( r8_off ), r8->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( r9_off ), r9->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( r10_off ), r10->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( r11_off ), r11->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( r12_off ), r12->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( r13_off ), r13->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( r14_off ), r14->as_VMReg()); + map->set_callee_saved(STACK_OFFSET( r15_off ), r15->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm0_off ), xmm0->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm1_off ), xmm1->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm2_off ), xmm2->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm3_off ), xmm3->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm4_off ), xmm4->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm5_off ), xmm5->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm6_off ), xmm6->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm7_off ), xmm7->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm8_off ), xmm8->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm9_off ), xmm9->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm10_off), xmm10->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm11_off), xmm11->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm12_off), xmm12->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm13_off), xmm13->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm14_off), xmm14->as_VMReg()); + map->set_callee_saved(STACK_OFFSET(xmm15_off), xmm15->as_VMReg()); // %%% These should all be a waste but we'll keep things as they were for now if (true) { - map->set_callee_saved(VMRegImpl::stack2reg( raxH_off + additional_frame_slots), - rax->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( rcxH_off + additional_frame_slots), - rcx->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( rdxH_off + additional_frame_slots), - rdx->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( rbxH_off + additional_frame_slots), - rbx->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( raxH_off ), rax->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( rcxH_off ), rcx->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( rdxH_off ), rdx->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( rbxH_off ), rbx->as_VMReg()->next()); // rbp location is known implicitly by the frame sender code, needs no oopmap - map->set_callee_saved(VMRegImpl::stack2reg( rsiH_off + additional_frame_slots), - rsi->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( rdiH_off + additional_frame_slots), - rdi->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( r8H_off + additional_frame_slots), - r8->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( r9H_off + additional_frame_slots), - r9->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( r10H_off + additional_frame_slots), - r10->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( r11H_off + additional_frame_slots), - r11->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( r12H_off + additional_frame_slots), - r12->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( r13H_off + additional_frame_slots), - r13->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( r14H_off + additional_frame_slots), - r14->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg( r15H_off + additional_frame_slots), - r15->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm0H_off + additional_frame_slots), - xmm0->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm1H_off + additional_frame_slots), - xmm1->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm2H_off + additional_frame_slots), - xmm2->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm3H_off + additional_frame_slots), - xmm3->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm4H_off + additional_frame_slots), - xmm4->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm5H_off + additional_frame_slots), - xmm5->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm6H_off + additional_frame_slots), - xmm6->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm7H_off + additional_frame_slots), - xmm7->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm8H_off + additional_frame_slots), - xmm8->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm9H_off + additional_frame_slots), - xmm9->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm10H_off + additional_frame_slots), - xmm10->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm11H_off + additional_frame_slots), - xmm11->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm12H_off + additional_frame_slots), - xmm12->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm13H_off + additional_frame_slots), - xmm13->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm14H_off + additional_frame_slots), - xmm14->as_VMReg()->next()); - map->set_callee_saved(VMRegImpl::stack2reg(xmm15H_off + additional_frame_slots), - xmm15->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( rsiH_off ), rsi->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( rdiH_off ), rdi->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( r8H_off ), r8->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( r9H_off ), r9->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( r10H_off ), r10->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( r11H_off ), r11->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( r12H_off ), r12->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( r13H_off ), r13->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( r14H_off ), r14->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET( r15H_off ), r15->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm0H_off ), xmm0->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm1H_off ), xmm1->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm2H_off ), xmm2->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm3H_off ), xmm3->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm4H_off ), xmm4->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm5H_off ), xmm5->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm6H_off ), xmm6->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm7H_off ), xmm7->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm8H_off ), xmm8->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm9H_off ), xmm9->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm10H_off), xmm10->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm11H_off), xmm11->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm12H_off), xmm12->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm13H_off), xmm13->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm14H_off), xmm14->as_VMReg()->next()); + map->set_callee_saved(STACK_OFFSET(xmm15H_off), xmm15->as_VMReg()->next()); } return map; } -void RegisterSaver::restore_live_registers(MacroAssembler* masm) { +void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) { if (frame::arg_reg_save_area_bytes != 0) { // Pop arg register save area __ addptr(rsp, frame::arg_reg_save_area_bytes); } +#ifdef COMPILER2 + if (restore_vectors) { + // Restore upper half of YMM registes. + assert(UseAVX > 0, "256bit vectors are supported only with AVX"); + assert(MaxVectorSize == 32, "only 256bit vectors are supported now"); + __ vinsertf128h(xmm0, Address(rsp, 0)); + __ vinsertf128h(xmm1, Address(rsp, 16)); + __ vinsertf128h(xmm2, Address(rsp, 32)); + __ vinsertf128h(xmm3, Address(rsp, 48)); + __ vinsertf128h(xmm4, Address(rsp, 64)); + __ vinsertf128h(xmm5, Address(rsp, 80)); + __ vinsertf128h(xmm6, Address(rsp, 96)); + __ vinsertf128h(xmm7, Address(rsp,112)); + __ vinsertf128h(xmm8, Address(rsp,128)); + __ vinsertf128h(xmm9, Address(rsp,144)); + __ vinsertf128h(xmm10, Address(rsp,160)); + __ vinsertf128h(xmm11, Address(rsp,176)); + __ vinsertf128h(xmm12, Address(rsp,192)); + __ vinsertf128h(xmm13, Address(rsp,208)); + __ vinsertf128h(xmm14, Address(rsp,224)); + __ vinsertf128h(xmm15, Address(rsp,240)); + __ addptr(rsp, 256); + } +#else + assert(!restore_vectors, "vectors are generated only by C2"); +#endif // Recover CPU state __ pop_CPU_state(); // Get the rbp described implicitly by the calling convention (no oopMap) @@ -297,6 +329,12 @@ __ addptr(rsp, return_offset_in_bytes()); } +// Is vector's size (in bytes) bigger than a size saved by default? +// 16 bytes XMM registers are saved by default using fxsave/fxrstor instructions. +bool SharedRuntime::is_wide_vector(int size) { + return size > 16; +} + // The java_calling_convention describes stack locations as ideal slots on // a frame with no abi restrictions. Since we must observe abi restrictions // (like the placement of the register window) the slots must be biased by @@ -1593,12 +1631,12 @@ }; static void verify_oop_args(MacroAssembler* masm, - int total_args_passed, + methodHandle method, const BasicType* sig_bt, const VMRegPair* regs) { Register temp_reg = rbx; // not part of any compiled calling seq if (VerifyOops) { - for (int i = 0; i < total_args_passed; i++) { + for (int i = 0; i < method->size_of_parameters(); i++) { if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) { VMReg r = regs[i].first(); @@ -1615,35 +1653,32 @@ } static void gen_special_dispatch(MacroAssembler* masm, - int total_args_passed, - int comp_args_on_stack, - vmIntrinsics::ID special_dispatch, + methodHandle method, const BasicType* sig_bt, const VMRegPair* regs) { - verify_oop_args(masm, total_args_passed, sig_bt, regs); + verify_oop_args(masm, method, sig_bt, regs); + vmIntrinsics::ID iid = method->intrinsic_id(); // Now write the args into the outgoing interpreter space bool has_receiver = false; Register receiver_reg = noreg; int member_arg_pos = -1; Register member_reg = noreg; - int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(special_dispatch); + int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid); if (ref_kind != 0) { - member_arg_pos = total_args_passed - 1; // trailing MemberName argument + member_arg_pos = method->size_of_parameters() - 1; // trailing MemberName argument member_reg = rbx; // known to be free at this point has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); - } else if (special_dispatch == vmIntrinsics::_invokeBasic) { + } else if (iid == vmIntrinsics::_invokeBasic) { has_receiver = true; } else { - guarantee(false, err_msg("special_dispatch=%d", special_dispatch)); + fatal(err_msg_res("unexpected intrinsic id %d", iid)); } if (member_reg != noreg) { // Load the member_arg into register, if necessary. - assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob"); - assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object"); + SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs); VMReg r = regs[member_arg_pos].first(); - assert(r->is_valid(), "bad member arg"); if (r->is_stack()) { __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); } else { @@ -1654,7 +1689,7 @@ if (has_receiver) { // Make sure the receiver is loaded into a register. - assert(total_args_passed > 0, "oob"); + assert(method->size_of_parameters() > 0, "oob"); assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object"); VMReg r = regs[0].first(); assert(r->is_valid(), "bad receiver arg"); @@ -1662,7 +1697,7 @@ // Porting note: This assumes that compiled calling conventions always // pass the receiver oop in a register. If this is not true on some // platform, pick a temp and load the receiver from stack. - assert(false, "receiver always in a register"); + fatal("receiver always in a register"); receiver_reg = j_rarg0; // known to be free at this point __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); } else { @@ -1672,7 +1707,7 @@ } // Figure out which address we are really jumping to: - MethodHandles::generate_method_handle_dispatch(masm, special_dispatch, + MethodHandles::generate_method_handle_dispatch(masm, iid, receiver_reg, member_reg, /*for_compiler_entry:*/ true); } @@ -1708,8 +1743,6 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, methodHandle method, int compile_id, - int total_in_args, - int comp_args_on_stack, BasicType* in_sig_bt, VMRegPair* in_regs, BasicType ret_type) { @@ -1718,9 +1751,7 @@ intptr_t start = (intptr_t)__ pc(); int vep_offset = ((intptr_t)__ pc()) - start; gen_special_dispatch(masm, - total_in_args, - comp_args_on_stack, - method->intrinsic_id(), + method, in_sig_bt, in_regs); int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period @@ -1754,6 +1785,7 @@ // we convert the java signature to a C signature by inserting // the hidden arguments as arg[0] and possibly arg[1] (static method) + const int total_in_args = method->size_of_parameters(); int total_c_args = total_in_args; if (!is_critical_native) { total_c_args += 1; @@ -3241,7 +3273,6 @@ return 0; } - //------------------------------generate_deopt_blob---------------------------- void SharedRuntime::generate_deopt_blob() { // Allocate space for the code @@ -3746,7 +3777,7 @@ // Generate a special Compile2Runtime blob that saves all registers, // and setup oopmap. // -SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) { +SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) { assert(StubRoutines::forward_exception_entry() != NULL, "must be generated before"); @@ -3761,6 +3792,8 @@ address start = __ pc(); address call_pc = NULL; int frame_size_in_words; + bool cause_return = (poll_type == POLL_AT_RETURN); + bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP); // Make room for return address (or push it again) if (!cause_return) { @@ -3768,7 +3801,7 @@ } // Save registers, fpu state, and flags - map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); + map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words, save_vectors); // The following is basically a call_VM. However, we need the precise // address of the call in order to generate an oopmap. Hence, we do all the @@ -3805,7 +3838,7 @@ // Exception pending - RegisterSaver::restore_live_registers(masm); + RegisterSaver::restore_live_registers(masm, save_vectors); __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); @@ -3813,7 +3846,7 @@ __ bind(noException); // Normal exit, restore registers and exit. - RegisterSaver::restore_live_registers(masm); + RegisterSaver::restore_live_registers(masm, save_vectors); __ ret(0); diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/vm_version_x86.cpp --- a/src/cpu/x86/vm/vm_version_x86.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/vm_version_x86.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -363,6 +363,11 @@ } _supports_cx8 = supports_cmpxchg8(); + // xchg and xadd instructions + _supports_atomic_getset4 = true; + _supports_atomic_getadd4 = true; + LP64_ONLY(_supports_atomic_getset8 = true); + LP64_ONLY(_supports_atomic_getadd8 = true); #ifdef _LP64 // OS should support SSE for x64 and hardware should support at least SSE2. @@ -562,10 +567,10 @@ AllocatePrefetchInstr = 3; } // On family 15h processors use XMM and UnalignedLoadStores for Array Copy - if( supports_sse2() && FLAG_IS_DEFAULT(UseXMMForArrayCopy) ) { + if (supports_sse2() && FLAG_IS_DEFAULT(UseXMMForArrayCopy)) { UseXMMForArrayCopy = true; } - if( FLAG_IS_DEFAULT(UseUnalignedLoadStores) && UseXMMForArrayCopy ) { + if (supports_sse2() && FLAG_IS_DEFAULT(UseUnalignedLoadStores)) { UseUnalignedLoadStores = true; } } @@ -612,16 +617,16 @@ MaxLoopPad = 11; } #endif // COMPILER2 - if( FLAG_IS_DEFAULT(UseXMMForArrayCopy) ) { + if (FLAG_IS_DEFAULT(UseXMMForArrayCopy)) { UseXMMForArrayCopy = true; // use SSE2 movq on new Intel cpus } - if( supports_sse4_2() && supports_ht() ) { // Newest Intel cpus - if( FLAG_IS_DEFAULT(UseUnalignedLoadStores) && UseXMMForArrayCopy ) { + if (supports_sse4_2() && supports_ht()) { // Newest Intel cpus + if (FLAG_IS_DEFAULT(UseUnalignedLoadStores)) { UseUnalignedLoadStores = true; // use movdqu on newest Intel cpus } } - if( supports_sse4_2() && UseSSE >= 4 ) { - if( FLAG_IS_DEFAULT(UseSSE42Intrinsics)) { + if (supports_sse4_2() && UseSSE >= 4) { + if (FLAG_IS_DEFAULT(UseSSE42Intrinsics)) { UseSSE42Intrinsics = true; } } @@ -638,6 +643,13 @@ FLAG_SET_DEFAULT(UsePopCountInstruction, false); } +#ifdef COMPILER2 + if (FLAG_IS_DEFAULT(AlignVector)) { + // Modern processors allow misaligned memory operations for vectors. + AlignVector = !UseUnalignedLoadStores; + } +#endif // COMPILER2 + assert(0 <= ReadPrefetchInstr && ReadPrefetchInstr <= 3, "invalid value"); assert(0 <= AllocatePrefetchInstr && AllocatePrefetchInstr <= 3, "invalid value"); diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/x86.ad --- a/src/cpu/x86/vm/x86.ad Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/x86.ad Fri Sep 28 10:16:29 2012 -0700 @@ -498,10 +498,18 @@ case Op_PopCountL: if (!UsePopCountInstruction) return false; + break; case Op_MulVI: if ((UseSSE < 4) && (UseAVX < 1)) // only with SSE4_1 or AVX return false; break; + case Op_CompareAndSwapL: +#ifdef _LP64 + case Op_CompareAndSwapP: +#endif + if (!VM_Version::supports_cx8()) + return false; + break; } return true; // Per default match rules are supported. diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/x86_32.ad --- a/src/cpu/x86/vm/x86_32.ad Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/x86_32.ad Fri Sep 28 10:16:29 2012 -0700 @@ -7762,6 +7762,7 @@ // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ + predicate(VM_Version::supports_cx8()); match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); effect(KILL cr, KILL oldval); format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" @@ -7798,6 +7799,47 @@ ins_pipe( pipe_cmpxchg ); %} +instruct xaddI_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{ + predicate(n->as_LoadStore()->result_not_used()); + match(Set dummy (GetAndAddI mem add)); + effect(KILL cr); + format %{ "ADDL [$mem],$add" %} + ins_encode %{ + if (os::is_MP()) { __ lock(); } + __ addl($mem$$Address, $add$$constant); + %} + ins_pipe( pipe_cmpxchg ); +%} + +instruct xaddI( memory mem, rRegI newval, eFlagsReg cr) %{ + match(Set newval (GetAndAddI mem newval)); + effect(KILL cr); + format %{ "XADDL [$mem],$newval" %} + ins_encode %{ + if (os::is_MP()) { __ lock(); } + __ xaddl($mem$$Address, $newval$$Register); + %} + ins_pipe( pipe_cmpxchg ); +%} + +instruct xchgI( memory mem, rRegI newval) %{ + match(Set newval (GetAndSetI mem newval)); + format %{ "XCHGL $newval,[$mem]" %} + ins_encode %{ + __ xchgl($newval$$Register, $mem$$Address); + %} + ins_pipe( pipe_cmpxchg ); +%} + +instruct xchgP( memory mem, pRegP newval) %{ + match(Set newval (GetAndSetP mem newval)); + format %{ "XCHGL $newval,[$mem]" %} + ins_encode %{ + __ xchgl($newval$$Register, $mem$$Address); + %} + ins_pipe( pipe_cmpxchg ); +%} + //----------Subtraction Instructions------------------------------------------- // Integer Subtraction Instructions instruct subI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{ diff -r 15fba4382765 -r f2e12eb74117 src/cpu/x86/vm/x86_64.ad --- a/src/cpu/x86/vm/x86_64.ad Fri Sep 28 14:14:25 2012 +0200 +++ b/src/cpu/x86/vm/x86_64.ad Fri Sep 28 10:16:29 2012 -0700 @@ -7242,6 +7242,7 @@ rax_RegP oldval, rRegP newval, rFlagsReg cr) %{ + predicate(VM_Version::supports_cx8()); match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); effect(KILL cr, KILL oldval); @@ -7265,6 +7266,7 @@ rax_RegL oldval, rRegL newval, rFlagsReg cr) %{ + predicate(VM_Version::supports_cx8()); match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); effect(KILL cr, KILL oldval); @@ -7329,6 +7331,88 @@ ins_pipe( pipe_cmpxchg ); %} +instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ + predicate(n->as_LoadStore()->result_not_used()); + match(Set dummy (GetAndAddI mem add)); + effect(KILL cr); + format %{ "ADDL [$mem],$add" %} + ins_encode %{ + if (os::is_MP()) { __ lock(); } + __ addl($mem$$Address, $add$$constant); + %} + ins_pipe( pipe_cmpxchg ); +%} + +instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ + match(Set newval (GetAndAddI mem newval)); + effect(KILL cr); + format %{ "XADDL [$mem],$newval" %} + ins_encode %{ + if (os::is_MP()) { __ lock(); } + __ xaddl($mem$$Address, $newval$$Register); + %} + ins_pipe( pipe_cmpxchg ); +%} + +instruct xaddL_no_res( memory mem, Universe dummy, immL add, rFlagsReg cr) %{ + predicate(n->as_LoadStore()->result_not_used()); + match(Set dummy (GetAndAddL mem add)); + effect(KILL cr); + format %{ "ADDQ [$mem],$add" %} + ins_encode %{ + if (os::is_MP()) { __ lock(); } + __ addq($mem$$Address, $add$$constant); + %} + ins_pipe( pipe_cmpxchg ); +%} + +instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ + match(Set newval (GetAndAddL mem newval)); + effect(KILL cr); + format %{ "XADDQ [$mem],$newval" %} + ins_encode %{ + if (os::is_MP()) { __ lock(); } + __ xaddq($mem$$Address, $newval$$Register); + %} + ins_pipe( pipe_cmpxchg ); +%} + +instruct xchgI( memory mem, rRegI newval) %{ + match(Set newval (GetAndSetI mem newval)); + format %{ "XCHGL $newval,[$mem]" %} + ins_encode %{ + __ xchgl($newval$$Register, $mem$$Address); + %} + ins_pipe( pipe_cmpxchg ); +%} + +instruct xchgL( memory mem, rRegL newval) %{ + match(Set newval (GetAndSetL mem newval)); + format %{ "XCHGL $newval,[$mem]" %} + ins_encode %{ + __ xchgq($newval$$Register, $mem$$Address); + %} + ins_pipe( pipe_cmpxchg ); +%} + +instruct xchgP( memory mem, rRegP newval) %{ + match(Set newval (GetAndSetP mem newval)); + format %{ "XCHGQ $newval,[$mem]" %} + ins_encode %{ + __ xchgq($newval$$Register, $mem$$Address); + %} + ins_pipe( pipe_cmpxchg ); +%} + +instruct xchgN( memory mem, rRegN newval) %{ + match(Set newval (GetAndSetN mem newval)); + format %{ "XCHGL $newval,$mem]" %} + ins_encode %{ + __ xchgl($newval$$Register, $mem$$Address); + %} + ins_pipe( pipe_cmpxchg ); +%} + //----------Subtraction Instructions------------------------------------------- // Integer Subtraction Instructions diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/BuildConfig.java --- a/src/share/tools/ProjectCreator/BuildConfig.java Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/tools/ProjectCreator/BuildConfig.java Fri Sep 28 10:16:29 2012 -0700 @@ -22,15 +22,14 @@ * */ -import java.io.File; import java.util.Enumeration; import java.util.Hashtable; -import java.util.Iterator; import java.util.Vector; class BuildConfig { + @SuppressWarnings("rawtypes") Hashtable vars; - Vector basicNames, basicPaths; + Vector basicNames, basicPaths; String[] context; static CompilerInterface ci; @@ -47,6 +46,7 @@ return ci; } + @SuppressWarnings("rawtypes") protected void initNames(String flavour, String build, String outDll) { if (vars == null) vars = new Hashtable(); @@ -63,26 +63,28 @@ // ones mentioned above were needed to expand format String buildBase = expandFormat(getFieldString(null, "BuildBase")); String sourceBase = getFieldString(null, "SourceBase"); + String buildSpace = getFieldString(null, "BuildSpace"); String outDir = buildBase; put("Id", flavourBuild); put("OutputDir", outDir); put("SourceBase", sourceBase); put("BuildBase", buildBase); + put("BuildSpace", buildSpace); put("OutputDll", outDir + Util.sep + outDll); context = new String [] {flavourBuild, flavour, build, null}; } - protected void init(Vector includes, Vector defines) { + protected void init(Vector includes, Vector defines) { initDefaultDefines(defines); initDefaultCompilerFlags(includes); initDefaultLinkerFlags(); - handleDB(); + //handleDB(); } - protected void initDefaultCompilerFlags(Vector includes) { + protected void initDefaultCompilerFlags(Vector includes) { Vector compilerFlags = new Vector(); compilerFlags.addAll(getCI().getBaseCompilerFlags(getV("Define"), @@ -100,143 +102,48 @@ put("LinkerFlags", linkerFlags); } - DirectoryTree getSourceTree(String sourceBase, String startAt) { - DirectoryTree tree = new DirectoryTree(); - - tree.addSubdirToIgnore("Codemgr_wsdata"); - tree.addSubdirToIgnore("deleted_files"); - tree.addSubdirToIgnore("SCCS"); - tree.setVerbose(true); - if (startAt != null) { - tree.readDirectory(sourceBase + File.separator + startAt); - } else { - tree.readDirectory(sourceBase); - } - - return tree; - } - - - Vector getPreferredPaths() { - Vector preferredPaths = new Vector(); - - // In the case of multiple files with the same name in - // different subdirectories, prefer these versions - preferredPaths.add("windows"); - preferredPaths.add("x86"); - preferredPaths.add("closed"); - - // Also prefer "opto" over "adlc" for adlcVMDeps.hpp - preferredPaths.add("opto"); - - return preferredPaths; - } - - - void handleDB() { - WinGammaPlatform platform = (WinGammaPlatform)getField(null, "PlatformObject"); - - putSpecificField("AllFilesHash", computeAllFiles(platform)); - } - - - private boolean matchesIgnoredPath(String prefixedName) { - Vector rv = new Vector(); + public boolean matchesIgnoredPath(String path) { + Vector rv = new Vector(); collectRelevantVectors(rv, "IgnorePath"); - for (Iterator i = rv.iterator(); i.hasNext(); ) { - String pathPart = (String) i.next(); - if (prefixedName.contains(Util.normalize(pathPart))) { + for (String pathPart : rv) { + if (path.contains(pathPart)) { return true; } } return false; } - void addAll(Iterator i, Hashtable hash, - WinGammaPlatform platform, DirectoryTree tree, - Vector preferredPaths, Vector filesNotFound, Vector filesDuplicate) { - for (; i.hasNext(); ) { - String fileName = (String) i.next(); - if (lookupHashFieldInContext("IgnoreFile", fileName) == null) { - String prefixedName = platform.envVarPrefixedFileName(fileName, - 0, /* ignored */ - tree, - preferredPaths, - filesNotFound, - filesDuplicate); - if (prefixedName != null) { - prefixedName = Util.normalize(prefixedName); - if (!matchesIgnoredPath(prefixedName)) { - addTo(hash, prefixedName, fileName); - } + public boolean matchesHidePath(String path) { + Vector rv = new Vector(); + collectRelevantVectors(rv, "HidePath"); + for (String pathPart : rv) { + if (path.contains(Util.normalize(pathPart))) { + return true; + } + } + return false; + } + + public Vector matchesAdditionalGeneratedPath(String fullPath) { + Vector rv = new Vector(); + Hashtable v = (Hashtable)BuildConfig.getField(this.toString(), "AdditionalGeneratedFile"); + if (v != null) { + for (Enumeration e=v.keys(); e.hasMoreElements(); ) { + String key = e.nextElement(); + String val = v.get(key); + + if (fullPath.endsWith(expandFormat(key))) { + rv.add(expandFormat(val)); } } } + return rv; } void addTo(Hashtable ht, String key, String value) { ht.put(expandFormat(key), expandFormat(value)); } - Hashtable computeAllFiles(WinGammaPlatform platform) { - Hashtable rv = new Hashtable(); - DirectoryTree tree = getSourceTree(get("SourceBase"), getFieldString(null, "StartAt")); - Vector preferredPaths = getPreferredPaths(); - - // Hold errors until end - Vector filesNotFound = new Vector(); - Vector filesDuplicate = new Vector(); - - Vector includedFiles = new Vector(); - - // find all files - Vector dirs = getSourceIncludes(); - for (Iterator i = dirs.iterator(); i.hasNext(); ) { - String dir = (String)i.next(); - DirectoryTree subtree = getSourceTree(dir, null); - for (Iterator fi = subtree.getFileIterator(); fi.hasNext(); ) { - String name = ((File)fi.next()).getName(); - includedFiles.add(name); - } - } - addAll(includedFiles.iterator(), rv, - platform, tree, - preferredPaths, filesNotFound, filesDuplicate); - - Vector addFiles = new Vector(); - collectRelevantVectors(addFiles, "AdditionalFile"); - addAll(addFiles.iterator(), rv, - platform, tree, - preferredPaths, filesNotFound, filesDuplicate); - - collectRelevantHashes(rv, "AdditionalGeneratedFile"); - - if ((filesNotFound.size() != 0) || - (filesDuplicate.size() != 0)) { - System.err.println("Error: some files were not found or " + - "appeared in multiple subdirectories of " + - "directory " + get("SourceBase") + " and could not " + - "be resolved with os_family and arch."); - if (filesNotFound.size() != 0) { - System.err.println("Files not found:"); - for (Iterator iter = filesNotFound.iterator(); - iter.hasNext(); ) { - System.err.println(" " + (String) iter.next()); - } - } - if (filesDuplicate.size() != 0) { - System.err.println("Duplicate files:"); - for (Iterator iter = filesDuplicate.iterator(); - iter.hasNext(); ) { - System.err.println(" " + (String) iter.next()); - } - } - throw new RuntimeException(); - } - - return rv; - } - void initDefaultDefines(Vector defines) { Vector sysDefines = new Vector(); sysDefines.add("WIN32"); @@ -324,20 +231,19 @@ } void collectRelevantVectors(Vector rv, String field) { - for (int i = 0; i < context.length; i++) { - Vector v = getFieldVector(context[i], field); + for (String ctx : context) { + Vector v = getFieldVector(ctx, field); if (v != null) { - for (Iterator j=v.iterator(); j.hasNext(); ) { - String val = (String)j.next(); - rv.add(expandFormat(val)); + for (String val : v) { + rv.add(expandFormat(val).replace('/', '\\')); } } } } void collectRelevantHashes(Hashtable rv, String field) { - for (int i = 0; i < context.length; i++) { - Hashtable v = (Hashtable)getField(context[i], field); + for (String ctx : context) { + Hashtable v = (Hashtable)getField(ctx, field); if (v != null) { for (Enumeration e=v.keys(); e.hasMoreElements(); ) { String key = (String)e.nextElement(); @@ -357,21 +263,17 @@ Vector getIncludes() { Vector rv = new Vector(); - collectRelevantVectors(rv, "AbsoluteInclude"); - rv.addAll(getSourceIncludes()); - return rv; } private Vector getSourceIncludes() { - Vector rv = new Vector(); - Vector ri = new Vector(); + Vector rv = new Vector(); + Vector ri = new Vector(); String sourceBase = getFieldString(null, "SourceBase"); collectRelevantVectors(ri, "RelativeInclude"); - for (Iterator i = ri.iterator(); i.hasNext(); ) { - String f = (String)i.next(); + for (String f : ri) { rv.add(sourceBase + Util.sep + f); } return rv; @@ -604,7 +506,6 @@ } } - abstract class ProductConfig extends BuildConfig { protected void init(Vector includes, Vector defines) { defines.add("NDEBUG"); @@ -638,7 +539,6 @@ } } - class CoreDebugConfig extends GenericDebugNonKernelConfig { String getOptFlag() { return getCI().getNoOptFlag(); @@ -650,7 +550,6 @@ } } - class CoreFastDebugConfig extends GenericDebugNonKernelConfig { String getOptFlag() { return getCI().getOptFlag(); @@ -662,7 +561,6 @@ } } - class CoreProductConfig extends ProductConfig { CoreProductConfig() { initNames("core", "product", "jvm.dll"); @@ -700,6 +598,7 @@ init(getIncludes(), getDefines()); } } + abstract class CompilerInterface { abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir); abstract Vector getBaseLinkerFlags(String outDir, String outDll, String platformName); diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/DirectoryTree.java --- a/src/share/tools/ProjectCreator/DirectoryTree.java Fri Sep 28 14:14:25 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,287 +0,0 @@ -/* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -/** Encapsulates a notion of a directory tree. Designed to allow fast - querying of full paths for unique filenames in the hierarchy. */ - -import java.io.*; -import java.util.*; - -public class DirectoryTree { - - /** The root of the read directoryTree */ - private Node rootNode; - - /** Subdirs to ignore; Vector of Strings */ - private Vector subdirsToIgnore; - - /** This maps file names to Lists of nodes. */ - private Hashtable nameToNodeListTable; - - /** Output "."'s as directories are read. Defaults to false. */ - private boolean verbose; - - public DirectoryTree() { - subdirsToIgnore = new Vector(); - verbose = false; - } - - public void addSubdirToIgnore(String subdir) { - subdirsToIgnore.add(subdir); - } - - private class FileIterator implements Iterator { - private Vector nodes = new Vector(); - - public FileIterator(Node rootNode) { - if(rootNode == null) { - return; - } - nodes.add(rootNode); - prune(); - } - public boolean hasNext() { - return nodes.size() > 0; - } - public Object next() { - Node last = (Node)nodes.remove(nodes.size() - 1); - prune(); - return new File(last.getName()); - } - - public void remove() { - throw new RuntimeException(); - } - - private void prune() { - while (nodes.size() > 0) { - Node last = (Node)nodes.get(nodes.size() - 1); - - if (last.isDirectory()) { - nodes.remove(nodes.size() - 1); - nodes.addAll(last.children); - } else { - // Is at file - return; - } - } - } - } - - public Iterator getFileIterator() { - return new FileIterator(rootNode); - } - - /** Output "."'s to System.out as directories are read. Defaults - to false. */ - public void setVerbose(boolean newValue) { - verbose = newValue; - } - - public boolean getVerbose() { - return verbose; - } - - public String getRootNodeName() { - return rootNode.getName(); - } - - /** Takes an absolute path to the root directory of this - DirectoryTree. Throws IllegalArgumentException if the given - string represents a plain file or nonexistent directory. */ - - public void readDirectory(String baseDirectory) - throws IllegalArgumentException { - File root = new File(Util.normalize(baseDirectory)); - if (!root.isDirectory()) { - return; - } - try { - root = root.getCanonicalFile(); - } - catch (IOException e) { - throw new RuntimeException(e.toString()); - } - rootNode = new Node(root); - readDirectory(rootNode, root); - } - - /** Queries the DirectoryTree for a file or directory name. Takes - only the name of the file or directory itself (i.e., no parent - directory information should be in the passed name). Returns a - List of DirectoryTreeNodes specifying the full paths of all of - the files or directories of this name in the DirectoryTree. - Returns null if the directory tree has not been read from disk - yet or if the file was not found in the tree. */ - public List findFile(String name) { - if (rootNode == null) { - return null; - } - - if (nameToNodeListTable == null) { - nameToNodeListTable = new Hashtable(); - try { - buildNameToNodeListTable(rootNode); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - - return (List) nameToNodeListTable.get(name); - } - - private void buildNameToNodeListTable(Node curNode) - throws IOException { - String fullName = curNode.getName(); - String parent = curNode.getParent(); - String separator = System.getProperty("file.separator"); - - if (parent != null) { - if (!fullName.startsWith(parent)) { - throw new RuntimeException( - "Internal error: parent of file name \"" + fullName + - "\" does not match file name \"" + parent + "\"" - ); - } - - int len = parent.length(); - if (!parent.endsWith(separator)) { - len += separator.length(); - } - - String fileName = fullName.substring(len); - - if (fileName == null) { - throw new RuntimeException( - "Internal error: file name was empty" - ); - } - - List nodeList = (List) nameToNodeListTable.get(fileName); - if (nodeList == null) { - nodeList = new Vector(); - nameToNodeListTable.put(fileName, nodeList); - } - - nodeList.add(curNode); - } else { - if (curNode != rootNode) { - throw new RuntimeException( - "Internal error: parent of file + \"" + fullName + "\"" + - " was null" - ); - } - } - - if (curNode.isDirectory()) { - Iterator iter = curNode.getChildren(); - if (iter != null) { - while (iter.hasNext()) { - buildNameToNodeListTable((Node) iter.next()); - } - } - } - } - - /** Reads all of the files in the given directory and adds them as - children of the directory tree node. Requires that the passed - node represents a directory. */ - - private void readDirectory(Node parentNode, File parentDir) { - File[] children = parentDir.listFiles(); - if (children == null) - return; - if (verbose) { - System.out.print("."); - System.out.flush(); - } - for (int i = 0; i < children.length; i++) { - File child = children[i]; - children[i] = null; - boolean isDir = child.isDirectory(); - boolean mustSkip = false; - if (isDir) { - for (Iterator iter = subdirsToIgnore.iterator(); - iter.hasNext(); ) { - if (child.getName().equals((String) iter.next())) { - mustSkip = true; - break; - } - } - } - if (!mustSkip) { - Node childNode = new Node(child); - parentNode.addChild(childNode); - if (isDir) { - readDirectory(childNode, child); - } - } - } - } - - private class Node implements DirectoryTreeNode { - private File file; - private Vector children; - - /** file must be a canonical file */ - Node(File file) { - this.file = file; - children = new Vector(); - } - - public boolean isFile() { - return file.isFile(); - } - - public boolean isDirectory() { - return file.isDirectory(); - } - - public String getName() { - return file.getPath(); - } - - public String getParent() { - return file.getParent(); - } - - public void addChild(Node n) { - children.add(n); - } - - public Iterator getChildren() throws IllegalArgumentException { - return children.iterator(); - } - - public int getNumChildren() throws IllegalArgumentException { - return children.size(); - } - - public DirectoryTreeNode getChild(int i) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - return (DirectoryTreeNode) children.get(i); - } - } -} diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/DirectoryTreeNode.java --- a/src/share/tools/ProjectCreator/DirectoryTreeNode.java Fri Sep 28 14:14:25 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -import java.util.*; - -public interface DirectoryTreeNode { - public boolean isFile(); - public boolean isDirectory(); - public String getName(); - public String getParent(); - public Iterator getChildren() throws IllegalArgumentException; - public int getNumChildren() throws IllegalArgumentException; - public DirectoryTreeNode getChild(int i) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException; -} diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/FileFormatException.java --- a/src/share/tools/ProjectCreator/FileFormatException.java Fri Sep 28 14:14:25 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -@SuppressWarnings("serial") -public class FileFormatException extends Exception { - - public FileFormatException() { - super(); - } - - public FileFormatException(String s) { - super(s); - } -} diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/FileTreeCreator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/ProjectCreator/FileTreeCreator.java Fri Sep 28 10:16:29 2012 -0700 @@ -0,0 +1,72 @@ +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.util.HashSet; +import java.util.Stack; +import java.util.Vector; + +public class FileTreeCreator extends SimpleFileVisitor +{ + Path vcProjLocation; + Path startDir; + final int startDirLength; + Stack attributes = new Stack(); + Vector allConfigs; + WinGammaPlatformVC10 wg; + + public FileTreeCreator(Path startDir, Vector allConfigs, WinGammaPlatformVC10 wg) { + super(); + this.wg = wg; + this.allConfigs = allConfigs; + this.startDir = startDir; + startDirLength = startDir.toAbsolutePath().toString().length(); + vcProjLocation = FileSystems.getDefault().getPath(allConfigs.firstElement().get("BuildSpace")); + attributes.push(new DirAttributes()); + } + + public class DirAttributes { + + private HashSet ignores; + private HashSet disablePch; + + public DirAttributes() { + ignores = new HashSet(); + disablePch = new HashSet(); + } + + public DirAttributes(HashSet excludes2, HashSet disablePch2) { + ignores = excludes2; + disablePch = disablePch2; + } + + @SuppressWarnings("unchecked") + public DirAttributes clone() { + return new DirAttributes((HashSet)this.ignores.clone(), (HashSet)this.disablePch.clone()); + } + + public void setIgnore(BuildConfig conf) { + ignores.add(conf); + } + + public boolean hasIgnore(BuildConfig cfg) { + return ignores.contains(cfg); + } + + public void removeFromIgnored(BuildConfig cfg) { + ignores.remove(cfg); + } + + public void setDisablePch(BuildConfig conf) { + disablePch.add(conf); + } + + public boolean hasDisablePch(BuildConfig cfg) { + return disablePch.contains(cfg); + } + + public void removeFromDisablePch(BuildConfig cfg) { + disablePch.remove(cfg); + } + + } +} diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/FileTreeCreatorVC10.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java Fri Sep 28 10:16:29 2012 -0700 @@ -0,0 +1,142 @@ +import static java.nio.file.FileVisitResult.CONTINUE; + +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Stack; +import java.util.Vector; + +public class FileTreeCreatorVC10 extends FileTreeCreator { + + public FileTreeCreatorVC10(Path startDir, Vector allConfigs, WinGammaPlatformVC10 wg) { + super(startDir, allConfigs, wg); + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attr) { + DirAttributes currentFileAttr = attributes.peek().clone(); + boolean usePch = false; + boolean disablePch = false; + boolean useIgnore = false; + String fileName = file.getFileName().toString(); + + // TODO hideFile + + // usePch applies to all configs for a file. + if (fileName.equals(BuildConfig.getFieldString(null, "UseToGeneratePch"))) { + usePch = true; + } + + for (BuildConfig cfg : allConfigs) { + if (cfg.lookupHashFieldInContext("IgnoreFile", fileName) != null) { + useIgnore = true; + currentFileAttr.setIgnore(cfg); + } else if (cfg.matchesIgnoredPath(file.toAbsolutePath().toString())) { + useIgnore = true; + currentFileAttr.setIgnore(cfg); + } + + if (cfg.lookupHashFieldInContext("DisablePch", fileName) != null) { + disablePch = true; + currentFileAttr.setDisablePch(cfg); + } + + Vector rv = new Vector(); + cfg.collectRelevantVectors(rv, "AdditionalFile"); + for(String addFile : rv) { + if (addFile.equals(fileName)) { + // supress any ignore + // TODO - may need some adjustments + if (file.toAbsolutePath().toString().contains(cfg.get("Flavour"))) { + currentFileAttr.removeFromIgnored(cfg); + } + } + } + } + + String tagName = wg.getFileTagFromSuffix(fileName); + String fileLoc = vcProjLocation.relativize(file).toString(); + + if (!useIgnore && !disablePch && !usePch) { + wg.tag(tagName, new String[] { "Include", fileLoc}); + } else { + wg.startTag( + tagName, + new String[] { "Include", fileLoc}); + + for (BuildConfig cfg : allConfigs) { + boolean ignore = currentFileAttr.hasIgnore(cfg); + if (ignore) { + wg.tagData("ExcludedFromBuild", "true", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'"); + } + if (usePch) { + wg.tagData("PrecompiledHeader", "Create", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'"); + } + if (disablePch) { + wg.tag("PrecompiledHeader", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'"); + } + } + wg.endTag(); + } + + String filter = startDir.relativize(file.getParent().toAbsolutePath()).toString(); + wg.addFilterDependency(fileLoc, filter); + + return CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs) + throws IOException { + Boolean hide = false; + // TODO remove attrs, if path is matched in this dir, then it is too in every subdir. + // And we will check anyway + DirAttributes newAttr = attributes.peek().clone(); + + // check per config ignorePaths! + for (BuildConfig cfg : allConfigs) { + if (cfg.matchesIgnoredPath(path.toAbsolutePath().toString())) { + newAttr.setIgnore(cfg); + } + + // Hide is always on all configs. And additional files are never hiddden + if (cfg.matchesHidePath(path.toAbsolutePath().toString())) { + hide = true; + break; + } + } + + if (!hide) { + String name = startDir.relativize(path.toAbsolutePath()).toString(); + if (!"".equals(name)) { + wg.addFilter(name); + } + + attributes.push(newAttr); + return super.preVisitDirectory(path, attrs); + } else { + return FileVisitResult.SKIP_SUBTREE; + } + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { + //end matching attributes set by ignorepath + attributes.pop(); + return CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + return CONTINUE; + } + + public void writeFileTree() throws IOException { + Files.walkFileTree(this.startDir, this); + } + + + } \ No newline at end of file diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/FileTreeCreatorVC7.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java Fri Sep 28 10:16:29 2012 -0700 @@ -0,0 +1,156 @@ +import static java.nio.file.FileVisitResult.CONTINUE; + +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Stack; +import java.util.Vector; + +public class FileTreeCreatorVC7 extends FileTreeCreator { + + public FileTreeCreatorVC7(Path startDir, Vector allConfigs, WinGammaPlatform wg) { + super(startDir, allConfigs, null); + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attr) { + DirAttributes currentFileAttr = attributes.peek().clone(); + boolean usePch = false; + boolean disablePch = false; + boolean useIgnore = false; + String fileName = file.getFileName().toString(); + + // usePch applies to all configs for a file. + if (fileName.equals(BuildConfig.getFieldString(null, "UseToGeneratePch"))) { + usePch = true; + } + + for (BuildConfig cfg : allConfigs) { + if (cfg.lookupHashFieldInContext("IgnoreFile", fileName) != null) { + useIgnore = true; + currentFileAttr.setIgnore(cfg); + } else if (cfg.matchesIgnoredPath(file.toAbsolutePath().toString())) { + useIgnore = true; + currentFileAttr.setIgnore(cfg); + } + + if (cfg.lookupHashFieldInContext("DisablePch", fileName) != null) { + disablePch = true; + currentFileAttr.setDisablePch(cfg); + } + + Vector rv = new Vector(); + cfg.collectRelevantVectors(rv, "AdditionalFile"); + for(String addFile : rv) { + if (addFile.equals(fileName)) { + // supress any ignore + currentFileAttr.removeFromIgnored(cfg); + } + } + } + + if (!useIgnore && !disablePch && !usePch) { + wg.tag("File", new String[] { "RelativePath", vcProjLocation.relativize(file).toString()}); + } else { + wg.startTag( + "File", + new String[] { "RelativePath", vcProjLocation.relativize(file).toString()}); + + for (BuildConfig cfg : allConfigs) { + boolean ignore = currentFileAttr.hasIgnore(cfg); + String [] fileConfAttr; + + if (ignore) { + fileConfAttr = new String[] {"Name", cfg.get("Name"), "ExcludedFromBuild", "TRUE" }; + } else { + fileConfAttr = new String[] {"Name", cfg.get("Name")}; + } + + if (!disablePch && !usePch && !ignore) { + continue; + } else if (!disablePch && !usePch) { + wg.tag("FileConfiguration", fileConfAttr); + } else { + wg.startTag("FileConfiguration", fileConfAttr); + if (usePch) { + // usePch always applies to all configs, might not always be so. + wg.tag("Tool", new String[] { + "Name", "VCCLCompilerTool", "UsePrecompiledHeader", + "1" }); + assert(!disablePch); + } + if (disablePch) { + if (currentFileAttr.hasDisablePch(cfg)) { + wg.tag("Tool", new String[] { + "Name", "VCCLCompilerTool", "UsePrecompiledHeader", + "0" }); + } + assert(!usePch); + } + wg.endTag(); + } + } + wg.endTag(); + } + + return CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs) + throws IOException { + Boolean hide = false; + DirAttributes newAttr = attributes.peek().clone(); + + String rPath; + if (path.toAbsolutePath().toString().equals(this.startDir.toAbsolutePath().toString())){ + rPath = startDir.toString(); + } else { + rPath = path.getFileName().toString(); + } + + // check per config ignorePaths! + for (BuildConfig cfg : allConfigs) { + if (cfg.matchesIgnoredPath(path.toAbsolutePath().toString())) { + newAttr.setIgnore(cfg); + } + + // Hide is always on all configs. And additional files are never hiddden + if (cfg.matchesHidePath(path.toAbsolutePath().toString())) { + hide = true; + break; + } + } + + if (!hide) { + wg.startTag("Filter", new String[] { + "Name", rPath}); + + attributes.push(newAttr); + return super.preVisitDirectory(path, attrs); + } else { + return FileVisitResult.SKIP_SUBTREE; + } + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { + //end matching attributes set by ignorepath + wg.endTag(); + attributes.pop(); + + return CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + return CONTINUE; + } + + public void writeFileTree() throws IOException { + Files.walkFileTree(this.startDir, this); + } + } \ No newline at end of file diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/ProjectCreator.java --- a/src/share/tools/ProjectCreator/ProjectCreator.java Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/tools/ProjectCreator/ProjectCreator.java Fri Sep 28 10:16:29 2012 -0700 @@ -24,75 +24,76 @@ public class ProjectCreator { - public static void usage() { - System.out.println("ProjectCreator options:"); - System.err.println("WinGammaPlatform platform-specific options:"); - System.err.println(" -sourceBase "); - System.err.println(" -dspFileName "); - System.err.println(" -envVar "); - System.err.println(" -dllLoc "); - System.err.println(" If any of the above are specified, "+ - "they must all be."); - System.err.println(" Additional, optional arguments, which can be " + - "specified multiple times:"); - System.err.println(" -absoluteInclude "); - System.err.println(" -relativeInclude "); - System.err.println(" -define "); - System.err.println(" -perFileLine "); - System.err.println(" -conditionalPerFileLine "); - System.err.println(" (NOTE: To work around a bug in nmake, where " + - "you can't have a '#' character in a quoted " + - "string, all of the lines outputted have \"#\"" + - "prepended)"); - System.err.println(" -startAt "); - System.err.println(" -ignoreFile "); - System.err.println(" -additionalFile "); - System.err.println(" -additionalGeneratedFile " + - ""); - System.err.println(" -prelink :"); - System.err.println(" Generate a set of prelink commands for the given BUILD"); - System.err.println(" (\"Debug\" or \"Release\"). The prelink description and commands"); - System.err.println(" are both quoted strings."); - System.err.println(" Default includes: \".\""); - System.err.println(" Default defines: WIN32, _WINDOWS, \"HOTSPOT_BUILD_USER=$(USERNAME)\""); - } + public static void usage() { + System.out.println("ProjectCreator options:"); + System.err.println("WinGammaPlatform platform-specific options:"); + System.err.println(" -sourceBase "); + System.err.println(" -dspFileName "); + System.err.println(" -envVar "); + System.err.println(" -dllLoc "); + System.err.println(" If any of the above are specified, " + + "they must all be."); + System.err.println(" Additional, optional arguments, which can be " + + "specified multiple times:"); + System.err.println(" -absoluteInclude "); + System.err.println(" -relativeInclude "); + System.err.println(" -define "); + System.err.println(" -perFileLine "); + System.err.println(" -conditionalPerFileLine "); + System.err.println(" (NOTE: To work around a bug in nmake, where " + + "you can't have a '#' character in a quoted " + + "string, all of the lines outputted have \"#\"" + "prepended)"); + System.err.println(" -startAt "); + System.err.println(" -ignoreFile "); + System.err.println(" -additionalFile "); + System.err + .println(" -additionalGeneratedFile " + + ""); + System.err.println(" -prelink :"); + System.err + .println(" Generate a set of prelink commands for the given BUILD"); + System.err + .println(" (\"Debug\" or \"Release\"). The prelink description and commands"); + System.err.println(" are both quoted strings."); + System.err.println(" Default includes: \".\""); + System.err + .println(" Default defines: WIN32, _WINDOWS, \"HOTSPOT_BUILD_USER=$(USERNAME)\""); + } - public static void main(String[] args) { - try { - if (args.length < 3) { - usage(); - System.exit(1); - } + public static void main(String[] args) { + try { + if (args.length < 3) { + usage(); + System.exit(1); + } - String platformName = args[0]; - Class platformClass = Class.forName(platformName); - WinGammaPlatform platform = (WinGammaPlatform) platformClass.newInstance(); + String platformName = args[0]; + Class platformClass = Class.forName(platformName); + WinGammaPlatform platform = (WinGammaPlatform) platformClass + .newInstance(); - String[] platformArgs = new String[args.length - 1]; - System.arraycopy(args, 1, platformArgs, 0, platformArgs.length); + String[] platformArgs = new String[args.length - 1]; + System.arraycopy(args, 1, platformArgs, 0, platformArgs.length); - // Allow the platform to write platform-specific files - platform.createVcproj(platformArgs); - } - catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } - } + // Allow the platform to write platform-specific files + platform.createVcproj(platformArgs); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } } diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/Util.java --- a/src/share/tools/ProjectCreator/Util.java Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/tools/ProjectCreator/Util.java Fri Sep 28 10:16:29 2012 -0700 @@ -26,18 +26,19 @@ import java.io.File; public class Util { - static String join(String padder, Vector v) { + + static String join(String padder, Vector v) { return join(padder, v, false); } - static String join(String padder, Vector v, boolean quoted) { + static String join(String padder, Vector v, boolean quoted) { StringBuffer sb = new StringBuffer(); - for (Iterator iter = v.iterator(); iter.hasNext(); ) { + for (Iterator iter = v.iterator(); iter.hasNext(); ) { if (quoted) { sb.append('"'); } - sb.append((String)iter.next()); + sb.append(iter.next()); if (quoted) { sb.append('"'); } @@ -48,10 +49,10 @@ } - static String prefixed_join(String padder, Vector v, boolean quoted) { + static String prefixed_join(String padder, Vector v, boolean quoted) { StringBuffer sb = new StringBuffer(); - for (Iterator iter = v.iterator(); iter.hasNext(); ) { + for (Iterator iter = v.iterator(); iter.hasNext(); ) { sb.append(padder); if (quoted) { diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/WinGammaPlatform.java --- a/src/share/tools/ProjectCreator/WinGammaPlatform.java Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/tools/ProjectCreator/WinGammaPlatform.java Fri Sep 28 10:16:29 2012 -0700 @@ -29,6 +29,7 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.List; +import java.util.Stack; import java.util.TreeSet; import java.util.Vector; @@ -218,69 +219,6 @@ return false; } - /* This returns a String containing the full path to the passed - file name, or null if an error occurred. If the file was not - found or was a duplicate and couldn't be resolved using the - preferred paths, the file name is added to the appropriate - Vector of Strings. */ - private String findFileInDirectory(String fileName, - DirectoryTree directory, - Vector preferredPaths, - Vector filesNotFound, - Vector filesDuplicate) { - List locationsInTree = directory.findFile(fileName); - int rootNameLength = directory.getRootNodeName().length(); - String name = null; - if ((locationsInTree == null) || - (locationsInTree.size() == 0)) { - filesNotFound.add(fileName); - } else if (locationsInTree.size() > 1) { - // Iterate through them, trying to find one with a - // preferred path - search: - { - for (Iterator locIter = locationsInTree.iterator(); - locIter.hasNext(); ) { - DirectoryTreeNode node = - (DirectoryTreeNode) locIter.next(); - String tmpName = node.getName(); - for (Iterator prefIter = preferredPaths.iterator(); - prefIter.hasNext(); ) { - // We need to make sure the preferred path is - // found from the file path not including the root node name. - if (tmpName.indexOf((String)prefIter.next(), - rootNameLength) != -1) { - name = tmpName; - break search; - } - } - } - } - - if (name == null) { - filesDuplicate.add(fileName); - } - } else { - name = ((DirectoryTreeNode) locationsInTree.get(0)).getName(); - } - - return name; - } - - protected String envVarPrefixedFileName(String fileName, - int sourceBaseLen, - DirectoryTree tree, - Vector preferredPaths, - Vector filesNotFound, - Vector filesDuplicate) { - String fullName = findFileInDirectory(fileName, - tree, - preferredPaths, - filesNotFound, - filesDuplicate); - return fullName; - } - String getProjectName(String fullPath, String extension) throws IllegalArgumentException, IOException { File file = new File(fullPath).getCanonicalFile(); @@ -369,6 +307,12 @@ HsArgHandler.STRING ), + new HsArgRule("-buildSpace", + "BuildSpace", + null, + HsArgHandler.STRING + ), + new HsArgRule("-platformName", "PlatformName", null, @@ -405,6 +349,18 @@ HsArgHandler.VECTOR ), + new HsArgRule("-absoluteSrcInclude", + "AbsoluteSrcInclude", + null, + HsArgHandler.VECTOR + ), + + new HsArgRule("-relativeSrcInclude", + "RelativeSrcInclude", + null, + HsArgHandler.VECTOR + ), + new HsArgRule("-define", "Define", null, @@ -494,6 +450,12 @@ HsArgHandler.VECTOR ), + new HsArgRule("-hidePath", + "HidePath", + null, + HsArgHandler.VECTOR + ), + new HsArgRule("-additionalFile", "AdditionalFile", null, @@ -611,107 +573,101 @@ return allConfigs; } - class FileAttribute { - int numConfigs; - Vector configs; - String shortName; - boolean noPch, pchRoot; - - FileAttribute(String shortName, BuildConfig cfg, int numConfigs) { - this.shortName = shortName; - this.noPch = (cfg.lookupHashFieldInContext("DisablePch", shortName) != null); - this.pchRoot = shortName.equals(BuildConfig.getFieldString(null, "UseToGeneratePch")); - this.numConfigs = numConfigs; - - configs = new Vector(); - add(cfg.get("Name")); - } - - void add(String confName) { - configs.add(confName); - - // if presented in all configs - if (configs.size() == numConfigs) { - configs = null; - } - } - } - - class FileInfo implements Comparable { - String full; - FileAttribute attr; - - FileInfo(String full, FileAttribute attr) { - this.full = full; - this.attr = attr; - } - - public int compareTo(Object o) { - FileInfo oo = (FileInfo)o; - return full.compareTo(oo.full); - } - - boolean isHeader() { - return attr.shortName.endsWith(".h") || attr.shortName.endsWith(".hpp"); - } - - boolean isCpp() { - return attr.shortName.endsWith(".cpp"); - } - } - - - TreeSet sortFiles(Hashtable allFiles) { - TreeSet rv = new TreeSet(); - Enumeration e = allFiles.keys(); - while (e.hasMoreElements()) { - String fullPath = (String)e.nextElement(); - rv.add(new FileInfo(fullPath, (FileAttribute)allFiles.get(fullPath))); - } - return rv; - } - - Hashtable computeAttributedFiles(Vector allConfigs) { - Hashtable ht = new Hashtable(); - int numConfigs = allConfigs.size(); - - for (Iterator i = allConfigs.iterator(); i.hasNext(); ) { - BuildConfig bc = (BuildConfig)i.next(); - Hashtable confFiles = (Hashtable)bc.getSpecificField("AllFilesHash"); - String confName = bc.get("Name"); - - for (Enumeration e=confFiles.keys(); e.hasMoreElements(); ) { - String filePath = (String)e.nextElement(); - FileAttribute fa = (FileAttribute)ht.get(filePath); - - if (fa == null) { - fa = new FileAttribute((String)confFiles.get(filePath), bc, numConfigs); - ht.put(filePath, fa); - } else { - fa.add(confName); - } - } - } - - return ht; - } - - Hashtable computeAttributedFiles(BuildConfig bc) { - Hashtable ht = new Hashtable(); - Hashtable confFiles = (Hashtable)bc.getSpecificField("AllFilesHash"); - - for (Enumeration e = confFiles.keys(); e.hasMoreElements(); ) { - String filePath = (String)e.nextElement(); - ht.put(filePath, new FileAttribute((String)confFiles.get(filePath), bc, 1)); - } - - return ht; - } - PrintWriter printWriter; public void writeProjectFile(String projectFileName, String projectName, Vector allConfigs) throws IOException { throw new RuntimeException("use compiler version specific version"); } + + int indent; + private Stack tagStack = new Stack(); + + private void startTagPrim(String name, String[] attrs, boolean close) { + startTagPrim(name, attrs, close, true); + } + + private void startTagPrim(String name, String[] attrs, boolean close, + boolean newline) { + doIndent(); + printWriter.print("<" + name); + indent++; + + if (attrs != null && attrs.length > 0) { + for (int i = 0; i < attrs.length; i += 2) { + printWriter.print(" " + attrs[i] + "=\"" + attrs[i + 1] + "\""); + if (i < attrs.length - 2) { + } + } + } + + if (close) { + indent--; + printWriter.print(" />"); + } else { + // TODO push tag name, and change endTag to pop and print. + tagStack.push(name); + printWriter.print(">"); + } + if (newline) { + printWriter.println(); + } + } + + void startTag(String name, String... attrs) { + startTagPrim(name, attrs, false); + } + + void startTagV(String name, Vector attrs) { + String s[] = new String[attrs.size()]; + for (int i = 0; i < attrs.size(); i++) { + s[i] = (String) attrs.elementAt(i); + } + startTagPrim(name, s, false); + } + + void endTag() { + String name = tagStack.pop(); + indent--; + doIndent(); + printWriter.println(""); + } + + private void endTagNoIndent() { + String name = tagStack.pop(); + indent--; + printWriter.println(""); + } + + void tag(String name, String... attrs) { + startTagPrim(name, attrs, true); + } + + void tagData(String name, String data) { + startTagPrim(name, null, false, false); + printWriter.print(data); + endTagNoIndent(); + } + + void tagData(String name, String data, String... attrs) { + startTagPrim(name, attrs, false, false); + printWriter.print(data); + endTagNoIndent(); + } + + void tagV(String name, Vector attrs) { + String s[] = new String[attrs.size()]; + for (int i = 0; i < attrs.size(); i++) { + s[i] = (String) attrs.elementAt(i); + } + startTagPrim(name, s, true); + } + + void doIndent() { + for (int i = 0; i < indent; i++) { + printWriter.print(" "); + } + } + + } diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/WinGammaPlatformVC10.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java Fri Sep 28 10:16:29 2012 -0700 @@ -3,14 +3,18 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; -import java.util.Hashtable; +import java.nio.file.FileSystems; import java.util.Iterator; -import java.util.TreeSet; +import java.util.LinkedList; import java.util.UUID; import java.util.Vector; public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 { + + LinkedList filters = new LinkedList(); + LinkedList filterDeps = new LinkedList(); + @Override protected String getProjectExt() { return ".vcxproj"; @@ -37,15 +41,15 @@ "Include", cfg.get("Name")); tagData("Configuration", cfg.get("Id")); tagData("Platform", cfg.get("PlatformName")); - endTag("ProjectConfiguration"); + endTag(); } - endTag("ItemGroup"); + endTag(); startTag("PropertyGroup", "Label", "Globals"); tagData("ProjectGuid", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}"); tag("SccProjectName"); tag("SccLocalPath"); - endTag("PropertyGroup"); + endTag(); tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"); @@ -53,19 +57,19 @@ startTag(cfg, "PropertyGroup", "Label", "Configuration"); tagData("ConfigurationType", "DynamicLibrary"); tagData("UseOfMfc", "false"); - endTag("PropertyGroup"); + endTag(); } tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.props"); startTag("ImportGroup", "Label", "ExtensionSettings"); - endTag("ImportGroup"); + endTag(); for (BuildConfig cfg : allConfigs) { startTag(cfg, "ImportGroup", "Label", "PropertySheets"); tag("Import", "Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props", "Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')", "Label", "LocalAppDataPlatform"); - endTag("ImportGroup"); + endTag(); } tag("PropertyGroup", "Label", "UserMacros"); @@ -82,38 +86,38 @@ tag(cfg, "CodeAnalysisRules"); tag(cfg, "CodeAnalysisRuleAssemblies"); } - endTag("PropertyGroup"); + endTag(); for (BuildConfig cfg : allConfigs) { startTag(cfg, "ItemDefinitionGroup"); startTag("ClCompile"); tagV(cfg.getV("CompilerFlags")); - endTag("ClCompile"); + endTag(); startTag("Link"); tagV(cfg.getV("LinkerFlags")); - endTag("Link"); + endTag(); startTag("PostBuildEvent"); tagData("Message", BuildConfig.getFieldString(null, "PostbuildDescription")); tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace("\t", "\r\n"))); - endTag("PostBuildEvent"); + endTag(); startTag("PreLinkEvent"); tagData("Message", BuildConfig.getFieldString(null, "PrelinkDescription")); tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace("\t", "\r\n"))); - endTag("PreLinkEvent"); + endTag(); - endTag("ItemDefinitionGroup"); + endTag(); } writeFiles(allConfigs, projDir); tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); startTag("ImportGroup", "Label", "ExtensionTargets"); - endTag("ImportGroup"); + endTag(); - endTag("Project"); + endTag(); printWriter.close(); System.out.println(" Done."); @@ -138,14 +142,22 @@ for (BuildConfig cfg : allConfigs) { startTag(cfg, "PropertyGroup"); tagData("LocalDebuggerCommand", "$(TargetDir)/hotspot.exe"); - endTag("PropertyGroup"); + endTag(); } - endTag("Project"); + endTag(); printWriter.close(); System.out.println(" Done."); } + public void addFilter(String rPath) { + filters.add(rPath); + } + + public void addFilterDependency(String fileLoc, String filter) { + filterDeps.add(new String[] {fileLoc, filter}); + } + private void writeFilterFile(String projectFileName, String projectName, Vector allConfigs, String base) throws FileNotFoundException, UnsupportedEncodingException { String filterFileName = projectFileName + ".filters"; @@ -157,210 +169,92 @@ "ToolsVersion", "4.0", "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); - Hashtable allFiles = computeAttributedFiles(allConfigs); - TreeSet sortedFiles = sortFiles(allFiles); - Vector filters = makeFilters(sortedFiles); - - // first all filters startTag("ItemGroup"); - for (NameFilter filter : filters) { - doWriteFilter(filter, ""); + for (String filter : filters) { + startTag("Filter", "Include",filter); + UUID uuid = UUID.randomUUID(); + tagData("UniqueIdentifier", "{" + uuid.toString() + "}"); + endTag(); } startTag("Filter", "Include", "Resource Files"); UUID uuid = UUID.randomUUID(); tagData("UniqueIdentifier", "{" + uuid.toString() + "}"); tagData("Extensions", "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"); - endTag("Filter"); - endTag("ItemGroup"); + endTag(); + endTag(); - // then all cpp files - startTag("ItemGroup"); - for (NameFilter filter : filters) { - doWriteFiles(sortedFiles, filter, "", "ClCompile", new Evaluator() { - public boolean pick(FileInfo fi) { - return fi.isCpp(); - } - }, base); - } - endTag("ItemGroup"); + //TODO - do I need to split cpp and hpp files? - // then all header files + // then all files startTag("ItemGroup"); - for (NameFilter filter : filters) { - doWriteFiles(sortedFiles, filter, "", "ClInclude", new Evaluator() { - public boolean pick(FileInfo fi) { - return fi.isHeader(); - } - }, base); - } - endTag("ItemGroup"); + for (String[] dep : filterDeps) { + String tagName = getFileTagFromSuffix(dep[0]); - // then all other files - startTag("ItemGroup"); - for (NameFilter filter : filters) { - doWriteFiles(sortedFiles, filter, "", "None", new Evaluator() { - public boolean pick(FileInfo fi) { - return true; - } - }, base); + startTag(tagName, "Include", dep[0]); + tagData("Filter", dep[1]); + endTag(); } - endTag("ItemGroup"); + endTag(); - endTag("Project"); + endTag(); printWriter.close(); System.out.println(" Done."); } - - private void doWriteFilter(NameFilter filter, String start) { - startTag("Filter", "Include", start + filter.fname); - UUID uuid = UUID.randomUUID(); - tagData("UniqueIdentifier", "{" + uuid.toString() + "}"); - endTag("Filter"); - if (filter instanceof ContainerFilter) { - Iterator i = ((ContainerFilter)filter).babies(); - while (i.hasNext()) { - doWriteFilter((NameFilter)i.next(), start + filter.fname + "\\"); - } - } - } - - interface Evaluator { - boolean pick(FileInfo fi); + public String getFileTagFromSuffix(String fileName) { + if (fileName.endsWith(".cpp")) { + return"ClCompile"; + } else if (fileName.endsWith(".c")) { + return "ClCompile"; + } else if (fileName.endsWith(".hpp")) { + return"ClInclude"; + } else if (fileName.endsWith(".h")) { + return "ClInclude"; + } else { + return"None"; + } } - private void doWriteFiles(TreeSet allFiles, NameFilter filter, String start, String tool, Evaluator eval, String base) { - if (filter instanceof ContainerFilter) { - Iterator i = ((ContainerFilter)filter).babies(); - while (i.hasNext()) { - doWriteFiles(allFiles, (NameFilter)i.next(), start + filter.fname + "\\", tool, eval, base); - } - } - else { - Iterator i = allFiles.iterator(); - while (i.hasNext()) { - FileInfo fi = (FileInfo)i.next(); - - if (!filter.match(fi)) { - continue; - } - if (eval.pick(fi)) { - startTag(tool, "Include", rel(fi.full, base)); - tagData("Filter", start + filter.fname); - endTag(tool); - - // we not gonna look at this file anymore (sic!) - i.remove(); - } - } - } - } - - void writeFiles(Vector allConfigs, String projDir) { - Hashtable allFiles = computeAttributedFiles(allConfigs); - TreeSet sortedFiles = sortFiles(allFiles); + // This code assummes there are no config specific includes. + startTag("ItemGroup"); - // first cpp-files - startTag("ItemGroup"); - for (FileInfo fi : sortedFiles) { - if (!fi.isCpp()) { - continue; - } - writeFile("ClCompile", allConfigs, fi, projDir); - } - endTag("ItemGroup"); + String sourceBase = BuildConfig.getFieldString(null, "SourceBase"); + + // Use first config for all global absolute includes. + BuildConfig baseConfig = allConfigs.firstElement(); + Vector rv = new Vector(); - // then header-files - startTag("ItemGroup"); - for (FileInfo fi : sortedFiles) { - if (!fi.isHeader()) { - continue; - } - writeFile("ClInclude", allConfigs, fi, projDir); - } - endTag("ItemGroup"); + // Then use first config for all relative includes + Vector ri = new Vector(); + baseConfig.collectRelevantVectors(ri, "RelativeSrcInclude"); + for (String f : ri) { + rv.add(sourceBase + Util.sep + f); + } - // then others - startTag("ItemGroup"); - for (FileInfo fi : sortedFiles) { - if (fi.isHeader() || fi.isCpp()) { - continue; - } - writeFile("None", allConfigs, fi, projDir); - } - endTag("ItemGroup"); + baseConfig.collectRelevantVectors(rv, "AbsoluteSrcInclude"); + + handleIncludes(rv, allConfigs); + + endTag(); } - /** - * Make "path" into a relative path using "base" as the base. - * - * path and base are assumed to be normalized with / as the file separator. - * returned path uses "\\" as file separator - */ - private String rel(String path, String base) - { - if(!base.endsWith("/")) { - base += "/"; - } - String[] pathTok = path.split("/"); - String[] baseTok = base.split("/"); - int pi = 0; - int bi = 0; - StringBuilder newPath = new StringBuilder(); - - // first step past all path components that are the same - while (pi < pathTok.length && - bi < baseTok.length && - pathTok[pi].equals(baseTok[bi])) { - pi++; - bi++; - } - - // for each path component left in base, add "../" - while (bi < baseTok.length) { - bi++; - newPath.append("..\\"); - } - - // now add everything left in path - while (pi < pathTok.length) { - newPath.append(pathTok[pi]); - pi++; - if (pi != pathTok.length) { - newPath.append("\\"); - } - } - return newPath.toString(); - } - - private void writeFile(String tool, Vector allConfigs, FileInfo fi, String base) { - if (fi.attr.configs == null && fi.attr.pchRoot == false && fi.attr.noPch == false) { - tag(tool, "Include", rel(fi.full, base)); - } - else { - startTag(tool, "Include", rel(fi.full, base)); - for (BuildConfig cfg : allConfigs) { - if (fi.attr.configs != null && !fi.attr.configs.contains(cfg.get("Name"))) { - tagData(cfg, "ExcludedFromBuild", "true"); - } - if (fi.attr.pchRoot) { - tagData(cfg, "PrecompiledHeader", "Create"); - } - if (fi.attr.noPch) { - startTag(cfg, "PrecompiledHeader"); - endTag("PrecompiledHeader"); - } - } - endTag(tool); - } + // Will visit file tree for each include + private void handleIncludes(Vector includes, Vector allConfigs) { + for (String path : includes) { + FileTreeCreatorVC10 ftc = new FileTreeCreatorVC10(FileSystems.getDefault().getPath(path) , allConfigs, this); + try { + ftc.writeFileTree(); + } catch (IOException e) { + e.printStackTrace(); + } + } } String buildCond(BuildConfig cfg) { return "'$(Configuration)|$(Platform)'=='"+cfg.get("Name")+"'"; } - void tagV(Vector v) { Iterator i = v.iterator(); while(i.hasNext()) { @@ -391,6 +285,7 @@ startTag(name, ss); } + } class CompilerInterfaceVC10 extends CompilerInterface { diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/WinGammaPlatformVC6.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC6.java Fri Sep 28 14:14:25 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -import java.io.*; -import java.util.*; - -public class WinGammaPlatformVC6 extends WinGammaPlatform { - public void writeProjectFile(String projectFileName, String projectName, - Vector allConfigs) throws IOException { - Vector allConfigNames = new Vector(); - - printWriter = new PrintWriter(new FileWriter(projectFileName)); - String cfg = ((BuildConfig)allConfigs.get(0)).get("Name"); - - printWriter.println("# Microsoft Developer Studio Project File - Name=\"" + projectName + "\" - Package Owner=<4>"); - printWriter.println("# Microsoft Developer Studio Generated Build File, Format Version 6.00"); - printWriter.println("# ** DO NOT EDIT **"); - printWriter.println(""); - printWriter.println("# TARGTYPE \"Win32 (x86) Dynamic-Link Library\" 0x0102"); - printWriter.println("CFG=" + cfg); - printWriter.println(""); - - printWriter.println("!MESSAGE This is not a valid makefile. To build this project using NMAKE,"); - printWriter.println("!MESSAGE use the Export Makefile command and run"); - printWriter.println("!MESSAGE "); - printWriter.println("!MESSAGE NMAKE /f \"" + projectName + ".mak\"."); - printWriter.println("!MESSAGE "); - printWriter.println("!MESSAGE You can specify a configuration when running NMAKE"); - printWriter.println("!MESSAGE by defining the macro CFG on the command line. For example:"); - printWriter.println("!MESSAGE "); - printWriter.println("!MESSAGE NMAKE /f \"" + projectName + ".mak\" CFG=\"" + cfg + "\""); - printWriter.println("!MESSAGE "); - printWriter.println("!MESSAGE Possible choices for configuration are:"); - printWriter.println("!MESSAGE "); - for (Iterator i = allConfigs.iterator(); i.hasNext(); ) { - String name = ((BuildConfig)i.next()).get("Name"); - printWriter.println("!MESSAGE \""+ name + "\" (based on \"Win32 (x86) Dynamic-Link Library\")"); - allConfigNames.add(name); - } - printWriter.println("!MESSAGE "); - printWriter.println(""); - - printWriter.println("# Begin Project"); - printWriter.println("# PROP AllowPerConfigDependencies 0"); - printWriter.println("# PROP Scc_ProjName \"\""); - printWriter.println("# PROP Scc_LocalPath \"\""); - printWriter.println("CPP=cl.exe"); - printWriter.println("MTL=midl.exe"); - printWriter.println("RSC=rc.exe"); - - - String keyword = "!IF"; - for (Iterator i = allConfigs.iterator(); i.hasNext(); ) { - BuildConfig bcfg = (BuildConfig)i.next(); - printWriter.println(keyword + " \"$(CFG)\" == \"" + bcfg.get("Name") + "\""); - writeConfigHeader(bcfg); - keyword = "!ELSEIF"; - if (!i.hasNext()) printWriter.println("!ENDIF"); - } - - - TreeSet sortedFiles = sortFiles(computeAttributedFiles(allConfigs)); - - printWriter.println("# Begin Target"); - - for (Iterator i = allConfigs.iterator(); i.hasNext(); ) { - printWriter.println("# Name \"" + ((BuildConfig)i.next()).get("Name") + "\""); - } - printWriter.println("# Begin Group \"Header Files\""); - printWriter.println("# PROP Default_Filter \"h;hpp;hxx;hm;inl;fi;fd\""); - - Iterator i = sortedFiles.iterator(); - - while (i.hasNext()) { - FileInfo fi = (FileInfo)i.next(); - - // skip sources - if (!fi.isHeader()) { - continue; - } - - printFile(fi, allConfigNames); - } - printWriter.println("# End Group"); - printWriter.println(""); - - printWriter.println("# Begin Group \"Source Files\""); - printWriter.println("# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90\""); - - i = sortedFiles.iterator(); - while (i.hasNext()) { - FileInfo fi = (FileInfo)i.next(); - - // skip headers - if (fi.isHeader()) { - continue; - } - - printFile(fi, allConfigNames); - } - printWriter.println("# End Group"); - printWriter.println(""); - - - printWriter.println("# Begin Group \"Resource Files\""); - printWriter.println("# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe\""); - printWriter.println("# End Group"); - printWriter.println(""); - printWriter.println("# End Target"); - - printWriter.println("# End Project"); - - printWriter.close(); - } - - - void printFile(FileInfo fi, Vector allConfigNames) { - printWriter.println("# Begin Source File"); - printWriter.println(""); - printWriter.println("SOURCE=\"" + fi.full + "\""); - FileAttribute attr = fi.attr; - - if (attr.noPch) { - printWriter.println("# SUBTRACT CPP /YX /Yc /Yu"); - } - - if (attr.pchRoot) { - printWriter.println("# ADD CPP /Yc\"incls/_precompiled.incl\""); - } - if (attr.configs != null) { - String keyword = "!IF"; - for (Iterator j=allConfigNames.iterator(); j.hasNext();) { - String cfg = (String)j.next(); - if (!attr.configs.contains(cfg)) { - printWriter.println(keyword+" \"$(CFG)\" == \"" + cfg +"\""); - printWriter.println("# PROP BASE Exclude_From_Build 1"); - printWriter.println("# PROP Exclude_From_Build 1"); - keyword = "!ELSEIF"; - } - } - printWriter.println("!ENDIF"); - } - - printWriter.println("# End Source File"); - } - - void writeConfigHeader(BuildConfig cfg) { - printWriter.println("# Begin Special Build Tool"); - printWriter.println("SOURCE=\"$(InputPath)\""); - printWriter.println("PreLink_Desc=" + BuildConfig.getFieldString(null, "PrelinkDescription")); - printWriter.println("PreLink_Cmds=" + - cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand"))); - printWriter.println("# End Special Build Tool"); - printWriter.println(""); - - for (Iterator i = cfg.getV("CompilerFlags").iterator(); i.hasNext(); ) { - printWriter.println("# "+(String)i.next()); - } - - - printWriter.println("LINK32=link.exe"); - - for (Iterator i = cfg.getV("LinkerFlags").iterator(); i.hasNext(); ) { - printWriter.println("# "+(String)i.next()); - } - - printWriter.println("ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32"); - printWriter.println("ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32"); - printWriter.println("ADD BASE RSC /l 0x409 /d \"_DEBUG\""); - printWriter.println("ADD RSC /l 0x409 /d \"_DEBUG\""); - printWriter.println("BSC32=bscmake.exe"); - printWriter.println("ADD BASE BSC32 /nologo"); - printWriter.println("ADD BSC32 /nologo"); - printWriter.println(""); - } - - protected String getProjectExt() { - return ".dsp"; - } -} - - -class CompilerInterfaceVC6 extends CompilerInterface { - Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) { - Vector rv = new Vector(); - - rv.add("PROP BASE Use_MFC 0"); - rv.add("PROP Use_MFC 0"); - rv.add("ADD CPP /nologo /MT /W3 /WX /GX /YX /Fr /FD /c"); - rv.add("PROP BASE Output_Dir \""+outDir+"\""); - rv.add("PROP Output_Dir \""+outDir+"\""); - rv.add("PROP BASE Intermediate_Dir \""+outDir+"\""); - rv.add("PROP Intermediate_Dir \""+outDir+"\""); - rv.add("PROP BASE Target_Dir \"\""); - rv.add("PROP Target_Dir \"\""); - rv.add("ADD BASE CPP "+Util.prefixed_join(" /I ", includes, true)); - rv.add("ADD CPP "+Util.prefixed_join(" /I ", includes, true)); - rv.add("ADD BASE CPP "+Util.prefixed_join(" /D ", defines, true)); - rv.add("ADD CPP "+Util.prefixed_join(" /D ", defines, true)); - rv.add("ADD CPP /Yu\"incls/_precompiled.incl\""); - - return rv; - } - - Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) { - Vector rv = new Vector(); - - rv.add("PROP Ignore_Export_Lib 0"); - rv.add("ADD BASE CPP /MD"); - rv.add("ADD CPP /MD"); - rv.add("ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib " + - " advapi32.lib shell32.lib ole32.lib oleaut32.lib winmm.lib"); - String machine = "/machine:I386"; - if (platformName.equals("x64")) { - machine = "/machine:X64"; - } - rv.add("ADD LINK32 /out:\""+outDll+"\" "+ - " /nologo /subsystem:windows /machine:" + machine + - " /nologo /base:\"0x8000000\" /subsystem:windows /dll" + - " /export:JNI_GetDefaultJavaVMInitArgs /export:JNI_CreateJavaVM /export:JNI_GetCreatedJavaVMs "+ - " /export:jio_snprintf /export:jio_printf /export:jio_fprintf /export:jio_vfprintf "+ - " /export:jio_vsnprintf "); - rv.add("SUBTRACT LINK32 /pdb:none /map"); - - return rv; - } - - Vector getDebugCompilerFlags(String opt) { - Vector rv = new Vector(); - - rv.add("ADD BASE CPP /Gm /Zi /O"+opt); - - return rv; - } - - Vector getDebugLinkerFlags() { - Vector rv = new Vector(); - - rv.add("PROP BASE Use_Debug_Libraries 1"); - rv.add("PROP Use_Debug_Libraries 1"); - rv.add("ADD LINK32 /debug"); - - return rv; - } - - void getAdditionalNonKernelLinkerFlags(Vector rv) {} - - Vector getProductCompilerFlags() { - Vector rv = new Vector(); - - rv.add("ADD CPP /O"+getOptFlag()); - - return rv; - } - - Vector getProductLinkerFlags() { - Vector rv = new Vector(); - - rv.add("PROP BASE Use_Debug_Libraries 0"); - rv.add("PROP Use_Debug_Libraries 0"); - - return rv; - } - - String getOptFlag() { - return "2"; - } - - String getNoOptFlag() { - return "d"; - } - - String makeCfgName(String flavourBuild, String platform) { - return "vm - "+ platform + " " + flavourBuild; - } -} diff -r 15fba4382765 -r f2e12eb74117 src/share/tools/ProjectCreator/WinGammaPlatformVC7.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java Fri Sep 28 10:16:29 2012 -0700 @@ -25,758 +25,326 @@ import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.TreeSet; +import java.nio.file.FileSystems; import java.util.Vector; public class WinGammaPlatformVC7 extends WinGammaPlatform { - String projectVersion() {return "7.10";}; + // TODO How about moving all globals configs to its own BuildConfig? - public void writeProjectFile(String projectFileName, String projectName, - Vector allConfigs) throws IOException { - System.out.println(); - System.out.println(" Writing .vcproj file: "+projectFileName); - // If we got this far without an error, we're safe to actually - // write the .vcproj file - printWriter = new PrintWriter(new FileWriter(projectFileName)); + String projectVersion() { + return "7.10"; + }; - printWriter.println(""); - startTag( - "VisualStudioProject", - new String[] { - "ProjectType", "Visual C++", - "Version", projectVersion(), - "Name", projectName, - "ProjectGUID", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}", - "SccProjectName", "", - "SccLocalPath", "" - } - ); - startTag("Platforms"); - tag("Platform", new String[] {"Name", (String) BuildConfig.getField(null, "PlatformName")}); - endTag("Platforms"); - - startTag("Configurations"); - - for (Iterator i = allConfigs.iterator(); i.hasNext(); ) { - writeConfiguration((BuildConfig)i.next()); - } - - endTag("Configurations"); - - tag("References"); - - writeFiles(allConfigs); - - tag("Globals"); - - endTag("VisualStudioProject"); - printWriter.close(); - - System.out.println(" Done."); - } - - - abstract class NameFilter { - protected String fname; + public void writeProjectFile(String projectFileName, String projectName, + Vector allConfigs) throws IOException { + System.out.println(); + System.out.println(" Writing .vcproj file: " + projectFileName); + // If we got this far without an error, we're safe to actually + // write the .vcproj file + printWriter = new PrintWriter(new FileWriter(projectFileName)); - abstract boolean match(FileInfo fi); - - String filterString() { return ""; } - String name() { return this.fname;} - - @Override - // eclipse auto-generated - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + getOuterType().hashCode(); - result = prime * result + ((fname == null) ? 0 : fname.hashCode()); - return result; - } + printWriter + .println(""); + startTag("VisualStudioProject", new String[] { "ProjectType", + "Visual C++", "Version", projectVersion(), "Name", projectName, + "ProjectGUID", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}", + "SccProjectName", "", "SccLocalPath", "" }); + startTag("Platforms"); + tag("Platform", + new String[] { "Name", + (String) BuildConfig.getField(null, "PlatformName") }); + endTag(); - @Override - // eclipse auto-generated - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - NameFilter other = (NameFilter) obj; - if (!getOuterType().equals(other.getOuterType())) - return false; - if (fname == null) { - if (other.fname != null) - return false; - } else if (!fname.equals(other.fname)) - return false; - return true; - } + startTag("Configurations"); - // eclipse auto-generated - private WinGammaPlatformVC7 getOuterType() { - return WinGammaPlatformVC7.this; - } - } + for (BuildConfig cfg : allConfigs) { + writeConfiguration(cfg); + } - class DirectoryFilter extends NameFilter { - String dir; - int baseLen, dirLen; + endTag(); - DirectoryFilter(String dir, String sbase) { - this.dir = dir; - this.baseLen = sbase.length(); - this.dirLen = dir.length(); - this.fname = dir; - } + tag("References"); - DirectoryFilter(String fname, String dir, String sbase) { - this.dir = dir; - this.baseLen = sbase.length(); - this.dirLen = dir.length(); - this.fname = fname; - } - + writeFiles(allConfigs); - boolean match(FileInfo fi) { - int lastSlashIndex = fi.full.lastIndexOf('/'); - String fullDir = fi.full.substring(0, lastSlashIndex); - return fullDir.endsWith(dir); - } + tag("Globals"); - @Override - // eclipse auto-generated - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + getOuterType().hashCode(); - result = prime * result + baseLen; - result = prime * result + ((dir == null) ? 0 : dir.hashCode()); - result = prime * result + dirLen; - return result; - } + endTag(); + printWriter.close(); - @Override - // eclipse auto-generated - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - DirectoryFilter other = (DirectoryFilter) obj; - if (!getOuterType().equals(other.getOuterType())) - return false; - if (baseLen != other.baseLen) - return false; - if (dir == null) { - if (other.dir != null) - return false; - } else if (!dir.equals(other.dir)) - return false; - if (dirLen != other.dirLen) - return false; - return true; - } + System.out.println(" Done."); + } - // eclipse auto-generated - private WinGammaPlatformVC7 getOuterType() { - return WinGammaPlatformVC7.this; - } - } + void writeCustomToolConfig(Vector configs, String[] customToolAttrs) { + for (BuildConfig cfg : configs) { + startTag("FileConfiguration", + new String[] { "Name", (String) cfg.get("Name") }); + tag("Tool", customToolAttrs); - class TerminatorFilter extends NameFilter { - TerminatorFilter(String fname) { - this.fname = fname; - - } - boolean match(FileInfo fi) { - return true; - } - - } - - class SpecificNameFilter extends NameFilter { - String pats[]; + endTag(); + } + } - SpecificNameFilter(String fname, String[] pats) { - this.fname = fname; - this.pats = pats; - } + void writeFiles(Vector allConfigs) { - boolean match(FileInfo fi) { - for (int i=0; i rv = new Vector(); - boolean match(FileInfo fi) { - for (int i=0; i ri = new Vector(); + baseConfig.collectRelevantVectors(ri, "RelativeSrcInclude"); + for (String f : ri) { + rv.add(sourceBase + Util.sep + f); + } - } - - class ContainerFilter extends NameFilter { - Vector children; - - ContainerFilter(String fname) { - this.fname = fname; - children = new Vector(); + baseConfig.collectRelevantVectors(rv, "AbsoluteSrcInclude"); - } - boolean match(FileInfo fi) { - return false; - } - - Iterator babies() { return children.iterator(); } - - void add(NameFilter f) { - children.add(f); - } - } - - - void writeCustomToolConfig(Vector configs, String[] customToolAttrs) { - for (Iterator i = configs.iterator(); i.hasNext(); ) { - startTag("FileConfiguration", - new String[] { - "Name", (String)i.next() - } - ); - tag("Tool", customToolAttrs); - - endTag("FileConfiguration"); - } - } + handleIncludes(rv, allConfigs); - // here we define filters, which define layout of what can be seen in 'Solution View' of MSVC - // Basically there are two types of entities - container filters and real filters - // - container filter just provides a container to group together real filters - // - real filter can select elements from the set according to some rule, put it into XML - // and remove from the list - Vector makeFilters(TreeSet files) { - Vector rv = new Vector(); - String sbase = Util.normalize(BuildConfig.getFieldString(null, "SourceBase")+"/src/"); - - String currentDir = ""; - DirectoryFilter container = null; - for(FileInfo fileInfo : files) { + startTag("Filter", new String[] { "Name", "Resource Files", "Filter", + "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" }); + endTag(); - if (!fileInfo.full.startsWith(sbase)) { - continue; - } - - int lastSlash = fileInfo.full.lastIndexOf('/'); - String dir = fileInfo.full.substring(sbase.length(), lastSlash); - if(dir.equals("share/vm")) { - // skip files directly in share/vm - should only be precompiled.hpp which is handled below - continue; - } - if (!dir.equals(currentDir)) { - currentDir = dir; - if (container != null && !rv.contains(container)) { - rv.add(container); - } + endTag(); + } - // remove "share/vm/" from names - String name = dir; - if (dir.startsWith("share/vm/")) { - name = dir.substring("share/vm/".length(), dir.length()); - } - DirectoryFilter newfilter = new DirectoryFilter(name, dir, sbase); - int i = rv.indexOf(newfilter); - if(i == -1) { - container = newfilter; - } else { - // if the filter already exists, reuse it - container = (DirectoryFilter) rv.get(i); - } - } - } - if (container != null && !rv.contains(container)) { - rv.add(container); - } + // Will visit file tree for each include + private void handleIncludes(Vector includes, Vector allConfigs) { + for (String path : includes) { + FileTreeCreatorVC7 ftc = new FileTreeCreatorVC7(FileSystems.getDefault().getPath(path) , allConfigs, this); + try { + ftc.writeFileTree(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } - ContainerFilter generated = new ContainerFilter("Generated"); - ContainerFilter c1Generated = new ContainerFilter("C1"); - c1Generated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*compiler1/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"})); - c1Generated.add(new SpecificPathFilter("jvmtifiles", new String[] {".*compiler1/generated/jvmtifiles/.*"})); - generated.add(c1Generated); - ContainerFilter c2Generated = new ContainerFilter("C2"); - c2Generated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*compiler2/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"})); - c2Generated.add(new SpecificPathFilter("adfiles", new String[] {".*compiler2/generated/adfiles/.*"})); - c2Generated.add(new SpecificPathFilter("jvmtifiles", new String[] {".*compiler2/generated/jvmtifiles/.*"})); - generated.add(c2Generated); - ContainerFilter coreGenerated = new ContainerFilter("Core"); - coreGenerated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*core/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"})); - coreGenerated.add(new SpecificPathFilter("jvmtifiles", new String[] {".*core/generated/jvmtifiles/.*"})); - generated.add(coreGenerated); - ContainerFilter tieredGenerated = new ContainerFilter("Tiered"); - tieredGenerated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*tiered/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"})); - tieredGenerated.add(new SpecificPathFilter("adfiles", new String[] {".*tiered/generated/adfiles/.*"})); - tieredGenerated.add(new SpecificPathFilter("jvmtifiles", new String[] {".*tiered/generated/jvmtifiles/.*"})); - generated.add(tieredGenerated); - ContainerFilter kernelGenerated = new ContainerFilter("Kernel"); - kernelGenerated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*kernel/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"})); - kernelGenerated.add(new SpecificPathFilter("jvmtifiles", new String[] {".*kernel/generated/jvmtifiles/.*"})); - generated.add(kernelGenerated); - rv.add(generated); + void writeConfiguration(BuildConfig cfg) { + startTag("Configuration", new String[] { "Name", cfg.get("Name"), + "OutputDirectory", cfg.get("OutputDir"), + "IntermediateDirectory", cfg.get("OutputDir"), + "ConfigurationType", "2", "UseOfMFC", "0", + "ATLMinimizesCRunTimeLibraryUsage", "FALSE" }); - rv.add(new SpecificNameFilter("Precompiled Header", new String[] {"precompiled.hpp"})); - - // this one is to catch files not caught by other filters - rv.add(new TerminatorFilter("Source Files")); + tagV("Tool", cfg.getV("CompilerFlags")); - return rv; - } + tag("Tool", new String[] { "Name", "VCCustomBuildTool" }); - void writeFiles(Vector allConfigs) { - - Hashtable allFiles = computeAttributedFiles(allConfigs); + tagV("Tool", cfg.getV("LinkerFlags")); - Vector allConfigNames = new Vector(); - for (Iterator i = allConfigs.iterator(); i.hasNext(); ) { - allConfigNames.add(((BuildConfig)i.next()).get("Name")); - } - - TreeSet sortedFiles = sortFiles(allFiles); - - startTag("Files"); - - for (Iterator i = makeFilters(sortedFiles).iterator(); i.hasNext(); ) { - doWriteFiles(sortedFiles, allConfigNames, (NameFilter)i.next()); - } - - - startTag("Filter", - new String[] { - "Name", "Resource Files", - "Filter", "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" - } - ); - endTag("Filter"); - - endTag("Files"); - } + tag("Tool", + new String[] { + "Name", + "VCPostBuildEventTool", + "Description", + BuildConfig + .getFieldString(null, "PostbuildDescription"), + // Caution: String.replace(String,String) is available + // from JDK5 onwards only + "CommandLine", + cfg.expandFormat(BuildConfig.getFieldString(null, + "PostbuildCommand").replace("\t", + " ")) }); - void doWriteFiles(TreeSet allFiles, Vector allConfigNames, NameFilter filter) { - startTag("Filter", - new String[] { - "Name", filter.name(), - "Filter", filter.filterString() - } - ); - - if (filter instanceof ContainerFilter) { - - Iterator i = ((ContainerFilter)filter).babies(); - while (i.hasNext()) { - doWriteFiles(allFiles, allConfigNames, (NameFilter)i.next()); - } - - } else { - - Iterator i = allFiles.iterator(); - while (i.hasNext()) { - FileInfo fi = (FileInfo)i.next(); - - if (!filter.match(fi)) { - continue; - } + tag("Tool", new String[] { "Name", "VCPreBuildEventTool" }); - startTag("File", - new String[] { - "RelativePath", fi.full.replace('/', '\\') - } - ); - - FileAttribute a = fi.attr; - if (a.pchRoot) { - writeCustomToolConfig(allConfigNames, - new String[] { - "Name", "VCCLCompilerTool", - "UsePrecompiledHeader", "1" - }); - } - - if (a.noPch) { - writeCustomToolConfig(allConfigNames, - new String[] { - "Name", "VCCLCompilerTool", - "UsePrecompiledHeader", "0" - }); - } + tag("Tool", + new String[] { + "Name", + "VCPreLinkEventTool", + "Description", + BuildConfig.getFieldString(null, "PrelinkDescription"), + // Caution: String.replace(String,String) is available + // from JDK5 onwards only + "CommandLine", + cfg.expandFormat(BuildConfig.getFieldString(null, + "PrelinkCommand").replace("\t", " ")) }); - if (a.configs != null) { - for (Iterator j=allConfigNames.iterator(); j.hasNext();) { - String cfg = (String)j.next(); - if (!a.configs.contains(cfg)) { - startTag("FileConfiguration", - new String[] { - "Name", cfg, - "ExcludedFromBuild", "TRUE" - }); - endTag("FileConfiguration"); - - } - } - } - - endTag("File"); + tag("Tool", new String[] { "Name", "VCResourceCompilerTool", + "PreprocessorDefinitions", "NDEBUG", "Culture", "1033" }); - // we not gonna look at this file anymore - i.remove(); - } - } - - endTag("Filter"); - } - + tag("Tool", new String[] { "Name", "VCMIDLTool", + "PreprocessorDefinitions", "NDEBUG", "MkTypLibCompatible", + "TRUE", "SuppressStartupBanner", "TRUE", "TargetEnvironment", + "1", "TypeLibraryName", + cfg.get("OutputDir") + Util.sep + "vm.tlb", "HeaderFileName", + "" }); - void writeConfiguration(BuildConfig cfg) { - startTag("Configuration", - new String[] { - "Name", cfg.get("Name"), - "OutputDirectory", cfg.get("OutputDir"), - "IntermediateDirectory", cfg.get("OutputDir"), - "ConfigurationType", "2", - "UseOfMFC", "0", - "ATLMinimizesCRunTimeLibraryUsage", "FALSE" - } - ); + endTag(); + } - tagV("Tool", cfg.getV("CompilerFlags")); - - tag("Tool", - new String[] { - "Name", "VCCustomBuildTool" - } - ); - - tagV("Tool", cfg.getV("LinkerFlags")); - - tag("Tool", - new String[] { - "Name", "VCPostBuildEventTool", - "Description", BuildConfig.getFieldString(null, "PostbuildDescription"), - //Caution: String.replace(String,String) is available from JDK5 onwards only - "CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace - ("\t", " ")) - } - ); - - tag("Tool", - new String[] { - "Name", "VCPreBuildEventTool" - } - ); - - tag("Tool", - new String[] { - "Name", "VCPreLinkEventTool", - "Description", BuildConfig.getFieldString(null, "PrelinkDescription"), - //Caution: String.replace(String,String) is available from JDK5 onwards only - "CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace - ("\t", " ")) - } - ); - - tag("Tool", - new String[] { - "Name", "VCResourceCompilerTool", - // XXX??? - "PreprocessorDefinitions", "NDEBUG", - "Culture", "1033" - } - ); - - tag("Tool", - new String[] { - "Name", "VCMIDLTool", - "PreprocessorDefinitions", "NDEBUG", - "MkTypLibCompatible", "TRUE", - "SuppressStartupBanner", "TRUE", - "TargetEnvironment", "1", - "TypeLibraryName", cfg.get("OutputDir") + Util.sep + "vm.tlb", - "HeaderFileName", "" - } - ); - - endTag("Configuration"); - } - - int indent; - - private void startTagPrim(String name, - String[] attrs, - boolean close) { - startTagPrim(name, attrs, close, true); - } - - private void startTagPrim(String name, - String[] attrs, - boolean close, - boolean newline) { - doIndent(); - printWriter.print("<"+name); - indent++; - - if (attrs != null && attrs.length > 0) { - for (int i=0; i"); - } else { - printWriter.print(">"); - } - if(newline) { - printWriter.println(); - } - } - - void startTag(String name, String... attrs) { - startTagPrim(name, attrs, false); - } - - void startTagV(String name, Vector attrs) { - String s[] = new String [attrs.size()]; - for (int i=0; i"); - } - - void tag(String name, String... attrs) { - startTagPrim(name, attrs, true); - } - - void tagData(String name, String data) { - doIndent(); - printWriter.print("<"+name+">"); - printWriter.print(data); - printWriter.println(""); - } - - void tagData(String name, String data, String... attrs) { - startTagPrim(name, attrs, false, false); - printWriter.print(data); - printWriter.println(""); - indent--; - } - - void tagV(String name, Vector attrs) { - String s[] = new String [attrs.size()]; - for (int i=0; i_rChild->_opType,"DecodeN") || !strcmp(_matrule->_rChild->_opType,"EncodeP") || !strcmp(_matrule->_rChild->_opType,"LoadN") || + !strcmp(_matrule->_rChild->_opType,"GetAndSetN") || !strcmp(_matrule->_rChild->_opType,"LoadNKlass") || !strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception !strcmp(_matrule->_rChild->_opType,"CheckCastPP")) ) return true; @@ -3399,7 +3400,9 @@ "StorePConditional", "StoreIConditional", "StoreLConditional", "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN", "StoreCM", - "ClearArray" + "ClearArray", + "GetAndAddI", "GetAndSetI", "GetAndSetP", + "GetAndAddL", "GetAndSetL", "GetAndSetN", }; int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*); if( strcmp(_opType,"PrefetchRead")==0 || @@ -4040,18 +4043,27 @@ } bool MatchRule::is_vector() const { - if( _rChild ) { + static const char *vector_list[] = { + "AddVB","AddVS","AddVI","AddVL","AddVF","AddVD", + "SubVB","SubVS","SubVI","SubVL","SubVF","SubVD", + "MulVS","MulVI","MulVF","MulVD", + "DivVF","DivVD", + "AndV" ,"XorV" ,"OrV", + "LShiftVB","LShiftVS","LShiftVI","LShiftVL", + "RShiftVB","RShiftVS","RShiftVI","RShiftVL", + "URShiftVB","URShiftVS","URShiftVI","URShiftVL", + "ReplicateB","ReplicateS","ReplicateI","ReplicateL","ReplicateF","ReplicateD", + "LoadVector","StoreVector", + // Next are not supported currently. + "PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D", + "ExtractB","ExtractUB","ExtractC","ExtractS","ExtractI","ExtractL","ExtractF","ExtractD" + }; + int cnt = sizeof(vector_list)/sizeof(char*); + if (_rChild) { const char *opType = _rChild->_opType; - if( strcmp(opType,"ReplicateB")==0 || - strcmp(opType,"ReplicateS")==0 || - strcmp(opType,"ReplicateI")==0 || - strcmp(opType,"ReplicateL")==0 || - strcmp(opType,"ReplicateF")==0 || - strcmp(opType,"ReplicateD")==0 || - strcmp(opType,"LoadVector")==0 || - strcmp(opType,"StoreVector")==0 || - 0 /* 0 to line up columns nicely */ ) - return true; + for (int i=0; i_counters = _counters;\n",cnt); } + // Fill in the bottom_type where requested + if (node->captures_bottom_type(_globalNames) && + new_inst->captures_bottom_type(_globalNames)) { + fprintf(fp, " ((MachTypeNode*)n%d)->_bottom_type = bottom_type();\n", cnt); + } + const char *resultOper = new_inst->reduce_result(); fprintf(fp," n%d->set_opnd_array(0, state->MachOperGenerator( %s, C ));\n", cnt, machOperEnum(resultOper)); @@ -1767,7 +1773,7 @@ } fprintf(fp," kill = "); - fprintf(fp,"new (C, 1) MachProjNode( %s, %d, (%s), Op_%s );\n", + fprintf(fp,"new (C) MachProjNode( %s, %d, (%s), Op_%s );\n", machNode, proj_no++, regmask, ideal_type); fprintf(fp," proj_list.push(kill);\n"); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/asm/codeBuffer.cpp --- a/src/share/vm/asm/codeBuffer.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/asm/codeBuffer.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -1026,25 +1026,30 @@ } return a; } + + // Convenience for add_comment. + CodeComment* find_last(intptr_t offset) { + CodeComment* a = find(offset); + if (a != NULL) { + while ((a->_next != NULL) && (a->_next->_offset == offset)) { + a = a->_next; + } + } + return a; + } }; void CodeComments::add_comment(intptr_t offset, const char * comment) { - CodeComment* c = new CodeComment(offset, comment); - CodeComment* insert = NULL; - if (_comments != NULL) { - CodeComment* c = _comments->find(offset); - insert = c; - while (c && c->offset() == offset) { - insert = c; - c = c->next(); - } - } - if (insert) { - // insert after comments with same offset - c->set_next(insert->next()); - insert->set_next(c); + CodeComment* c = new CodeComment(offset, comment); + CodeComment* inspos = (_comments == NULL) ? NULL : _comments->find_last(offset); + + if (inspos) { + // insert after already existing comments with same offset + c->set_next(inspos->next()); + inspos->set_next(c); } else { + // no comments with such offset, yet. Insert before anything else. c->set_next(_comments); _comments = c; } @@ -1052,12 +1057,11 @@ void CodeComments::assign(CodeComments& other) { - assert(_comments == NULL, "don't overwrite old value"); _comments = other._comments; } -void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) { +void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) const { if (_comments != NULL) { CodeComment* c = _comments->find(offset); while (c && c->offset() == offset) { @@ -1085,6 +1089,7 @@ void CodeBuffer::decode() { + ttyLocker ttyl; Disassembler::decode(decode_begin(), insts_end()); _decode_begin = insts_end(); } @@ -1096,6 +1101,7 @@ void CodeBuffer::decode_all() { + ttyLocker ttyl; for (int n = 0; n < (int)SECT_LIMIT; n++) { // dump contents of each section CodeSection* cs = code_section(n); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/asm/codeBuffer.hpp --- a/src/share/vm/asm/codeBuffer.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/asm/codeBuffer.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -253,7 +253,7 @@ } void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; - void print_block_comment(outputStream* stream, intptr_t offset) PRODUCT_RETURN; + void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN; void assign(CodeComments& other) PRODUCT_RETURN; void free() PRODUCT_RETURN; }; diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/asm/register.hpp --- a/src/share/vm/asm/register.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/asm/register.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -103,8 +103,8 @@ ) { assert( a != b, - err_msg("registers must be different: a=%d, b=%d", - a, b) + err_msg_res("registers must be different: a=%d, b=%d", + a, b) ); } @@ -117,8 +117,8 @@ assert( a != b && a != c && b != c, - err_msg("registers must be different: a=%d, b=%d, c=%d", - a, b, c) + err_msg_res("registers must be different: a=%d, b=%d, c=%d", + a, b, c) ); } @@ -133,8 +133,8 @@ a != b && a != c && a != d && b != c && b != d && c != d, - err_msg("registers must be different: a=%d, b=%d, c=%d, d=%d", - a, b, c, d) + err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d", + a, b, c, d) ); } @@ -151,8 +151,8 @@ && b != c && b != d && b != e && c != d && c != e && d != e, - err_msg("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d", - a, b, c, d, e) + err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d", + a, b, c, d, e) ); } @@ -171,8 +171,8 @@ && c != d && c != e && c != f && d != e && d != f && e != f, - err_msg("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d", - a, b, c, d, e, f) + err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d", + a, b, c, d, e, f) ); } @@ -193,8 +193,8 @@ && d != e && d != f && d != g && e != f && e != g && f != g, - err_msg("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d", - a, b, c, d, e, f, g) + err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d", + a, b, c, d, e, f, g) ); } @@ -217,8 +217,8 @@ && e != f && e != g && e != h && f != g && f != h && g != h, - err_msg("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d", - a, b, c, d, e, f, g, h) + err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d", + a, b, c, d, e, f, g, h) ); } @@ -243,8 +243,8 @@ && f != g && f != h && f != i && g != h && g != i && h != i, - err_msg("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d", - a, b, c, d, e, f, g, h, i) + err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d", + a, b, c, d, e, f, g, h, i) ); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_Canonicalizer.cpp --- a/src/share/vm/c1/c1_Canonicalizer.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_Canonicalizer.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -931,6 +931,7 @@ void Canonicalizer::do_UnsafePutRaw(UnsafePutRaw* x) { if (OptimizeUnsafes) do_UnsafeRawOp(x); } void Canonicalizer::do_UnsafeGetObject(UnsafeGetObject* x) {} void Canonicalizer::do_UnsafePutObject(UnsafePutObject* x) {} +void Canonicalizer::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {} void Canonicalizer::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {} void Canonicalizer::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} void Canonicalizer::do_ProfileCall(ProfileCall* x) {} diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_Canonicalizer.hpp --- a/src/share/vm/c1/c1_Canonicalizer.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_Canonicalizer.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -100,6 +100,7 @@ virtual void do_UnsafePutRaw (UnsafePutRaw* x); virtual void do_UnsafeGetObject(UnsafeGetObject* x); virtual void do_UnsafePutObject(UnsafePutObject* x); + virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x); virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_Compilation.cpp --- a/src/share/vm/c1/c1_Compilation.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_Compilation.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -346,7 +346,8 @@ implicit_exception_table(), compiler(), _env->comp_level(), - has_unsafe_access() + has_unsafe_access(), + SharedRuntime::is_wide_vector(max_vector_size()) ); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_Compilation.hpp --- a/src/share/vm/c1/c1_Compilation.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_Compilation.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -127,6 +127,7 @@ bool has_exception_handlers() const { return _has_exception_handlers; } bool has_fpu_code() const { return _has_fpu_code; } bool has_unsafe_access() const { return _has_unsafe_access; } + int max_vector_size() const { return 0; } ciMethod* method() const { return _method; } int osr_bci() const { return _osr_bci; } bool is_osr_compile() const { return osr_bci() >= 0; } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -3383,6 +3383,41 @@ append_unsafe_CAS(callee); return true; + case vmIntrinsics::_getAndAddInt: + if (!VM_Version::supports_atomic_getadd4()) { + return false; + } + return append_unsafe_get_and_set_obj(callee, true); + case vmIntrinsics::_getAndAddLong: + if (!VM_Version::supports_atomic_getadd8()) { + return false; + } + return append_unsafe_get_and_set_obj(callee, true); + case vmIntrinsics::_getAndSetInt: + if (!VM_Version::supports_atomic_getset4()) { + return false; + } + return append_unsafe_get_and_set_obj(callee, false); + case vmIntrinsics::_getAndSetLong: + if (!VM_Version::supports_atomic_getset8()) { + return false; + } + return append_unsafe_get_and_set_obj(callee, false); + case vmIntrinsics::_getAndSetObject: +#ifdef _LP64 + if (!UseCompressedOops && !VM_Version::supports_atomic_getset8()) { + return false; + } + if (UseCompressedOops && !VM_Version::supports_atomic_getset4()) { + return false; + } +#else + if (!VM_Version::supports_atomic_getset4()) { + return false; + } +#endif + return append_unsafe_get_and_set_obj(callee, false); + case vmIntrinsics::_Reference_get: // Use the intrinsic version of Reference.get() so that the value in // the referent field can be registered by the G1 pre-barrier code. @@ -4106,6 +4141,22 @@ } } +bool GraphBuilder::append_unsafe_get_and_set_obj(ciMethod* callee, bool is_add) { + if (InlineUnsafeOps) { + Values* args = state()->pop_arguments(callee->arg_size()); + BasicType t = callee->return_type()->basic_type(); + null_check(args->at(0)); + Instruction* offset = args->at(2); +#ifndef _LP64 + offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); +#endif + Instruction* op = append(new UnsafeGetAndSetObject(t, args->at(1), offset, args->at(3), is_add)); + compilation()->set_has_unsafe_access(true); + kill_all(); + push(op->type(), op); + } + return InlineUnsafeOps; +} #ifndef PRODUCT void GraphBuilder::print_stats() { diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_GraphBuilder.hpp --- a/src/share/vm/c1/c1_GraphBuilder.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_GraphBuilder.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -367,6 +367,7 @@ bool append_unsafe_put_raw(ciMethod* callee, BasicType t); bool append_unsafe_prefetch(ciMethod* callee, bool is_store, bool is_static); void append_unsafe_CAS(ciMethod* callee); + bool append_unsafe_get_and_set_obj(ciMethod* callee, bool is_add); void print_inlining(ciMethod* callee, const char* msg, bool success = true); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_Instruction.hpp --- a/src/share/vm/c1/c1_Instruction.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_Instruction.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -102,6 +102,7 @@ class UnsafeObjectOp; class UnsafeGetObject; class UnsafePutObject; +class UnsafeGetAndSetObject; class UnsafePrefetch; class UnsafePrefetchRead; class UnsafePrefetchWrite; @@ -202,6 +203,7 @@ virtual void do_UnsafePutRaw (UnsafePutRaw* x) = 0; virtual void do_UnsafeGetObject(UnsafeGetObject* x) = 0; virtual void do_UnsafePutObject(UnsafePutObject* x) = 0; + virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) = 0; virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x) = 0; virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0; virtual void do_ProfileCall (ProfileCall* x) = 0; @@ -2273,6 +2275,27 @@ f->visit(&_value); } }; +LEAF(UnsafeGetAndSetObject, UnsafeObjectOp) + private: + Value _value; // Value to be stored + bool _is_add; + public: + UnsafeGetAndSetObject(BasicType basic_type, Value object, Value offset, Value value, bool is_add) + : UnsafeObjectOp(basic_type, object, offset, false, false) + , _value(value) + , _is_add(is_add) + { + ASSERT_VALUES + } + + // accessors + bool is_add() const { return _is_add; } + Value value() { return _value; } + + // generic + virtual void input_values_do(ValueVisitor* f) { UnsafeObjectOp::input_values_do(f); + f->visit(&_value); } +}; BASE(UnsafePrefetch, UnsafeObjectOp) public: diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_InstructionPrinter.cpp --- a/src/share/vm/c1/c1_InstructionPrinter.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_InstructionPrinter.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -831,6 +831,12 @@ output()->put(')'); } +void InstructionPrinter::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { + print_unsafe_object_op(x, x->is_add()?"UnsafeGetAndSetObject (add)":"UnsafeGetAndSetObject"); + output()->print(", value "); + print_value(x->value()); + output()->put(')'); +} void InstructionPrinter::do_UnsafePrefetchRead(UnsafePrefetchRead* x) { print_unsafe_object_op(x, "UnsafePrefetchRead"); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_InstructionPrinter.hpp --- a/src/share/vm/c1/c1_InstructionPrinter.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_InstructionPrinter.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -128,6 +128,7 @@ virtual void do_UnsafePutRaw (UnsafePutRaw* x); virtual void do_UnsafeGetObject(UnsafeGetObject* x); virtual void do_UnsafePutObject(UnsafePutObject* x); + virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x); virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_LIR.cpp --- a/src/share/vm/c1/c1_LIR.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_LIR.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -264,6 +264,7 @@ #ifdef ASSERT switch (code()) { case lir_cmove: + case lir_xchg: break; default: @@ -630,6 +631,8 @@ case lir_shl: case lir_shr: case lir_ushr: + case lir_xadd: + case lir_xchg: { assert(op->as_Op2() != NULL, "must be"); LIR_Op2* op2 = (LIR_Op2*)op; @@ -641,6 +644,13 @@ if (op2->_opr2->is_valid()) do_input(op2->_opr2); if (op2->_tmp1->is_valid()) do_temp(op2->_tmp1); if (op2->_result->is_valid()) do_output(op2->_result); + if (op->code() == lir_xchg || op->code() == lir_xadd) { + // on ARM and PPC, return value is loaded first so could + // destroy inputs. On other platforms that implement those + // (x86, sparc), the extra constrainsts are harmless. + if (op2->_opr1->is_valid()) do_temp(op2->_opr1); + if (op2->_opr2->is_valid()) do_temp(op2->_opr2); + } break; } @@ -1733,6 +1743,8 @@ case lir_shr: s = "shift_right"; break; case lir_ushr: s = "ushift_right"; break; case lir_alloc_array: s = "alloc_array"; break; + case lir_xadd: s = "xadd"; break; + case lir_xchg: s = "xchg"; break; // LIR_Op3 case lir_idiv: s = "idiv"; break; case lir_irem: s = "irem"; break; diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_LIR.hpp --- a/src/share/vm/c1/c1_LIR.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_LIR.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -963,6 +963,8 @@ , lir_alloc_array , lir_throw , lir_compare_to + , lir_xadd + , lir_xchg , end_op2 , begin_op3 , lir_idiv @@ -2191,6 +2193,9 @@ void profile_call(ciMethod* method, int bci, ciMethod* callee, LIR_Opr mdo, LIR_Opr recv, LIR_Opr t1, ciKlass* cha_klass) { append(new LIR_OpProfileCall(lir_profile_call, method, bci, callee, mdo, recv, t1, cha_klass)); } + + void xadd(LIR_Opr src, LIR_Opr add, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xadd, src, add, res, tmp)); } + void xchg(LIR_Opr src, LIR_Opr set, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xchg, src, set, res, tmp)); } }; void print_LIR(BlockList* blocks); @@ -2287,16 +2292,21 @@ LIR_Address* address = opr->as_address_ptr(); if (address != NULL) { // special handling for addresses: add base and index register of the address - // both are always input operands! + // both are always input operands or temp if we want to extend + // their liveness! + if (mode == outputMode) { + mode = inputMode; + } + assert (mode == inputMode || mode == tempMode, "input or temp only for addresses"); if (address->_base->is_valid()) { assert(address->_base->is_register(), "must be"); - assert(_oprs_len[inputMode] < maxNumberOfOperands, "array overflow"); - _oprs_new[inputMode][_oprs_len[inputMode]++] = &address->_base; + assert(_oprs_len[mode] < maxNumberOfOperands, "array overflow"); + _oprs_new[mode][_oprs_len[mode]++] = &address->_base; } if (address->_index->is_valid()) { assert(address->_index->is_register(), "must be"); - assert(_oprs_len[inputMode] < maxNumberOfOperands, "array overflow"); - _oprs_new[inputMode][_oprs_len[inputMode]++] = &address->_index; + assert(_oprs_len[mode] < maxNumberOfOperands, "array overflow"); + _oprs_new[mode][_oprs_len[mode]++] = &address->_index; } } else { diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_LIRAssembler.cpp --- a/src/share/vm/c1/c1_LIRAssembler.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_LIRAssembler.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -773,6 +773,11 @@ throw_op(op->in_opr1(), op->in_opr2(), op->info()); break; + case lir_xadd: + case lir_xchg: + atomic_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->tmp1_opr()); + break; + default: Unimplemented(); break; diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_LIRAssembler.hpp --- a/src/share/vm/c1/c1_LIRAssembler.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_LIRAssembler.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -252,6 +252,8 @@ void verify_oop_map(CodeEmitInfo* info); + void atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp); + #ifdef TARGET_ARCH_x86 # include "c1_LIRAssembler_x86.hpp" #endif diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_LIRGenerator.hpp --- a/src/share/vm/c1/c1_LIRGenerator.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_LIRGenerator.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -527,6 +527,7 @@ virtual void do_UnsafePutRaw (UnsafePutRaw* x); virtual void do_UnsafeGetObject(UnsafeGetObject* x); virtual void do_UnsafePutObject(UnsafePutObject* x); + virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x); virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_Optimizer.cpp --- a/src/share/vm/c1/c1_Optimizer.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_Optimizer.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -505,6 +505,7 @@ void do_UnsafePutRaw (UnsafePutRaw* x); void do_UnsafeGetObject(UnsafeGetObject* x); void do_UnsafePutObject(UnsafePutObject* x); + void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x); void do_UnsafePrefetchRead (UnsafePrefetchRead* x); void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); void do_ProfileCall (ProfileCall* x); @@ -676,6 +677,7 @@ void NullCheckVisitor::do_UnsafePutRaw (UnsafePutRaw* x) {} void NullCheckVisitor::do_UnsafeGetObject(UnsafeGetObject* x) {} void NullCheckVisitor::do_UnsafePutObject(UnsafePutObject* x) {} +void NullCheckVisitor::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {} void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {} void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/c1/c1_ValueMap.hpp --- a/src/share/vm/c1/c1_ValueMap.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/c1/c1_ValueMap.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -157,6 +157,7 @@ void do_Invoke (Invoke* x) { kill_memory(); } void do_UnsafePutRaw (UnsafePutRaw* x) { kill_memory(); } void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); } + void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { kill_memory(); } void do_Intrinsic (Intrinsic* x) { if (!x->preserves_state()) kill_memory(); } void do_Phi (Phi* x) { /* nothing to do */ } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/ci/ciEnv.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -921,7 +921,8 @@ ImplicitExceptionTable* inc_table, AbstractCompiler* compiler, int comp_level, - bool has_unsafe_access) { + bool has_unsafe_access, + bool has_wide_vectors) { VM_ENTRY_MARK; nmethod* nm = NULL; { @@ -1016,6 +1017,7 @@ } } else { nm->set_has_unsafe_access(has_unsafe_access); + nm->set_has_wide_vectors(has_wide_vectors); // Record successful registration. // (Put nm into the task handle *before* publishing to the Java heap.) diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/ci/ciEnv.hpp --- a/src/share/vm/ci/ciEnv.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/ci/ciEnv.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -362,7 +362,8 @@ ImplicitExceptionTable* inc_table, AbstractCompiler* compiler, int comp_level, - bool has_unsafe_access); + bool has_unsafe_access, + bool has_wide_vectors); // Access to certain well known ciObjects. diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -873,6 +873,20 @@ do_name( putOrderedInt_name, "putOrderedInt") \ do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \ \ + do_intrinsic(_getAndAddInt, sun_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \ + do_name( getAndAddInt_name, "getAndAddInt") \ + do_signature(getAndAddInt_signature, "(Ljava/lang/Object;JI)I" ) \ + do_intrinsic(_getAndAddLong, sun_misc_Unsafe, getAndAddLong_name, getAndAddLong_signature, F_R) \ + do_name( getAndAddLong_name, "getAndAddLong") \ + do_signature(getAndAddLong_signature, "(Ljava/lang/Object;JJ)J" ) \ + do_intrinsic(_getAndSetInt, sun_misc_Unsafe, getAndSet_name, getAndSetInt_signature, F_R) \ + do_name( getAndSet_name, "getAndSet") \ + do_alias( getAndSetInt_signature, /*"(Ljava/lang/Object;JI)I"*/ getAndAddInt_signature) \ + do_intrinsic(_getAndSetLong, sun_misc_Unsafe, getAndSet_name, getAndSetLong_signature, F_R) \ + do_alias( getAndSetLong_signature, /*"(Ljava/lang/Object;JJ)J"*/ getAndAddLong_signature) \ + do_intrinsic(_getAndSetObject, sun_misc_Unsafe, getAndSet_name, getAndSetObject_signature, F_R) \ + do_signature(getAndSetObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \ + \ /* prefetch_signature is shared by all prefetch variants */ \ do_signature( prefetch_signature, "(Ljava/lang/Object;J)V") \ \ diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/code/codeBlob.cpp --- a/src/share/vm/code/codeBlob.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/code/codeBlob.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -162,8 +162,10 @@ assert(strlen(name1) + strlen(name2) < sizeof(stub_id), ""); jio_snprintf(stub_id, sizeof(stub_id), "%s%s", name1, name2); if (PrintStubCode) { + ttyLocker ttyl; tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, (intptr_t) stub); Disassembler::decode(stub->code_begin(), stub->code_end()); + tty->cr(); } Forte::register_stub(stub_id, stub->code_begin(), stub->code_end()); @@ -548,6 +550,7 @@ } void RuntimeStub::print_on(outputStream* st) const { + ttyLocker ttyl; CodeBlob::print_on(st); st->print("Runtime Stub (" INTPTR_FORMAT "): ", this); st->print_cr(name()); @@ -563,6 +566,7 @@ } void SingletonBlob::print_on(outputStream* st) const { + ttyLocker ttyl; CodeBlob::print_on(st); st->print_cr(name()); Disassembler::decode((CodeBlob*)this, st); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/code/codeBlob.hpp --- a/src/share/vm/code/codeBlob.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/code/codeBlob.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -184,7 +184,7 @@ static void trace_new_stub(CodeBlob* blob, const char* name1, const char* name2 = ""); // Print the comment associated with offset on stream, if there is one - virtual void print_block_comment(outputStream* stream, address block_begin) { + virtual void print_block_comment(outputStream* stream, address block_begin) const { intptr_t offset = (intptr_t)(block_begin - code_begin()); _comments.print_block_comment(stream, offset); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/code/icBuffer.hpp --- a/src/share/vm/code/icBuffer.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/code/icBuffer.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -25,6 +25,7 @@ #ifndef SHARE_VM_CODE_ICBUFFER_HPP #define SHARE_VM_CODE_ICBUFFER_HPP +#include "asm/codeBuffer.hpp" #include "code/stubs.hpp" #include "interpreter/bytecodes.hpp" #include "memory/allocation.hpp" @@ -48,7 +49,8 @@ protected: friend class ICStubInterface; // This will be called only by ICStubInterface - void initialize(int size) { _size = size; _ic_site = NULL; } + void initialize(int size, + CodeComments comments) { _size = size; _ic_site = NULL; } void finalize(); // called when a method is removed // General info diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/code/nmethod.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -463,6 +463,7 @@ _has_unsafe_access = 0; _has_method_handle_invokes = 0; _lazy_critical_native = 0; + _has_wide_vectors = 0; _marked_for_deoptimization = 0; _lock_count = 0; _stack_traversal_mark = 0; @@ -700,7 +701,9 @@ // then print the requested information if (PrintNativeNMethods) { print_code(); - oop_maps->print(); + if (oop_maps != NULL) { + oop_maps->print(); + } } if (PrintRelocations) { print_relocations(); @@ -2666,7 +2669,7 @@ return NULL; } -void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) { +void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) const { if (block_begin == entry_point()) stream->print_cr("[Entry Point]"); if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]"); if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/code/nmethod.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -177,6 +177,7 @@ unsigned int _has_unsafe_access:1; // May fault due to unsafe access. unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes? unsigned int _lazy_critical_native:1; // Lazy JNI critical native + unsigned int _has_wide_vectors:1; // Preserve wide vectors at safepoints // Protected by Patching_lock unsigned char _state; // {alive, not_entrant, zombie, unloaded} @@ -442,6 +443,9 @@ bool is_lazy_critical_native() const { return _lazy_critical_native; } void set_lazy_critical_native(bool z) { _lazy_critical_native = z; } + bool has_wide_vectors() const { return _has_wide_vectors; } + void set_has_wide_vectors(bool z) { _has_wide_vectors = z; } + int comp_level() const { return _comp_level; } // Support for oops in scopes and relocs: @@ -647,11 +651,11 @@ void log_state_change() const; // Prints block-level comments, including nmethod specific block labels: - virtual void print_block_comment(outputStream* stream, address block_begin) { + virtual void print_block_comment(outputStream* stream, address block_begin) const { print_nmethod_labels(stream, block_begin); CodeBlob::print_block_comment(stream, block_begin); } - void print_nmethod_labels(outputStream* stream, address block_begin); + void print_nmethod_labels(outputStream* stream, address block_begin) const; // Prints a comment for one native instruction (reloc info, pc desc) void print_code_comment_on(outputStream* st, int column, address begin, address end); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/code/stubs.cpp --- a/src/share/vm/code/stubs.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/code/stubs.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -101,7 +101,8 @@ Stub* StubQueue::request_committed(int code_size) { Stub* s = request(code_size); - if (s != NULL) commit(code_size); + CodeComments comments; + if (s != NULL) commit(code_size, comments); return s; } @@ -118,7 +119,8 @@ assert(_buffer_limit == _buffer_size, "buffer must be fully usable"); if (_queue_end + requested_size <= _buffer_size) { // code fits in at the end => nothing to do - stub_initialize(s, requested_size); + CodeComments comments; + stub_initialize(s, requested_size, comments); return s; } else { // stub doesn't fit in at the queue end @@ -135,7 +137,8 @@ // Queue: |XXX|.......|XXXXXXX|.......| // ^0 ^end ^begin ^limit ^size s = current_stub(); - stub_initialize(s, requested_size); + CodeComments comments; + stub_initialize(s, requested_size, comments); return s; } // Not enough space left @@ -144,12 +147,12 @@ } -void StubQueue::commit(int committed_code_size) { +void StubQueue::commit(int committed_code_size, CodeComments& comments) { assert(committed_code_size > 0, "committed_code_size must be > 0"); int committed_size = round_to(stub_code_size_to_size(committed_code_size), CodeEntryAlignment); Stub* s = current_stub(); assert(committed_size <= stub_size(s), "committed size must not exceed requested size"); - stub_initialize(s, committed_size); + stub_initialize(s, committed_size, comments); _queue_end += committed_size; _number_of_stubs++; if (_mutex != NULL) _mutex->unlock(); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/code/stubs.hpp --- a/src/share/vm/code/stubs.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/code/stubs.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -25,6 +25,7 @@ #ifndef SHARE_VM_CODE_STUBS_HPP #define SHARE_VM_CODE_STUBS_HPP +#include "asm/codeBuffer.hpp" #include "memory/allocation.hpp" #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" @@ -71,7 +72,8 @@ class Stub VALUE_OBJ_CLASS_SPEC { public: // Initialization/finalization - void initialize(int size) { ShouldNotCallThis(); } // called to initialize/specify the stub's size + void initialize(int size, + CodeComments& comments) { ShouldNotCallThis(); } // called to initialize/specify the stub's size void finalize() { ShouldNotCallThis(); } // called before the stub is deallocated // General info/converters @@ -104,7 +106,8 @@ class StubInterface: public CHeapObj { public: // Initialization/finalization - virtual void initialize(Stub* self, int size) = 0; // called after creation (called twice if allocated via (request, commit)) + virtual void initialize(Stub* self, int size, + CodeComments& comments) = 0; // called after creation (called twice if allocated via (request, commit)) virtual void finalize(Stub* self) = 0; // called before deallocation // General info/converters @@ -132,7 +135,8 @@ \ public: \ /* Initialization/finalization */ \ - virtual void initialize(Stub* self, int size) { cast(self)->initialize(size); } \ + virtual void initialize(Stub* self, int size, \ + CodeComments& comments) { cast(self)->initialize(size, comments); } \ virtual void finalize(Stub* self) { cast(self)->finalize(); } \ \ /* General info */ \ @@ -171,7 +175,8 @@ Stub* current_stub() const { return stub_at(_queue_end); } // Stub functionality accessed via interface - void stub_initialize(Stub* s, int size) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size); } + void stub_initialize(Stub* s, int size, + CodeComments& comments) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, comments); } void stub_finalize(Stub* s) { _stub_interface->finalize(s); } int stub_size(Stub* s) const { return _stub_interface->size(s); } bool stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); } @@ -200,7 +205,8 @@ // Stub allocation (atomic transactions) Stub* request_committed(int code_size); // request a stub that provides exactly code_size space for code Stub* request(int requested_code_size); // request a stub with a (maximum) code space - locks the queue - void commit (int committed_code_size); // commit the previously requested stub - unlocks the queue + void commit (int committed_code_size, + CodeComments& comments); // commit the previously requested stub - unlocks the queue // Stub deallocation void remove_first(); // remove the first stub in the queue diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -197,9 +197,9 @@ void log_compile(JavaThread* thread, CompileTask* task) { StringLogMessage lm; - stringStream msg = lm.stream(); + stringStream sstr = lm.stream(); // msg.time_stamp().update_to(tty->time_stamp().ticks()); - task->print_compilation(&msg, true); + task->print_compilation(&sstr, NULL, true); log(thread, "%s", (const char*)lm); } @@ -491,9 +491,9 @@ // ------------------------------------------------------------------ // CompileTask::print_compilation -void CompileTask::print_compilation(outputStream* st, bool short_form) { +void CompileTask::print_compilation(outputStream* st, const char* msg, bool short_form) { bool is_osr_method = osr_bci() != InvocationEntryBci; - print_compilation_impl(st, method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), NULL, short_form); + print_compilation_impl(st, method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form); } // ------------------------------------------------------------------ @@ -1249,7 +1249,7 @@ // We accept a higher level osr method nmethod* nm = method->lookup_osr_nmethod_for(osr_bci, comp_level, false); if (nm != NULL) return nm; - if (method->is_not_osr_compilable()) return NULL; + if (method->is_not_osr_compilable(comp_level)) return NULL; } assert(!HAS_PENDING_EXCEPTION, "No exception should be present"); @@ -1330,7 +1330,7 @@ int comp_level) { bool is_osr = (osr_bci != standard_entry_bci); if (is_osr) { - if (method->is_not_osr_compilable()) { + if (method->is_not_osr_compilable(comp_level)) { return true; } else { nmethod* result = method->lookup_osr_nmethod_for(osr_bci, comp_level, true); @@ -1381,7 +1381,7 @@ // Some compilers may not support on stack replacement. if (is_osr && (!CICompileOSR || !compiler(comp_level)->supports_osr())) { - method->set_not_osr_compilable(); + method->set_not_osr_compilable(comp_level); return true; } @@ -1807,11 +1807,10 @@ _compilation_log->log_failure(thread, task, ci_env.failure_reason(), retry_message); } if (PrintCompilation) { - tty->print("%4d COMPILE SKIPPED: %s", compile_id, ci_env.failure_reason()); - if (retry_message != NULL) { - tty->print(" (%s)", retry_message); - } - tty->cr(); + FormatBufferResource msg = retry_message != NULL ? + err_msg_res("COMPILE SKIPPED: %s (%s)", ci_env.failure_reason(), retry_message) : + err_msg_res("COMPILE SKIPPED: %s", ci_env.failure_reason()); + task->print_compilation(tty, msg); } } else { task->mark_success(); @@ -1840,14 +1839,20 @@ tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, (int)time.milliseconds(), task->num_inlined_bytecodes()); } - if (compilable == ciEnv::MethodCompilable_never) { - if (is_osr) { - method->set_not_osr_compilable(); - } else { + // Disable compilation, if required. + switch (compilable) { + case ciEnv::MethodCompilable_never: + if (is_osr) + method->set_not_osr_compilable_quietly(); + else method->set_not_compilable_quietly(); - } - } else if (compilable == ciEnv::MethodCompilable_not_at_tier) { - method->set_not_compilable_quietly(task->comp_level()); + break; + case ciEnv::MethodCompilable_not_at_tier: + if (is_osr) + method->set_not_osr_compilable_quietly(task->comp_level()); + else + method->set_not_compilable_quietly(task->comp_level()); + break; } // Note that the queued_for_compilation bits are cleared without diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/compiler/compileBroker.hpp --- a/src/share/vm/compiler/compileBroker.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/compiler/compileBroker.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -105,7 +105,7 @@ const char* msg = NULL, bool short_form = false); public: - void print_compilation(outputStream* st = tty, bool short_form = false); + void print_compilation(outputStream* st = tty, const char* msg = NULL, bool short_form = false); static void print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false) { print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(), nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false, diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/compiler/compileLog.cpp --- a/src/share/vm/compiler/compileLog.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/compiler/compileLog.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -125,46 +125,46 @@ ciMetadata* mobj = obj->as_metadata(); if (mobj->is_klass()) { ciKlass* klass = mobj->as_klass(); - begin_elem("klass id='%d'", id); - name(klass->name()); - if (!klass->is_loaded()) { - print(" unloaded='1'"); - } else { - print(" flags='%d'", klass->modifier_flags()); - } - end_elem(); + begin_elem("klass id='%d'", id); + name(klass->name()); + if (!klass->is_loaded()) { + print(" unloaded='1'"); + } else { + print(" flags='%d'", klass->modifier_flags()); + } + end_elem(); } else if (mobj->is_method()) { ciMethod* method = mobj->as_method(); - ciSignature* sig = method->signature(); - // Pre-identify items that we will need! - identify(sig->return_type()); - for (int i = 0; i < sig->count(); i++) { - identify(sig->type_at(i)); - } - begin_elem("method id='%d' holder='%d'", - id, identify(method->holder())); - name(method->name()); - print(" return='%d'", identify(sig->return_type())); - if (sig->count() > 0) { - print(" arguments='"); + ciSignature* sig = method->signature(); + // Pre-identify items that we will need! + identify(sig->return_type()); for (int i = 0; i < sig->count(); i++) { - print((i == 0) ? "%d" : " %d", identify(sig->type_at(i))); + identify(sig->type_at(i)); } - print("'"); - } - if (!method->is_loaded()) { - print(" unloaded='1'"); - } else { - print(" flags='%d'", (jchar) method->flags().as_int()); - // output a few metrics - print(" bytes='%d'", method->code_size()); - method->log_nmethod_identity(this); - //print(" count='%d'", method->invocation_count()); - //int bec = method->backedge_count(); - //if (bec != 0) print(" backedge_count='%d'", bec); - print(" iicount='%d'", method->interpreter_invocation_count()); - } - end_elem(); + begin_elem("method id='%d' holder='%d'", + id, identify(method->holder())); + name(method->name()); + print(" return='%d'", identify(sig->return_type())); + if (sig->count() > 0) { + print(" arguments='"); + for (int i = 0; i < sig->count(); i++) { + print((i == 0) ? "%d" : " %d", identify(sig->type_at(i))); + } + print("'"); + } + if (!method->is_loaded()) { + print(" unloaded='1'"); + } else { + print(" flags='%d'", (jchar) method->flags().as_int()); + // output a few metrics + print(" bytes='%d'", method->code_size()); + method->log_nmethod_identity(this); + //print(" count='%d'", method->invocation_count()); + //int bec = method->backedge_count(); + //if (bec != 0) print(" backedge_count='%d'", bec); + print(" iicount='%d'", method->interpreter_invocation_count()); + } + end_elem(); } else if (mobj->is_type()) { BasicType type = mobj->as_type()->basic_type(); elem("type id='%d' name='%s'", id, type2name(type)); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/compiler/disassembler.cpp --- a/src/share/vm/compiler/disassembler.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/compiler/disassembler.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -148,6 +148,7 @@ private: nmethod* _nm; CodeBlob* _code; + CodeComments _comments; outputStream* _output; address _start, _end; @@ -187,7 +188,7 @@ void print_address(address value); public: - decode_env(CodeBlob* code, outputStream* output); + decode_env(CodeBlob* code, outputStream* output, CodeComments c = CodeComments()); address decode_instructions(address start, address end); @@ -231,12 +232,13 @@ const char* options() { return _option_buf; } }; -decode_env::decode_env(CodeBlob* code, outputStream* output) { +decode_env::decode_env(CodeBlob* code, outputStream* output, CodeComments c) { memset(this, 0, sizeof(*this)); _output = output ? output : tty; _code = code; if (code != NULL && code->is_nmethod()) _nm = (nmethod*) code; + _comments.assign(c); // by default, output pc but not bytes: _print_pc = true; @@ -358,6 +360,7 @@ if (cb != NULL) { cb->print_block_comment(st, p); } + _comments.print_block_comment(st, (intptr_t)(p - _start)); if (_print_pc) { st->print(" " PTR_FORMAT ": ", p); } @@ -471,10 +474,9 @@ env.decode_instructions(cb->code_begin(), cb->code_end()); } - -void Disassembler::decode(address start, address end, outputStream* st) { +void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) { if (!load_library()) return; - decode_env env(CodeCache::find_blob_unsafe(start), st); + decode_env env(CodeCache::find_blob_unsafe(start), st, c); env.decode_instructions(start, end); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/compiler/disassembler.hpp --- a/src/share/vm/compiler/disassembler.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/compiler/disassembler.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -25,6 +25,7 @@ #ifndef SHARE_VM_COMPILER_DISASSEMBLER_HPP #define SHARE_VM_COMPILER_DISASSEMBLER_HPP +#include "asm/codeBuffer.hpp" #include "runtime/globals.hpp" #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" @@ -88,7 +89,7 @@ } static void decode(CodeBlob *cb, outputStream* st = NULL); static void decode(nmethod* nm, outputStream* st = NULL); - static void decode(address begin, address end, outputStream* st = NULL); + static void decode(address begin, address end, outputStream* st = NULL, CodeComments c = CodeComments()); }; #endif // SHARE_VM_COMPILER_DISASSEMBLER_HPP diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/interpreter/interpreter.cpp --- a/src/share/vm/interpreter/interpreter.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/interpreter/interpreter.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -60,6 +60,8 @@ void InterpreterCodelet::print_on(outputStream* st) const { + ttyLocker ttyl; + if (PrintInterpreter) { st->cr(); st->print_cr("----------------------------------------------------------------------"); @@ -72,7 +74,7 @@ if (PrintInterpreter) { st->cr(); - Disassembler::decode(code_begin(), code_end(), st); + Disassembler::decode(code_begin(), code_end(), st, DEBUG_ONLY(_comments) NOT_DEBUG(CodeComments())); } } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/interpreter/interpreter.hpp --- a/src/share/vm/interpreter/interpreter.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/interpreter/interpreter.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -48,10 +48,12 @@ int _size; // the size in bytes const char* _description; // a description of the codelet, for debugging & printing Bytecodes::Code _bytecode; // associated bytecode if any + DEBUG_ONLY(CodeComments _comments;) // Comments for annotating assembler output. public: // Initialization/finalization - void initialize(int size) { _size = size; } + void initialize(int size, + CodeComments& comments) { _size = size; DEBUG_ONLY(_comments.assign(comments);) } void finalize() { ShouldNotCallThis(); } // General info/converters @@ -129,7 +131,7 @@ // commit Codelet - AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size()); + AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size(), (*_masm)->code()->comments()); // make sure nobody can use _masm outside a CodeletMark lifespan *_masm = NULL; } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/oops/method.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -251,8 +251,12 @@ int Method::bci_from(address bcp) const { +#ifdef ASSERT + { ResourceMark rm; assert(is_native() && bcp == code_base() || contains(bcp) || is_error_reported(), err_msg("bcp doesn't belong to this method: bcp: " INTPTR_FORMAT ", method: %s", bcp, name_and_sig_as_C_string())); + } +#endif return bcp - code_base(); } @@ -688,30 +692,18 @@ } -bool Method::is_not_compilable(int comp_level) const { - if (number_of_breakpoints() > 0) { - return true; - } - if (is_method_handle_intrinsic()) { - return !is_synthetic(); // the generated adapters must be compiled - } - if (comp_level == CompLevel_any) { - return is_not_c1_compilable() || is_not_c2_compilable(); - } - if (is_c1_compile(comp_level)) { - return is_not_c1_compilable(); - } - if (is_c2_compile(comp_level)) { - return is_not_c2_compilable(); - } - return false; -} - -// call this when compiler finds that this method is not compilable -void Method::set_not_compilable(int comp_level, bool report) { +void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report) { if (PrintCompilation && report) { ttyLocker ttyl; - tty->print("made not compilable "); + tty->print("made not %scompilable on ", is_osr ? "OSR " : ""); + if (comp_level == CompLevel_all) { + tty->print("all levels "); + } else { + tty->print("levels "); + for (int i = (int)CompLevel_none; i <= comp_level; i++) { + tty->print("%d ", i); + } + } this->print_short_name(tty); int size = this->code_size(); if (size > 0) @@ -720,21 +712,64 @@ } if ((TraceDeoptimization || LogCompilation) && (xtty != NULL)) { ttyLocker ttyl; - xtty->begin_elem("make_not_compilable thread='%d'", (int) os::current_thread_id()); + xtty->begin_elem("make_not_%scompilable thread='%d'", is_osr ? "osr_" : "", (int) os::current_thread_id()); xtty->method(this); xtty->stamp(); xtty->end_elem(); } +} + +bool Method::is_not_compilable(int comp_level) const { + if (number_of_breakpoints() > 0) + return true; + if (is_method_handle_intrinsic()) + return !is_synthetic(); // the generated adapters must be compiled + if (comp_level == CompLevel_any) + return is_not_c1_compilable() || is_not_c2_compilable(); + if (is_c1_compile(comp_level)) + return is_not_c1_compilable(); + if (is_c2_compile(comp_level)) + return is_not_c2_compilable(); + return false; +} + +// call this when compiler finds that this method is not compilable +void Method::set_not_compilable(int comp_level, bool report) { + print_made_not_compilable(comp_level, /*is_osr*/ false, report); if (comp_level == CompLevel_all) { set_not_c1_compilable(); set_not_c2_compilable(); } else { - if (is_c1_compile(comp_level)) { + if (is_c1_compile(comp_level)) set_not_c1_compilable(); - } else - if (is_c2_compile(comp_level)) { - set_not_c2_compilable(); - } + if (is_c2_compile(comp_level)) + set_not_c2_compilable(); + } + CompilationPolicy::policy()->disable_compilation(this); +} + +bool Method::is_not_osr_compilable(int comp_level) const { + if (is_not_compilable(comp_level)) + return true; + if (comp_level == CompLevel_any) + return is_not_c1_osr_compilable() || is_not_c2_osr_compilable(); + if (is_c1_compile(comp_level)) + return is_not_c1_osr_compilable(); + if (is_c2_compile(comp_level)) + return is_not_c2_osr_compilable(); + return false; +} + +void Method::set_not_osr_compilable(int comp_level, bool report) { + print_made_not_compilable(comp_level, /*is_osr*/ true, report); + if (comp_level == CompLevel_all) { + set_not_c1_osr_compilable(); + set_not_c2_osr_compilable(); + } else { + if (is_c1_compile(comp_level)) + set_not_c1_osr_compilable(); + if (is_c2_compile(comp_level)) + set_not_c2_osr_compilable(); } CompilationPolicy::policy()->disable_compilation(this); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/oops/method.hpp --- a/src/share/vm/oops/method.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/oops/method.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -745,19 +745,30 @@ // Indicates whether compilation failed earlier for this method, or // whether it is not compilable for another reason like having a // breakpoint set in it. - bool is_not_compilable(int comp_level = CompLevel_any) const; + bool is_not_compilable(int comp_level = CompLevel_any) const; void set_not_compilable(int comp_level = CompLevel_all, bool report = true); void set_not_compilable_quietly(int comp_level = CompLevel_all) { set_not_compilable(comp_level, false); } - bool is_not_osr_compilable(int comp_level = CompLevel_any) const { - return is_not_compilable(comp_level) || access_flags().is_not_osr_compilable(); + bool is_not_osr_compilable(int comp_level = CompLevel_any) const; + void set_not_osr_compilable(int comp_level = CompLevel_all, bool report = true); + void set_not_osr_compilable_quietly(int comp_level = CompLevel_all) { + set_not_osr_compilable(comp_level, false); } - void set_not_osr_compilable() { _access_flags.set_not_osr_compilable(); } - bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } - void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); } - bool is_not_c2_compilable() const { return access_flags().is_not_c2_compilable(); } - void set_not_c2_compilable() { _access_flags.set_not_c2_compilable(); } + + private: + void print_made_not_compilable(int comp_level, bool is_osr, bool report); + + public: + bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } + void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); } + bool is_not_c2_compilable() const { return access_flags().is_not_c2_compilable(); } + void set_not_c2_compilable() { _access_flags.set_not_c2_compilable(); } + + bool is_not_c1_osr_compilable() const { return is_not_c1_compilable(); } // don't waste an accessFlags bit + void set_not_c1_osr_compilable() { set_not_c1_compilable(); } // don't waste an accessFlags bit + bool is_not_c2_osr_compilable() const { return access_flags().is_not_c2_osr_compilable(); } + void set_not_c2_osr_compilable() { _access_flags.set_not_c2_osr_compilable(); } // Background compilation support bool queued_for_compilation() const { return access_flags().queued_for_compilation(); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/addnode.cpp --- a/src/share/vm/opto/addnode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/addnode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -248,47 +248,47 @@ const Type *t_sub1 = phase->type( in1->in(1) ); const Type *t_2 = phase->type( in2 ); if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP ) - return new (phase->C, 3) SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ), + return new (phase->C) SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ), in1->in(2) ); // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)" if( op2 == Op_SubI ) { // Check for dead cycle: d = (a-b)+(c-d) assert( in1->in(2) != this && in2->in(2) != this, "dead loop in AddINode::Ideal" ); - Node *sub = new (phase->C, 3) SubINode(NULL, NULL); - sub->init_req(1, phase->transform(new (phase->C, 3) AddINode(in1->in(1), in2->in(1) ) )); - sub->init_req(2, phase->transform(new (phase->C, 3) AddINode(in1->in(2), in2->in(2) ) )); + Node *sub = new (phase->C) SubINode(NULL, NULL); + sub->init_req(1, phase->transform(new (phase->C) AddINode(in1->in(1), in2->in(1) ) )); + sub->init_req(2, phase->transform(new (phase->C) AddINode(in1->in(2), in2->in(2) ) )); return sub; } // Convert "(a-b)+(b+c)" into "(a+c)" if( op2 == Op_AddI && in1->in(2) == in2->in(1) ) { assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal"); - return new (phase->C, 3) AddINode(in1->in(1), in2->in(2)); + return new (phase->C) AddINode(in1->in(1), in2->in(2)); } // Convert "(a-b)+(c+b)" into "(a+c)" if( op2 == Op_AddI && in1->in(2) == in2->in(2) ) { assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddINode::Ideal"); - return new (phase->C, 3) AddINode(in1->in(1), in2->in(1)); + return new (phase->C) AddINode(in1->in(1), in2->in(1)); } // Convert "(a-b)+(b-c)" into "(a-c)" if( op2 == Op_SubI && in1->in(2) == in2->in(1) ) { assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal"); - return new (phase->C, 3) SubINode(in1->in(1), in2->in(2)); + return new (phase->C) SubINode(in1->in(1), in2->in(2)); } // Convert "(a-b)+(c-a)" into "(c-b)" if( op2 == Op_SubI && in1->in(1) == in2->in(2) ) { assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddINode::Ideal"); - return new (phase->C, 3) SubINode(in2->in(1), in1->in(2)); + return new (phase->C) SubINode(in2->in(1), in1->in(2)); } } // Convert "x+(0-y)" into "(x-y)" if( op2 == Op_SubI && phase->type(in2->in(1)) == TypeInt::ZERO ) - return new (phase->C, 3) SubINode(in1, in2->in(2) ); + return new (phase->C) SubINode(in1, in2->in(2) ); // Convert "(0-y)+x" into "(x-y)" if( op1 == Op_SubI && phase->type(in1->in(1)) == TypeInt::ZERO ) - return new (phase->C, 3) SubINode( in2, in1->in(2) ); + return new (phase->C) SubINode( in2, in1->in(2) ); // Convert (x>>>z)+y into (x+(y<>>z for small constant z and y. // Helps with array allocation math constant folding @@ -309,8 +309,8 @@ if( z < 5 && -5 < y && y < 0 ) { const Type *t_in11 = phase->type(in1->in(1)); if( t_in11 != Type::TOP && (t_in11->is_int()->_lo >= -(y << z)) ) { - Node *a = phase->transform( new (phase->C, 3) AddINode( in1->in(1), phase->intcon(y<C, 3) URShiftINode( a, in1->in(2) ); + Node *a = phase->transform( new (phase->C) AddINode( in1->in(1), phase->intcon(y<C) URShiftINode( a, in1->in(2) ); } } } @@ -381,47 +381,47 @@ const Type *t_sub1 = phase->type( in1->in(1) ); const Type *t_2 = phase->type( in2 ); if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP ) - return new (phase->C, 3) SubLNode(phase->makecon( add_ring( t_sub1, t_2 ) ), + return new (phase->C) SubLNode(phase->makecon( add_ring( t_sub1, t_2 ) ), in1->in(2) ); // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)" if( op2 == Op_SubL ) { // Check for dead cycle: d = (a-b)+(c-d) assert( in1->in(2) != this && in2->in(2) != this, "dead loop in AddLNode::Ideal" ); - Node *sub = new (phase->C, 3) SubLNode(NULL, NULL); - sub->init_req(1, phase->transform(new (phase->C, 3) AddLNode(in1->in(1), in2->in(1) ) )); - sub->init_req(2, phase->transform(new (phase->C, 3) AddLNode(in1->in(2), in2->in(2) ) )); + Node *sub = new (phase->C) SubLNode(NULL, NULL); + sub->init_req(1, phase->transform(new (phase->C) AddLNode(in1->in(1), in2->in(1) ) )); + sub->init_req(2, phase->transform(new (phase->C) AddLNode(in1->in(2), in2->in(2) ) )); return sub; } // Convert "(a-b)+(b+c)" into "(a+c)" if( op2 == Op_AddL && in1->in(2) == in2->in(1) ) { assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal"); - return new (phase->C, 3) AddLNode(in1->in(1), in2->in(2)); + return new (phase->C) AddLNode(in1->in(1), in2->in(2)); } // Convert "(a-b)+(c+b)" into "(a+c)" if( op2 == Op_AddL && in1->in(2) == in2->in(2) ) { assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal"); - return new (phase->C, 3) AddLNode(in1->in(1), in2->in(1)); + return new (phase->C) AddLNode(in1->in(1), in2->in(1)); } // Convert "(a-b)+(b-c)" into "(a-c)" if( op2 == Op_SubL && in1->in(2) == in2->in(1) ) { assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal"); - return new (phase->C, 3) SubLNode(in1->in(1), in2->in(2)); + return new (phase->C) SubLNode(in1->in(1), in2->in(2)); } // Convert "(a-b)+(c-a)" into "(c-b)" if( op2 == Op_SubL && in1->in(1) == in1->in(2) ) { assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal"); - return new (phase->C, 3) SubLNode(in2->in(1), in1->in(2)); + return new (phase->C) SubLNode(in2->in(1), in1->in(2)); } } // Convert "x+(0-y)" into "(x-y)" if( op2 == Op_SubL && phase->type(in2->in(1)) == TypeLong::ZERO ) - return new (phase->C, 3) SubLNode( in1, in2->in(2) ); + return new (phase->C) SubLNode( in1, in2->in(2) ); // Convert "(0-y)+x" into "(x-y)" if( op1 == Op_SubL && phase->type(in1->in(1)) == TypeInt::ZERO ) - return new (phase->C, 3) SubLNode( in2, in1->in(2) ); + return new (phase->C) SubLNode( in2, in1->in(2) ); // Convert "X+X+X+X+X...+X+Y" into "k*X+Y" or really convert "X+(X+Y)" // into "(X<<1)+Y" and let shift-folding happen. @@ -429,8 +429,8 @@ in2->in(1) == in1 && op1 != Op_ConL && 0 ) { - Node *shift = phase->transform(new (phase->C, 3) LShiftLNode(in1,phase->intcon(1))); - return new (phase->C, 3) AddLNode(shift,in2->in(2)); + Node *shift = phase->transform(new (phase->C) LShiftLNode(in1,phase->intcon(1))); + return new (phase->C) AddLNode(shift,in2->in(2)); } return AddNode::Ideal(phase, can_reshape); @@ -590,7 +590,7 @@ offset = phase->MakeConX(t2->get_con() + t12->get_con()); } else { // Else move the constant to the right. ((A+con)+B) into ((A+B)+con) - address = phase->transform(new (phase->C, 4) AddPNode(in(Base),addp->in(Address),in(Offset))); + address = phase->transform(new (phase->C) AddPNode(in(Base),addp->in(Address),in(Offset))); offset = addp->in(Offset); } PhaseIterGVN *igvn = phase->is_IterGVN(); @@ -610,7 +610,7 @@ // If this is a NULL+long form (from unsafe accesses), switch to a rawptr. if (phase->type(in(Address)) == TypePtr::NULL_PTR) { Node* offset = in(Offset); - return new (phase->C, 2) CastX2PNode(offset); + return new (phase->C) CastX2PNode(offset); } } @@ -622,7 +622,7 @@ if( add->Opcode() == Op_AddX && add->in(1) != add ) { const Type *t22 = phase->type( add->in(2) ); if( t22->singleton() && (t22 != Type::TOP) ) { // Right input is an add of a constant? - set_req(Address, phase->transform(new (phase->C, 4) AddPNode(in(Base),in(Address),add->in(1)))); + set_req(Address, phase->transform(new (phase->C) AddPNode(in(Base),in(Address),add->in(1)))); set_req(Offset, add->in(2)); return this; // Made progress } @@ -847,7 +847,7 @@ // to force a right-spline graph for the rest of MinINode::Ideal(). if( l->Opcode() == Op_MinI ) { assert( l != l->in(1), "dead loop in MinINode::Ideal" ); - r = phase->transform(new (phase->C, 3) MinINode(l->in(2),r)); + r = phase->transform(new (phase->C) MinINode(l->in(2),r)); l = l->in(1); set_req(1, l); set_req(2, r); @@ -895,18 +895,18 @@ } if( x->_idx > y->_idx ) - return new (phase->C, 3) MinINode(r->in(1),phase->transform(new (phase->C, 3) MinINode(l,r->in(2)))); + return new (phase->C) MinINode(r->in(1),phase->transform(new (phase->C) MinINode(l,r->in(2)))); // See if covers: MIN2(x+c0,MIN2(y+c1,z)) if( !phase->eqv(x,y) ) return NULL; // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into // MIN2(x+c0 or x+c1 which less, z). - return new (phase->C, 3) MinINode(phase->transform(new (phase->C, 3) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2)); + return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2)); } else { // See if covers: MIN2(x+c0,y+c1) if( !phase->eqv(x,y) ) return NULL; // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less. - return new (phase->C, 3) AddINode(x,phase->intcon(MIN2(x_off,y_off))); + return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off))); } } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/block.cpp --- a/src/share/vm/opto/block.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/block.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -378,7 +378,7 @@ // I'll need a few machine-specific GotoNodes. Make an Ideal GotoNode, // then Match it into a machine-specific Node. Then clone the machine // Node on demand. - Node *x = new (C, 1) GotoNode(NULL); + Node *x = new (C) GotoNode(NULL); x->init_req(0, x); _goto = m.match_tree(x); assert(_goto != NULL, ""); @@ -432,7 +432,7 @@ !p->is_block_start() ); // Make the block begin with one of Region or StartNode. if( !p->is_block_start() ) { - RegionNode *r = new (C, 2) RegionNode( 2 ); + RegionNode *r = new (C) RegionNode( 2 ); r->init_req(1, p); // Insert RegionNode in the way proj->set_req(0, r); // Insert RegionNode in the way p = r; @@ -508,7 +508,7 @@ // get ProjNode corresponding to the succ_no'th successor of the in block ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj(); // create region for basic block - RegionNode* region = new (C, 2) RegionNode(2); + RegionNode* region = new (C) RegionNode(2); region->init_req(1, proj); // setup corresponding basic block Block* block = new (_bbs._arena) Block(_bbs._arena, region); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/c2_globals.hpp --- a/src/share/vm/opto/c2_globals.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/c2_globals.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -85,7 +85,7 @@ "Max vector size in bytes, " \ "actual size could be less depending on elements type") \ \ - product(bool, AlignVector, false, \ + product(bool, AlignVector, true, \ "Perform vector store/load alignment in loop") \ \ product(intx, NumberOfLoopInstrToAlign, 4, \ @@ -535,7 +535,7 @@ notproduct(bool, TraceSpilling, false, \ "Trace spilling") \ \ - notproduct(bool, TraceTypeProfile, false, \ + diagnostic(bool, TraceTypeProfile, false, \ "Trace type profile") \ \ develop(bool, PoisonOSREntry, true, \ diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/callGenerator.cpp --- a/src/share/vm/opto/callGenerator.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/callGenerator.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -134,7 +134,7 @@ kit.C->log()->elem("direct_call bci='%d'", jvms->bci()); } - CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), target, method(), kit.bci()); + CallStaticJavaNode *call = new (kit.C) CallStaticJavaNode(tf(), target, method(), kit.bci()); _call_node = call; // Save the call node in case we need it later if (!is_static) { // Make an explicit receiver null_check as part of this call. @@ -221,7 +221,7 @@ "no vtable calls if +UseInlineCaches "); address target = SharedRuntime::get_resolve_virtual_call_stub(); // Normal inline cache used for call - CallDynamicJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallDynamicJavaNode(tf(), target, method(), _vtable_index, kit.bci()); + CallDynamicJavaNode *call = new (kit.C) CallDynamicJavaNode(tf(), target, method(), _vtable_index, kit.bci()); kit.set_arguments_for_java_call(call); kit.set_edges_for_java_call(call); Node* ret = kit.set_results_for_java_call(call); @@ -300,7 +300,7 @@ Compile* C = Compile::current(); JVMState* jvms = call->jvms()->clone_shallow(C); uint size = call->req(); - SafePointNode* map = new (C, size) SafePointNode(size, jvms); + SafePointNode* map = new (C) SafePointNode(size, jvms); for (uint i1 = 0; i1 < size; i1++) { map->init_req(i1, call->in(i1)); } @@ -551,7 +551,7 @@ // Finish the diamond. kit.C->set_has_split_ifs(true); // Has chance for split-if optimization - RegionNode* region = new (kit.C, 3) RegionNode(3); + RegionNode* region = new (kit.C) RegionNode(3); region->init_req(1, kit.control()); region->init_req(2, slow_map->control()); kit.set_control(gvn.transform(region)); @@ -636,7 +636,7 @@ const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr(); const Type* sig_type = TypeOopPtr::make_from_klass(signature->accessing_klass()); if (arg_type != NULL && !arg_type->higher_equal(sig_type)) { - Node* cast_obj = gvn.transform(new (C, 2) CheckCastPPNode(kit.control(), arg, sig_type)); + Node* cast_obj = gvn.transform(new (C) CheckCastPPNode(kit.control(), arg, sig_type)); kit.set_argument(0, cast_obj); } } @@ -648,7 +648,7 @@ const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr(); const Type* sig_type = TypeOopPtr::make_from_klass(t->as_klass()); if (arg_type != NULL && !arg_type->higher_equal(sig_type)) { - Node* cast_obj = gvn.transform(new (C, 2) CheckCastPPNode(kit.control(), arg, sig_type)); + Node* cast_obj = gvn.transform(new (C) CheckCastPPNode(kit.control(), arg, sig_type)); kit.set_argument(receiver_skip + i, cast_obj); } } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/callnode.cpp --- a/src/share/vm/opto/callnode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/callnode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -72,20 +72,20 @@ case TypeFunc::Control: case TypeFunc::I_O: case TypeFunc::Memory: - return new (match->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); + return new (match->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); case TypeFunc::FramePtr: - return new (match->C, 1) MachProjNode(this,proj->_con,Matcher::c_frame_ptr_mask, Op_RegP); + return new (match->C) MachProjNode(this,proj->_con,Matcher::c_frame_ptr_mask, Op_RegP); case TypeFunc::ReturnAdr: - return new (match->C, 1) MachProjNode(this,proj->_con,match->_return_addr_mask,Op_RegP); + return new (match->C) MachProjNode(this,proj->_con,match->_return_addr_mask,Op_RegP); case TypeFunc::Parms: default: { uint parm_num = proj->_con - TypeFunc::Parms; const Type *t = _domain->field_at(proj->_con); if (t->base() == Type::Half) // 2nd half of Longs and Doubles - return new (match->C, 1) ConNode(Type::TOP); + return new (match->C) ConNode(Type::TOP); uint ideal_reg = t->ideal_reg(); RegMask &rm = match->_calling_convention_mask[parm_num]; - return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg); + return new (match->C) MachProjNode(this,proj->_con,rm,ideal_reg); } } return NULL; @@ -625,12 +625,12 @@ case TypeFunc::Control: case TypeFunc::I_O: case TypeFunc::Memory: - return new (match->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); + return new (match->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); case TypeFunc::Parms+1: // For LONG & DOUBLE returns assert(tf()->_range->field_at(TypeFunc::Parms+1) == Type::HALF, ""); // 2nd half of doubles and longs - return new (match->C, 1) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad); + return new (match->C) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad); case TypeFunc::Parms: { // Normal returns uint ideal_reg = tf()->range()->field_at(TypeFunc::Parms)->ideal_reg(); @@ -640,7 +640,7 @@ RegMask rm = RegMask(regs.first()); if( OptoReg::is_valid(regs.second()) ) rm.Insert( regs.second() ); - return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg); + return new (match->C) MachProjNode(this,proj->_con,rm,ideal_reg); } case TypeFunc::ReturnAdr: @@ -1175,10 +1175,10 @@ Node* nproj = catchproj->clone(); igvn->register_new_node_with_optimizer(nproj); - Node *frame = new (phase->C, 1) ParmNode( phase->C->start(), TypeFunc::FramePtr ); + Node *frame = new (phase->C) ParmNode( phase->C->start(), TypeFunc::FramePtr ); frame = phase->transform(frame); // Halt & Catch Fire - Node *halt = new (phase->C, TypeFunc::Parms) HaltNode( nproj, frame ); + Node *halt = new (phase->C) HaltNode( nproj, frame ); phase->C->root()->add_req(halt); phase->transform(halt); @@ -1218,7 +1218,7 @@ if (!allow_new_nodes) return NULL; // Create a cast which is control dependent on the initialization to // propagate the fact that the array length must be positive. - length = new (phase->C, 2) CastIINode(length, narrow_length_type); + length = new (phase->C) CastIINode(length, narrow_length_type); length->set_req(0, initialization()->proj_out(0)); } } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/cfgnode.cpp --- a/src/share/vm/opto/cfgnode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/cfgnode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -612,17 +612,17 @@ convf2i->in(1) == bot_in ) { // Matched pattern, including LShiftI; RShiftI, replace with integer compares // max test - Node *cmp = gvn->register_new_node_with_optimizer(new (phase->C, 3) CmpINode( convf2i, min )); - Node *boo = gvn->register_new_node_with_optimizer(new (phase->C, 2) BoolNode( cmp, BoolTest::lt )); - IfNode *iff = (IfNode*)gvn->register_new_node_with_optimizer(new (phase->C, 2) IfNode( top_if->in(0), boo, PROB_UNLIKELY_MAG(5), top_if->_fcnt )); - Node *if_min= gvn->register_new_node_with_optimizer(new (phase->C, 1) IfTrueNode (iff)); - Node *ifF = gvn->register_new_node_with_optimizer(new (phase->C, 1) IfFalseNode(iff)); + Node *cmp = gvn->register_new_node_with_optimizer(new (phase->C) CmpINode( convf2i, min )); + Node *boo = gvn->register_new_node_with_optimizer(new (phase->C) BoolNode( cmp, BoolTest::lt )); + IfNode *iff = (IfNode*)gvn->register_new_node_with_optimizer(new (phase->C) IfNode( top_if->in(0), boo, PROB_UNLIKELY_MAG(5), top_if->_fcnt )); + Node *if_min= gvn->register_new_node_with_optimizer(new (phase->C) IfTrueNode (iff)); + Node *ifF = gvn->register_new_node_with_optimizer(new (phase->C) IfFalseNode(iff)); // min test - cmp = gvn->register_new_node_with_optimizer(new (phase->C, 3) CmpINode( convf2i, max )); - boo = gvn->register_new_node_with_optimizer(new (phase->C, 2) BoolNode( cmp, BoolTest::gt )); - iff = (IfNode*)gvn->register_new_node_with_optimizer(new (phase->C, 2) IfNode( ifF, boo, PROB_UNLIKELY_MAG(5), bot_if->_fcnt )); - Node *if_max= gvn->register_new_node_with_optimizer(new (phase->C, 1) IfTrueNode (iff)); - ifF = gvn->register_new_node_with_optimizer(new (phase->C, 1) IfFalseNode(iff)); + cmp = gvn->register_new_node_with_optimizer(new (phase->C) CmpINode( convf2i, max )); + boo = gvn->register_new_node_with_optimizer(new (phase->C) BoolNode( cmp, BoolTest::gt )); + iff = (IfNode*)gvn->register_new_node_with_optimizer(new (phase->C) IfNode( ifF, boo, PROB_UNLIKELY_MAG(5), bot_if->_fcnt )); + Node *if_max= gvn->register_new_node_with_optimizer(new (phase->C) IfTrueNode (iff)); + ifF = gvn->register_new_node_with_optimizer(new (phase->C) IfFalseNode(iff)); // update input edges to region node set_req_X( min_idx, if_min, gvn ); set_req_X( max_idx, if_max, gvn ); @@ -681,7 +681,7 @@ PhiNode* PhiNode::make(Node* r, Node* x, const Type *t, const TypePtr* at) { uint preds = r->req(); // Number of predecessor paths assert(t != Type::MEMORY || at == flatten_phi_adr_type(at), "flatten at"); - PhiNode* p = new (Compile::current(), preds) PhiNode(r, t, at); + PhiNode* p = new (Compile::current()) PhiNode(r, t, at); for (uint j = 1; j < preds; j++) { // Fill in all inputs, except those which the region does not yet have if (r->in(j) != NULL) @@ -699,7 +699,7 @@ const Type* t = x->bottom_type(); const TypePtr* at = NULL; if (t == Type::MEMORY) at = flatten_phi_adr_type(x->adr_type()); - return new (Compile::current(), r->req()) PhiNode(r, t, at); + return new (Compile::current()) PhiNode(r, t, at); } @@ -1205,9 +1205,9 @@ } else return NULL; // Build int->bool conversion - Node *n = new (phase->C, 2) Conv2BNode( cmp->in(1) ); + Node *n = new (phase->C) Conv2BNode( cmp->in(1) ); if( flipped ) - n = new (phase->C, 3) XorINode( phase->transform(n), phase->intcon(1) ); + n = new (phase->C) XorINode( phase->transform(n), phase->intcon(1) ); return n; } @@ -1266,9 +1266,9 @@ if( q->is_Con() && phase->type(q) != TypeInt::ZERO && y->is_Con() ) return NULL; - Node *cmplt = phase->transform( new (phase->C, 3) CmpLTMaskNode(p,q) ); - Node *j_and = phase->transform( new (phase->C, 3) AndINode(cmplt,y) ); - return new (phase->C, 3) AddINode(j_and,x); + Node *cmplt = phase->transform( new (phase->C) CmpLTMaskNode(p,q) ); + Node *j_and = phase->transform( new (phase->C) AndINode(cmplt,y) ); + return new (phase->C) AddINode(j_and,x); } //------------------------------is_absolute------------------------------------ @@ -1330,17 +1330,17 @@ if( sub->Opcode() != Op_SubF || sub->in(2) != x || phase->type(sub->in(1)) != tzero ) return NULL; - x = new (phase->C, 2) AbsFNode(x); + x = new (phase->C) AbsFNode(x); if (flip) { - x = new (phase->C, 3) SubFNode(sub->in(1), phase->transform(x)); + x = new (phase->C) SubFNode(sub->in(1), phase->transform(x)); } } else { if( sub->Opcode() != Op_SubD || sub->in(2) != x || phase->type(sub->in(1)) != tzero ) return NULL; - x = new (phase->C, 2) AbsDNode(x); + x = new (phase->C) AbsDNode(x); if (flip) { - x = new (phase->C, 3) SubDNode(sub->in(1), phase->transform(x)); + x = new (phase->C) SubDNode(sub->in(1), phase->transform(x)); } } @@ -1415,7 +1415,7 @@ // Now start splitting out the flow paths that merge the same value. // Split first the RegionNode. PhaseIterGVN *igvn = phase->is_IterGVN(); - RegionNode *newr = new (phase->C, hit+1) RegionNode(hit+1); + RegionNode *newr = new (phase->C) RegionNode(hit+1); split_once(igvn, phi, val, r, newr); // Now split all other Phis than this one @@ -1723,13 +1723,13 @@ } if (doit) { if (base == NULL) { - base = new (phase->C, in(0)->req()) PhiNode(in(0), type, NULL); + base = new (phase->C) PhiNode(in(0), type, NULL); for (uint i = 1; i < req(); i++) { base->init_req(i, in(i)->in(AddPNode::Base)); } phase->is_IterGVN()->register_new_node_with_optimizer(base); } - return new (phase->C, 4) AddPNode(base, base, y); + return new (phase->C) AddPNode(base, base, y); } } } @@ -1806,7 +1806,7 @@ // Phi(...MergeMem(m0, m1:AT1, m2:AT2)...) into // MergeMem(Phi(...m0...), Phi:AT1(...m1...), Phi:AT2(...m2...)) PhaseIterGVN *igvn = phase->is_IterGVN(); - Node* hook = new (phase->C, 1) Node(1); + Node* hook = new (phase->C) Node(1); PhiNode* new_base = (PhiNode*) clone(); // Must eagerly register phis, since they participate in loops. if (igvn) { @@ -1896,7 +1896,7 @@ PhaseIterGVN *igvn = phase->is_IterGVN(); // Make narrow type for new phi. const Type* narrow_t = TypeNarrowOop::make(this->bottom_type()->is_ptr()); - PhiNode* new_phi = new (phase->C, r->req()) PhiNode(r, narrow_t); + PhiNode* new_phi = new (phase->C) PhiNode(r, narrow_t); uint orig_cnt = req(); for (uint i=1; ias_Phi() == this) { new_ii = new_phi; } else { - new_ii = new (phase->C, 2) EncodePNode(ii, narrow_t); + new_ii = new (phase->C) EncodePNode(ii, narrow_t); igvn->register_new_node_with_optimizer(new_ii); } } new_phi->set_req(i, new_ii); } igvn->register_new_node_with_optimizer(new_phi, this); - progress = new (phase->C, 2) DecodeNNode(new_phi, bottom_type()); + progress = new (phase->C) DecodeNNode(new_phi, bottom_type()); } } #endif diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/chaitin.cpp --- a/src/share/vm/opto/chaitin.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/chaitin.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -1588,7 +1588,7 @@ // Now we see we need a base-Phi here to merge the bases const Type *t = base->bottom_type(); - base = new (C, derived->req()) PhiNode( derived->in(0), t ); + base = new (C) PhiNode( derived->in(0), t ); for( i = 1; i < derived->req(); i++ ) { base->init_req(i, find_base_for_derived(derived_base_map, derived->in(i), maxlrg)); t = t->meet(base->in(i)->bottom_type()); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/classes.hpp --- a/src/share/vm/opto/classes.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/classes.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -83,6 +83,12 @@ macro(CompareAndSwapL) macro(CompareAndSwapP) macro(CompareAndSwapN) +macro(GetAndAddI) +macro(GetAndAddL) +macro(GetAndSetI) +macro(GetAndSetL) +macro(GetAndSetP) +macro(GetAndSetN) macro(Con) macro(ConN) macro(ConD) diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/compile.cpp --- a/src/share/vm/opto/compile.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/compile.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -654,14 +654,14 @@ const TypeTuple *domain = StartOSRNode::osr_domain(); const TypeTuple *range = TypeTuple::make_range(method()->signature()); init_tf(TypeFunc::make(domain, range)); - StartNode* s = new (this, 2) StartOSRNode(root(), domain); + StartNode* s = new (this) StartOSRNode(root(), domain); initial_gvn()->set_type_bottom(s); init_start(s); cg = CallGenerator::for_osr(method(), entry_bci()); } else { // Normal case. init_tf(TypeFunc::make(method())); - StartNode* s = new (this, 2) StartNode(root(), tf()->domain()); + StartNode* s = new (this) StartNode(root(), tf()->domain()); initial_gvn()->set_type_bottom(s); init_start(s); if (method()->intrinsic_id() == vmIntrinsics::_Reference_get && UseG1GC) { @@ -825,7 +825,8 @@ &_handler_table, &_inc_table, compiler, env()->comp_level(), - has_unsafe_access() + has_unsafe_access(), + SharedRuntime::is_wide_vector(max_vector_size()) ); } } @@ -946,9 +947,9 @@ // Globally visible Nodes // First set TOP to NULL to give safe behavior during creation of RootNode set_cached_top_node(NULL); - set_root(new (this, 3) RootNode()); + set_root(new (this) RootNode()); // Now that you have a Root to point to, create the real TOP - set_cached_top_node( new (this, 1) ConNode(Type::TOP) ); + set_cached_top_node( new (this) ConNode(Type::TOP) ); set_recent_alloc(NULL, NULL); // Create Debug Information Recorder to record scopes, oopmaps, etc. @@ -963,6 +964,7 @@ _trap_can_recompile = false; // no traps emitted yet _major_progress = true; // start out assuming good things will happen set_has_unsafe_access(false); + set_max_vector_size(0); Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist)); set_decompile_count(0); @@ -2274,6 +2276,12 @@ case Op_CompareAndSwapL: case Op_CompareAndSwapP: case Op_CompareAndSwapN: + case Op_GetAndAddI: + case Op_GetAndAddL: + case Op_GetAndSetI: + case Op_GetAndSetL: + case Op_GetAndSetP: + case Op_GetAndSetN: case Op_StoreP: case Op_StoreN: case Op_LoadB: @@ -2337,7 +2345,7 @@ if (nn != NULL) { // Decode a narrow oop to match address // [R12 + narrow_oop_reg<<3 + offset] - nn = new (C, 2) DecodeNNode(nn, t); + nn = new (C) DecodeNNode(nn, t); n->set_req(AddPNode::Base, nn); n->set_req(AddPNode::Address, nn); if (addp->outcnt() == 0) { @@ -2455,7 +2463,7 @@ } } if (new_in2 != NULL) { - Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2); + Node* cmpN = new (C) CmpNNode(in1->in(1), new_in2); n->subsume_by( cmpN ); if (in1->outcnt() == 0) { in1->disconnect_inputs(NULL); @@ -2551,8 +2559,8 @@ n->subsume_by(divmod->mod_proj()); } else { // replace a%b with a-((a/b)*b) - Node* mult = new (C, 3) MulINode(d, d->in(2)); - Node* sub = new (C, 3) SubINode(d->in(1), mult); + Node* mult = new (C) MulINode(d, d->in(2)); + Node* sub = new (C) SubINode(d->in(1), mult); n->subsume_by( sub ); } } @@ -2572,8 +2580,8 @@ n->subsume_by(divmod->mod_proj()); } else { // replace a%b with a-((a/b)*b) - Node* mult = new (C, 3) MulLNode(d, d->in(2)); - Node* sub = new (C, 3) SubLNode(d->in(1), mult); + Node* mult = new (C) MulLNode(d, d->in(2)); + Node* sub = new (C) SubLNode(d->in(1), mult); n->subsume_by( sub ); } } @@ -2624,7 +2632,7 @@ } else { if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { Compile* C = Compile::current(); - Node* shift = new (C, 3) AndINode(in2, ConNode::make(C, TypeInt::make(mask))); + Node* shift = new (C) AndINode(in2, ConNode::make(C, TypeInt::make(mask))); n->set_req(2, shift); } } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/compile.hpp --- a/src/share/vm/opto/compile.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/compile.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -279,6 +279,7 @@ bool _has_split_ifs; // True if the method _may_ have some split-if bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores. bool _has_stringbuilder; // True StringBuffers or StringBuilders are allocated + int _max_vector_size; // Maximum size of generated vectors uint _trap_hist[trapHistLength]; // Cumulative traps bool _trap_can_recompile; // Have we emitted a recompiling trap? uint _decompile_count; // Cumulative decompilation counts. @@ -443,6 +444,8 @@ void set_has_unsafe_access(bool z) { _has_unsafe_access = z; } bool has_stringbuilder() const { return _has_stringbuilder; } void set_has_stringbuilder(bool z) { _has_stringbuilder = z; } + int max_vector_size() const { return _max_vector_size; } + void set_max_vector_size(int s) { _max_vector_size = s; } void set_trap_count(uint r, uint c) { assert(r < trapHistLength, "oob"); _trap_hist[r] = c; } uint trap_count(uint r) const { assert(r < trapHistLength, "oob"); return _trap_hist[r]; } bool trap_can_recompile() const { return _trap_can_recompile; } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/connode.cpp --- a/src/share/vm/opto/connode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/connode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -45,16 +45,16 @@ //------------------------------make------------------------------------------- ConNode *ConNode::make( Compile* C, const Type *t ) { switch( t->basic_type() ) { - case T_INT: return new (C, 1) ConINode( t->is_int() ); - case T_LONG: return new (C, 1) ConLNode( t->is_long() ); - case T_FLOAT: return new (C, 1) ConFNode( t->is_float_constant() ); - case T_DOUBLE: return new (C, 1) ConDNode( t->is_double_constant() ); - case T_VOID: return new (C, 1) ConNode ( Type::TOP ); - case T_OBJECT: return new (C, 1) ConPNode( t->is_ptr() ); - case T_ARRAY: return new (C, 1) ConPNode( t->is_aryptr() ); - case T_ADDRESS: return new (C, 1) ConPNode( t->is_ptr() ); - case T_NARROWOOP: return new (C, 1) ConNNode( t->is_narrowoop() ); - case T_METADATA: return new (C, 1) ConPNode( t->is_ptr() ); + case T_INT: return new (C) ConINode( t->is_int() ); + case T_LONG: return new (C) ConLNode( t->is_long() ); + case T_FLOAT: return new (C) ConFNode( t->is_float_constant() ); + case T_DOUBLE: return new (C) ConDNode( t->is_double_constant() ); + case T_VOID: return new (C) ConNode ( Type::TOP ); + case T_OBJECT: return new (C) ConPNode( t->is_ptr() ); + case T_ARRAY: return new (C) ConPNode( t->is_aryptr() ); + case T_ADDRESS: return new (C) ConPNode( t->is_ptr() ); + case T_NARROWOOP: return new (C) ConNNode( t->is_narrowoop() ); + case T_METADATA: return new (C) ConPNode( t->is_ptr() ); // Expected cases: TypePtr::NULL_PTR, any is_rawptr() // Also seen: AnyPtr(TopPTR *+top); from command line: // r -XX:+PrintOpto -XX:CIStart=285 -XX:+CompileTheWorld -XX:CompileTheWorldStartAt=660 @@ -195,13 +195,13 @@ // from the inputs we do not need to specify it here. CMoveNode *CMoveNode::make( Compile *C, Node *c, Node *bol, Node *left, Node *right, const Type *t ) { switch( t->basic_type() ) { - case T_INT: return new (C, 4) CMoveINode( bol, left, right, t->is_int() ); - case T_FLOAT: return new (C, 4) CMoveFNode( bol, left, right, t ); - case T_DOUBLE: return new (C, 4) CMoveDNode( bol, left, right, t ); - case T_LONG: return new (C, 4) CMoveLNode( bol, left, right, t->is_long() ); - case T_OBJECT: return new (C, 4) CMovePNode( c, bol, left, right, t->is_oopptr() ); - case T_ADDRESS: return new (C, 4) CMovePNode( c, bol, left, right, t->is_ptr() ); - case T_NARROWOOP: return new (C, 4) CMoveNNode( c, bol, left, right, t ); + case T_INT: return new (C) CMoveINode( bol, left, right, t->is_int() ); + case T_FLOAT: return new (C) CMoveFNode( bol, left, right, t ); + case T_DOUBLE: return new (C) CMoveDNode( bol, left, right, t ); + case T_LONG: return new (C) CMoveLNode( bol, left, right, t->is_long() ); + case T_OBJECT: return new (C) CMovePNode( c, bol, left, right, t->is_oopptr() ); + case T_ADDRESS: return new (C) CMovePNode( c, bol, left, right, t->is_ptr() ); + case T_NARROWOOP: return new (C) CMoveNNode( c, bol, left, right, t ); default: ShouldNotReachHere(); return NULL; @@ -268,9 +268,9 @@ #ifndef PRODUCT if( PrintOpto ) tty->print_cr("CMOV to I2B"); #endif - Node *n = new (phase->C, 2) Conv2BNode( cmp->in(1) ); + Node *n = new (phase->C) Conv2BNode( cmp->in(1) ); if( flip ) - n = new (phase->C, 3) XorINode( phase->transform(n), phase->intcon(1) ); + n = new (phase->C) XorINode( phase->transform(n), phase->intcon(1) ); return n; } @@ -324,9 +324,9 @@ sub->in(2) != X || phase->type(sub->in(1)) != TypeF::ZERO ) return NULL; - Node *abs = new (phase->C, 2) AbsFNode( X ); + Node *abs = new (phase->C) AbsFNode( X ); if( flip ) - abs = new (phase->C, 3) SubFNode(sub->in(1), phase->transform(abs)); + abs = new (phase->C) SubFNode(sub->in(1), phase->transform(abs)); return abs; } @@ -380,9 +380,9 @@ sub->in(2) != X || phase->type(sub->in(1)) != TypeD::ZERO ) return NULL; - Node *abs = new (phase->C, 2) AbsDNode( X ); + Node *abs = new (phase->C) AbsDNode( X ); if( flip ) - abs = new (phase->C, 3) SubDNode(sub->in(1), phase->transform(abs)); + abs = new (phase->C) SubDNode(sub->in(1), phase->transform(abs)); return abs; } @@ -480,7 +480,9 @@ opc == Op_CheckCastPP || opc == Op_StorePConditional || opc == Op_CompareAndSwapP || - opc == Op_CompareAndSwapN; + opc == Op_CompareAndSwapN || + opc == Op_GetAndSetP || + opc == Op_GetAndSetN; } return possible_alias; } @@ -959,11 +961,11 @@ ryhi = -rylo0; } - Node* cx = phase->transform( new (phase->C, 2) ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) ); - Node* cy = phase->transform( new (phase->C, 2) ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) ); + Node* cx = phase->transform( new (phase->C) ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) ); + Node* cy = phase->transform( new (phase->C) ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) ); switch (op) { - case Op_AddI: return new (phase->C, 3) AddLNode(cx, cy); - case Op_SubI: return new (phase->C, 3) SubLNode(cx, cy); + case Op_AddI: return new (phase->C) AddLNode(cx, cy); + case Op_SubI: return new (phase->C) SubLNode(cx, cy); default: ShouldNotReachHere(); } } @@ -1037,9 +1039,9 @@ assert( x != andl && y != andl, "dead loop in ConvL2INode::Ideal" ); if (phase->type(x) == Type::TOP) return NULL; if (phase->type(y) == Type::TOP) return NULL; - Node *add1 = phase->transform(new (phase->C, 2) ConvL2INode(x)); - Node *add2 = phase->transform(new (phase->C, 2) ConvL2INode(y)); - return new (phase->C, 3) AddINode(add1,add2); + Node *add1 = phase->transform(new (phase->C) ConvL2INode(x)); + Node *add2 = phase->transform(new (phase->C) ConvL2INode(y)); + return new (phase->C) AddINode(add1,add2); } // Disable optimization: LoadL->ConvL2I ==> LoadI. @@ -1076,10 +1078,10 @@ Node* dispX, bool negate = false) { if (negate) { - dispX = new (phase->C, 3) SubXNode(phase->MakeConX(0), phase->transform(dispX)); + dispX = new (phase->C) SubXNode(phase->MakeConX(0), phase->transform(dispX)); } - return new (phase->C, 4) AddPNode(phase->C->top(), - phase->transform(new (phase->C, 2) CastX2PNode(base)), + return new (phase->C) AddPNode(phase->C->top(), + phase->transform(new (phase->C) CastX2PNode(base)), phase->transform(dispX)); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/connode.hpp --- a/src/share/vm/opto/connode.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/connode.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -58,7 +58,7 @@ // Factory method: static ConINode* make( Compile* C, int con ) { - return new (C, 1) ConINode( TypeInt::make(con) ); + return new (C) ConINode( TypeInt::make(con) ); } }; @@ -73,9 +73,9 @@ // Factory methods: static ConPNode* make( Compile *C ,address con ) { if (con == NULL) - return new (C, 1) ConPNode( TypePtr::NULL_PTR ) ; + return new (C) ConPNode( TypePtr::NULL_PTR ) ; else - return new (C, 1) ConPNode( TypeRawPtr::make(con) ); + return new (C) ConPNode( TypeRawPtr::make(con) ); } }; @@ -98,7 +98,7 @@ // Factory method: static ConLNode* make( Compile *C ,jlong con ) { - return new (C, 1) ConLNode( TypeLong::make(con) ); + return new (C) ConLNode( TypeLong::make(con) ); } }; @@ -112,7 +112,7 @@ // Factory method: static ConFNode* make( Compile *C, float con ) { - return new (C, 1) ConFNode( TypeF::make(con) ); + return new (C) ConFNode( TypeF::make(con) ); } }; @@ -126,7 +126,7 @@ // Factory method: static ConDNode* make( Compile *C, double con ) { - return new (C, 1) ConDNode( TypeD::make(con) ); + return new (C) ConDNode( TypeD::make(con) ); } }; diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/divnode.cpp --- a/src/share/vm/opto/divnode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/divnode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -104,7 +104,7 @@ // division by +/- 1 if (!d_pos) { // Just negate the value - q = new (phase->C, 3) SubINode(phase->intcon(0), dividend); + q = new (phase->C) SubINode(phase->intcon(0), dividend); } } else if ( is_power_of_2(d) ) { // division by +/- a power of 2 @@ -141,18 +141,18 @@ // (-2+3)>>2 becomes 0, etc. // Compute 0 or -1, based on sign bit - Node *sign = phase->transform(new (phase->C, 3) RShiftINode(dividend, phase->intcon(N - 1))); + Node *sign = phase->transform(new (phase->C) RShiftINode(dividend, phase->intcon(N - 1))); // Mask sign bit to the low sign bits - Node *round = phase->transform(new (phase->C, 3) URShiftINode(sign, phase->intcon(N - l))); + Node *round = phase->transform(new (phase->C) URShiftINode(sign, phase->intcon(N - l))); // Round up before shifting - dividend = phase->transform(new (phase->C, 3) AddINode(dividend, round)); + dividend = phase->transform(new (phase->C) AddINode(dividend, round)); } // Shift for division - q = new (phase->C, 3) RShiftINode(dividend, phase->intcon(l)); + q = new (phase->C) RShiftINode(dividend, phase->intcon(l)); if (!d_pos) { - q = new (phase->C, 3) SubINode(phase->intcon(0), phase->transform(q)); + q = new (phase->C) SubINode(phase->intcon(0), phase->transform(q)); } } else { // Attempt the jint constant divide -> multiply transform found in @@ -164,33 +164,33 @@ jint shift_const; if (magic_int_divide_constants(d, magic_const, shift_const)) { Node *magic = phase->longcon(magic_const); - Node *dividend_long = phase->transform(new (phase->C, 2) ConvI2LNode(dividend)); + Node *dividend_long = phase->transform(new (phase->C) ConvI2LNode(dividend)); // Compute the high half of the dividend x magic multiplication - Node *mul_hi = phase->transform(new (phase->C, 3) MulLNode(dividend_long, magic)); + Node *mul_hi = phase->transform(new (phase->C) MulLNode(dividend_long, magic)); if (magic_const < 0) { - mul_hi = phase->transform(new (phase->C, 3) RShiftLNode(mul_hi, phase->intcon(N))); - mul_hi = phase->transform(new (phase->C, 2) ConvL2INode(mul_hi)); + mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(N))); + mul_hi = phase->transform(new (phase->C) ConvL2INode(mul_hi)); // The magic multiplier is too large for a 32 bit constant. We've adjusted // it down by 2^32, but have to add 1 dividend back in after the multiplication. // This handles the "overflow" case described by Granlund and Montgomery. - mul_hi = phase->transform(new (phase->C, 3) AddINode(dividend, mul_hi)); + mul_hi = phase->transform(new (phase->C) AddINode(dividend, mul_hi)); // Shift over the (adjusted) mulhi if (shift_const != 0) { - mul_hi = phase->transform(new (phase->C, 3) RShiftINode(mul_hi, phase->intcon(shift_const))); + mul_hi = phase->transform(new (phase->C) RShiftINode(mul_hi, phase->intcon(shift_const))); } } else { // No add is required, we can merge the shifts together. - mul_hi = phase->transform(new (phase->C, 3) RShiftLNode(mul_hi, phase->intcon(N + shift_const))); - mul_hi = phase->transform(new (phase->C, 2) ConvL2INode(mul_hi)); + mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(N + shift_const))); + mul_hi = phase->transform(new (phase->C) ConvL2INode(mul_hi)); } // Get a 0 or -1 from the sign of the dividend. Node *addend0 = mul_hi; - Node *addend1 = phase->transform(new (phase->C, 3) RShiftINode(dividend, phase->intcon(N-1))); + Node *addend1 = phase->transform(new (phase->C) RShiftINode(dividend, phase->intcon(N-1))); // If the divisor is negative, swap the order of the input addends; // this has the effect of negating the quotient. @@ -200,7 +200,7 @@ // Adjust the final quotient by subtracting -1 (adding 1) // from the mul_hi. - q = new (phase->C, 3) SubINode(addend0, addend1); + q = new (phase->C) SubINode(addend0, addend1); } } @@ -259,7 +259,7 @@ // no need to synthesize it in ideal nodes. if (Matcher::has_match_rule(Op_MulHiL)) { Node* v = phase->longcon(magic_const); - return new (phase->C, 3) MulHiLNode(dividend, v); + return new (phase->C) MulHiLNode(dividend, v); } // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed. @@ -285,11 +285,11 @@ const int N = 64; // Dummy node to keep intermediate nodes alive during construction - Node* hook = new (phase->C, 4) Node(4); + Node* hook = new (phase->C) Node(4); // u0 = u & 0xFFFFFFFF; u1 = u >> 32; - Node* u0 = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF))); - Node* u1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2))); + Node* u0 = phase->transform(new (phase->C) AndLNode(dividend, phase->longcon(0xFFFFFFFF))); + Node* u1 = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N / 2))); hook->init_req(0, u0); hook->init_req(1, u1); @@ -298,29 +298,29 @@ Node* v1 = phase->longcon(magic_const >> (N / 2)); // w0 = u0*v0; - Node* w0 = phase->transform(new (phase->C, 3) MulLNode(u0, v0)); + Node* w0 = phase->transform(new (phase->C) MulLNode(u0, v0)); // t = u1*v0 + (w0 >> 32); - Node* u1v0 = phase->transform(new (phase->C, 3) MulLNode(u1, v0)); - Node* temp = phase->transform(new (phase->C, 3) URShiftLNode(w0, phase->intcon(N / 2))); - Node* t = phase->transform(new (phase->C, 3) AddLNode(u1v0, temp)); + Node* u1v0 = phase->transform(new (phase->C) MulLNode(u1, v0)); + Node* temp = phase->transform(new (phase->C) URShiftLNode(w0, phase->intcon(N / 2))); + Node* t = phase->transform(new (phase->C) AddLNode(u1v0, temp)); hook->init_req(2, t); // w1 = t & 0xFFFFFFFF; - Node* w1 = phase->transform(new (phase->C, 3) AndLNode(t, phase->longcon(0xFFFFFFFF))); + Node* w1 = phase->transform(new (phase->C) AndLNode(t, phase->longcon(0xFFFFFFFF))); hook->init_req(3, w1); // w2 = t >> 32; - Node* w2 = phase->transform(new (phase->C, 3) RShiftLNode(t, phase->intcon(N / 2))); + Node* w2 = phase->transform(new (phase->C) RShiftLNode(t, phase->intcon(N / 2))); // w1 = u0*v1 + w1; - Node* u0v1 = phase->transform(new (phase->C, 3) MulLNode(u0, v1)); - w1 = phase->transform(new (phase->C, 3) AddLNode(u0v1, w1)); + Node* u0v1 = phase->transform(new (phase->C) MulLNode(u0, v1)); + w1 = phase->transform(new (phase->C) AddLNode(u0v1, w1)); // return u1*v1 + w2 + (w1 >> 32); - Node* u1v1 = phase->transform(new (phase->C, 3) MulLNode(u1, v1)); - Node* temp1 = phase->transform(new (phase->C, 3) AddLNode(u1v1, w2)); - Node* temp2 = phase->transform(new (phase->C, 3) RShiftLNode(w1, phase->intcon(N / 2))); + Node* u1v1 = phase->transform(new (phase->C) MulLNode(u1, v1)); + Node* temp1 = phase->transform(new (phase->C) AddLNode(u1v1, w2)); + Node* temp2 = phase->transform(new (phase->C) RShiftLNode(w1, phase->intcon(N / 2))); // Remove the bogus extra edges used to keep things alive PhaseIterGVN* igvn = phase->is_IterGVN(); @@ -332,7 +332,7 @@ } } - return new (phase->C, 3) AddLNode(temp1, temp2); + return new (phase->C) AddLNode(temp1, temp2); } @@ -355,7 +355,7 @@ // division by +/- 1 if (!d_pos) { // Just negate the value - q = new (phase->C, 3) SubLNode(phase->longcon(0), dividend); + q = new (phase->C) SubLNode(phase->longcon(0), dividend); } } else if ( is_power_of_2_long(d) ) { @@ -394,18 +394,18 @@ // (-2+3)>>2 becomes 0, etc. // Compute 0 or -1, based on sign bit - Node *sign = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N - 1))); + Node *sign = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N - 1))); // Mask sign bit to the low sign bits - Node *round = phase->transform(new (phase->C, 3) URShiftLNode(sign, phase->intcon(N - l))); + Node *round = phase->transform(new (phase->C) URShiftLNode(sign, phase->intcon(N - l))); // Round up before shifting - dividend = phase->transform(new (phase->C, 3) AddLNode(dividend, round)); + dividend = phase->transform(new (phase->C) AddLNode(dividend, round)); } // Shift for division - q = new (phase->C, 3) RShiftLNode(dividend, phase->intcon(l)); + q = new (phase->C) RShiftLNode(dividend, phase->intcon(l)); if (!d_pos) { - q = new (phase->C, 3) SubLNode(phase->longcon(0), phase->transform(q)); + q = new (phase->C) SubLNode(phase->longcon(0), phase->transform(q)); } } else if ( !Matcher::use_asm_for_ldiv_by_con(d) ) { // Use hardware DIV instruction when // it is faster than code generated below. @@ -425,17 +425,17 @@ // The magic multiplier is too large for a 64 bit constant. We've adjusted // it down by 2^64, but have to add 1 dividend back in after the multiplication. // This handles the "overflow" case described by Granlund and Montgomery. - mul_hi = phase->transform(new (phase->C, 3) AddLNode(dividend, mul_hi)); + mul_hi = phase->transform(new (phase->C) AddLNode(dividend, mul_hi)); } // Shift over the (adjusted) mulhi if (shift_const != 0) { - mul_hi = phase->transform(new (phase->C, 3) RShiftLNode(mul_hi, phase->intcon(shift_const))); + mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(shift_const))); } // Get a 0 or -1 from the sign of the dividend. Node *addend0 = mul_hi; - Node *addend1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N-1))); + Node *addend1 = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N-1))); // If the divisor is negative, swap the order of the input addends; // this has the effect of negating the quotient. @@ -445,7 +445,7 @@ // Adjust the final quotient by subtracting -1 (adding 1) // from the mul_hi. - q = new (phase->C, 3) SubLNode(addend0, addend1); + q = new (phase->C) SubLNode(addend0, addend1); } } @@ -735,7 +735,7 @@ assert( frexp((double)reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); // return multiplication by the reciprocal - return (new (phase->C, 3) MulFNode(in(1), phase->makecon(TypeF::make(reciprocal)))); + return (new (phase->C) MulFNode(in(1), phase->makecon(TypeF::make(reciprocal)))); } //============================================================================= @@ -829,7 +829,7 @@ assert( frexp(reciprocal, &exp) == 0.5, "reciprocal should be power of 2" ); // return multiplication by the reciprocal - return (new (phase->C, 3) MulDNode(in(1), phase->makecon(TypeD::make(reciprocal)))); + return (new (phase->C) MulDNode(in(1), phase->makecon(TypeD::make(reciprocal)))); } //============================================================================= @@ -856,7 +856,7 @@ if( !ti->is_con() ) return NULL; jint con = ti->get_con(); - Node *hook = new (phase->C, 1) Node(1); + Node *hook = new (phase->C) Node(1); // First, special check for modulo 2^k-1 if( con >= 0 && con < max_jint && is_power_of_2(con+1) ) { @@ -876,24 +876,24 @@ hook->init_req(0, x); // Add a use to x to prevent him from dying // Generate code to reduce X rapidly to nearly 2^k-1. for( int i = 0; i < trip_count; i++ ) { - Node *xl = phase->transform( new (phase->C, 3) AndINode(x,divisor) ); - Node *xh = phase->transform( new (phase->C, 3) RShiftINode(x,phase->intcon(k)) ); // Must be signed - x = phase->transform( new (phase->C, 3) AddINode(xh,xl) ); + Node *xl = phase->transform( new (phase->C) AndINode(x,divisor) ); + Node *xh = phase->transform( new (phase->C) RShiftINode(x,phase->intcon(k)) ); // Must be signed + x = phase->transform( new (phase->C) AddINode(xh,xl) ); hook->set_req(0, x); } // Generate sign-fixup code. Was original value positive? // int hack_res = (i >= 0) ? divisor : 1; - Node *cmp1 = phase->transform( new (phase->C, 3) CmpINode( in(1), phase->intcon(0) ) ); - Node *bol1 = phase->transform( new (phase->C, 2) BoolNode( cmp1, BoolTest::ge ) ); - Node *cmov1= phase->transform( new (phase->C, 4) CMoveINode(bol1, phase->intcon(1), divisor, TypeInt::POS) ); + Node *cmp1 = phase->transform( new (phase->C) CmpINode( in(1), phase->intcon(0) ) ); + Node *bol1 = phase->transform( new (phase->C) BoolNode( cmp1, BoolTest::ge ) ); + Node *cmov1= phase->transform( new (phase->C) CMoveINode(bol1, phase->intcon(1), divisor, TypeInt::POS) ); // if( x >= hack_res ) x -= divisor; - Node *sub = phase->transform( new (phase->C, 3) SubINode( x, divisor ) ); - Node *cmp2 = phase->transform( new (phase->C, 3) CmpINode( x, cmov1 ) ); - Node *bol2 = phase->transform( new (phase->C, 2) BoolNode( cmp2, BoolTest::ge ) ); + Node *sub = phase->transform( new (phase->C) SubINode( x, divisor ) ); + Node *cmp2 = phase->transform( new (phase->C) CmpINode( x, cmov1 ) ); + Node *bol2 = phase->transform( new (phase->C) BoolNode( cmp2, BoolTest::ge ) ); // Convention is to not transform the return value of an Ideal // since Ideal is expected to return a modified 'this' or a new node. - Node *cmov2= new (phase->C, 4) CMoveINode(bol2, x, sub, TypeInt::INT); + Node *cmov2= new (phase->C) CMoveINode(bol2, x, sub, TypeInt::INT); // cmov2 is now the mod // Now remove the bogus extra edges used to keep things alive @@ -916,7 +916,7 @@ jint pos_con = (con >= 0) ? con : -con; // integer Mod 1 is always 0 - if( pos_con == 1 ) return new (phase->C, 1) ConINode(TypeInt::ZERO); + if( pos_con == 1 ) return new (phase->C) ConINode(TypeInt::ZERO); int log2_con = -1; @@ -929,7 +929,7 @@ // See if this can be masked, if the dividend is non-negative if( dti && dti->_lo >= 0 ) - return ( new (phase->C, 3) AndINode( in(1), phase->intcon( pos_con-1 ) ) ); + return ( new (phase->C) AndINode( in(1), phase->intcon( pos_con-1 ) ) ); } // Save in(1) so that it cannot be changed or deleted @@ -944,12 +944,12 @@ Node *mult = NULL; if( log2_con >= 0 ) - mult = phase->transform( new (phase->C, 3) LShiftINode( divide, phase->intcon( log2_con ) ) ); + mult = phase->transform( new (phase->C) LShiftINode( divide, phase->intcon( log2_con ) ) ); else - mult = phase->transform( new (phase->C, 3) MulINode( divide, phase->intcon( pos_con ) ) ); + mult = phase->transform( new (phase->C) MulINode( divide, phase->intcon( pos_con ) ) ); // Finally, subtract the multiplied divided value from the original - result = new (phase->C, 3) SubINode( in(1), mult ); + result = new (phase->C) SubINode( in(1), mult ); } // Now remove the bogus extra edges used to keep things alive @@ -1027,7 +1027,7 @@ if( !tl->is_con() ) return NULL; jlong con = tl->get_con(); - Node *hook = new (phase->C, 1) Node(1); + Node *hook = new (phase->C) Node(1); // Expand mod if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) { @@ -1049,24 +1049,24 @@ hook->init_req(0, x); // Add a use to x to prevent him from dying // Generate code to reduce X rapidly to nearly 2^k-1. for( int i = 0; i < trip_count; i++ ) { - Node *xl = phase->transform( new (phase->C, 3) AndLNode(x,divisor) ); - Node *xh = phase->transform( new (phase->C, 3) RShiftLNode(x,phase->intcon(k)) ); // Must be signed - x = phase->transform( new (phase->C, 3) AddLNode(xh,xl) ); + Node *xl = phase->transform( new (phase->C) AndLNode(x,divisor) ); + Node *xh = phase->transform( new (phase->C) RShiftLNode(x,phase->intcon(k)) ); // Must be signed + x = phase->transform( new (phase->C) AddLNode(xh,xl) ); hook->set_req(0, x); // Add a use to x to prevent him from dying } // Generate sign-fixup code. Was original value positive? // long hack_res = (i >= 0) ? divisor : CONST64(1); - Node *cmp1 = phase->transform( new (phase->C, 3) CmpLNode( in(1), phase->longcon(0) ) ); - Node *bol1 = phase->transform( new (phase->C, 2) BoolNode( cmp1, BoolTest::ge ) ); - Node *cmov1= phase->transform( new (phase->C, 4) CMoveLNode(bol1, phase->longcon(1), divisor, TypeLong::LONG) ); + Node *cmp1 = phase->transform( new (phase->C) CmpLNode( in(1), phase->longcon(0) ) ); + Node *bol1 = phase->transform( new (phase->C) BoolNode( cmp1, BoolTest::ge ) ); + Node *cmov1= phase->transform( new (phase->C) CMoveLNode(bol1, phase->longcon(1), divisor, TypeLong::LONG) ); // if( x >= hack_res ) x -= divisor; - Node *sub = phase->transform( new (phase->C, 3) SubLNode( x, divisor ) ); - Node *cmp2 = phase->transform( new (phase->C, 3) CmpLNode( x, cmov1 ) ); - Node *bol2 = phase->transform( new (phase->C, 2) BoolNode( cmp2, BoolTest::ge ) ); + Node *sub = phase->transform( new (phase->C) SubLNode( x, divisor ) ); + Node *cmp2 = phase->transform( new (phase->C) CmpLNode( x, cmov1 ) ); + Node *bol2 = phase->transform( new (phase->C) BoolNode( cmp2, BoolTest::ge ) ); // Convention is to not transform the return value of an Ideal // since Ideal is expected to return a modified 'this' or a new node. - Node *cmov2= new (phase->C, 4) CMoveLNode(bol2, x, sub, TypeLong::LONG); + Node *cmov2= new (phase->C) CMoveLNode(bol2, x, sub, TypeLong::LONG); // cmov2 is now the mod // Now remove the bogus extra edges used to keep things alive @@ -1089,7 +1089,7 @@ jlong pos_con = (con >= 0) ? con : -con; // integer Mod 1 is always 0 - if( pos_con == 1 ) return new (phase->C, 1) ConLNode(TypeLong::ZERO); + if( pos_con == 1 ) return new (phase->C) ConLNode(TypeLong::ZERO); int log2_con = -1; @@ -1102,7 +1102,7 @@ // See if this can be masked, if the dividend is non-negative if( dtl && dtl->_lo >= 0 ) - return ( new (phase->C, 3) AndLNode( in(1), phase->longcon( pos_con-1 ) ) ); + return ( new (phase->C) AndLNode( in(1), phase->longcon( pos_con-1 ) ) ); } // Save in(1) so that it cannot be changed or deleted @@ -1117,12 +1117,12 @@ Node *mult = NULL; if( log2_con >= 0 ) - mult = phase->transform( new (phase->C, 3) LShiftLNode( divide, phase->intcon( log2_con ) ) ); + mult = phase->transform( new (phase->C) LShiftLNode( divide, phase->intcon( log2_con ) ) ); else - mult = phase->transform( new (phase->C, 3) MulLNode( divide, phase->longcon( pos_con ) ) ); + mult = phase->transform( new (phase->C) MulLNode( divide, phase->longcon( pos_con ) ) ); // Finally, subtract the multiplied divided value from the original - result = new (phase->C, 3) SubLNode( in(1), mult ); + result = new (phase->C) SubLNode( in(1), mult ); } // Now remove the bogus extra edges used to keep things alive @@ -1277,9 +1277,9 @@ assert(n->Opcode() == Op_DivI || n->Opcode() == Op_ModI, "only div or mod input pattern accepted"); - DivModINode* divmod = new (C, 3) DivModINode(n->in(0), n->in(1), n->in(2)); - Node* dproj = new (C, 1) ProjNode(divmod, DivModNode::div_proj_num); - Node* mproj = new (C, 1) ProjNode(divmod, DivModNode::mod_proj_num); + DivModINode* divmod = new (C) DivModINode(n->in(0), n->in(1), n->in(2)); + Node* dproj = new (C) ProjNode(divmod, DivModNode::div_proj_num); + Node* mproj = new (C) ProjNode(divmod, DivModNode::mod_proj_num); return divmod; } @@ -1289,9 +1289,9 @@ assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL, "only div or mod input pattern accepted"); - DivModLNode* divmod = new (C, 3) DivModLNode(n->in(0), n->in(1), n->in(2)); - Node* dproj = new (C, 1) ProjNode(divmod, DivModNode::div_proj_num); - Node* mproj = new (C, 1) ProjNode(divmod, DivModNode::mod_proj_num); + DivModLNode* divmod = new (C) DivModLNode(n->in(0), n->in(1), n->in(2)); + Node* dproj = new (C) ProjNode(divmod, DivModNode::div_proj_num); + Node* mproj = new (C) ProjNode(divmod, DivModNode::mod_proj_num); return divmod; } @@ -1306,7 +1306,7 @@ assert(proj->_con == mod_proj_num, "must be div or mod projection"); rm = match->modI_proj_mask(); } - return new (match->C, 1)MachProjNode(this, proj->_con, rm, ideal_reg); + return new (match->C)MachProjNode(this, proj->_con, rm, ideal_reg); } @@ -1321,5 +1321,5 @@ assert(proj->_con == mod_proj_num, "must be div or mod projection"); rm = match->modL_proj_mask(); } - return new (match->C, 1)MachProjNode(this, proj->_con, rm, ideal_reg); + return new (match->C)MachProjNode(this, proj->_con, rm, ideal_reg); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/doCall.cpp --- a/src/share/vm/opto/doCall.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/doCall.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -40,11 +40,10 @@ #include "prims/nativeLookup.hpp" #include "runtime/sharedRuntime.hpp" -#ifndef PRODUCT void trace_type_profile(ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) { - if (TraceTypeProfile || PrintInlining || PrintOptoInlining) { + if (TraceTypeProfile || PrintInlining NOT_PRODUCT(|| PrintOptoInlining)) { if (!PrintInlining) { - if (!PrintOpto && !PrintCompilation) { + if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) { method->print_short_name(); tty->cr(); } @@ -56,7 +55,6 @@ tty->cr(); } } -#endif CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, @@ -225,13 +223,13 @@ } if (miss_cg != NULL) { if (next_hit_cg != NULL) { - NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1))); + trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1)); // We don't need to record dependency on a receiver here and below. // Whenever we inline, the dependency is added by Parse::Parse(). miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX); } if (miss_cg != NULL) { - NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count)); + trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count); CallGenerator* cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0)); if (cg != NULL) return cg; } @@ -514,15 +512,15 @@ } else if (rt == T_INT || is_subword_type(rt)) { // FIXME: This logic should be factored out. if (ct == T_BOOLEAN) { - retnode = _gvn.transform( new (C, 3) AndINode(retnode, intcon(0x1)) ); + retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0x1)) ); } else if (ct == T_CHAR) { - retnode = _gvn.transform( new (C, 3) AndINode(retnode, intcon(0xFFFF)) ); + retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFFFF)) ); } else if (ct == T_BYTE) { - retnode = _gvn.transform( new (C, 3) LShiftINode(retnode, intcon(24)) ); - retnode = _gvn.transform( new (C, 3) RShiftINode(retnode, intcon(24)) ); + retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(24)) ); + retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(24)) ); } else if (ct == T_SHORT) { - retnode = _gvn.transform( new (C, 3) LShiftINode(retnode, intcon(16)) ); - retnode = _gvn.transform( new (C, 3) RShiftINode(retnode, intcon(16)) ); + retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(16)) ); + retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(16)) ); } else { assert(ct == T_INT, err_msg_res("rt=%s, ct=%s", type2name(rt), type2name(ct))); } @@ -532,7 +530,7 @@ const TypeOopPtr* arg_type = TypeOopPtr::make_from_klass(rtype->as_klass()); const Type* sig_type = TypeOopPtr::make_from_klass(ctype->as_klass()); if (arg_type != NULL && !arg_type->higher_equal(sig_type)) { - Node* cast_obj = _gvn.transform(new (C, 2) CheckCastPPNode(control(), retnode, sig_type)); + Node* cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(), retnode, sig_type)); pop(); push(cast_obj); } @@ -614,7 +612,7 @@ } int len = bcis->length(); - CatchNode *cn = new (C, 2) CatchNode(control(), i_o, len+1); + CatchNode *cn = new (C) CatchNode(control(), i_o, len+1); Node *catch_ = _gvn.transform(cn); // now branch with the exception state to each of the (potential) @@ -625,14 +623,14 @@ // Locals are just copied from before the call. // Get control from the CatchNode. int handler_bci = bcis->at(i); - Node* ctrl = _gvn.transform( new (C, 1) CatchProjNode(catch_, i+1,handler_bci)); + Node* ctrl = _gvn.transform( new (C) CatchProjNode(catch_, i+1,handler_bci)); // This handler cannot happen? if (ctrl == top()) continue; set_control(ctrl); // Create exception oop const TypeInstPtr* extype = extypes->at(i)->is_instptr(); - Node *ex_oop = _gvn.transform(new (C, 2) CreateExNode(extypes->at(i), ctrl, i_o)); + Node *ex_oop = _gvn.transform(new (C) CreateExNode(extypes->at(i), ctrl, i_o)); // Handle unloaded exception classes. if (saw_unloaded->contains(handler_bci)) { @@ -671,7 +669,7 @@ // The first CatchProj is for the normal return. // (Note: If this is a call to rethrow_Java, this node goes dead.) - set_control(_gvn.transform( new (C, 1) CatchProjNode(catch_, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci))); + set_control(_gvn.transform( new (C) CatchProjNode(catch_, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci))); } @@ -722,7 +720,7 @@ // I'm loading the class from, I can replace the LoadKlass with the // klass constant for the exception oop. if( ex_node->is_Phi() ) { - ex_klass_node = new (C, ex_node->req()) PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT ); + ex_klass_node = new (C) PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT ); for( uint i = 1; i < ex_node->req(); i++ ) { Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() ); Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) ); @@ -788,7 +786,7 @@ PreserveJVMState pjvms(this); const TypeInstPtr* tinst = TypeOopPtr::make_from_klass_unique(klass)->cast_to_ptr_type(TypePtr::NotNull)->is_instptr(); assert(klass->has_subklass() || tinst->klass_is_exact(), "lost exactness"); - Node* ex_oop = _gvn.transform(new (C, 2) CheckCastPPNode(control(), ex_node, tinst)); + Node* ex_oop = _gvn.transform(new (C) CheckCastPPNode(control(), ex_node, tinst)); push_ex_oop(ex_oop); // Push exception oop for handler #ifndef PRODUCT if (PrintOpto && WizardMode) { diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/escape.cpp --- a/src/share/vm/opto/escape.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/escape.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -282,6 +282,26 @@ return has_non_escaping_obj; } +// Utility function for nodes that load an object +void ConnectionGraph::add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) { + // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because + // ThreadLocal has RawPtr type. + const Type* t = _igvn->type(n); + if (t->make_ptr() != NULL) { + Node* adr = n->in(MemNode::Address); +#ifdef ASSERT + if (!adr->is_AddP()) { + assert(_igvn->type(adr)->isa_rawptr(), "sanity"); + } else { + assert((ptnode_adr(adr->_idx) == NULL || + ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity"); + } +#endif + add_local_var_and_edge(n, PointsToNode::NoEscape, + adr, delayed_worklist); + } +} + // Populate Connection Graph with PointsTo nodes and create simple // connection graph edges. void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) { @@ -387,22 +407,7 @@ case Op_LoadP: case Op_LoadN: case Op_LoadPLocked: { - // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because - // ThreadLocal has RawPrt type. - const Type* t = igvn->type(n); - if (t->make_ptr() != NULL) { - Node* adr = n->in(MemNode::Address); -#ifdef ASSERT - if (!adr->is_AddP()) { - assert(igvn->type(adr)->isa_rawptr(), "sanity"); - } else { - assert((ptnode_adr(adr->_idx) == NULL || - ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity"); - } -#endif - add_local_var_and_edge(n, PointsToNode::NoEscape, - adr, delayed_worklist); - } + add_objload_to_connection_graph(n, delayed_worklist); break; } case Op_Parm: { @@ -417,7 +422,7 @@ } case Op_Phi: { // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because - // ThreadLocal has RawPrt type. + // ThreadLocal has RawPtr type. const Type* t = n->as_Phi()->type(); if (t->make_ptr() != NULL) { add_local_var(n, PointsToNode::NoEscape); @@ -446,6 +451,11 @@ } break; } + case Op_GetAndSetP: + case Op_GetAndSetN: { + add_objload_to_connection_graph(n, delayed_worklist); + // fallthrough + } case Op_StoreP: case Op_StoreN: case Op_StorePConditional: @@ -585,7 +595,7 @@ case Op_LoadN: case Op_LoadPLocked: { // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because - // ThreadLocal has RawPrt type. + // ThreadLocal has RawPtr type. const Type* t = _igvn->type(n); if (t->make_ptr() != NULL) { Node* adr = n->in(MemNode::Address); @@ -596,7 +606,7 @@ } case Op_Phi: { // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because - // ThreadLocal has RawPrt type. + // ThreadLocal has RawPtr type. const Type* t = n->as_Phi()->type(); if (t->make_ptr() != NULL) { for (uint i = 1; i < n->req(); i++) { @@ -638,8 +648,16 @@ case Op_StoreN: case Op_StorePConditional: case Op_CompareAndSwapP: - case Op_CompareAndSwapN: { + case Op_CompareAndSwapN: + case Op_GetAndSetP: + case Op_GetAndSetN: { Node* adr = n->in(MemNode::Address); + if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) { + const Type* t = _igvn->type(n); + if (t->make_ptr() != NULL) { + add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL); + } + } const Type *adr_type = _igvn->type(adr); adr_type = adr_type->make_ptr(); if (adr_type->isa_oopptr() || diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/escape.hpp --- a/src/share/vm/opto/escape.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/escape.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -371,6 +371,8 @@ _nodes.at_put(n->_idx, ptn); } + // Utility function for nodes that load an object + void add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist); // Create PointsToNode node and add it to Connection Graph. void add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/generateOptoStub.cpp --- a/src/share/vm/opto/generateOptoStub.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/generateOptoStub.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -50,7 +50,7 @@ const TypeTuple *jrange = C->tf()->range(); // The procedure start - StartNode* start = new (C, 2) StartNode(root(), jdomain); + StartNode* start = new (C) StartNode(root(), jdomain); _gvn.set_type_bottom(start); // Make a map, with JVM state @@ -63,7 +63,7 @@ jvms->set_monoff(max_map); jvms->set_endoff(max_map); { - SafePointNode *map = new (C, max_map) SafePointNode( max_map, jvms ); + SafePointNode *map = new (C) SafePointNode( max_map, jvms ); jvms->set_map(map); set_jvms(jvms); assert(map == this->map(), "kit.map is set"); @@ -72,7 +72,7 @@ // Make up the parameters uint i; for( i = 0; i < parm_cnt; i++ ) - map()->init_req(i, _gvn.transform(new (C, 1) ParmNode(start, i))); + map()->init_req(i, _gvn.transform(new (C) ParmNode(start, i))); for( ; ireq(); i++ ) map()->init_req(i, top()); // For nicer debugging @@ -80,7 +80,7 @@ set_all_memory(map()->memory()); // Get base of thread-local storage area - Node* thread = _gvn.transform( new (C, 1) ThreadLocalNode() ); + Node* thread = _gvn.transform( new (C) ThreadLocalNode() ); const int NoAlias = Compile::AliasIdxBot; @@ -160,7 +160,7 @@ //----------------------------- // Make the call node - CallRuntimeNode *call = new (C, c_sig->domain()->cnt()) + CallRuntimeNode *call = new (C) CallRuntimeNode(c_sig, C_function, name, TypePtr::BOTTOM); //----------------------------- @@ -186,23 +186,23 @@ //----------------------------- // Now set up the return results - set_control( _gvn.transform( new (C, 1) ProjNode(call,TypeFunc::Control)) ); - set_i_o( _gvn.transform( new (C, 1) ProjNode(call,TypeFunc::I_O )) ); + set_control( _gvn.transform( new (C) ProjNode(call,TypeFunc::Control)) ); + set_i_o( _gvn.transform( new (C) ProjNode(call,TypeFunc::I_O )) ); set_all_memory_call(call); if (range->cnt() > TypeFunc::Parms) { - Node* retnode = _gvn.transform( new (C, 1) ProjNode(call,TypeFunc::Parms) ); + Node* retnode = _gvn.transform( new (C) ProjNode(call,TypeFunc::Parms) ); // C-land is allowed to return sub-word values. Convert to integer type. assert( retval != Type::TOP, "" ); if (retval == TypeInt::BOOL) { - retnode = _gvn.transform( new (C, 3) AndINode(retnode, intcon(0xFF)) ); + retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFF)) ); } else if (retval == TypeInt::CHAR) { - retnode = _gvn.transform( new (C, 3) AndINode(retnode, intcon(0xFFFF)) ); + retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFFFF)) ); } else if (retval == TypeInt::BYTE) { - retnode = _gvn.transform( new (C, 3) LShiftINode(retnode, intcon(24)) ); - retnode = _gvn.transform( new (C, 3) RShiftINode(retnode, intcon(24)) ); + retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(24)) ); + retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(24)) ); } else if (retval == TypeInt::SHORT) { - retnode = _gvn.transform( new (C, 3) LShiftINode(retnode, intcon(16)) ); - retnode = _gvn.transform( new (C, 3) RShiftINode(retnode, intcon(16)) ); + retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(16)) ); + retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(16)) ); } map()->set_req( TypeFunc::Parms, retnode ); } @@ -247,21 +247,21 @@ Node* exit_memory = reset_memory(); - Node* cmp = _gvn.transform( new (C, 3) CmpPNode(pending, null()) ); - Node* bo = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) ); + Node* cmp = _gvn.transform( new (C) CmpPNode(pending, null()) ); + Node* bo = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ne) ); IfNode *iff = create_and_map_if(control(), bo, PROB_MIN, COUNT_UNKNOWN); - Node* if_null = _gvn.transform( new (C, 1) IfFalseNode(iff) ); - Node* if_not_null = _gvn.transform( new (C, 1) IfTrueNode(iff) ); + Node* if_null = _gvn.transform( new (C) IfFalseNode(iff) ); + Node* if_not_null = _gvn.transform( new (C) IfTrueNode(iff) ); assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before"); Node *exc_target = makecon(TypeRawPtr::make( StubRoutines::forward_exception_entry() )); - Node *to_exc = new (C, TypeFunc::Parms+2) TailCallNode(if_not_null, - i_o(), - exit_memory, - frameptr(), - returnadr(), - exc_target, null()); + Node *to_exc = new (C) TailCallNode(if_not_null, + i_o(), + exit_memory, + frameptr(), + returnadr(), + exc_target, null()); root()->add_req(_gvn.transform(to_exc)); // bind to root to keep live C->init_start(start); @@ -271,31 +271,31 @@ switch( is_fancy_jump ) { case 0: // Make a return instruction // Return to caller, free any space for return address - ret = new (C, TypeFunc::Parms) ReturnNode(TypeFunc::Parms, if_null, - i_o(), - exit_memory, - frameptr(), - returnadr()); + ret = new (C) ReturnNode(TypeFunc::Parms, if_null, + i_o(), + exit_memory, + frameptr(), + returnadr()); if (C->tf()->range()->cnt() > TypeFunc::Parms) ret->add_req( map()->in(TypeFunc::Parms) ); break; case 1: // This is a fancy tail-call jump. Jump to computed address. // Jump to new callee; leave old return address alone. - ret = new (C, TypeFunc::Parms+2) TailCallNode(if_null, - i_o(), - exit_memory, - frameptr(), - returnadr(), - target, map()->in(TypeFunc::Parms)); + ret = new (C) TailCallNode(if_null, + i_o(), + exit_memory, + frameptr(), + returnadr(), + target, map()->in(TypeFunc::Parms)); break; case 2: // Pop return address & jump // Throw away old return address; jump to new computed address //assert(C_function == CAST_FROM_FN_PTR(address, OptoRuntime::rethrow_C), "fancy_jump==2 only for rethrow"); - ret = new (C, TypeFunc::Parms+2) TailJumpNode(if_null, - i_o(), - exit_memory, - frameptr(), - target, map()->in(TypeFunc::Parms)); + ret = new (C) TailJumpNode(if_null, + i_o(), + exit_memory, + frameptr(), + target, map()->in(TypeFunc::Parms)); break; default: ShouldNotReachHere(); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/graphKit.cpp --- a/src/share/vm/opto/graphKit.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/graphKit.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -280,7 +280,7 @@ JVMState* jvms = new (C) JVMState(_method, NULL); jvms->set_bci(_bci); jvms->set_sp(_sp); - jvms->set_map(new (C, TypeFunc::Parms) SafePointNode(TypeFunc::Parms, jvms)); + jvms->set_map(new (C) SafePointNode(TypeFunc::Parms, jvms)); set_jvms(jvms); for (uint i = 0; i < map()->req(); i++) map()->init_req(i, top()); set_all_memory(top()); @@ -332,7 +332,7 @@ if (region->in(0) != hidden_merge_mark) { // The control input is not (yet) a specially-marked region in phi_map. // Make it so, and build some phis. - region = new (C, 2) RegionNode(2); + region = new (C) RegionNode(2); _gvn.set_type(region, Type::CONTROL); region->set_req(0, hidden_merge_mark); // marks an internal ex-state region->init_req(1, phi_map->control()); @@ -481,13 +481,13 @@ // take the uncommon_trap in the BuildCutout below. // first must access the should_post_on_exceptions_flag in this thread's JavaThread - Node* jthread = _gvn.transform(new (C, 1) ThreadLocalNode()); + Node* jthread = _gvn.transform(new (C) ThreadLocalNode()); Node* adr = basic_plus_adr(top(), jthread, in_bytes(JavaThread::should_post_on_exceptions_flag_offset())); Node* should_post_flag = make_load(control(), adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw, false); // Test the should_post_on_exceptions_flag vs. 0 - Node* chk = _gvn.transform( new (C, 3) CmpINode(should_post_flag, intcon(0)) ); - Node* tst = _gvn.transform( new (C, 2) BoolNode(chk, BoolTest::eq) ); + Node* chk = _gvn.transform( new (C) CmpINode(should_post_flag, intcon(0)) ); + Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) ); // Branch to slow_path if should_post_on_exceptions_flag was true { BuildCutout unless(this, tst, PROB_MAX); @@ -656,8 +656,8 @@ SafePointNode* outer_map = _map; // preserved map is caller's SafePointNode* inner_map = kit->map(); IfNode* iff = kit->create_and_map_if(outer_map->control(), p, prob, cnt); - outer_map->set_control(kit->gvn().transform( new (kit->C, 1) IfTrueNode(iff) )); - inner_map->set_control(kit->gvn().transform( new (kit->C, 1) IfFalseNode(iff) )); + outer_map->set_control(kit->gvn().transform( new (kit->C) IfTrueNode(iff) )); + inner_map->set_control(kit->gvn().transform( new (kit->C) IfFalseNode(iff) )); } BuildCutout::~BuildCutout() { GraphKit* kit = _kit; @@ -1108,7 +1108,7 @@ Node* GraphKit::basic_plus_adr(Node* base, Node* ptr, Node* offset) { // short-circuit a common case if (offset == intcon(0)) return ptr; - return _gvn.transform( new (C, 4) AddPNode(base, ptr, offset) ); + return _gvn.transform( new (C) AddPNode(base, ptr, offset) ); } Node* GraphKit::ConvI2L(Node* offset) { @@ -1117,7 +1117,7 @@ if (offset_con != Type::OffsetBot) { return longcon((long) offset_con); } - return _gvn.transform( new (C, 2) ConvI2LNode(offset)); + return _gvn.transform( new (C) ConvI2LNode(offset)); } Node* GraphKit::ConvL2I(Node* offset) { // short-circuit a common case @@ -1125,7 +1125,7 @@ if (offset_con != (jlong)Type::OffsetBot) { return intcon((int) offset_con); } - return _gvn.transform( new (C, 2) ConvL2INode(offset)); + return _gvn.transform( new (C) ConvL2INode(offset)); } //-------------------------load_object_klass----------------------------------- @@ -1144,7 +1144,7 @@ Node *alen; if (alloc == NULL) { Node *r_adr = basic_plus_adr(array, arrayOopDesc::length_offset_in_bytes()); - alen = _gvn.transform( new (C, 3) LoadRangeNode(0, immutable_memory(), r_adr, TypeInt::POS)); + alen = _gvn.transform( new (C) LoadRangeNode(0, immutable_memory(), r_adr, TypeInt::POS)); } else { alen = alloc->Ideal_length(); Node* ccast = alloc->make_ideal_length(_gvn.type(array)->is_oopptr(), &_gvn); @@ -1177,8 +1177,8 @@ // Construct NULL check Node *chk = NULL; switch(type) { - case T_LONG : chk = new (C, 3) CmpLNode(value, _gvn.zerocon(T_LONG)); break; - case T_INT : chk = new (C, 3) CmpINode( value, _gvn.intcon(0)); break; + case T_LONG : chk = new (C) CmpLNode(value, _gvn.zerocon(T_LONG)); break; + case T_INT : chk = new (C) CmpINode( value, _gvn.intcon(0)); break; case T_ARRAY : // fall through type = T_OBJECT; // simplify further tests case T_OBJECT : { @@ -1225,7 +1225,7 @@ return value; // Elided null check quickly! } } - chk = new (C, 3) CmpPNode( value, null() ); + chk = new (C) CmpPNode( value, null() ); break; } @@ -1235,7 +1235,7 @@ chk = _gvn.transform(chk); BoolTest::mask btest = assert_null ? BoolTest::eq : BoolTest::ne; - BoolNode *btst = new (C, 2) BoolNode( chk, btest); + BoolNode *btst = new (C) BoolNode( chk, btest); Node *tst = _gvn.transform( btst ); //----------- @@ -1302,8 +1302,8 @@ if (null_control != NULL) { IfNode* iff = create_and_map_if(control(), tst, ok_prob, COUNT_UNKNOWN); - Node* null_true = _gvn.transform( new (C, 1) IfFalseNode(iff)); - set_control( _gvn.transform( new (C, 1) IfTrueNode(iff))); + Node* null_true = _gvn.transform( new (C) IfFalseNode(iff)); + set_control( _gvn.transform( new (C) IfTrueNode(iff))); if (null_true == top()) explicit_null_checks_elided++; (*null_control) = null_true; @@ -1355,7 +1355,7 @@ // Object is already not-null? if( t == t_not_null ) return obj; - Node *cast = new (C, 2) CastPPNode(obj,t_not_null); + Node *cast = new (C) CastPPNode(obj,t_not_null); cast->init_req(0, control()); cast = _gvn.transform( cast ); @@ -1410,7 +1410,7 @@ //------------------------------set_all_memory_call---------------------------- void GraphKit::set_all_memory_call(Node* call, bool separate_io_proj) { - Node* newmem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory, separate_io_proj) ); + Node* newmem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory, separate_io_proj) ); set_all_memory(newmem); } @@ -1614,9 +1614,9 @@ int index_max = max_jint - 1; // array size is max_jint, index is one less if (sizetype != NULL) index_max = sizetype->_hi - 1; const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax); - idx = _gvn.transform( new (C, 2) ConvI2LNode(idx, lidxtype) ); + idx = _gvn.transform( new (C) ConvI2LNode(idx, lidxtype) ); #endif - Node* scale = _gvn.transform( new (C, 3) LShiftXNode(idx, intcon(shift)) ); + Node* scale = _gvn.transform( new (C) LShiftXNode(idx, intcon(shift)) ); return basic_plus_adr(ary, base, scale); } @@ -1664,8 +1664,8 @@ // Re-use the current map to produce the result. - set_control(_gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Control))); - set_i_o( _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::I_O , separate_io_proj))); + set_control(_gvn.transform(new (C) ProjNode(call, TypeFunc::Control))); + set_i_o( _gvn.transform(new (C) ProjNode(call, TypeFunc::I_O , separate_io_proj))); set_all_memory_call(xcall, separate_io_proj); //return xcall; // no need, caller already has it @@ -1679,7 +1679,7 @@ if (call->method() == NULL || call->method()->return_type()->basic_type() == T_VOID) ret = top(); - else ret = _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Parms)); + else ret = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); // Note: Since any out-of-line call can produce an exception, // we always insert an I_O projection from the call into the result. @@ -1690,8 +1690,8 @@ // The caller requested separate projections be used by the fall // through and exceptional paths, so replace the projections for // the fall through path. - set_i_o(_gvn.transform( new (C, 1) ProjNode(call, TypeFunc::I_O) )); - set_all_memory(_gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) )); + set_i_o(_gvn.transform( new (C) ProjNode(call, TypeFunc::I_O) )); + set_all_memory(_gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) )); } return ret; } @@ -1731,13 +1731,13 @@ Node* keep_mem, const TypePtr* hook_mem) { // no i/o - set_control(_gvn.transform( new (C, 1) ProjNode(call,TypeFunc::Control) )); + set_control(_gvn.transform( new (C) ProjNode(call,TypeFunc::Control) )); if (keep_mem) { // First clone the existing memory state set_all_memory(keep_mem); if (hook_mem != NULL) { // Make memory for the call - Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) ); + Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) ); // Set the RawPtr memory state only. This covers all the heap top/GC stuff // We also use hook_mem to extract specific effects from arraycopy stubs. set_memory(mem, hook_mem); @@ -1841,7 +1841,7 @@ int adr_type = Compile::AliasIdxRaw; Node* ctrl = control(); Node* cnt = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type); - Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1))); + Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1))); store_to_memory( ctrl, counter_addr, incr, T_INT, adr_type ); } @@ -1957,7 +1957,7 @@ // The debug info is the only real input to this call. // Halt-and-catch fire here. The above call should never return! - HaltNode* halt = new(C, TypeFunc::Parms) HaltNode(control(), frameptr()); + HaltNode* halt = new(C) HaltNode(control(), frameptr()); _gvn.set_type_bottom(halt); root()->add_req(halt); @@ -2013,7 +2013,7 @@ Node* GraphKit::precision_rounding(Node* n) { return UseStrictFP && _method->flags().is_strict() && UseSSE == 0 && Matcher::strict_fp_requires_explicit_rounding - ? _gvn.transform( new (C, 2) RoundFloatNode(0, n) ) + ? _gvn.transform( new (C) RoundFloatNode(0, n) ) : n; } @@ -2021,7 +2021,7 @@ Node* GraphKit::dprecision_rounding(Node *n) { return UseStrictFP && _method->flags().is_strict() && UseSSE <= 1 && Matcher::strict_fp_requires_explicit_rounding - ? _gvn.transform( new (C, 2) RoundDoubleNode(0, n) ) + ? _gvn.transform( new (C) RoundDoubleNode(0, n) ) : n; } @@ -2029,7 +2029,7 @@ Node* GraphKit::dstore_rounding(Node* n) { return Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1 - ? _gvn.transform( new (C, 2) RoundDoubleNode(0, n) ) + ? _gvn.transform( new (C) RoundDoubleNode(0, n) ) : n; } @@ -2102,11 +2102,11 @@ IfNode *opt_iff = _gvn.transform(iff)->as_If(); // Fast path taken; set region slot 2 - Node *fast_taken = _gvn.transform( new (C, 1) IfFalseNode(opt_iff) ); + Node *fast_taken = _gvn.transform( new (C) IfFalseNode(opt_iff) ); region->init_req(2,fast_taken); // Capture fast-control // Fast path not-taken, i.e. slow path - Node *slow_taken = _gvn.transform( new (C, 1) IfTrueNode(opt_iff) ); + Node *slow_taken = _gvn.transform( new (C) IfTrueNode(opt_iff) ); return slow_taken; } @@ -2122,7 +2122,6 @@ Node* parm4, Node* parm5, Node* parm6, Node* parm7) { // Slow-path call - int size = call_type->domain()->cnt(); bool is_leaf = !(flags & RC_NO_LEAF); bool has_io = (!is_leaf && !(flags & RC_NO_IO)); if (call_name == NULL) { @@ -2131,12 +2130,12 @@ } CallNode* call; if (!is_leaf) { - call = new(C, size) CallStaticJavaNode(call_type, call_addr, call_name, + call = new(C) CallStaticJavaNode(call_type, call_addr, call_name, bci(), adr_type); } else if (flags & RC_NO_FP) { - call = new(C, size) CallLeafNoFPNode(call_type, call_addr, call_name, adr_type); + call = new(C) CallLeafNoFPNode(call_type, call_addr, call_name, adr_type); } else { - call = new(C, size) CallLeafNode(call_type, call_addr, call_name, adr_type); + call = new(C) CallLeafNode(call_type, call_addr, call_name, adr_type); } // The following is similar to set_edges_for_java_call, @@ -2197,7 +2196,7 @@ } if (has_io) { - set_i_o(_gvn.transform(new (C, 1) ProjNode(call, TypeFunc::I_O))); + set_i_o(_gvn.transform(new (C) ProjNode(call, TypeFunc::I_O))); } return call; @@ -2238,10 +2237,10 @@ if (stopped()) return; // Make a catch node with just two handlers: fall-through and catch-all - Node* i_o = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::I_O, separate_io_proj) ); - Node* catc = _gvn.transform( new (C, 2) CatchNode(control(), i_o, 2) ); - Node* norm = _gvn.transform( new (C, 1) CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) ); - Node* excp = _gvn.transform( new (C, 1) CatchProjNode(catc, CatchProjNode::catch_all_index, CatchProjNode::no_handler_bci) ); + Node* i_o = _gvn.transform( new (C) ProjNode(call, TypeFunc::I_O, separate_io_proj) ); + Node* catc = _gvn.transform( new (C) CatchNode(control(), i_o, 2) ); + Node* norm = _gvn.transform( new (C) CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) ); + Node* excp = _gvn.transform( new (C) CatchProjNode(catc, CatchProjNode::catch_all_index, CatchProjNode::no_handler_bci) ); { PreserveJVMState pjvms(this); set_control(excp); @@ -2251,7 +2250,7 @@ // Create an exception state also. // Use an exact type if the caller has specified a specific exception. const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull); - Node* ex_oop = new (C, 2) CreateExNode(ex_type, control(), i_o); + Node* ex_oop = new (C) CreateExNode(ex_type, control(), i_o); add_exception_state(make_exception_state(_gvn.transform(ex_oop))); } } @@ -2301,11 +2300,11 @@ case SSC_easy_test: { // Just do a direct pointer compare and be done. - Node* cmp = _gvn.transform( new(C, 3) CmpPNode(subklass, superklass) ); - Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) ); + Node* cmp = _gvn.transform( new(C) CmpPNode(subklass, superklass) ); + Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) ); IfNode* iff = create_and_xform_if(control(), bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); - set_control( _gvn.transform( new(C, 1) IfTrueNode (iff) ) ); - return _gvn.transform( new(C, 1) IfFalseNode(iff) ); + set_control( _gvn.transform( new(C) IfTrueNode (iff) ) ); + return _gvn.transform( new(C) IfFalseNode(iff) ); } case SSC_full_test: break; @@ -2320,7 +2319,7 @@ // First load the super-klass's check-offset Node *p1 = basic_plus_adr( superklass, superklass, in_bytes(Klass::super_check_offset_offset()) ); - Node *chk_off = _gvn.transform( new (C, 3) LoadINode( NULL, memory(p1), p1, _gvn.type(p1)->is_ptr() ) ); + Node *chk_off = _gvn.transform( new (C) LoadINode( NULL, memory(p1), p1, _gvn.type(p1)->is_ptr() ) ); int cacheoff_con = in_bytes(Klass::secondary_super_cache_offset()); bool might_be_cache = (find_int_con(chk_off, cacheoff_con) == cacheoff_con); @@ -2331,7 +2330,7 @@ // Worst-case type is a little odd: NULL is allowed as a result (usually // klass loads can never produce a NULL). Node *chk_off_X = ConvI2X(chk_off); - Node *p2 = _gvn.transform( new (C, 4) AddPNode(subklass,subklass,chk_off_X) ); + Node *p2 = _gvn.transform( new (C) AddPNode(subklass,subklass,chk_off_X) ); // For some types like interfaces the following loadKlass is from a 1-word // cache which is mutable so can't use immutable memory. Other // types load from the super-class display table which is immutable. @@ -2345,11 +2344,11 @@ // See if we get an immediate positive hit. Happens roughly 83% of the // time. Test to see if the value loaded just previously from the subklass // is exactly the superklass. - Node *cmp1 = _gvn.transform( new (C, 3) CmpPNode( superklass, nkls ) ); - Node *bol1 = _gvn.transform( new (C, 2) BoolNode( cmp1, BoolTest::eq ) ); + Node *cmp1 = _gvn.transform( new (C) CmpPNode( superklass, nkls ) ); + Node *bol1 = _gvn.transform( new (C) BoolNode( cmp1, BoolTest::eq ) ); IfNode *iff1 = create_and_xform_if( control(), bol1, PROB_LIKELY(0.83f), COUNT_UNKNOWN ); - Node *iftrue1 = _gvn.transform( new (C, 1) IfTrueNode ( iff1 ) ); - set_control( _gvn.transform( new (C, 1) IfFalseNode( iff1 ) ) ); + Node *iftrue1 = _gvn.transform( new (C) IfTrueNode ( iff1 ) ); + set_control( _gvn.transform( new (C) IfFalseNode( iff1 ) ) ); // Compile speed common case: Check for being deterministic right now. If // chk_off is a constant and not equal to cacheoff then we are NOT a @@ -2362,9 +2361,9 @@ } // Gather the various success & failures here - RegionNode *r_ok_subtype = new (C, 4) RegionNode(4); + RegionNode *r_ok_subtype = new (C) RegionNode(4); record_for_igvn(r_ok_subtype); - RegionNode *r_not_subtype = new (C, 3) RegionNode(3); + RegionNode *r_not_subtype = new (C) RegionNode(3); record_for_igvn(r_not_subtype); r_ok_subtype->init_req(1, iftrue1); @@ -2375,20 +2374,20 @@ // cache. If it points to the display (and NOT the cache) and the display // missed then it's not a subtype. Node *cacheoff = _gvn.intcon(cacheoff_con); - Node *cmp2 = _gvn.transform( new (C, 3) CmpINode( chk_off, cacheoff ) ); - Node *bol2 = _gvn.transform( new (C, 2) BoolNode( cmp2, BoolTest::ne ) ); + Node *cmp2 = _gvn.transform( new (C) CmpINode( chk_off, cacheoff ) ); + Node *bol2 = _gvn.transform( new (C) BoolNode( cmp2, BoolTest::ne ) ); IfNode *iff2 = create_and_xform_if( control(), bol2, PROB_LIKELY(0.63f), COUNT_UNKNOWN ); - r_not_subtype->init_req(1, _gvn.transform( new (C, 1) IfTrueNode (iff2) ) ); - set_control( _gvn.transform( new (C, 1) IfFalseNode(iff2) ) ); + r_not_subtype->init_req(1, _gvn.transform( new (C) IfTrueNode (iff2) ) ); + set_control( _gvn.transform( new (C) IfFalseNode(iff2) ) ); // Check for self. Very rare to get here, but it is taken 1/3 the time. // No performance impact (too rare) but allows sharing of secondary arrays // which has some footprint reduction. - Node *cmp3 = _gvn.transform( new (C, 3) CmpPNode( subklass, superklass ) ); - Node *bol3 = _gvn.transform( new (C, 2) BoolNode( cmp3, BoolTest::eq ) ); + Node *cmp3 = _gvn.transform( new (C) CmpPNode( subklass, superklass ) ); + Node *bol3 = _gvn.transform( new (C) BoolNode( cmp3, BoolTest::eq ) ); IfNode *iff3 = create_and_xform_if( control(), bol3, PROB_LIKELY(0.36f), COUNT_UNKNOWN ); - r_ok_subtype->init_req(2, _gvn.transform( new (C, 1) IfTrueNode ( iff3 ) ) ); - set_control( _gvn.transform( new (C, 1) IfFalseNode( iff3 ) ) ); + r_ok_subtype->init_req(2, _gvn.transform( new (C) IfTrueNode ( iff3 ) ) ); + set_control( _gvn.transform( new (C) IfFalseNode( iff3 ) ) ); // -- Roads not taken here: -- // We could also have chosen to perform the self-check at the beginning @@ -2412,13 +2411,13 @@ // The decision to inline or out-of-line this final check is platform // dependent, and is found in the AD file definition of PartialSubtypeCheck. Node* psc = _gvn.transform( - new (C, 3) PartialSubtypeCheckNode(control(), subklass, superklass) ); - - Node *cmp4 = _gvn.transform( new (C, 3) CmpPNode( psc, null() ) ); - Node *bol4 = _gvn.transform( new (C, 2) BoolNode( cmp4, BoolTest::ne ) ); + new (C) PartialSubtypeCheckNode(control(), subklass, superklass) ); + + Node *cmp4 = _gvn.transform( new (C) CmpPNode( psc, null() ) ); + Node *bol4 = _gvn.transform( new (C) BoolNode( cmp4, BoolTest::ne ) ); IfNode *iff4 = create_and_xform_if( control(), bol4, PROB_FAIR, COUNT_UNKNOWN ); - r_not_subtype->init_req(2, _gvn.transform( new (C, 1) IfTrueNode (iff4) ) ); - r_ok_subtype ->init_req(3, _gvn.transform( new (C, 1) IfFalseNode(iff4) ) ); + r_not_subtype->init_req(2, _gvn.transform( new (C) IfTrueNode (iff4) ) ); + r_ok_subtype ->init_req(3, _gvn.transform( new (C) IfFalseNode(iff4) ) ); // Return false path; set default control to true path. set_control( _gvn.transform(r_ok_subtype) ); @@ -2482,18 +2481,18 @@ const TypeKlassPtr* tklass = TypeKlassPtr::make(klass); Node* recv_klass = load_object_klass(receiver); Node* want_klass = makecon(tklass); - Node* cmp = _gvn.transform( new(C, 3) CmpPNode(recv_klass, want_klass) ); - Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) ); + Node* cmp = _gvn.transform( new(C) CmpPNode(recv_klass, want_klass) ); + Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) ); IfNode* iff = create_and_xform_if(control(), bol, prob, COUNT_UNKNOWN); - set_control( _gvn.transform( new(C, 1) IfTrueNode (iff) )); - Node* fail = _gvn.transform( new(C, 1) IfFalseNode(iff) ); + set_control( _gvn.transform( new(C) IfTrueNode (iff) )); + Node* fail = _gvn.transform( new(C) IfFalseNode(iff) ); const TypeOopPtr* recv_xtype = tklass->as_instance_type(); assert(recv_xtype->klass_is_exact(), ""); // Subsume downstream occurrences of receiver with a cast to // recv_xtype, since now we know what the type will be. - Node* cast = new(C, 2) CheckCastPPNode(control(), receiver, recv_xtype); + Node* cast = new(C) CheckCastPPNode(control(), receiver, recv_xtype); (*casted_receiver) = _gvn.transform(cast); // (User must make the replace_in_map call.) @@ -2580,8 +2579,8 @@ // Make the merge point enum { _obj_path = 1, _fail_path, _null_path, PATH_LIMIT }; - RegionNode* region = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); - Node* phi = new(C, PATH_LIMIT) PhiNode(region, TypeInt::BOOL); + RegionNode* region = new(C) RegionNode(PATH_LIMIT); + Node* phi = new(C) PhiNode(region, TypeInt::BOOL); C->set_has_split_ifs(true); // Has chance for split-if optimization ciProfileData* data = NULL; @@ -2683,8 +2682,8 @@ // Make the merge point enum { _obj_path = 1, _null_path, PATH_LIMIT }; - RegionNode* region = new (C, PATH_LIMIT) RegionNode(PATH_LIMIT); - Node* phi = new (C, PATH_LIMIT) PhiNode(region, toop); + RegionNode* region = new (C) RegionNode(PATH_LIMIT); + Node* phi = new (C) PhiNode(region, toop); C->set_has_split_ifs(true); // Has chance for split-if optimization // Use null-cast information if it is available @@ -2733,7 +2732,7 @@ Node* not_subtype_ctrl = gen_subtype_check( obj_klass, superklass ); // Plug in success path into the merge - cast_obj = _gvn.transform(new (C, 2) CheckCastPPNode(control(), + cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(), not_null_obj, toop)); // Failure path ends in uncommon trap (or may be dead - failure impossible) if (failure_control == NULL) { @@ -2787,7 +2786,7 @@ mb->init_req(TypeFunc::Control, control()); mb->init_req(TypeFunc::Memory, reset_memory()); Node* membar = _gvn.transform(mb); - set_control(_gvn.transform(new (C, 1) ProjNode(membar,TypeFunc::Control) )); + set_control(_gvn.transform(new (C) ProjNode(membar,TypeFunc::Control) )); set_all_memory_call(membar); return membar; } @@ -2816,11 +2815,11 @@ mb->set_req(TypeFunc::Memory, memory(alias_idx)); } Node* membar = _gvn.transform(mb); - set_control(_gvn.transform(new (C, 1) ProjNode(membar, TypeFunc::Control))); + set_control(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Control))); if (alias_idx == Compile::AliasIdxBot) { - merged_memory()->set_base_memory(_gvn.transform(new (C, 1) ProjNode(membar, TypeFunc::Memory))); + merged_memory()->set_base_memory(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Memory))); } else { - set_memory(_gvn.transform(new (C, 1) ProjNode(membar, TypeFunc::Memory)),alias_idx); + set_memory(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Memory)),alias_idx); } return membar; } @@ -2840,10 +2839,10 @@ assert(dead_locals_are_killed(), "should kill locals before sync. point"); // Box the stack location - Node* box = _gvn.transform(new (C, 1) BoxLockNode(next_monitor())); + Node* box = _gvn.transform(new (C) BoxLockNode(next_monitor())); Node* mem = reset_memory(); - FastLockNode * flock = _gvn.transform(new (C, 3) FastLockNode(0, obj, box) )->as_FastLock(); + FastLockNode * flock = _gvn.transform(new (C) FastLockNode(0, obj, box) )->as_FastLock(); if (PrintPreciseBiasedLockingStatistics) { // Create the counters for this fast lock. flock->create_lock_counter(sync_jvms()); // sync_jvms used to get current bci @@ -2853,7 +2852,7 @@ map()->push_monitor( flock ); const TypeFunc *tf = LockNode::lock_type(); - LockNode *lock = new (C, tf->domain()->cnt()) LockNode(C, tf); + LockNode *lock = new (C) LockNode(C, tf); lock->init_req( TypeFunc::Control, control() ); lock->init_req( TypeFunc::Memory , mem ); @@ -2907,7 +2906,7 @@ insert_mem_bar(Op_MemBarReleaseLock); const TypeFunc *tf = OptoRuntime::complete_monitor_exit_Type(); - UnlockNode *unlock = new (C, tf->domain()->cnt()) UnlockNode(C, tf); + UnlockNode *unlock = new (C) UnlockNode(C, tf); uint raw_idx = Compile::AliasIdxRaw; unlock->init_req( TypeFunc::Control, control() ); unlock->init_req( TypeFunc::Memory , memory(raw_idx) ); @@ -2973,19 +2972,19 @@ alloc->set_req( TypeFunc::FramePtr, frameptr() ); add_safepoint_edges(alloc); Node* allocx = _gvn.transform(alloc); - set_control( _gvn.transform(new (C, 1) ProjNode(allocx, TypeFunc::Control) ) ); + set_control( _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Control) ) ); // create memory projection for i_o - set_memory ( _gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx ); + set_memory ( _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx ); make_slow_call_ex(allocx, env()->OutOfMemoryError_klass(), true); // create a memory projection as for the normal control path - Node* malloc = _gvn.transform(new (C, 1) ProjNode(allocx, TypeFunc::Memory)); + Node* malloc = _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Memory)); set_memory(malloc, rawidx); // a normal slow-call doesn't change i_o, but an allocation does // we create a separate i_o projection for the normal control path - set_i_o(_gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::I_O, false) ) ); - Node* rawoop = _gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::Parms) ); + set_i_o(_gvn.transform( new (C) ProjNode(allocx, TypeFunc::I_O, false) ) ); + Node* rawoop = _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Parms) ); // put in an initialization barrier InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, rawidx, @@ -3021,7 +3020,7 @@ } // Cast raw oop to the real thing... - Node* javaoop = new (C, 2) CheckCastPPNode(control(), rawoop, oop_type); + Node* javaoop = new (C) CheckCastPPNode(control(), rawoop, oop_type); javaoop = _gvn.transform(javaoop); C->set_recent_alloc(control(), javaoop); assert(just_allocated_object(control()) == javaoop, "just allocated"); @@ -3080,9 +3079,9 @@ // (It may be stress-tested by specifying StressReflectiveCode.) // Basically, we want to get into the VM is there's an illegal argument. Node* bit = intcon(Klass::_lh_instance_slow_path_bit); - initial_slow_test = _gvn.transform( new (C, 3) AndINode(layout_val, bit) ); + initial_slow_test = _gvn.transform( new (C) AndINode(layout_val, bit) ); if (extra_slow_test != intcon(0)) { - initial_slow_test = _gvn.transform( new (C, 3) OrINode(initial_slow_test, extra_slow_test) ); + initial_slow_test = _gvn.transform( new (C) OrINode(initial_slow_test, extra_slow_test) ); } // (Macro-expander will further convert this to a Bool, if necessary.) } @@ -3099,7 +3098,7 @@ // Clear the low bits to extract layout_helper_size_in_bytes: assert((int)Klass::_lh_instance_slow_path_bit < BytesPerLong, "clear bit"); Node* mask = MakeConX(~ (intptr_t)right_n_bits(LogBytesPerLong)); - size = _gvn.transform( new (C, 3) AndXNode(size, mask) ); + size = _gvn.transform( new (C) AndXNode(size, mask) ); } if (return_size_val != NULL) { (*return_size_val) = size; @@ -3120,11 +3119,10 @@ set_all_memory(mem); // Create new memory state AllocateNode* alloc - = new (C, AllocateNode::ParmLimit) - AllocateNode(C, AllocateNode::alloc_type(), - control(), mem, i_o(), - size, klass_node, - initial_slow_test); + = new (C) AllocateNode(C, AllocateNode::alloc_type(), + control(), mem, i_o(), + size, klass_node, + initial_slow_test); return set_output_for_allocation(alloc, oop_type); } @@ -3147,8 +3145,8 @@ // Optimistically assume that it is a subtype of Object[], // so that we can fold up all the address arithmetic. layout_con = Klass::array_layout_helper(T_OBJECT); - Node* cmp_lh = _gvn.transform( new(C, 3) CmpINode(layout_val, intcon(layout_con)) ); - Node* bol_lh = _gvn.transform( new(C, 2) BoolNode(cmp_lh, BoolTest::eq) ); + Node* cmp_lh = _gvn.transform( new(C) CmpINode(layout_val, intcon(layout_con)) ); + Node* bol_lh = _gvn.transform( new(C) BoolNode(cmp_lh, BoolTest::eq) ); { BuildCutout unless(this, bol_lh, PROB_MAX); _sp += nargs; uncommon_trap(Deoptimization::Reason_class_check, @@ -3172,8 +3170,8 @@ fast_size_limit <<= (LogBytesPerLong - log2_esize); } - Node* initial_slow_cmp = _gvn.transform( new (C, 3) CmpUNode( length, intcon( fast_size_limit ) ) ); - Node* initial_slow_test = _gvn.transform( new (C, 2) BoolNode( initial_slow_cmp, BoolTest::gt ) ); + Node* initial_slow_cmp = _gvn.transform( new (C) CmpUNode( length, intcon( fast_size_limit ) ) ); + Node* initial_slow_test = _gvn.transform( new (C) BoolNode( initial_slow_cmp, BoolTest::gt ) ); if (initial_slow_test->is_Bool()) { // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick. initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn); @@ -3201,10 +3199,10 @@ } else { Node* hss = intcon(Klass::_lh_header_size_shift); Node* hsm = intcon(Klass::_lh_header_size_mask); - Node* hsize = _gvn.transform( new(C, 3) URShiftINode(layout_val, hss) ); - hsize = _gvn.transform( new(C, 3) AndINode(hsize, hsm) ); + Node* hsize = _gvn.transform( new(C) URShiftINode(layout_val, hss) ); + hsize = _gvn.transform( new(C) AndINode(hsize, hsm) ); Node* mask = intcon(round_mask); - header_size = _gvn.transform( new(C, 3) AddINode(hsize, mask) ); + header_size = _gvn.transform( new(C) AddINode(hsize, mask) ); } Node* elem_shift = NULL; @@ -3229,7 +3227,7 @@ jlong size_max = arrayOopDesc::max_array_length(T_BYTE); if (size_max > tllen->_hi) size_max = tllen->_hi; const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin); - lengthx = _gvn.transform( new (C, 2) ConvI2LNode(length, tlcon)); + lengthx = _gvn.transform( new (C) ConvI2LNode(length, tlcon)); } } #endif @@ -3240,11 +3238,11 @@ // after a successful allocation. Node* abody = lengthx; if (elem_shift != NULL) - abody = _gvn.transform( new(C, 3) LShiftXNode(lengthx, elem_shift) ); - Node* size = _gvn.transform( new(C, 3) AddXNode(headerx, abody) ); + abody = _gvn.transform( new(C) LShiftXNode(lengthx, elem_shift) ); + Node* size = _gvn.transform( new(C) AddXNode(headerx, abody) ); if (round_mask != 0) { Node* mask = MakeConX(~round_mask); - size = _gvn.transform( new(C, 3) AndXNode(size, mask) ); + size = _gvn.transform( new(C) AndXNode(size, mask) ); } // else if round_mask == 0, the size computation is self-rounding @@ -3262,12 +3260,11 @@ // Create the AllocateArrayNode and its result projections AllocateArrayNode* alloc - = new (C, AllocateArrayNode::ParmLimit) - AllocateArrayNode(C, AllocateArrayNode::alloc_type(), - control(), mem, i_o(), - size, klass_node, - initial_slow_test, - length); + = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(), + control(), mem, i_o(), + size, klass_node, + initial_slow_test, + length); // Cast to correct type. Note that the klass_node may be constant or not, // and in the latter case the actual array type will be inexact also. @@ -3386,10 +3383,10 @@ } Node *cont = _gvn.intcon(1); - Node* opq = _gvn.transform(new (C, 2) Opaque1Node(C, cont)); - Node *bol = _gvn.transform(new (C, 2) Conv2BNode(opq)); + Node* opq = _gvn.transform(new (C) Opaque1Node(C, cont)); + Node *bol = _gvn.transform(new (C) Conv2BNode(opq)); IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN); - Node* iffalse = _gvn.transform(new (C, 1) IfFalseNode(iff)); + Node* iffalse = _gvn.transform(new (C) IfFalseNode(iff)); C->add_predicate_opaq(opq); { PreserveJVMState pjvms(this); @@ -3397,7 +3394,7 @@ _sp += nargs; uncommon_trap(reason, Deoptimization::Action_maybe_recompile); } - Node* iftrue = _gvn.transform(new (C, 1) IfTrueNode(iff)); + Node* iftrue = _gvn.transform(new (C) IfTrueNode(iff)); set_control(iftrue); } @@ -3590,7 +3587,7 @@ #ifdef _LP64 // We could refine the type for what it's worth // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue); - next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); + next_indexX = _gvn.transform( new (C) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); #endif // Now get the buffer location we will log the previous value into and store it @@ -3638,7 +3635,7 @@ #ifdef _LP64 // We could refine the type for what it's worth // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue); - next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); + next_indexX = _gvn.transform( new (C) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); #endif // _LP64 Node* log_addr = __ AddP(no_base, buffer, next_indexX); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/graphKit.hpp --- a/src/share/vm/opto/graphKit.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/graphKit.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -303,31 +303,31 @@ // Some convenient shortcuts for common nodes - Node* IfTrue(IfNode* iff) { return _gvn.transform(new (C,1) IfTrueNode(iff)); } - Node* IfFalse(IfNode* iff) { return _gvn.transform(new (C,1) IfFalseNode(iff)); } + Node* IfTrue(IfNode* iff) { return _gvn.transform(new (C) IfTrueNode(iff)); } + Node* IfFalse(IfNode* iff) { return _gvn.transform(new (C) IfFalseNode(iff)); } - Node* AddI(Node* l, Node* r) { return _gvn.transform(new (C,3) AddINode(l, r)); } - Node* SubI(Node* l, Node* r) { return _gvn.transform(new (C,3) SubINode(l, r)); } - Node* MulI(Node* l, Node* r) { return _gvn.transform(new (C,3) MulINode(l, r)); } - Node* DivI(Node* ctl, Node* l, Node* r) { return _gvn.transform(new (C,3) DivINode(ctl, l, r)); } + Node* AddI(Node* l, Node* r) { return _gvn.transform(new (C) AddINode(l, r)); } + Node* SubI(Node* l, Node* r) { return _gvn.transform(new (C) SubINode(l, r)); } + Node* MulI(Node* l, Node* r) { return _gvn.transform(new (C) MulINode(l, r)); } + Node* DivI(Node* ctl, Node* l, Node* r) { return _gvn.transform(new (C) DivINode(ctl, l, r)); } - Node* AndI(Node* l, Node* r) { return _gvn.transform(new (C,3) AndINode(l, r)); } - Node* OrI(Node* l, Node* r) { return _gvn.transform(new (C,3) OrINode(l, r)); } - Node* XorI(Node* l, Node* r) { return _gvn.transform(new (C,3) XorINode(l, r)); } + Node* AndI(Node* l, Node* r) { return _gvn.transform(new (C) AndINode(l, r)); } + Node* OrI(Node* l, Node* r) { return _gvn.transform(new (C) OrINode(l, r)); } + Node* XorI(Node* l, Node* r) { return _gvn.transform(new (C) XorINode(l, r)); } - Node* MaxI(Node* l, Node* r) { return _gvn.transform(new (C,3) MaxINode(l, r)); } - Node* MinI(Node* l, Node* r) { return _gvn.transform(new (C,3) MinINode(l, r)); } + Node* MaxI(Node* l, Node* r) { return _gvn.transform(new (C) MaxINode(l, r)); } + Node* MinI(Node* l, Node* r) { return _gvn.transform(new (C) MinINode(l, r)); } - Node* LShiftI(Node* l, Node* r) { return _gvn.transform(new (C,3) LShiftINode(l, r)); } - Node* RShiftI(Node* l, Node* r) { return _gvn.transform(new (C,3) RShiftINode(l, r)); } - Node* URShiftI(Node* l, Node* r) { return _gvn.transform(new (C,3) URShiftINode(l, r)); } + Node* LShiftI(Node* l, Node* r) { return _gvn.transform(new (C) LShiftINode(l, r)); } + Node* RShiftI(Node* l, Node* r) { return _gvn.transform(new (C) RShiftINode(l, r)); } + Node* URShiftI(Node* l, Node* r) { return _gvn.transform(new (C) URShiftINode(l, r)); } - Node* CmpI(Node* l, Node* r) { return _gvn.transform(new (C,3) CmpINode(l, r)); } - Node* CmpL(Node* l, Node* r) { return _gvn.transform(new (C,3) CmpLNode(l, r)); } - Node* CmpP(Node* l, Node* r) { return _gvn.transform(new (C,3) CmpPNode(l, r)); } - Node* Bool(Node* cmp, BoolTest::mask relop) { return _gvn.transform(new (C,2) BoolNode(cmp, relop)); } + Node* CmpI(Node* l, Node* r) { return _gvn.transform(new (C) CmpINode(l, r)); } + Node* CmpL(Node* l, Node* r) { return _gvn.transform(new (C) CmpLNode(l, r)); } + Node* CmpP(Node* l, Node* r) { return _gvn.transform(new (C) CmpPNode(l, r)); } + Node* Bool(Node* cmp, BoolTest::mask relop) { return _gvn.transform(new (C) BoolNode(cmp, relop)); } - Node* AddP(Node* b, Node* a, Node* o) { return _gvn.transform(new (C,4) AddPNode(b, a, o)); } + Node* AddP(Node* b, Node* a, Node* o) { return _gvn.transform(new (C) AddPNode(b, a, o)); } // Convert between int and long, and size_t. // (See macros ConvI2X, etc., in type.hpp for ConvI2X, etc.) @@ -792,7 +792,7 @@ // Handy for making control flow IfNode* create_and_map_if(Node* ctrl, Node* tst, float prob, float cnt) { - IfNode* iff = new (C, 2) IfNode(ctrl, tst, prob, cnt);// New IfNode's + IfNode* iff = new (C) IfNode(ctrl, tst, prob, cnt);// New IfNode's _gvn.set_type(iff, iff->Value(&_gvn)); // Value may be known at parse-time // Place 'if' on worklist if it will be in graph if (!tst->is_Con()) record_for_igvn(iff); // Range-check and Null-check removal is later @@ -800,7 +800,7 @@ } IfNode* create_and_xform_if(Node* ctrl, Node* tst, float prob, float cnt) { - IfNode* iff = new (C, 2) IfNode(ctrl, tst, prob, cnt);// New IfNode's + IfNode* iff = new (C) IfNode(ctrl, tst, prob, cnt);// New IfNode's _gvn.transform(iff); // Value may be known at parse-time // Place 'if' on worklist if it will be in graph if (!tst->is_Con()) record_for_igvn(iff); // Range-check and Null-check removal is later diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/idealKit.cpp --- a/src/share/vm/opto/idealKit.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/idealKit.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -86,7 +86,7 @@ } // Delay gvn.tranform on if-nodes until construction is finished // to prevent a constant bool input from discarding a control output. - IfNode* iff = delay_transform(new (C, 2) IfNode(ctrl(), bol, prob, cnt))->as_If(); + IfNode* iff = delay_transform(new (C) IfNode(ctrl(), bol, prob, cnt))->as_If(); Node* then = IfTrue(iff); Node* elsen = IfFalse(iff); Node* else_cvstate = copy_cvstate(); @@ -205,7 +205,7 @@ assert(_cvstate != NULL, "must declare variables before labels"); Node* lab = new_cvstate(); int sz = 1 + goto_ct + 1 /* fall thru */; - Node* reg = delay_transform(new (C, sz) RegionNode(sz)); + Node* reg = delay_transform(new (C) RegionNode(sz)); lab->init_req(TypeFunc::Control, reg); return lab; } @@ -315,7 +315,7 @@ //-----------------------------new_cvstate----------------------------------- Node* IdealKit::new_cvstate() { uint sz = _var_ct + first_var; - return new (C, sz) Node(sz); + return new (C) Node(sz); } //-----------------------------copy_cvstate----------------------------------- @@ -413,7 +413,7 @@ // Add required edge to oop_store, optimizer does not support precedence edges. // Convert required edge to precedence edge before allocation. - Node* st = new (C, 5) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store, oop_adr_idx); + Node* st = new (C) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store, oop_adr_idx); st = transform(st); set_memory(st, adr_idx); @@ -513,8 +513,7 @@ uint adr_idx = C->get_alias_index(adr_type); // Slow-path leaf call - int size = slow_call_type->domain()->cnt(); - CallNode *call = (CallNode*)new (C, size) CallLeafNode( slow_call_type, slow_call, leaf_name, adr_type); + CallNode *call = (CallNode*)new (C) CallLeafNode( slow_call_type, slow_call, leaf_name, adr_type); // Set fixed predefined input arguments call->init_req( TypeFunc::Control, ctrl() ); @@ -535,10 +534,10 @@ // Slow leaf call has no side-effects, sets few values - set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) )); + set_ctrl(transform( new (C) ProjNode(call,TypeFunc::Control) )); // Make memory for the call - Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) ); + Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) ); // Set the RawPtr memory state only. set_memory(mem, adr_idx); @@ -561,8 +560,7 @@ uint adr_idx = C->get_alias_index(adr_type); // Slow-path leaf call - int size = slow_call_type->domain()->cnt(); - CallNode *call = (CallNode*)new (C, size) CallLeafNoFPNode( slow_call_type, slow_call, leaf_name, adr_type); + CallNode *call = (CallNode*)new (C) CallLeafNoFPNode( slow_call_type, slow_call, leaf_name, adr_type); // Set fixed predefined input arguments call->init_req( TypeFunc::Control, ctrl() ); @@ -583,10 +581,10 @@ // Slow leaf call has no side-effects, sets few values - set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) )); + set_ctrl(transform( new (C) ProjNode(call,TypeFunc::Control) )); // Make memory for the call - Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) ); + Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) ); // Set the RawPtr memory state only. set_memory(mem, adr_idx); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/idealKit.hpp --- a/src/share/vm/opto/idealKit.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/idealKit.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -175,39 +175,39 @@ void declarations_done(); void drain_delay_transform(); - Node* IfTrue(IfNode* iff) { return transform(new (C,1) IfTrueNode(iff)); } - Node* IfFalse(IfNode* iff) { return transform(new (C,1) IfFalseNode(iff)); } + Node* IfTrue(IfNode* iff) { return transform(new (C) IfTrueNode(iff)); } + Node* IfFalse(IfNode* iff) { return transform(new (C) IfFalseNode(iff)); } // Data Node* ConI(jint k) { return (Node*)gvn().intcon(k); } Node* makecon(const Type *t) const { return _gvn.makecon(t); } - Node* AddI(Node* l, Node* r) { return transform(new (C,3) AddINode(l, r)); } - Node* SubI(Node* l, Node* r) { return transform(new (C,3) SubINode(l, r)); } - Node* AndI(Node* l, Node* r) { return transform(new (C,3) AndINode(l, r)); } - Node* MaxI(Node* l, Node* r) { return transform(new (C,3) MaxINode(l, r)); } - Node* LShiftI(Node* l, Node* r) { return transform(new (C,3) LShiftINode(l, r)); } - Node* CmpI(Node* l, Node* r) { return transform(new (C,3) CmpINode(l, r)); } - Node* Bool(Node* cmp, BoolTest::mask relop) { return transform(new (C,2) BoolNode(cmp, relop)); } + Node* AddI(Node* l, Node* r) { return transform(new (C) AddINode(l, r)); } + Node* SubI(Node* l, Node* r) { return transform(new (C) SubINode(l, r)); } + Node* AndI(Node* l, Node* r) { return transform(new (C) AndINode(l, r)); } + Node* MaxI(Node* l, Node* r) { return transform(new (C) MaxINode(l, r)); } + Node* LShiftI(Node* l, Node* r) { return transform(new (C) LShiftINode(l, r)); } + Node* CmpI(Node* l, Node* r) { return transform(new (C) CmpINode(l, r)); } + Node* Bool(Node* cmp, BoolTest::mask relop) { return transform(new (C) BoolNode(cmp, relop)); } void increment(IdealVariable& v, Node* j) { set(v, AddI(value(v), j)); } void decrement(IdealVariable& v, Node* j) { set(v, SubI(value(v), j)); } - Node* CmpL(Node* l, Node* r) { return transform(new (C,3) CmpLNode(l, r)); } + Node* CmpL(Node* l, Node* r) { return transform(new (C) CmpLNode(l, r)); } // TLS - Node* thread() { return gvn().transform(new (C, 1) ThreadLocalNode()); } + Node* thread() { return gvn().transform(new (C) ThreadLocalNode()); } // Pointers - Node* AddP(Node *base, Node *ptr, Node *off) { return transform(new (C,4) AddPNode(base, ptr, off)); } - Node* CmpP(Node* l, Node* r) { return transform(new (C,3) CmpPNode(l, r)); } + Node* AddP(Node *base, Node *ptr, Node *off) { return transform(new (C) AddPNode(base, ptr, off)); } + Node* CmpP(Node* l, Node* r) { return transform(new (C) CmpPNode(l, r)); } #ifdef _LP64 - Node* XorX(Node* l, Node* r) { return transform(new (C,3) XorLNode(l, r)); } + Node* XorX(Node* l, Node* r) { return transform(new (C) XorLNode(l, r)); } #else // _LP64 - Node* XorX(Node* l, Node* r) { return transform(new (C,3) XorINode(l, r)); } + Node* XorX(Node* l, Node* r) { return transform(new (C) XorINode(l, r)); } #endif // _LP64 - Node* URShiftX(Node* l, Node* r) { return transform(new (C,3) URShiftXNode(l, r)); } + Node* URShiftX(Node* l, Node* r) { return transform(new (C) URShiftXNode(l, r)); } Node* ConX(jint k) { return (Node*)gvn().MakeConX(k); } - Node* CastPX(Node* ctl, Node* p) { return transform(new (C,2) CastP2XNode(ctl, p)); } + Node* CastPX(Node* ctl, Node* p) { return transform(new (C) CastP2XNode(ctl, p)); } // Add a fixed offset to a pointer Node* basic_plus_adr(Node* base, Node* ptr, intptr_t offset); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/ifnode.cpp --- a/src/share/vm/opto/ifnode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/ifnode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -238,10 +238,10 @@ Node* predicate_x = NULL; bool counted_loop = r->is_CountedLoop(); - Node *region_c = new (igvn->C, req_c + 1) RegionNode(req_c + 1); + Node *region_c = new (igvn->C) RegionNode(req_c + 1); Node *phi_c = con1; uint len = r->req(); - Node *region_x = new (igvn->C, len - req_c) RegionNode(len - req_c); + Node *region_x = new (igvn->C) RegionNode(len - req_c); Node *phi_x = PhiNode::make_blank(region_x, phi); for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) { if (phi->in(i) == con1) { @@ -272,7 +272,7 @@ // Prevent the untimely death of phi_x. Currently he has no uses. He is // about to get one. If this only use goes away, then phi_x will look dead. // However, he will be picking up some more uses down below. - Node *hook = new (igvn->C, 4) Node(4); + Node *hook = new (igvn->C) Node(4); hook->init_req(0, phi_x); hook->init_req(1, phi_c); phi_x = phase->transform( phi_x ); @@ -284,30 +284,30 @@ cmp_x->set_req(2,con2); cmp_x = phase->transform(cmp_x); // Make the bool - Node *b_c = phase->transform(new (igvn->C, 2) BoolNode(cmp_c,b->_test._test)); - Node *b_x = phase->transform(new (igvn->C, 2) BoolNode(cmp_x,b->_test._test)); + Node *b_c = phase->transform(new (igvn->C) BoolNode(cmp_c,b->_test._test)); + Node *b_x = phase->transform(new (igvn->C) BoolNode(cmp_x,b->_test._test)); // Make the IfNode - IfNode *iff_c = new (igvn->C, 2) IfNode(region_c,b_c,iff->_prob,iff->_fcnt); + IfNode *iff_c = new (igvn->C) IfNode(region_c,b_c,iff->_prob,iff->_fcnt); igvn->set_type_bottom(iff_c); igvn->_worklist.push(iff_c); hook->init_req(2, iff_c); - IfNode *iff_x = new (igvn->C, 2) IfNode(region_x,b_x,iff->_prob, iff->_fcnt); + IfNode *iff_x = new (igvn->C) IfNode(region_x,b_x,iff->_prob, iff->_fcnt); igvn->set_type_bottom(iff_x); igvn->_worklist.push(iff_x); hook->init_req(3, iff_x); // Make the true/false arms - Node *iff_c_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_c)); - Node *iff_c_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_c)); + Node *iff_c_t = phase->transform(new (igvn->C) IfTrueNode (iff_c)); + Node *iff_c_f = phase->transform(new (igvn->C) IfFalseNode(iff_c)); if (predicate_c != NULL) { assert(predicate_x == NULL, "only one predicate entry expected"); // Clone loop predicates to each path iff_c_t = igvn->clone_loop_predicates(predicate_c, iff_c_t, !counted_loop); iff_c_f = igvn->clone_loop_predicates(predicate_c, iff_c_f, !counted_loop); } - Node *iff_x_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_x)); - Node *iff_x_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_x)); + Node *iff_x_t = phase->transform(new (igvn->C) IfTrueNode (iff_x)); + Node *iff_x_f = phase->transform(new (igvn->C) IfFalseNode(iff_x)); if (predicate_x != NULL) { assert(predicate_c == NULL, "only one predicate entry expected"); // Clone loop predicates to each path @@ -316,14 +316,14 @@ } // Merge the TRUE paths - Node *region_s = new (igvn->C, 3) RegionNode(3); + Node *region_s = new (igvn->C) RegionNode(3); igvn->_worklist.push(region_s); region_s->init_req(1, iff_c_t); region_s->init_req(2, iff_x_t); igvn->register_new_node_with_optimizer( region_s ); // Merge the FALSE paths - Node *region_f = new (igvn->C, 3) RegionNode(3); + Node *region_f = new (igvn->C) RegionNode(3); igvn->_worklist.push(region_f); region_f->init_req(1, iff_c_f); region_f->init_req(2, iff_x_f); @@ -438,7 +438,7 @@ // Must return either the original node (now dead) or a new node // (Do not return a top here, since that would break the uniqueness of top.) - return new (igvn->C, 1) ConINode(TypeInt::ZERO); + return new (igvn->C) ConINode(TypeInt::ZERO); } //------------------------------is_range_check--------------------------------- @@ -541,16 +541,16 @@ // Compute a new check Node *new_add = gvn->intcon(off_lo); if( index ) { - new_add = off_lo ? gvn->transform(new (gvn->C, 3) AddINode( index, new_add )) : index; + new_add = off_lo ? gvn->transform(new (gvn->C) AddINode( index, new_add )) : index; } Node *new_cmp = (flip == 1) - ? new (gvn->C, 3) CmpUNode( new_add, range ) - : new (gvn->C, 3) CmpUNode( range, new_add ); + ? new (gvn->C) CmpUNode( new_add, range ) + : new (gvn->C) CmpUNode( range, new_add ); new_cmp = gvn->transform(new_cmp); // See if no need to adjust the existing check if( new_cmp == cmp ) return; // Else, adjust existing check - Node *new_bol = gvn->transform( new (gvn->C, 2) BoolNode( new_cmp, bol->as_Bool()->_test._test ) ); + Node *new_bol = gvn->transform( new (gvn->C) BoolNode( new_cmp, bol->as_Bool()->_test._test ) ); igvn->rehash_node_delayed( iff ); iff->set_req_X( 1, new_bol, igvn ); } @@ -727,9 +727,9 @@ if (failtype->_hi != max_jint && failtype->_lo != min_jint && bound > 1) { // Merge the two compares into a single unsigned compare by building (CmpU (n - lo) hi) BoolTest::mask cond = fail->as_Proj()->_con ? BoolTest::lt : BoolTest::ge; - Node* adjusted = phase->transform(new (phase->C, 3) SubINode(n, phase->intcon(failtype->_lo))); - Node* newcmp = phase->transform(new (phase->C, 3) CmpUNode(adjusted, phase->intcon(bound))); - Node* newbool = phase->transform(new (phase->C, 2) BoolNode(newcmp, cond)); + Node* adjusted = phase->transform(new (phase->C) SubINode(n, phase->intcon(failtype->_lo))); + Node* newcmp = phase->transform(new (phase->C) CmpUNode(adjusted, phase->intcon(bound))); + Node* newbool = phase->transform(new (phase->C) BoolNode(newcmp, cond)); phase->is_IterGVN()->replace_input_of(dom_iff, 1, phase->intcon(ctrl->as_Proj()->_con)); phase->hash_delete(this); set_req(1, newbool); @@ -1002,7 +1002,7 @@ // Must return either the original node (now dead) or a new node // (Do not return a top here, since that would break the uniqueness of top.) - return new (phase->C, 1) ConINode(TypeInt::ZERO); + return new (phase->C) ConINode(TypeInt::ZERO); } //------------------------------dominated_by----------------------------------- @@ -1098,7 +1098,7 @@ // Flip test to be canonical. Requires flipping the IfFalse/IfTrue and // cloning the IfNode. - Node* new_b = phase->transform( new (phase->C, 2) BoolNode(b->in(1), bt.negate()) ); + Node* new_b = phase->transform( new (phase->C) BoolNode(b->in(1), bt.negate()) ); if( !new_b->is_Bool() ) return NULL; b = new_b->as_Bool(); @@ -1106,7 +1106,7 @@ assert( igvn, "Test is not canonical in parser?" ); // The IF node never really changes, but it needs to be cloned - iff = new (phase->C, 2) IfNode( iff->in(0), b, 1.0-iff->_prob, iff->_fcnt); + iff = new (phase->C) IfNode( iff->in(0), b, 1.0-iff->_prob, iff->_fcnt); Node *prior = igvn->hash_find_insert(iff); if( prior ) { @@ -1119,8 +1119,8 @@ igvn->_worklist.push(iff); // Now handle projections. Cloning not required. - Node* new_if_f = (Node*)(new (phase->C, 1) IfFalseNode( iff )); - Node* new_if_t = (Node*)(new (phase->C, 1) IfTrueNode ( iff )); + Node* new_if_f = (Node*)(new (phase->C) IfFalseNode( iff )); + Node* new_if_t = (Node*)(new (phase->C) IfTrueNode ( iff )); igvn->register_new_node_with_optimizer(new_if_f); igvn->register_new_node_with_optimizer(new_if_t); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/lcm.cpp --- a/src/share/vm/opto/lcm.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/lcm.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -369,7 +369,7 @@ Node *tmp2 = _nodes[end_idx()+2]; _nodes.map(end_idx()+1, tmp2); _nodes.map(end_idx()+2, tmp1); - Node *tmp = new (C, 1) Node(C->top()); // Use not NULL input + Node *tmp = new (C) Node(C->top()); // Use not NULL input tmp1->replace_by(tmp); tmp2->replace_by(tmp1); tmp->replace_by(tmp2); @@ -612,7 +612,7 @@ // Set all registers killed and not already defined by the call. uint r_cnt = mcall->tf()->range()->cnt(); int op = mcall->ideal_Opcode(); - MachProjNode *proj = new (matcher.C, 1) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj ); + MachProjNode *proj = new (matcher.C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj ); bbs.map(proj->_idx,this); _nodes.insert(node_cnt++, proj); @@ -839,7 +839,7 @@ regs.Insert(matcher.c_frame_pointer()); regs.OR(n->out_RegMask()); - MachProjNode *proj = new (matcher.C, 1) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); + MachProjNode *proj = new (matcher.C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); cfg->_bbs.map(proj->_idx,this); _nodes.insert(phi_cnt++, proj); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/library_call.cpp --- a/src/share/vm/opto/library_call.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/library_call.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -65,6 +65,8 @@ private: LibraryIntrinsic* _intrinsic; // the library intrinsic being called + const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr = false); + public: LibraryCallKit(JVMState* caller, LibraryIntrinsic* intrinsic) : GraphKit(caller), @@ -241,7 +243,8 @@ Node* src, Node* src_offset, Node* dest, Node* dest_offset, Node* copy_length, bool dest_uninitialized); - bool inline_unsafe_CAS(BasicType type); + typedef enum { LS_xadd, LS_xchg, LS_cmpxchg } LoadStoreKind; + bool inline_unsafe_load_store(BasicType type, LoadStoreKind kind); bool inline_unsafe_ordered_store(BasicType type); bool inline_fp_conversions(vmIntrinsics::ID id); bool inline_numberOfLeadingZeros(vmIntrinsics::ID id); @@ -290,6 +293,11 @@ case vmIntrinsics::_compareTo: case vmIntrinsics::_equals: case vmIntrinsics::_equalsC: + case vmIntrinsics::_getAndAddInt: + case vmIntrinsics::_getAndAddLong: + case vmIntrinsics::_getAndSetInt: + case vmIntrinsics::_getAndSetLong: + case vmIntrinsics::_getAndSetObject: break; // InlineNatives does not control String.compareTo case vmIntrinsics::_Reference_get: break; // InlineNatives does not control Reference.get @@ -369,6 +377,42 @@ // across safepoint since GC can change it value. break; + case vmIntrinsics::_compareAndSwapObject: +#ifdef _LP64 + if (!UseCompressedOops && !Matcher::match_rule_supported(Op_CompareAndSwapP)) return NULL; +#endif + break; + + case vmIntrinsics::_compareAndSwapLong: + if (!Matcher::match_rule_supported(Op_CompareAndSwapL)) return NULL; + break; + + case vmIntrinsics::_getAndAddInt: + if (!Matcher::match_rule_supported(Op_GetAndAddI)) return NULL; + break; + + case vmIntrinsics::_getAndAddLong: + if (!Matcher::match_rule_supported(Op_GetAndAddL)) return NULL; + break; + + case vmIntrinsics::_getAndSetInt: + if (!Matcher::match_rule_supported(Op_GetAndSetI)) return NULL; + break; + + case vmIntrinsics::_getAndSetLong: + if (!Matcher::match_rule_supported(Op_GetAndSetL)) return NULL; + break; + + case vmIntrinsics::_getAndSetObject: +#ifdef _LP64 + if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; + if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL; + break; +#else + if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; + break; +#endif + default: assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility"); assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); @@ -620,11 +664,11 @@ return inline_unsafe_prefetch(!is_native_ptr, is_store, is_static); case vmIntrinsics::_compareAndSwapObject: - return inline_unsafe_CAS(T_OBJECT); + return inline_unsafe_load_store(T_OBJECT, LS_cmpxchg); case vmIntrinsics::_compareAndSwapInt: - return inline_unsafe_CAS(T_INT); + return inline_unsafe_load_store(T_INT, LS_cmpxchg); case vmIntrinsics::_compareAndSwapLong: - return inline_unsafe_CAS(T_LONG); + return inline_unsafe_load_store(T_LONG, LS_cmpxchg); case vmIntrinsics::_putOrderedObject: return inline_unsafe_ordered_store(T_OBJECT); @@ -633,6 +677,17 @@ case vmIntrinsics::_putOrderedLong: return inline_unsafe_ordered_store(T_LONG); + case vmIntrinsics::_getAndAddInt: + return inline_unsafe_load_store(T_INT, LS_xadd); + case vmIntrinsics::_getAndAddLong: + return inline_unsafe_load_store(T_LONG, LS_xadd); + case vmIntrinsics::_getAndSetInt: + return inline_unsafe_load_store(T_INT, LS_xchg); + case vmIntrinsics::_getAndSetLong: + return inline_unsafe_load_store(T_LONG, LS_xchg); + case vmIntrinsics::_getAndSetObject: + return inline_unsafe_load_store(T_OBJECT, LS_xchg); + case vmIntrinsics::_currentThread: return inline_native_currentThread(); case vmIntrinsics::_isInterrupted: @@ -759,7 +814,7 @@ IfNode* iff = create_and_map_if(control(), test, true_prob, COUNT_UNKNOWN); - Node* if_slow = _gvn.transform( new (C, 1) IfTrueNode(iff) ); + Node* if_slow = _gvn.transform( new (C) IfTrueNode(iff) ); if (if_slow == top()) { // The slow branch is never taken. No need to build this guard. return NULL; @@ -768,7 +823,7 @@ if (region != NULL) region->add_req(if_slow); - Node* if_fast = _gvn.transform( new (C, 1) IfFalseNode(iff) ); + Node* if_fast = _gvn.transform( new (C) IfFalseNode(iff) ); set_control(if_fast); return if_slow; @@ -787,12 +842,12 @@ return NULL; // already stopped if (_gvn.type(index)->higher_equal(TypeInt::POS)) // [0,maxint] return NULL; // index is already adequately typed - Node* cmp_lt = _gvn.transform( new (C, 3) CmpINode(index, intcon(0)) ); - Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) ); + Node* cmp_lt = _gvn.transform( new (C) CmpINode(index, intcon(0)) ); + Node* bol_lt = _gvn.transform( new (C) BoolNode(cmp_lt, BoolTest::lt) ); Node* is_neg = generate_guard(bol_lt, region, PROB_MIN); if (is_neg != NULL && pos_index != NULL) { // Emulate effect of Parse::adjust_map_after_if. - Node* ccast = new (C, 2) CastIINode(index, TypeInt::POS); + Node* ccast = new (C) CastIINode(index, TypeInt::POS); ccast->set_req(0, control()); (*pos_index) = _gvn.transform(ccast); } @@ -805,13 +860,13 @@ return NULL; // already stopped if (_gvn.type(index)->higher_equal(TypeInt::POS1)) // [1,maxint] return NULL; // index is already adequately typed - Node* cmp_le = _gvn.transform( new (C, 3) CmpINode(index, intcon(0)) ); + Node* cmp_le = _gvn.transform( new (C) CmpINode(index, intcon(0)) ); BoolTest::mask le_or_eq = (never_negative ? BoolTest::eq : BoolTest::le); - Node* bol_le = _gvn.transform( new (C, 2) BoolNode(cmp_le, le_or_eq) ); + Node* bol_le = _gvn.transform( new (C) BoolNode(cmp_le, le_or_eq) ); Node* is_notp = generate_guard(bol_le, NULL, PROB_MIN); if (is_notp != NULL && pos_index != NULL) { // Emulate effect of Parse::adjust_map_after_if. - Node* ccast = new (C, 2) CastIINode(index, TypeInt::POS1); + Node* ccast = new (C) CastIINode(index, TypeInt::POS1); ccast->set_req(0, control()); (*pos_index) = _gvn.transform(ccast); } @@ -843,9 +898,9 @@ return NULL; // common case of whole-array copy Node* last = subseq_length; if (!zero_offset) // last += offset - last = _gvn.transform( new (C, 3) AddINode(last, offset)); - Node* cmp_lt = _gvn.transform( new (C, 3) CmpUNode(array_length, last) ); - Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) ); + last = _gvn.transform( new (C) AddINode(last, offset)); + Node* cmp_lt = _gvn.transform( new (C) CmpUNode(array_length, last) ); + Node* bol_lt = _gvn.transform( new (C) BoolNode(cmp_lt, BoolTest::lt) ); Node* is_over = generate_guard(bol_lt, region, PROB_MIN); return is_over; } @@ -855,7 +910,7 @@ Node* LibraryCallKit::generate_current_thread(Node* &tls_output) { ciKlass* thread_klass = env()->Thread_klass(); const Type* thread_type = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull); - Node* thread = _gvn.transform(new (C, 1) ThreadLocalNode()); + Node* thread = _gvn.transform(new (C) ThreadLocalNode()); Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset())); Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT); tls_output = thread; @@ -890,18 +945,18 @@ // Get length of string 2 str2_len = load_String_length(no_ctrl, str2); - result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), + result = new (C) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), str1_start, str1_len, str2_start, str2_len); break; case Op_StrComp: // Get length of string 2 str2_len = load_String_length(no_ctrl, str2); - result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS), + result = new (C) StrCompNode(control(), memory(TypeAryPtr::CHARS), str1_start, str1_len, str2_start, str2_len); break; case Op_StrEquals: - result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), + result = new (C) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), str1_start, str2_start, str1_len); break; default: @@ -924,15 +979,15 @@ Node* result = NULL; switch (opcode) { case Op_StrIndexOf: - result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), + result = new (C) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), str1_start, cnt1, str2_start, cnt2); break; case Op_StrComp: - result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS), + result = new (C) StrCompNode(control(), memory(TypeAryPtr::CHARS), str1_start, cnt1, str2_start, cnt2); break; case Op_StrEquals: - result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), + result = new (C) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), str1_start, str2_start, cnt1); break; default: @@ -997,12 +1052,12 @@ } // paths (plus control) merge - RegionNode* region = new (C, 5) RegionNode(5); - Node* phi = new (C, 5) PhiNode(region, TypeInt::BOOL); + RegionNode* region = new (C) RegionNode(5); + Node* phi = new (C) PhiNode(region, TypeInt::BOOL); // does source == target string? - Node* cmp = _gvn.transform(new (C, 3) CmpPNode(receiver, argument)); - Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq)); + Node* cmp = _gvn.transform(new (C) CmpPNode(receiver, argument)); + Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::eq)); Node* if_eq = generate_slow_guard(bol, NULL); if (if_eq != NULL) { @@ -1018,8 +1073,8 @@ _sp += nargs; // gen_instanceof might do an uncommon trap Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass))); _sp -= nargs; - Node* cmp = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1))); - Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::ne)); + Node* cmp = _gvn.transform(new (C) CmpINode(inst, intcon(1))); + Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::ne)); Node* inst_false = generate_guard(bol, NULL, PROB_MIN); //instanceOf == true, fallthrough @@ -1034,7 +1089,7 @@ const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); // Properly cast the argument to String - argument = _gvn.transform(new (C, 2) CheckCastPPNode(control(), argument, string_type)); + argument = _gvn.transform(new (C) CheckCastPPNode(control(), argument, string_type)); // This path is taken only when argument's type is String:NotNull. argument = cast_not_null(argument, false); @@ -1057,8 +1112,8 @@ Node* argument_cnt = load_String_length(no_ctrl, argument); // Check for receiver count != argument count - Node* cmp = _gvn.transform( new(C, 3) CmpINode(receiver_cnt, argument_cnt) ); - Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::ne) ); + Node* cmp = _gvn.transform( new(C) CmpINode(receiver_cnt, argument_cnt) ); + Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::ne) ); Node* if_ne = generate_slow_guard(bol, NULL); if (if_ne != NULL) { phi->init_req(4, intcon(0)); @@ -1093,7 +1148,7 @@ Node *argument1 = pop(); Node* equals = - _gvn.transform(new (C, 4) AryEqNode(control(), memory(TypeAryPtr::CHARS), + _gvn.transform(new (C) AryEqNode(control(), memory(TypeAryPtr::CHARS), argument1, argument2) ); push(equals); return true; @@ -1268,8 +1323,8 @@ const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(str_klass); // Make the merge point - RegionNode* result_rgn = new (C, 4) RegionNode(4); - Node* result_phi = new (C, 4) PhiNode(result_rgn, TypeInt::INT); + RegionNode* result_rgn = new (C) RegionNode(4); + Node* result_phi = new (C) PhiNode(result_rgn, TypeInt::INT); Node* no_ctrl = NULL; // Get start addr of source string @@ -1289,8 +1344,8 @@ Node* substr_cnt = load_String_length(no_ctrl, argument); // Check for substr count > string count - Node* cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, source_cnt) ); - Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::gt) ); + Node* cmp = _gvn.transform( new(C) CmpINode(substr_cnt, source_cnt) ); + Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::gt) ); Node* if_gt = generate_slow_guard(bol, NULL); if (if_gt != NULL) { result_phi->init_req(2, intcon(-1)); @@ -1299,8 +1354,8 @@ if (!stopped()) { // Check for substr count == 0 - cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, intcon(0)) ); - bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) ); + cmp = _gvn.transform( new(C) CmpINode(substr_cnt, intcon(0)) ); + bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) ); Node* if_zero = generate_slow_guard(bol, NULL); if (if_zero != NULL) { result_phi->init_req(3, intcon(0)); @@ -1401,7 +1456,7 @@ Node * LibraryCallKit::pop_math_arg() { Node *arg = pop_pair(); if( Matcher::strict_fp_requires_explicit_rounding && UseSSE<=1 ) - arg = _gvn.transform( new (C, 2) RoundDoubleNode(0, arg) ); + arg = _gvn.transform( new (C) RoundDoubleNode(0, arg) ); return arg; } @@ -1415,13 +1470,13 @@ switch (id) { case vmIntrinsics::_dsin: - trig = _gvn.transform((Node*)new (C, 2) SinDNode(arg)); + trig = _gvn.transform((Node*)new (C) SinDNode(arg)); break; case vmIntrinsics::_dcos: - trig = _gvn.transform((Node*)new (C, 2) CosDNode(arg)); + trig = _gvn.transform((Node*)new (C) CosDNode(arg)); break; case vmIntrinsics::_dtan: - trig = _gvn.transform((Node*)new (C, 2) TanDNode(arg)); + trig = _gvn.transform((Node*)new (C) TanDNode(arg)); break; default: assert(false, "bad intrinsic was passed in"); @@ -1465,17 +1520,17 @@ // probably do the math inside the SIN encoding. // Make the merge point - RegionNode *r = new (C, 3) RegionNode(3); - Node *phi = new (C, 3) PhiNode(r,Type::DOUBLE); + RegionNode *r = new (C) RegionNode(3); + Node *phi = new (C) PhiNode(r,Type::DOUBLE); // Flatten arg so we need only 1 test - Node *abs = _gvn.transform(new (C, 2) AbsDNode(arg)); + Node *abs = _gvn.transform(new (C) AbsDNode(arg)); // Node for PI/4 constant Node *pi4 = makecon(TypeD::make(pi_4)); // Check PI/4 : abs(arg) - Node *cmp = _gvn.transform(new (C, 3) CmpDNode(pi4,abs)); + Node *cmp = _gvn.transform(new (C) CmpDNode(pi4,abs)); // Check: If PI/4 < abs(arg) then go slow - Node *bol = _gvn.transform( new (C, 2) BoolNode( cmp, BoolTest::lt ) ); + Node *bol = _gvn.transform( new (C) BoolNode( cmp, BoolTest::lt ) ); // Branch either way IfNode *iff = create_and_xform_if(control(),bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); set_control(opt_iff(r,iff)); @@ -1503,7 +1558,7 @@ break; } assert(control()->in(0) == call, ""); - Node* slow_result = _gvn.transform(new (C, 1) ProjNode(call,TypeFunc::Parms)); + Node* slow_result = _gvn.transform(new (C) ProjNode(call,TypeFunc::Parms)); r->init_req(1,control()); phi->init_req(1,slow_result); @@ -1524,7 +1579,7 @@ bool LibraryCallKit::inline_sqrt(vmIntrinsics::ID id) { assert(id == vmIntrinsics::_dsqrt, "Not square root"); _sp += arg_size(); // restore stack pointer - push_pair(_gvn.transform(new (C, 2) SqrtDNode(0, pop_math_arg()))); + push_pair(_gvn.transform(new (C) SqrtDNode(0, pop_math_arg()))); return true; } @@ -1533,7 +1588,7 @@ bool LibraryCallKit::inline_abs(vmIntrinsics::ID id) { assert(id == vmIntrinsics::_dabs, "Not absolute value"); _sp += arg_size(); // restore stack pointer - push_pair(_gvn.transform(new (C, 2) AbsDNode(pop_math_arg()))); + push_pair(_gvn.transform(new (C) AbsDNode(pop_math_arg()))); return true; } @@ -1542,9 +1597,9 @@ //result=(result.isNaN())? funcAddr():result; // Check: If isNaN() by checking result!=result? then either trap // or go to runtime - Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result)); + Node* cmpisnan = _gvn.transform(new (C) CmpDNode(result,result)); // Build the boolean node - Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) ); + Node* bolisnum = _gvn.transform( new (C) BoolNode(cmpisnan, BoolTest::eq) ); if (!too_many_traps(Deoptimization::Reason_intrinsic)) { { @@ -1565,12 +1620,12 @@ // to the runtime to properly handle corner cases IfNode* iff = create_and_xform_if(control(), bolisnum, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); - Node* if_slow = _gvn.transform( new (C, 1) IfFalseNode(iff) ); - Node* if_fast = _gvn.transform( new (C, 1) IfTrueNode(iff) ); + Node* if_slow = _gvn.transform( new (C) IfFalseNode(iff) ); + Node* if_fast = _gvn.transform( new (C) IfTrueNode(iff) ); if (!if_slow->is_top()) { - RegionNode* result_region = new(C, 3) RegionNode(3); - PhiNode* result_val = new (C, 3) PhiNode(result_region, Type::DOUBLE); + RegionNode* result_region = new(C) RegionNode(3); + PhiNode* result_val = new (C) PhiNode(result_region, Type::DOUBLE); result_region->init_req(1, if_fast); result_val->init_req(1, result); @@ -1581,9 +1636,9 @@ Node* rt = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName, no_memory_effects, x, top(), y, y ? top() : NULL); - Node* value = _gvn.transform(new (C, 1) ProjNode(rt, TypeFunc::Parms+0)); + Node* value = _gvn.transform(new (C) ProjNode(rt, TypeFunc::Parms+0)); #ifdef ASSERT - Node* value_top = _gvn.transform(new (C, 1) ProjNode(rt, TypeFunc::Parms+1)); + Node* value_top = _gvn.transform(new (C) ProjNode(rt, TypeFunc::Parms+1)); assert(value_top == top(), "second value must be top"); #endif @@ -1604,7 +1659,7 @@ _sp += arg_size(); // restore stack pointer Node *x = pop_math_arg(); - Node *result = _gvn.transform(new (C, 2) ExpDNode(0,x)); + Node *result = _gvn.transform(new (C) ExpDNode(0,x)); finish_pow_exp(result, x, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP"); @@ -1643,58 +1698,58 @@ if (!too_many_traps(Deoptimization::Reason_intrinsic)) { // Short form: skip the fancy tests and just check for NaN result. - result = _gvn.transform( new (C, 3) PowDNode(0, x, y) ); + result = _gvn.transform( new (C) PowDNode(0, x, y) ); } else { // If this inlining ever returned NaN in the past, include all // checks + call to the runtime. // Set the merge point for If node with condition of (x <= 0.0) // There are four possible paths to region node and phi node - RegionNode *r = new (C, 4) RegionNode(4); - Node *phi = new (C, 4) PhiNode(r, Type::DOUBLE); + RegionNode *r = new (C) RegionNode(4); + Node *phi = new (C) PhiNode(r, Type::DOUBLE); // Build the first if node: if (x <= 0.0) // Node for 0 constant Node *zeronode = makecon(TypeD::ZERO); // Check x:0 - Node *cmp = _gvn.transform(new (C, 3) CmpDNode(x, zeronode)); + Node *cmp = _gvn.transform(new (C) CmpDNode(x, zeronode)); // Check: If (x<=0) then go complex path - Node *bol1 = _gvn.transform( new (C, 2) BoolNode( cmp, BoolTest::le ) ); + Node *bol1 = _gvn.transform( new (C) BoolNode( cmp, BoolTest::le ) ); // Branch either way IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); // Fast path taken; set region slot 3 - Node *fast_taken = _gvn.transform( new (C, 1) IfFalseNode(if1) ); + Node *fast_taken = _gvn.transform( new (C) IfFalseNode(if1) ); r->init_req(3,fast_taken); // Capture fast-control // Fast path not-taken, i.e. slow path - Node *complex_path = _gvn.transform( new (C, 1) IfTrueNode(if1) ); + Node *complex_path = _gvn.transform( new (C) IfTrueNode(if1) ); // Set fast path result - Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, x, y) ); + Node *fast_result = _gvn.transform( new (C) PowDNode(0, x, y) ); phi->init_req(3, fast_result); // Complex path // Build the second if node (if y is long) // Node for (long)y - Node *longy = _gvn.transform( new (C, 2) ConvD2LNode(y)); + Node *longy = _gvn.transform( new (C) ConvD2LNode(y)); // Node for (double)((long) y) - Node *doublelongy= _gvn.transform( new (C, 2) ConvL2DNode(longy)); + Node *doublelongy= _gvn.transform( new (C) ConvL2DNode(longy)); // Check (double)((long) y) : y - Node *cmplongy= _gvn.transform(new (C, 3) CmpDNode(doublelongy, y)); + Node *cmplongy= _gvn.transform(new (C) CmpDNode(doublelongy, y)); // Check if (y isn't long) then go to slow path - Node *bol2 = _gvn.transform( new (C, 2) BoolNode( cmplongy, BoolTest::ne ) ); + Node *bol2 = _gvn.transform( new (C) BoolNode( cmplongy, BoolTest::ne ) ); // Branch either way IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); - Node* ylong_path = _gvn.transform( new (C, 1) IfFalseNode(if2)); - - Node *slow_path = _gvn.transform( new (C, 1) IfTrueNode(if2) ); + Node* ylong_path = _gvn.transform( new (C) IfFalseNode(if2)); + + Node *slow_path = _gvn.transform( new (C) IfTrueNode(if2) ); // Calculate DPow(abs(x), y)*(1 & (long)y) // Node for constant 1 Node *conone = longcon(1); // 1& (long)y - Node *signnode= _gvn.transform( new (C, 3) AndLNode(conone, longy) ); + Node *signnode= _gvn.transform( new (C) AndLNode(conone, longy) ); // A huge number is always even. Detect a huge number by checking // if y + 1 == y and set integer to be tested for parity to 0. @@ -1702,18 +1757,18 @@ // (long)9.223372036854776E18 = max_jlong // (double)(long)9.223372036854776E18 = 9.223372036854776E18 // max_jlong is odd but 9.223372036854776E18 is even - Node* yplus1 = _gvn.transform( new (C, 3) AddDNode(y, makecon(TypeD::make(1)))); - Node *cmpyplus1= _gvn.transform(new (C, 3) CmpDNode(yplus1, y)); - Node *bolyplus1 = _gvn.transform( new (C, 2) BoolNode( cmpyplus1, BoolTest::eq ) ); + Node* yplus1 = _gvn.transform( new (C) AddDNode(y, makecon(TypeD::make(1)))); + Node *cmpyplus1= _gvn.transform(new (C) CmpDNode(yplus1, y)); + Node *bolyplus1 = _gvn.transform( new (C) BoolNode( cmpyplus1, BoolTest::eq ) ); Node* correctedsign = NULL; if (ConditionalMoveLimit != 0) { correctedsign = _gvn.transform( CMoveNode::make(C, NULL, bolyplus1, signnode, longcon(0), TypeLong::LONG)); } else { IfNode *ifyplus1 = create_and_xform_if(ylong_path,bolyplus1, PROB_FAIR, COUNT_UNKNOWN); - RegionNode *r = new (C, 3) RegionNode(3); - Node *phi = new (C, 3) PhiNode(r, TypeLong::LONG); - r->init_req(1, _gvn.transform( new (C, 1) IfFalseNode(ifyplus1))); - r->init_req(2, _gvn.transform( new (C, 1) IfTrueNode(ifyplus1))); + RegionNode *r = new (C) RegionNode(3); + Node *phi = new (C) PhiNode(r, TypeLong::LONG); + r->init_req(1, _gvn.transform( new (C) IfFalseNode(ifyplus1))); + r->init_req(2, _gvn.transform( new (C) IfTrueNode(ifyplus1))); phi->init_req(1, signnode); phi->init_req(2, longcon(0)); correctedsign = _gvn.transform(phi); @@ -1724,25 +1779,25 @@ // zero node Node *conzero = longcon(0); // Check (1&(long)y)==0? - Node *cmpeq1 = _gvn.transform(new (C, 3) CmpLNode(correctedsign, conzero)); + Node *cmpeq1 = _gvn.transform(new (C) CmpLNode(correctedsign, conzero)); // Check if (1&(long)y)!=0?, if so the result is negative - Node *bol3 = _gvn.transform( new (C, 2) BoolNode( cmpeq1, BoolTest::ne ) ); + Node *bol3 = _gvn.transform( new (C) BoolNode( cmpeq1, BoolTest::ne ) ); // abs(x) - Node *absx=_gvn.transform( new (C, 2) AbsDNode(x)); + Node *absx=_gvn.transform( new (C) AbsDNode(x)); // abs(x)^y - Node *absxpowy = _gvn.transform( new (C, 3) PowDNode(0, absx, y) ); + Node *absxpowy = _gvn.transform( new (C) PowDNode(0, absx, y) ); // -abs(x)^y - Node *negabsxpowy = _gvn.transform(new (C, 2) NegDNode (absxpowy)); + Node *negabsxpowy = _gvn.transform(new (C) NegDNode (absxpowy)); // (1&(long)y)==1?-DPow(abs(x), y):DPow(abs(x), y) Node *signresult = NULL; if (ConditionalMoveLimit != 0) { signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE)); } else { IfNode *ifyeven = create_and_xform_if(ylong_path,bol3, PROB_FAIR, COUNT_UNKNOWN); - RegionNode *r = new (C, 3) RegionNode(3); - Node *phi = new (C, 3) PhiNode(r, Type::DOUBLE); - r->init_req(1, _gvn.transform( new (C, 1) IfFalseNode(ifyeven))); - r->init_req(2, _gvn.transform( new (C, 1) IfTrueNode(ifyeven))); + RegionNode *r = new (C) RegionNode(3); + Node *phi = new (C) PhiNode(r, Type::DOUBLE); + r->init_req(1, _gvn.transform( new (C) IfFalseNode(ifyeven))); + r->init_req(2, _gvn.transform( new (C) IfTrueNode(ifyeven))); phi->init_req(1, absxpowy); phi->init_req(2, negabsxpowy); signresult = _gvn.transform(phi); @@ -1781,10 +1836,10 @@ switch (id) { case vmIntrinsics::_dlog: - trans = _gvn.transform((Node*)new (C, 2) LogDNode(arg)); + trans = _gvn.transform((Node*)new (C) LogDNode(arg)); break; case vmIntrinsics::_dlog10: - trans = _gvn.transform((Node*)new (C, 2) Log10DNode(arg)); + trans = _gvn.transform((Node*)new (C) Log10DNode(arg)); break; default: assert(false, "bad intrinsic was passed in"); @@ -1815,9 +1870,9 @@ Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName, no_memory_effects, a, top(), b, b ? top() : NULL); - Node* value = _gvn.transform(new (C, 1) ProjNode(trig, TypeFunc::Parms+0)); + Node* value = _gvn.transform(new (C) ProjNode(trig, TypeFunc::Parms+0)); #ifdef ASSERT - Node* value_top = _gvn.transform(new (C, 1) ProjNode(trig, TypeFunc::Parms+1)); + Node* value_top = _gvn.transform(new (C) ProjNode(trig, TypeFunc::Parms+1)); assert(value_top == top(), "second value must be top"); #endif @@ -1908,7 +1963,7 @@ int cmp_op = Op_CmpI; Node* xkey = xvalue; Node* ykey = yvalue; - Node* ideal_cmpxy = _gvn.transform( new(C, 3) CmpINode(xkey, ykey) ); + Node* ideal_cmpxy = _gvn.transform( new(C) CmpINode(xkey, ykey) ); if (ideal_cmpxy->is_Cmp()) { // E.g., if we have CmpI(length - offset, count), // it might idealize to CmpI(length, count + offset) @@ -2001,7 +2056,7 @@ default: if (cmpxy == NULL) cmpxy = ideal_cmpxy; - best_bol = _gvn.transform( new(C, 2) BoolNode(cmpxy, BoolTest::lt) ); + best_bol = _gvn.transform( new(C) BoolNode(cmpxy, BoolTest::lt) ); // and fall through: case BoolTest::lt: // x < y case BoolTest::le: // x <= y @@ -2061,7 +2116,7 @@ return Type::AnyPtr; } else if (base_type == TypePtr::NULL_PTR) { // Since this is a NULL+long form, we have to switch to a rawptr. - base = _gvn.transform( new (C, 2) CastX2PNode(offset) ); + base = _gvn.transform( new (C) CastX2PNode(offset) ); offset = MakeConX(0); return Type::RawPtr; } else if (base_type->base() == Type::RawPtr) { @@ -2106,10 +2161,10 @@ _sp += arg_size(); // restore stack pointer switch (id) { case vmIntrinsics::_numberOfLeadingZeros_i: - push(_gvn.transform(new (C, 2) CountLeadingZerosINode(pop()))); + push(_gvn.transform(new (C) CountLeadingZerosINode(pop()))); break; case vmIntrinsics::_numberOfLeadingZeros_l: - push(_gvn.transform(new (C, 2) CountLeadingZerosLNode(pop_pair()))); + push(_gvn.transform(new (C) CountLeadingZerosLNode(pop_pair()))); break; default: ShouldNotReachHere(); @@ -2127,10 +2182,10 @@ _sp += arg_size(); // restore stack pointer switch (id) { case vmIntrinsics::_numberOfTrailingZeros_i: - push(_gvn.transform(new (C, 2) CountTrailingZerosINode(pop()))); + push(_gvn.transform(new (C) CountTrailingZerosINode(pop()))); break; case vmIntrinsics::_numberOfTrailingZeros_l: - push(_gvn.transform(new (C, 2) CountTrailingZerosLNode(pop_pair()))); + push(_gvn.transform(new (C) CountTrailingZerosLNode(pop_pair()))); break; default: ShouldNotReachHere(); @@ -2148,10 +2203,10 @@ _sp += arg_size(); // restore stack pointer switch (id) { case vmIntrinsics::_bitCount_i: - push(_gvn.transform(new (C, 2) PopCountINode(pop()))); + push(_gvn.transform(new (C) PopCountINode(pop()))); break; case vmIntrinsics::_bitCount_l: - push(_gvn.transform(new (C, 2) PopCountLNode(pop_pair()))); + push(_gvn.transform(new (C) PopCountLNode(pop_pair()))); break; default: ShouldNotReachHere(); @@ -2175,16 +2230,16 @@ _sp += arg_size(); // restore stack pointer switch (id) { case vmIntrinsics::_reverseBytes_i: - push(_gvn.transform(new (C, 2) ReverseBytesINode(0, pop()))); + push(_gvn.transform(new (C) ReverseBytesINode(0, pop()))); break; case vmIntrinsics::_reverseBytes_l: - push_pair(_gvn.transform(new (C, 2) ReverseBytesLNode(0, pop_pair()))); + push_pair(_gvn.transform(new (C) ReverseBytesLNode(0, pop_pair()))); break; case vmIntrinsics::_reverseBytes_c: - push(_gvn.transform(new (C, 2) ReverseBytesUSNode(0, pop()))); + push(_gvn.transform(new (C) ReverseBytesUSNode(0, pop()))); break; case vmIntrinsics::_reverseBytes_s: - push(_gvn.transform(new (C, 2) ReverseBytesSNode(0, pop()))); + push(_gvn.transform(new (C) ReverseBytesSNode(0, pop()))); break; default: ; @@ -2301,6 +2356,43 @@ // Interpret Unsafe.fieldOffset cookies correctly: extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset); +const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr) { + // Attempt to infer a sharper value type from the offset and base type. + ciKlass* sharpened_klass = NULL; + + // See if it is an instance field, with an object type. + if (alias_type->field() != NULL) { + assert(!is_native_ptr, "native pointer op cannot use a java address"); + if (alias_type->field()->type()->is_klass()) { + sharpened_klass = alias_type->field()->type()->as_klass(); + } + } + + // See if it is a narrow oop array. + if (adr_type->isa_aryptr()) { + if (adr_type->offset() >= objArrayOopDesc::base_offset_in_bytes()) { + const TypeOopPtr *elem_type = adr_type->is_aryptr()->elem()->isa_oopptr(); + if (elem_type != NULL) { + sharpened_klass = elem_type->klass(); + } + } + } + + if (sharpened_klass != NULL) { + const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass); + +#ifndef PRODUCT + if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { + tty->print(" from base type: "); adr_type->dump(); + tty->print(" sharpened value: "); tjp->dump(); + } +#endif + // Sharpen the value type. + return tjp; + } + return NULL; +} + bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile) { if (callee()->is_static()) return false; // caller must have the capability! @@ -2430,39 +2522,9 @@ offset != top() && heap_base_oop != top(); if (!is_store && type == T_OBJECT) { - // Attempt to infer a sharper value type from the offset and base type. - ciKlass* sharpened_klass = NULL; - - // See if it is an instance field, with an object type. - if (alias_type->field() != NULL) { - assert(!is_native_ptr, "native pointer op cannot use a java address"); - if (alias_type->field()->type()->is_klass()) { - sharpened_klass = alias_type->field()->type()->as_klass(); - } - } - - // See if it is a narrow oop array. - if (adr_type->isa_aryptr()) { - if (adr_type->offset() >= objArrayOopDesc::base_offset_in_bytes()) { - const TypeOopPtr *elem_type = adr_type->is_aryptr()->elem()->isa_oopptr(); - if (elem_type != NULL) { - sharpened_klass = elem_type->klass(); - } - } - } - - if (sharpened_klass != NULL) { - const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass); - - // Sharpen the value type. + const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type, is_native_ptr); + if (tjp != NULL) { value_type = tjp; - -#ifndef PRODUCT - if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { - tty->print(" from base type: "); adr_type->dump(); - tty->print(" sharpened value: "); value_type->dump(); - } -#endif } } @@ -2522,7 +2584,7 @@ break; case T_ADDRESS: // Cast to an int type. - p = _gvn.transform( new (C, 2) CastP2XNode(NULL,p) ); + p = _gvn.transform( new (C) CastP2XNode(NULL,p) ); p = ConvX2L(p); push_pair(p); break; @@ -2541,7 +2603,7 @@ case T_ADDRESS: // Repackage the long as a pointer. val = ConvL2X(val); - val = _gvn.transform( new (C, 2) CastX2PNode(val) ); + val = _gvn.transform( new (C) CastX2PNode(val) ); break; } @@ -2663,9 +2725,9 @@ // Generate the read or write prefetch Node *prefetch; if (is_store) { - prefetch = new (C, 3) PrefetchWriteNode(i_o(), adr); + prefetch = new (C) PrefetchWriteNode(i_o(), adr); } else { - prefetch = new (C, 3) PrefetchReadNode(i_o(), adr); + prefetch = new (C) PrefetchReadNode(i_o(), adr); } prefetch->init_req(0, control()); set_i_o(_gvn.transform(prefetch)); @@ -2673,9 +2735,9 @@ return true; } -//----------------------------inline_unsafe_CAS---------------------------- - -bool LibraryCallKit::inline_unsafe_CAS(BasicType type) { +//----------------------------inline_unsafe_load_store---------------------------- + +bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind) { // This basic scheme here is the same as inline_unsafe_access, but // differs in enough details that combining them would make the code // overly confusing. (This is a true fact! I originally combined @@ -2686,37 +2748,47 @@ if (callee()->is_static()) return false; // caller must have the capability! #ifndef PRODUCT + BasicType rtype; { ResourceMark rm; - // Check the signatures. ciSignature* sig = signature(); + rtype = sig->return_type()->basic_type(); + if (kind == LS_xadd || kind == LS_xchg) { + // Check the signatures. #ifdef ASSERT - BasicType rtype = sig->return_type()->basic_type(); - assert(rtype == T_BOOLEAN, "CAS must return boolean"); - assert(sig->count() == 4, "CAS has 4 arguments"); - assert(sig->type_at(0)->basic_type() == T_OBJECT, "CAS base is object"); - assert(sig->type_at(1)->basic_type() == T_LONG, "CAS offset is long"); + assert(rtype == type, "get and set must return the expected type"); + assert(sig->count() == 3, "get and set has 3 arguments"); + assert(sig->type_at(0)->basic_type() == T_OBJECT, "get and set base is object"); + assert(sig->type_at(1)->basic_type() == T_LONG, "get and set offset is long"); + assert(sig->type_at(2)->basic_type() == type, "get and set must take expected type as new value/delta"); #endif // ASSERT + } else if (kind == LS_cmpxchg) { + // Check the signatures. +#ifdef ASSERT + assert(rtype == T_BOOLEAN, "CAS must return boolean"); + assert(sig->count() == 4, "CAS has 4 arguments"); + assert(sig->type_at(0)->basic_type() == T_OBJECT, "CAS base is object"); + assert(sig->type_at(1)->basic_type() == T_LONG, "CAS offset is long"); +#endif // ASSERT + } else { + ShouldNotReachHere(); + } } #endif //PRODUCT // number of stack slots per value argument (1 or 2) int type_words = type2size[type]; - // Cannot inline wide CAS on machines that don't support it natively - if (type2aelembytes(type) > BytesPerInt && !VM_Version::supports_cx8()) - return false; - C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe". - // Argument words: "this" plus oop plus offset plus oldvalue plus newvalue; - int nargs = 1 + 1 + 2 + type_words + type_words; - - // pop arguments: newval, oldval, offset, base, and receiver + // Argument words: "this" plus oop plus offset (plus oldvalue) plus newvalue/delta; + int nargs = 1 + 1 + 2 + ((kind == LS_cmpxchg) ? type_words : 0) + type_words; + + // pop arguments: newval, offset, base, and receiver debug_only(int saved_sp = _sp); _sp += nargs; Node* newval = (type_words == 1) ? pop() : pop_pair(); - Node* oldval = (type_words == 1) ? pop() : pop_pair(); + Node* oldval = (kind == LS_cmpxchg) ? ((type_words == 1) ? pop() : pop_pair()) : NULL; Node *offset = pop_pair(); Node *base = pop(); Node *receiver = pop(); @@ -2740,16 +2812,24 @@ Node* adr = make_unsafe_address(base, offset); const TypePtr *adr_type = _gvn.type(adr)->isa_ptr(); - // (Unlike inline_unsafe_access, there seems no point in trying - // to refine types. Just use the coarse types here. + // For CAS, unlike inline_unsafe_access, there seems no point in + // trying to refine types. Just use the coarse types here. const Type *value_type = Type::get_const_basic_type(type); Compile::AliasType* alias_type = C->alias_type(adr_type); assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here"); + + if (kind == LS_xchg && type == T_OBJECT) { + const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type); + if (tjp != NULL) { + value_type = tjp; + } + } + int alias_idx = C->get_alias_index(adr_type); - // Memory-model-wise, a CAS acts like a little synchronized block, - // so needs barriers on each side. These don't translate into - // actual barriers on most machines, but we still need rest of + // Memory-model-wise, a LoadStore acts like a little synchronized + // block, so needs barriers on each side. These don't translate + // into actual barriers on most machines, but we still need rest of // compiler to respect ordering. insert_mem_bar(Op_MemBarRelease); @@ -2762,13 +2842,29 @@ // For now, we handle only those cases that actually exist: ints, // longs, and Object. Adding others should be straightforward. - Node* cas; + Node* load_store; switch(type) { case T_INT: - cas = _gvn.transform(new (C, 5) CompareAndSwapINode(control(), mem, adr, newval, oldval)); + if (kind == LS_xadd) { + load_store = _gvn.transform(new (C) GetAndAddINode(control(), mem, adr, newval, adr_type)); + } else if (kind == LS_xchg) { + load_store = _gvn.transform(new (C) GetAndSetINode(control(), mem, adr, newval, adr_type)); + } else if (kind == LS_cmpxchg) { + load_store = _gvn.transform(new (C) CompareAndSwapINode(control(), mem, adr, newval, oldval)); + } else { + ShouldNotReachHere(); + } break; case T_LONG: - cas = _gvn.transform(new (C, 5) CompareAndSwapLNode(control(), mem, adr, newval, oldval)); + if (kind == LS_xadd) { + load_store = _gvn.transform(new (C) GetAndAddLNode(control(), mem, adr, newval, adr_type)); + } else if (kind == LS_xchg) { + load_store = _gvn.transform(new (C) GetAndSetLNode(control(), mem, adr, newval, adr_type)); + } else if (kind == LS_cmpxchg) { + load_store = _gvn.transform(new (C) CompareAndSwapLNode(control(), mem, adr, newval, oldval)); + } else { + ShouldNotReachHere(); + } break; case T_OBJECT: // Transformation of a value which could be NULL pointer (CastPP #NULL) @@ -2778,40 +2874,57 @@ newval = _gvn.makecon(TypePtr::NULL_PTR); // Reference stores need a store barrier. - // (They don't if CAS fails, but it isn't worth checking.) pre_barrier(true /* do_load*/, control(), base, adr, alias_idx, newval, value_type->make_oopptr(), NULL /* pre_val*/, T_OBJECT); #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { - Node *newval_enc = _gvn.transform(new (C, 2) EncodePNode(newval, newval->bottom_type()->make_narrowoop())); - Node *oldval_enc = _gvn.transform(new (C, 2) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop())); - cas = _gvn.transform(new (C, 5) CompareAndSwapNNode(control(), mem, adr, - newval_enc, oldval_enc)); + Node *newval_enc = _gvn.transform(new (C) EncodePNode(newval, newval->bottom_type()->make_narrowoop())); + if (kind == LS_xchg) { + load_store = _gvn.transform(new (C) GetAndSetNNode(control(), mem, adr, + newval_enc, adr_type, value_type->make_narrowoop())); + } else { + assert(kind == LS_cmpxchg, "wrong LoadStore operation"); + Node *oldval_enc = _gvn.transform(new (C) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop())); + load_store = _gvn.transform(new (C) CompareAndSwapNNode(control(), mem, adr, + newval_enc, oldval_enc)); + } } else #endif { - cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval)); + if (kind == LS_xchg) { + load_store = _gvn.transform(new (C) GetAndSetPNode(control(), mem, adr, newval, adr_type, value_type->is_oopptr())); + } else { + assert(kind == LS_cmpxchg, "wrong LoadStore operation"); + load_store = _gvn.transform(new (C) CompareAndSwapPNode(control(), mem, adr, newval, oldval)); + } } - post_barrier(control(), cas, base, adr, alias_idx, newval, T_OBJECT, true); + post_barrier(control(), load_store, base, adr, alias_idx, newval, T_OBJECT, true); break; default: ShouldNotReachHere(); break; } - // SCMemProjNodes represent the memory state of CAS. Their main - // role is to prevent CAS nodes from being optimized away when their - // results aren't used. - Node* proj = _gvn.transform( new (C, 1) SCMemProjNode(cas)); + // SCMemProjNodes represent the memory state of a LoadStore. Their + // main role is to prevent LoadStore nodes from being optimized away + // when their results aren't used. + Node* proj = _gvn.transform( new (C) SCMemProjNode(load_store)); set_memory(proj, alias_idx); // Add the trailing membar surrounding the access insert_mem_bar(Op_MemBarCPUOrder); insert_mem_bar(Op_MemBarAcquire); - push(cas); +#ifdef _LP64 + if (type == T_OBJECT && adr->bottom_type()->is_ptr_to_narrowoop() && kind == LS_xchg) { + load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->bottom_type()->make_ptr())); + } +#endif + + assert(type2size[load_store->bottom_type()->basic_type()] == type2size[rtype], "result type should match"); + push_node(load_store->bottom_type()->basic_type(), load_store); return true; } @@ -2909,7 +3022,7 @@ // can generate code to load it as unsigned byte. Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN); Node* bits = intcon(InstanceKlass::fully_initialized); - Node* test = _gvn.transform( new (C, 3) SubINode(inst, bits) ); + Node* test = _gvn.transform( new (C) SubINode(inst, bits) ); // The 'test' is non-zero if we need to take a slow path. Node* obj = new_instance(kls, test); @@ -2938,9 +3051,9 @@ Node* insp = basic_plus_adr(kls, in_bytes(offset)); Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG); Node* bits = longcon(~0x03l); // ignore bit 0 & 1 - Node* andl = _gvn.transform(new (C, 3) AndLNode(tvalue, bits)); + Node* andl = _gvn.transform(new (C) AndLNode(tvalue, bits)); Node* clsused = longcon(0x01l); // set the class bit - Node* orl = _gvn.transform(new (C, 3) OrLNode(tvalue, clsused)); + Node* orl = _gvn.transform(new (C) OrLNode(tvalue, clsused)); const TypePtr *adr_type = _gvn.type(insp)->isa_ptr(); store_to_memory(control(), insp, orl, T_LONG, adr_type); @@ -2977,9 +3090,9 @@ const TypeFunc *tf = OptoRuntime::void_long_Type(); const TypePtr* no_memory_effects = NULL; Node* time = make_runtime_call(RC_LEAF, tf, funcAddr, funcName, no_memory_effects); - Node* value = _gvn.transform(new (C, 1) ProjNode(time, TypeFunc::Parms+0)); + Node* value = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+0)); #ifdef ASSERT - Node* value_top = _gvn.transform(new (C, 1) ProjNode(time, TypeFunc::Parms + 1)); + Node* value_top = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms + 1)); assert(value_top == top(), "second value must be top"); #endif push_pair(value); @@ -3008,10 +3121,10 @@ // We only go to the fast case code if we pass two guards. // Paths which do not pass are accumulated in the slow_region. - RegionNode* slow_region = new (C, 1) RegionNode(1); + RegionNode* slow_region = new (C) RegionNode(1); record_for_igvn(slow_region); - RegionNode* result_rgn = new (C, 4) RegionNode(1+3); // fast1, fast2, slow - PhiNode* result_val = new (C, 4) PhiNode(result_rgn, TypeInt::BOOL); + RegionNode* result_rgn = new (C) RegionNode(1+3); // fast1, fast2, slow + PhiNode* result_val = new (C) PhiNode(result_rgn, TypeInt::BOOL); enum { no_int_result_path = 1, no_clear_result_path = 2, slow_result_path = 3 @@ -3021,8 +3134,8 @@ Node* rec_thr = argument(0); Node* tls_ptr = NULL; Node* cur_thr = generate_current_thread(tls_ptr); - Node* cmp_thr = _gvn.transform( new (C, 3) CmpPNode(cur_thr, rec_thr) ); - Node* bol_thr = _gvn.transform( new (C, 2) BoolNode(cmp_thr, BoolTest::ne) ); + Node* cmp_thr = _gvn.transform( new (C) CmpPNode(cur_thr, rec_thr) ); + Node* bol_thr = _gvn.transform( new (C) BoolNode(cmp_thr, BoolTest::ne) ); bool known_current_thread = (_gvn.type(bol_thr) == TypeInt::ZERO); if (!known_current_thread) @@ -3034,32 +3147,32 @@ p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::interrupted_offset())); // Set the control input on the field _interrupted read to prevent it floating up. Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT); - Node* cmp_bit = _gvn.transform( new (C, 3) CmpINode(int_bit, intcon(0)) ); - Node* bol_bit = _gvn.transform( new (C, 2) BoolNode(cmp_bit, BoolTest::ne) ); + Node* cmp_bit = _gvn.transform( new (C) CmpINode(int_bit, intcon(0)) ); + Node* bol_bit = _gvn.transform( new (C) BoolNode(cmp_bit, BoolTest::ne) ); IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); // First fast path: if (!TLS._interrupted) return false; - Node* false_bit = _gvn.transform( new (C, 1) IfFalseNode(iff_bit) ); + Node* false_bit = _gvn.transform( new (C) IfFalseNode(iff_bit) ); result_rgn->init_req(no_int_result_path, false_bit); result_val->init_req(no_int_result_path, intcon(0)); // drop through to next case - set_control( _gvn.transform(new (C, 1) IfTrueNode(iff_bit)) ); + set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)) ); // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. Node* clr_arg = argument(1); - Node* cmp_arg = _gvn.transform( new (C, 3) CmpINode(clr_arg, intcon(0)) ); - Node* bol_arg = _gvn.transform( new (C, 2) BoolNode(cmp_arg, BoolTest::ne) ); + Node* cmp_arg = _gvn.transform( new (C) CmpINode(clr_arg, intcon(0)) ); + Node* bol_arg = _gvn.transform( new (C) BoolNode(cmp_arg, BoolTest::ne) ); IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN); // Second fast path: ... else if (!clear_int) return true; - Node* false_arg = _gvn.transform( new (C, 1) IfFalseNode(iff_arg) ); + Node* false_arg = _gvn.transform( new (C) IfFalseNode(iff_arg) ); result_rgn->init_req(no_clear_result_path, false_arg); result_val->init_req(no_clear_result_path, intcon(1)); // drop through to next case - set_control( _gvn.transform(new (C, 1) IfTrueNode(iff_arg)) ); + set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)) ); // (d) Otherwise, go to the slow path. slow_region->add_req(control()); @@ -3147,9 +3260,9 @@ Node* mods = make_load(NULL, modp, TypeInt::INT, T_INT); Node* mask = intcon(modifier_mask); Node* bits = intcon(modifier_bits); - Node* mbit = _gvn.transform( new (C, 3) AndINode(mods, mask) ); - Node* cmp = _gvn.transform( new (C, 3) CmpINode(mbit, bits) ); - Node* bol = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) ); + Node* mbit = _gvn.transform( new (C) AndINode(mods, mask) ); + Node* cmp = _gvn.transform( new (C) CmpINode(mbit, bits) ); + Node* bol = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ne) ); return generate_fair_guard(bol, region); } Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { @@ -3222,9 +3335,9 @@ #endif // Null-check the mirror, and the mirror's klass ptr (in case it is a primitive). - RegionNode* region = new (C, PATH_LIMIT) RegionNode(PATH_LIMIT); + RegionNode* region = new (C) RegionNode(PATH_LIMIT); record_for_igvn(region); - PhiNode* phi = new (C, PATH_LIMIT) PhiNode(region, return_type); + PhiNode* phi = new (C) PhiNode(region, return_type); // The mirror will never be null of Reflection.getClassAccessFlags, however // it may be null for Class.isInstance or Class.getModifiers. Throw a NPE @@ -3372,8 +3485,8 @@ PATH_LIMIT }; - RegionNode* region = new (C, PATH_LIMIT) RegionNode(PATH_LIMIT); - Node* phi = new (C, PATH_LIMIT) PhiNode(region, TypeInt::BOOL); + RegionNode* region = new (C) RegionNode(PATH_LIMIT); + Node* phi = new (C) PhiNode(region, TypeInt::BOOL); record_for_igvn(region); const TypePtr* adr_type = TypeRawPtr::BOTTOM; // memory type of loads @@ -3424,8 +3537,8 @@ set_control(region->in(_prim_0_path)); // go back to first null check if (!stopped()) { // Since superc is primitive, make a guard for the superc==subc case. - Node* cmp_eq = _gvn.transform( new (C, 3) CmpPNode(args[0], args[1]) ); - Node* bol_eq = _gvn.transform( new (C, 2) BoolNode(cmp_eq, BoolTest::eq) ); + Node* cmp_eq = _gvn.transform( new (C) CmpPNode(args[0], args[1]) ); + Node* bol_eq = _gvn.transform( new (C) BoolNode(cmp_eq, BoolTest::eq) ); generate_guard(bol_eq, region, PROB_FAIR); if (region->req() == PATH_LIMIT+1) { // A guard was added. If the added guard is taken, superc==subc. @@ -3491,11 +3604,11 @@ ? ((jint)Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift) : Klass::_lh_neutral_value); - Node* cmp = _gvn.transform( new(C, 3) CmpINode(layout_val, intcon(nval)) ); + Node* cmp = _gvn.transform( new(C) CmpINode(layout_val, intcon(nval)) ); BoolTest::mask btest = BoolTest::lt; // correct for testing is_[obj]array // invert the test if we are looking for a non-array if (not_array) btest = BoolTest(btest).negate(); - Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, btest) ); + Node* bol = _gvn.transform( new(C) BoolNode(cmp, btest) ); return generate_fair_guard(bol, region); } @@ -3513,12 +3626,12 @@ if (stopped()) return true; enum { _normal_path = 1, _slow_path = 2, PATH_LIMIT }; - RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); - PhiNode* result_val = new(C, PATH_LIMIT) PhiNode(result_reg, - TypeInstPtr::NOTNULL); - PhiNode* result_io = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO); - PhiNode* result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY, - TypePtr::BOTTOM); + RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); + PhiNode* result_val = new(C) PhiNode(result_reg, + TypeInstPtr::NOTNULL); + PhiNode* result_io = new(C) PhiNode(result_reg, Type::ABIO); + PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, + TypePtr::BOTTOM); bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check); Node* klass_node = load_array_klass_from_mirror(mirror, never_see_null, @@ -3633,7 +3746,7 @@ NULL, 0); klass_node = do_null_check(klass_node, T_OBJECT); - RegionNode* bailout = new (C, 1) RegionNode(1); + RegionNode* bailout = new (C) RegionNode(1); record_for_igvn(bailout); // Despite the generic type of Arrays.copyOf, the mirror might be int, int[], etc. @@ -3643,7 +3756,7 @@ // Improve the klass node's type from the new optimistic assumption: ciKlass* ak = ciArrayKlass::make(env()->Object_klass()); const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/); - Node* cast = new (C, 2) CastPPNode(klass_node, akls); + Node* cast = new (C) CastPPNode(klass_node, akls); cast->init_req(0, control()); klass_node = _gvn.transform(cast); } @@ -3654,7 +3767,7 @@ Node* length = end; if (_gvn.type(start) != TypeInt::ZERO) { - length = _gvn.transform( new (C, 3) SubINode(end, start) ); + length = _gvn.transform( new (C) SubINode(end, start) ); } // Bail out if length is negative. @@ -3674,7 +3787,7 @@ // How many elements will we copy from the original? // The answer is MinI(orig_length - start, length). - Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) ); + Node* orig_tail = _gvn.transform( new(C) SubINode(orig_length, start) ); Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length); newcopy = new_array(klass_node, length, 0); @@ -3721,8 +3834,8 @@ const TypePtr* native_call_addr = TypeMetadataPtr::make(method); Node* native_call = makecon(native_call_addr); - Node* chk_native = _gvn.transform( new(C, 3) CmpPNode(target_call, native_call) ); - Node* test_native = _gvn.transform( new(C, 2) BoolNode(chk_native, BoolTest::ne) ); + Node* chk_native = _gvn.transform( new(C) CmpPNode(target_call, native_call) ); + Node* test_native = _gvn.transform( new(C) BoolNode(chk_native, BoolTest::ne) ); return generate_slow_guard(test_native, slow_region); } @@ -3744,13 +3857,12 @@ guarantee(method_id == method->intrinsic_id(), "must match"); const TypeFunc* tf = TypeFunc::make(method); - int tfdc = tf->domain()->cnt(); CallJavaNode* slow_call; if (is_static) { assert(!is_virtual, ""); - slow_call = new(C, tfdc) CallStaticJavaNode(tf, - SharedRuntime::get_resolve_static_call_stub(), - method, bci()); + slow_call = new(C) CallStaticJavaNode(tf, + SharedRuntime::get_resolve_static_call_stub(), + method, bci()); } else if (is_virtual) { null_check_receiver(method); int vtable_index = Method::invalid_vtable_index; @@ -3762,12 +3874,12 @@ // No need to use the linkResolver to get it. vtable_index = method->vtable_index(); } - slow_call = new(C, tfdc) CallDynamicJavaNode(tf, - SharedRuntime::get_resolve_virtual_call_stub(), - method, vtable_index, bci()); + slow_call = new(C) CallDynamicJavaNode(tf, + SharedRuntime::get_resolve_virtual_call_stub(), + method, vtable_index, bci()); } else { // neither virtual nor static: opt_virtual null_check_receiver(method); - slow_call = new(C, tfdc) CallStaticJavaNode(tf, + slow_call = new(C) CallStaticJavaNode(tf, SharedRuntime::get_resolve_opt_virtual_call_stub(), method, bci()); slow_call->set_optimized_virtual(true); @@ -3786,12 +3898,12 @@ enum { _slow_path = 1, _fast_path, _null_path, PATH_LIMIT }; - RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); - PhiNode* result_val = new(C, PATH_LIMIT) PhiNode(result_reg, - TypeInt::INT); - PhiNode* result_io = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO); - PhiNode* result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY, - TypePtr::BOTTOM); + RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); + PhiNode* result_val = new(C) PhiNode(result_reg, + TypeInt::INT); + PhiNode* result_io = new(C) PhiNode(result_reg, Type::ABIO); + PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, + TypePtr::BOTTOM); Node* obj = NULL; if (!is_static) { // Check for hashing null object @@ -3825,7 +3937,7 @@ // We only go to the fast case code if we pass a number of guards. The // paths which do not pass are accumulated in the slow_region. - RegionNode* slow_region = new (C, 1) RegionNode(1); + RegionNode* slow_region = new (C) RegionNode(1); record_for_igvn(slow_region); // If this is a virtual call, we generate a funny guard. We pull out @@ -3844,10 +3956,10 @@ // Test the header to see if it is unlocked. Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); - Node *lmasked_header = _gvn.transform( new (C, 3) AndXNode(header, lock_mask) ); + Node *lmasked_header = _gvn.transform( new (C) AndXNode(header, lock_mask) ); Node *unlocked_val = _gvn.MakeConX(markOopDesc::unlocked_value); - Node *chk_unlocked = _gvn.transform( new (C, 3) CmpXNode( lmasked_header, unlocked_val)); - Node *test_unlocked = _gvn.transform( new (C, 2) BoolNode( chk_unlocked, BoolTest::ne) ); + Node *chk_unlocked = _gvn.transform( new (C) CmpXNode( lmasked_header, unlocked_val)); + Node *test_unlocked = _gvn.transform( new (C) BoolNode( chk_unlocked, BoolTest::ne) ); generate_slow_guard(test_unlocked, slow_region); @@ -3857,17 +3969,17 @@ // vm: see markOop.hpp. Node *hash_mask = _gvn.intcon(markOopDesc::hash_mask); Node *hash_shift = _gvn.intcon(markOopDesc::hash_shift); - Node *hshifted_header= _gvn.transform( new (C, 3) URShiftXNode(header, hash_shift) ); + Node *hshifted_header= _gvn.transform( new (C) URShiftXNode(header, hash_shift) ); // This hack lets the hash bits live anywhere in the mark object now, as long // as the shift drops the relevant bits into the low 32 bits. Note that // Java spec says that HashCode is an int so there's no point in capturing // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build). hshifted_header = ConvX2I(hshifted_header); - Node *hash_val = _gvn.transform( new (C, 3) AndINode(hshifted_header, hash_mask) ); + Node *hash_val = _gvn.transform( new (C) AndINode(hshifted_header, hash_mask) ); Node *no_hash_val = _gvn.intcon(markOopDesc::no_hash); - Node *chk_assigned = _gvn.transform( new (C, 3) CmpINode( hash_val, no_hash_val)); - Node *test_assigned = _gvn.transform( new (C, 2) BoolNode( chk_assigned, BoolTest::eq) ); + Node *chk_assigned = _gvn.transform( new (C) CmpINode( hash_val, no_hash_val)); + Node *test_assigned = _gvn.transform( new (C) BoolNode( chk_assigned, BoolTest::eq) ); generate_slow_guard(test_assigned, slow_region); @@ -4071,31 +4183,31 @@ switch (id) { case vmIntrinsics::_floatToRawIntBits: - push(_gvn.transform( new (C, 2) MoveF2INode(pop()))); + push(_gvn.transform( new (C) MoveF2INode(pop()))); break; case vmIntrinsics::_intBitsToFloat: - push(_gvn.transform( new (C, 2) MoveI2FNode(pop()))); + push(_gvn.transform( new (C) MoveI2FNode(pop()))); break; case vmIntrinsics::_doubleToRawLongBits: - push_pair(_gvn.transform( new (C, 2) MoveD2LNode(pop_pair()))); + push_pair(_gvn.transform( new (C) MoveD2LNode(pop_pair()))); break; case vmIntrinsics::_longBitsToDouble: - push_pair(_gvn.transform( new (C, 2) MoveL2DNode(pop_pair()))); + push_pair(_gvn.transform( new (C) MoveL2DNode(pop_pair()))); break; case vmIntrinsics::_doubleToLongBits: { Node* value = pop_pair(); // two paths (plus control) merge in a wood - RegionNode *r = new (C, 3) RegionNode(3); - Node *phi = new (C, 3) PhiNode(r, TypeLong::LONG); - - Node *cmpisnan = _gvn.transform( new (C, 3) CmpDNode(value, value)); + RegionNode *r = new (C) RegionNode(3); + Node *phi = new (C) PhiNode(r, TypeLong::LONG); + + Node *cmpisnan = _gvn.transform( new (C) CmpDNode(value, value)); // Build the boolean node - Node *bolisnan = _gvn.transform( new (C, 2) BoolNode( cmpisnan, BoolTest::ne ) ); + Node *bolisnan = _gvn.transform( new (C) BoolNode( cmpisnan, BoolTest::ne ) ); // Branch either way. // NaN case is less traveled, which makes all the difference. @@ -4103,7 +4215,7 @@ Node *opt_isnan = _gvn.transform(ifisnan); assert( opt_isnan->is_If(), "Expect an IfNode"); IfNode *opt_ifisnan = (IfNode*)opt_isnan; - Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode(opt_ifisnan) ); + Node *iftrue = _gvn.transform( new (C) IfTrueNode(opt_ifisnan) ); set_control(iftrue); @@ -4113,10 +4225,10 @@ r->init_req(1, iftrue); // Else fall through - Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(opt_ifisnan) ); + Node *iffalse = _gvn.transform( new (C) IfFalseNode(opt_ifisnan) ); set_control(iffalse); - phi->init_req(2, _gvn.transform( new (C, 2) MoveD2LNode(value))); + phi->init_req(2, _gvn.transform( new (C) MoveD2LNode(value))); r->init_req(2, iffalse); // Post merge @@ -4136,12 +4248,12 @@ Node* value = pop(); // two paths (plus control) merge in a wood - RegionNode *r = new (C, 3) RegionNode(3); - Node *phi = new (C, 3) PhiNode(r, TypeInt::INT); - - Node *cmpisnan = _gvn.transform( new (C, 3) CmpFNode(value, value)); + RegionNode *r = new (C) RegionNode(3); + Node *phi = new (C) PhiNode(r, TypeInt::INT); + + Node *cmpisnan = _gvn.transform( new (C) CmpFNode(value, value)); // Build the boolean node - Node *bolisnan = _gvn.transform( new (C, 2) BoolNode( cmpisnan, BoolTest::ne ) ); + Node *bolisnan = _gvn.transform( new (C) BoolNode( cmpisnan, BoolTest::ne ) ); // Branch either way. // NaN case is less traveled, which makes all the difference. @@ -4149,7 +4261,7 @@ Node *opt_isnan = _gvn.transform(ifisnan); assert( opt_isnan->is_If(), "Expect an IfNode"); IfNode *opt_ifisnan = (IfNode*)opt_isnan; - Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode(opt_ifisnan) ); + Node *iftrue = _gvn.transform( new (C) IfTrueNode(opt_ifisnan) ); set_control(iftrue); @@ -4159,10 +4271,10 @@ r->init_req(1, iftrue); // Else fall through - Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(opt_ifisnan) ); + Node *iffalse = _gvn.transform( new (C) IfFalseNode(opt_ifisnan) ); set_control(iffalse); - phi->init_req(2, _gvn.transform( new (C, 2) MoveF2INode(value))); + phi->init_req(2, _gvn.transform( new (C) MoveF2INode(value))); r->init_req(2, iffalse); // Post merge @@ -4284,8 +4396,8 @@ // Compute the length also, if needed: Node* countx = size; - countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(base_off)) ); - countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong) )); + countx = _gvn.transform( new (C) SubXNode(countx, MakeConX(base_off)) ); + countx = _gvn.transform( new (C) URShiftXNode(countx, intcon(LogBytesPerLong) )); const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; bool disjoint_bases = true; @@ -4376,12 +4488,12 @@ _instance_path, // plain instance allocation, plus arrayof_long_arraycopy PATH_LIMIT }; - RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); - result_val = new(C, PATH_LIMIT) PhiNode(result_reg, - TypeInstPtr::NOTNULL); - PhiNode* result_i_o = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO); - PhiNode* result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY, - TypePtr::BOTTOM); + RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); + result_val = new(C) PhiNode(result_reg, + TypeInstPtr::NOTNULL); + PhiNode* result_i_o = new(C) PhiNode(result_reg, Type::ABIO); + PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, + TypePtr::BOTTOM); record_for_igvn(result_reg); const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; @@ -4437,7 +4549,7 @@ // We only go to the instance fast case code if we pass a number of guards. // The paths which do not pass are accumulated in the slow_region. - RegionNode* slow_region = new (C, 1) RegionNode(1); + RegionNode* slow_region = new (C) RegionNode(1); record_for_igvn(slow_region); if (!stopped()) { // It's an instance (we did array above). Make the slow-path tests. @@ -4607,7 +4719,7 @@ // (8) dest_offset + length must not exceed length of dest. // (9) each element of an oop array must be assignable - RegionNode* slow_region = new (C, 1) RegionNode(1); + RegionNode* slow_region = new (C) RegionNode(1); record_for_igvn(slow_region); // (3) operands must not be null @@ -4697,7 +4809,7 @@ RegionNode* slow_region) { if (slow_region == NULL) { - slow_region = new(C,1) RegionNode(1); + slow_region = new(C) RegionNode(1); record_for_igvn(slow_region); } @@ -4745,9 +4857,9 @@ bcopy_path = 5, // copy primitive array by 64-bit blocks PATH_LIMIT = 6 }; - RegionNode* result_region = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); - PhiNode* result_i_o = new(C, PATH_LIMIT) PhiNode(result_region, Type::ABIO); - PhiNode* result_memory = new(C, PATH_LIMIT) PhiNode(result_region, Type::MEMORY, adr_type); + RegionNode* result_region = new(C) RegionNode(PATH_LIMIT); + PhiNode* result_i_o = new(C) PhiNode(result_region, Type::ABIO); + PhiNode* result_memory = new(C) PhiNode(result_region, Type::MEMORY, adr_type); record_for_igvn(result_region); _gvn.set_type_bottom(result_i_o); _gvn.set_type_bottom(result_memory); @@ -4821,7 +4933,7 @@ // are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length]. Node* dest_size = alloc->in(AllocateNode::AllocSize); Node* dest_length = alloc->in(AllocateNode::ALength); - Node* dest_tail = _gvn.transform( new(C,3) AddINode(dest_offset, + Node* dest_tail = _gvn.transform( new(C) AddINode(dest_offset, copy_length) ); // If there is a head section that needs zeroing, do it now. @@ -4838,8 +4950,8 @@ // the copy to a more hardware-friendly word size of 64 bits. Node* tail_ctl = NULL; if (!stopped() && !dest_tail->eqv_uncast(dest_length)) { - Node* cmp_lt = _gvn.transform( new(C,3) CmpINode(dest_tail, dest_length) ); - Node* bol_lt = _gvn.transform( new(C,2) BoolNode(cmp_lt, BoolTest::lt) ); + Node* cmp_lt = _gvn.transform( new(C) CmpINode(dest_tail, dest_length) ); + Node* bol_lt = _gvn.transform( new(C) BoolNode(cmp_lt, BoolTest::lt) ); tail_ctl = generate_slow_guard(bol_lt, NULL); assert(tail_ctl != NULL || !stopped(), "must be an outcome"); } @@ -4873,8 +4985,8 @@ dest_size); } else { // Make a local merge. - Node* done_ctl = new(C,3) RegionNode(3); - Node* done_mem = new(C,3) PhiNode(done_ctl, Type::MEMORY, adr_type); + Node* done_ctl = new(C) RegionNode(3); + Node* done_mem = new(C) PhiNode(done_ctl, Type::MEMORY, adr_type); done_ctl->init_req(1, notail_ctl); done_mem->init_req(1, memory(adr_type)); generate_clear_array(adr_type, dest, basic_elem_type, @@ -4969,21 +5081,21 @@ // Clean up after the checked call. // The returned value is either 0 or -1^K, // where K = number of partially transferred array elements. - Node* cmp = _gvn.transform( new(C, 3) CmpINode(checked_value, intcon(0)) ); - Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) ); + Node* cmp = _gvn.transform( new(C) CmpINode(checked_value, intcon(0)) ); + Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) ); IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN); // If it is 0, we are done, so transfer to the end. - Node* checks_done = _gvn.transform( new(C, 1) IfTrueNode(iff) ); + Node* checks_done = _gvn.transform( new(C) IfTrueNode(iff) ); result_region->init_req(checked_path, checks_done); result_i_o ->init_req(checked_path, checked_i_o); result_memory->init_req(checked_path, checked_mem); // If it is not zero, merge into the slow call. - set_control( _gvn.transform( new(C, 1) IfFalseNode(iff) )); - RegionNode* slow_reg2 = new(C, 3) RegionNode(3); - PhiNode* slow_i_o2 = new(C, 3) PhiNode(slow_reg2, Type::ABIO); - PhiNode* slow_mem2 = new(C, 3) PhiNode(slow_reg2, Type::MEMORY, adr_type); + set_control( _gvn.transform( new(C) IfFalseNode(iff) )); + RegionNode* slow_reg2 = new(C) RegionNode(3); + PhiNode* slow_i_o2 = new(C) PhiNode(slow_reg2, Type::ABIO); + PhiNode* slow_mem2 = new(C) PhiNode(slow_reg2, Type::MEMORY, adr_type); record_for_igvn(slow_reg2); slow_reg2 ->init_req(1, slow_control); slow_i_o2 ->init_req(1, slow_i_o); @@ -5003,16 +5115,16 @@ } else { // We must continue the copy exactly where it failed, or else // another thread might see the wrong number of writes to dest. - Node* checked_offset = _gvn.transform( new(C, 3) XorINode(checked_value, intcon(-1)) ); - Node* slow_offset = new(C, 3) PhiNode(slow_reg2, TypeInt::INT); + Node* checked_offset = _gvn.transform( new(C) XorINode(checked_value, intcon(-1)) ); + Node* slow_offset = new(C) PhiNode(slow_reg2, TypeInt::INT); slow_offset->init_req(1, intcon(0)); slow_offset->init_req(2, checked_offset); slow_offset = _gvn.transform(slow_offset); // Adjust the arguments by the conditionally incoming offset. - Node* src_off_plus = _gvn.transform( new(C, 3) AddINode(src_offset, slow_offset) ); - Node* dest_off_plus = _gvn.transform( new(C, 3) AddINode(dest_offset, slow_offset) ); - Node* length_minus = _gvn.transform( new(C, 3) SubINode(copy_length, slow_offset) ); + Node* src_off_plus = _gvn.transform( new(C) AddINode(src_offset, slow_offset) ); + Node* dest_off_plus = _gvn.transform( new(C) AddINode(dest_offset, slow_offset) ); + Node* length_minus = _gvn.transform( new(C) SubINode(copy_length, slow_offset) ); // Tweak the node variables to adjust the code produced below: src_offset = src_off_plus; @@ -5233,10 +5345,10 @@ int end_round = (-1 << scale) & (BytesPerLong - 1); Node* end = ConvI2X(slice_len); if (scale != 0) - end = _gvn.transform( new(C,3) LShiftXNode(end, intcon(scale) )); + end = _gvn.transform( new(C) LShiftXNode(end, intcon(scale) )); end_base += end_round; - end = _gvn.transform( new(C,3) AddXNode(end, MakeConX(end_base)) ); - end = _gvn.transform( new(C,3) AndXNode(end, MakeConX(~end_round)) ); + end = _gvn.transform( new(C) AddXNode(end, MakeConX(end_base)) ); + end = _gvn.transform( new(C) AndXNode(end, MakeConX(~end_round)) ); mem = ClearArrayNode::clear_memory(control(), mem, dest, start_con, end, &_gvn); } else if (start_con < 0 && dest_size != top()) { @@ -5245,8 +5357,8 @@ Node* start = slice_idx; start = ConvI2X(start); if (scale != 0) - start = _gvn.transform( new(C,3) LShiftXNode( start, intcon(scale) )); - start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(abase)) ); + start = _gvn.transform( new(C) LShiftXNode( start, intcon(scale) )); + start = _gvn.transform( new(C) AddXNode(start, MakeConX(abase)) ); if ((bump_bit | clear_low) != 0) { int to_clear = (bump_bit | clear_low); // Align up mod 8, then store a jint zero unconditionally @@ -5257,14 +5369,14 @@ assert((abase & to_clear) == 0, "array base must be long-aligned"); } else { // Bump 'start' up to (or past) the next jint boundary: - start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(bump_bit)) ); + start = _gvn.transform( new(C) AddXNode(start, MakeConX(bump_bit)) ); assert((abase & clear_low) == 0, "array base must be int-aligned"); } // Round bumped 'start' down to jlong boundary in body of array. - start = _gvn.transform( new(C,3) AndXNode(start, MakeConX(~to_clear)) ); + start = _gvn.transform( new(C) AndXNode(start, MakeConX(~to_clear)) ); if (bump_bit != 0) { // Store a zero to the immediately preceding jint: - Node* x1 = _gvn.transform( new(C,3) AddXNode(start, MakeConX(-bump_bit)) ); + Node* x1 = _gvn.transform( new(C) AddXNode(start, MakeConX(-bump_bit)) ); Node* p1 = basic_plus_adr(dest, x1); mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT); mem = _gvn.transform(mem); @@ -5331,8 +5443,8 @@ Node* sptr = basic_plus_adr(src, src_off); Node* dptr = basic_plus_adr(dest, dest_off); Node* countx = dest_size; - countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(dest_off)) ); - countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong)) ); + countx = _gvn.transform( new (C) SubXNode(countx, MakeConX(dest_off)) ); + countx = _gvn.transform( new (C) URShiftXNode(countx, intcon(LogBytesPerLong)) ); bool disjoint_bases = true; // since alloc != NULL generate_unchecked_arraycopy(adr_type, T_LONG, disjoint_bases, @@ -5382,7 +5494,7 @@ // super_check_offset, for the desired klass. int sco_offset = in_bytes(Klass::super_check_offset_offset()); Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset); - Node* n3 = new(C, 3) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr()); + Node* n3 = new(C) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr()); Node* check_offset = ConvI2X(_gvn.transform(n3)); Node* check_value = dest_elem_klass; @@ -5400,7 +5512,7 @@ check_offset XTOP, check_value); - return _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Parms)); + return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); } @@ -5422,7 +5534,7 @@ copyfunc_addr, "generic_arraycopy", adr_type, src, src_offset, dest, dest_offset, copy_length); - return _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Parms)); + return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); } // Helper function; generates the fast out-of-line call to an arraycopy stub. diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/loopPredicate.cpp --- a/src/share/vm/opto/loopPredicate.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/loopPredicate.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -159,7 +159,7 @@ assert(rgn->is_Call(), "must be call uct"); CallNode* call = rgn->as_Call(); IdealLoopTree* loop = get_loop(call); - rgn = new (C, 1) RegionNode(1); + rgn = new (C) RegionNode(1); rgn->add_req(uncommon_proj); register_control(rgn, loop, uncommon_proj); _igvn.hash_delete(call); @@ -185,8 +185,8 @@ IfNode *new_iff = iff->clone()->as_If(); new_iff->set_req(0, entry); register_control(new_iff, lp, entry); - Node *if_cont = new (C, 1) IfTrueNode(new_iff); - Node *if_uct = new (C, 1) IfFalseNode(new_iff); + Node *if_cont = new (C) IfTrueNode(new_iff); + Node *if_uct = new (C) IfFalseNode(new_iff); if (cont_proj->is_IfFalse()) { // Swap Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp; @@ -246,7 +246,7 @@ if (!rgn->is_Region()) { // create a region to guard the call assert(rgn->is_Call(), "must be call uct"); CallNode* call = rgn->as_Call(); - rgn = new (C, 1) RegionNode(1); + rgn = new (C) RegionNode(1); register_new_node_with_optimizer(rgn); rgn->add_req(uncommon_proj); hash_delete(call); @@ -263,8 +263,8 @@ new_iff->set_req(0, new_entry); register_new_node_with_optimizer(new_iff); - Node *if_cont = new (C, 1) IfTrueNode(new_iff); - Node *if_uct = new (C, 1) IfFalseNode(new_iff); + Node *if_cont = new (C) IfTrueNode(new_iff); + Node *if_uct = new (C) IfFalseNode(new_iff); if (cont_proj->is_IfFalse()) { // Swap Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp; @@ -309,10 +309,10 @@ // Match original condition since predicate's projections could be swapped. assert(predicate_proj->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be"); - Node* opq = new (igvn->C, 2) Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1)); + Node* opq = new (igvn->C) Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1)); igvn->C->add_predicate_opaq(opq); - Node* bol = new (igvn->C, 2) Conv2BNode(opq); + Node* bol = new (igvn->C) Conv2BNode(opq); if (loop_phase != NULL) { loop_phase->register_new_node(opq, ctrl); loop_phase->register_new_node(bol, ctrl); @@ -660,11 +660,11 @@ // Calculate exact limit here. // Note, counted loop's test is '<' or '>'. limit = exact_limit(loop); - max_idx_expr = new (C, 3) SubINode(limit, stride); + max_idx_expr = new (C) SubINode(limit, stride); register_new_node(max_idx_expr, ctrl); if (TraceLoopPredicate) predString->print("(limit - stride) "); } else { - max_idx_expr = new (C, 3) SubINode(limit, stride); + max_idx_expr = new (C) SubINode(limit, stride); register_new_node(max_idx_expr, ctrl); if (TraceLoopPredicate) predString->print("(limit - stride) "); } @@ -674,22 +674,22 @@ if (scale != 1) { ConNode* con_scale = _igvn.intcon(scale); - max_idx_expr = new (C, 3) MulINode(max_idx_expr, con_scale); + max_idx_expr = new (C) MulINode(max_idx_expr, con_scale); register_new_node(max_idx_expr, ctrl); if (TraceLoopPredicate) predString->print("* %d ", scale); } if (offset && (!offset->is_Con() || offset->get_int() != 0)){ - max_idx_expr = new (C, 3) AddINode(max_idx_expr, offset); + max_idx_expr = new (C) AddINode(max_idx_expr, offset); register_new_node(max_idx_expr, ctrl); if (TraceLoopPredicate) if (offset->is_Con()) predString->print("+ %d ", offset->get_int()); else predString->print("+ offset "); } - CmpUNode* cmp = new (C, 3) CmpUNode(max_idx_expr, range); + CmpUNode* cmp = new (C) CmpUNode(max_idx_expr, range); register_new_node(cmp, ctrl); - BoolNode* bol = new (C, 2) BoolNode(cmp, BoolTest::lt); + BoolNode* bol = new (C) BoolNode(cmp, BoolTest::lt); register_new_node(bol, ctrl); if (TraceLoopPredicate) { @@ -805,7 +805,7 @@ // Negate test if necessary bool negated = false; if (proj->_con != predicate_proj->_con) { - new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate()); + new_predicate_bol = new (C) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate()); register_new_node(new_predicate_bol, ctrl); negated = true; } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/loopTransform.cpp --- a/src/share/vm/opto/loopTransform.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/loopTransform.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -224,24 +224,24 @@ if (neg_inv1) { Node *zero = phase->_igvn.intcon(0); phase->set_ctrl(zero, phase->C->root()); - n_inv1 = new (phase->C, 3) SubINode(zero, inv1); + n_inv1 = new (phase->C) SubINode(zero, inv1); phase->register_new_node(n_inv1, inv1_c); } else { n_inv1 = inv1; } Node* inv; if (neg_inv2) { - inv = new (phase->C, 3) SubINode(n_inv1, inv2); + inv = new (phase->C) SubINode(n_inv1, inv2); } else { - inv = new (phase->C, 3) AddINode(n_inv1, inv2); + inv = new (phase->C) AddINode(n_inv1, inv2); } phase->register_new_node(inv, phase->get_early_ctrl(inv)); Node* addx; if (neg_x) { - addx = new (phase->C, 3) SubINode(inv, x); + addx = new (phase->C) SubINode(inv, x); } else { - addx = new (phase->C, 3) AddINode(x, inv); + addx = new (phase->C) AddINode(x, inv); } phase->register_new_node(addx, phase->get_ctrl(x)); phase->_igvn.replace_node(n1, addx); @@ -932,7 +932,7 @@ post_end->_prob = PROB_FAIR; // Build the main-loop normal exit. - IfFalseNode *new_main_exit = new (C, 1) IfFalseNode(main_end); + IfFalseNode *new_main_exit = new (C) IfFalseNode(main_end); _igvn.register_new_node_with_optimizer( new_main_exit ); set_idom(new_main_exit, main_end, dd_main_exit ); set_loop(new_main_exit, loop->_parent); @@ -942,15 +942,15 @@ // (the main-loop trip-counter exit value) because we will be changing // the exit value (via unrolling) so we cannot constant-fold away the zero // trip guard until all unrolling is done. - Node *zer_opaq = new (C, 2) Opaque1Node(C, incr); - Node *zer_cmp = new (C, 3) CmpINode( zer_opaq, limit ); - Node *zer_bol = new (C, 2) BoolNode( zer_cmp, b_test ); + Node *zer_opaq = new (C) Opaque1Node(C, incr); + Node *zer_cmp = new (C) CmpINode( zer_opaq, limit ); + Node *zer_bol = new (C) BoolNode( zer_cmp, b_test ); register_new_node( zer_opaq, new_main_exit ); register_new_node( zer_cmp , new_main_exit ); register_new_node( zer_bol , new_main_exit ); // Build the IfNode - IfNode *zer_iff = new (C, 2) IfNode( new_main_exit, zer_bol, PROB_FAIR, COUNT_UNKNOWN ); + IfNode *zer_iff = new (C) IfNode( new_main_exit, zer_bol, PROB_FAIR, COUNT_UNKNOWN ); _igvn.register_new_node_with_optimizer( zer_iff ); set_idom(zer_iff, new_main_exit, dd_main_exit); set_loop(zer_iff, loop->_parent); @@ -960,7 +960,7 @@ set_idom(main_exit, zer_iff, dd_main_exit); set_idom(main_exit->unique_out(), zer_iff, dd_main_exit); // Make the true-path, must enter the post loop - Node *zer_taken = new (C, 1) IfTrueNode( zer_iff ); + Node *zer_taken = new (C) IfTrueNode( zer_iff ); _igvn.register_new_node_with_optimizer( zer_taken ); set_idom(zer_taken, zer_iff, dd_main_exit); set_loop(zer_taken, loop->_parent); @@ -1008,7 +1008,7 @@ // Find the pre-loop normal exit. Node* pre_exit = pre_end->proj_out(false); assert( pre_exit->Opcode() == Op_IfFalse, "" ); - IfFalseNode *new_pre_exit = new (C, 1) IfFalseNode(pre_end); + IfFalseNode *new_pre_exit = new (C) IfFalseNode(pre_end); _igvn.register_new_node_with_optimizer( new_pre_exit ); set_idom(new_pre_exit, pre_end, dd_main_head); set_loop(new_pre_exit, loop->_parent); @@ -1017,15 +1017,15 @@ // pre-loop, the main-loop may not execute at all. Later in life this // zero-trip guard will become the minimum-trip guard when we unroll // the main-loop. - Node *min_opaq = new (C, 2) Opaque1Node(C, limit); - Node *min_cmp = new (C, 3) CmpINode( pre_incr, min_opaq ); - Node *min_bol = new (C, 2) BoolNode( min_cmp, b_test ); + Node *min_opaq = new (C) Opaque1Node(C, limit); + Node *min_cmp = new (C) CmpINode( pre_incr, min_opaq ); + Node *min_bol = new (C) BoolNode( min_cmp, b_test ); register_new_node( min_opaq, new_pre_exit ); register_new_node( min_cmp , new_pre_exit ); register_new_node( min_bol , new_pre_exit ); // Build the IfNode (assume the main-loop is executed always). - IfNode *min_iff = new (C, 2) IfNode( new_pre_exit, min_bol, PROB_ALWAYS, COUNT_UNKNOWN ); + IfNode *min_iff = new (C) IfNode( new_pre_exit, min_bol, PROB_ALWAYS, COUNT_UNKNOWN ); _igvn.register_new_node_with_optimizer( min_iff ); set_idom(min_iff, new_pre_exit, dd_main_head); set_loop(min_iff, loop->_parent); @@ -1036,7 +1036,7 @@ set_idom(pre_exit, min_iff, dd_main_head); set_idom(pre_exit->unique_out(), min_iff, dd_main_head); // Make the true-path, must enter the main loop - Node *min_taken = new (C, 1) IfTrueNode( min_iff ); + Node *min_taken = new (C) IfTrueNode( min_iff ); _igvn.register_new_node_with_optimizer( min_taken ); set_idom(min_taken, min_iff, dd_main_head); set_loop(min_taken, loop->_parent); @@ -1066,11 +1066,11 @@ // RCE and alignment may change this later. Node *cmp_end = pre_end->cmp_node(); assert( cmp_end->in(2) == limit, "" ); - Node *pre_limit = new (C, 3) AddINode( init, stride ); + Node *pre_limit = new (C) AddINode( init, stride ); // Save the original loop limit in this Opaque1 node for // use by range check elimination. - Node *pre_opaq = new (C, 3) Opaque1Node(C, pre_limit, limit); + Node *pre_opaq = new (C) Opaque1Node(C, pre_limit, limit); register_new_node( pre_limit, pre_head->in(0) ); register_new_node( pre_opaq , pre_head->in(0) ); @@ -1095,19 +1095,19 @@ BoolTest::mask new_test = (main_end->stride_con() > 0) ? BoolTest::lt : BoolTest::gt; // Modify pre loop end condition Node* pre_bol = pre_end->in(CountedLoopEndNode::TestValue)->as_Bool(); - BoolNode* new_bol0 = new (C, 2) BoolNode(pre_bol->in(1), new_test); + BoolNode* new_bol0 = new (C) BoolNode(pre_bol->in(1), new_test); register_new_node( new_bol0, pre_head->in(0) ); _igvn.hash_delete(pre_end); pre_end->set_req(CountedLoopEndNode::TestValue, new_bol0); // Modify main loop guard condition assert(min_iff->in(CountedLoopEndNode::TestValue) == min_bol, "guard okay"); - BoolNode* new_bol1 = new (C, 2) BoolNode(min_bol->in(1), new_test); + BoolNode* new_bol1 = new (C) BoolNode(min_bol->in(1), new_test); register_new_node( new_bol1, new_pre_exit ); _igvn.hash_delete(min_iff); min_iff->set_req(CountedLoopEndNode::TestValue, new_bol1); // Modify main loop end condition BoolNode* main_bol = main_end->in(CountedLoopEndNode::TestValue)->as_Bool(); - BoolNode* new_bol2 = new (C, 2) BoolNode(main_bol->in(1), new_test); + BoolNode* new_bol2 = new (C) BoolNode(main_bol->in(1), new_test); register_new_node( new_bol2, main_end->in(CountedLoopEndNode::TestControl) ); _igvn.hash_delete(main_end); main_end->set_req(CountedLoopEndNode::TestValue, new_bol2); @@ -1257,13 +1257,13 @@ // zero trip guard limit will be different from loop limit. assert(has_ctrl(opaq), "should have it"); Node* opaq_ctrl = get_ctrl(opaq); - limit = new (C, 2) Opaque2Node( C, limit ); + limit = new (C) Opaque2Node( C, limit ); register_new_node( limit, opaq_ctrl ); } if (stride_con > 0 && ((limit_type->_lo - stride_con) < limit_type->_lo) || stride_con < 0 && ((limit_type->_hi - stride_con) > limit_type->_hi)) { // No underflow. - new_limit = new (C, 3) SubINode(limit, stride); + new_limit = new (C) SubINode(limit, stride); } else { // (limit - stride) may underflow. // Clamp the adjustment value with MININT or MAXINT: @@ -1293,18 +1293,18 @@ old_limit = bol->in(1)->in(1); // Adjust previous adjusted limit. adj_limit = limit->in(CMoveNode::IfFalse); - adj_limit = new (C, 3) SubINode(adj_limit, stride); + adj_limit = new (C) SubINode(adj_limit, stride); } else { old_limit = limit; - adj_limit = new (C, 3) SubINode(limit, stride); + adj_limit = new (C) SubINode(limit, stride); } assert(old_limit != NULL && adj_limit != NULL, ""); register_new_node( adj_limit, ctrl ); // adjust amount - Node* adj_cmp = new (C, 3) CmpINode(old_limit, adj_limit); + Node* adj_cmp = new (C) CmpINode(old_limit, adj_limit); register_new_node( adj_cmp, ctrl ); - Node* adj_bool = new (C, 2) BoolNode(adj_cmp, bt); + Node* adj_bool = new (C) BoolNode(adj_cmp, bt); register_new_node( adj_bool, ctrl ); - new_limit = new (C, 4) CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT); + new_limit = new (C) CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT); } register_new_node(new_limit, ctrl); } @@ -1366,24 +1366,24 @@ // CountedLoop this is exact (stride divides limit-init exactly). // We are going to double the loop body, so we want to knock off any // odd iteration: (trip_cnt & ~1). Then back compute a new limit. - Node *span = new (C, 3) SubINode( limit, init ); + Node *span = new (C) SubINode( limit, init ); register_new_node( span, ctrl ); - Node *trip = new (C, 3) DivINode( 0, span, stride ); + Node *trip = new (C) DivINode( 0, span, stride ); register_new_node( trip, ctrl ); Node *mtwo = _igvn.intcon(-2); set_ctrl(mtwo, C->root()); - Node *rond = new (C, 3) AndINode( trip, mtwo ); + Node *rond = new (C) AndINode( trip, mtwo ); register_new_node( rond, ctrl ); - Node *spn2 = new (C, 3) MulINode( rond, stride ); + Node *spn2 = new (C) MulINode( rond, stride ); register_new_node( spn2, ctrl ); - new_limit = new (C, 3) AddINode( spn2, init ); + new_limit = new (C) AddINode( spn2, init ); register_new_node( new_limit, ctrl ); // Hammer in the new limit Node *ctrl2 = loop_end->in(0); - Node *cmp2 = new (C, 3) CmpINode( loop_head->incr(), new_limit ); + Node *cmp2 = new (C) CmpINode( loop_head->incr(), new_limit ); register_new_node( cmp2, ctrl2 ); - Node *bol2 = new (C, 2) BoolNode( cmp2, loop_end->test_trip() ); + Node *bol2 = new (C) BoolNode( cmp2, loop_end->test_trip() ); register_new_node( bol2, ctrl2 ); _igvn.hash_delete(loop_end); loop_end->set_req(CountedLoopEndNode::TestValue, bol2); @@ -1489,15 +1489,15 @@ // Helper function for add_constraint(). Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl) { // Compute "I :: (limit-offset)/scale" - Node *con = new (C, 3) SubINode(rc_limit, offset); + Node *con = new (C) SubINode(rc_limit, offset); register_new_node(con, pre_ctrl); - Node *X = new (C, 3) DivINode(0, con, scale); + Node *X = new (C) DivINode(0, con, scale); register_new_node(X, pre_ctrl); // Adjust loop limit loop_limit = (stride_con > 0) - ? (Node*)(new (C, 3) MinINode(loop_limit, X)) - : (Node*)(new (C, 3) MaxINode(loop_limit, X)); + ? (Node*)(new (C) MinINode(loop_limit, X)) + : (Node*)(new (C) MaxINode(loop_limit, X)); register_new_node(loop_limit, pre_ctrl); return loop_limit; } @@ -1558,9 +1558,9 @@ // to avoid problem with scale == -1 (min_int/(-1) == min_int). Node* shift = _igvn.intcon(31); set_ctrl(shift, C->root()); - Node* sign = new (C, 3) RShiftINode(offset, shift); + Node* sign = new (C) RShiftINode(offset, shift); register_new_node(sign, pre_ctrl); - offset = new (C, 3) AndINode(offset, sign); + offset = new (C) AndINode(offset, sign); register_new_node(offset, pre_ctrl); } else { assert(low_limit->get_int() == 0, "wrong low limit for range check"); @@ -1593,7 +1593,7 @@ Node *one = _igvn.intcon(1); set_ctrl(one, C->root()); - Node *plus_one = new (C, 3) AddINode(offset, one); + Node *plus_one = new (C) AddINode(offset, one); register_new_node( plus_one, pre_ctrl ); // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond); *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl); @@ -1611,9 +1611,9 @@ // to avoid problem with scale == -1 (min_int/(-1) == min_int). Node* shift = _igvn.intcon(31); set_ctrl(shift, C->root()); - Node* sign = new (C, 3) RShiftINode(plus_one, shift); + Node* sign = new (C) RShiftINode(plus_one, shift); register_new_node(sign, pre_ctrl); - plus_one = new (C, 3) AndINode(plus_one, sign); + plus_one = new (C) AndINode(plus_one, sign); register_new_node(plus_one, pre_ctrl); } else { assert(low_limit->get_int() == 0, "wrong low limit for range check"); @@ -1696,7 +1696,7 @@ p_offset != NULL ? &offset2 : NULL, depth+1)) { if (p_offset != NULL) { Node *ctrl_off2 = get_ctrl(offset2); - Node* offset = new (C, 3) AddINode(offset2, exp->in(2)); + Node* offset = new (C) AddINode(offset2, exp->in(2)); register_new_node(offset, ctrl_off2); *p_offset = offset; } @@ -1709,7 +1709,7 @@ Node *zero = _igvn.intcon(0); set_ctrl(zero, C->root()); Node *ctrl_off = get_ctrl(exp->in(2)); - Node* offset = new (C, 3) SubINode(zero, exp->in(2)); + Node* offset = new (C) SubINode(zero, exp->in(2)); register_new_node(offset, ctrl_off); *p_offset = offset; } @@ -1912,15 +1912,15 @@ case BoolTest::ge: // Convert (I*scale+offset) >= Limit to (I*(-scale)+(-offset)) <= -Limit scale_con = -scale_con; - offset = new (C, 3) SubINode( zero, offset ); + offset = new (C) SubINode( zero, offset ); register_new_node( offset, pre_ctrl ); - limit = new (C, 3) SubINode( zero, limit ); + limit = new (C) SubINode( zero, limit ); register_new_node( limit, pre_ctrl ); // Fall into LE case case BoolTest::le: if (b_test._test != BoolTest::gt) { // Convert X <= Y to X < Y+1 - limit = new (C, 3) AddINode( limit, one ); + limit = new (C) AddINode( limit, one ); register_new_node( limit, pre_ctrl ); } // Fall into LT case @@ -1971,8 +1971,8 @@ // Update loop limits if (conditional_rc) { - pre_limit = (stride_con > 0) ? (Node*)new (C,3) MinINode(pre_limit, orig_limit) - : (Node*)new (C,3) MaxINode(pre_limit, orig_limit); + pre_limit = (stride_con > 0) ? (Node*)new (C) MinINode(pre_limit, orig_limit) + : (Node*)new (C) MaxINode(pre_limit, orig_limit); register_new_node(pre_limit, pre_ctrl); } _igvn.hash_delete(pre_opaq); @@ -1987,16 +1987,16 @@ Node *ctrl = get_ctrl(main_limit); Node *stride = cl->stride(); Node *init = cl->init_trip(); - Node *span = new (C, 3) SubINode(main_limit,init); + Node *span = new (C) SubINode(main_limit,init); register_new_node(span,ctrl); Node *rndup = _igvn.intcon(stride_con + ((stride_con>0)?-1:1)); - Node *add = new (C, 3) AddINode(span,rndup); + Node *add = new (C) AddINode(span,rndup); register_new_node(add,ctrl); - Node *div = new (C, 3) DivINode(0,add,stride); + Node *div = new (C) DivINode(0,add,stride); register_new_node(div,ctrl); - Node *mul = new (C, 3) MulINode(div,stride); + Node *mul = new (C) MulINode(div,stride); register_new_node(mul,ctrl); - Node *newlim = new (C, 3) AddINode(mul,init); + Node *newlim = new (C) AddINode(mul,init); register_new_node(newlim,ctrl); main_limit = newlim; } @@ -2167,7 +2167,7 @@ } // Note: the final value after increment should not overflow since // counted loop has limit check predicate. - Node *final = new (phase->C, 3) SubINode( exact_limit, cl->stride() ); + Node *final = new (phase->C) SubINode( exact_limit, cl->stride() ); phase->register_new_node(final,cl->in(LoopNode::EntryControl)); phase->_igvn.replace_node(phi,final); phase->C->set_major_progress(); @@ -2651,20 +2651,20 @@ // Build an expression for the beginning of the copy region Node* index = head->init_trip(); #ifdef _LP64 - index = new (C, 2) ConvI2LNode(index); + index = new (C) ConvI2LNode(index); _igvn.register_new_node_with_optimizer(index); #endif if (shift != NULL) { // byte arrays don't require a shift but others do. - index = new (C, 3) LShiftXNode(index, shift->in(2)); + index = new (C) LShiftXNode(index, shift->in(2)); _igvn.register_new_node_with_optimizer(index); } - index = new (C, 4) AddPNode(base, base, index); + index = new (C) AddPNode(base, base, index); _igvn.register_new_node_with_optimizer(index); - Node* from = new (C, 4) AddPNode(base, index, offset); + Node* from = new (C) AddPNode(base, index, offset); _igvn.register_new_node_with_optimizer(from); // Compute the number of elements to copy - Node* len = new (C, 3) SubINode(head->limit(), head->init_trip()); + Node* len = new (C) SubINode(head->limit(), head->init_trip()); _igvn.register_new_node_with_optimizer(len); BasicType t = store->as_Mem()->memory_type(); @@ -2681,10 +2681,10 @@ // Convert float/double to int/long for fill routines if (t == T_FLOAT) { - store_value = new (C, 2) MoveF2INode(store_value); + store_value = new (C) MoveF2INode(store_value); _igvn.register_new_node_with_optimizer(store_value); } else if (t == T_DOUBLE) { - store_value = new (C, 2) MoveD2LNode(store_value); + store_value = new (C) MoveD2LNode(store_value); _igvn.register_new_node_with_optimizer(store_value); } @@ -2692,13 +2692,12 @@ Node* result_ctrl; Node* result_mem; const TypeFunc* call_type = OptoRuntime::array_fill_Type(); - int size = call_type->domain()->cnt(); - CallLeafNode *call = new (C, size) CallLeafNoFPNode(call_type, fill, - fill_name, TypeAryPtr::get_array_body_type(t)); + CallLeafNode *call = new (C) CallLeafNoFPNode(call_type, fill, + fill_name, TypeAryPtr::get_array_body_type(t)); call->init_req(TypeFunc::Parms+0, from); call->init_req(TypeFunc::Parms+1, store_value); #ifdef _LP64 - len = new (C, 2) ConvI2LNode(len); + len = new (C) ConvI2LNode(len); _igvn.register_new_node_with_optimizer(len); #endif call->init_req(TypeFunc::Parms+2, len); @@ -2711,9 +2710,9 @@ call->init_req( TypeFunc::ReturnAdr, C->start()->proj_out(TypeFunc::ReturnAdr) ); call->init_req( TypeFunc::FramePtr, C->start()->proj_out(TypeFunc::FramePtr) ); _igvn.register_new_node_with_optimizer(call); - result_ctrl = new (C, 1) ProjNode(call,TypeFunc::Control); + result_ctrl = new (C) ProjNode(call,TypeFunc::Control); _igvn.register_new_node_with_optimizer(result_ctrl); - result_mem = new (C, 1) ProjNode(call,TypeFunc::Memory); + result_mem = new (C) ProjNode(call,TypeFunc::Memory); _igvn.register_new_node_with_optimizer(result_mem); // If this fill is tightly coupled to an allocation and overwrites diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/loopUnswitch.cpp --- a/src/share/vm/opto/loopUnswitch.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/loopUnswitch.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -223,15 +223,15 @@ Node *cont = _igvn.intcon(1); set_ctrl(cont, C->root()); - Node* opq = new (C, 2) Opaque1Node(C, cont); + Node* opq = new (C) Opaque1Node(C, cont); register_node(opq, outer_loop, entry, dom_depth(entry)); - Node *bol = new (C, 2) Conv2BNode(opq); + Node *bol = new (C) Conv2BNode(opq); register_node(bol, outer_loop, entry, dom_depth(entry)); - IfNode* iff = new (C, 2) IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN); + IfNode* iff = new (C) IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN); register_node(iff, outer_loop, entry, dom_depth(entry)); - ProjNode* iffast = new (C, 1) IfTrueNode(iff); + ProjNode* iffast = new (C) IfTrueNode(iff); register_node(iffast, outer_loop, iff, dom_depth(iff)); - ProjNode* ifslow = new (C, 1) IfFalseNode(iff); + ProjNode* ifslow = new (C) IfFalseNode(iff); register_node(ifslow, outer_loop, iff, dom_depth(iff)); // Clone the loop body. The clone becomes the fast loop. The diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/loopnode.cpp --- a/src/share/vm/opto/loopnode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/loopnode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -343,7 +343,7 @@ assert(x->Opcode() == Op_Loop, "regular loops only"); C->print_method("Before CountedLoop", 3); - Node *hook = new (C, 6) Node(6); + Node *hook = new (C) Node(6); if (LoopLimitCheck) { @@ -406,11 +406,11 @@ Node* bol; if (stride_con > 0) { - cmp_limit = new (C, 3) CmpINode(limit, _igvn.intcon(max_jint - stride_m)); - bol = new (C, 2) BoolNode(cmp_limit, BoolTest::le); + cmp_limit = new (C) CmpINode(limit, _igvn.intcon(max_jint - stride_m)); + bol = new (C) BoolNode(cmp_limit, BoolTest::le); } else { - cmp_limit = new (C, 3) CmpINode(limit, _igvn.intcon(min_jint - stride_m)); - bol = new (C, 2) BoolNode(cmp_limit, BoolTest::ge); + cmp_limit = new (C) CmpINode(limit, _igvn.intcon(min_jint - stride_m)); + bol = new (C) BoolNode(cmp_limit, BoolTest::ge); } cmp_limit = _igvn.register_new_node_with_optimizer(cmp_limit); bol = _igvn.register_new_node_with_optimizer(bol); @@ -447,7 +447,7 @@ // is converted to // i = init; do {} while(++i < limit+1); // - limit = gvn->transform(new (C, 3) AddINode(limit, stride)); + limit = gvn->transform(new (C) AddINode(limit, stride)); } // Now we need to canonicalize loop condition. @@ -466,7 +466,7 @@ // we can convert 'i <= limit' to 'i < limit+1' since stride != 0. // Node* one = (stride_con > 0) ? gvn->intcon( 1) : gvn->intcon(-1); - limit = gvn->transform(new (C, 3) AddINode(limit, one)); + limit = gvn->transform(new (C) AddINode(limit, one)); if (bt == BoolTest::le) bt = BoolTest::lt; else if (bt == BoolTest::ge) @@ -482,7 +482,7 @@ // can directly point to the phi; in this case adjust the compare so that // it points to the incr by adjusting the limit. if (cmp->in(1) == phi || cmp->in(2) == phi) - limit = gvn->transform(new (C, 3) AddINode(limit,stride)); + limit = gvn->transform(new (C) AddINode(limit,stride)); // trip-count for +-tive stride should be: (limit - init_trip + stride - 1)/stride. // Final value for iterator should be: trip_count * stride + init_trip. @@ -495,16 +495,16 @@ ShouldNotReachHere(); case BoolTest::ne: // Ahh, the case we desire if (stride_con == 1) - trip_count = gvn->transform(new (C, 3) SubINode(limit,init_trip)); + trip_count = gvn->transform(new (C) SubINode(limit,init_trip)); else if (stride_con == -1) - trip_count = gvn->transform(new (C, 3) SubINode(init_trip,limit)); + trip_count = gvn->transform(new (C) SubINode(init_trip,limit)); else ShouldNotReachHere(); set_subtree_ctrl(trip_count); //_loop.map(trip_count->_idx,loop(limit)); break; case BoolTest::le: // Maybe convert to '<' case - limit = gvn->transform(new (C, 3) AddINode(limit,one_p)); + limit = gvn->transform(new (C) AddINode(limit,one_p)); set_subtree_ctrl( limit ); hook->init_req(4, limit); @@ -515,26 +515,26 @@ case BoolTest::lt: { // Maybe convert to '!=' case if (stride_con < 0) // Count down loop rolls through MAXINT ShouldNotReachHere(); - Node *range = gvn->transform(new (C, 3) SubINode(limit,init_trip)); + Node *range = gvn->transform(new (C) SubINode(limit,init_trip)); set_subtree_ctrl( range ); hook->init_req(0, range); - Node *bias = gvn->transform(new (C, 3) AddINode(range,stride)); + Node *bias = gvn->transform(new (C) AddINode(range,stride)); set_subtree_ctrl( bias ); hook->init_req(1, bias); - Node *bias1 = gvn->transform(new (C, 3) AddINode(bias,one_m)); + Node *bias1 = gvn->transform(new (C) AddINode(bias,one_m)); set_subtree_ctrl( bias1 ); hook->init_req(2, bias1); - trip_count = gvn->transform(new (C, 3) DivINode(0,bias1,stride)); + trip_count = gvn->transform(new (C) DivINode(0,bias1,stride)); set_subtree_ctrl( trip_count ); hook->init_req(3, trip_count); break; } case BoolTest::ge: // Maybe convert to '>' case - limit = gvn->transform(new (C, 3) AddINode(limit,one_m)); + limit = gvn->transform(new (C) AddINode(limit,one_m)); set_subtree_ctrl( limit ); hook->init_req(4 ,limit); @@ -545,30 +545,30 @@ case BoolTest::gt: { // Maybe convert to '!=' case if (stride_con > 0) // count up loop rolls through MININT ShouldNotReachHere(); - Node *range = gvn->transform(new (C, 3) SubINode(limit,init_trip)); + Node *range = gvn->transform(new (C) SubINode(limit,init_trip)); set_subtree_ctrl( range ); hook->init_req(0, range); - Node *bias = gvn->transform(new (C, 3) AddINode(range,stride)); + Node *bias = gvn->transform(new (C) AddINode(range,stride)); set_subtree_ctrl( bias ); hook->init_req(1, bias); - Node *bias1 = gvn->transform(new (C, 3) AddINode(bias,one_p)); + Node *bias1 = gvn->transform(new (C) AddINode(bias,one_p)); set_subtree_ctrl( bias1 ); hook->init_req(2, bias1); - trip_count = gvn->transform(new (C, 3) DivINode(0,bias1,stride)); + trip_count = gvn->transform(new (C) DivINode(0,bias1,stride)); set_subtree_ctrl( trip_count ); hook->init_req(3, trip_count); break; } } // switch( bt ) - Node *span = gvn->transform(new (C, 3) MulINode(trip_count,stride)); + Node *span = gvn->transform(new (C) MulINode(trip_count,stride)); set_subtree_ctrl( span ); hook->init_req(5, span); - limit = gvn->transform(new (C, 3) AddINode(span,init_trip)); + limit = gvn->transform(new (C) AddINode(span,init_trip)); set_subtree_ctrl( limit ); } // LoopLimitCheck @@ -617,7 +617,7 @@ set_ctrl(test, iff->in(0)); // Replace the old IfNode with a new LoopEndNode - Node *lex = _igvn.register_new_node_with_optimizer(new (C, 2) CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt )); + Node *lex = _igvn.register_new_node_with_optimizer(new (C) CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt )); IfNode *le = lex->as_If(); uint dd = dom_depth(iff); set_idom(le, le->in(0), dd); // Update dominance for loop exit @@ -628,8 +628,8 @@ // Need to swap loop-exit and loop-back control? if (iftrue_op == Op_IfFalse) { - Node *ift2=_igvn.register_new_node_with_optimizer(new (C, 1) IfTrueNode (le)); - Node *iff2=_igvn.register_new_node_with_optimizer(new (C, 1) IfFalseNode(le)); + Node *ift2=_igvn.register_new_node_with_optimizer(new (C) IfTrueNode (le)); + Node *iff2=_igvn.register_new_node_with_optimizer(new (C) IfFalseNode(le)); loop->_tail = back_control = ift2; set_loop(ift2, loop); @@ -655,7 +655,7 @@ lazy_replace( iff, le ); // fix 'get_ctrl' // Now setup a new CountedLoopNode to replace the existing LoopNode - CountedLoopNode *l = new (C, 3) CountedLoopNode(init_control, back_control); + CountedLoopNode *l = new (C) CountedLoopNode(init_control, back_control); l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve // The following assert is approximately true, and defines the intention // of can_be_counted_loop. It fails, however, because phase->type @@ -729,7 +729,7 @@ limit = _igvn.intcon(final_int); } else { // Create new LoopLimit node to get exact limit (final iv value). - limit = new (C, 4) LoopLimitNode(C, cl->init_trip(), cl->limit(), cl->stride()); + limit = new (C) LoopLimitNode(C, cl->init_trip(), cl->limit(), cl->stride()); register_new_node(limit, cl->in(LoopNode::EntryControl)); } assert(limit != NULL, "sanity"); @@ -846,11 +846,11 @@ if (range <= max) { // Convert to integer expression if it is not overflow. Node* stride_m = phase->intcon(stride_con - (stride_con > 0 ? 1 : -1)); - Node *range = phase->transform(new (phase->C, 3) SubINode(in(Limit), in(Init))); - Node *bias = phase->transform(new (phase->C, 3) AddINode(range, stride_m)); - Node *trip = phase->transform(new (phase->C, 3) DivINode(0, bias, in(Stride))); - Node *span = phase->transform(new (phase->C, 3) MulINode(trip, in(Stride))); - return new (phase->C, 3) AddINode(span, in(Init)); // exact limit + Node *range = phase->transform(new (phase->C) SubINode(in(Limit), in(Init))); + Node *bias = phase->transform(new (phase->C) AddINode(range, stride_m)); + Node *trip = phase->transform(new (phase->C) DivINode(0, bias, in(Stride))); + Node *span = phase->transform(new (phase->C) MulINode(trip, in(Stride))); + return new (phase->C) AddINode(span, in(Init)); // exact limit } if (is_power_of_2(stride_p) || // divisor is 2^n @@ -858,13 +858,13 @@ // Convert to long expression to avoid integer overflow // and let igvn optimizer convert this division. // - Node* init = phase->transform( new (phase->C, 2) ConvI2LNode(in(Init))); - Node* limit = phase->transform( new (phase->C, 2) ConvI2LNode(in(Limit))); + Node* init = phase->transform( new (phase->C) ConvI2LNode(in(Init))); + Node* limit = phase->transform( new (phase->C) ConvI2LNode(in(Limit))); Node* stride = phase->longcon(stride_con); Node* stride_m = phase->longcon(stride_con - (stride_con > 0 ? 1 : -1)); - Node *range = phase->transform(new (phase->C, 3) SubLNode(limit, init)); - Node *bias = phase->transform(new (phase->C, 3) AddLNode(range, stride_m)); + Node *range = phase->transform(new (phase->C) SubLNode(limit, init)); + Node *bias = phase->transform(new (phase->C) AddLNode(range, stride_m)); Node *span; if (stride_con > 0 && is_power_of_2(stride_p)) { // bias >= 0 if stride >0, so if stride is 2^n we can use &(-stride) @@ -875,14 +875,14 @@ // only RCE predicate where exact limit is used and the predicate // will simply fail forcing recompilation. Node* neg_stride = phase->longcon(-stride_con); - span = phase->transform(new (phase->C, 3) AndLNode(bias, neg_stride)); + span = phase->transform(new (phase->C) AndLNode(bias, neg_stride)); } else { - Node *trip = phase->transform(new (phase->C, 3) DivLNode(0, bias, stride)); - span = phase->transform(new (phase->C, 3) MulLNode(trip, stride)); + Node *trip = phase->transform(new (phase->C) DivLNode(0, bias, stride)); + span = phase->transform(new (phase->C) MulLNode(trip, stride)); } // Convert back to int - Node *span_int = phase->transform(new (phase->C, 2) ConvL2INode(span)); - return new (phase->C, 3) AddINode(span_int, in(Init)); // exact limit + Node *span_int = phase->transform(new (phase->C) ConvL2INode(span)); + return new (phase->C) AddINode(span_int, in(Init)); // exact limit } return NULL; // No progress @@ -1088,7 +1088,7 @@ uint i; // Make a new RegionNode to be the landing pad. - Node *landing_pad = new (phase->C, fall_in_cnt+1) RegionNode( fall_in_cnt+1 ); + Node *landing_pad = new (phase->C) RegionNode( fall_in_cnt+1 ); phase->set_loop(landing_pad,_parent); // Gather all the fall-in control paths into the landing pad uint icnt = fall_in_cnt; @@ -1174,7 +1174,7 @@ // Make a LoopNode for the outermost loop. Node *ctl = _head->in(LoopNode::EntryControl); - Node *outer = new (phase->C, 3) LoopNode( ctl, _head->in(outer_idx) ); + Node *outer = new (phase->C) LoopNode( ctl, _head->in(outer_idx) ); outer = igvn.register_new_node_with_optimizer(outer, _head); phase->set_created_loop_node(); @@ -1288,7 +1288,7 @@ Node *hot_tail = NULL; // Make a Region for the merge point - Node *r = new (phase->C, 1) RegionNode(1); + Node *r = new (phase->C) RegionNode(1); for( i = 2; i < _head->req(); i++ ) { if( i != hot_idx ) r->add_req( _head->in(i) ); @@ -1307,7 +1307,7 @@ PhiNode* n = out->as_Phi(); igvn.hash_delete(n); // Delete from hash before hacking edges Node *hot_phi = NULL; - Node *phi = new (phase->C, r->req()) PhiNode(r, n->type(), n->adr_type()); + Node *phi = new (phase->C) PhiNode(r, n->type(), n->adr_type()); // Check all inputs for the ones to peel out uint j = 1; for( uint i = 2; i < n->req(); i++ ) { @@ -1429,7 +1429,7 @@ } else if( !_head->is_Loop() && !_irreducible ) { // Make a new LoopNode to replace the old loop head - Node *l = new (phase->C, 3) LoopNode( _head->in(1), _head->in(2) ); + Node *l = new (phase->C) LoopNode( _head->in(1), _head->in(2) ); l = igvn.register_new_node_with_optimizer(l, _head); phase->set_created_loop_node(); // Go ahead and replace _head @@ -1671,16 +1671,16 @@ // It is scaled by the 'ratio_con'. Node* ratio = _igvn.intcon(ratio_con); set_ctrl(ratio, C->root()); - Node* ratio_init = new (C, 3) MulINode(init, ratio); + Node* ratio_init = new (C) MulINode(init, ratio); _igvn.register_new_node_with_optimizer(ratio_init, init); set_early_ctrl(ratio_init); - Node* diff = new (C, 3) SubINode(init2, ratio_init); + Node* diff = new (C) SubINode(init2, ratio_init); _igvn.register_new_node_with_optimizer(diff, init2); set_early_ctrl(diff); - Node* ratio_idx = new (C, 3) MulINode(phi, ratio); + Node* ratio_idx = new (C) MulINode(phi, ratio); _igvn.register_new_node_with_optimizer(ratio_idx, phi); set_ctrl(ratio_idx, cl); - Node* add = new (C, 3) AddINode(ratio_idx, diff); + Node* add = new (C) AddINode(ratio_idx, diff); _igvn.register_new_node_with_optimizer(add); set_ctrl(add, cl); _igvn.replace_node( phi2, add ); @@ -2677,10 +2677,10 @@ if (!_verify_only) { // Insert the NeverBranch between 'm' and it's control user. - NeverBranchNode *iff = new (C, 1) NeverBranchNode( m ); + NeverBranchNode *iff = new (C) NeverBranchNode( m ); _igvn.register_new_node_with_optimizer(iff); set_loop(iff, l); - Node *if_t = new (C, 1) CProjNode( iff, 0 ); + Node *if_t = new (C) CProjNode( iff, 0 ); _igvn.register_new_node_with_optimizer(if_t); set_loop(if_t, l); @@ -2696,16 +2696,16 @@ cfg->set_req( k, if_t ); // Now point to NeverBranch // Now create the never-taken loop exit - Node *if_f = new (C, 1) CProjNode( iff, 1 ); + Node *if_f = new (C) CProjNode( iff, 1 ); _igvn.register_new_node_with_optimizer(if_f); set_loop(if_f, l); // Find frame ptr for Halt. Relies on the optimizer // V-N'ing. Easier and quicker than searching through // the program structure. - Node *frame = new (C, 1) ParmNode( C->start(), TypeFunc::FramePtr ); + Node *frame = new (C) ParmNode( C->start(), TypeFunc::FramePtr ); _igvn.register_new_node_with_optimizer(frame); // Halt & Catch Fire - Node *halt = new (C, TypeFunc::Parms) HaltNode( if_f, frame ); + Node *halt = new (C) HaltNode( if_f, frame ); _igvn.register_new_node_with_optimizer(halt); set_loop(halt, l); C->root()->add_req(halt); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/loopopts.cpp --- a/src/share/vm/opto/loopopts.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/loopopts.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -53,7 +53,7 @@ int iid = t_oop->instance_id(); int index = C->get_alias_index(t_oop); int offset = t_oop->offset(); - phi = new (C,region->req()) PhiNode(region, type, NULL, iid, index, offset); + phi = new (C) PhiNode(region, type, NULL, iid, index, offset); } else { phi = PhiNode::make_blank(region, n); } @@ -356,9 +356,9 @@ _igvn.type( add->in(1) ) != TypeInt::ZERO ) { Node *zero = _igvn.intcon(0); set_ctrl(zero, C->root()); - Node *neg = new (C, 3) SubINode( _igvn.intcon(0), add->in(2) ); + Node *neg = new (C) SubINode( _igvn.intcon(0), add->in(2) ); register_new_node( neg, get_ctrl(add->in(2) ) ); - add = new (C, 3) AddINode( add->in(1), neg ); + add = new (C) AddINode( add->in(1), neg ); register_new_node( add, add_ctrl ); } if( add->Opcode() != Op_AddI ) return NULL; @@ -384,14 +384,14 @@ return NULL; // No invariant part of the add? // Yes! Reshape address expression! - Node *inv_scale = new (C, 3) LShiftINode( add_invar, scale ); + Node *inv_scale = new (C) LShiftINode( add_invar, scale ); Node *inv_scale_ctrl = dom_depth(add_invar_ctrl) > dom_depth(scale_ctrl) ? add_invar_ctrl : scale_ctrl; register_new_node( inv_scale, inv_scale_ctrl ); - Node *var_scale = new (C, 3) LShiftINode( add_var, scale ); + Node *var_scale = new (C) LShiftINode( add_var, scale ); register_new_node( var_scale, n_ctrl ); - Node *var_add = new (C, 3) AddINode( var_scale, inv_scale ); + Node *var_add = new (C) AddINode( var_scale, inv_scale ); register_new_node( var_add, n_ctrl ); _igvn.replace_node( n, var_add ); return var_add; @@ -423,10 +423,10 @@ IdealLoopTree *n23_loop = get_loop( n23_ctrl ); if( n22loop != n_loop && n22loop->is_member(n_loop) && n23_loop == n_loop ) { - Node *add1 = new (C, 4) AddPNode( n->in(1), n->in(2)->in(2), n->in(3) ); + Node *add1 = new (C) AddPNode( n->in(1), n->in(2)->in(2), n->in(3) ); // Stuff new AddP in the loop preheader register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) ); - Node *add2 = new (C, 4) AddPNode( n->in(1), add1, n->in(2)->in(3) ); + Node *add2 = new (C) AddPNode( n->in(1), add1, n->in(2)->in(3) ); register_new_node( add2, n_ctrl ); _igvn.replace_node( n, add2 ); return add2; @@ -444,10 +444,10 @@ Node *tmp = V; V = I; I = tmp; } if( !is_member(n_loop,get_ctrl(I)) ) { - Node *add1 = new (C, 4) AddPNode( n->in(1), n->in(2), I ); + Node *add1 = new (C) AddPNode( n->in(1), n->in(2), I ); // Stuff new AddP in the loop preheader register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) ); - Node *add2 = new (C, 4) AddPNode( n->in(1), add1, V ); + Node *add2 = new (C) AddPNode( n->in(1), add1, V ); register_new_node( add2, n_ctrl ); _igvn.replace_node( n, add2 ); return add2; @@ -1094,9 +1094,8 @@ Node *sample_cmp = sample_bool->in(1); // Make Phis to merge the Cmp's inputs. - int size = phi->in(0)->req(); - PhiNode *phi1 = new (C, size) PhiNode( phi->in(0), Type::TOP ); - PhiNode *phi2 = new (C, size) PhiNode( phi->in(0), Type::TOP ); + PhiNode *phi1 = new (C) PhiNode( phi->in(0), Type::TOP ); + PhiNode *phi2 = new (C) PhiNode( phi->in(0), Type::TOP ); for( i = 1; i < phi->req(); i++ ) { Node *n1 = phi->in(i)->in(1)->in(1); Node *n2 = phi->in(i)->in(1)->in(2); @@ -1163,9 +1162,8 @@ Node *sample_cmp = phi->in(1); // Make Phis to merge the Cmp's inputs. - int size = phi->in(0)->req(); - PhiNode *phi1 = new (C, size) PhiNode( phi->in(0), Type::TOP ); - PhiNode *phi2 = new (C, size) PhiNode( phi->in(0), Type::TOP ); + PhiNode *phi1 = new (C) PhiNode( phi->in(0), Type::TOP ); + PhiNode *phi2 = new (C) PhiNode( phi->in(0), Type::TOP ); for( uint j = 1; j < phi->req(); j++ ) { Node *cmp_top = phi->in(j); // Inputs are all Cmp or TOP Node *n1, *n2; @@ -1329,7 +1327,7 @@ // We need a Region to merge the exit from the peeled body and the // exit from the old loop body. - RegionNode *r = new (C, 3) RegionNode(3); + RegionNode *r = new (C) RegionNode(3); // Map the old use to the new merge point old_new.map( use->_idx, r ); uint dd_r = MIN2(dom_depth(newuse),dom_depth(use)); @@ -1675,13 +1673,13 @@ ProjNode* proj2 = proj_clone(proj, iff); register_node(proj2, loop, iff, ddepth); - Node* cmp = Signed ? (Node*) new (C,3)CmpINode(left, right) : (Node*) new (C,3)CmpUNode(left, right); + Node* cmp = Signed ? (Node*) new (C)CmpINode(left, right) : (Node*) new (C)CmpUNode(left, right); register_node(cmp, loop, proj2, ddepth); - BoolNode* bol = new (C,2)BoolNode(cmp, relop); + BoolNode* bol = new (C)BoolNode(cmp, relop); register_node(bol, loop, proj2, ddepth); - IfNode* new_if = new (C,2)IfNode(proj2, bol, iff->_prob, iff->_fcnt); + IfNode* new_if = new (C)IfNode(proj2, bol, iff->_prob, iff->_fcnt); register_node(new_if, loop, proj2, ddepth); proj->set_req(0, new_if); // reattach @@ -1732,11 +1730,11 @@ ProjNode* proj2 = proj_clone(proj, iff); register_node(proj2, loop, iff, ddepth); - RegionNode* reg = new (C,2)RegionNode(2); + RegionNode* reg = new (C)RegionNode(2); reg->set_req(1, proj2); register_node(reg, loop, iff, ddepth); - IfNode* dum_if = new (C,2)IfNode(reg, short_circuit_if(NULL, proj), iff->_prob, iff->_fcnt); + IfNode* dum_if = new (C)IfNode(reg, short_circuit_if(NULL, proj), iff->_prob, iff->_fcnt); register_node(dum_if, loop, reg, ddepth); proj->set_req(0, dum_if); // reattach @@ -2547,7 +2545,7 @@ // Create new loop head for new phis and to hang // the nodes being moved (sinked) from the peel region. - LoopNode* new_head = new (C, 3) LoopNode(last_peel, last_peel); + LoopNode* new_head = new (C) LoopNode(last_peel, last_peel); new_head->set_unswitch_count(head->unswitch_count()); // Preserve _igvn.register_new_node_with_optimizer(new_head); assert(first_not_peeled->in(0) == last_peel, "last_peel <- first_not_peeled"); @@ -2746,11 +2744,11 @@ if (dom_lca(exit, u_ctrl) != exit) continue; // Hit! Refactor use to use the post-incremented tripcounter. // Compute a post-increment tripcounter. - Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() ); + Node *opaq = new (C) Opaque2Node( C, cle->incr() ); register_new_node( opaq, u_ctrl ); Node *neg_stride = _igvn.intcon(-cle->stride_con()); set_ctrl(neg_stride, C->root()); - Node *post = new (C, 3) AddINode( opaq, neg_stride); + Node *post = new (C) AddINode( opaq, neg_stride); register_new_node( post, u_ctrl ); _igvn.rehash_node_delayed(use); for (uint j = 1; j < use->req(); j++) { diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/macro.cpp --- a/src/share/vm/opto/macro.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/macro.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -103,20 +103,20 @@ Node* PhaseMacroExpand::opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path) { Node* cmp; if (mask != 0) { - Node* and_node = transform_later(new (C, 3) AndXNode(word, MakeConX(mask))); - cmp = transform_later(new (C, 3) CmpXNode(and_node, MakeConX(bits))); + Node* and_node = transform_later(new (C) AndXNode(word, MakeConX(mask))); + cmp = transform_later(new (C) CmpXNode(and_node, MakeConX(bits))); } else { cmp = word; } - Node* bol = transform_later(new (C, 2) BoolNode(cmp, BoolTest::ne)); - IfNode* iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN ); + Node* bol = transform_later(new (C) BoolNode(cmp, BoolTest::ne)); + IfNode* iff = new (C) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN ); transform_later(iff); // Fast path taken. - Node *fast_taken = transform_later( new (C, 1) IfFalseNode(iff) ); + Node *fast_taken = transform_later( new (C) IfFalseNode(iff) ); // Fast path not-taken, i.e. slow path - Node *slow_taken = transform_later( new (C, 1) IfTrueNode(iff) ); + Node *slow_taken = transform_later( new (C) IfTrueNode(iff) ); if (return_fast_path) { region->init_req(edge, slow_taken); // Capture slow-control @@ -141,10 +141,9 @@ CallNode* PhaseMacroExpand::make_slow_call(CallNode *oldcall, const TypeFunc* slow_call_type, address slow_call, const char* leaf_name, Node* slow_path, Node* parm0, Node* parm1) { // Slow-path call - int size = slow_call_type->domain()->cnt(); CallNode *call = leaf_name - ? (CallNode*)new (C, size) CallLeafNode ( slow_call_type, slow_call, leaf_name, TypeRawPtr::BOTTOM ) - : (CallNode*)new (C, size) CallStaticJavaNode( slow_call_type, slow_call, OptoRuntime::stub_name(slow_call), oldcall->jvms()->bci(), TypeRawPtr::BOTTOM ); + ? (CallNode*)new (C) CallLeafNode ( slow_call_type, slow_call, leaf_name, TypeRawPtr::BOTTOM ) + : (CallNode*)new (C) CallStaticJavaNode( slow_call_type, slow_call, OptoRuntime::stub_name(slow_call), oldcall->jvms()->bci(), TypeRawPtr::BOTTOM ); // Slow path call has no side-effects, uses few values copy_predefined_input_for_runtime_call(slow_path, oldcall, call ); @@ -412,7 +411,7 @@ GrowableArray values(length, length, NULL, false); // create a new Phi for the value - PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset); + PhiNode *phi = new (C) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset); transform_later(phi); value_phis->push(phi, mem->_idx); @@ -720,7 +719,7 @@ SafePointNode* sfpt = safepoints.pop(); Node* mem = sfpt->memory(); uint first_ind = sfpt->req(); - SafePointScalarObjectNode* sobj = new (C, 1) SafePointScalarObjectNode(res_type, + SafePointScalarObjectNode* sobj = new (C) SafePointScalarObjectNode(res_type, #ifdef ASSERT alloc, #endif @@ -828,7 +827,7 @@ if (field_val->is_EncodeP()) { field_val = field_val->in(1); } else { - field_val = transform_later(new (C, 2) DecodeNNode(field_val, field_val->bottom_type()->make_ptr())); + field_val = transform_later(new (C) DecodeNNode(field_val, field_val->bottom_type()->make_ptr())); } } sfpt->add_req(field_val); @@ -995,7 +994,7 @@ //---------------------------set_eden_pointers------------------------- void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) { if (UseTLAB) { // Private allocation: load from TLS - Node* thread = transform_later(new (C, 1) ThreadLocalNode()); + Node* thread = transform_later(new (C) ThreadLocalNode()); int tlab_top_offset = in_bytes(JavaThread::tlab_top_offset()); int tlab_end_offset = in_bytes(JavaThread::tlab_end_offset()); eden_top_adr = basic_plus_adr(top()/*not oop*/, thread, tlab_top_offset); @@ -1137,18 +1136,18 @@ assert (initial_slow_test == NULL || !always_slow, "arguments must be consistent"); // generate the initial test if necessary if (initial_slow_test != NULL ) { - slow_region = new (C, 3) RegionNode(3); + slow_region = new (C) RegionNode(3); // Now make the initial failure test. Usually a too-big test but // might be a TRUE for finalizers or a fancy class check for // newInstance0. - IfNode *toobig_iff = new (C, 2) IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN); + IfNode *toobig_iff = new (C) IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN); transform_later(toobig_iff); // Plug the failing-too-big test into the slow-path region - Node *toobig_true = new (C, 1) IfTrueNode( toobig_iff ); + Node *toobig_true = new (C) IfTrueNode( toobig_iff ); transform_later(toobig_true); slow_region ->init_req( too_big_or_final_path, toobig_true ); - toobig_false = new (C, 1) IfFalseNode( toobig_iff ); + toobig_false = new (C) IfFalseNode( toobig_iff ); transform_later(toobig_false); } else { // No initial test, just fall into next case toobig_false = ctrl; @@ -1181,10 +1180,10 @@ Node *eden_end = make_load(ctrl, mem, eden_end_adr, 0, TypeRawPtr::BOTTOM, T_ADDRESS); // allocate the Region and Phi nodes for the result - result_region = new (C, 3) RegionNode(3); - result_phi_rawmem = new (C, 3) PhiNode(result_region, Type::MEMORY, TypeRawPtr::BOTTOM); - result_phi_rawoop = new (C, 3) PhiNode(result_region, TypeRawPtr::BOTTOM); - result_phi_i_o = new (C, 3) PhiNode(result_region, Type::ABIO); // I/O is used for Prefetch + result_region = new (C) RegionNode(3); + result_phi_rawmem = new (C) PhiNode(result_region, Type::MEMORY, TypeRawPtr::BOTTOM); + result_phi_rawoop = new (C) PhiNode(result_region, TypeRawPtr::BOTTOM); + result_phi_i_o = new (C) PhiNode(result_region, Type::ABIO); // I/O is used for Prefetch // We need a Region for the loop-back contended case. enum { fall_in_path = 1, contended_loopback_path = 2 }; @@ -1194,8 +1193,8 @@ contended_region = toobig_false; contended_phi_rawmem = mem; } else { - contended_region = new (C, 3) RegionNode(3); - contended_phi_rawmem = new (C, 3) PhiNode(contended_region, Type::MEMORY, TypeRawPtr::BOTTOM); + contended_region = new (C) RegionNode(3); + contended_phi_rawmem = new (C) PhiNode(contended_region, Type::MEMORY, TypeRawPtr::BOTTOM); // Now handle the passing-too-big test. We fall into the contended // loop-back merge point. contended_region ->init_req(fall_in_path, toobig_false); @@ -1207,23 +1206,23 @@ // Load(-locked) the heap top. // See note above concerning the control input when using a TLAB Node *old_eden_top = UseTLAB - ? new (C, 3) LoadPNode (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM) - : new (C, 3) LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr); + ? new (C) LoadPNode (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM) + : new (C) LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr); transform_later(old_eden_top); // Add to heap top to get a new heap top - Node *new_eden_top = new (C, 4) AddPNode(top(), old_eden_top, size_in_bytes); + Node *new_eden_top = new (C) AddPNode(top(), old_eden_top, size_in_bytes); transform_later(new_eden_top); // Check for needing a GC; compare against heap end - Node *needgc_cmp = new (C, 3) CmpPNode(new_eden_top, eden_end); + Node *needgc_cmp = new (C) CmpPNode(new_eden_top, eden_end); transform_later(needgc_cmp); - Node *needgc_bol = new (C, 2) BoolNode(needgc_cmp, BoolTest::ge); + Node *needgc_bol = new (C) BoolNode(needgc_cmp, BoolTest::ge); transform_later(needgc_bol); - IfNode *needgc_iff = new (C, 2) IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN); + IfNode *needgc_iff = new (C) IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN); transform_later(needgc_iff); // Plug the failing-heap-space-need-gc test into the slow-path region - Node *needgc_true = new (C, 1) IfTrueNode(needgc_iff); + Node *needgc_true = new (C) IfTrueNode(needgc_iff); transform_later(needgc_true); if (initial_slow_test) { slow_region->init_req(need_gc_path, needgc_true); @@ -1234,7 +1233,7 @@ slow_region = needgc_true; } // No need for a GC. Setup for the Store-Conditional - Node *needgc_false = new (C, 1) IfFalseNode(needgc_iff); + Node *needgc_false = new (C) IfFalseNode(needgc_iff); transform_later(needgc_false); // Grab regular I/O before optional prefetch may change it. @@ -1254,37 +1253,37 @@ // memory state. if (UseTLAB) { Node* store_eden_top = - new (C, 4) StorePNode(needgc_false, contended_phi_rawmem, eden_top_adr, + new (C) StorePNode(needgc_false, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, new_eden_top); transform_later(store_eden_top); fast_oop_ctrl = needgc_false; // No contention, so this is the fast path fast_oop_rawmem = store_eden_top; } else { Node* store_eden_top = - new (C, 5) StorePConditionalNode(needgc_false, contended_phi_rawmem, eden_top_adr, + new (C) StorePConditionalNode(needgc_false, contended_phi_rawmem, eden_top_adr, new_eden_top, fast_oop/*old_eden_top*/); transform_later(store_eden_top); - Node *contention_check = new (C, 2) BoolNode(store_eden_top, BoolTest::ne); + Node *contention_check = new (C) BoolNode(store_eden_top, BoolTest::ne); transform_later(contention_check); - store_eden_top = new (C, 1) SCMemProjNode(store_eden_top); + store_eden_top = new (C) SCMemProjNode(store_eden_top); transform_later(store_eden_top); // If not using TLABs, check to see if there was contention. - IfNode *contention_iff = new (C, 2) IfNode (needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN); + IfNode *contention_iff = new (C) IfNode (needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN); transform_later(contention_iff); - Node *contention_true = new (C, 1) IfTrueNode(contention_iff); + Node *contention_true = new (C) IfTrueNode(contention_iff); transform_later(contention_true); // If contention, loopback and try again. contended_region->init_req(contended_loopback_path, contention_true); contended_phi_rawmem->init_req(contended_loopback_path, store_eden_top); // Fast-path succeeded with no contention! - Node *contention_false = new (C, 1) IfFalseNode(contention_iff); + Node *contention_false = new (C) IfFalseNode(contention_iff); transform_later(contention_false); fast_oop_ctrl = contention_false; // Bump total allocated bytes for this thread - Node* thread = new (C, 1) ThreadLocalNode(); + Node* thread = new (C) ThreadLocalNode(); transform_later(thread); Node* alloc_bytes_adr = basic_plus_adr(top()/*not oop*/, thread, in_bytes(JavaThread::allocated_bytes_offset())); @@ -1293,10 +1292,10 @@ #ifdef _LP64 Node* alloc_size = size_in_bytes; #else - Node* alloc_size = new (C, 2) ConvI2LNode(size_in_bytes); + Node* alloc_size = new (C) ConvI2LNode(size_in_bytes); transform_later(alloc_size); #endif - Node* new_alloc_bytes = new (C, 3) AddLNode(alloc_bytes, alloc_size); + Node* new_alloc_bytes = new (C) AddLNode(alloc_bytes, alloc_size); transform_later(new_alloc_bytes); fast_oop_rawmem = make_store(fast_oop_ctrl, store_eden_top, alloc_bytes_adr, 0, new_alloc_bytes, T_LONG); @@ -1323,9 +1322,9 @@ mb->init_req(TypeFunc::Memory, fast_oop_rawmem); mb->init_req(TypeFunc::Control, fast_oop_ctrl); - fast_oop_ctrl = new (C, 1) ProjNode(mb,TypeFunc::Control); + fast_oop_ctrl = new (C) ProjNode(mb,TypeFunc::Control); transform_later(fast_oop_ctrl); - fast_oop_rawmem = new (C, 1) ProjNode(mb,TypeFunc::Memory); + fast_oop_rawmem = new (C) ProjNode(mb,TypeFunc::Memory); transform_later(fast_oop_rawmem); } else { // Add the MemBarStoreStore after the InitializeNode so that @@ -1339,9 +1338,9 @@ MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot); transform_later(mb); - Node* ctrl = new (C, 1) ProjNode(init,TypeFunc::Control); + Node* ctrl = new (C) ProjNode(init,TypeFunc::Control); transform_later(ctrl); - Node* mem = new (C, 1) ProjNode(init,TypeFunc::Memory); + Node* mem = new (C) ProjNode(init,TypeFunc::Memory); transform_later(mem); // The MemBarStoreStore depends on control and memory coming @@ -1349,9 +1348,9 @@ mb->init_req(TypeFunc::Memory, mem); mb->init_req(TypeFunc::Control, ctrl); - ctrl = new (C, 1) ProjNode(mb,TypeFunc::Control); + ctrl = new (C) ProjNode(mb,TypeFunc::Control); transform_later(ctrl); - mem = new (C, 1) ProjNode(mb,TypeFunc::Memory); + mem = new (C) ProjNode(mb,TypeFunc::Memory); transform_later(mem); // All nodes that depended on the InitializeNode for control @@ -1365,13 +1364,13 @@ if (C->env()->dtrace_extended_probes()) { // Slow-path call int size = TypeFunc::Parms + 2; - CallLeafNode *call = new (C, size) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(), - CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc_base), - "dtrace_object_alloc", - TypeRawPtr::BOTTOM); + CallLeafNode *call = new (C) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(), + CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc_base), + "dtrace_object_alloc", + TypeRawPtr::BOTTOM); // Get base of thread-local storage area - Node* thread = new (C, 1) ThreadLocalNode(); + Node* thread = new (C) ThreadLocalNode(); transform_later(thread); call->init_req(TypeFunc::Parms+0, thread); @@ -1382,9 +1381,9 @@ call->init_req(TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr)); call->init_req(TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr)); transform_later(call); - fast_oop_ctrl = new (C, 1) ProjNode(call,TypeFunc::Control); + fast_oop_ctrl = new (C) ProjNode(call,TypeFunc::Control); transform_later(fast_oop_ctrl); - fast_oop_rawmem = new (C, 1) ProjNode(call,TypeFunc::Memory); + fast_oop_rawmem = new (C) ProjNode(call,TypeFunc::Memory); transform_later(fast_oop_rawmem); } @@ -1399,11 +1398,10 @@ } // Generate slow-path call - CallNode *call = new (C, slow_call_type->domain()->cnt()) - CallStaticJavaNode(slow_call_type, slow_call_address, - OptoRuntime::stub_name(slow_call_address), - alloc->jvms()->bci(), - TypePtr::BOTTOM); + CallNode *call = new (C) CallStaticJavaNode(slow_call_type, slow_call_address, + OptoRuntime::stub_name(slow_call_address), + alloc->jvms()->bci(), + TypePtr::BOTTOM); call->init_req( TypeFunc::Control, slow_region ); call->init_req( TypeFunc::I_O , top() ) ; // does no i/o call->init_req( TypeFunc::Memory , slow_mem ); // may gc ptrs @@ -1457,7 +1455,7 @@ // _memproj_catchall so we end up with a call that has only 1 memory projection. if (_memproj_catchall != NULL ) { if (_memproj_fallthrough == NULL) { - _memproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::Memory); + _memproj_fallthrough = new (C) ProjNode(call, TypeFunc::Memory); transform_later(_memproj_fallthrough); } for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) { @@ -1489,7 +1487,7 @@ // _ioproj_catchall so we end up with a call that has only 1 i_o projection. if (_ioproj_catchall != NULL ) { if (_ioproj_fallthrough == NULL) { - _ioproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::I_O); + _ioproj_fallthrough = new (C) ProjNode(call, TypeFunc::I_O); transform_later(_ioproj_fallthrough); } for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) { @@ -1623,46 +1621,46 @@ // As an allocation hits the watermark, we will prefetch starting // at a "distance" away from watermark. - Node *pf_region = new (C, 3) RegionNode(3); - Node *pf_phi_rawmem = new (C, 3) PhiNode( pf_region, Type::MEMORY, + Node *pf_region = new (C) RegionNode(3); + Node *pf_phi_rawmem = new (C) PhiNode( pf_region, Type::MEMORY, TypeRawPtr::BOTTOM ); // I/O is used for Prefetch - Node *pf_phi_abio = new (C, 3) PhiNode( pf_region, Type::ABIO ); + Node *pf_phi_abio = new (C) PhiNode( pf_region, Type::ABIO ); - Node *thread = new (C, 1) ThreadLocalNode(); + Node *thread = new (C) ThreadLocalNode(); transform_later(thread); - Node *eden_pf_adr = new (C, 4) AddPNode( top()/*not oop*/, thread, + Node *eden_pf_adr = new (C) AddPNode( top()/*not oop*/, thread, _igvn.MakeConX(in_bytes(JavaThread::tlab_pf_top_offset())) ); transform_later(eden_pf_adr); - Node *old_pf_wm = new (C, 3) LoadPNode( needgc_false, + Node *old_pf_wm = new (C) LoadPNode( needgc_false, contended_phi_rawmem, eden_pf_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM ); transform_later(old_pf_wm); // check against new_eden_top - Node *need_pf_cmp = new (C, 3) CmpPNode( new_eden_top, old_pf_wm ); + Node *need_pf_cmp = new (C) CmpPNode( new_eden_top, old_pf_wm ); transform_later(need_pf_cmp); - Node *need_pf_bol = new (C, 2) BoolNode( need_pf_cmp, BoolTest::ge ); + Node *need_pf_bol = new (C) BoolNode( need_pf_cmp, BoolTest::ge ); transform_later(need_pf_bol); - IfNode *need_pf_iff = new (C, 2) IfNode( needgc_false, need_pf_bol, + IfNode *need_pf_iff = new (C) IfNode( needgc_false, need_pf_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN ); transform_later(need_pf_iff); // true node, add prefetchdistance - Node *need_pf_true = new (C, 1) IfTrueNode( need_pf_iff ); + Node *need_pf_true = new (C) IfTrueNode( need_pf_iff ); transform_later(need_pf_true); - Node *need_pf_false = new (C, 1) IfFalseNode( need_pf_iff ); + Node *need_pf_false = new (C) IfFalseNode( need_pf_iff ); transform_later(need_pf_false); - Node *new_pf_wmt = new (C, 4) AddPNode( top(), old_pf_wm, + Node *new_pf_wmt = new (C) AddPNode( top(), old_pf_wm, _igvn.MakeConX(AllocatePrefetchDistance) ); transform_later(new_pf_wmt ); new_pf_wmt->set_req(0, need_pf_true); - Node *store_new_wmt = new (C, 4) StorePNode( need_pf_true, + Node *store_new_wmt = new (C) StorePNode( need_pf_true, contended_phi_rawmem, eden_pf_adr, TypeRawPtr::BOTTOM, new_pf_wmt ); transform_later(store_new_wmt); @@ -1677,10 +1675,10 @@ uint distance = 0; for ( uint i = 0; i < lines; i++ ) { - prefetch_adr = new (C, 4) AddPNode( old_pf_wm, new_pf_wmt, + prefetch_adr = new (C) AddPNode( old_pf_wm, new_pf_wmt, _igvn.MakeConX(distance) ); transform_later(prefetch_adr); - prefetch = new (C, 3) PrefetchAllocationNode( i_o, prefetch_adr ); + prefetch = new (C) PrefetchAllocationNode( i_o, prefetch_adr ); transform_later(prefetch); distance += step_size; i_o = prefetch; @@ -1703,9 +1701,9 @@ } else if( UseTLAB && AllocatePrefetchStyle == 3 ) { // Insert a prefetch for each allocation. // This code is used for Sparc with BIS. - Node *pf_region = new (C, 3) RegionNode(3); - Node *pf_phi_rawmem = new (C, 3) PhiNode( pf_region, Type::MEMORY, - TypeRawPtr::BOTTOM ); + Node *pf_region = new (C) RegionNode(3); + Node *pf_phi_rawmem = new (C) PhiNode( pf_region, Type::MEMORY, + TypeRawPtr::BOTTOM ); // Generate several prefetch instructions. uint lines = (length != NULL) ? AllocatePrefetchLines : AllocateInstancePrefetchLines; @@ -1713,29 +1711,29 @@ uint distance = AllocatePrefetchDistance; // Next cache address. - Node *cache_adr = new (C, 4) AddPNode(old_eden_top, old_eden_top, + Node *cache_adr = new (C) AddPNode(old_eden_top, old_eden_top, _igvn.MakeConX(distance)); transform_later(cache_adr); - cache_adr = new (C, 2) CastP2XNode(needgc_false, cache_adr); + cache_adr = new (C) CastP2XNode(needgc_false, cache_adr); transform_later(cache_adr); Node* mask = _igvn.MakeConX(~(intptr_t)(step_size-1)); - cache_adr = new (C, 3) AndXNode(cache_adr, mask); + cache_adr = new (C) AndXNode(cache_adr, mask); transform_later(cache_adr); - cache_adr = new (C, 2) CastX2PNode(cache_adr); + cache_adr = new (C) CastX2PNode(cache_adr); transform_later(cache_adr); // Prefetch - Node *prefetch = new (C, 3) PrefetchAllocationNode( contended_phi_rawmem, cache_adr ); + Node *prefetch = new (C) PrefetchAllocationNode( contended_phi_rawmem, cache_adr ); prefetch->set_req(0, needgc_false); transform_later(prefetch); contended_phi_rawmem = prefetch; Node *prefetch_adr; distance = step_size; for ( uint i = 1; i < lines; i++ ) { - prefetch_adr = new (C, 4) AddPNode( cache_adr, cache_adr, + prefetch_adr = new (C) AddPNode( cache_adr, cache_adr, _igvn.MakeConX(distance) ); transform_later(prefetch_adr); - prefetch = new (C, 3) PrefetchAllocationNode( contended_phi_rawmem, prefetch_adr ); + prefetch = new (C) PrefetchAllocationNode( contended_phi_rawmem, prefetch_adr ); transform_later(prefetch); distance += step_size; contended_phi_rawmem = prefetch; @@ -1749,10 +1747,10 @@ uint step_size = AllocatePrefetchStepSize; uint distance = AllocatePrefetchDistance; for ( uint i = 0; i < lines; i++ ) { - prefetch_adr = new (C, 4) AddPNode( old_eden_top, new_eden_top, + prefetch_adr = new (C) AddPNode( old_eden_top, new_eden_top, _igvn.MakeConX(distance) ); transform_later(prefetch_adr); - prefetch = new (C, 3) PrefetchAllocationNode( i_o, prefetch_adr ); + prefetch = new (C) PrefetchAllocationNode( i_o, prefetch_adr ); // Do not let it float too high, since if eden_top == eden_end, // both might be null. if( i == 0 ) { // Set control for first prefetch, next follows it @@ -2101,12 +2099,12 @@ * } */ - region = new (C, 5) RegionNode(5); + region = new (C) RegionNode(5); // create a Phi for the memory state - mem_phi = new (C, 5) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); + mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); - Node* fast_lock_region = new (C, 3) RegionNode(3); - Node* fast_lock_mem_phi = new (C, 3) PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM); + Node* fast_lock_region = new (C) RegionNode(3); + Node* fast_lock_mem_phi = new (C) PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM); // First, check mark word for the biased lock pattern. Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type()); @@ -2136,10 +2134,10 @@ } Node *proto_node = make_load(ctrl, mem, klass_node, in_bytes(Klass::prototype_header_offset()), TypeX_X, TypeX_X->basic_type()); - Node* thread = transform_later(new (C, 1) ThreadLocalNode()); - Node* cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread)); - Node* o_node = transform_later(new (C, 3) OrXNode(cast_thread, proto_node)); - Node* x_node = transform_later(new (C, 3) XorXNode(o_node, mark_node)); + Node* thread = transform_later(new (C) ThreadLocalNode()); + Node* cast_thread = transform_later(new (C) CastP2XNode(ctrl, thread)); + Node* o_node = transform_later(new (C) OrXNode(cast_thread, proto_node)); + Node* x_node = transform_later(new (C) XorXNode(o_node, mark_node)); // Get slow path - mark word does NOT match the value. Node* not_biased_ctrl = opt_bits_test(ctrl, region, 3, x_node, @@ -2162,17 +2160,17 @@ // We are going to try to reset the mark of this object to the prototype // value and fall through to the CAS-based locking scheme. Node* adr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes()); - Node* cas = new (C, 5) StoreXConditionalNode(not_biased_ctrl, mem, adr, - proto_node, mark_node); + Node* cas = new (C) StoreXConditionalNode(not_biased_ctrl, mem, adr, + proto_node, mark_node); transform_later(cas); - Node* proj = transform_later( new (C, 1) SCMemProjNode(cas)); + Node* proj = transform_later( new (C) SCMemProjNode(cas)); fast_lock_mem_phi->init_req(2, proj); // Second, check epoch bits. - Node* rebiased_region = new (C, 3) RegionNode(3); - Node* old_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X); - Node* new_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X); + Node* rebiased_region = new (C) RegionNode(3); + Node* old_phi = new (C) PhiNode( rebiased_region, TypeX_X); + Node* new_phi = new (C) PhiNode( rebiased_region, TypeX_X); // Get slow path - mark word does NOT match epoch bits. Node* epoch_ctrl = opt_bits_test(ctrl, rebiased_region, 1, x_node, @@ -2189,9 +2187,9 @@ Node* cmask = MakeConX(markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place); - Node* old = transform_later(new (C, 3) AndXNode(mark_node, cmask)); - cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread)); - Node* new_mark = transform_later(new (C, 3) OrXNode(cast_thread, old)); + Node* old = transform_later(new (C) AndXNode(mark_node, cmask)); + cast_thread = transform_later(new (C) CastP2XNode(ctrl, thread)); + Node* new_mark = transform_later(new (C) OrXNode(cast_thread, old)); old_phi->init_req(1, old); new_phi->init_req(1, new_mark); @@ -2201,10 +2199,10 @@ // Try to acquire the bias of the object using an atomic operation. // If this fails we will go in to the runtime to revoke the object's bias. - cas = new (C, 5) StoreXConditionalNode(rebiased_region, mem, adr, + cas = new (C) StoreXConditionalNode(rebiased_region, mem, adr, new_phi, old_phi); transform_later(cas); - proj = transform_later( new (C, 1) SCMemProjNode(cas)); + proj = transform_later( new (C) SCMemProjNode(cas)); // Get slow path - Failed to CAS. not_biased_ctrl = opt_bits_test(rebiased_region, region, 4, cas, 0, 0); @@ -2212,8 +2210,8 @@ // region->in(4) is set to fast path - the object is rebiased to the current thread. // Failed to CAS. - slow_path = new (C, 3) RegionNode(3); - Node *slow_mem = new (C, 3) PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM); + slow_path = new (C) RegionNode(3); + Node *slow_mem = new (C) PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM); slow_path->init_req(1, not_biased_ctrl); // Capture slow-control slow_mem->init_req(1, proj); @@ -2237,9 +2235,9 @@ lock->set_req(TypeFunc::Memory, slow_mem); } else { - region = new (C, 3) RegionNode(3); + region = new (C) RegionNode(3); // create a Phi for the memory state - mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); + mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); // Optimize test; set region slot 2 slow_path = opt_bits_test(ctrl, region, 2, flock, 0, 0); @@ -2270,7 +2268,7 @@ transform_later(region); _igvn.replace_node(_fallthroughproj, region); - Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) ); + Node *memproj = transform_later( new(C) ProjNode(call, TypeFunc::Memory) ); mem_phi->init_req(1, memproj ); transform_later(mem_phi); _igvn.replace_node(_memproj_fallthrough, mem_phi); @@ -2295,9 +2293,9 @@ if (UseOptoBiasInlining) { // Check for biased locking unlock case, which is a no-op. // See the full description in MacroAssembler::biased_locking_exit(). - region = new (C, 4) RegionNode(4); + region = new (C) RegionNode(4); // create a Phi for the memory state - mem_phi = new (C, 4) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); + mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); mem_phi->init_req(3, mem); Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type()); @@ -2305,12 +2303,12 @@ markOopDesc::biased_lock_mask_in_place, markOopDesc::biased_lock_pattern); } else { - region = new (C, 3) RegionNode(3); + region = new (C) RegionNode(3); // create a Phi for the memory state - mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); + mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); } - FastUnlockNode *funlock = new (C, 3) FastUnlockNode( ctrl, obj, box ); + FastUnlockNode *funlock = new (C) FastUnlockNode( ctrl, obj, box ); funlock = transform_later( funlock )->as_FastUnlock(); // Optimize test; set region slot 2 Node *slow_path = opt_bits_test(ctrl, region, 2, funlock, 0, 0); @@ -2335,7 +2333,7 @@ transform_later(region); _igvn.replace_node(_fallthroughproj, region); - Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) ); + Node *memproj = transform_later( new(C) ProjNode(call, TypeFunc::Memory) ); mem_phi->init_req(1, memproj ); mem_phi->init_req(2, mem); transform_later(mem_phi); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/macro.hpp --- a/src/share/vm/opto/macro.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/macro.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -52,7 +52,7 @@ return basic_plus_adr(base, base, offset); } Node* basic_plus_adr(Node* base, Node* ptr, Node* offset) { - Node* adr = new (C, 4) AddPNode(base, ptr, offset); + Node* adr = new (C) AddPNode(base, ptr, offset); return transform_later(adr); } Node* transform_later(Node* n) { diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/matcher.cpp --- a/src/share/vm/opto/matcher.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/matcher.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -727,7 +727,7 @@ tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1)); tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1)); halt_rms [ halt_edge_cnt].Insert(OptoReg::Name(i+1)); - mproj = new (C, 1) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegD ); + mproj = new (C) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegD ); proj_cnt += 2; // Skip 2 for doubles } else if( (i&1) == 1 && // Else check for high half of double @@ -753,7 +753,7 @@ tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1)); tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1)); halt_rms [ halt_edge_cnt].Insert(OptoReg::Name(i+1)); - mproj = new (C, 1) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegL ); + mproj = new (C) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegL ); proj_cnt += 2; // Skip 2 for longs } else if( (i&1) == 1 && // Else check for high half of long @@ -768,7 +768,7 @@ mproj = C->top(); } else { // Make a projection for it off the Start - mproj = new (C, 1) MachProjNode( start, proj_cnt++, ret_rms[ret_edge_cnt], _register_save_type[i] ); + mproj = new (C) MachProjNode( start, proj_cnt++, ret_rms[ret_edge_cnt], _register_save_type[i] ); } ret_edge_cnt ++; @@ -821,13 +821,13 @@ // Compute generic short-offset Loads #ifdef _LP64 - MachNode *spillCP = match_tree(new (C, 3) LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM)); + MachNode *spillCP = match_tree(new (C) LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM)); #endif - MachNode *spillI = match_tree(new (C, 3) LoadINode(NULL,mem,fp,atp)); - MachNode *spillL = match_tree(new (C, 3) LoadLNode(NULL,mem,fp,atp)); - MachNode *spillF = match_tree(new (C, 3) LoadFNode(NULL,mem,fp,atp)); - MachNode *spillD = match_tree(new (C, 3) LoadDNode(NULL,mem,fp,atp)); - MachNode *spillP = match_tree(new (C, 3) LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM)); + MachNode *spillI = match_tree(new (C) LoadINode(NULL,mem,fp,atp)); + MachNode *spillL = match_tree(new (C) LoadLNode(NULL,mem,fp,atp)); + MachNode *spillF = match_tree(new (C) LoadFNode(NULL,mem,fp,atp)); + MachNode *spillD = match_tree(new (C) LoadDNode(NULL,mem,fp,atp)); + MachNode *spillP = match_tree(new (C) LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM)); assert(spillI != NULL && spillL != NULL && spillF != NULL && spillD != NULL && spillP != NULL, ""); @@ -844,19 +844,19 @@ // Vector regmasks. if (Matcher::vector_size_supported(T_BYTE,4)) { TypeVect::VECTS = TypeVect::make(T_BYTE, 4); - MachNode *spillVectS = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTS)); + MachNode *spillVectS = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTS)); idealreg2regmask[Op_VecS] = &spillVectS->out_RegMask(); } if (Matcher::vector_size_supported(T_FLOAT,2)) { - MachNode *spillVectD = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTD)); + MachNode *spillVectD = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTD)); idealreg2regmask[Op_VecD] = &spillVectD->out_RegMask(); } if (Matcher::vector_size_supported(T_FLOAT,4)) { - MachNode *spillVectX = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTX)); + MachNode *spillVectX = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTX)); idealreg2regmask[Op_VecX] = &spillVectX->out_RegMask(); } if (Matcher::vector_size_supported(T_FLOAT,8)) { - MachNode *spillVectY = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTY)); + MachNode *spillVectY = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTY)); idealreg2regmask[Op_VecY] = &spillVectY->out_RegMask(); } } @@ -1303,7 +1303,7 @@ // is excluded on the max-per-method basis, debug info cannot land in // this killed area. uint r_cnt = mcall->tf()->range()->cnt(); - MachProjNode *proj = new (C, 1) MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj ); + MachProjNode *proj = new (C) MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj ); if (!RegMask::can_represent_arg(OptoReg::Name(out_arg_limit_per_call-1))) { C->record_method_not_compilable_all_tiers("unsupported outgoing calling sequence"); } else { @@ -2134,10 +2134,10 @@ case Op_CompareAndSwapP: case Op_CompareAndSwapN: { // Convert trinary to binary-tree Node *newval = n->in(MemNode::ValueIn ); - Node *oldval = n->in(LoadStoreNode::ExpectedIn); - Node *pair = new (C, 3) BinaryNode( oldval, newval ); + Node *oldval = n->in(LoadStoreConditionalNode::ExpectedIn); + Node *pair = new (C) BinaryNode( oldval, newval ); n->set_req(MemNode::ValueIn,pair); - n->del_req(LoadStoreNode::ExpectedIn); + n->del_req(LoadStoreConditionalNode::ExpectedIn); break; } case Op_CMoveD: // Convert trinary to binary-tree @@ -2150,22 +2150,22 @@ // we could move this code up next to the graph reshaping for IfNodes // or vice-versa, but I do not want to debug this for Ladybird. // 10/2/2000 CNC. - Node *pair1 = new (C, 3) BinaryNode(n->in(1),n->in(1)->in(1)); + Node *pair1 = new (C) BinaryNode(n->in(1),n->in(1)->in(1)); n->set_req(1,pair1); - Node *pair2 = new (C, 3) BinaryNode(n->in(2),n->in(3)); + Node *pair2 = new (C) BinaryNode(n->in(2),n->in(3)); n->set_req(2,pair2); n->del_req(3); break; } case Op_LoopLimit: { - Node *pair1 = new (C, 3) BinaryNode(n->in(1),n->in(2)); + Node *pair1 = new (C) BinaryNode(n->in(1),n->in(2)); n->set_req(1,pair1); n->set_req(2,n->in(3)); n->del_req(3); break; } case Op_StrEquals: { - Node *pair1 = new (C, 3) BinaryNode(n->in(2),n->in(3)); + Node *pair1 = new (C) BinaryNode(n->in(2),n->in(3)); n->set_req(2,pair1); n->set_req(3,n->in(4)); n->del_req(4); @@ -2173,9 +2173,9 @@ } case Op_StrComp: case Op_StrIndexOf: { - Node *pair1 = new (C, 3) BinaryNode(n->in(2),n->in(3)); + Node *pair1 = new (C) BinaryNode(n->in(2),n->in(3)); n->set_req(2,pair1); - Node *pair2 = new (C, 3) BinaryNode(n->in(4),n->in(5)); + Node *pair2 = new (C) BinaryNode(n->in(4),n->in(5)); n->set_req(3,pair2); n->del_req(5); n->del_req(4); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/memnode.cpp --- a/src/share/vm/opto/memnode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/memnode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -883,25 +883,25 @@ rt->isa_oopptr() || is_immutable_value(adr), "raw memory operations should have control edge"); switch (bt) { - case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int() ); - case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() ); - case T_INT: return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int() ); - case T_CHAR: return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int() ); - case T_SHORT: return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int() ); - case T_LONG: return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long() ); - case T_FLOAT: return new (C, 3) LoadFNode (ctl, mem, adr, adr_type, rt ); - case T_DOUBLE: return new (C, 3) LoadDNode (ctl, mem, adr, adr_type, rt ); - case T_ADDRESS: return new (C, 3) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr() ); + case T_BOOLEAN: return new (C) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int() ); + case T_BYTE: return new (C) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() ); + case T_INT: return new (C) LoadINode (ctl, mem, adr, adr_type, rt->is_int() ); + case T_CHAR: return new (C) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int() ); + case T_SHORT: return new (C) LoadSNode (ctl, mem, adr, adr_type, rt->is_int() ); + case T_LONG: return new (C) LoadLNode (ctl, mem, adr, adr_type, rt->is_long() ); + case T_FLOAT: return new (C) LoadFNode (ctl, mem, adr, adr_type, rt ); + case T_DOUBLE: return new (C) LoadDNode (ctl, mem, adr, adr_type, rt ); + case T_ADDRESS: return new (C) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr() ); case T_OBJECT: #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { - Node* load = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop())); - return new (C, 2) DecodeNNode(load, load->bottom_type()->make_ptr()); + Node* load = gvn.transform(new (C) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop())); + return new (C) DecodeNNode(load, load->bottom_type()->make_ptr()); } else #endif { assert(!adr->bottom_type()->is_ptr_to_narrowoop(), "should have got back a narrow oop"); - return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr()); + return new (C) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr()); } } ShouldNotReachHere(); @@ -910,7 +910,7 @@ LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt) { bool require_atomic = true; - return new (C, 3) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), require_atomic); + return new (C) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), require_atomic); } @@ -1244,20 +1244,20 @@ // Add up all the offsets making of the address of the load Node* result = elements[0]; for (int i = 1; i < count; i++) { - result = phase->transform(new (phase->C, 3) AddXNode(result, elements[i])); + result = phase->transform(new (phase->C) AddXNode(result, elements[i])); } // Remove the constant offset from the address and then // remove the scaling of the offset to recover the original index. - result = phase->transform(new (phase->C, 3) AddXNode(result, phase->MakeConX(-offset))); + result = phase->transform(new (phase->C) AddXNode(result, phase->MakeConX(-offset))); if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) { // Peel the shift off directly but wrap it in a dummy node // since Ideal can't return existing nodes - result = new (phase->C, 3) RShiftXNode(result->in(1), phase->intcon(0)); + result = new (phase->C) RShiftXNode(result->in(1), phase->intcon(0)); } else { - result = new (phase->C, 3) RShiftXNode(result, phase->intcon(shift)); + result = new (phase->C) RShiftXNode(result, phase->intcon(shift)); } #ifdef _LP64 - result = new (phase->C, 2) ConvL2INode(phase->transform(result)); + result = new (phase->C) ConvL2INode(phase->transform(result)); #endif return result; } @@ -1320,7 +1320,7 @@ int this_offset = addr_t->offset(); int this_iid = addr_t->is_oopptr()->instance_id(); PhaseIterGVN *igvn = phase->is_IterGVN(); - Node *phi = new (igvn->C, region->req()) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset); + Node *phi = new (igvn->C) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset); for (uint i = 1; i < region->req(); i++) { Node *x; Node* the_clone = NULL; @@ -1771,8 +1771,8 @@ Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) { - Node *result = phase->transform( new (phase->C, 3) LShiftINode(value, phase->intcon(24)) ); - return new (phase->C, 3) RShiftINode(result, phase->intcon(24)); + Node *result = phase->transform( new (phase->C) LShiftINode(value, phase->intcon(24)) ); + return new (phase->C) RShiftINode(result, phase->intcon(24)); } // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); @@ -1803,7 +1803,7 @@ Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem, phase); if (value && !phase->type(value)->higher_equal(_type)) - return new (phase->C, 3) AndINode(value, phase->intcon(0xFF)); + return new (phase->C) AndINode(value, phase->intcon(0xFF)); // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); } @@ -1833,7 +1833,7 @@ Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) - return new (phase->C, 3) AndINode(value,phase->intcon(0xFFFF)); + return new (phase->C) AndINode(value,phase->intcon(0xFFFF)); // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); } @@ -1863,8 +1863,8 @@ Node* mem = in(MemNode::Memory); Node* value = can_see_stored_value(mem,phase); if( value && !phase->type(value)->higher_equal( _type ) ) { - Node *result = phase->transform( new (phase->C, 3) LShiftINode(value, phase->intcon(16)) ); - return new (phase->C, 3) RShiftINode(result, phase->intcon(16)); + Node *result = phase->transform( new (phase->C) LShiftINode(value, phase->intcon(16)) ); + return new (phase->C) RShiftINode(result, phase->intcon(16)); } // Identity call will handle the case where truncation is not needed. return LoadNode::Ideal(phase, can_reshape); @@ -1896,12 +1896,12 @@ #ifdef _LP64 if (adr_type->is_ptr_to_narrowoop()) { assert(UseCompressedKlassPointers, "no compressed klasses"); - Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop())); - return new (C, 2) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr()); + Node* load_klass = gvn.transform(new (C) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop())); + return new (C) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr()); } #endif assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop"); - return new (C, 3) LoadKlassNode(ctl, mem, adr, at, tk); + return new (C) LoadKlassNode(ctl, mem, adr, at, tk); } //------------------------------Value------------------------------------------ @@ -2123,7 +2123,7 @@ if( t == Type::TOP ) return x; if( t->isa_narrowoop()) return x; - return phase->transform(new (phase->C, 2) EncodePNode(x, t->make_narrowoop())); + return phase->transform(new (phase->C) EncodePNode(x, t->make_narrowoop())); } //------------------------------Value----------------------------------------- @@ -2217,13 +2217,13 @@ switch (bt) { case T_BOOLEAN: - case T_BYTE: return new (C, 4) StoreBNode(ctl, mem, adr, adr_type, val); - case T_INT: return new (C, 4) StoreINode(ctl, mem, adr, adr_type, val); + case T_BYTE: return new (C) StoreBNode(ctl, mem, adr, adr_type, val); + case T_INT: return new (C) StoreINode(ctl, mem, adr, adr_type, val); case T_CHAR: - case T_SHORT: return new (C, 4) StoreCNode(ctl, mem, adr, adr_type, val); - case T_LONG: return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val); - case T_FLOAT: return new (C, 4) StoreFNode(ctl, mem, adr, adr_type, val); - case T_DOUBLE: return new (C, 4) StoreDNode(ctl, mem, adr, adr_type, val); + case T_SHORT: return new (C) StoreCNode(ctl, mem, adr, adr_type, val); + case T_LONG: return new (C) StoreLNode(ctl, mem, adr, adr_type, val); + case T_FLOAT: return new (C) StoreFNode(ctl, mem, adr, adr_type, val); + case T_DOUBLE: return new (C) StoreDNode(ctl, mem, adr, adr_type, val); case T_METADATA: case T_ADDRESS: case T_OBJECT: @@ -2231,12 +2231,12 @@ if (adr->bottom_type()->is_ptr_to_narrowoop() || (UseCompressedKlassPointers && val->bottom_type()->isa_klassptr() && adr->bottom_type()->isa_rawptr())) { - val = gvn.transform(new (C, 2) EncodePNode(val, val->bottom_type()->make_narrowoop())); - return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, val); + val = gvn.transform(new (C) EncodePNode(val, val->bottom_type()->make_narrowoop())); + return new (C) StoreNNode(ctl, mem, adr, adr_type, val); } else #endif { - return new (C, 4) StorePNode(ctl, mem, adr, adr_type, val); + return new (C) StorePNode(ctl, mem, adr, adr_type, val); } } ShouldNotReachHere(); @@ -2245,7 +2245,7 @@ StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val) { bool require_atomic = true; - return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val, require_atomic); + return new (C) StoreLNode(ctl, mem, adr, adr_type, val, require_atomic); } @@ -2552,14 +2552,38 @@ } //============================================================================= -LoadStoreNode::LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex ) : Node(5) { +//----------------------------------LoadStoreNode------------------------------ +LoadStoreNode::LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* rt, uint required ) + : Node(required), + _type(rt), + _adr_type(at) +{ init_req(MemNode::Control, c ); init_req(MemNode::Memory , mem); init_req(MemNode::Address, adr); init_req(MemNode::ValueIn, val); - init_req( ExpectedIn, ex ); init_class_id(Class_LoadStore); - +} + +uint LoadStoreNode::ideal_reg() const { + return _type->ideal_reg(); +} + +bool LoadStoreNode::result_not_used() const { + for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) { + Node *x = fast_out(i); + if (x->Opcode() == Op_SCMemProj) continue; + return false; + } + return true; +} + +uint LoadStoreNode::size_of() const { return sizeof(*this); } + +//============================================================================= +//----------------------------------LoadStoreConditionalNode-------------------- +LoadStoreConditionalNode::LoadStoreConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex ) : LoadStoreNode(c, mem, adr, val, NULL, TypeInt::BOOL, 5) { + init_req(ExpectedIn, ex ); } //============================================================================= @@ -2614,12 +2638,12 @@ Node *zero = phase->makecon(TypeLong::ZERO); Node *off = phase->MakeConX(BytesPerLong); - mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); + mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero); count--; while( count-- ) { mem = phase->transform(mem); - adr = phase->transform(new (phase->C, 4) AddPNode(base,adr,off)); - mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); + adr = phase->transform(new (phase->C) AddPNode(base,adr,off)); + mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero); } return mem; } @@ -2660,7 +2684,7 @@ int unit = BytesPerLong; if ((offset % unit) != 0) { - Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(offset)); + Node* adr = new (C) AddPNode(dest, dest, phase->MakeConX(offset)); adr = phase->transform(adr); const TypePtr* atp = TypeRawPtr::BOTTOM; mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT); @@ -2690,16 +2714,16 @@ // Scale to the unit required by the CPU: if (!Matcher::init_array_count_is_in_bytes) { Node* shift = phase->intcon(exact_log2(unit)); - zbase = phase->transform( new(C,3) URShiftXNode(zbase, shift) ); - zend = phase->transform( new(C,3) URShiftXNode(zend, shift) ); + zbase = phase->transform( new(C) URShiftXNode(zbase, shift) ); + zend = phase->transform( new(C) URShiftXNode(zend, shift) ); } - Node* zsize = phase->transform( new(C,3) SubXNode(zend, zbase) ); + Node* zsize = phase->transform( new(C) SubXNode(zend, zbase) ); Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT); // Bulk clear double-words - Node* adr = phase->transform( new(C,4) AddPNode(dest, dest, start_offset) ); - mem = new (C, 4) ClearArrayNode(ctl, mem, zsize, adr); + Node* adr = phase->transform( new(C) AddPNode(dest, dest, start_offset) ); + mem = new (C) ClearArrayNode(ctl, mem, zsize, adr); return phase->transform(mem); } @@ -2723,7 +2747,7 @@ start_offset, phase->MakeConX(done_offset), phase); } if (done_offset < end_offset) { // emit the final 32-bit store - Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(done_offset)); + Node* adr = new (C) AddPNode(dest, dest, phase->MakeConX(done_offset)); adr = phase->transform(adr); const TypePtr* atp = TypeRawPtr::BOTTOM; mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT); @@ -2789,16 +2813,15 @@ //------------------------------make------------------------------------------- MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) { - int len = Precedent + (pn == NULL? 0: 1); switch (opcode) { - case Op_MemBarAcquire: return new(C, len) MemBarAcquireNode(C, atp, pn); - case Op_MemBarRelease: return new(C, len) MemBarReleaseNode(C, atp, pn); - case Op_MemBarAcquireLock: return new(C, len) MemBarAcquireLockNode(C, atp, pn); - case Op_MemBarReleaseLock: return new(C, len) MemBarReleaseLockNode(C, atp, pn); - case Op_MemBarVolatile: return new(C, len) MemBarVolatileNode(C, atp, pn); - case Op_MemBarCPUOrder: return new(C, len) MemBarCPUOrderNode(C, atp, pn); - case Op_Initialize: return new(C, len) InitializeNode(C, atp, pn); - case Op_MemBarStoreStore: return new(C, len) MemBarStoreStoreNode(C, atp, pn); + case Op_MemBarAcquire: return new(C) MemBarAcquireNode(C, atp, pn); + case Op_MemBarRelease: return new(C) MemBarReleaseNode(C, atp, pn); + case Op_MemBarAcquireLock: return new(C) MemBarAcquireLockNode(C, atp, pn); + case Op_MemBarReleaseLock: return new(C) MemBarReleaseLockNode(C, atp, pn); + case Op_MemBarVolatile: return new(C) MemBarVolatileNode(C, atp, pn); + case Op_MemBarCPUOrder: return new(C) MemBarCPUOrderNode(C, atp, pn); + case Op_Initialize: return new(C) InitializeNode(C, atp, pn); + case Op_MemBarStoreStore: return new(C) MemBarStoreStoreNode(C, atp, pn); default: ShouldNotReachHere(); return NULL; } } @@ -2828,7 +2851,7 @@ igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control)); // Must return either the original node (now dead) or a new node // (Do not return a top here, since that would break the uniqueness of top.) - return new (phase->C, 1) ConINode(TypeInt::ZERO); + return new (phase->C) ConINode(TypeInt::ZERO); } } } @@ -2849,7 +2872,7 @@ switch (proj->_con) { case TypeFunc::Control: case TypeFunc::Memory: - return new (m->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); + return new (m->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); } ShouldNotReachHere(); return NULL; @@ -3193,7 +3216,7 @@ Node* addr = in(RawAddress); if (offset != 0) { Compile* C = phase->C; - addr = phase->transform( new (C, 4) AddPNode(C->top(), addr, + addr = phase->transform( new (C) AddPNode(C->top(), addr, phase->MakeConX(offset)) ); } return addr; @@ -3882,7 +3905,7 @@ // Make a new, untransformed MergeMem with the same base as 'mem'. // If mem is itself a MergeMem, populate the result with the same edges. MergeMemNode* MergeMemNode::make(Compile* C, Node* mem) { - return new(C, 1+Compile::AliasIdxRaw) MergeMemNode(mem); + return new(C) MergeMemNode(mem); } //------------------------------cmp-------------------------------------------- diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/memnode.hpp --- a/src/share/vm/opto/memnode.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/memnode.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -657,23 +657,36 @@ //------------------------------LoadStoreNode--------------------------- // Note: is_Mem() method returns 'true' for this class. class LoadStoreNode : public Node { +private: + const Type* const _type; // What kind of value is loaded? + const TypePtr* _adr_type; // What kind of memory is being addressed? + virtual uint size_of() const; // Size is bigger +public: + LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* rt, uint required ); + virtual bool depends_only_on_test() const { return false; } + virtual uint match_edge(uint idx) const { return idx == MemNode::Address || idx == MemNode::ValueIn; } + + virtual const Type *bottom_type() const { return _type; } + virtual uint ideal_reg() const; + virtual const class TypePtr *adr_type() const { return _adr_type; } // returns bottom_type of address + + bool result_not_used() const; +}; + +class LoadStoreConditionalNode : public LoadStoreNode { public: enum { ExpectedIn = MemNode::ValueIn+1 // One more input than MemNode }; - LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex); - virtual bool depends_only_on_test() const { return false; } - virtual const Type *bottom_type() const { return TypeInt::BOOL; } - virtual uint ideal_reg() const { return Op_RegI; } - virtual uint match_edge(uint idx) const { return idx == MemNode::Address || idx == MemNode::ValueIn; } + LoadStoreConditionalNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex); }; //------------------------------StorePConditionalNode--------------------------- // Conditionally store pointer to memory, if no change since prior // load-locked. Sets flags for success or failure of the store. -class StorePConditionalNode : public LoadStoreNode { +class StorePConditionalNode : public LoadStoreConditionalNode { public: - StorePConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { } + StorePConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreConditionalNode(c, mem, adr, val, ll) { } virtual int Opcode() const; // Produces flags virtual uint ideal_reg() const { return Op_RegFlags; } @@ -682,9 +695,9 @@ //------------------------------StoreIConditionalNode--------------------------- // Conditionally store int to memory, if no change since prior // load-locked. Sets flags for success or failure of the store. -class StoreIConditionalNode : public LoadStoreNode { +class StoreIConditionalNode : public LoadStoreConditionalNode { public: - StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreNode(c, mem, adr, val, ii) { } + StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreConditionalNode(c, mem, adr, val, ii) { } virtual int Opcode() const; // Produces flags virtual uint ideal_reg() const { return Op_RegFlags; } @@ -693,9 +706,9 @@ //------------------------------StoreLConditionalNode--------------------------- // Conditionally store long to memory, if no change since prior // load-locked. Sets flags for success or failure of the store. -class StoreLConditionalNode : public LoadStoreNode { +class StoreLConditionalNode : public LoadStoreConditionalNode { public: - StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { } + StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreConditionalNode(c, mem, adr, val, ll) { } virtual int Opcode() const; // Produces flags virtual uint ideal_reg() const { return Op_RegFlags; } @@ -703,32 +716,75 @@ //------------------------------CompareAndSwapLNode--------------------------- -class CompareAndSwapLNode : public LoadStoreNode { +class CompareAndSwapLNode : public LoadStoreConditionalNode { public: - CompareAndSwapLNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { } + CompareAndSwapLNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreConditionalNode(c, mem, adr, val, ex) { } virtual int Opcode() const; }; //------------------------------CompareAndSwapINode--------------------------- -class CompareAndSwapINode : public LoadStoreNode { +class CompareAndSwapINode : public LoadStoreConditionalNode { public: - CompareAndSwapINode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { } + CompareAndSwapINode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreConditionalNode(c, mem, adr, val, ex) { } virtual int Opcode() const; }; //------------------------------CompareAndSwapPNode--------------------------- -class CompareAndSwapPNode : public LoadStoreNode { +class CompareAndSwapPNode : public LoadStoreConditionalNode { public: - CompareAndSwapPNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { } + CompareAndSwapPNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreConditionalNode(c, mem, adr, val, ex) { } virtual int Opcode() const; }; //------------------------------CompareAndSwapNNode--------------------------- -class CompareAndSwapNNode : public LoadStoreNode { +class CompareAndSwapNNode : public LoadStoreConditionalNode { +public: + CompareAndSwapNNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreConditionalNode(c, mem, adr, val, ex) { } + virtual int Opcode() const; +}; + +//------------------------------GetAndAddINode--------------------------- +class GetAndAddINode : public LoadStoreNode { +public: + GetAndAddINode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeInt::INT, 4) { } + virtual int Opcode() const; +}; + +//------------------------------GetAndAddLNode--------------------------- +class GetAndAddLNode : public LoadStoreNode { public: - CompareAndSwapNNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { } + GetAndAddLNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeLong::LONG, 4) { } + virtual int Opcode() const; +}; + + +//------------------------------GetAndSetINode--------------------------- +class GetAndSetINode : public LoadStoreNode { +public: + GetAndSetINode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeInt::INT, 4) { } + virtual int Opcode() const; +}; + +//------------------------------GetAndSetINode--------------------------- +class GetAndSetLNode : public LoadStoreNode { +public: + GetAndSetLNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeLong::LONG, 4) { } + virtual int Opcode() const; +}; + +//------------------------------GetAndSetPNode--------------------------- +class GetAndSetPNode : public LoadStoreNode { +public: + GetAndSetPNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* t ) : LoadStoreNode(c, mem, adr, val, at, t, 4) { } + virtual int Opcode() const; +}; + +//------------------------------GetAndSetNNode--------------------------- +class GetAndSetNNode : public LoadStoreNode { +public: + GetAndSetNNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* t ) : LoadStoreNode(c, mem, adr, val, at, t, 4) { } virtual int Opcode() const; }; diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/mulnode.cpp --- a/src/share/vm/opto/mulnode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/mulnode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -198,22 +198,22 @@ Node *res = NULL; jint bit1 = con & -con; // Extract low bit if( bit1 == con ) { // Found a power of 2? - res = new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ); + res = new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ); } else { // Check for constant with 2 bits set jint bit2 = con-bit1; bit2 = bit2 & -bit2; // Extract 2nd bit if( bit2 + bit1 == con ) { // Found all bits in con? - Node *n1 = phase->transform( new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) ); - Node *n2 = phase->transform( new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) ); - res = new (phase->C, 3) AddINode( n2, n1 ); + Node *n1 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) ); + Node *n2 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) ); + res = new (phase->C) AddINode( n2, n1 ); } else if (is_power_of_2(con+1)) { // Sleezy: power-of-2 -1. Next time be generic. jint temp = (jint) (con + 1); - Node *n1 = phase->transform( new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) ); - res = new (phase->C, 3) SubINode( n1, in(1) ); + Node *n1 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) ); + res = new (phase->C) SubINode( n1, in(1) ); } else { return MulNode::Ideal(phase, can_reshape); } @@ -221,7 +221,7 @@ if( sign_flip ) { // Need to negate result? res = phase->transform(res);// Transform, before making the zero con - res = new (phase->C, 3) SubINode(phase->intcon(0),res); + res = new (phase->C) SubINode(phase->intcon(0),res); } return res; // Return final result @@ -294,22 +294,22 @@ Node *res = NULL; jlong bit1 = con & -con; // Extract low bit if( bit1 == con ) { // Found a power of 2? - res = new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ); + res = new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ); } else { // Check for constant with 2 bits set jlong bit2 = con-bit1; bit2 = bit2 & -bit2; // Extract 2nd bit if( bit2 + bit1 == con ) { // Found all bits in con? - Node *n1 = phase->transform( new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) ); - Node *n2 = phase->transform( new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) ); - res = new (phase->C, 3) AddLNode( n2, n1 ); + Node *n1 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) ); + Node *n2 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) ); + res = new (phase->C) AddLNode( n2, n1 ); } else if (is_power_of_2_long(con+1)) { // Sleezy: power-of-2 -1. Next time be generic. jlong temp = (jlong) (con + 1); - Node *n1 = phase->transform( new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) ); - res = new (phase->C, 3) SubLNode( n1, in(1) ); + Node *n1 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) ); + res = new (phase->C) SubLNode( n1, in(1) ); } else { return MulNode::Ideal(phase, can_reshape); } @@ -317,7 +317,7 @@ if( sign_flip ) { // Need to negate result? res = phase->transform(res);// Transform, before making the zero con - res = new (phase->C, 3) SubLNode(phase->longcon(0),res); + res = new (phase->C) SubLNode(phase->longcon(0),res); } return res; // Return final result @@ -476,27 +476,27 @@ // Masking bits off of a Character? Hi bits are already zero. if( lop == Op_LoadUS && (mask & 0xFFFF0000) ) // Can we make a smaller mask? - return new (phase->C, 3) AndINode(load,phase->intcon(mask&0xFFFF)); + return new (phase->C) AndINode(load,phase->intcon(mask&0xFFFF)); // Masking bits off of a Short? Loading a Character does some masking if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) { - Node *ldus = new (phase->C, 3) LoadUSNode(load->in(MemNode::Control), + Node *ldus = new (phase->C) LoadUSNode(load->in(MemNode::Control), load->in(MemNode::Memory), load->in(MemNode::Address), load->adr_type()); ldus = phase->transform(ldus); - return new (phase->C, 3) AndINode(ldus, phase->intcon(mask & 0xFFFF)); + return new (phase->C) AndINode(ldus, phase->intcon(mask & 0xFFFF)); } // Masking sign bits off of a Byte? Do an unsigned byte load plus // an and. if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) { - Node* ldub = new (phase->C, 3) LoadUBNode(load->in(MemNode::Control), + Node* ldub = new (phase->C) LoadUBNode(load->in(MemNode::Control), load->in(MemNode::Memory), load->in(MemNode::Address), load->adr_type()); ldub = phase->transform(ldub); - return new (phase->C, 3) AndINode(ldub, phase->intcon(mask)); + return new (phase->C) AndINode(ldub, phase->intcon(mask)); } // Masking off sign bits? Dont make them! @@ -510,8 +510,8 @@ // bits survive. NO sign-extension bits survive the maskings. if( (sign_bits_mask & mask) == 0 ) { // Use zero-fill shift instead - Node *zshift = phase->transform(new (phase->C, 3) URShiftINode(load->in(1),load->in(2))); - return new (phase->C, 3) AndINode( zshift, in(2) ); + Node *zshift = phase->transform(new (phase->C) URShiftINode(load->in(1),load->in(2))); + return new (phase->C) AndINode( zshift, in(2) ); } } } @@ -521,7 +521,7 @@ // plus 1) and the mask is of the low order bit. Skip the negate. if( lop == Op_SubI && mask == 1 && load->in(1) && phase->type(load->in(1)) == TypeInt::ZERO ) - return new (phase->C, 3) AndINode( load->in(2), in(2) ); + return new (phase->C) AndINode( load->in(2), in(2) ); return MulNode::Ideal(phase, can_reshape); } @@ -607,7 +607,7 @@ // which is wrong. if (op == Op_ConvI2L && in1->in(1)->Opcode() == Op_LoadI && mask == CONST64(0x00000000FFFFFFFF)) { Node* load = in1->in(1); - return new (phase->C, 3) LoadUI2LNode(load->in(MemNode::Control), + return new (phase->C) LoadUI2LNode(load->in(MemNode::Control), load->in(MemNode::Memory), load->in(MemNode::Address), load->adr_type()); @@ -619,9 +619,9 @@ // value. This check includes UI2L masks (0x00000000FFFFFFFF) which // would be optimized away later in Identity. if (op == Op_ConvI2L && (mask & CONST64(0xFFFFFFFF80000000)) == 0) { - Node* andi = new (phase->C, 3) AndINode(in1->in(1), phase->intcon(mask)); + Node* andi = new (phase->C) AndINode(in1->in(1), phase->intcon(mask)); andi = phase->transform(andi); - return new (phase->C, 2) ConvI2LNode(andi); + return new (phase->C) ConvI2LNode(andi); } // Masking off sign bits? Dont make them! @@ -635,8 +635,8 @@ // bits survive. NO sign-extension bits survive the maskings. if( (sign_bits_mask & mask) == 0 ) { // Use zero-fill shift instead - Node *zshift = phase->transform(new (phase->C, 3) URShiftLNode(in1->in(1), in1->in(2))); - return new (phase->C, 3) AndLNode(zshift, in(2)); + Node *zshift = phase->transform(new (phase->C) URShiftLNode(in1->in(1), in1->in(2))); + return new (phase->C) AndLNode(zshift, in(2)); } } } @@ -674,9 +674,9 @@ // and 'i2b' patterns which typically fold into 'StoreC/StoreB'. if( con < 16 ) { // Compute X << con0 - Node *lsh = phase->transform( new (phase->C, 3) LShiftINode( add1->in(1), in(2) ) ); + Node *lsh = phase->transform( new (phase->C) LShiftINode( add1->in(1), in(2) ) ); // Compute X<C, 3) AddINode( lsh, phase->intcon(t12->get_con() << con)); + return new (phase->C) AddINode( lsh, phase->intcon(t12->get_con() << con)); } } } @@ -685,7 +685,7 @@ if( (add1_op == Op_RShiftI || add1_op == Op_URShiftI ) && add1->in(2) == in(2) ) // Convert to "(x & -(1<C, 3) AndINode(add1->in(1),phase->intcon( -(1<C) AndINode(add1->in(1),phase->intcon( -(1<>c0) & Y)<in(2) == in(2) ) { // Convert to "(x & (Y<transform( new (phase->C, 3) LShiftINode( add1->in(2), in(2) ) ); - return new (phase->C, 3) AndINode( add2->in(1), y_sh ); + Node *y_sh = phase->transform( new (phase->C) LShiftINode( add1->in(2), in(2) ) ); + return new (phase->C) AndINode( add2->in(1), y_sh ); } } @@ -704,7 +704,7 @@ const jint bits_mask = right_n_bits(BitsPerJavaInteger-con); if( add1_op == Op_AndI && phase->type(add1->in(2)) == TypeInt::make( bits_mask ) ) - return new (phase->C, 3) LShiftINode( add1->in(1), in(2) ); + return new (phase->C) LShiftINode( add1->in(1), in(2) ); return NULL; } @@ -784,9 +784,9 @@ const TypeLong *t12 = phase->type(add1->in(2))->isa_long(); if( t12 && t12->is_con() ){ // Left input is an add of a con? // Compute X << con0 - Node *lsh = phase->transform( new (phase->C, 3) LShiftLNode( add1->in(1), in(2) ) ); + Node *lsh = phase->transform( new (phase->C) LShiftLNode( add1->in(1), in(2) ) ); // Compute X<C, 3) AddLNode( lsh, phase->longcon(t12->get_con() << con)); + return new (phase->C) AddLNode( lsh, phase->longcon(t12->get_con() << con)); } } @@ -794,7 +794,7 @@ if( (add1_op == Op_RShiftL || add1_op == Op_URShiftL ) && add1->in(2) == in(2) ) // Convert to "(x & -(1<C, 3) AndLNode(add1->in(1),phase->longcon( -(CONST64(1)<C) AndLNode(add1->in(1),phase->longcon( -(CONST64(1)<>c0) & Y)<in(2) == in(2) ) { // Convert to "(x & (Y<transform( new (phase->C, 3) LShiftLNode( add1->in(2), in(2) ) ); - return new (phase->C, 3) AndLNode( add2->in(1), y_sh ); + Node *y_sh = phase->transform( new (phase->C) LShiftLNode( add1->in(2), in(2) ) ); + return new (phase->C) AndLNode( add2->in(1), y_sh ); } } @@ -813,7 +813,7 @@ const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1); if( add1_op == Op_AndL && phase->type(add1->in(2)) == TypeLong::make( bits_mask ) ) - return new (phase->C, 3) LShiftLNode( add1->in(1), in(2) ); + return new (phase->C) LShiftLNode( add1->in(1), in(2) ); return NULL; } @@ -915,8 +915,8 @@ Node *x = mask->in(1); jint maskbits = t3->get_con(); // Convert to "(x >> shift) & (mask >> shift)" - Node *shr_nomask = phase->transform( new (phase->C, 3) RShiftINode(mask->in(1), in(2)) ); - return new (phase->C, 3) AndINode(shr_nomask, phase->intcon( maskbits >> shift)); + Node *shr_nomask = phase->transform( new (phase->C) RShiftINode(mask->in(1), in(2)) ); + return new (phase->C) AndINode(shr_nomask, phase->intcon( maskbits >> shift)); } // Check for "(short[i] <<16)>>16" which simply sign-extends @@ -939,7 +939,7 @@ } else if( ld->Opcode() == Op_LoadUS ) // Replace zero-extension-load with sign-extension-load - return new (phase->C, 3) LoadSNode( ld->in(MemNode::Control), + return new (phase->C) LoadSNode( ld->in(MemNode::Control), ld->in(MemNode::Memory), ld->in(MemNode::Address), ld->adr_type()); @@ -1124,7 +1124,7 @@ const int con2 = t12->get_con() & 31; // Shift count is always masked const int con3 = con+con2; if( con3 < 32 ) // Only merge shifts if total is < 32 - return new (phase->C, 3) URShiftINode( in(1)->in(1), phase->intcon(con3) ); + return new (phase->C) URShiftINode( in(1)->in(1), phase->intcon(con3) ); } } @@ -1137,9 +1137,9 @@ Node *lshl = add->in(1); if( lshl->Opcode() == Op_LShiftI && phase->type(lshl->in(2)) == t2 ) { - Node *y_z = phase->transform( new (phase->C, 3) URShiftINode(add->in(2),in(2)) ); - Node *sum = phase->transform( new (phase->C, 3) AddINode( lshl->in(1), y_z ) ); - return new (phase->C, 3) AndINode( sum, phase->intcon(mask) ); + Node *y_z = phase->transform( new (phase->C) URShiftINode(add->in(2),in(2)) ); + Node *sum = phase->transform( new (phase->C) AddINode( lshl->in(1), y_z ) ); + return new (phase->C) AndINode( sum, phase->intcon(mask) ); } } @@ -1152,8 +1152,8 @@ if( t3 && t3->is_con() ) { // Right input is a constant jint mask2 = t3->get_con(); mask2 >>= con; // *signed* shift downward (high-order zeroes do not help) - Node *newshr = phase->transform( new (phase->C, 3) URShiftINode(andi->in(1), in(2)) ); - return new (phase->C, 3) AndINode(newshr, phase->intcon(mask2)); + Node *newshr = phase->transform( new (phase->C) URShiftINode(andi->in(1), in(2)) ); + return new (phase->C) AndINode(newshr, phase->intcon(mask2)); // The negative values are easier to materialize than positive ones. // A typical case from address arithmetic is ((x & ~15) >> 4). // It's better to change that to ((x >> 4) & ~0) versus @@ -1165,7 +1165,7 @@ Node *shl = in(1); if( in1_op == Op_LShiftI && phase->type(shl->in(2)) == t2 ) - return new (phase->C, 3) AndINode( shl->in(1), phase->intcon(mask) ); + return new (phase->C) AndINode( shl->in(1), phase->intcon(mask) ); return NULL; } @@ -1270,9 +1270,9 @@ Node *lshl = add->in(1); if( lshl->Opcode() == Op_LShiftL && phase->type(lshl->in(2)) == t2 ) { - Node *y_z = phase->transform( new (phase->C, 3) URShiftLNode(add->in(2),in(2)) ); - Node *sum = phase->transform( new (phase->C, 3) AddLNode( lshl->in(1), y_z ) ); - return new (phase->C, 3) AndLNode( sum, phase->longcon(mask) ); + Node *y_z = phase->transform( new (phase->C) URShiftLNode(add->in(2),in(2)) ); + Node *sum = phase->transform( new (phase->C) AddLNode( lshl->in(1), y_z ) ); + return new (phase->C) AndLNode( sum, phase->longcon(mask) ); } } @@ -1285,8 +1285,8 @@ if( t3 && t3->is_con() ) { // Right input is a constant jlong mask2 = t3->get_con(); mask2 >>= con; // *signed* shift downward (high-order zeroes do not help) - Node *newshr = phase->transform( new (phase->C, 3) URShiftLNode(andi->in(1), in(2)) ); - return new (phase->C, 3) AndLNode(newshr, phase->longcon(mask2)); + Node *newshr = phase->transform( new (phase->C) URShiftLNode(andi->in(1), in(2)) ); + return new (phase->C) AndLNode(newshr, phase->longcon(mask2)); } } @@ -1294,7 +1294,7 @@ Node *shl = in(1); if( shl->Opcode() == Op_LShiftL && phase->type(shl->in(2)) == t2 ) - return new (phase->C, 3) AndLNode( shl->in(1), phase->longcon(mask) ); + return new (phase->C) AndLNode( shl->in(1), phase->longcon(mask) ); return NULL; } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/node.cpp --- a/src/share/vm/opto/node.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/node.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -296,6 +296,14 @@ assert(Compile::current() == C, "must use operator new(Compile*)"); int idx = C->next_unique(); + // Allocate memory for the necessary number of edges. + if (req > 0) { + // Allocate space for _in array to have double alignment. + _in = (Node **) ((char *) (C->node_arena()->Amalloc_D(req * sizeof(void*)))); +#ifdef ASSERT + _in[req-1] = this; // magic cookie for assertion check +#endif + } // If there are default notes floating around, capture them: Node_Notes* nn = C->default_node_notes(); if (nn != NULL) init_node_notes(C, idx, nn); @@ -1004,15 +1012,15 @@ // set_req(2, phase->intcon(7)); // return this; // Example: reshape "X*4" into "X<<2" -// return new (C,3) LShiftINode(in(1), phase->intcon(2)); +// return new (C) LShiftINode(in(1), phase->intcon(2)); // // You must call 'phase->transform(X)' on any new Nodes X you make, except // for the returned root node. Example: reshape "X*31" with "(X<<5)-X". -// Node *shift=phase->transform(new(C,3)LShiftINode(in(1),phase->intcon(5))); -// return new (C,3) AddINode(shift, in(1)); +// Node *shift=phase->transform(new(C)LShiftINode(in(1),phase->intcon(5))); +// return new (C) AddINode(shift, in(1)); // // When making a Node for a constant use 'phase->makecon' or 'phase->intcon'. -// These forms are faster than 'phase->transform(new (C,1) ConNode())' and Do +// These forms are faster than 'phase->transform(new (C) ConNode())' and Do // The Right Thing with def-use info. // // You cannot bury the 'this' Node inside of a graph reshape. If the reshaped diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/node.hpp --- a/src/share/vm/opto/node.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/node.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -217,18 +217,6 @@ return (void*)n; } - // New Operator that takes a Compile pointer, this will eventually - // be the "new" New operator. - inline void* operator new( size_t x, Compile* C, int y) { - Node* n = (Node*)C->node_arena()->Amalloc_D(x + y*sizeof(void*)); - n->_in = (Node**)(((char*)n) + x); -#ifdef ASSERT - n->_in[y-1] = n; // magic cookie for assertion check -#endif - n->_out = (Node**)C; - return (void*)n; - } - // Delete is a NOP void operator delete( void *ptr ) {} // Fancy destructor; eagerly attempt to reclaim Node numberings and storage diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/output.cpp --- a/src/share/vm/opto/output.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/output.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -265,9 +265,9 @@ Node* Compile::call_zap_node(MachSafePointNode* node_to_check, int block_no) { const TypeFunc *tf = OptoRuntime::zap_dead_locals_Type(); CallStaticJavaNode* ideal_node = - new (this, tf->domain()->cnt()) CallStaticJavaNode( tf, + new (this) CallStaticJavaNode( tf, OptoRuntime::zap_dead_locals_stub(_method->flags().is_native()), - "call zap dead locals stub", 0, TypePtr::BOTTOM); + "call zap dead locals stub", 0, TypePtr::BOTTOM); // We need to copy the OopMap from the site we're zapping at. // We have to make a copy, because the zap site might not be // a call site, and zap_dead is a call site. @@ -1869,7 +1869,9 @@ if (!do_scheduling()) return; - assert(MaxVectorSize <= 8, "scheduling code works only with pairs"); + // Scheduling code works only with pairs (8 bytes) maximum. + if (max_vector_size() > 8) + return; NOT_PRODUCT( TracePhase t2("isched", &_t_instrSched, TimeCompiler); ) @@ -2682,7 +2684,7 @@ if ( _pinch_free_list.size() > 0) { pinch = _pinch_free_list.pop(); } else { - pinch = new (_cfg->C, 1) Node(1); // Pinch point to-be + pinch = new (_cfg->C) Node(1); // Pinch point to-be } if (pinch->_idx >= _regalloc->node_regs_max_index()) { _cfg->C->record_method_not_compilable("too many D-U pinch points"); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/parse1.cpp --- a/src/share/vm/opto/parse1.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/parse1.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -107,10 +107,10 @@ // doubles on Sparc. Intel can handle them just fine directly. Node *l; switch( bt ) { // Signature is flattened - case T_INT: l = new (C, 3) LoadINode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break; - case T_FLOAT: l = new (C, 3) LoadFNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break; - case T_ADDRESS: l = new (C, 3) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM ); break; - case T_OBJECT: l = new (C, 3) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break; + case T_INT: l = new (C) LoadINode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break; + case T_FLOAT: l = new (C) LoadFNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break; + case T_ADDRESS: l = new (C) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM ); break; + case T_OBJECT: l = new (C) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break; case T_LONG: case T_DOUBLE: { // Since arguments are in reverse order, the argument address 'adr' @@ -118,12 +118,12 @@ adr = basic_plus_adr( local_addrs_base, local_addrs, -(index+1)*wordSize ); if( Matcher::misaligned_doubles_ok ) { l = (bt == T_DOUBLE) - ? (Node*)new (C, 3) LoadDNode( ctl, mem, adr, TypeRawPtr::BOTTOM ) - : (Node*)new (C, 3) LoadLNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); + ? (Node*)new (C) LoadDNode( ctl, mem, adr, TypeRawPtr::BOTTOM ) + : (Node*)new (C) LoadLNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); } else { l = (bt == T_DOUBLE) - ? (Node*)new (C, 3) LoadD_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM ) - : (Node*)new (C, 3) LoadL_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); + ? (Node*)new (C) LoadD_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM ) + : (Node*)new (C) LoadL_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); } break; } @@ -147,11 +147,11 @@ if (type == TypePtr::NULL_PTR || (tp != NULL && !tp->klass()->is_loaded())) { // Value must be null, not a real oop. - Node* chk = _gvn.transform( new (C, 3) CmpPNode(l, null()) ); - Node* tst = _gvn.transform( new (C, 2) BoolNode(chk, BoolTest::eq) ); + Node* chk = _gvn.transform( new (C) CmpPNode(l, null()) ); + Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) ); IfNode* iff = create_and_map_if(control(), tst, PROB_MAX, COUNT_UNKNOWN); - set_control(_gvn.transform( new (C, 1) IfTrueNode(iff) )); - Node* bad_type = _gvn.transform( new (C, 1) IfFalseNode(iff) ); + set_control(_gvn.transform( new (C) IfTrueNode(iff) )); + Node* bad_type = _gvn.transform( new (C) IfFalseNode(iff) ); bad_type_exit->control()->add_req(bad_type); l = null(); } @@ -218,7 +218,7 @@ Node *monitors_addr = basic_plus_adr(osr_buf, osr_buf, (max_locals+mcnt*2-1)*wordSize); for (index = 0; index < mcnt; index++) { // Make a BoxLockNode for the monitor. - Node *box = _gvn.transform(new (C, 1) BoxLockNode(next_monitor())); + Node *box = _gvn.transform(new (C) BoxLockNode(next_monitor())); // Displaced headers and locked objects are interleaved in the @@ -233,7 +233,7 @@ // Build a bogus FastLockNode (no code will be generated) and push the // monitor into our debug info. - const FastLockNode *flock = _gvn.transform(new (C, 3) FastLockNode( 0, lock_object, box ))->as_FastLock(); + const FastLockNode *flock = _gvn.transform(new (C) FastLockNode( 0, lock_object, box ))->as_FastLock(); map()->push_monitor(flock); // If the lock is our method synchronization lock, tuck it away in @@ -323,7 +323,7 @@ // Now that the interpreter state is loaded, make sure it will match // at execution time what the compiler is expecting now: SafePointNode* bad_type_exit = clone_map(); - bad_type_exit->set_control(new (C, 1) RegionNode(1)); + bad_type_exit->set_control(new (C) RegionNode(1)); assert(osr_block->flow()->jsrs()->size() == 0, "should be no jsrs live at osr point"); for (index = 0; index < max_locals; index++) { @@ -647,7 +647,7 @@ add_predicate(); // Add new region for back branches. int edges = block->pred_count() - block->preds_parsed() + 1; // +1 for original region - RegionNode *r = new (C, edges+1) RegionNode(edges+1); + RegionNode *r = new (C) RegionNode(edges+1); _gvn.set_type(r, Type::CONTROL); record_for_igvn(r); r->init_req(edges, control()); @@ -714,14 +714,14 @@ _exits.clean_stack(_exits.sp()); _exits.sync_jvms(); - RegionNode* region = new (C, 1) RegionNode(1); + RegionNode* region = new (C) RegionNode(1); record_for_igvn(region); gvn().set_type_bottom(region); _exits.set_control(region); // Note: iophi and memphi are not transformed until do_exits. - Node* iophi = new (C, region->req()) PhiNode(region, Type::ABIO); - Node* memphi = new (C, region->req()) PhiNode(region, Type::MEMORY, TypePtr::BOTTOM); + Node* iophi = new (C) PhiNode(region, Type::ABIO); + Node* memphi = new (C) PhiNode(region, Type::MEMORY, TypePtr::BOTTOM); _exits.set_i_o(iophi); _exits.set_all_memory(memphi); @@ -736,7 +736,7 @@ ret_type = TypeOopPtr::BOTTOM; } int ret_size = type2size[ret_type->basic_type()]; - Node* ret_phi = new (C, region->req()) PhiNode(region, ret_type); + Node* ret_phi = new (C) PhiNode(region, ret_type); _exits.ensure_stack(ret_size); assert((int)(tf()->range()->cnt() - TypeFunc::Parms) == ret_size, "good tf range"); assert(method()->return_type()->size() == ret_size, "tf agrees w/ method"); @@ -753,7 +753,7 @@ int arg_size = tf->domain()->cnt(); int max_size = MAX2(arg_size, (int)tf->range()->cnt()); JVMState* jvms = new (this) JVMState(max_size - TypeFunc::Parms); - SafePointNode* map = new (this, max_size) SafePointNode(max_size, NULL); + SafePointNode* map = new (this) SafePointNode(max_size, NULL); record_for_igvn(map); assert(arg_size == TypeFunc::Parms + (is_osr_compilation() ? 1 : method()->arg_size()), "correct arg_size"); Node_Notes* old_nn = default_node_notes(); @@ -767,7 +767,7 @@ } uint i; for (i = 0; i < (uint)arg_size; i++) { - Node* parm = initial_gvn()->transform(new (this, 1) ParmNode(start, i)); + Node* parm = initial_gvn()->transform(new (this) ParmNode(start, i)); map->init_req(i, parm); // Record all these guys for later GVN. record_for_igvn(parm); @@ -798,7 +798,7 @@ //--------------------------return_values-------------------------------------- void Compile::return_values(JVMState* jvms) { GraphKit kit(jvms); - Node* ret = new (this, TypeFunc::Parms) ReturnNode(TypeFunc::Parms, + Node* ret = new (this) ReturnNode(TypeFunc::Parms, kit.control(), kit.i_o(), kit.reset_memory(), @@ -826,7 +826,7 @@ // Load my combined exception state into the kit, with all phis transformed: SafePointNode* ex_map = kit.combine_and_pop_all_exception_states(); Node* ex_oop = kit.use_exception_state(ex_map); - RethrowNode* exit = new (this, TypeFunc::Parms + 1) RethrowNode(kit.control(), + RethrowNode* exit = new (this) RethrowNode(kit.control(), kit.i_o(), kit.reset_memory(), kit.frameptr(), kit.returnadr(), // like a return but with exception input @@ -1020,7 +1020,7 @@ // Create an initial safepoint to hold JVM state during parsing JVMState* jvms = new (C) JVMState(method(), _caller->has_method() ? _caller : NULL); - set_map(new (C, len) SafePointNode(len, jvms)); + set_map(new (C) SafePointNode(len, jvms)); jvms->set_map(map()); record_for_igvn(map()); assert(jvms->endoff() == len, "correct jvms sizing"); @@ -1528,7 +1528,7 @@ // later lazily. int edges = target->pred_count(); if (edges < pnum) edges = pnum; // might be a new path! - RegionNode *r = new (C, edges+1) RegionNode(edges+1); + RegionNode *r = new (C) RegionNode(edges+1); gvn().set_type(r, Type::CONTROL); record_for_igvn(r); // zap all inputs to NULL for debugging (done in Node(uint) constructor) @@ -1923,19 +1923,19 @@ Node* access_flags_addr = basic_plus_adr(klass, klass, in_bytes(Klass::access_flags_offset())); Node* access_flags = make_load(NULL, access_flags_addr, TypeInt::INT, T_INT); - Node* mask = _gvn.transform(new (C, 3) AndINode(access_flags, intcon(JVM_ACC_HAS_FINALIZER))); - Node* check = _gvn.transform(new (C, 3) CmpINode(mask, intcon(0))); - Node* test = _gvn.transform(new (C, 2) BoolNode(check, BoolTest::ne)); + Node* mask = _gvn.transform(new (C) AndINode(access_flags, intcon(JVM_ACC_HAS_FINALIZER))); + Node* check = _gvn.transform(new (C) CmpINode(mask, intcon(0))); + Node* test = _gvn.transform(new (C) BoolNode(check, BoolTest::ne)); IfNode* iff = create_and_map_if(control(), test, PROB_MAX, COUNT_UNKNOWN); - RegionNode* result_rgn = new (C, 3) RegionNode(3); + RegionNode* result_rgn = new (C) RegionNode(3); record_for_igvn(result_rgn); - Node *skip_register = _gvn.transform(new (C, 1) IfFalseNode(iff)); + Node *skip_register = _gvn.transform(new (C) IfFalseNode(iff)); result_rgn->init_req(1, skip_register); - Node *needs_register = _gvn.transform(new (C, 1) IfTrueNode(iff)); + Node *needs_register = _gvn.transform(new (C) IfTrueNode(iff)); set_control(needs_register); if (stopped()) { // There is no slow path. @@ -2013,7 +2013,7 @@ // sharpen the type eagerly; this eases certain assert checking if (tp->higher_equal(TypeInstPtr::NOTNULL)) tr = tr->join(TypeInstPtr::NOTNULL)->is_instptr(); - value = _gvn.transform(new (C, 2) CheckCastPPNode(0,value,tr)); + value = _gvn.transform(new (C) CheckCastPPNode(0,value,tr)); } } phi->add_req(value); @@ -2048,7 +2048,7 @@ kill_dead_locals(); // Clone the JVM State - SafePointNode *sfpnt = new (C, parms) SafePointNode(parms, NULL); + SafePointNode *sfpnt = new (C) SafePointNode(parms, NULL); // Capture memory state BEFORE a SafePoint. Since we can block at a // SafePoint we need our GC state to be safe; i.e. we need all our current diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/parse2.cpp --- a/src/share/vm/opto/parse2.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/parse2.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -127,9 +127,9 @@ Node* len = load_array_length(ary); // Test length vs index (standard trick using unsigned compare) - Node* chk = _gvn.transform( new (C, 3) CmpUNode(idx, len) ); + Node* chk = _gvn.transform( new (C) CmpUNode(idx, len) ); BoolTest::mask btest = BoolTest::lt; - tst = _gvn.transform( new (C, 2) BoolNode(chk, btest) ); + tst = _gvn.transform( new (C) BoolNode(chk, btest) ); } // Branch to failure if out of bounds { BuildCutout unless(this, tst, PROB_MAX); @@ -165,15 +165,15 @@ // returns IfNode IfNode* Parse::jump_if_fork_int(Node* a, Node* b, BoolTest::mask mask) { - Node *cmp = _gvn.transform( new (C, 3) CmpINode( a, b)); // two cases: shiftcount > 32 and shiftcount <= 32 - Node *tst = _gvn.transform( new (C, 2) BoolNode( cmp, mask)); + Node *cmp = _gvn.transform( new (C) CmpINode( a, b)); // two cases: shiftcount > 32 and shiftcount <= 32 + Node *tst = _gvn.transform( new (C) BoolNode( cmp, mask)); IfNode *iff = create_and_map_if( control(), tst, ((mask == BoolTest::eq) ? PROB_STATIC_INFREQUENT : PROB_FAIR), COUNT_UNKNOWN ); return iff; } // return Region node Node* Parse::jump_if_join(Node* iffalse, Node* iftrue) { - Node *region = new (C, 3) RegionNode(3); // 2 results + Node *region = new (C) RegionNode(3); // 2 results record_for_igvn(region); region->init_req(1, iffalse); region->init_req(2, iftrue ); @@ -188,28 +188,28 @@ void Parse::jump_if_true_fork(IfNode *iff, int dest_bci_if_true, int prof_table_index) { // True branch, use existing map info { PreserveJVMState pjvms(this); - Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode (iff) ); + Node *iftrue = _gvn.transform( new (C) IfTrueNode (iff) ); set_control( iftrue ); profile_switch_case(prof_table_index); merge_new_path(dest_bci_if_true); } // False branch - Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(iff) ); + Node *iffalse = _gvn.transform( new (C) IfFalseNode(iff) ); set_control( iffalse ); } void Parse::jump_if_false_fork(IfNode *iff, int dest_bci_if_true, int prof_table_index) { // True branch, use existing map info { PreserveJVMState pjvms(this); - Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode (iff) ); + Node *iffalse = _gvn.transform( new (C) IfFalseNode (iff) ); set_control( iffalse ); profile_switch_case(prof_table_index); merge_new_path(dest_bci_if_true); } // False branch - Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode(iff) ); + Node *iftrue = _gvn.transform( new (C) IfTrueNode(iff) ); set_control( iftrue ); } @@ -437,14 +437,14 @@ // Normalize table lookups to zero int lowval = lo->lo(); - key_val = _gvn.transform( new (C, 3) SubINode(key_val, _gvn.intcon(lowval)) ); + key_val = _gvn.transform( new (C) SubINode(key_val, _gvn.intcon(lowval)) ); // Generate a guard to protect against input keyvals that aren't // in the switch domain. if (needs_guard) { Node* size = _gvn.intcon(num_cases); - Node* cmp = _gvn.transform( new (C, 3) CmpUNode(key_val, size) ); - Node* tst = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ge) ); + Node* cmp = _gvn.transform( new (C) CmpUNode(key_val, size) ); + Node* tst = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ge) ); IfNode* iff = create_and_map_if( control(), tst, PROB_FAIR, COUNT_UNKNOWN); jump_if_true_fork(iff, default_dest, NullTableIndex); } @@ -457,21 +457,21 @@ // Clean the 32-bit int into a real 64-bit offset. // Otherwise, the jint value 0 might turn into an offset of 0x0800000000. const TypeLong* lkeytype = TypeLong::make(CONST64(0), num_cases-1, Type::WidenMin); - key_val = _gvn.transform( new (C, 2) ConvI2LNode(key_val, lkeytype) ); + key_val = _gvn.transform( new (C) ConvI2LNode(key_val, lkeytype) ); #endif // Shift the value by wordsize so we have an index into the table, rather // than a switch value Node *shiftWord = _gvn.MakeConX(wordSize); - key_val = _gvn.transform( new (C, 3) MulXNode( key_val, shiftWord)); + key_val = _gvn.transform( new (C) MulXNode( key_val, shiftWord)); // Create the JumpNode - Node* jtn = _gvn.transform( new (C, 2) JumpNode(control(), key_val, num_cases) ); + Node* jtn = _gvn.transform( new (C) JumpNode(control(), key_val, num_cases) ); // These are the switch destinations hanging off the jumpnode int i = 0; for (SwitchRange* r = lo; r <= hi; r++) { for (int j = r->lo(); j <= r->hi(); j++, i++) { - Node* input = _gvn.transform(new (C, 1) JumpProjNode(jtn, i, r->dest(), j - lowval)); + Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), j - lowval)); { PreserveJVMState pjvms(this); set_control(input); @@ -572,8 +572,8 @@ // two comparisons of same values--should enable 1 test for 2 branches // Use BoolTest::le instead of BoolTest::gt IfNode *iff_le = jump_if_fork_int(key_val, test_val, BoolTest::le); - Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode(iff_le) ); - Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(iff_le) ); + Node *iftrue = _gvn.transform( new (C) IfTrueNode(iff_le) ); + Node *iffalse = _gvn.transform( new (C) IfFalseNode(iff_le) ); { PreserveJVMState pjvms(this); set_control(iffalse); jump_switch_ranges(key_val, mid+1, hi, switch_depth+1); @@ -589,8 +589,8 @@ if (mid == hi) { jump_if_true_fork(iff_ge, mid->dest(), mid->table_index()); } else { - Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode(iff_ge) ); - Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(iff_ge) ); + Node *iftrue = _gvn.transform( new (C) IfTrueNode(iff_ge) ); + Node *iffalse = _gvn.transform( new (C) IfFalseNode(iff_ge) ); { PreserveJVMState pjvms(this); set_control(iftrue); jump_switch_ranges(key_val, mid, hi, switch_depth+1); @@ -645,7 +645,7 @@ CAST_FROM_FN_PTR(address, SharedRuntime::frem), "frem", NULL, //no memory effects f1, f2); - Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms + 0)); + Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 0)); push(res); } @@ -657,10 +657,10 @@ CAST_FROM_FN_PTR(address, SharedRuntime::drem), "drem", NULL, //no memory effects d1, top(), d2, top()); - Node* res_d = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms + 0)); + Node* res_d = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 0)); #ifdef ASSERT - Node* res_top = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms + 1)); + Node* res_top = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 1)); assert(res_top == top(), "second value must be top"); #endif @@ -674,7 +674,7 @@ CAST_FROM_FN_PTR(address, SharedRuntime::l2f), "l2f", NULL, //no memory effects f1, f2); - Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms + 0)); + Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 0)); push(res); } @@ -701,17 +701,17 @@ // Sigh, must handle negative dividends Node *zero = _gvn.intcon(0); IfNode *ifff = jump_if_fork_int(a, zero, BoolTest::lt); - Node *iff = _gvn.transform( new (C, 1) IfFalseNode(ifff) ); - Node *ift = _gvn.transform( new (C, 1) IfTrueNode (ifff) ); + Node *iff = _gvn.transform( new (C) IfFalseNode(ifff) ); + Node *ift = _gvn.transform( new (C) IfTrueNode (ifff) ); Node *reg = jump_if_join(ift, iff); Node *phi = PhiNode::make(reg, NULL, TypeInt::INT); // Negative path; negate/and/negate - Node *neg = _gvn.transform( new (C, 3) SubINode(zero, a) ); - Node *andn= _gvn.transform( new (C, 3) AndINode(neg, mask) ); - Node *negn= _gvn.transform( new (C, 3) SubINode(zero, andn) ); + Node *neg = _gvn.transform( new (C) SubINode(zero, a) ); + Node *andn= _gvn.transform( new (C) AndINode(neg, mask) ); + Node *negn= _gvn.transform( new (C) SubINode(zero, andn) ); phi->init_req(1, negn); // Fast positive case - Node *andx = _gvn.transform( new (C, 3) AndINode(a, mask) ); + Node *andx = _gvn.transform( new (C) AndINode(a, mask) ); phi->init_req(2, andx); // Push the merge push( _gvn.transform(phi) ); @@ -720,7 +720,7 @@ } } // Default case - push( _gvn.transform( new (C, 3) ModINode(control(),a,b) ) ); + push( _gvn.transform( new (C) ModINode(control(),a,b) ) ); } // Handle jsr and jsr_w bytecode @@ -997,7 +997,7 @@ explicit_null_checks_inserted++; // Generate real control flow - Node *tst = _gvn.transform( new (C, 2) BoolNode( c, btest ) ); + Node *tst = _gvn.transform( new (C) BoolNode( c, btest ) ); // Sanity check the probability value assert(prob > 0.0f,"Bad probability in Parser"); @@ -1006,7 +1006,7 @@ assert(iff->_prob > 0.0f,"Optimizer made bad probability in parser"); // True branch { PreserveJVMState pjvms(this); - Node* iftrue = _gvn.transform( new (C, 1) IfTrueNode (iff) ); + Node* iftrue = _gvn.transform( new (C) IfTrueNode (iff) ); set_control(iftrue); if (stopped()) { // Path is dead? @@ -1026,7 +1026,7 @@ } // False branch - Node* iffalse = _gvn.transform( new (C, 1) IfFalseNode(iff) ); + Node* iffalse = _gvn.transform( new (C) IfFalseNode(iff) ); set_control(iffalse); if (stopped()) { // Path is dead? @@ -1089,7 +1089,7 @@ } assert(btest != BoolTest::eq, "!= is the only canonical exact test"); - Node* tst0 = new (C, 2) BoolNode(c, btest); + Node* tst0 = new (C) BoolNode(c, btest); Node* tst = _gvn.transform(tst0); BoolTest::mask taken_btest = BoolTest::illegal; BoolTest::mask untaken_btest = BoolTest::illegal; @@ -1120,8 +1120,8 @@ float true_prob = (taken_if_true ? prob : untaken_prob); IfNode* iff = create_and_map_if(control(), tst, true_prob, cnt); assert(iff->_prob > 0.0f,"Optimizer made bad probability in parser"); - Node* taken_branch = new (C, 1) IfTrueNode(iff); - Node* untaken_branch = new (C, 1) IfFalseNode(iff); + Node* taken_branch = new (C) IfTrueNode(iff); + Node* untaken_branch = new (C) IfFalseNode(iff); if (!taken_if_true) { // Finish conversion to canonical form Node* tmp = taken_branch; taken_branch = untaken_branch; @@ -1285,7 +1285,7 @@ JVMState* jvms = this->jvms(); if (obj_in_map >= 0 && (jvms->is_loc(obj_in_map) || jvms->is_stk(obj_in_map))) { - TypeNode* ccast = new (C, 2) CheckCastPPNode(control(), obj, tboth); + TypeNode* ccast = new (C) CheckCastPPNode(control(), obj, tboth); const Type* tcc = ccast->as_Type()->type(); assert(tcc != obj_type && tcc->higher_equal(obj_type), "must improve"); // Delay transform() call to allow recovery of pre-cast value @@ -1320,10 +1320,10 @@ const Type* tboth = tcon->join(tval); if (tboth == tval) break; // Nothing to gain. if (tcon->isa_int()) { - ccast = new (C, 2) CastIINode(val, tboth); + ccast = new (C) CastIINode(val, tboth); } else if (tcon == TypePtr::NULL_PTR) { // Cast to null, but keep the pointer identity temporarily live. - ccast = new (C, 2) CastPPNode(val, tboth); + ccast = new (C) CastPPNode(val, tboth); } else { const TypeF* tf = tcon->isa_float_constant(); const TypeD* td = tcon->isa_double_constant(); @@ -1738,59 +1738,59 @@ if (stopped()) return; b = pop(); a = pop(); - push( _gvn.transform( new (C, 3) DivINode(control(),a,b) ) ); + push( _gvn.transform( new (C) DivINode(control(),a,b) ) ); break; case Bytecodes::_imul: b = pop(); a = pop(); - push( _gvn.transform( new (C, 3) MulINode(a,b) ) ); + push( _gvn.transform( new (C) MulINode(a,b) ) ); break; case Bytecodes::_iadd: b = pop(); a = pop(); - push( _gvn.transform( new (C, 3) AddINode(a,b) ) ); + push( _gvn.transform( new (C) AddINode(a,b) ) ); break; case Bytecodes::_ineg: a = pop(); - push( _gvn.transform( new (C, 3) SubINode(_gvn.intcon(0),a)) ); + push( _gvn.transform( new (C) SubINode(_gvn.intcon(0),a)) ); break; case Bytecodes::_isub: b = pop(); a = pop(); - push( _gvn.transform( new (C, 3) SubINode(a,b) ) ); + push( _gvn.transform( new (C) SubINode(a,b) ) ); break; case Bytecodes::_iand: b = pop(); a = pop(); - push( _gvn.transform( new (C, 3) AndINode(a,b) ) ); + push( _gvn.transform( new (C) AndINode(a,b) ) ); break; case Bytecodes::_ior: b = pop(); a = pop(); - push( _gvn.transform( new (C, 3) OrINode(a,b) ) ); + push( _gvn.transform( new (C) OrINode(a,b) ) ); break; case Bytecodes::_ixor: b = pop(); a = pop(); - push( _gvn.transform( new (C, 3) XorINode(a,b) ) ); + push( _gvn.transform( new (C) XorINode(a,b) ) ); break; case Bytecodes::_ishl: b = pop(); a = pop(); - push( _gvn.transform( new (C, 3) LShiftINode(a,b) ) ); + push( _gvn.transform( new (C) LShiftINode(a,b) ) ); break; case Bytecodes::_ishr: b = pop(); a = pop(); - push( _gvn.transform( new (C, 3) RShiftINode(a,b) ) ); + push( _gvn.transform( new (C) RShiftINode(a,b) ) ); break; case Bytecodes::_iushr: b = pop(); a = pop(); - push( _gvn.transform( new (C, 3) URShiftINode(a,b) ) ); + push( _gvn.transform( new (C) URShiftINode(a,b) ) ); break; case Bytecodes::_fneg: a = pop(); - b = _gvn.transform(new (C, 2) NegFNode (a)); + b = _gvn.transform(new (C) NegFNode (a)); push(b); break; case Bytecodes::_fsub: b = pop(); a = pop(); - c = _gvn.transform( new (C, 3) SubFNode(a,b) ); + c = _gvn.transform( new (C) SubFNode(a,b) ); d = precision_rounding(c); push( d ); break; @@ -1798,7 +1798,7 @@ case Bytecodes::_fadd: b = pop(); a = pop(); - c = _gvn.transform( new (C, 3) AddFNode(a,b) ); + c = _gvn.transform( new (C) AddFNode(a,b) ); d = precision_rounding(c); push( d ); break; @@ -1806,7 +1806,7 @@ case Bytecodes::_fmul: b = pop(); a = pop(); - c = _gvn.transform( new (C, 3) MulFNode(a,b) ); + c = _gvn.transform( new (C) MulFNode(a,b) ); d = precision_rounding(c); push( d ); break; @@ -1814,7 +1814,7 @@ case Bytecodes::_fdiv: b = pop(); a = pop(); - c = _gvn.transform( new (C, 3) DivFNode(0,a,b) ); + c = _gvn.transform( new (C) DivFNode(0,a,b) ); d = precision_rounding(c); push( d ); break; @@ -1824,7 +1824,7 @@ // Generate a ModF node. b = pop(); a = pop(); - c = _gvn.transform( new (C, 3) ModFNode(0,a,b) ); + c = _gvn.transform( new (C) ModFNode(0,a,b) ); d = precision_rounding(c); push( d ); } @@ -1837,7 +1837,7 @@ case Bytecodes::_fcmpl: b = pop(); a = pop(); - c = _gvn.transform( new (C, 3) CmpF3Node( a, b)); + c = _gvn.transform( new (C) CmpF3Node( a, b)); push(c); break; case Bytecodes::_fcmpg: @@ -1849,40 +1849,40 @@ // as well by using CmpF3 which implements unordered-lesser instead of // unordered-greater semantics. Finally, commute the result bits. Result // is same as using a CmpF3Greater except we did it with CmpF3 alone. - c = _gvn.transform( new (C, 3) CmpF3Node( b, a)); - c = _gvn.transform( new (C, 3) SubINode(_gvn.intcon(0),c) ); + c = _gvn.transform( new (C) CmpF3Node( b, a)); + c = _gvn.transform( new (C) SubINode(_gvn.intcon(0),c) ); push(c); break; case Bytecodes::_f2i: a = pop(); - push(_gvn.transform(new (C, 2) ConvF2INode(a))); + push(_gvn.transform(new (C) ConvF2INode(a))); break; case Bytecodes::_d2i: a = pop_pair(); - b = _gvn.transform(new (C, 2) ConvD2INode(a)); + b = _gvn.transform(new (C) ConvD2INode(a)); push( b ); break; case Bytecodes::_f2d: a = pop(); - b = _gvn.transform( new (C, 2) ConvF2DNode(a)); + b = _gvn.transform( new (C) ConvF2DNode(a)); push_pair( b ); break; case Bytecodes::_d2f: a = pop_pair(); - b = _gvn.transform( new (C, 2) ConvD2FNode(a)); + b = _gvn.transform( new (C) ConvD2FNode(a)); // This breaks _227_mtrt (speed & correctness) and _222_mpegaudio (speed) - //b = _gvn.transform(new (C, 2) RoundFloatNode(0, b) ); + //b = _gvn.transform(new (C) RoundFloatNode(0, b) ); push( b ); break; case Bytecodes::_l2f: if (Matcher::convL2FSupported()) { a = pop_pair(); - b = _gvn.transform( new (C, 2) ConvL2FNode(a)); + b = _gvn.transform( new (C) ConvL2FNode(a)); // For i486.ad, FILD doesn't restrict precision to 24 or 53 bits. // Rather than storing the result into an FP register then pushing // out to memory to round, the machine instruction that implements @@ -1897,7 +1897,7 @@ case Bytecodes::_l2d: a = pop_pair(); - b = _gvn.transform( new (C, 2) ConvL2DNode(a)); + b = _gvn.transform( new (C) ConvL2DNode(a)); // For i486.ad, rounding is always necessary (see _l2f above). // c = dprecision_rounding(b); c = _gvn.transform(b); @@ -1906,20 +1906,20 @@ case Bytecodes::_f2l: a = pop(); - b = _gvn.transform( new (C, 2) ConvF2LNode(a)); + b = _gvn.transform( new (C) ConvF2LNode(a)); push_pair(b); break; case Bytecodes::_d2l: a = pop_pair(); - b = _gvn.transform( new (C, 2) ConvD2LNode(a)); + b = _gvn.transform( new (C) ConvD2LNode(a)); push_pair(b); break; case Bytecodes::_dsub: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) SubDNode(a,b) ); + c = _gvn.transform( new (C) SubDNode(a,b) ); d = dprecision_rounding(c); push_pair( d ); break; @@ -1927,7 +1927,7 @@ case Bytecodes::_dadd: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) AddDNode(a,b) ); + c = _gvn.transform( new (C) AddDNode(a,b) ); d = dprecision_rounding(c); push_pair( d ); break; @@ -1935,7 +1935,7 @@ case Bytecodes::_dmul: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) MulDNode(a,b) ); + c = _gvn.transform( new (C) MulDNode(a,b) ); d = dprecision_rounding(c); push_pair( d ); break; @@ -1943,14 +1943,14 @@ case Bytecodes::_ddiv: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) DivDNode(0,a,b) ); + c = _gvn.transform( new (C) DivDNode(0,a,b) ); d = dprecision_rounding(c); push_pair( d ); break; case Bytecodes::_dneg: a = pop_pair(); - b = _gvn.transform(new (C, 2) NegDNode (a)); + b = _gvn.transform(new (C) NegDNode (a)); push_pair(b); break; @@ -1961,7 +1961,7 @@ a = pop_pair(); // a % b - c = _gvn.transform( new (C, 3) ModDNode(0,a,b) ); + c = _gvn.transform( new (C) ModDNode(0,a,b) ); d = dprecision_rounding(c); push_pair( d ); } @@ -1974,7 +1974,7 @@ case Bytecodes::_dcmpl: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) CmpD3Node( a, b)); + c = _gvn.transform( new (C) CmpD3Node( a, b)); push(c); break; @@ -1987,8 +1987,8 @@ // unordered-lesser instead of unordered-greater semantics. // Finally, negate the result bits. Result is same as using a // CmpD3Greater except we did it with CmpD3 alone. - c = _gvn.transform( new (C, 3) CmpD3Node( b, a)); - c = _gvn.transform( new (C, 3) SubINode(_gvn.intcon(0),c) ); + c = _gvn.transform( new (C) CmpD3Node( b, a)); + c = _gvn.transform( new (C) SubINode(_gvn.intcon(0),c) ); push(c); break; @@ -1997,44 +1997,44 @@ case Bytecodes::_land: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) AndLNode(a,b) ); + c = _gvn.transform( new (C) AndLNode(a,b) ); push_pair(c); break; case Bytecodes::_lor: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) OrLNode(a,b) ); + c = _gvn.transform( new (C) OrLNode(a,b) ); push_pair(c); break; case Bytecodes::_lxor: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) XorLNode(a,b) ); + c = _gvn.transform( new (C) XorLNode(a,b) ); push_pair(c); break; case Bytecodes::_lshl: b = pop(); // the shift count a = pop_pair(); // value to be shifted - c = _gvn.transform( new (C, 3) LShiftLNode(a,b) ); + c = _gvn.transform( new (C) LShiftLNode(a,b) ); push_pair(c); break; case Bytecodes::_lshr: b = pop(); // the shift count a = pop_pair(); // value to be shifted - c = _gvn.transform( new (C, 3) RShiftLNode(a,b) ); + c = _gvn.transform( new (C) RShiftLNode(a,b) ); push_pair(c); break; case Bytecodes::_lushr: b = pop(); // the shift count a = pop_pair(); // value to be shifted - c = _gvn.transform( new (C, 3) URShiftLNode(a,b) ); + c = _gvn.transform( new (C) URShiftLNode(a,b) ); push_pair(c); break; case Bytecodes::_lmul: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) MulLNode(a,b) ); + c = _gvn.transform( new (C) MulLNode(a,b) ); push_pair(c); break; @@ -2046,7 +2046,7 @@ if (stopped()) return; b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) ModLNode(control(),a,b) ); + c = _gvn.transform( new (C) ModLNode(control(),a,b) ); push_pair(c); break; @@ -2058,20 +2058,20 @@ if (stopped()) return; b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) DivLNode(control(),a,b) ); + c = _gvn.transform( new (C) DivLNode(control(),a,b) ); push_pair(c); break; case Bytecodes::_ladd: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) AddLNode(a,b) ); + c = _gvn.transform( new (C) AddLNode(a,b) ); push_pair(c); break; case Bytecodes::_lsub: b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) SubLNode(a,b) ); + c = _gvn.transform( new (C) SubLNode(a,b) ); push_pair(c); break; case Bytecodes::_lcmp: @@ -2102,58 +2102,58 @@ } b = pop_pair(); a = pop_pair(); - c = _gvn.transform( new (C, 3) CmpL3Node( a, b )); + c = _gvn.transform( new (C) CmpL3Node( a, b )); push(c); break; case Bytecodes::_lneg: a = pop_pair(); - b = _gvn.transform( new (C, 3) SubLNode(longcon(0),a)); + b = _gvn.transform( new (C) SubLNode(longcon(0),a)); push_pair(b); break; case Bytecodes::_l2i: a = pop_pair(); - push( _gvn.transform( new (C, 2) ConvL2INode(a))); + push( _gvn.transform( new (C) ConvL2INode(a))); break; case Bytecodes::_i2l: a = pop(); - b = _gvn.transform( new (C, 2) ConvI2LNode(a)); + b = _gvn.transform( new (C) ConvI2LNode(a)); push_pair(b); break; case Bytecodes::_i2b: // Sign extend a = pop(); - a = _gvn.transform( new (C, 3) LShiftINode(a,_gvn.intcon(24)) ); - a = _gvn.transform( new (C, 3) RShiftINode(a,_gvn.intcon(24)) ); + a = _gvn.transform( new (C) LShiftINode(a,_gvn.intcon(24)) ); + a = _gvn.transform( new (C) RShiftINode(a,_gvn.intcon(24)) ); push( a ); break; case Bytecodes::_i2s: a = pop(); - a = _gvn.transform( new (C, 3) LShiftINode(a,_gvn.intcon(16)) ); - a = _gvn.transform( new (C, 3) RShiftINode(a,_gvn.intcon(16)) ); + a = _gvn.transform( new (C) LShiftINode(a,_gvn.intcon(16)) ); + a = _gvn.transform( new (C) RShiftINode(a,_gvn.intcon(16)) ); push( a ); break; case Bytecodes::_i2c: a = pop(); - push( _gvn.transform( new (C, 3) AndINode(a,_gvn.intcon(0xFFFF)) ) ); + push( _gvn.transform( new (C) AndINode(a,_gvn.intcon(0xFFFF)) ) ); break; case Bytecodes::_i2f: a = pop(); - b = _gvn.transform( new (C, 2) ConvI2FNode(a) ) ; + b = _gvn.transform( new (C) ConvI2FNode(a) ) ; c = precision_rounding(b); push (b); break; case Bytecodes::_i2d: a = pop(); - b = _gvn.transform( new (C, 2) ConvI2DNode(a)); + b = _gvn.transform( new (C) ConvI2DNode(a)); push_pair(b); break; case Bytecodes::_iinc: // Increment local i = iter().get_index(); // Get local index - set_local( i, _gvn.transform( new (C, 3) AddINode( _gvn.intcon(iter().get_iinc_con()), local(i) ) ) ); + set_local( i, _gvn.transform( new (C) AddINode( _gvn.intcon(iter().get_iinc_con()), local(i) ) ) ); break; // Exit points of synchronized methods must have an unlock node @@ -2225,7 +2225,7 @@ maybe_add_safepoint(iter().get_dest()); a = null(); b = pop(); - c = _gvn.transform( new (C, 3) CmpPNode(b, a) ); + c = _gvn.transform( new (C) CmpPNode(b, a) ); do_ifnull(btest, c); break; @@ -2236,7 +2236,7 @@ maybe_add_safepoint(iter().get_dest()); a = pop(); b = pop(); - c = _gvn.transform( new (C, 3) CmpPNode(b, a) ); + c = _gvn.transform( new (C) CmpPNode(b, a) ); do_if(btest, c); break; @@ -2251,7 +2251,7 @@ maybe_add_safepoint(iter().get_dest()); a = _gvn.intcon(0); b = pop(); - c = _gvn.transform( new (C, 3) CmpINode(b, a) ); + c = _gvn.transform( new (C) CmpINode(b, a) ); do_if(btest, c); break; @@ -2266,7 +2266,7 @@ maybe_add_safepoint(iter().get_dest()); a = pop(); b = pop(); - c = _gvn.transform( new (C, 3) CmpINode( b, a ) ); + c = _gvn.transform( new (C) CmpINode( b, a ) ); do_if(btest, c); break; diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/parse3.cpp --- a/src/share/vm/opto/parse3.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/parse3.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -510,7 +510,7 @@ dims); } - Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms)); + Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms)); const Type* type = TypeOopPtr::make_from_klass_raw(array_klass); @@ -524,7 +524,7 @@ // We cannot sharpen the nested sub-arrays, since the top level is mutable. - Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) ); + Node* cast = _gvn.transform( new (C) CheckCastPPNode(control(), res, type) ); push(cast); // Possible improvements: diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/parseHelper.cpp --- a/src/share/vm/opto/parseHelper.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/parseHelper.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -43,7 +43,7 @@ const char *call_name = is_entry ? "dtrace_method_entry" : "dtrace_method_exit"; // Get base of thread-local storage area - Node* thread = _gvn.transform( new (C, 1) ThreadLocalNode() ); + Node* thread = _gvn.transform( new (C) ThreadLocalNode() ); // Get method const TypePtr* method_type = TypeMetadataPtr::make(method); @@ -175,8 +175,8 @@ // Make a constant out of the inexact array klass const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr(); Node* con = makecon(extak); - Node* cmp = _gvn.transform(new (C, 3) CmpPNode( array_klass, con )); - Node* bol = _gvn.transform(new (C, 2) BoolNode( cmp, BoolTest::eq )); + Node* cmp = _gvn.transform(new (C) CmpPNode( array_klass, con )); + Node* bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::eq )); Node* ctrl= control(); { BuildCutout unless(this, bol, PROB_MAX); uncommon_trap(Deoptimization::Reason_array_check, @@ -215,8 +215,8 @@ // if (klass->_init_thread != current_thread || // klass->_init_state != being_initialized) // uncommon_trap - Node* cur_thread = _gvn.transform( new (C, 1) ThreadLocalNode() ); - Node* merge = new (C, 3) RegionNode(3); + Node* cur_thread = _gvn.transform( new (C) ThreadLocalNode() ); + Node* merge = new (C) RegionNode(3); _gvn.set_type(merge, Type::CONTROL); Node* kls = makecon(TypeKlassPtr::make(klass)); @@ -322,9 +322,9 @@ // Test invocation count vs threshold Node *threshold = makecon(TypeInt::make(limit)); - Node *chk = _gvn.transform( new (C, 3) CmpUNode( cnt, threshold) ); + Node *chk = _gvn.transform( new (C) CmpUNode( cnt, threshold) ); BoolTest::mask btest = BoolTest::lt; - Node *tst = _gvn.transform( new (C, 2) BoolNode( chk, btest) ); + Node *tst = _gvn.transform( new (C) BoolNode( chk, btest) ); // Branch to failure if threshold exceeded { BuildCutout unless(this, tst, PROB_ALWAYS); uncommon_trap(Deoptimization::Reason_age, @@ -348,7 +348,7 @@ test_counter_against_threshold(cnt, limit); // Add one to the counter and store - Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1))); + Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1))); store_to_memory( NULL, adr_node, incr, T_INT, adr_type ); } @@ -369,8 +369,8 @@ if (stride != 0) { Node* str = _gvn.MakeConX(stride); - Node* scale = _gvn.transform( new (C, 3) MulXNode( idx, str ) ); - ptr = _gvn.transform( new (C, 4) AddPNode( mdo, ptr, scale ) ); + Node* scale = _gvn.transform( new (C) MulXNode( idx, str ) ); + ptr = _gvn.transform( new (C) AddPNode( mdo, ptr, scale ) ); } return ptr; @@ -382,7 +382,7 @@ const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr(); Node* cnt = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type); - Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(DataLayout::counter_increment))); + Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(DataLayout::counter_increment))); store_to_memory(NULL, adr_node, incr, T_INT, adr_type ); } @@ -402,7 +402,7 @@ const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr(); Node* flags = make_load(NULL, adr_node, TypeInt::BYTE, T_BYTE, adr_type); - Node* incr = _gvn.transform(new (C, 3) OrINode(flags, _gvn.intcon(flag_constant))); + Node* incr = _gvn.transform(new (C) OrINode(flags, _gvn.intcon(flag_constant))); store_to_memory(NULL, adr_node, incr, T_BYTE, adr_type); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/phaseX.cpp --- a/src/share/vm/opto/phaseX.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/phaseX.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -48,7 +48,7 @@ _total_insert_probes(0), _total_inserts(0), _insert_probes(0), _grows(0) { // _sentinel must be in the current node space - _sentinel = new (Compile::current(), 1) ProjNode(NULL, TypeFunc::Control); + _sentinel = new (Compile::current()) ProjNode(NULL, TypeFunc::Control); memset(_table,0,sizeof(Node*)*_max); } @@ -63,7 +63,7 @@ _total_insert_probes(0), _total_inserts(0), _insert_probes(0), _grows(0) { // _sentinel must be in the current node space - _sentinel = new (Compile::current(), 1) ProjNode(NULL, TypeFunc::Control); + _sentinel = new (Compile::current()) ProjNode(NULL, TypeFunc::Control); memset(_table,0,sizeof(Node*)*_max); } @@ -1246,7 +1246,7 @@ } // Smash all inputs to 'old', isolating him completely - Node *temp = new (C, 1) Node(1); + Node *temp = new (C) Node(1); temp->init_req(0,nn); // Add a use to nn to prevent him from dying remove_dead_node( old ); temp->del_req(0); // Yank bogus edge diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/reg_split.cpp --- a/src/share/vm/opto/reg_split.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/reg_split.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -646,7 +646,7 @@ // create a new phi node and insert it into the block // type is taken from left over pointer to a predecessor assert(n3,"No non-NULL reaching DEF for a Phi"); - phi = new (C, b->num_preds()) PhiNode(b->head(), n3->bottom_type()); + phi = new (C) PhiNode(b->head(), n3->bottom_type()); // initialize the Reaches entry for this LRG Reachblock[slidx] = phi; diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/split_if.cpp --- a/src/share/vm/opto/split_if.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/split_if.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -35,7 +35,7 @@ uint wins = 0; assert( n->is_CFG(), "" ); assert( region->is_Region(), "" ); - Node *r = new (C, region->req()) RegionNode( region->req() ); + Node *r = new (C) RegionNode( region->req() ); IdealLoopTree *loop = get_loop( n ); for( uint i = 1; i < region->req(); i++ ) { Node *x = n->clone(); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/stringopts.cpp --- a/src/share/vm/opto/stringopts.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/stringopts.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -69,7 +69,7 @@ _multiple(false), _string_alloc(NULL), _stringopts(stringopts) { - _arguments = new (_stringopts->C, 1) Node(1); + _arguments = new (_stringopts->C) Node(1); _arguments->del_req(0); } @@ -220,11 +220,10 @@ // Build a new call using the jvms state of the allocate address call_addr = SharedRuntime::uncommon_trap_blob()->entry_point(); const TypeFunc* call_type = OptoRuntime::uncommon_trap_Type(); - int size = call_type->domain()->cnt(); const TypePtr* no_memory_effects = NULL; Compile* C = _stringopts->C; - CallStaticJavaNode* call = new (C, size) CallStaticJavaNode(call_type, call_addr, "uncommon_trap", - jvms->bci(), no_memory_effects); + CallStaticJavaNode* call = new (C) CallStaticJavaNode(call_type, call_addr, "uncommon_trap", + jvms->bci(), no_memory_effects); for (int e = 0; e < TypeFunc::Parms; e++) { call->init_req(e, uct->in(e)); } @@ -969,9 +968,9 @@ } Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) { - RegionNode *final_merge = new (C, 3) RegionNode(3); + RegionNode *final_merge = new (C) RegionNode(3); kit.gvn().set_type(final_merge, Type::CONTROL); - Node* final_size = new (C, 3) PhiNode(final_merge, TypeInt::INT); + Node* final_size = new (C) PhiNode(final_merge, TypeInt::INT); kit.gvn().set_type(final_size, TypeInt::INT); IfNode* iff = kit.create_and_map_if(kit.control(), @@ -988,11 +987,11 @@ } else { // int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); - RegionNode *r = new (C, 3) RegionNode(3); + RegionNode *r = new (C) RegionNode(3); kit.gvn().set_type(r, Type::CONTROL); - Node *phi = new (C, 3) PhiNode(r, TypeInt::INT); + Node *phi = new (C) PhiNode(r, TypeInt::INT); kit.gvn().set_type(phi, TypeInt::INT); - Node *size = new (C, 3) PhiNode(r, TypeInt::INT); + Node *size = new (C) PhiNode(r, TypeInt::INT); kit.gvn().set_type(size, TypeInt::INT); Node* chk = __ CmpI(arg, __ intcon(0)); Node* p = __ Bool(chk, BoolTest::lt); @@ -1017,11 +1016,11 @@ // Add loop predicate first. kit.add_predicate(); - RegionNode *loop = new (C, 3) RegionNode(3); + RegionNode *loop = new (C) RegionNode(3); loop->init_req(1, kit.control()); kit.gvn().set_type(loop, Type::CONTROL); - Node *index = new (C, 3) PhiNode(loop, TypeInt::INT); + Node *index = new (C) PhiNode(loop, TypeInt::INT); index->init_req(1, __ intcon(0)); kit.gvn().set_type(index, TypeInt::INT); kit.set_control(loop); @@ -1054,7 +1053,7 @@ } void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, Node* start, Node* end) { - RegionNode *final_merge = new (C, 4) RegionNode(4); + RegionNode *final_merge = new (C) RegionNode(4); kit.gvn().set_type(final_merge, Type::CONTROL); Node *final_mem = PhiNode::make(final_merge, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS); kit.gvn().set_type(final_mem, Type::MEMORY); @@ -1104,11 +1103,11 @@ __ Bool(__ CmpI(arg, __ intcon(0)), BoolTest::lt), PROB_FAIR, COUNT_UNKNOWN); - RegionNode *merge = new (C, 3) RegionNode(3); + RegionNode *merge = new (C) RegionNode(3); kit.gvn().set_type(merge, Type::CONTROL); - i = new (C, 3) PhiNode(merge, TypeInt::INT); + i = new (C) PhiNode(merge, TypeInt::INT); kit.gvn().set_type(i, TypeInt::INT); - sign = new (C, 3) PhiNode(merge, TypeInt::INT); + sign = new (C) PhiNode(merge, TypeInt::INT); kit.gvn().set_type(sign, TypeInt::INT); merge->init_req(1, __ IfTrue(iff)); @@ -1137,10 +1136,10 @@ // Add loop predicate first. kit.add_predicate(); - RegionNode *head = new (C, 3) RegionNode(3); + RegionNode *head = new (C) RegionNode(3); head->init_req(1, kit.control()); kit.gvn().set_type(head, Type::CONTROL); - Node *i_phi = new (C, 3) PhiNode(head, TypeInt::INT); + Node *i_phi = new (C) PhiNode(head, TypeInt::INT); i_phi->init_req(1, i); kit.gvn().set_type(i_phi, TypeInt::INT); charPos = PhiNode::make(head, charPos); @@ -1261,7 +1260,7 @@ // as a shim for the insertion of the new code. JVMState* jvms = sc->begin()->jvms()->clone_shallow(C); uint size = sc->begin()->req(); - SafePointNode* map = new (C, size) SafePointNode(size, jvms); + SafePointNode* map = new (C) SafePointNode(size, jvms); // copy the control and memory state from the final call into our // new starting state. This allows any preceeding tests to feed @@ -1306,12 +1305,12 @@ // Create a region for the overflow checks to merge into. int args = MAX2(sc->num_arguments(), 1); - RegionNode* overflow = new (C, args) RegionNode(args); + RegionNode* overflow = new (C) RegionNode(args); kit.gvn().set_type(overflow, Type::CONTROL); // Create a hook node to hold onto the individual sizes since they // are need for the copying phase. - Node* string_sizes = new (C, args) Node(args); + Node* string_sizes = new (C) Node(args); Node* length = __ intcon(0); for (int argi = 0; argi < sc->num_arguments(); argi++) { @@ -1355,9 +1354,9 @@ } else if (!type->higher_equal(TypeInstPtr::NOTNULL)) { // s = s != null ? s : "null"; // length = length + (s.count - s.offset); - RegionNode *r = new (C, 3) RegionNode(3); + RegionNode *r = new (C) RegionNode(3); kit.gvn().set_type(r, Type::CONTROL); - Node *phi = new (C, 3) PhiNode(r, type); + Node *phi = new (C) PhiNode(r, type); kit.gvn().set_type(phi, phi->bottom_type()); Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne); IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/subnode.cpp --- a/src/share/vm/opto/subnode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/subnode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -149,7 +149,7 @@ if( t2->base() == Type::Int ){ // Might be bottom or top... const TypeInt *i = t2->is_int(); if( i->is_con() ) - return new (phase->C, 3) AddINode(in1, phase->intcon(-i->get_con())); + return new (phase->C) AddINode(in1, phase->intcon(-i->get_con())); } // Convert "(x+c0) - y" into (x-y) + c0" @@ -158,8 +158,8 @@ if( op1 == Op_AddI && ok_to_convert(in1, in2) ) { const Type *tadd = phase->type( in1->in(2) ); if( tadd->singleton() && tadd != Type::TOP ) { - Node *sub2 = phase->transform( new (phase->C, 3) SubINode( in1->in(1), in2 )); - return new (phase->C, 3) AddINode( sub2, in1->in(2) ); + Node *sub2 = phase->transform( new (phase->C) SubINode( in1->in(1), in2 )); + return new (phase->C) AddINode( sub2, in1->in(2) ); } } @@ -171,9 +171,9 @@ Node* in22 = in2->in(2); const TypeInt* tcon = phase->type(in22)->isa_int(); if (tcon != NULL && tcon->is_con()) { - Node* sub2 = phase->transform( new (phase->C, 3) SubINode(in1, in21) ); + Node* sub2 = phase->transform( new (phase->C) SubINode(in1, in21) ); Node* neg_c0 = phase->intcon(- tcon->get_con()); - return new (phase->C, 3) AddINode(sub2, neg_c0); + return new (phase->C) AddINode(sub2, neg_c0); } } @@ -191,47 +191,47 @@ // Convert "x - (x+y)" into "-y" if( op2 == Op_AddI && phase->eqv( in1, in2->in(1) ) ) - return new (phase->C, 3) SubINode( phase->intcon(0),in2->in(2)); + return new (phase->C) SubINode( phase->intcon(0),in2->in(2)); // Convert "(x-y) - x" into "-y" if( op1 == Op_SubI && phase->eqv( in1->in(1), in2 ) ) - return new (phase->C, 3) SubINode( phase->intcon(0),in1->in(2)); + return new (phase->C) SubINode( phase->intcon(0),in1->in(2)); // Convert "x - (y+x)" into "-y" if( op2 == Op_AddI && phase->eqv( in1, in2->in(2) ) ) - return new (phase->C, 3) SubINode( phase->intcon(0),in2->in(1)); + return new (phase->C) SubINode( phase->intcon(0),in2->in(1)); // Convert "0 - (x-y)" into "y-x" if( t1 == TypeInt::ZERO && op2 == Op_SubI ) - return new (phase->C, 3) SubINode( in2->in(2), in2->in(1) ); + return new (phase->C) SubINode( in2->in(2), in2->in(1) ); // Convert "0 - (x+con)" into "-con-x" jint con; if( t1 == TypeInt::ZERO && op2 == Op_AddI && (con = in2->in(2)->find_int_con(0)) != 0 ) - return new (phase->C, 3) SubINode( phase->intcon(-con), in2->in(1) ); + return new (phase->C) SubINode( phase->intcon(-con), in2->in(1) ); // Convert "(X+A) - (X+B)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) ) - return new (phase->C, 3) SubINode( in1->in(2), in2->in(2) ); + return new (phase->C) SubINode( in1->in(2), in2->in(2) ); // Convert "(A+X) - (B+X)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) ) - return new (phase->C, 3) SubINode( in1->in(1), in2->in(1) ); + return new (phase->C) SubINode( in1->in(1), in2->in(1) ); // Convert "(A+X) - (X+B)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(1) ) - return new (phase->C, 3) SubINode( in1->in(1), in2->in(2) ); + return new (phase->C) SubINode( in1->in(1), in2->in(2) ); // Convert "(X+A) - (B+X)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(2) ) - return new (phase->C, 3) SubINode( in1->in(2), in2->in(1) ); + return new (phase->C) SubINode( in1->in(2), in2->in(1) ); // Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally // nicer to optimize than subtract. if( op2 == Op_SubI && in2->outcnt() == 1) { - Node *add1 = phase->transform( new (phase->C, 3) AddINode( in1, in2->in(2) ) ); - return new (phase->C, 3) SubINode( add1, in2->in(1) ); + Node *add1 = phase->transform( new (phase->C) AddINode( in1, in2->in(2) ) ); + return new (phase->C) SubINode( add1, in2->in(1) ); } return NULL; @@ -278,7 +278,7 @@ // Convert "x-c0" into "x+ -c0". if( i && // Might be bottom or top... i->is_con() ) - return new (phase->C, 3) AddLNode(in1, phase->longcon(-i->get_con())); + return new (phase->C) AddLNode(in1, phase->longcon(-i->get_con())); // Convert "(x+c0) - y" into (x-y) + c0" // Do not collapse (x+c0)-y if "+" is a loop increment or @@ -287,8 +287,8 @@ Node *in11 = in1->in(1); const Type *tadd = phase->type( in1->in(2) ); if( tadd->singleton() && tadd != Type::TOP ) { - Node *sub2 = phase->transform( new (phase->C, 3) SubLNode( in11, in2 )); - return new (phase->C, 3) AddLNode( sub2, in1->in(2) ); + Node *sub2 = phase->transform( new (phase->C) SubLNode( in11, in2 )); + return new (phase->C) AddLNode( sub2, in1->in(2) ); } } @@ -299,9 +299,9 @@ Node* in22 = in2->in(2); const TypeLong* tcon = phase->type(in22)->isa_long(); if (tcon != NULL && tcon->is_con()) { - Node* sub2 = phase->transform( new (phase->C, 3) SubLNode(in1, in21) ); + Node* sub2 = phase->transform( new (phase->C) SubLNode(in1, in21) ); Node* neg_c0 = phase->longcon(- tcon->get_con()); - return new (phase->C, 3) AddLNode(sub2, neg_c0); + return new (phase->C) AddLNode(sub2, neg_c0); } } @@ -319,28 +319,28 @@ // Convert "x - (x+y)" into "-y" if( op2 == Op_AddL && phase->eqv( in1, in2->in(1) ) ) - return new (phase->C, 3) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2)); + return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2)); // Convert "x - (y+x)" into "-y" if( op2 == Op_AddL && phase->eqv( in1, in2->in(2) ) ) - return new (phase->C, 3) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1)); + return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1)); // Convert "0 - (x-y)" into "y-x" if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL ) - return new (phase->C, 3) SubLNode( in2->in(2), in2->in(1) ); + return new (phase->C) SubLNode( in2->in(2), in2->in(1) ); // Convert "(X+A) - (X+B)" into "A - B" if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) ) - return new (phase->C, 3) SubLNode( in1->in(2), in2->in(2) ); + return new (phase->C) SubLNode( in1->in(2), in2->in(2) ); // Convert "(A+X) - (B+X)" into "A - B" if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) ) - return new (phase->C, 3) SubLNode( in1->in(1), in2->in(1) ); + return new (phase->C) SubLNode( in1->in(1), in2->in(1) ); // Convert "A-(B-C)" into (A+C)-B" if( op2 == Op_SubL && in2->outcnt() == 1) { - Node *add1 = phase->transform( new (phase->C, 3) AddLNode( in1, in2->in(2) ) ); - return new (phase->C, 3) SubLNode( add1, in2->in(1) ); + Node *add1 = phase->transform( new (phase->C) AddLNode( in1, in2->in(2) ) ); + return new (phase->C) SubLNode( add1, in2->in(1) ); } return NULL; @@ -407,7 +407,7 @@ // Convert "x - (x+y)" into "-y" if( in(2)->is_Add() && phase->eqv(in(1),in(2)->in(1) ) ) - return new (phase->C, 3) SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2)); + return new (phase->C) SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2)); } // Cannot replace 0.0-X with -X because a 'fsub' bytecode computes @@ -450,7 +450,7 @@ // Convert "x - (x+y)" into "-y" if( in(2)->is_Add() && phase->eqv(in(1),in(2)->in(1) ) ) - return new (phase->C, 3) SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2)); + return new (phase->C) SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2)); } // Cannot replace 0.0-X with -X because a 'dsub' bytecode computes @@ -581,11 +581,11 @@ if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) { switch (in(1)->Opcode()) { case Op_CmpL3: // Collapse a CmpL3/CmpI into a CmpL - return new (phase->C, 3) CmpLNode(in(1)->in(1),in(1)->in(2)); + return new (phase->C) CmpLNode(in(1)->in(1),in(1)->in(2)); case Op_CmpF3: // Collapse a CmpF3/CmpI into a CmpF - return new (phase->C, 3) CmpFNode(in(1)->in(1),in(1)->in(2)); + return new (phase->C) CmpFNode(in(1)->in(1),in(1)->in(2)); case Op_CmpD3: // Collapse a CmpD3/CmpI into a CmpD - return new (phase->C, 3) CmpDNode(in(1)->in(1),in(1)->in(2)); + return new (phase->C) CmpDNode(in(1)->in(1),in(1)->in(2)); //case Op_SubI: // If (x - y) cannot overflow, then ((x - y) 0) // can be turned into (x y). @@ -1023,8 +1023,8 @@ new_in2 = tmp; } CmpFNode *new_cmp = (Opcode() == Op_CmpD3) - ? new (phase->C, 3) CmpF3Node( new_in1, new_in2 ) - : new (phase->C, 3) CmpFNode ( new_in1, new_in2 ) ; + ? new (phase->C) CmpF3Node( new_in1, new_in2 ) + : new (phase->C) CmpFNode ( new_in1, new_in2 ) ; return new_cmp; // Changed to CmpFNode } // Testing value required the precision of a double @@ -1085,7 +1085,7 @@ ncmp->set_req(1,cmp1); ncmp->set_req(2,cmp2); ncmp = gvn->transform( ncmp ); - return new (gvn->C, 2) BoolNode( ncmp, test ); + return new (gvn->C) BoolNode( ncmp, test ); } //-------------------------------make_predicate-------------------------------- @@ -1106,9 +1106,9 @@ // Else fall through. The CMove gets in the way of the test. // It should be the case that make_predicate(bol->as_int_value()) == bol. } - Node* cmp = new (C, 3) CmpINode(test_value, phase->intcon(0)); + Node* cmp = new (C) CmpINode(test_value, phase->intcon(0)); cmp = phase->transform(cmp); - Node* bol = new (C, 2) BoolNode(cmp, BoolTest::ne); + Node* bol = new (C) BoolNode(cmp, BoolTest::ne); return phase->transform(bol); } @@ -1124,7 +1124,7 @@ //----------------------------------negate------------------------------------- BoolNode* BoolNode::negate(PhaseGVN* phase) { Compile* C = phase->C; - return new (C, 2) BoolNode(in(1), _test.negate()); + return new (C) BoolNode(in(1), _test.negate()); } @@ -1158,7 +1158,7 @@ // Swap inputs to the clone cmp->swap_edges(1, 2); cmp = phase->transform( cmp ); - return new (phase->C, 2) BoolNode( cmp, _test.commute() ); + return new (phase->C) BoolNode( cmp, _test.commute() ); } // Change "bool eq/ne (cmp (xor X 1) 0)" into "bool ne/eq (cmp X 0)". @@ -1175,8 +1175,8 @@ phase->type( j_xor->in(2) ) == TypeInt::ONE && (_test._test == BoolTest::eq || _test._test == BoolTest::ne) ) { - Node *ncmp = phase->transform(new (phase->C, 3) CmpINode(j_xor->in(1),cmp2)); - return new (phase->C, 2) BoolNode( ncmp, _test.negate() ); + Node *ncmp = phase->transform(new (phase->C) CmpINode(j_xor->in(1),cmp2)); + return new (phase->C) BoolNode( ncmp, _test.negate() ); } // Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)". @@ -1187,10 +1187,10 @@ (_test._test == BoolTest::eq || _test._test == BoolTest::ne) ) { Node *ncmp = phase->transform(phase->type(c2b->in(1))->isa_int() - ? (Node*)new (phase->C, 3) CmpINode(c2b->in(1),cmp2) - : (Node*)new (phase->C, 3) CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR)) + ? (Node*)new (phase->C) CmpINode(c2b->in(1),cmp2) + : (Node*)new (phase->C) CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR)) ); - return new (phase->C, 2) BoolNode( ncmp, _test._test ); + return new (phase->C) BoolNode( ncmp, _test._test ); } // Comparing a SubI against a zero is equal to comparing the SubI @@ -1200,8 +1200,8 @@ (cop == Op_CmpI) && (cmp1->Opcode() == Op_SubI) && ( cmp2_type == TypeInt::ZERO ) ) { - Node *ncmp = phase->transform( new (phase->C, 3) CmpINode(cmp1->in(1),cmp1->in(2))); - return new (phase->C, 2) BoolNode( ncmp, _test._test ); + Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(1),cmp1->in(2))); + return new (phase->C) BoolNode( ncmp, _test._test ); } // Change (-A vs 0) into (A vs 0) by commuting the test. Disallow in the @@ -1212,8 +1212,8 @@ cmp2_type == TypeInt::ZERO && phase->type( cmp1->in(1) ) == TypeInt::ZERO && phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) { - Node *ncmp = phase->transform( new (phase->C, 3) CmpINode(cmp1->in(2),cmp2)); - return new (phase->C, 2) BoolNode( ncmp, _test.commute() ); + Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(2),cmp2)); + return new (phase->C) BoolNode( ncmp, _test.commute() ); } // The transformation below is not valid for either signed or unsigned diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/superword.cpp --- a/src/share/vm/opto/superword.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/superword.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -179,6 +179,7 @@ for (int i = 0; i < _block.length(); i++) { Node* n = _block.at(i); if (n->is_Mem() && !n->is_LoadStore() && in_bb(n) && + n->Opcode() != Op_LoadUI2L && is_java_primitive(n->as_Mem()->memory_type())) { int align = memory_alignment(n->as_Mem(), 0); if (align != bottom_align) { @@ -481,12 +482,19 @@ int vw = vector_width_in_bytes(mem_ref); assert(vw > 1, "sanity"); int stride_sign = (scale * iv_stride()) > 0 ? 1 : -1; - int iv_adjustment = (stride_sign * vw - (offset % vw)) % vw; + // At least one iteration is executed in pre-loop by default. As result + // several iterations are needed to align memory operations in main-loop even + // if offset is 0. + int iv_adjustment_in_bytes = (stride_sign * vw - (offset % vw)); + int elt_size = align_to_ref_p.memory_size(); + assert(((ABS(iv_adjustment_in_bytes) % elt_size) == 0), + err_msg_res("(%d) should be divisible by (%d)", iv_adjustment_in_bytes, elt_size)); + int iv_adjustment = iv_adjustment_in_bytes/elt_size; #ifndef PRODUCT if (TraceSuperWord) tty->print_cr("\noffset = %d iv_adjust = %d elt_size = %d scale = %d iv_stride = %d vect_size %d", - offset, iv_adjustment, align_to_ref_p.memory_size(), scale, iv_stride(), vw); + offset, iv_adjustment, elt_size, scale, iv_stride(), vw); #endif return iv_adjustment; } @@ -1080,23 +1088,22 @@ uint start, end; VectorNode::vector_operands(p0, &start, &end); - // Return false if some input is not vector and inside block + // Return false if some inputs are not vectors or vectors with different + // size or alignment. + // Also, for now, return false if not scalar promotion case when inputs are + // the same. Later, implement PackNode and allow differing, non-vector inputs + // (maybe just the ones from outside the block.) for (uint i = start; i < end; i++) { - if (!is_vector_use(p0, i)) { - // For now, return false if not scalar promotion case (inputs are the same.) - // Later, implement PackNode and allow differing, non-vector inputs - // (maybe just the ones from outside the block.) - if (!same_inputs(p, i)) { - return false; - } - } + if (!is_vector_use(p0, i)) + return false; } if (VectorNode::is_shift(p0)) { - // For now, return false if shift count is vector because - // hw does not support it. - if (is_vector_use(p0, 2)) + // For now, return false if shift count is vector or not scalar promotion + // case (different shift counts) because it is not supported yet. + Node* cnt = p0->in(2); + Node_List* cnt_pk = my_pack(cnt); + if (cnt_pk != NULL) return false; - // For the same reason return false if different shift counts. if (!same_inputs(p, 2)) return false; } @@ -1350,11 +1357,14 @@ insert_extracts(_packset.at(i)); } + Compile* C = _phase->C; + uint max_vlen_in_bytes = 0; for (int i = 0; i < _block.length(); i++) { Node* n = _block.at(i); Node_List* p = my_pack(n); if (p && n == executed_last(p)) { uint vlen = p->size(); + uint vlen_in_bytes = 0; Node* vn = NULL; Node* low_adr = p->at(0); Node* first = executed_first(p); @@ -1364,7 +1374,8 @@ Node* mem = first->in(MemNode::Memory); Node* adr = low_adr->in(MemNode::Address); const TypePtr* atyp = n->adr_type(); - vn = LoadVectorNode::make(_phase->C, opc, ctl, mem, adr, atyp, vlen, velt_basic_type(n)); + vn = LoadVectorNode::make(C, opc, ctl, mem, adr, atyp, vlen, velt_basic_type(n)); + vlen_in_bytes = vn->as_LoadVector()->memory_size(); } else if (n->is_Store()) { // Promote value to be stored to vector Node* val = vector_opd(p, MemNode::ValueIn); @@ -1372,7 +1383,8 @@ Node* mem = first->in(MemNode::Memory); Node* adr = low_adr->in(MemNode::Address); const TypePtr* atyp = n->adr_type(); - vn = StoreVectorNode::make(_phase->C, opc, ctl, mem, adr, atyp, val, vlen); + vn = StoreVectorNode::make(C, opc, ctl, mem, adr, atyp, val, vlen); + vlen_in_bytes = vn->as_StoreVector()->memory_size(); } else if (n->req() == 3) { // Promote operands to vector Node* in1 = vector_opd(p, 1); @@ -1383,18 +1395,23 @@ in1 = in2; in2 = tmp; } - vn = VectorNode::make(_phase->C, opc, in1, in2, vlen, velt_basic_type(n)); + vn = VectorNode::make(C, opc, in1, in2, vlen, velt_basic_type(n)); + vlen_in_bytes = vn->as_Vector()->length_in_bytes(); } else { ShouldNotReachHere(); } assert(vn != NULL, "sanity"); - _phase->_igvn.register_new_node_with_optimizer(vn); + _igvn.register_new_node_with_optimizer(vn); _phase->set_ctrl(vn, _phase->get_ctrl(p->at(0))); for (uint j = 0; j < p->size(); j++) { Node* pm = p->at(j); _igvn.replace_node(pm, vn); } _igvn._worklist.push(vn); + + if (vlen_in_bytes > max_vlen_in_bytes) { + max_vlen_in_bytes = vlen_in_bytes; + } #ifdef ASSERT if (TraceNewVectors) { tty->print("new Vector node: "); @@ -1403,6 +1420,7 @@ #endif } } + C->set_max_vector_size(max_vlen_in_bytes); } //------------------------------vector_opd--------------------------- @@ -1432,17 +1450,17 @@ } else { if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { cnt = ConNode::make(C, TypeInt::make(mask)); - _phase->_igvn.register_new_node_with_optimizer(cnt); - cnt = new (C, 3) AndINode(opd, cnt); - _phase->_igvn.register_new_node_with_optimizer(cnt); + _igvn.register_new_node_with_optimizer(cnt); + cnt = new (C) AndINode(opd, cnt); + _igvn.register_new_node_with_optimizer(cnt); _phase->set_ctrl(cnt, _phase->get_ctrl(opd)); } assert(opd->bottom_type()->isa_int(), "int type only"); // Move non constant shift count into XMM register. - cnt = new (_phase->C, 2) MoveI2FNode(cnt); + cnt = new (C) MoveI2FNode(cnt); } if (cnt != opd) { - _phase->_igvn.register_new_node_with_optimizer(cnt); + _igvn.register_new_node_with_optimizer(cnt); _phase->set_ctrl(cnt, _phase->get_ctrl(opd)); } return cnt; @@ -1454,7 +1472,7 @@ const Type* p0_t = velt_type(p0); VectorNode* vn = VectorNode::scalar2vector(_phase->C, opd, vlen, p0_t); - _phase->_igvn.register_new_node_with_optimizer(vn); + _igvn.register_new_node_with_optimizer(vn); _phase->set_ctrl(vn, _phase->get_ctrl(opd)); #ifdef ASSERT if (TraceNewVectors) { @@ -1477,13 +1495,13 @@ assert(opd_bt == in->bottom_type()->basic_type(), "all same type"); pk->add_opd(in); } - _phase->_igvn.register_new_node_with_optimizer(pk); + _igvn.register_new_node_with_optimizer(pk); _phase->set_ctrl(pk, _phase->get_ctrl(opd)); #ifdef ASSERT - if (TraceNewVectors) { - tty->print("new Vector node: "); - pk->dump(); - } + if (TraceNewVectors) { + tty->print("new Vector node: "); + pk->dump(); + } #endif return pk; } @@ -1524,7 +1542,7 @@ int def_pos = alignment(def) / data_size(def); Node* ex = ExtractNode::make(_phase->C, def, def_pos, velt_basic_type(def)); - _phase->_igvn.register_new_node_with_optimizer(ex); + _igvn.register_new_node_with_optimizer(ex); _phase->set_ctrl(ex, _phase->get_ctrl(def)); _igvn.replace_input_of(use, idx, ex); _igvn._worklist.push(def); @@ -1805,7 +1823,7 @@ //------------------------------memory_alignment--------------------------- // Alignment within a vector memory reference -int SuperWord::memory_alignment(MemNode* s, int iv_adjust_in_bytes) { +int SuperWord::memory_alignment(MemNode* s, int iv_adjust) { SWPointer p(s, this); if (!p.valid()) { return bottom_align; @@ -1815,7 +1833,7 @@ return bottom_align; // No vectors for this type } int offset = p.offset_in_bytes(); - offset += iv_adjust_in_bytes; + offset += iv_adjust*p.memory_size(); int off_rem = offset % vw; int off_mod = off_rem >= 0 ? off_rem : off_rem + vw; return off_mod; @@ -1838,7 +1856,7 @@ bool SuperWord::same_velt_type(Node* n1, Node* n2) { const Type* vt1 = velt_type(n1); - const Type* vt2 = velt_type(n1); + const Type* vt2 = velt_type(n2); if (vt1->basic_type() == T_INT && vt2->basic_type() == T_INT) { // Compare vectors element sizes for integer types. return data_size(n1) == data_size(n2); @@ -2003,73 +2021,73 @@ if (align_to_ref_p.invar() != NULL) { // incorporate any extra invariant piece producing (offset +/- invar) >>> log2(elt) Node* log2_elt = _igvn.intcon(exact_log2(elt_size)); - Node* aref = new (_phase->C, 3) URShiftINode(align_to_ref_p.invar(), log2_elt); - _phase->_igvn.register_new_node_with_optimizer(aref); + Node* aref = new (_phase->C) URShiftINode(align_to_ref_p.invar(), log2_elt); + _igvn.register_new_node_with_optimizer(aref); _phase->set_ctrl(aref, pre_ctrl); if (align_to_ref_p.negate_invar()) { - e = new (_phase->C, 3) SubINode(e, aref); + e = new (_phase->C) SubINode(e, aref); } else { - e = new (_phase->C, 3) AddINode(e, aref); + e = new (_phase->C) AddINode(e, aref); } - _phase->_igvn.register_new_node_with_optimizer(e); + _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); } if (vw > ObjectAlignmentInBytes) { // incorporate base e +/- base && Mask >>> log2(elt) - Node* xbase = new(_phase->C, 2) CastP2XNode(NULL, align_to_ref_p.base()); - _phase->_igvn.register_new_node_with_optimizer(xbase); + Node* xbase = new(_phase->C) CastP2XNode(NULL, align_to_ref_p.base()); + _igvn.register_new_node_with_optimizer(xbase); #ifdef _LP64 - xbase = new (_phase->C, 2) ConvL2INode(xbase); - _phase->_igvn.register_new_node_with_optimizer(xbase); + xbase = new (_phase->C) ConvL2INode(xbase); + _igvn.register_new_node_with_optimizer(xbase); #endif Node* mask = _igvn.intcon(vw-1); - Node* masked_xbase = new (_phase->C, 3) AndINode(xbase, mask); - _phase->_igvn.register_new_node_with_optimizer(masked_xbase); + Node* masked_xbase = new (_phase->C) AndINode(xbase, mask); + _igvn.register_new_node_with_optimizer(masked_xbase); Node* log2_elt = _igvn.intcon(exact_log2(elt_size)); - Node* bref = new (_phase->C, 3) URShiftINode(masked_xbase, log2_elt); - _phase->_igvn.register_new_node_with_optimizer(bref); + Node* bref = new (_phase->C) URShiftINode(masked_xbase, log2_elt); + _igvn.register_new_node_with_optimizer(bref); _phase->set_ctrl(bref, pre_ctrl); - e = new (_phase->C, 3) AddINode(e, bref); - _phase->_igvn.register_new_node_with_optimizer(e); + e = new (_phase->C) AddINode(e, bref); + _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); } // compute e +/- lim0 if (scale < 0) { - e = new (_phase->C, 3) SubINode(e, lim0); + e = new (_phase->C) SubINode(e, lim0); } else { - e = new (_phase->C, 3) AddINode(e, lim0); + e = new (_phase->C) AddINode(e, lim0); } - _phase->_igvn.register_new_node_with_optimizer(e); + _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); if (stride * scale > 0) { // compute V - (e +/- lim0) Node* va = _igvn.intcon(v_align); - e = new (_phase->C, 3) SubINode(va, e); - _phase->_igvn.register_new_node_with_optimizer(e); + e = new (_phase->C) SubINode(va, e); + _igvn.register_new_node_with_optimizer(e); _phase->set_ctrl(e, pre_ctrl); } // compute N = (exp) % V Node* va_msk = _igvn.intcon(v_align - 1); - Node* N = new (_phase->C, 3) AndINode(e, va_msk); - _phase->_igvn.register_new_node_with_optimizer(N); + Node* N = new (_phase->C) AndINode(e, va_msk); + _igvn.register_new_node_with_optimizer(N); _phase->set_ctrl(N, pre_ctrl); // substitute back into (1), so that new limit // lim = lim0 + N Node* lim; if (stride < 0) { - lim = new (_phase->C, 3) SubINode(lim0, N); + lim = new (_phase->C) SubINode(lim0, N); } else { - lim = new (_phase->C, 3) AddINode(lim0, N); + lim = new (_phase->C) AddINode(lim0, N); } - _phase->_igvn.register_new_node_with_optimizer(lim); + _igvn.register_new_node_with_optimizer(lim); _phase->set_ctrl(lim, pre_ctrl); Node* constrained = - (stride > 0) ? (Node*) new (_phase->C,3) MinINode(lim, orig_limit) - : (Node*) new (_phase->C,3) MaxINode(lim, orig_limit); - _phase->_igvn.register_new_node_with_optimizer(constrained); + (stride > 0) ? (Node*) new (_phase->C) MinINode(lim, orig_limit) + : (Node*) new (_phase->C) MaxINode(lim, orig_limit); + _igvn.register_new_node_with_optimizer(constrained); _phase->set_ctrl(constrained, pre_ctrl); _igvn.hash_delete(pre_opaq); pre_opaq->set_req(1, constrained); diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/superword.hpp --- a/src/share/vm/opto/superword.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/superword.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -400,7 +400,7 @@ // Return the node executed last in pack p. Node* executed_last(Node_List* p); // Alignment within a vector memory reference - int memory_alignment(MemNode* s, int iv_adjust_in_bytes); + int memory_alignment(MemNode* s, int iv_adjust); // (Start, end] half-open range defining which operands are vector void vector_opd_range(Node* n, uint* start, uint* end); // Smallest type containing range of values diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/opto/vectornode.cpp --- a/src/share/vm/opto/vectornode.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/opto/vectornode.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -245,46 +245,46 @@ int vopc = VectorNode::opcode(opc, bt); switch (vopc) { - case Op_AddVB: return new (C, 3) AddVBNode(n1, n2, vt); - case Op_AddVS: return new (C, 3) AddVSNode(n1, n2, vt); - case Op_AddVI: return new (C, 3) AddVINode(n1, n2, vt); - case Op_AddVL: return new (C, 3) AddVLNode(n1, n2, vt); - case Op_AddVF: return new (C, 3) AddVFNode(n1, n2, vt); - case Op_AddVD: return new (C, 3) AddVDNode(n1, n2, vt); + case Op_AddVB: return new (C) AddVBNode(n1, n2, vt); + case Op_AddVS: return new (C) AddVSNode(n1, n2, vt); + case Op_AddVI: return new (C) AddVINode(n1, n2, vt); + case Op_AddVL: return new (C) AddVLNode(n1, n2, vt); + case Op_AddVF: return new (C) AddVFNode(n1, n2, vt); + case Op_AddVD: return new (C) AddVDNode(n1, n2, vt); - case Op_SubVB: return new (C, 3) SubVBNode(n1, n2, vt); - case Op_SubVS: return new (C, 3) SubVSNode(n1, n2, vt); - case Op_SubVI: return new (C, 3) SubVINode(n1, n2, vt); - case Op_SubVL: return new (C, 3) SubVLNode(n1, n2, vt); - case Op_SubVF: return new (C, 3) SubVFNode(n1, n2, vt); - case Op_SubVD: return new (C, 3) SubVDNode(n1, n2, vt); + case Op_SubVB: return new (C) SubVBNode(n1, n2, vt); + case Op_SubVS: return new (C) SubVSNode(n1, n2, vt); + case Op_SubVI: return new (C) SubVINode(n1, n2, vt); + case Op_SubVL: return new (C) SubVLNode(n1, n2, vt); + case Op_SubVF: return new (C) SubVFNode(n1, n2, vt); + case Op_SubVD: return new (C) SubVDNode(n1, n2, vt); - case Op_MulVS: return new (C, 3) MulVSNode(n1, n2, vt); - case Op_MulVI: return new (C, 3) MulVINode(n1, n2, vt); - case Op_MulVF: return new (C, 3) MulVFNode(n1, n2, vt); - case Op_MulVD: return new (C, 3) MulVDNode(n1, n2, vt); + case Op_MulVS: return new (C) MulVSNode(n1, n2, vt); + case Op_MulVI: return new (C) MulVINode(n1, n2, vt); + case Op_MulVF: return new (C) MulVFNode(n1, n2, vt); + case Op_MulVD: return new (C) MulVDNode(n1, n2, vt); - case Op_DivVF: return new (C, 3) DivVFNode(n1, n2, vt); - case Op_DivVD: return new (C, 3) DivVDNode(n1, n2, vt); + case Op_DivVF: return new (C) DivVFNode(n1, n2, vt); + case Op_DivVD: return new (C) DivVDNode(n1, n2, vt); - case Op_LShiftVB: return new (C, 3) LShiftVBNode(n1, n2, vt); - case Op_LShiftVS: return new (C, 3) LShiftVSNode(n1, n2, vt); - case Op_LShiftVI: return new (C, 3) LShiftVINode(n1, n2, vt); - case Op_LShiftVL: return new (C, 3) LShiftVLNode(n1, n2, vt); + case Op_LShiftVB: return new (C) LShiftVBNode(n1, n2, vt); + case Op_LShiftVS: return new (C) LShiftVSNode(n1, n2, vt); + case Op_LShiftVI: return new (C) LShiftVINode(n1, n2, vt); + case Op_LShiftVL: return new (C) LShiftVLNode(n1, n2, vt); - case Op_RShiftVB: return new (C, 3) RShiftVBNode(n1, n2, vt); - case Op_RShiftVS: return new (C, 3) RShiftVSNode(n1, n2, vt); - case Op_RShiftVI: return new (C, 3) RShiftVINode(n1, n2, vt); - case Op_RShiftVL: return new (C, 3) RShiftVLNode(n1, n2, vt); + case Op_RShiftVB: return new (C) RShiftVBNode(n1, n2, vt); + case Op_RShiftVS: return new (C) RShiftVSNode(n1, n2, vt); + case Op_RShiftVI: return new (C) RShiftVINode(n1, n2, vt); + case Op_RShiftVL: return new (C) RShiftVLNode(n1, n2, vt); - case Op_URShiftVB: return new (C, 3) URShiftVBNode(n1, n2, vt); - case Op_URShiftVS: return new (C, 3) URShiftVSNode(n1, n2, vt); - case Op_URShiftVI: return new (C, 3) URShiftVINode(n1, n2, vt); - case Op_URShiftVL: return new (C, 3) URShiftVLNode(n1, n2, vt); + case Op_URShiftVB: return new (C) URShiftVBNode(n1, n2, vt); + case Op_URShiftVS: return new (C) URShiftVSNode(n1, n2, vt); + case Op_URShiftVI: return new (C) URShiftVINode(n1, n2, vt); + case Op_URShiftVL: return new (C) URShiftVLNode(n1, n2, vt); - case Op_AndV: return new (C, 3) AndVNode(n1, n2, vt); - case Op_OrV: return new (C, 3) OrVNode (n1, n2, vt); - case Op_XorV: return new (C, 3) XorVNode(n1, n2, vt); + case Op_AndV: return new (C) AndVNode(n1, n2, vt); + case Op_OrV: return new (C) OrVNode (n1, n2, vt); + case Op_XorV: return new (C) XorVNode(n1, n2, vt); } ShouldNotReachHere(); return NULL; @@ -299,18 +299,18 @@ switch (bt) { case T_BOOLEAN: case T_BYTE: - return new (C, 2) ReplicateBNode(s, vt); + return new (C) ReplicateBNode(s, vt); case T_CHAR: case T_SHORT: - return new (C, 2) ReplicateSNode(s, vt); + return new (C) ReplicateSNode(s, vt); case T_INT: - return new (C, 2) ReplicateINode(s, vt); + return new (C) ReplicateINode(s, vt); case T_LONG: - return new (C, 2) ReplicateLNode(s, vt); + return new (C) ReplicateLNode(s, vt); case T_FLOAT: - return new (C, 2) ReplicateFNode(s, vt); + return new (C) ReplicateFNode(s, vt); case T_DOUBLE: - return new (C, 2) ReplicateDNode(s, vt); + return new (C) ReplicateDNode(s, vt); } ShouldNotReachHere(); return NULL; @@ -322,18 +322,18 @@ switch (bt) { case T_BOOLEAN: case T_BYTE: - return new (C, 2) PackBNode(s, vt); + return new (C) PackBNode(s, vt); case T_CHAR: case T_SHORT: - return new (C, 2) PackSNode(s, vt); + return new (C) PackSNode(s, vt); case T_INT: - return new (C, 2) PackINode(s, vt); + return new (C) PackINode(s, vt); case T_LONG: - return new (C, 2) PackLNode(s, vt); + return new (C) PackLNode(s, vt); case T_FLOAT: - return new (C, 2) PackFNode(s, vt); + return new (C) PackFNode(s, vt); case T_DOUBLE: - return new (C, 2) PackDNode(s, vt); + return new (C) PackDNode(s, vt); } ShouldNotReachHere(); return NULL; @@ -358,18 +358,18 @@ switch (bt) { case T_BOOLEAN: case T_BYTE: - return new (C, 3) PackSNode(n1, n2, TypeVect::make(T_SHORT, 2)); + return new (C) PackSNode(n1, n2, TypeVect::make(T_SHORT, 2)); case T_CHAR: case T_SHORT: - return new (C, 3) PackINode(n1, n2, TypeVect::make(T_INT, 2)); + return new (C) PackINode(n1, n2, TypeVect::make(T_INT, 2)); case T_INT: - return new (C, 3) PackLNode(n1, n2, TypeVect::make(T_LONG, 2)); + return new (C) PackLNode(n1, n2, TypeVect::make(T_LONG, 2)); case T_LONG: - return new (C, 3) Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2)); + return new (C) Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2)); case T_FLOAT: - return new (C, 3) PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); + return new (C) PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); case T_DOUBLE: - return new (C, 3) Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); + return new (C) Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2)); } ShouldNotReachHere(); } @@ -380,7 +380,7 @@ LoadVectorNode* LoadVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem, Node* adr, const TypePtr* atyp, uint vlen, BasicType bt) { const TypeVect* vt = TypeVect::make(bt, vlen); - return new (C, 3) LoadVectorNode(ctl, mem, adr, atyp, vt); + return new (C) LoadVectorNode(ctl, mem, adr, atyp, vt); return NULL; } @@ -388,7 +388,7 @@ StoreVectorNode* StoreVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem, Node* adr, const TypePtr* atyp, Node* val, uint vlen) { - return new (C, 4) StoreVectorNode(ctl, mem, adr, atyp, val); + return new (C) StoreVectorNode(ctl, mem, adr, atyp, val); } // Extract a scalar element of vector. @@ -397,21 +397,21 @@ ConINode* pos = ConINode::make(C, (int)position); switch (bt) { case T_BOOLEAN: - return new (C, 3) ExtractUBNode(v, pos); + return new (C) ExtractUBNode(v, pos); case T_BYTE: - return new (C, 3) ExtractBNode(v, pos); + return new (C) ExtractBNode(v, pos); case T_CHAR: - return new (C, 3) ExtractCNode(v, pos); + return new (C) ExtractCNode(v, pos); case T_SHORT: - return new (C, 3) ExtractSNode(v, pos); + return new (C) ExtractSNode(v, pos); case T_INT: - return new (C, 3) ExtractINode(v, pos); + return new (C) ExtractINode(v, pos); case T_LONG: - return new (C, 3) ExtractLNode(v, pos); + return new (C) ExtractLNode(v, pos); case T_FLOAT: - return new (C, 3) ExtractFNode(v, pos); + return new (C) ExtractFNode(v, pos); case T_DOUBLE: - return new (C, 3) ExtractDNode(v, pos); + return new (C) ExtractDNode(v, pos); } ShouldNotReachHere(); return NULL; diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/runtime/advancedThresholdPolicy.cpp --- a/src/share/vm/runtime/advancedThresholdPolicy.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -30,12 +30,12 @@ // Print an event. void AdvancedThresholdPolicy::print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { - tty->print(" rate: "); + tty->print(" rate="); if (mh->prev_time() == 0) tty->print("n/a"); else tty->print("%f", mh->rate()); - tty->print(" k: %.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback), - threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback)); + tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback), + threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback)); } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/runtime/compilationPolicy.cpp --- a/src/share/vm/runtime/compilationPolicy.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/runtime/compilationPolicy.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -394,28 +394,27 @@ // SimpleCompPolicy - compile current method void SimpleCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) { - int hot_count = m->invocation_count(); + const int comp_level = CompLevel_highest_tier; + const int hot_count = m->invocation_count(); reset_counter_for_invocation_event(m); const char* comment = "count"; if (is_compilation_enabled() && can_be_compiled(m)) { nmethod* nm = m->code(); if (nm == NULL ) { - const char* comment = "count"; - CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_highest_tier, - m, hot_count, comment, thread); + CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, comment, thread); } } } void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) { - int hot_count = m->backedge_count(); + const int comp_level = CompLevel_highest_tier; + const int hot_count = m->backedge_count(); const char* comment = "backedge_count"; - if (is_compilation_enabled() && !m->is_not_osr_compilable() && can_be_compiled(m)) { - CompileBroker::compile_method(m, bci, CompLevel_highest_tier, - m, hot_count, comment, thread); - NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true));) + if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m)) { + CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread); + NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));) } } // StackWalkCompPolicy - walk up stack to find a suitable method to compile @@ -426,7 +425,8 @@ // Consider m for compilation void StackWalkCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) { - int hot_count = m->invocation_count(); + const int comp_level = CompLevel_highest_tier; + const int hot_count = m->invocation_count(); reset_counter_for_invocation_event(m); const char* comment = "count"; @@ -457,20 +457,20 @@ if (TimeCompilationPolicy) accumulated_time()->stop(); assert(top != NULL, "findTopInlinableFrame returned null"); if (TraceCompilationPolicy) top->print(); - CompileBroker::compile_method(top->top_method(), InvocationEntryBci, CompLevel_highest_tier, + CompileBroker::compile_method(top->top_method(), InvocationEntryBci, comp_level, m, hot_count, comment, thread); } } } void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) { - int hot_count = m->backedge_count(); + const int comp_level = CompLevel_highest_tier; + const int hot_count = m->backedge_count(); const char* comment = "backedge_count"; - if (is_compilation_enabled() && !m->is_not_osr_compilable() && can_be_compiled(m)) { - CompileBroker::compile_method(m, bci, CompLevel_highest_tier, m, hot_count, comment, thread); - - NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true));) + if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m)) { + CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread); + NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));) } } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/runtime/sharedRuntime.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -88,6 +88,7 @@ RuntimeStub* SharedRuntime::_resolve_static_call_blob; DeoptimizationBlob* SharedRuntime::_deopt_blob; +SafepointBlob* SharedRuntime::_polling_page_vectors_safepoint_handler_blob; SafepointBlob* SharedRuntime::_polling_page_safepoint_handler_blob; SafepointBlob* SharedRuntime::_polling_page_return_handler_blob; @@ -104,8 +105,14 @@ _resolve_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C), "resolve_virtual_call"); _resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C), "resolve_static_call"); - _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), false); - _polling_page_return_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), true); +#ifdef COMPILER2 + // Vectors are generated only by C2. + if (is_wide_vector(MaxVectorSize)) { + _polling_page_vectors_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_VECTOR_LOOP); + } +#endif // COMPILER2 + _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_LOOP); + _polling_page_return_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_RETURN); generate_deopt_blob(); @@ -535,10 +542,15 @@ "Only polling locations are used for safepoint"); bool at_poll_return = ((nmethod*)cb)->is_at_poll_return(pc); + bool has_wide_vectors = ((nmethod*)cb)->has_wide_vectors(); if (at_poll_return) { assert(SharedRuntime::polling_page_return_handler_blob() != NULL, "polling page return stub not created yet"); stub = SharedRuntime::polling_page_return_handler_blob()->entry_point(); + } else if (has_wide_vectors) { + assert(SharedRuntime::polling_page_vectors_safepoint_handler_blob() != NULL, + "polling page vectors safepoint stub not created yet"); + stub = SharedRuntime::polling_page_vectors_safepoint_handler_blob()->entry_point(); } else { assert(SharedRuntime::polling_page_safepoint_handler_blob() != NULL, "polling page safepoint stub not created yet"); @@ -1618,6 +1630,31 @@ return callee_method; } +#ifdef ASSERT +void SharedRuntime::check_member_name_argument_is_last_argument(methodHandle method, + const BasicType* sig_bt, + const VMRegPair* regs) { + ResourceMark rm; + const int total_args_passed = method->size_of_parameters(); + const VMRegPair* regs_with_member_name = regs; + VMRegPair* regs_without_member_name = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed - 1); + + const int member_arg_pos = total_args_passed - 1; + assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob"); + assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object"); + + const bool is_outgoing = method->is_method_handle_intrinsic(); + int comp_args_on_stack = java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1, is_outgoing); + + for (int i = 0; i < member_arg_pos; i++) { + VMReg a = regs_with_member_name[i].first(); + VMReg b = regs_without_member_name[i].first(); + assert(a->value() == b->value(), err_msg_res("register allocation mismatch: a=%d, b=%d", a->value(), b->value())); + } + assert(regs_with_member_name[member_arg_pos].first()->is_valid(), "bad member arg"); +} +#endif + // --------------------------------------------------------------------------- // We are calling the interpreter via a c2i. Normally this would mean that // we were called by a compiled method. However we could have lost a race @@ -2423,6 +2460,7 @@ #ifndef PRODUCT // debugging suppport if (PrintAdapterHandlers || PrintStubCode) { + ttyLocker ttyl; entry->print_adapter_on(tty); tty->print_cr("i2c argument handler #%d for: %s %s (%d bytes generated)", _adapters->number_of_entries(), (method->is_static() ? "static" : "receiver"), @@ -2430,8 +2468,10 @@ tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry()); if (Verbose || PrintStubCode) { address first_pc = entry->base_address(); - if (first_pc != NULL) + if (first_pc != NULL) { Disassembler::decode(first_pc, first_pc + insts_size); + tty->cr(); + } } } #endif @@ -2546,10 +2586,10 @@ MacroAssembler _masm(&buffer); // Fill in the signature array, for the calling-convention call. - int total_args_passed = method->size_of_parameters(); - - BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed); - VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair,total_args_passed); + const int total_args_passed = method->size_of_parameters(); + + BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed); + VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed); int i=0; if( !method->is_static() ) // Pass in receiver first sig_bt[i++] = T_OBJECT; @@ -2559,7 +2599,7 @@ if( ss.type() == T_LONG || ss.type() == T_DOUBLE ) sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots } - assert( i==total_args_passed, "" ); + assert(i == total_args_passed, ""); BasicType ret_type = ss.type(); // Now get the compiled-Java layout as input (or output) arguments. @@ -2572,9 +2612,8 @@ nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, - total_args_passed, - comp_args_on_stack, - sig_bt,regs, + sig_bt, + regs, ret_type); } } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/runtime/sharedRuntime.hpp --- a/src/share/vm/runtime/sharedRuntime.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/runtime/sharedRuntime.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -62,6 +62,7 @@ static DeoptimizationBlob* _deopt_blob; + static SafepointBlob* _polling_page_vectors_safepoint_handler_blob; static SafepointBlob* _polling_page_safepoint_handler_blob; static SafepointBlob* _polling_page_return_handler_blob; @@ -75,7 +76,8 @@ #endif // !PRODUCT private: - static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return); + enum { POLL_AT_RETURN, POLL_AT_LOOP, POLL_AT_VECTOR_LOOP }; + static SafepointBlob* generate_handler_blob(address call_ptr, int poll_type); static RuntimeStub* generate_resolve_blob(address destination, const char* name); public: @@ -223,6 +225,7 @@ static SafepointBlob* polling_page_return_handler_blob() { return _polling_page_return_handler_blob; } static SafepointBlob* polling_page_safepoint_handler_blob() { return _polling_page_safepoint_handler_blob; } + static SafepointBlob* polling_page_vectors_safepoint_handler_blob() { return _polling_page_vectors_safepoint_handler_blob; } // Counters #ifndef PRODUCT @@ -345,7 +348,11 @@ // the bottom of the frame the first 16 words will be skipped and SharedInfo::stack0 // will be just above it. ( // return value is the maximum number of VMReg stack slots the convention will use. - static int java_calling_convention(const BasicType *sig_bt, VMRegPair *regs, int total_args_passed, int is_outgoing); + static int java_calling_convention(const BasicType* sig_bt, VMRegPair* regs, int total_args_passed, int is_outgoing); + + static void check_member_name_argument_is_last_argument(methodHandle method, + const BasicType* sig_bt, + const VMRegPair* regs) NOT_DEBUG_RETURN; // Ditto except for calling C static int c_calling_convention(const BasicType *sig_bt, VMRegPair *regs, int total_args_passed); @@ -412,6 +419,10 @@ // when an interrupt occurs. static uint out_preserve_stack_slots(); + // Is vector's size (in bytes) bigger than a size saved by default? + // For example, on x86 16 bytes XMM registers are saved by default. + static bool is_wide_vector(int size); + // Save and restore a native result static void save_native_result(MacroAssembler *_masm, BasicType ret_type, int frame_slots ); static void restore_native_result(MacroAssembler *_masm, BasicType ret_type, int frame_slots ); @@ -425,13 +436,11 @@ // The wrapper may contain special-case code if the given method // is a JNI critical method, or a compiled method handle adapter, // such as _invokeBasic, _linkToVirtual, etc. - static nmethod *generate_native_wrapper(MacroAssembler* masm, + static nmethod* generate_native_wrapper(MacroAssembler* masm, methodHandle method, int compile_id, - int total_args_passed, - int max_arg, - BasicType *sig_bt, - VMRegPair *regs, + BasicType* sig_bt, + VMRegPair* regs, BasicType ret_type ); // Block before entering a JNI critical method diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/runtime/simpleThresholdPolicy.cpp --- a/src/share/vm/runtime/simpleThresholdPolicy.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/runtime/simpleThresholdPolicy.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -43,11 +43,11 @@ mdo_invocations_start = mdh->invocation_count_start(); mdo_backedges_start = mdh->backedge_count_start(); } - tty->print(" %stotal: %d,%d %smdo: %d(%d),%d(%d)", prefix, + tty->print(" %stotal=%d,%d %smdo=%d(%d),%d(%d)", prefix, invocation_count, backedge_count, prefix, mdo_invocations, mdo_invocations_start, mdo_backedges, mdo_backedges_start); - tty->print(" %smax levels: %d,%d", prefix, + tty->print(" %smax levels=%d,%d", prefix, mh->highest_comp_level(), mh->highest_osr_comp_level()); } @@ -85,7 +85,7 @@ tty->print("unknown"); } - tty->print(" level: %d ", level); + tty->print(" level=%d ", level); ResourceMark rm; char *method_name = mh->name_and_sig_as_C_string(); @@ -95,8 +95,8 @@ tty->print(" [%s]] ", inlinee_name); } else tty->print("] "); - tty->print("@%d queues: %d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile), - CompileBroker::queue_size(CompLevel_full_optimization)); + tty->print("@%d queues=%d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile), + CompileBroker::queue_size(CompLevel_full_optimization)); print_specific(type, mh, imh, bci, level); @@ -105,25 +105,30 @@ if (inlinee_event) { print_counters("inlinee ", imh); } - tty->print(" compilable: "); + tty->print(" compilable="); bool need_comma = false; if (!mh->is_not_compilable(CompLevel_full_profile)) { tty->print("c1"); need_comma = true; } + if (!mh->is_not_osr_compilable(CompLevel_full_profile)) { + if (need_comma) tty->print(","); + tty->print("c1-osr"); + need_comma = true; + } if (!mh->is_not_compilable(CompLevel_full_optimization)) { - if (need_comma) tty->print(", "); + if (need_comma) tty->print(","); tty->print("c2"); need_comma = true; } - if (!mh->is_not_osr_compilable()) { - if (need_comma) tty->print(", "); - tty->print("osr"); + if (!mh->is_not_osr_compilable(CompLevel_full_optimization)) { + if (need_comma) tty->print(","); + tty->print("c2-osr"); } - tty->print(" status:"); + tty->print(" status="); if (mh->queued_for_compilation()) { - tty->print(" in queue"); - } else tty->print(" idle"); + tty->print("in-queue"); + } else tty->print("idle"); } tty->print_cr("]"); } @@ -223,7 +228,7 @@ } return; } - if (bci != InvocationEntryBci && mh->is_not_osr_compilable()) { + if (bci != InvocationEntryBci && mh->is_not_osr_compilable(level)) { return; } if (!CompileBroker::compilation_is_in_queue(mh, bci)) { diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/runtime/vmStructs.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -1905,6 +1905,8 @@ declare_c2_type(SubVLNode, VectorNode) \ declare_c2_type(SubVFNode, VectorNode) \ declare_c2_type(SubVDNode, VectorNode) \ + declare_c2_type(MulVSNode, VectorNode) \ + declare_c2_type(MulVINode, VectorNode) \ declare_c2_type(MulVFNode, VectorNode) \ declare_c2_type(MulVDNode, VectorNode) \ declare_c2_type(DivVFNode, VectorNode) \ @@ -1912,9 +1914,15 @@ declare_c2_type(LShiftVBNode, VectorNode) \ declare_c2_type(LShiftVSNode, VectorNode) \ declare_c2_type(LShiftVINode, VectorNode) \ + declare_c2_type(LShiftVLNode, VectorNode) \ declare_c2_type(RShiftVBNode, VectorNode) \ declare_c2_type(RShiftVSNode, VectorNode) \ declare_c2_type(RShiftVINode, VectorNode) \ + declare_c2_type(RShiftVLNode, VectorNode) \ + declare_c2_type(URShiftVBNode, VectorNode) \ + declare_c2_type(URShiftVSNode, VectorNode) \ + declare_c2_type(URShiftVINode, VectorNode) \ + declare_c2_type(URShiftVLNode, VectorNode) \ declare_c2_type(AndVNode, VectorNode) \ declare_c2_type(OrVNode, VectorNode) \ declare_c2_type(XorVNode, VectorNode) \ @@ -1937,6 +1945,8 @@ declare_c2_type(Pack2DNode, PackNode) \ declare_c2_type(ExtractNode, Node) \ declare_c2_type(ExtractBNode, ExtractNode) \ + declare_c2_type(ExtractUBNode, ExtractNode) \ + declare_c2_type(ExtractCNode, ExtractNode) \ declare_c2_type(ExtractSNode, ExtractNode) \ declare_c2_type(ExtractINode, ExtractNode) \ declare_c2_type(ExtractLNode, ExtractNode) \ @@ -2182,7 +2192,7 @@ declare_constant(JVM_ACC_HAS_LOOPS) \ declare_constant(JVM_ACC_LOOPS_FLAG_INIT) \ declare_constant(JVM_ACC_QUEUED) \ - declare_constant(JVM_ACC_NOT_OSR_COMPILABLE) \ + declare_constant(JVM_ACC_NOT_C2_OSR_COMPILABLE) \ declare_constant(JVM_ACC_HAS_LINE_NUMBER_TABLE) \ declare_constant(JVM_ACC_HAS_CHECKED_EXCEPTIONS) \ declare_constant(JVM_ACC_HAS_JSRS) \ diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/runtime/vm_version.cpp --- a/src/share/vm/runtime/vm_version.cpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/runtime/vm_version.cpp Fri Sep 28 10:16:29 2012 -0700 @@ -45,6 +45,10 @@ const char* Abstract_VM_Version::_s_vm_release = Abstract_VM_Version::vm_release(); const char* Abstract_VM_Version::_s_internal_vm_info_string = Abstract_VM_Version::internal_vm_info_string(); bool Abstract_VM_Version::_supports_cx8 = false; +bool Abstract_VM_Version::_supports_atomic_getset4 = false; +bool Abstract_VM_Version::_supports_atomic_getset8 = false; +bool Abstract_VM_Version::_supports_atomic_getadd4 = false; +bool Abstract_VM_Version::_supports_atomic_getadd8 = false; unsigned int Abstract_VM_Version::_logical_processors_per_package = 1U; int Abstract_VM_Version::_reserve_for_allocation_prefetch = 0; diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/runtime/vm_version.hpp --- a/src/share/vm/runtime/vm_version.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/runtime/vm_version.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -37,6 +37,10 @@ static const char* _s_internal_vm_info_string; // These are set by machine-dependent initializations static bool _supports_cx8; + static bool _supports_atomic_getset4; + static bool _supports_atomic_getset8; + static bool _supports_atomic_getadd4; + static bool _supports_atomic_getadd8; static unsigned int _logical_processors_per_package; static int _vm_major_version; static int _vm_minor_version; @@ -75,6 +79,13 @@ // does HW support an 8-byte compare-exchange operation? static bool supports_cx8() {return _supports_cx8;} + // does HW support atomic get-and-set or atomic get-and-add? Used + // to guide intrinsification decisions for Unsafe atomic ops + static bool supports_atomic_getset4() {return _supports_atomic_getset4;} + static bool supports_atomic_getset8() {return _supports_atomic_getset8;} + static bool supports_atomic_getadd4() {return _supports_atomic_getadd4;} + static bool supports_atomic_getadd8() {return _supports_atomic_getadd8;} + static unsigned int logical_processors_per_package() { return _logical_processors_per_package; } diff -r 15fba4382765 -r f2e12eb74117 src/share/vm/utilities/accessFlags.hpp --- a/src/share/vm/utilities/accessFlags.hpp Fri Sep 28 14:14:25 2012 +0200 +++ b/src/share/vm/utilities/accessFlags.hpp Fri Sep 28 10:16:29 2012 -0700 @@ -47,7 +47,7 @@ JVM_ACC_QUEUED = 0x01000000, // Queued for compilation JVM_ACC_NOT_C2_COMPILABLE = 0x02000000, JVM_ACC_NOT_C1_COMPILABLE = 0x04000000, - JVM_ACC_NOT_OSR_COMPILABLE = 0x08000000, + JVM_ACC_NOT_C2_OSR_COMPILABLE = 0x08000000, JVM_ACC_HAS_LINE_NUMBER_TABLE = 0x00100000, JVM_ACC_HAS_CHECKED_EXCEPTIONS = 0x00400000, JVM_ACC_HAS_JSRS = 0x00800000, @@ -121,9 +121,9 @@ bool has_loops () const { return (_flags & JVM_ACC_HAS_LOOPS ) != 0; } bool loops_flag_init () const { return (_flags & JVM_ACC_LOOPS_FLAG_INIT ) != 0; } bool queued_for_compilation () const { return (_flags & JVM_ACC_QUEUED ) != 0; } - bool is_not_c1_compilable () const { return (_flags & JVM_ACC_NOT_C1_COMPILABLE ) != 0; } - bool is_not_c2_compilable () const { return (_flags & JVM_ACC_NOT_C2_COMPILABLE ) != 0; } - bool is_not_osr_compilable () const { return (_flags & JVM_ACC_NOT_OSR_COMPILABLE ) != 0; } + bool is_not_c1_compilable () const { return (_flags & JVM_ACC_NOT_C1_COMPILABLE ) != 0; } + bool is_not_c2_compilable () const { return (_flags & JVM_ACC_NOT_C2_COMPILABLE ) != 0; } + bool is_not_c2_osr_compilable() const { return (_flags & JVM_ACC_NOT_C2_OSR_COMPILABLE ) != 0; } bool has_linenumber_table () const { return (_flags & JVM_ACC_HAS_LINE_NUMBER_TABLE ) != 0; } bool has_checked_exceptions () const { return (_flags & JVM_ACC_HAS_CHECKED_EXCEPTIONS ) != 0; } bool has_jsrs () const { return (_flags & JVM_ACC_HAS_JSRS ) != 0; } @@ -186,7 +186,7 @@ void set_loops_flag_init() { atomic_set_bits(JVM_ACC_LOOPS_FLAG_INIT); } void set_not_c1_compilable() { atomic_set_bits(JVM_ACC_NOT_C1_COMPILABLE); } void set_not_c2_compilable() { atomic_set_bits(JVM_ACC_NOT_C2_COMPILABLE); } - void set_not_osr_compilable() { atomic_set_bits(JVM_ACC_NOT_OSR_COMPILABLE); } + void set_not_c2_osr_compilable() { atomic_set_bits(JVM_ACC_NOT_C2_OSR_COMPILABLE); } void set_has_linenumber_table() { atomic_set_bits(JVM_ACC_HAS_LINE_NUMBER_TABLE); } void set_has_checked_exceptions() { atomic_set_bits(JVM_ACC_HAS_CHECKED_EXCEPTIONS); } void set_has_jsrs() { atomic_set_bits(JVM_ACC_HAS_JSRS); } diff -r 15fba4382765 -r f2e12eb74117 test/compiler/7196199/Test7196199.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/7196199/Test7196199.java Fri Sep 28 10:16:29 2012 -0700 @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 7196199 + * @summary java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect + * + * @run main/othervm/timeout=400 -Xmx32m -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:CompileCommand=exclude,Test7196199.test -XX:+SafepointALot -XX:GuaranteedSafepointInterval=100 Test7196199 + */ + + +public class Test7196199 { + private static final int ARRLEN = 97; + private static final int ITERS = 5000; + private static final int INI_ITERS = 1000; + private static final int SFP_ITERS = 10000; + private static final float SFP_ITERS_F = 10000.f; + private static final float VALUE = 15.f; + public static void main(String args[]) { + int errn = test(); + if (errn > 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + System.out.println("PASSED"); + } + + static int test() { + float[] a0 = new float[ARRLEN]; + float[] a1 = new float[ARRLEN]; + // Initialize + for (int i=0; i 0) + return errn; + + System.out.println("Time"); + long start, end; + + start = System.currentTimeMillis(); + for (int i=0; i test.out 2>&1 + +COUNT=`grep AddVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 4 ] +then + echo "Test Failed: AddVI $COUNT < 4" + exit 1 +fi + +# AddVI is generated for test_subc +COUNT=`grep SubVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 4 ] +then + echo "Test Failed: SubVI $COUNT < 4" + exit 1 +fi + +# LShiftVI+SubVI is generated for test_mulc +COUNT=`grep MulVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 2 ] +then + echo "Test Failed: MulVI $COUNT < 2" + exit 1 +fi + +COUNT=`grep AndV test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 3 ] +then + echo "Test Failed: AndV $COUNT < 3" + exit 1 +fi + +COUNT=`grep OrV test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 3 ] +then + echo "Test Failed: OrV $COUNT < 3" + exit 1 +fi + +COUNT=`grep XorV test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 3 ] +then + echo "Test Failed: XorV $COUNT < 3" + exit 1 +fi + +COUNT=`grep LShiftVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 5 ] +then + echo "Test Failed: LShiftVI $COUNT < 5" + exit 1 +fi + +# RShiftVI + URShiftVI +COUNT=`grep RShiftVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 6 ] +then + echo "Test Failed: RShiftVI $COUNT < 6" + exit 1 +fi + +COUNT=`grep URShiftVI test.out | wc -l | awk '{print $1}'` +if [ $COUNT -lt 3 ] +then + echo "Test Failed: URShiftVI $COUNT < 3" + exit 1 +fi + diff -r 15fba4382765 -r f2e12eb74117 test/compiler/7200264/TestIntVect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/7200264/TestIntVect.java Fri Sep 28 10:16:29 2012 -0700 @@ -0,0 +1,650 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 7200264 + * @summary 7192963 changes disabled shift vectors + * + * @run shell Test7200264.sh + */ + +/* + * Copy of test/compiler/6340864/TestIntVect.java without performance tests. + */ +public class TestIntVect { + private static final int ARRLEN = 997; + private static final int ITERS = 11000; + private static final int ADD_INIT = Integer.MAX_VALUE-500; + private static final int BIT_MASK = 0xEC80F731; + private static final int VALUE = 15; + private static final int SHIFT = 32; + + public static void main(String args[]) { + System.out.println("Testing Integer vectors"); + int errn = test(); + if (errn > 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + System.out.println("PASSED"); + } + + static int test() { + int[] a0 = new int[ARRLEN]; + int[] a1 = new int[ARRLEN]; + int[] a2 = new int[ARRLEN]; + int[] a3 = new int[ARRLEN]; + int[] a4 = new int[ARRLEN]; + long[] p2 = new long[ARRLEN/2]; + // Initialize + int gold_sum = 0; + for (int i=0; i>>VALUE)); + } + test_srlv(a0, a1, VALUE); + for (int i=0; i>>VALUE)); + } + + test_srac(a0, a1); + for (int i=0; i>VALUE)); + } + test_srav(a0, a1, VALUE); + for (int i=0; i>VALUE)); + } + + test_sllc_n(a0, a1); + for (int i=0; i>>(-VALUE))); + } + test_srlv(a0, a1, -VALUE); + for (int i=0; i>>(-VALUE))); + } + + test_srac_n(a0, a1); + for (int i=0; i>(-VALUE))); + } + test_srav(a0, a1, -VALUE); + for (int i=0; i>(-VALUE))); + } + + test_sllc_o(a0, a1); + for (int i=0; i>>SHIFT)); + } + test_srlv(a0, a1, SHIFT); + for (int i=0; i>>SHIFT)); + } + + test_srac_o(a0, a1); + for (int i=0; i>SHIFT)); + } + test_srav(a0, a1, SHIFT); + for (int i=0; i>SHIFT)); + } + + test_sllc_on(a0, a1); + for (int i=0; i>>(-SHIFT))); + } + test_srlv(a0, a1, -SHIFT); + for (int i=0; i>>(-SHIFT))); + } + + test_srac_on(a0, a1); + for (int i=0; i>(-SHIFT))); + } + test_srav(a0, a1, -SHIFT); + for (int i=0; i>(-SHIFT))); + } + + test_pack2(p2, a1); + for (int i=0; i>>VALUE); + } + } + static void test_srlc_n(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>>(-VALUE)); + } + } + static void test_srlc_o(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>>SHIFT); + } + } + static void test_srlc_on(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>>(-SHIFT)); + } + } + static void test_srlv(int[] a0, int[] a1, int b) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>>b); + } + } + + static void test_srac(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>VALUE); + } + } + static void test_srac_n(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>(-VALUE)); + } + } + static void test_srac_o(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>SHIFT); + } + } + static void test_srac_on(int[] a0, int[] a1) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>(-SHIFT)); + } + } + static void test_srav(int[] a0, int[] a1, int b) { + for (int i = 0; i < a0.length; i+=1) { + a0[i] = (int)(a1[i]>>b); + } + } + + static void test_pack2(long[] p2, int[] a1) { + if (p2.length*2 > a1.length) return; + for (int i = 0; i < p2.length; i+=1) { + long l0 = (long)a1[i*2+0]; + long l1 = (long)a1[i*2+1]; + p2[i] = (l1 << 32) | (l0 & 0xFFFFFFFFl); + } + } + static void test_unpack2(int[] a0, long[] p2) { + if (p2.length*2 > a0.length) return; + for (int i = 0; i < p2.length; i+=1) { + long l = p2[i]; + a0[i*2+0] = (int)(l & 0xFFFFFFFFl); + a0[i*2+1] = (int)(l >> 32); + } + } + static void test_pack2_swap(long[] p2, int[] a1) { + if (p2.length*2 > a1.length) return; + for (int i = 0; i < p2.length; i+=1) { + long l0 = (long)a1[i*2+0]; + long l1 = (long)a1[i*2+1]; + p2[i] = (l0 << 32) | (l1 & 0xFFFFFFFFl); + } + } + static void test_unpack2_swap(int[] a0, long[] p2) { + if (p2.length*2 > a0.length) return; + for (int i = 0; i < p2.length; i+=1) { + long l = p2[i]; + a0[i*2+0] = (int)(l >> 32); + a0[i*2+1] = (int)(l & 0xFFFFFFFFl); + } + } + + static int verify(String text, int i, int elem, int val) { + if (elem != val) { + System.err.println(text + "[" + i + "] = " + elem + " != " + val); + return 1; + } + return 0; + } + + static int verify(String text, int i, long elem, long val) { + if (elem != val) { + System.err.println(text + "[" + i + "] = " + Long.toHexString(elem) + " != " + Long.toHexString(val)); + return 1; + } + return 0; + } +}