mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-25 13:54:38 +02:00
Merge
This commit is contained in:
commit
fbd1f6e3be
138 changed files with 5462 additions and 4473 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 __
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 __
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) %{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
72
hotspot/src/share/tools/ProjectCreator/FileTreeCreator.java
Normal file
72
hotspot/src/share/tools/ProjectCreator/FileTreeCreator.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
142
hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java
Normal file
142
hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
156
hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java
Normal file
156
hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(" ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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())
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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 */ }
|
||||
|
|
|
@ -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.)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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") \
|
||||
\
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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) );
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() ||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue