This commit is contained in:
Vladimir Kozlov 2012-09-28 10:16:29 -07:00
commit fbd1f6e3be
138 changed files with 5462 additions and 4473 deletions

View File

@ -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 @@ ProjectCreatorIncludesPRIVATE=\
-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=\
$(ProjectCreatorIDEOptions) \
-sourceBase $(HOTSPOTWORKSPACE) \
-buildBase $(HOTSPOTBUILDSPACE)\%f\%b \
-buildSpace $(HOTSPOTBUILDSPACE) \
-startAt src \
-compiler $(VcVersion) \
-projectFileName $(HOTSPOTBUILDSPACE)\$(ProjectFile) \
@ -103,6 +117,7 @@ ProjectCreatorIDEOptions=\
-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 @@ ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
!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 @@ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=kernel) \
##################################################
ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
-define_compiler1 COMPILER1 \
-ignorePath_compiler1 core \
$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1)
##################################################
@ -217,18 +237,19 @@ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1)
#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 @@ ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
# 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

View File

@ -725,24 +725,6 @@ void MacroAssembler::jump(const AddressLiteral& addrlit, Register temp, int offs
}
// 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 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
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 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
// 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 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
// 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 @@ void MacroAssembler::lookup_interface_method(Register recv_klass,
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);
}
}

View File

@ -2428,9 +2428,6 @@ public:
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

View File

@ -347,7 +347,11 @@ inline void Assembler::sub(Register s1, RegisterOrConstant s2, Register d, int o
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

View File

@ -1315,7 +1315,13 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod
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::peephole(LIR_List* lir) {
}
}
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 __

View File

@ -1204,3 +1204,58 @@ void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
__ 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);
}
}

View File

@ -1395,12 +1395,17 @@ void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocat
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);
}

View File

@ -121,6 +121,7 @@ void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Registe
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 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
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 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
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 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
// 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 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
// 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 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
// get target Method* & entry point
__ lookup_virtual_method(temp1_recv_klass, temp2_index, G5_method);
method_is_live = true;
break;
}
@ -432,13 +430,13 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
// 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 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
}
// 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();
}
}
}

View File

@ -313,6 +313,14 @@ void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
}
// 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 @@ static VMRegPair reg64_to_VMRegPair(Register r) {
// ---------------------------------------------------------------------------
// 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 SharedRuntime::java_calling_convention(const BasicType *sig_bt,
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;
int slot = 0;
// Now do the signature layout
for (int i = 0; i < total_args_passed; i++) {
switch (sig_bt[i]) {
case T_INT:
@ -461,11 +406,14 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
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 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
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++));
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 (flt_reg < flt_reg_max) {
FloatRegister r = as_FloatRegister(flt_reg++);
regs[i].set1(r->as_VMReg());
} else {
regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
stk_reg_pairs += 2;
regs[i].set1(VMRegImpl::stack2reg(slot++));
}
break;
case T_VOID: regs[i].set_bad(); break; // Halves of longs & doubles
case T_DOUBLE:
assert(sig_bt[i+1] == T_VOID, "expecting half");
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 {
slot = round_to(slot, 2); // align
regs[i].set2(VMRegImpl::stack2reg(slot));
slot += 2;
}
break;
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 @@ void AdapterGenerator::patch_callers_callsite() {
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 @@ void AdapterGenerator::patch_callers_callsite() {
__ 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 @@ void AdapterGenerator::gen_c2i_adapter(
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 @@ void AdapterGenerator::gen_c2i_adapter(
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 @@ void AdapterGenerator::gen_c2i_adapter(
(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;
const 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);
}
// 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; i<total_args_passed; i++) {
const int st_off = interp_arg_offset - (i*Interpreter::stackElementSize) + bias;
VMReg r_1 = regs[i].first();
VMReg r_2 = regs[i].second();
if (r_1 == G1_scratch->as_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; i<total_args_passed; i++) {
// Write the args into the outgoing interpreter space.
for (int i = 0; i < total_args_passed; i++) {
const int st_off = interp_arg_offset - (i*Interpreter::stackElementSize) + bias;
VMReg r_1 = regs[i].first();
VMReg r_2 = regs[i].second();
@ -804,23 +701,9 @@ void AdapterGenerator::gen_c2i_adapter(
assert(!r_2->is_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 @@ void AdapterGenerator::gen_c2i_adapter(
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 @@ void AdapterGenerator::gen_c2i_adapter(
}
}
#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 @@ void AdapterGenerator::gen_i2c_adapter(
// 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 @@ void AdapterGenerator::gen_i2c_adapter(
// +--------------+ <--- 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 @@ void AdapterGenerator::gen_i2c_adapter(
// 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 @@ void AdapterGenerator::gen_i2c_adapter(
__ 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; i<total_args_passed; i++) {
for (int i = 0; i < total_args_passed; i++) {
if (sig_bt[i] == T_VOID) {
// Longs and doubles are passed in native word order, but misaligned
// in the 32-bit build.
@ -1088,14 +953,13 @@ void AdapterGenerator::gen_i2c_adapter(
next_arg_slot(ld_off) : arg_slot(ld_off);
__ ldx(Gargs, slot, r);
#else
// Need to load a 64-bit value into G1/G4, but G1/G4 is being used in the
// stack shuffle. Load the first 2 longs into G1/G4 later.
fatal("longs should be on stack");
#endif
}
} else {
assert(r_1->is_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 @@ void AdapterGenerator::gen_i2c_adapter(
// 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 @@ void AdapterGenerator::gen_i2c_adapter(
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; i<total_args_passed; i++) {
if (regs[i].first()->is_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 */
__ 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);
// 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);
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();
}
__ restore();
}
__ jmpl(G3, 0, G0);
__ delayed()->nop();
__ jmpl(G3, 0, G0);
__ delayed()->nop();
}
// ---------------------------------------------------------------
@ -1221,28 +1044,17 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
// 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 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
// 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 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
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 unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType
}
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 verify_oop_args(MacroAssembler* masm,
}
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 @@ static void gen_special_dispatch(MacroAssembler* masm,
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 @@ static void gen_special_dispatch(MacroAssembler* masm,
// 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 @@ static void gen_special_dispatch(MacroAssembler* masm,
}
// 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 @@ static void gen_special_dispatch(MacroAssembler* masm,
// 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 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
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 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// 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 @@ void SharedRuntime::generate_uncommon_trap_blob() {
// 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 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
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();

View File

@ -1838,6 +1838,12 @@ const bool Matcher::match_rule_supported(int opcode) {
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 @@ instruct storeLConditional( iRegP mem_ptr, iRegL oldval, g3RegL newval, flagsReg
// 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 compareAndSwapI_bool(iRegP mem_ptr, iRegI oldval, iRegI newval, iRegI r
%}
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 @@ instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI r
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

View File

@ -96,6 +96,7 @@ void VM_Version::initialize() {
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 @@ void VM_Version::revert() {
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);

View File

@ -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 @@ public:
// 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

View File

@ -3496,6 +3496,33 @@ void Assembler::vinsertf128h(XMMRegister dst, XMMRegister nds, XMMRegister src)
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 @@ void Assembler::vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src)
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 @@ void MacroAssembler::fp_runtime_fallback(address runtime_entry, int nb_args, int
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 @@ void MacroAssembler::fp_runtime_fallback(address runtime_entry, int nb_args, int
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 @@ void MacroAssembler::fp_runtime_fallback(address runtime_entry, int nb_args, int
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
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
}
if (UseSSE >= 1) {
addptr(rsp, sizeof(jdouble)* LP64_ONLY(16) NOT_LP64(8));
}
popa();
}

View File

@ -1743,6 +1743,12 @@ private:
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

View File

@ -3794,5 +3794,49 @@ void LIR_Assembler::peephole(LIR_List*) {
// 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 __

View File

@ -753,9 +753,24 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
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::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data,
}
}
}
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);
}
}
}

View File

@ -327,10 +327,11 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
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 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
// 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 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
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 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
// get target Method* & entry point
__ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method);
method_is_live = true;
break;
}
@ -464,35 +462,32 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
}
// 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()));
}
}
}

View File

@ -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 @@ class RegisterSaver {
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 @@ class RegisterSaver {
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 @@ class RegisterSaver {
};
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 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
__ 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 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
__ 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 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
}
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 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm) {
__ 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 @@ void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
__ 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 unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType
}
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 verify_oop_args(MacroAssembler* masm,
}
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 @@ static void gen_special_dispatch(MacroAssembler* masm,
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 @@ static void gen_special_dispatch(MacroAssembler* masm,
// 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 @@ static void gen_special_dispatch(MacroAssembler* masm,
}
// 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 @@ static void gen_special_dispatch(MacroAssembler* masm,
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 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
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 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// 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 @@ uint SharedRuntime::out_preserve_stack_slots() {
return 0;
}
//------------------------------generate_deopt_blob----------------------------
void SharedRuntime::generate_deopt_blob() {
// allocate space for the code
@ -3276,7 +3326,7 @@ void SharedRuntime::generate_uncommon_trap_blob() {
// 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 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
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)
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);
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 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
__ 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 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
__ 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);

View File

@ -116,8 +116,8 @@ class RegisterSaver {
};
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 @@ class RegisterSaver {
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 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
__ 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 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
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 @@ void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
__ 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 @@ class ComputeMoveOrder: public StackObj {
};
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 verify_oop_args(MacroAssembler* masm,
}
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 @@ static void gen_special_dispatch(MacroAssembler* masm,
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 @@ static void gen_special_dispatch(MacroAssembler* masm,
// 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 @@ static void gen_special_dispatch(MacroAssembler* masm,
}
// 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 @@ static void gen_special_dispatch(MacroAssembler* masm,
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 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
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 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// 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 @@ uint SharedRuntime::out_preserve_stack_slots() {
return 0;
}
//------------------------------generate_deopt_blob----------------------------
void SharedRuntime::generate_deopt_blob() {
// Allocate space for the code
@ -3746,7 +3777,7 @@ void SharedRuntime::generate_uncommon_trap_blob() {
// 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 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
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 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
}
// 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 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
// Exception pending
RegisterSaver::restore_live_registers(masm);
RegisterSaver::restore_live_registers(masm, save_vectors);
__ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
@ -3813,7 +3846,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
__ bind(noException);
// Normal exit, restore registers and exit.
RegisterSaver::restore_live_registers(masm);
RegisterSaver::restore_live_registers(masm, save_vectors);
__ ret(0);

View File

@ -363,6 +363,11 @@ void VM_Version::get_processor_features() {
}
_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 @@ void VM_Version::get_processor_features() {
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 @@ void VM_Version::get_processor_features() {
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 @@ void VM_Version::get_processor_features() {
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");

View File

@ -498,10 +498,18 @@ const bool Matcher::match_rule_supported(int opcode) {
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.

View File

@ -7762,6 +7762,7 @@ instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlags
// 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 @@ instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newv
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) %{

View File

@ -7242,6 +7242,7 @@ instruct compareAndSwapP(rRegI res,
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 @@ instruct compareAndSwapL(rRegI res,
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 @@ instruct compareAndSwapN(rRegI res,
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

View File

@ -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<String> basicNames, basicPaths;
String[] context;
static CompilerInterface ci;
@ -47,6 +46,7 @@ class BuildConfig {
return ci;
}
@SuppressWarnings("rawtypes")
protected void initNames(String flavour, String build, String outDll) {
if (vars == null) vars = new Hashtable();
@ -63,26 +63,28 @@ class BuildConfig {
// 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<String> includes, Vector<String> defines) {
initDefaultDefines(defines);
initDefaultCompilerFlags(includes);
initDefaultLinkerFlags();
handleDB();
//handleDB();
}
protected void initDefaultCompilerFlags(Vector includes) {
protected void initDefaultCompilerFlags(Vector<String> includes) {
Vector compilerFlags = new Vector();
compilerFlags.addAll(getCI().getBaseCompilerFlags(getV("Define"),
@ -100,143 +102,48 @@ class BuildConfig {
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<String> rv = new Vector<String>();
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<String> rv = new Vector<String>();
collectRelevantVectors(rv, "HidePath");
for (String pathPart : rv) {
if (path.contains(Util.normalize(pathPart))) {
return true;
}
}
return false;
}
public Vector<String> matchesAdditionalGeneratedPath(String fullPath) {
Vector<String> rv = new Vector<String>();
Hashtable<String, String> v = (Hashtable<String, String>)BuildConfig.getField(this.toString(), "AdditionalGeneratedFile");
if (v != null) {
for (Enumeration<String> 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 @@ class BuildConfig {
}
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<String> 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 @@ class BuildConfig {
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<String> rv = new Vector<String>();
Vector<String> ri = new Vector<String>();
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 @@ class TieredFastDebugConfig extends GenericDebugNonKernelConfig {
}
}
abstract class ProductConfig extends BuildConfig {
protected void init(Vector includes, Vector defines) {
defines.add("NDEBUG");
@ -638,7 +539,6 @@ class TieredProductConfig extends ProductConfig {
}
}
class CoreDebugConfig extends GenericDebugNonKernelConfig {
String getOptFlag() {
return getCI().getNoOptFlag();
@ -650,7 +550,6 @@ class CoreDebugConfig extends GenericDebugNonKernelConfig {
}
}
class CoreFastDebugConfig extends GenericDebugNonKernelConfig {
String getOptFlag() {
return getCI().getOptFlag();
@ -662,7 +561,6 @@ class CoreFastDebugConfig extends GenericDebugNonKernelConfig {
}
}
class CoreProductConfig extends ProductConfig {
CoreProductConfig() {
initNames("core", "product", "jvm.dll");
@ -700,6 +598,7 @@ class KernelProductConfig extends ProductConfig {
init(getIncludes(), getDefines());
}
}
abstract class CompilerInterface {
abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir);
abstract Vector getBaseLinkerFlags(String outDir, String outDll, String platformName);

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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>
{
Path vcProjLocation;
Path startDir;
final int startDirLength;
Stack<DirAttributes> attributes = new Stack<DirAttributes>();
Vector<BuildConfig> allConfigs;
WinGammaPlatformVC10 wg;
public FileTreeCreator(Path startDir, Vector<BuildConfig> 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<BuildConfig> ignores;
private HashSet<BuildConfig> disablePch;
public DirAttributes() {
ignores = new HashSet<BuildConfig>();
disablePch = new HashSet<BuildConfig>();
}
public DirAttributes(HashSet<BuildConfig> excludes2, HashSet<BuildConfig> disablePch2) {
ignores = excludes2;
disablePch = disablePch2;
}
@SuppressWarnings("unchecked")
public DirAttributes clone() {
return new DirAttributes((HashSet<BuildConfig>)this.ignores.clone(), (HashSet<BuildConfig>)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);
}
}
}

View File

@ -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<BuildConfig> 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<String> rv = new Vector<String>();
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);
}
}

View File

@ -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<BuildConfig> 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<String> rv = new Vector<String>();
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);
}
}

View File

@ -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 <path to directory (workspace) " +
"containing source files; no trailing slash>");
System.err.println(" -dspFileName <full pathname to which .dsp file " +
"will be written; all parent directories must " +
"already exist>");
System.err.println(" -envVar <environment variable to be inserted " +
"into .dsp file, substituting for path given in " +
"-sourceBase. Example: HotSpotWorkSpace>");
System.err.println(" -dllLoc <path to directory in which to put " +
"jvm.dll and jvm_g.dll; no trailing slash>");
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 <string containing absolute " +
"path to include directory>");
System.err.println(" -relativeInclude <string containing include " +
"directory relative to -envVar>");
System.err.println(" -define <preprocessor flag to be #defined " +
"(note: doesn't yet support " +
"#define (flag) (value))>");
System.err.println(" -perFileLine <file> <line>");
System.err.println(" -conditionalPerFileLine <file> <line for " +
"release build> <line for debug build>");
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 <subdir of sourceBase>");
System.err.println(" -ignoreFile <file which won't be able to be " +
"found in the sourceBase because it's generated " +
"later>");
System.err.println(" -additionalFile <file not in database but " +
"which should show up in .dsp file>");
System.err.println(" -additionalGeneratedFile <environment variable of " +
"generated file's location> <relative path to " +
"directory containing file; no trailing slash> " +
"<name of file generated later in the build process>");
System.err.println(" -prelink <build> <desc> <cmds>:");
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 <path to directory (workspace) "
+ "containing source files; no trailing slash>");
System.err.println(" -dspFileName <full pathname to which .dsp file "
+ "will be written; all parent directories must "
+ "already exist>");
System.err.println(" -envVar <environment variable to be inserted "
+ "into .dsp file, substituting for path given in "
+ "-sourceBase. Example: HotSpotWorkSpace>");
System.err.println(" -dllLoc <path to directory in which to put "
+ "jvm.dll and jvm_g.dll; no trailing slash>");
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 <string containing absolute "
+ "path to include directory>");
System.err.println(" -relativeInclude <string containing include "
+ "directory relative to -envVar>");
System.err.println(" -define <preprocessor flag to be #defined "
+ "(note: doesn't yet support " + "#define (flag) (value))>");
System.err.println(" -perFileLine <file> <line>");
System.err.println(" -conditionalPerFileLine <file> <line for "
+ "release build> <line for debug build>");
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 <subdir of sourceBase>");
System.err.println(" -ignoreFile <file which won't be able to be "
+ "found in the sourceBase because it's generated " + "later>");
System.err.println(" -additionalFile <file not in database but "
+ "which should show up in .dsp file>");
System.err
.println(" -additionalGeneratedFile <environment variable of "
+ "generated file's location> <relative path to "
+ "directory containing file; no trailing slash> "
+ "<name of file generated later in the build process>");
System.err.println(" -prelink <build> <desc> <cmds>:");
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);
}
}
}

View File

@ -26,18 +26,19 @@ import java.util.*;
import java.io.File;
public class Util {
static String join(String padder, Vector v) {
static String join(String padder, Vector<String> v) {
return join(padder, v, false);
}
static String join(String padder, Vector v, boolean quoted) {
static String join(String padder, Vector<String> v, boolean quoted) {
StringBuffer sb = new StringBuffer();
for (Iterator iter = v.iterator(); iter.hasNext(); ) {
for (Iterator<String> 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 @@ public class Util {
}
static String prefixed_join(String padder, Vector v, boolean quoted) {
static String prefixed_join(String padder, Vector<String> v, boolean quoted) {
StringBuffer sb = new StringBuffer();
for (Iterator iter = v.iterator(); iter.hasNext(); ) {
for (Iterator<String> iter = v.iterator(); iter.hasNext(); ) {
sb.append(padder);
if (quoted) {

View File

@ -29,6 +29,7 @@ import java.util.Enumeration;
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 @@ public abstract class WinGammaPlatform {
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 @@ public abstract class WinGammaPlatform {
HsArgHandler.STRING
),
new HsArgRule("-buildSpace",
"BuildSpace",
null,
HsArgHandler.STRING
),
new HsArgRule("-platformName",
"PlatformName",
null,
@ -405,6 +349,18 @@ public abstract class WinGammaPlatform {
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 @@ public abstract class WinGammaPlatform {
HsArgHandler.VECTOR
),
new HsArgRule("-hidePath",
"HidePath",
null,
HsArgHandler.VECTOR
),
new HsArgRule("-additionalFile",
"AdditionalFile",
null,
@ -611,107 +573,101 @@ public abstract class WinGammaPlatform {
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<BuildConfig> allConfigs) throws IOException {
throw new RuntimeException("use compiler version specific version");
}
int indent;
private Stack<String> tagStack = new Stack<String>();
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("</" + name + ">");
}
private void endTagNoIndent() {
String name = tagStack.pop();
indent--;
printWriter.println("</" + name + ">");
}
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(" ");
}
}
}

View File

@ -3,14 +3,18 @@ import java.io.FileNotFoundException;
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 <String>filters = new LinkedList<String>();
LinkedList <String[]>filterDeps = new LinkedList<String[]>();
@Override
protected String getProjectExt() {
return ".vcxproj";
@ -37,15 +41,15 @@ public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
"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 @@ public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
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 @@ public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
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 @@ public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
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<BuildConfig> allConfigs, String base) throws FileNotFoundException, UnsupportedEncodingException {
String filterFileName = projectFileName + ".filters";
@ -157,210 +169,92 @@ public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
"ToolsVersion", "4.0",
"xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
Hashtable<String, FileAttribute> allFiles = computeAttributedFiles(allConfigs);
TreeSet<FileInfo> sortedFiles = sortFiles(allFiles);
Vector<NameFilter> 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
//TODO - do I need to split cpp and hpp files?
// then all files
startTag("ItemGroup");
for (NameFilter filter : filters) {
doWriteFiles(sortedFiles, filter, "", "ClCompile", new Evaluator() {
public boolean pick(FileInfo fi) {
return fi.isCpp();
}
}, base);
}
endTag("ItemGroup");
for (String[] dep : filterDeps) {
String tagName = getFileTagFromSuffix(dep[0]);
// then all header files
startTag("ItemGroup");
for (NameFilter filter : filters) {
doWriteFiles(sortedFiles, filter, "", "ClInclude", new Evaluator() {
public boolean pick(FileInfo fi) {
return fi.isHeader();
}
}, base);
startTag(tagName, "Include", dep[0]);
tagData("Filter", dep[1]);
endTag();
}
endTag("ItemGroup");
endTag();
// then all other files
startTag("ItemGroup");
for (NameFilter filter : filters) {
doWriteFiles(sortedFiles, filter, "", "None", new Evaluator() {
public boolean pick(FileInfo fi) {
return true;
}
}, base);
}
endTag("ItemGroup");
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 + "\\");
}
}
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";
}
}
interface Evaluator {
boolean pick(FileInfo fi);
}
private void doWriteFiles(TreeSet<FileInfo> 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<BuildConfig> allConfigs, String projDir) {
Hashtable<String, FileAttribute> allFiles = computeAttributedFiles(allConfigs);
TreeSet<FileInfo> 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");
// then header-files
startTag("ItemGroup");
for (FileInfo fi : sortedFiles) {
if (!fi.isHeader()) {
continue;
}
writeFile("ClInclude", allConfigs, fi, projDir);
}
endTag("ItemGroup");
// Use first config for all global absolute includes.
BuildConfig baseConfig = allConfigs.firstElement();
Vector<String> rv = new Vector<String>();
// then others
startTag("ItemGroup");
for (FileInfo fi : sortedFiles) {
if (fi.isHeader() || fi.isCpp()) {
continue;
}
writeFile("None", allConfigs, fi, projDir);
}
endTag("ItemGroup");
// Then use first config for all relative includes
Vector<String> ri = new Vector<String>();
baseConfig.collectRelevantVectors(ri, "RelativeSrcInclude");
for (String f : ri) {
rv.add(sourceBase + Util.sep + f);
}
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<BuildConfig> 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<String> includes, Vector<BuildConfig> 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<String> v) {
Iterator<String> i = v.iterator();
while(i.hasNext()) {
@ -391,6 +285,7 @@ public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
startTag(name, ss);
}
}
class CompilerInterfaceVC10 extends CompilerInterface {

View File

@ -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;
}
}

View File

@ -751,6 +751,7 @@ bool InstructForm::captures_bottom_type(FormDict &globals) const {
!strcmp(_matrule->_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 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
"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 @@ Form::DataType MatchRule::is_ideal_load() const {
}
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<cnt; i++)
if (strcmp(opType,vector_list[i]) == 0)
return true;
}
return false;
}

View File

@ -1606,6 +1606,12 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
fprintf(fp, " ((MachFastLockNode*)n%d)->_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 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
}
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");
}

View File

@ -1026,25 +1026,30 @@ class CodeComment: public CHeapObj<mtCode> {
}
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::add_comment(intptr_t offset, const char * comment) {
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 CodeComments::free() {
void CodeBuffer::decode() {
ttyLocker ttyl;
Disassembler::decode(decode_begin(), insts_end());
_decode_begin = insts_end();
}
@ -1096,6 +1101,7 @@ void CodeBuffer::skip_decode() {
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);

View File

@ -253,7 +253,7 @@ public:
}
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;
};

View File

@ -103,8 +103,8 @@ inline void assert_different_registers(
) {
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 @@ inline void assert_different_registers(
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 @@ inline void assert_different_registers(
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 @@ inline void assert_different_registers(
&& 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 @@ inline void assert_different_registers(
&& 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 @@ inline void assert_different_registers(
&& 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 @@ inline void assert_different_registers(
&& 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 @@ inline void assert_different_registers(
&& 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)
);
}

View File

@ -931,6 +931,7 @@ void Canonicalizer::do_UnsafeGetRaw(UnsafeGetRaw* x) { if (OptimizeUnsafes) do_U
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) {}

View File

@ -100,6 +100,7 @@ class Canonicalizer: InstructionVisitor {
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);

View File

@ -346,7 +346,8 @@ void Compilation::install_code(int frame_size) {
implicit_exception_table(),
compiler(),
_env->comp_level(),
has_unsafe_access()
has_unsafe_access(),
SharedRuntime::is_wide_vector(max_vector_size())
);
}

View File

@ -127,6 +127,7 @@ class Compilation: public StackObj {
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; }

View File

@ -3383,6 +3383,41 @@ bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
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 @@ void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool succes
}
}
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() {

View File

@ -367,6 +367,7 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC {
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);

View File

@ -102,6 +102,7 @@ class UnsafePutRaw;
class UnsafeObjectOp;
class UnsafeGetObject;
class UnsafePutObject;
class UnsafeGetAndSetObject;
class UnsafePrefetch;
class UnsafePrefetchRead;
class UnsafePrefetchWrite;
@ -202,6 +203,7 @@ class InstructionVisitor: public StackObj {
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 @@ LEAF(UnsafePutObject, UnsafeObjectOp)
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:

View File

@ -831,6 +831,12 @@ void InstructionPrinter::do_UnsafePutObject(UnsafePutObject* x) {
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");

View File

@ -128,6 +128,7 @@ class InstructionPrinter: public InstructionVisitor {
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);

View File

@ -264,6 +264,7 @@ void LIR_Op2::verify() const {
#ifdef ASSERT
switch (code()) {
case lir_cmove:
case lir_xchg:
break;
default:
@ -630,6 +631,8 @@ void LIR_OpVisitState::visit(LIR_Op* op) {
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 @@ void LIR_OpVisitState::visit(LIR_Op* op) {
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 @@ const char * LIR_Op::name() const {
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;

View File

@ -963,6 +963,8 @@ enum LIR_Code {
, lir_alloc_array
, lir_throw
, lir_compare_to
, lir_xadd
, lir_xchg
, end_op2
, begin_op3
, lir_idiv
@ -2191,6 +2193,9 @@ class LIR_List: public CompilationResourceObj {
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 @@ class LIR_OpVisitState: public StackObj {
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 {

View File

@ -773,6 +773,11 @@ void LIR_Assembler::emit_op2(LIR_Op2* op) {
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;

View File

@ -252,6 +252,8 @@ class LIR_Assembler: public CompilationResourceObj {
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

View File

@ -527,6 +527,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure {
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);

View File

@ -505,6 +505,7 @@ public:
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_UnsafeGetRaw (UnsafeGetRaw* x) {}
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(); }

View File

@ -157,6 +157,7 @@ class ValueNumberingVisitor: public InstructionVisitor {
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 */ }

View File

@ -921,7 +921,8 @@ void ciEnv::register_method(ciMethod* target,
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 @@ void ciEnv::register_method(ciMethod* target,
}
} 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.)

View File

@ -362,7 +362,8 @@ public:
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.

View File

@ -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") \
\

View File

@ -162,8 +162,10 @@ void CodeBlob::trace_new_stub(CodeBlob* stub, const char* name1, const char* nam
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::verify() {
}
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::verify() {
}
void SingletonBlob::print_on(outputStream* st) const {
ttyLocker ttyl;
CodeBlob::print_on(st);
st->print_cr(name());
Disassembler::decode((CodeBlob*)this, st);

View File

@ -184,7 +184,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
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);
}

View File

@ -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 @@ class ICStub: public Stub {
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

View File

@ -463,6 +463,7 @@ void nmethod::init_defaults() {
_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 @@ nmethod::nmethod(
// 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 @@ ScopeDesc* nmethod::scope_desc_in(address begin, address end) {
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]");

View File

@ -177,6 +177,7 @@ class nmethod : public CodeBlob {
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 @@ class nmethod : public CodeBlob {
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 @@ public:
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);

View File

@ -101,7 +101,8 @@ Stub* StubQueue::stub_containing(address pc) const {
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 @@ Stub* StubQueue::request(int requested_code_size) {
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 @@ Stub* StubQueue::request(int requested_code_size) {
// 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 @@ Stub* StubQueue::request(int requested_code_size) {
}
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();

View File

@ -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 Stub VALUE_OBJ_CLASS_SPEC {
class StubInterface: public CHeapObj<mtCode> {
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 @@ class StubInterface: public CHeapObj<mtCode> {
\
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 @@ class StubQueue: public CHeapObj<mtCode> {
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 @@ class StubQueue: public CHeapObj<mtCode> {
// 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

View File

@ -197,9 +197,9 @@ class CompilationLog : public StringEventLog {
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 @@ void CompileTask::print_inline_indent(int inline_level, outputStream* st) {
// ------------------------------------------------------------------
// 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 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
// 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 @@ bool CompileBroker::compilation_is_complete(methodHandle method,
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 @@ bool CompileBroker::compilation_is_prohibited(methodHandle method, int osr_bci,
// 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 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
_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 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
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

View File

@ -105,7 +105,7 @@ private:
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,

View File

@ -125,46 +125,46 @@ int CompileLog::identify(ciBaseObject* obj) {
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));

View File

@ -148,6 +148,7 @@ class decode_env {
private:
nmethod* _nm;
CodeBlob* _code;
CodeComments _comments;
outputStream* _output;
address _start, _end;
@ -187,7 +188,7 @@ class decode_env {
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 @@ class decode_env {
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 @@ void decode_env::print_insn_labels() {
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 @@ void Disassembler::decode(CodeBlob* cb, outputStream* st) {
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);
}

View File

@ -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 @@ class Disassembler {
}
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

View File

@ -60,6 +60,8 @@ void InterpreterCodelet::verify() {
void InterpreterCodelet::print_on(outputStream* st) const {
ttyLocker ttyl;
if (PrintInterpreter) {
st->cr();
st->print_cr("----------------------------------------------------------------------");
@ -72,7 +74,7 @@ void InterpreterCodelet::print_on(outputStream* st) const {
if (PrintInterpreter) {
st->cr();
Disassembler::decode(code_begin(), code_end(), st);
Disassembler::decode(code_begin(), code_end(), st, DEBUG_ONLY(_comments) NOT_DEBUG(CodeComments()));
}
}

View File

@ -48,10 +48,12 @@ class InterpreterCodelet: public Stub {
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 @@ class CodeletMark: ResourceMark {
// 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;
}

View File

@ -251,8 +251,12 @@ void Method::mask_for(int bci, InterpreterOopMap* mask) {
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 @@ void Method::set_signature_handler(address handler) {
}
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 @@ void Method::set_not_compilable(int comp_level, bool report) {
}
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);
}

View File

@ -745,19 +745,30 @@ class Method : public Metadata {
// 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(); }

View File

@ -248,47 +248,47 @@ Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) {
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))>>>z for small constant z and y.
// Helps with array allocation math constant folding
@ -309,8 +309,8 @@ Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) {
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<<z) ) );
return new (phase->C, 3) URShiftINode( a, in1->in(2) );
Node *a = phase->transform( new (phase->C) AddINode( in1->in(1), phase->intcon(y<<z) ) );
return new (phase->C) URShiftINode( a, in1->in(2) );
}
}
}
@ -381,47 +381,47 @@ Node *AddLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *AddLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *AddPNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *AddPNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// 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 @@ Node *AddPNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
// 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 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
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)));
}
}

View File

@ -378,7 +378,7 @@ PhaseCFG::PhaseCFG( Arena *a, RootNode *r, Matcher &m ) :
// 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 @@ uint PhaseCFG::build_cfg() {
!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 @@ void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) {
// 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);

View File

@ -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, \

View File

@ -134,7 +134,7 @@ JVMState* DirectCallGenerator::generate(JVMState* jvms) {
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 @@ JVMState* VirtualCallGenerator::generate(JVMState* jvms) {
"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 @@ void LateInlineCallGenerator::do_late_inline() {
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 @@ JVMState* PredictedCallGenerator::generate(JVMState* jvms) {
// 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 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod*
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 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod*
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);
}
}

View File

@ -72,20 +72,20 @@ Node *StartNode::match( const ProjNode *proj, const Matcher *match ) {
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 @@ Node *CallNode::match( const ProjNode *proj, const Matcher *match ) {
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 @@ Node *CallNode::match( const ProjNode *proj, const Matcher *match ) {
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* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseTran
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));
}
}

View File

@ -612,17 +612,17 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ const TypePtr* flatten_phi_adr_type(const TypePtr* at) {
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 @@ PhiNode* PhiNode::make_blank(Node* r, Node* x) {
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 @@ static Node *is_x2logic( PhaseGVN *phase, PhiNode *phi, int true_path ) {
} 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 @@ static Node* is_cond_add(PhaseGVN *phase, PhiNode *phi, int true_path) {
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 @@ static Node* is_absolute( PhaseGVN *phase, PhiNode *phi_root, int true_path) {
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 @@ static Node* split_flow_path(PhaseGVN *phase, PhiNode *phi) {
// 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 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
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 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// 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 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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; i<req(); ++i) {// For all paths in
Node *ii = in(i);
@ -1909,14 +1909,14 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (ii->as_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

View File

@ -1588,7 +1588,7 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive
// 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());

View File

@ -83,6 +83,12 @@ macro(CompareAndSwapI)
macro(CompareAndSwapL)
macro(CompareAndSwapP)
macro(CompareAndSwapN)
macro(GetAndAddI)
macro(GetAndAddL)
macro(GetAndSetI)
macro(GetAndSetL)
macro(GetAndSetP)
macro(GetAndSetN)
macro(Con)
macro(ConN)
macro(ConD)

View File

@ -654,14 +654,14 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
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 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
&_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 @@ void Compile::Init(int aliaslevel) {
// 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 @@ void Compile::Init(int aliaslevel) {
_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 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) {
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 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) {
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 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) {
}
}
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 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) {
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 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) {
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 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) {
} 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);
}
}

View File

@ -279,6 +279,7 @@ class Compile : public Phase {
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 @@ class Compile : public Phase {
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; }

View File

@ -45,16 +45,16 @@ uint ConNode::hash() const {
//------------------------------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 @@ const Type *CMoveNode::Value( PhaseTransform *phase ) const {
// 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 @@ Node *CMoveINode::Ideal(PhaseGVN *phase, bool can_reshape) {
#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 @@ Node *CMoveFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *CMoveDNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ static bool can_cause_alias(Node *n, PhaseTransform *phase) {
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 @@ Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *ConvL2INode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ static inline Node* addP_of_X2P(PhaseGVN *phase,
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));
}

View File

@ -58,7 +58,7 @@ public:
// 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 @@ public:
// 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 @@ public:
// 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 @@ public:
// 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 @@ public:
// Factory method:
static ConDNode* make( Compile *C, double con ) {
return new (C, 1) ConDNode( TypeD::make(con) );
return new (C) ConDNode( TypeD::make(con) );
}
};

View File

@ -104,7 +104,7 @@ static Node *transform_int_divide( PhaseGVN *phase, Node *dividend, jint divisor
// 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 @@ static Node *transform_int_divide( PhaseGVN *phase, Node *dividend, jint divisor
// (-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 @@ static Node *transform_int_divide( PhaseGVN *phase, Node *dividend, jint divisor
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 @@ static Node *transform_int_divide( PhaseGVN *phase, Node *dividend, jint divisor
// 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 @@ static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_con
// 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 @@ static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_con
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 @@ static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_con
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 @@ static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_con
}
}
return new (phase->C, 3) AddLNode(temp1, temp2);
return new (phase->C) AddLNode(temp1, temp2);
}
@ -355,7 +355,7 @@ static Node *transform_long_divide( PhaseGVN *phase, Node *dividend, jlong divis
// 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 @@ static Node *transform_long_divide( PhaseGVN *phase, Node *dividend, jlong divis
// (-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 @@ static Node *transform_long_divide( PhaseGVN *phase, Node *dividend, jlong divis
// 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 @@ static Node *transform_long_divide( PhaseGVN *phase, Node *dividend, jlong divis
// 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 @@ Node *DivFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *DivDNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) {
// 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 *ModINode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ Node *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// 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 *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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 @@ DivModINode* DivModINode::make(Compile* C, Node* div_or_mod) {
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 @@ DivModLNode* DivModLNode::make(Compile* C, Node* div_or_mod) {
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 @@ Node *DivModINode::match( const ProjNode *proj, const Matcher *match ) {
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 @@ Node *DivModLNode::match( const ProjNode *proj, const Matcher *match ) {
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);
}

View File

@ -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 @@ void trace_type_profile(ciMethod *method, int depth, int bci, ciMethod *prof_met
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 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
}
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 @@ void Parse::do_call() {
} 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 @@ void Parse::do_call() {
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 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
}
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 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
// 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 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
// 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 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
// 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 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
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) {

View File

@ -282,6 +282,26 @@ bool ConnectionGraph::compute_escape() {
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 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
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 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
}
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 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
}
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 @@ void ConnectionGraph::add_final_edges(Node *n) {
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 @@ void ConnectionGraph::add_final_edges(Node *n) {
}
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 @@ void ConnectionGraph::add_final_edges(Node *n) {
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() ||

View File

@ -371,6 +371,8 @@ private:
_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);

View File

@ -50,7 +50,7 @@ void GraphKit::gen_stub(address C_function,
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 @@ void GraphKit::gen_stub(address C_function,
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 @@ void GraphKit::gen_stub(address C_function,
// 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( ; i<map()->req(); i++ )
map()->init_req(i, top()); // For nicer debugging
@ -80,7 +80,7 @@ void GraphKit::gen_stub(address C_function,
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 @@ void GraphKit::gen_stub(address C_function,
//-----------------------------
// 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 @@ void GraphKit::gen_stub(address C_function,
//-----------------------------
// 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 @@ void GraphKit::gen_stub(address C_function,
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 @@ void GraphKit::gen_stub(address C_function,
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();

View File

@ -280,7 +280,7 @@ JVMState* GraphKit::transfer_exceptions_into_jvms() {
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 @@ void GraphKit::combine_exception_states(SafePointNode* ex_map, SafePointNode* ph
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 @@ void GraphKit::uncommon_trap_if_should_post_on_exceptions(Deoptimization::DeoptR
// 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 @@ BuildCutout::BuildCutout(GraphKit* kit, Node* p, float prob, float cnt)
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 @@ bool GraphKit::compute_stack_effects(int& inputs, int& depth, bool for_parse) {
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 @@ Node* GraphKit::ConvI2L(Node* offset) {
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 @@ Node* GraphKit::ConvL2I(Node* offset) {
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* GraphKit::load_array_length(Node* array) {
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 @@ Node* GraphKit::null_check_common(Node* value, BasicType type,
// 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 @@ Node* GraphKit::null_check_common(Node* value, BasicType type,
return value; // Elided null check quickly!
}
}
chk = new (C, 3) CmpPNode( value, null() );
chk = new (C) CmpPNode( value, null() );
break;
}
@ -1235,7 +1235,7 @@ Node* GraphKit::null_check_common(Node* value, BasicType type,
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 @@ Node* GraphKit::null_check_common(Node* value, BasicType type,
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 @@ Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) {
// 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 @@ void GraphKit::set_all_memory(Node* newmem) {
//------------------------------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 @@ Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt,
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 @@ void GraphKit::set_edges_for_java_call(CallJavaNode* call, bool must_throw, bool
// 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 @@ Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_p
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 @@ Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_p
// 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 @@ void GraphKit::set_predefined_output_for_runtime_call(Node* call,
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 @@ void GraphKit::increment_counter(Node* counter_addr) {
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 @@ void GraphKit::uncommon_trap(int trap_request,
// 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 @@ void GraphKit::round_double_result(ciMethod* dest_method) {
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::precision_rounding(Node* n) {
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::dprecision_rounding(Node *n) {
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 @@ Node* GraphKit::opt_iff(Node* region, Node* iff) {
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* GraphKit::make_runtime_call(int flags,
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 @@ Node* GraphKit::make_runtime_call(int flags,
}
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 @@ Node* GraphKit::make_runtime_call(int flags,
}
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 @@ void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool sep
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 @@ void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool sep
// 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 @@ Node* GraphKit::gen_subtype_check(Node* subklass, Node* superklass) {
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 @@ Node* GraphKit::gen_subtype_check(Node* subklass, Node* superklass) {
// 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 @@ Node* GraphKit::gen_subtype_check(Node* subklass, Node* superklass) {
// 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 @@ Node* GraphKit::gen_subtype_check(Node* subklass, Node* superklass) {
// 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 @@ Node* GraphKit::gen_subtype_check(Node* subklass, Node* superklass) {
}
// 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 @@ Node* GraphKit::gen_subtype_check(Node* subklass, Node* superklass) {
// 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 @@ Node* GraphKit::gen_subtype_check(Node* subklass, Node* superklass) {
// 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) );
new (C) 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 ) );
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 @@ Node* GraphKit::type_check_receiver(Node* receiver, ciKlass* klass,
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 @@ Node* GraphKit::gen_instanceof(Node* obj, Node* superklass) {
// 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 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass,
// 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* GraphKit::gen_checkcast(Node *obj, Node* superklass,
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 @@ Node* GraphKit::insert_mem_bar(int opcode, Node* precedent) {
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 @@ Node* GraphKit::insert_mem_bar_volatile(int opcode, int alias_idx, Node* precede
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 @@ FastLockNode* GraphKit::shared_lock(Node* obj) {
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 @@ FastLockNode* GraphKit::shared_lock(Node* obj) {
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 @@ void GraphKit::shared_unlock(Node* box, Node* obj) {
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 @@ Node* GraphKit::set_output_for_allocation(AllocateNode* alloc,
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 @@ Node* GraphKit::set_output_for_allocation(AllocateNode* alloc,
}
// 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 @@ Node* GraphKit::new_instance(Node* klass_node,
// (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 @@ Node* GraphKit::new_instance(Node* klass_node,
// 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 @@ Node* GraphKit::new_instance(Node* klass_node,
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 @@ Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
// 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 @@ Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
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 @@ Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
} 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 @@ Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
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 @@ Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
// 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 @@ Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
// 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 @@ void GraphKit::add_predicate_impl(Deoptimization::DeoptReason reason, int nargs)
}
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 @@ void GraphKit::add_predicate_impl(Deoptimization::DeoptReason reason, int nargs)
_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 @@ void GraphKit::g1_write_barrier_pre(bool do_load,
#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 @@ void GraphKit::g1_mark_card(IdealKit& ideal,
#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);

View File

@ -303,31 +303,31 @@ class GraphKit : public Phase {
// 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 @@ class GraphKit : public Phase {
// 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 @@ class GraphKit : public Phase {
}
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

View File

@ -86,7 +86,7 @@ void IdealKit::if_then(Node* left, BoolTest::mask relop,
}
// 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 @@ Node* IdealKit::make_label(int goto_ct) {
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 @@ Node* IdealKit::delay_transform(Node* n) {
//-----------------------------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 @@ Node* IdealKit::storeCM(Node* ctl, Node* adr, Node *val, Node* oop_store, int oo
// 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 @@ void IdealKit::make_leaf_call(const TypeFunc *slow_call_type,
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 @@ void IdealKit::make_leaf_call(const TypeFunc *slow_call_type,
// 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 @@ void IdealKit::make_leaf_call_no_fp(const TypeFunc *slow_call_type,
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 @@ void IdealKit::make_leaf_call_no_fp(const TypeFunc *slow_call_type,
// 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);

View File

@ -175,39 +175,39 @@ class IdealKit: public StackObj {
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);

View File

@ -238,10 +238,10 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
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 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
// 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 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
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 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
}
// 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 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
// 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 @@ static void adjust_check(Node* proj, Node* range, Node* index,
// 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 @@ Node* IfNode::fold_compares(PhaseGVN* phase) {
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 @@ Node *IfNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// 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 @@ static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff) {
// 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 @@ static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff) {
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 @@ static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff) {
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);

View File

@ -369,7 +369,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe
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 @@ uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_
// 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 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray<int> &
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);

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More