# HG changeset patch # User aoqi # Date 1527162590 -28800 # Node ID ffcdff41a92f45aaf144e16a1a7a3c46bb4e7f07 # Parent e4aeef458496c49b79b3cdde8d0af8825d422481 some C1 fix Contributed-by: chenhaoxuan, zhaixiang, aoqi diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/c1_CodeStubs_mips.cpp --- a/src/cpu/mips/vm/c1_CodeStubs_mips.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/c1_CodeStubs_mips.cpp Thu May 24 19:49:50 2018 +0800 @@ -51,6 +51,7 @@ #ifdef TIERED void CounterOverflowStub::emit_code(LIR_Assembler* ce) { __ bind(_entry); + ce->store_parameter(_method->as_register(), 1); ce->store_parameter(_bci, 0); __ call(Runtime1::entry_for(Runtime1::counter_overflow_id), relocInfo::runtime_call_type); __ delayed()->nop(); @@ -198,22 +199,16 @@ void NewObjectArrayStub::emit_code(LIR_Assembler* ce) { assert(__ sp_offset() == 0, "frame size should be fixed"); __ bind(_entry); - //assert(_length->as_register() == rbx, "length must in rbx,"); - //assert(_klass_reg->as_register() == rdx, "klass_reg must in rdx"); - //__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::new_object_array_id))); assert(_length->as_register() == T2, "length must in ebx"); #ifndef _LP64 assert(_klass_reg->as_register() == T4, "klass_reg must in T4"); #else - //FIXME. in A4? aoqi assert(_klass_reg->as_register() == A4, "klass_reg must in A4"); #endif __ call(Runtime1::entry_for(Runtime1::new_object_array_id), relocInfo::runtime_call_type); __ delayed()->nop(); ce->add_call_info_here(_info); ce->verify_oop_map(_info); - //assert(_result->as_register() == rax, "result must in rax,"); - //__ jmp(_continuation); assert(_result->as_register() == V0, "result must in eax"); __ b_far(_continuation); __ delayed()->nop(); @@ -234,20 +229,14 @@ __ bind(_entry); ce->store_parameter(_obj_reg->as_register(), 1); ce->store_parameter(_lock_reg->is_single_cpu()? _lock_reg->as_register() : _lock_reg->as_register_lo(), 0); - /* - Runtime1::StubID enter_id; - if (ce->compilation()->has_fpu_code()) { - enter_id = Runtime1::monitorenter_id; - } else { - enter_id = Runtime1::monitorenter_nofpu_id; - } - __ call(RuntimeAddress(Runtime1::entry_for(enter_id))); - */ + Runtime1::StubID enter_id; if (ce->compilation()->has_fpu_code()) { - __ call(Runtime1::entry_for(Runtime1::monitorenter_id), relocInfo::runtime_call_type); + enter_id = Runtime1::monitorenter_id; } else { - __ call(Runtime1::entry_for(Runtime1::monitorenter_nofpu_id), relocInfo::runtime_call_type); + enter_id = Runtime1::monitorenter_nofpu_id; } + //__ call(RuntimeAddress(Runtime1::entry_for(enter_id))); + __ call(Runtime1::entry_for(enter_id), relocInfo::runtime_call_type); __ delayed()->nop(); ce->add_call_info_here(_info); ce->verify_oop_map(_info); @@ -264,24 +253,16 @@ } ce->store_parameter(_lock_reg->as_register(), 0); // note: non-blocking leaf routine => no call info needed - /* - Runtime1::StubID exit_id; - if (ce->compilation()->has_fpu_code()) { - exit_id = Runtime1::monitorexit_id; - } else { - exit_id = Runtime1::monitorexit_nofpu_id; - } - __ call(RuntimeAddress(Runtime1::entry_for(exit_id))); - __ jmp(_continuation); - */ + Runtime1::StubID exit_id; if (ce->compilation()->has_fpu_code()) { - __ call(Runtime1::entry_for(Runtime1::monitorexit_id), relocInfo::runtime_call_type); + exit_id = Runtime1::monitorexit_id; } else { - __ call(Runtime1::entry_for(Runtime1::monitorexit_nofpu_id), relocInfo::runtime_call_type); + exit_id = Runtime1::monitorexit_nofpu_id; } + //__ call(RuntimeAddress(Runtime1::entry_for(exit_id))); + __ call(Runtime1::entry_for(exit_id), relocInfo::runtime_call_type); __ delayed()->nop(); - //__ jmp(_continuation); __ b_far(_continuation); __ delayed()->nop(); } @@ -308,7 +289,8 @@ // doesn't span a cache line. // the NativeJump is not finished, i am not sure what to do here. FIXME - //masm->align(round_to(NativeGeneralJump::instruction_size, wordSize)); + // masm->align(round_to(NativeGeneralJump::instruction_size, wordSize)); + //tty->print_cr("align_patch_site has not finished yet!!!"); } void PatchingStub::emit_code(LIR_Assembler* ce) { @@ -327,19 +309,31 @@ } if (_id == load_klass_id) { // produce a copy of the load klass instruction for use by the being initialized case +//#ifdef ASSERT address start = __ pc(); +//#endif + Metadata* o = NULL; + RelocationHolder rspec = metadata_Relocation::spec(_index); + __ relocate(rspec); + __ li48(_obj, (long)o); + while ((intx)__ pc() - (intx)start < NativeCall::instruction_size) { + __ nop(); + } +#ifdef ASSERT + for (int i = 0; i < _bytes_to_copy; i++) { + address ptr = (address)(_pc_start + i); + int a_byte = (*ptr) & 0xFF; + assert(a_byte == *start++, "should be the same code"); + } +#endif + } else if (_id == load_mirror_id || _id == load_appendix_id) { +//#ifdef ASSERT + address start = __ pc(); +//#endif jobject o = NULL; - int oop_index = __ oop_recorder()->allocate_oop_index(o); - RelocationHolder rspec = oop_Relocation::spec(oop_index); + RelocationHolder rspec = oop_Relocation::spec(_index); __ relocate(rspec); -#ifndef _LP64 - //by_css - __ lui(_obj, Assembler::split_high((int)o)); - __ addiu(_obj, _obj, Assembler::split_low((int)o)); -#else - //This should be same as jobject2reg_with_patching. __ li48(_obj, (long)o); -#endif while ((intx)__ pc() - (intx)start < NativeCall::instruction_size) { __ nop(); } @@ -366,21 +360,18 @@ address end_of_patch = __ pc(); int bytes_to_skip = 0; - if (_id == load_klass_id) { + if (_id == load_mirror_id) { int offset = __ offset(); if (CommentedAssembly) { __ block_comment(" being_initialized check"); } assert(_obj != NOREG, "must be a valid register"); -#ifndef OPT_THREAD - //FIXME, T8 need be saved ? - Register thread = T8; - __ get_thread(thread); -#else - Register thread = TREG; -#endif - __ ld(AT, _obj, in_bytes(InstanceKlass::init_thread_offset())); - __ bne(thread, AT, call_patch); + Register tmp = AT; + Register tmp2 = T9; + __ ld_ptr(tmp2, Address(_obj, java_lang_Class::klass_offset_in_bytes())); + __ get_thread(tmp); + __ ld_ptr(tmp2, Address(tmp2, InstanceKlass::init_thread_offset())); + __ bne(tmp, tmp2, call_patch); __ delayed()->nop(); // access_field patches may execute the patched code before it's @@ -402,23 +393,8 @@ bytes_to_skip += sizeof_patch_record; // emit the offsets needed to find the code to patch - int being_initialized_entry_offset = __ pc() - being_initialized_entry + patch_info_size; + int being_initialized_entry_offset = __ pc() - being_initialized_entry + sizeof_patch_record; -#ifdef _LP64 - /* Jin: In MIPS64, byte_skip is much larger than that in X86. It can not be contained in a byte: - * - bytes_to_skip = 0x190; - * - _bytes_to_copy = 0x20; - * - being_initialized_entry_offset = 0x1b0; - * - * To minimize the modification of share codes, the values are decreased 4 times when generated, - * thus can be packed into a long type. - * - * See [share/vm/c1/c1_Runtime1.cpp 918] Runtime1::patch_code() - */ - being_initialized_entry_offset /= 4; - _bytes_to_copy /= 4; - bytes_to_skip /= 4; -#endif // patch_info_pc offset | size of b instruction(8)| patched code size assert((char)being_initialized_entry_offset==being_initialized_entry_offset, "just check"); assert((char)bytes_to_skip==bytes_to_skip, "just check"); @@ -426,18 +402,17 @@ __ emit_int32(being_initialized_entry_offset<<8 | (bytes_to_skip<<16) | (_bytes_to_copy<<24) ); address patch_info_pc = __ pc(); -#ifdef _LP64 - assert(patch_info_pc - end_of_patch == bytes_to_skip * 4, "incorrect patch info"); -#else assert(patch_info_pc - end_of_patch == bytes_to_skip, "incorrect patch info"); -#endif address entry = __ pc(); NativeGeneralJump::insert_unconditional((address)_pc_start, entry); address target = NULL; + relocInfo::relocType reloc_type = relocInfo::none; switch (_id) { case access_field_id: target = Runtime1::entry_for(Runtime1::access_field_patching_id); break; - case load_klass_id: target = Runtime1::entry_for(Runtime1::load_klass_patching_id); break; + case load_klass_id: target = Runtime1::entry_for(Runtime1::load_klass_patching_id); reloc_type = relocInfo::metadata_type; break; + case load_mirror_id: target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); reloc_type = relocInfo::oop_type; break; + case load_appendix_id: target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); reloc_type = relocInfo::oop_type; break; default: ShouldNotReachHere(); } __ bind(call_patch); @@ -446,12 +421,7 @@ if (CommentedAssembly) { __ block_comment("patch entry point"); } -#ifndef _LP64 - __ lui(T9, Assembler::split_high((int)target)); - __ addiu(T9, T9, Assembler::split_low((int)target)); -#else __ li48(T9, (long)target); -#endif __ jalr(T9); __ delayed()->nop(); assert(_patch_info_offset == (patch_info_pc - __ pc()), "must not change"); @@ -464,15 +434,23 @@ for (int j = __ offset(); j < jmp_off + NativeCall::instruction_size; j += 4 ) { __ nop(); } - if (_id == load_klass_id) { + if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) { CodeSection* cs = __ code_section(); address pc = (address)_pc_start; RelocIterator iter(cs, pc, pc + 1); - relocInfo::change_reloc_info_for_address(&iter, pc, relocInfo::oop_type, relocInfo::none); + relocInfo::change_reloc_info_for_address(&iter, pc, reloc_type, relocInfo::none); } } +void DeoptimizeStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + __ call(Runtime1::entry_for(Runtime1::deoptimize_id), relocInfo::runtime_call_type); + ce->add_call_info_here(_info); + DEBUG_ONLY(__ should_not_reach_here()); +} + + void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) { ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); __ bind(_entry); diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/c1_FrameMap_mips.cpp --- a/src/cpu/mips/vm/c1_FrameMap_mips.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/c1_FrameMap_mips.cpp Thu May 24 19:49:50 2018 +0800 @@ -162,6 +162,31 @@ LIR_Opr FrameMap::_s6_oop_opr; LIR_Opr FrameMap::_s7_oop_opr; +//add metadata_opr +LIR_Opr FrameMap::_v0_metadata_opr; +LIR_Opr FrameMap::_v1_metadata_opr; +LIR_Opr FrameMap::_a0_metadata_opr; +LIR_Opr FrameMap::_a1_metadata_opr; +LIR_Opr FrameMap::_a2_metadata_opr; +LIR_Opr FrameMap::_a3_metadata_opr; +LIR_Opr FrameMap::_t0_metadata_opr; +LIR_Opr FrameMap::_t1_metadata_opr; +LIR_Opr FrameMap::_t2_metadata_opr; +LIR_Opr FrameMap::_t3_metadata_opr; +LIR_Opr FrameMap::_a4_metadata_opr; +LIR_Opr FrameMap::_a5_metadata_opr; +LIR_Opr FrameMap::_a6_metadata_opr; +LIR_Opr FrameMap::_a7_metadata_opr; +LIR_Opr FrameMap::_t8_metadata_opr; +LIR_Opr FrameMap::_t9_metadata_opr; +LIR_Opr FrameMap::_s0_metadata_opr; +LIR_Opr FrameMap::_s1_metadata_opr; +LIR_Opr FrameMap::_s2_metadata_opr; +LIR_Opr FrameMap::_s3_metadata_opr; +LIR_Opr FrameMap::_s4_metadata_opr; +LIR_Opr FrameMap::_s5_metadata_opr; +LIR_Opr FrameMap::_s6_metadata_opr; +LIR_Opr FrameMap::_s7_metadata_opr; LIR_Opr FrameMap::_a0_a1_long_opr; LIR_Opr FrameMap::_a2_a3_long_opr; @@ -220,15 +245,15 @@ #else _at_opr=LIR_OprFact::single_cpu(1); #endif - map_register(2,V0); _v0_opr=LIR_OprFact::single_cpu(2); _v0_oop_opr=LIR_OprFact::single_cpu_oop(2); - map_register(3,V1); _v1_opr=LIR_OprFact::single_cpu(3); _v1_oop_opr=LIR_OprFact::single_cpu_oop(3); - map_register(4,A0); _a0_opr=LIR_OprFact::single_cpu(4); _a0_oop_opr=LIR_OprFact::single_cpu_oop(4); - map_register(5,A1); _a1_opr=LIR_OprFact::single_cpu(5); _a1_oop_opr=LIR_OprFact::single_cpu_oop(5); - map_register(6,A2); _a2_opr=LIR_OprFact::single_cpu(6); _a2_oop_opr=LIR_OprFact::single_cpu_oop(6); - map_register(7,A3); _a3_opr=LIR_OprFact::single_cpu(7); _a3_oop_opr=LIR_OprFact::single_cpu_oop(7); + map_register(2,V0); _v0_opr=LIR_OprFact::single_cpu(2); _v0_oop_opr=LIR_OprFact::single_cpu_oop(2); _v0_metadata_opr=LIR_OprFact::single_cpu_metadata(2); + map_register(3,V1); _v1_opr=LIR_OprFact::single_cpu(3); _v1_oop_opr=LIR_OprFact::single_cpu_oop(3); _v1_metadata_opr=LIR_OprFact::single_cpu_metadata(3); + map_register(4,A0); _a0_opr=LIR_OprFact::single_cpu(4); _a0_oop_opr=LIR_OprFact::single_cpu_oop(4); _a0_metadata_opr=LIR_OprFact::single_cpu_metadata(4); + map_register(5,A1); _a1_opr=LIR_OprFact::single_cpu(5); _a1_oop_opr=LIR_OprFact::single_cpu_oop(5); _a1_metadata_opr=LIR_OprFact::single_cpu_metadata(5); + map_register(6,A2); _a2_opr=LIR_OprFact::single_cpu(6); _a2_oop_opr=LIR_OprFact::single_cpu_oop(6); _a2_metadata_opr=LIR_OprFact::single_cpu_metadata(6); + map_register(7,A3); _a3_opr=LIR_OprFact::single_cpu(7); _a3_oop_opr=LIR_OprFact::single_cpu_oop(7); _a3_metadata_opr=LIR_OprFact::single_cpu_metadata(7); #ifndef _LP64 - map_register(8,T0); _t0_opr=LIR_OprFact::single_cpu(8); _t0_oop_opr=LIR_OprFact::single_cpu_oop(8); - map_register(9,T1); _t1_opr=LIR_OprFact::single_cpu(9); _t1_oop_opr=LIR_OprFact::single_cpu_oop(9); + map_register(8,T0); _t0_opr=LIR_OprFact::single_cpu(8); _t0_oop_opr=LIR_OprFact::single_cpu_oop(8); + map_register(9,T1); _t1_opr=LIR_OprFact::single_cpu(9); _t1_oop_opr=LIR_OprFact::single_cpu_oop(9); map_register(10,T2); _t2_opr=LIR_OprFact::single_cpu(10); _t2_oop_opr=LIR_OprFact::single_cpu_oop(10); map_register(11,T3); _t3_opr=LIR_OprFact::single_cpu(11); _t3_oop_opr=LIR_OprFact::single_cpu_oop(11); map_register(12,T4); _t4_opr=LIR_OprFact::single_cpu(12); _t4_oop_opr=LIR_OprFact::single_cpu_oop(12); @@ -236,23 +261,23 @@ map_register(14,T6); _t6_opr=LIR_OprFact::single_cpu(14); _t6_oop_opr=LIR_OprFact::single_cpu_oop(14); map_register(15,T7); _t7_opr=LIR_OprFact::single_cpu(15); _t7_oop_opr=LIR_OprFact::single_cpu_oop(15); #else - map_register(8,A4); _a4_opr=LIR_OprFact::single_cpu(8); _a4_oop_opr=LIR_OprFact::single_cpu_oop(8); - map_register(9,A5); _a5_opr=LIR_OprFact::single_cpu(9); _a5_oop_opr=LIR_OprFact::single_cpu_oop(9); - map_register(10,A6); _a6_opr=LIR_OprFact::single_cpu(10); _a6_oop_opr=LIR_OprFact::single_cpu_oop(10); - map_register(11,A7); _a7_opr=LIR_OprFact::single_cpu(11); _a7_oop_opr=LIR_OprFact::single_cpu_oop(11); - map_register(12,T0); _t0_opr=LIR_OprFact::single_cpu(12); _t0_oop_opr=LIR_OprFact::single_cpu_oop(12); - map_register(13,T1); _t1_opr=LIR_OprFact::single_cpu(13); _t1_oop_opr=LIR_OprFact::single_cpu_oop(13); - map_register(14,T2); _t2_opr=LIR_OprFact::single_cpu(14); _t2_oop_opr=LIR_OprFact::single_cpu_oop(14); - map_register(15,T3); _t3_opr=LIR_OprFact::single_cpu(15); _t3_oop_opr=LIR_OprFact::single_cpu_oop(15); + map_register(8,A4); _a4_opr=LIR_OprFact::single_cpu(8); _a4_oop_opr=LIR_OprFact::single_cpu_oop(8); _a4_metadata_opr=LIR_OprFact::single_cpu_metadata(8); + map_register(9,A5); _a5_opr=LIR_OprFact::single_cpu(9); _a5_oop_opr=LIR_OprFact::single_cpu_oop(9); _a5_metadata_opr=LIR_OprFact::single_cpu_metadata(9); + map_register(10,A6); _a6_opr=LIR_OprFact::single_cpu(10); _a6_oop_opr=LIR_OprFact::single_cpu_oop(10); _a6_metadata_opr=LIR_OprFact::single_cpu_metadata(10); + map_register(11,A7); _a7_opr=LIR_OprFact::single_cpu(11); _a7_oop_opr=LIR_OprFact::single_cpu_oop(11); _a7_metadata_opr=LIR_OprFact::single_cpu_metadata(11); + map_register(12,T0); _t0_opr=LIR_OprFact::single_cpu(12); _t0_oop_opr=LIR_OprFact::single_cpu_oop(12); _t0_metadata_opr=LIR_OprFact::single_cpu_metadata(12); + map_register(13,T1); _t1_opr=LIR_OprFact::single_cpu(13); _t1_oop_opr=LIR_OprFact::single_cpu_oop(13); _t1_metadata_opr=LIR_OprFact::single_cpu_metadata(13); + map_register(14,T2); _t2_opr=LIR_OprFact::single_cpu(14); _t2_oop_opr=LIR_OprFact::single_cpu_oop(14); _t2_metadata_opr=LIR_OprFact::single_cpu_metadata(14); + map_register(15,T3); _t3_opr=LIR_OprFact::single_cpu(15); _t3_oop_opr=LIR_OprFact::single_cpu_oop(15); _t3_metadata_opr=LIR_OprFact::single_cpu_metadata(15); #endif - map_register(16,S0); _s0_opr=LIR_OprFact::single_cpu(16); _s0_oop_opr=LIR_OprFact::single_cpu_oop(16); - map_register(17,S1); _s1_opr=LIR_OprFact::single_cpu(17); _s1_oop_opr=LIR_OprFact::single_cpu_oop(17); - map_register(18,S2); _s2_opr=LIR_OprFact::single_cpu(18); _s2_oop_opr=LIR_OprFact::single_cpu_oop(18); - map_register(19,S3); _s3_opr=LIR_OprFact::single_cpu(19); _s3_oop_opr=LIR_OprFact::single_cpu_oop(19); - map_register(20,S4); _s4_opr=LIR_OprFact::single_cpu(20); _s4_oop_opr=LIR_OprFact::single_cpu_oop(20); - map_register(21,S5); _s5_opr=LIR_OprFact::single_cpu(21); _s5_oop_opr=LIR_OprFact::single_cpu_oop(21); - map_register(22,S6); _s6_opr=LIR_OprFact::single_cpu(22); _s6_oop_opr=LIR_OprFact::single_cpu_oop(22); - map_register(23,S7); _s7_opr=LIR_OprFact::single_cpu(23); _s7_oop_opr=LIR_OprFact::single_cpu_oop(23); + map_register(16,S0); _s0_opr=LIR_OprFact::single_cpu(16); _s0_oop_opr=LIR_OprFact::single_cpu_oop(16); _s0_metadata_opr=LIR_OprFact::single_cpu_metadata(16); + map_register(17,S1); _s1_opr=LIR_OprFact::single_cpu(17); _s1_oop_opr=LIR_OprFact::single_cpu_oop(17); _s1_metadata_opr=LIR_OprFact::single_cpu_metadata(17); + map_register(18,S2); _s2_opr=LIR_OprFact::single_cpu(18); _s2_oop_opr=LIR_OprFact::single_cpu_oop(18); _s2_metadata_opr=LIR_OprFact::single_cpu_metadata(18); + map_register(19,S3); _s3_opr=LIR_OprFact::single_cpu(19); _s3_oop_opr=LIR_OprFact::single_cpu_oop(19); _s3_metadata_opr=LIR_OprFact::single_cpu_metadata(19); + map_register(20,S4); _s4_opr=LIR_OprFact::single_cpu(20); _s4_oop_opr=LIR_OprFact::single_cpu_oop(20); _s4_metadata_opr=LIR_OprFact::single_cpu_metadata(20); + map_register(21,S5); _s5_opr=LIR_OprFact::single_cpu(21); _s5_oop_opr=LIR_OprFact::single_cpu_oop(21); _s5_metadata_opr=LIR_OprFact::single_cpu_metadata(21); + map_register(22,S6); _s6_opr=LIR_OprFact::single_cpu(22); _s6_oop_opr=LIR_OprFact::single_cpu_oop(22); _s6_metadata_opr=LIR_OprFact::single_cpu_metadata(22); + map_register(23,S7); _s7_opr=LIR_OprFact::single_cpu(23); _s7_oop_opr=LIR_OprFact::single_cpu_oop(23); _s7_metadata_opr=LIR_OprFact::single_cpu_metadata(23); map_register(24,T8); _t8_opr=LIR_OprFact::single_cpu(24); map_register(25,T9); _t9_opr=LIR_OprFact::single_cpu(25); map_register(26,K0); _k0_opr=LIR_OprFact::single_cpu(26); diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/c1_FrameMap_mips.hpp --- a/src/cpu/mips/vm/c1_FrameMap_mips.hpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/c1_FrameMap_mips.hpp Thu May 24 19:49:50 2018 +0800 @@ -174,6 +174,51 @@ static LIR_Opr _d14_double_opr; + static LIR_Opr _zero_metadata_opr; + static LIR_Opr _at_metadata_opr; + static LIR_Opr _v0_metadata_opr; + static LIR_Opr _v1_metadata_opr; + static LIR_Opr _a0_metadata_opr; + static LIR_Opr _a1_metadata_opr; + static LIR_Opr _a2_metadata_opr; + static LIR_Opr _a3_metadata_opr; + static LIR_Opr _t0_metadata_opr; + static LIR_Opr _t1_metadata_opr; + static LIR_Opr _t2_metadata_opr; + static LIR_Opr _t3_metadata_opr; + static LIR_Opr _a4_metadata_opr; + static LIR_Opr _a5_metadata_opr; + static LIR_Opr _a6_metadata_opr; + static LIR_Opr _a7_metadata_opr; + static LIR_Opr _t8_metadata_opr; + static LIR_Opr _t9_metadata_opr; + static LIR_Opr _s0_metadata_opr; + static LIR_Opr _s1_metadata_opr; + static LIR_Opr _s2_metadata_opr; + static LIR_Opr _s3_metadata_opr; + static LIR_Opr _s4_metadata_opr; + static LIR_Opr _s5_metadata_opr; + static LIR_Opr _s6_metadata_opr; + static LIR_Opr _s7_metadata_opr; + static LIR_Opr _gp_metadata_opr; + static LIR_Opr _fp_metadata_opr; + static LIR_Opr _sp_metadata_opr; + static LIR_Opr _ra_metadata_opr; + static LIR_Opr _k0_metadata_opr; + static LIR_Opr _k1_metadata_opr; + +//no implementation + static LIR_Opr _f0_metadata_opr; + static LIR_Opr _f12_metadata_opr; + static LIR_Opr _f14_metadata_opr; + static LIR_Opr _d0_metadata_opr; + static LIR_Opr _d12_metadata_opr; + static LIR_Opr _d14_metadata_opr; + + static LIR_Opr _a0_a1_metadata_opr; + static LIR_Opr _a2_a3_metadata_opr; + static LIR_Opr _v0_v1_metadata_opr; + static LIR_Opr as_long_opr(Register r, Register r2){ return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r2)); } diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/c1_LIRAssembler_mips.cpp --- a/src/cpu/mips/vm/c1_LIRAssembler_mips.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/c1_LIRAssembler_mips.cpp Thu May 24 19:49:50 2018 +0800 @@ -316,8 +316,8 @@ void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) { jobject o = NULL; - PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id); int oop_index = __ oop_recorder()->allocate_oop_index(o); + PatchingStub* patch = new PatchingStub(_masm, patching_id(info), oop_index); RelocationHolder rspec = oop_Relocation::spec(oop_index); __ relocate(rspec); #ifndef _LP64 @@ -326,57 +326,21 @@ __ addiu(reg, reg, Assembler::split_low((int)o)); #else //li may not pass NativeMovConstReg::verify. see nativeMovConstReg_at(pc_start()); in PatchingStub::install. by aoqi +// __ li48(reg, (long)o); __ li48(reg, (long)o); #endif // patching_epilog(patch, LIR_Op1::patch_normal, noreg, info); patching_epilog(patch, lir_patch_normal, reg, info); } - -void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register unused, int monitor_no, Register exception) { - - if (exception->is_valid()) { - // preserve exception - // note: the monitor_exit runtime call is a leaf routine - // and cannot block => no GC can happen - // The slow case (MonitorAccessStub) uses the first two stack slots - // ([SP+0] and [SP+4]), therefore we store the exception at [esp+8] - __ st_ptr(exception, SP, 2 * wordSize); - } - - Register obj_reg = obj_opr->as_register(); - Register lock_reg = lock_opr->as_register(); - - // compute pointer to BasicLock - //Address lock_addr = frame_map()->address_for_monitor_lock_index(monitor_no); - Address lock_addr = frame_map()->address_for_monitor_lock(monitor_no); - __ lea(lock_reg, lock_addr); - // unlock object - MonitorAccessStub* slow_case = new MonitorExitStub(lock_opr, true, monitor_no); - // temporary fix: must be created after exceptionhandler, therefore as call stub - _slow_case_stubs->append(slow_case); - if (UseFastLocking) { - // try inlined fast unlocking first, revert to slow locking if it fails - // note: lock_reg points to the displaced header since the displaced header offset is 0! - assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); - __ unlock_object(NOREG, obj_reg, lock_reg, *slow_case->entry()); - } else { - // always do slow unlocking - // note: the slow unlocking code could be inlined here, however if we use - // slow unlocking, speed doesn't matter anyway and this solution is - // simpler and requires less duplicated code - additionally, the - // slow unlocking code is the same in either case which simplifies - // debugging - __ b_far(*slow_case->entry()); - __ delayed()->nop(); - } - // done - __ bind(*slow_case->continuation()); - - if (exception->is_valid()) { - // restore exception - __ ld_ptr(exception, SP, 2 * wordSize); - } +void LIR_Assembler::klass2reg_with_patching(Register reg, CodeEmitInfo* info) { + Metadata *o = NULL; + int index = __ oop_recorder()->allocate_metadata_index(o); + PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id, index); + RelocationHolder rspec = metadata_Relocation::spec(index); + __ relocate(rspec); + __ li48(reg, (long)o); + patching_epilog(patch, lir_patch_normal, reg, info); } // This specifies the esp decrement needed to build the frame @@ -405,61 +369,28 @@ // generate code for exception handler address handler_base = __ start_a_stub(exception_handler_size); if (handler_base == NULL) { - //no enough space + // no enough space bailout("exception handler overflow"); return -1; } - - - //compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset()); - // if the method does not have an exception handler, then there is - // no reason to search for one - //if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) { - // the exception oop and pc are in V0 and V1 - // no other registers need to be preserved, so invalidate them - // check that there is really an exception -// __ verify_not_null_oop(V0); - - // search an exception handler (V0: exception oop, V1: throwing pc) -// __ call(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id), -// relocInfo::runtime_call_type); -// __ delayed()->nop(); - // if the call returns here, then the exception handler for particular - // exception doesn't exist -> unwind activation and forward exception to caller - // } - int offset = code_offset(); - - // the exception oop is in V0 + int offset = code_offset(); + + // the exception oop and pc are in V0, and V1 // no other registers need to be preserved, so invalidate them + //__ invalidate_registers(false, true, true, false, true, true); + // check that there is really an exception __ verify_not_null_oop(V0); - //FIXME:wuhui?? - //__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id))); - //__ delayed()->nop(); - __ should_not_reach_here(); - guarantee(code_offset() - offset <= exception_handler_size, "overflow"); - __ end_a_stub(); - return offset; - - // unlock the receiver/klass if necessary - // V0: exception -// ciMethod* method = compilation()->method(); -// if (method->is_synchronized() && GenerateSynchronizationCode) { -//#ifndef _LP64 -//by_css -// monitorexit(FrameMap::_t0_oop_opr, FrameMap::_t6_opr, NOREG, 0, V0); -//#else -// monitorexit(FrameMap::_t0_oop_opr, FrameMap::_a6_opr, NOREG, 0, V0); -//#endif -// } - - // unwind activation and forward exception to caller - // V0: exception -// __ jmp(Runtime1::entry_for(Runtime1::unwind_exception_id), -// relocInfo::runtime_call_type); -// __ delayed()->nop(); -// __ end_a_stub(); + + // search an exception handler (V0: exception oop, V1: throwing pc) + __ call(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id)); + __ delayed()->nop(); + __ should_not_reach_here(); + guarantee(code_offset() - offset <= exception_handler_size, "overflow"); + __ end_a_stub(); + + return offset; } // Emit the code to remove the frame from the stack in the exception @@ -472,46 +403,52 @@ #endif int offset = code_offset(); - /* // Fetch the exception from TLS and clear out exception related thread state - __ get_thread(rsi); - __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset())); - __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD); - __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD); + // Fetch the exception from TLS and clear out exception related thread state + Register thread = TREG; +#ifndef OPT_THREAD + __ get_thread(thread); +#endif + __ ld_ptr(V0, Address(thread, JavaThread::exception_oop_offset())); + __ st_ptr(R0, Address(thread, JavaThread::exception_oop_offset())); + __ st_ptr(R0, Address(thread, JavaThread::exception_pc_offset())); __ bind(_unwind_handler_entry); - __ verify_not_null_oop(rax); + __ verify_not_null_oop(V0); if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { - __ mov(rsi, rax); // Preserve the exception + __ move(S0, V0); // Preserve the exception (rbx is always callee-saved) } - // Preform needed unlocking - MonitorExitStub* stub = NULL; + + // Preform needed unlocking + MonitorExitStub* stub = NULL; if (method()->is_synchronized()) { - monitor_address(0, FrameMap::rax_opr); - stub = new MonitorExitStub(FrameMap::rax_opr, true, 0); - __ unlock_object(rdi, rbx, rax, *stub->entry()); + monitor_address(0, FrameMap::_v0_opr); + stub = new MonitorExitStub(FrameMap::_v0_opr, true, 0); + __ unlock_object(A0, A1, V0, *stub->entry()); __ bind(*stub->continuation()); } if (compilation()->env()->dtrace_method_probes()) { - __ get_thread(rax); - __ movptr(Address(rsp, 0), rax); - __ mov_metadata(Address(rsp, sizeof(void*)), method()->constant_encoding()); - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit))); + __ move(A0, thread); + __ mov_metadata(A1, method()->constant_encoding()); + __ patchable_call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit)); } if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { - __ mov(rax, rsi); // Restore the exception + __ move(V0, S0); // Restore the exception } // remove the activation and dispatch to the unwind handler - __ remove_frame(initial_frame_size_in_bytes()); - __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); + // leave activation of nmethod + __ remove_frame(initial_frame_size_in_bytes()); + + __ jmp(Runtime1::entry_for(Runtime1::unwind_exception_id)); + __ delayed()->nop(); // Emit the slow path assembly - if (stub != NULL) { + if (stub != NULL) { stub->emit_code(this); } -*/ + return offset; } @@ -653,7 +590,7 @@ void LIR_Assembler::return_op(LIR_Opr result) { assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == V0, "word returns are in V0"); // Pop the stack before the safepoint code - __ leave(); + __ remove_frame(initial_frame_size_in_bytes()); #ifndef _LP64 //by aoqi __ lui(AT, Assembler::split_high((intptr_t)os::get_polling_page() @@ -674,6 +611,7 @@ #endif #endif + __ pop(RA); __ jr(RA); __ delayed()->nop(); } @@ -724,16 +662,15 @@ assert(dest->is_register(), "should not call otherwise"); LIR_Const* c = src->as_constant_ptr(); switch (c->type()) { + case T_ADDRESS: { + assert(patch_code == lir_patch_none, "no patching handled here"); + __ move(dest->as_register(), c->as_jint()); // FIXME + break; + } + case T_INT: { - jint con = c->as_jint(); - if (dest->is_single_cpu()) { - assert(patch_code == lir_patch_none, "no patching handled here"); - __ move(dest->as_register(), con); - } else { - assert(dest->is_single_fpu(), "wrong register kind"); - __ move(AT, con); - __ mtc1(AT, dest->as_float_reg()); - } + assert(patch_code == lir_patch_none, "no patching handled here"); + __ move(dest->as_register(), c->as_jint()); break; } @@ -772,6 +709,15 @@ break; } + case T_METADATA: { + if (patch_code != lir_patch_none) { + klass2reg_with_patching(dest->as_register(), info); + } else { + __ mov_metadata(dest->as_register(), c->as_metadata()); + } + break; + } + case T_FLOAT: { address const_addr = float_constant(c->as_jfloat()); assert (const_addr != NULL, "must create float constant in the constant table"); @@ -855,6 +801,11 @@ __ sw(AT, frame_map()->address_for_slot(dest->single_stack_ix())); break; + case T_ADDRESS: + __ move(AT, c->as_jint_bits()); + __ st_ptr(AT, frame_map()->address_for_slot(dest->single_stack_ix())); + break; + case T_OBJECT: if (c->as_jobject() == NULL) { __ st_ptr(R0, frame_map()->address_for_slot(dest->single_stack_ix())); @@ -957,6 +908,10 @@ } else __ sw(R0, as_Address(addr)); break; + case T_ADDRESS: + __ move(AT, c->as_jint_bits()); + __ st_ptr(AT, as_Address(addr)); + break; case T_BOOLEAN: // fall through case T_BYTE: if(c->as_jint() != 0) { @@ -1217,7 +1172,7 @@ break; case T_LONG: { - Register from_lo = src->as_register_lo(); + Register from_lo = src->as_register_lo(); Register from_hi = src->as_register_hi(); #ifdef _LP64 if (needs_patching) { @@ -1535,42 +1490,55 @@ case T_ARRAY: if (UseCompressedOops && !wide) { if (disp_reg == noreg) { - __ lw(dest->as_register(), src_reg, disp_value); + __ lwu(dest->as_register(), src_reg, disp_value); } else if (needs_patching) { - __ dadd(AT, src_reg, disp_reg); - offset = code_offset(); - __ lw(dest->as_register(), AT, 0); + __ dadd(AT, src_reg, disp_reg); + offset = code_offset(); + __ lwu(dest->as_register(), AT, 0); } else { - __ dadd(AT, src_reg, disp_reg); - offset = code_offset(); - __ lw(dest->as_register(), AT, Assembler::split_low(disp_value)); + __ dadd(AT, src_reg, disp_reg); + offset = code_offset(); + __ lwu(dest->as_register(), AT, Assembler::split_low(disp_value)); } - } else { if (disp_reg == noreg) { - __ ld_ptr(dest->as_register(), src_reg, disp_value); + __ ld_ptr(dest->as_register(), src_reg, disp_value); } else if (needs_patching) { - __ dadd(AT, src_reg, disp_reg); - offset = code_offset(); - __ ld_ptr(dest->as_register(), AT, 0); + __ dadd(AT, src_reg, disp_reg); + offset = code_offset(); + __ ld_ptr(dest->as_register(), AT, 0); } else { - __ dadd(AT, src_reg, disp_reg); - offset = code_offset(); - __ ld_ptr(dest->as_register(), AT, Assembler::split_low(disp_value)); + __ dadd(AT, src_reg, disp_reg); + offset = code_offset(); + __ ld_ptr(dest->as_register(), AT, Assembler::split_low(disp_value)); } } break; case T_ADDRESS: - if (disp_reg == noreg) { + if (UseCompressedClassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) { + if (disp_reg == noreg) { + __ lwu(dest->as_register(), src_reg, disp_value); + } else if (needs_patching) { + __ dadd(AT, src_reg, disp_reg); + offset = code_offset(); + __ lwu(dest->as_register(), AT, 0); + } else { + __ dadd(AT, src_reg, disp_reg); + offset = code_offset(); + __ lwu(dest->as_register(), AT, Assembler::split_low(disp_value)); + } + } else { + if (disp_reg == noreg) { __ ld_ptr(dest->as_register(), src_reg, disp_value); - } else if (needs_patching) { + } else if (needs_patching) { __ dadd(AT, src_reg, disp_reg); offset = code_offset(); __ ld_ptr(dest->as_register(), AT, 0); - } else { + } else { __ dadd(AT, src_reg, disp_reg); offset = code_offset(); __ ld_ptr(dest->as_register(), AT, Assembler::split_low(disp_value)); + } } break; case T_INT: { @@ -1704,6 +1672,10 @@ } #endif __ verify_oop(dest->as_register()); + } else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) { + if (UseCompressedClassPointers) { + __ decode_klass_not_null(dest->as_register()); + } } if (info != NULL) add_debug_info_for_null_check(offset, info); } @@ -3088,11 +3060,197 @@ __ bind(*op->stub()->continuation()); } +void LIR_Assembler::type_profile_helper(Register mdo, + ciMethodData *md, ciProfileData *data, + Register recv, Label* update_done) { + for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) { + Label next_test; + // See if the receiver is receiver[n]. + __ ld_ptr(AT, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); + __ bne(AT, recv, next_test); + __ delayed()->nop(); + Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))); + __ ld_ptr(AT, data_addr); + __ addi(AT, AT, DataLayout::counter_increment); + __ st_ptr(AT, data_addr); + __ b(*update_done); + __ delayed()->nop(); + __ bind(next_test); + } + + // Didn't find receiver; find next empty slot and fill it in + for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) { + Label next_test; + Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i))); + __ ld_ptr(AT, recv_addr); + __ bne(AT, R0, next_test); + __ delayed()->nop(); + __ st_ptr(recv, recv_addr); + __ move(AT, DataLayout::counter_increment); + __ st_ptr(AT, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)))); + __ b(*update_done); + __ delayed()->nop(); + __ bind(next_test); + } +} + +void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) { + // we always need a stub for the failure case. + CodeStub* stub = op->stub(); + Register obj = op->object()->as_register(); + Register k_RInfo = op->tmp1()->as_register(); + Register klass_RInfo = op->tmp2()->as_register(); + Register dst = op->result_opr()->as_register(); + ciKlass* k = op->klass(); + Register Rtmp1 = noreg; + + // check if it needs to be profiled + ciMethodData* md; + ciProfileData* data; + + if (op->should_profile()) { + ciMethod* method = op->profiled_method(); + assert(method != NULL, "Should have method"); + int bci = op->profiled_bci(); + md = method->method_data_or_null(); + assert(md != NULL, "Sanity"); + data = md->bci_to_data(bci); + assert(data != NULL, "need data for type check"); + assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); + } + Label profile_cast_success, profile_cast_failure; + Label *success_target = op->should_profile() ? &profile_cast_success : success; + Label *failure_target = op->should_profile() ? &profile_cast_failure : failure; + + if (obj == k_RInfo) { + k_RInfo = dst; + } else if (obj == klass_RInfo) { + klass_RInfo = dst; + } + if (k->is_loaded() && !UseCompressedClassPointers) { + select_different_registers(obj, dst, k_RInfo, klass_RInfo); + } else { + Rtmp1 = op->tmp3()->as_register(); + select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1); + } + + assert_different_registers(obj, k_RInfo, klass_RInfo); + + if (op->should_profile()) { + Label not_null; + __ bne(obj, R0, not_null); + __ delayed()->nop(); + // Object is null; update MDO and exit + Register mdo = klass_RInfo; + __ mov_metadata(mdo, md->constant_encoding()); + Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); + int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); + __ lw(AT, data_addr); + __ ori(AT, AT, header_bits); + __ sw(AT,data_addr); + __ b(*obj_is_null); + __ delayed()->nop(); + __ bind(not_null); + } else { + __ beq(obj, R0, *obj_is_null); + __ delayed()->nop(); + } + + if (!k->is_loaded()) { + klass2reg_with_patching(k_RInfo, op->info_for_patch()); + } else { +#ifdef _LP64 + __ mov_metadata(k_RInfo, k->constant_encoding()); +#endif // _LP64 + } + __ verify_oop(obj); + + if (op->fast_check()) { + // get object class + // not a safepoint as obj null check happens earlier + if (UseCompressedClassPointers) { + __ load_klass(Rtmp1, obj); + __ bne(k_RInfo, Rtmp1, *failure_target); + __ delayed()->nop(); + } else { + __ ld(AT, Address(obj, oopDesc::klass_offset_in_bytes())); + __ bne(k_RInfo, AT, *failure_target); + __ delayed()->nop(); + } + // successful cast, fall through to profile or jump + } else { + // get object class + // not a safepoint as obj null check happens earlier + __ load_klass(klass_RInfo, obj); + if (k->is_loaded()) { + // See if we get an immediate positive hit + __ ld(AT, Address(klass_RInfo, k->super_check_offset())); + if ((juint)in_bytes(Klass::secondary_super_cache_offset()) != k->super_check_offset()) { + __ bne(k_RInfo, AT, *failure_target); + __ delayed()->nop(); + // successful cast, fall through to profile or jump + } else { + // See if we get an immediate positive hit + __ beq(k_RInfo, AT, *success_target); + __ delayed()->nop(); + // check for self + __ beq(k_RInfo, klass_RInfo, *success_target); + __ delayed()->nop(); + + __ push(klass_RInfo); + __ push(k_RInfo); + __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); + __ pop(klass_RInfo); + __ pop(klass_RInfo); + // result is a boolean + __ beq(klass_RInfo, R0, *failure_target); + __ delayed()->nop(); + // successful cast, fall through to profile or jump + } + } else { + // perform the fast part of the checking logic + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); + // call out-of-line instance of __ check_klass_subtype_slow_path(...): + __ push(klass_RInfo); + __ push(k_RInfo); + __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); + __ pop(klass_RInfo); + __ pop(k_RInfo); + // result is a boolean + __ beq(k_RInfo, R0, *failure_target); + __ delayed()->nop(); + // successful cast, fall through to profile or jump + } + } + if (op->should_profile()) { + Register mdo = klass_RInfo, recv = k_RInfo; + __ bind(profile_cast_success); + __ mov_metadata(mdo, md->constant_encoding()); + __ load_klass(recv, obj); + Label update_done; + type_profile_helper(mdo, md, data, recv, success); + __ b(*success); + __ delayed()->nop(); + + __ bind(profile_cast_failure); + __ mov_metadata(mdo, md->constant_encoding()); + Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); + __ ld_ptr(AT, counter_addr); + __ addi(AT, AT, -DataLayout::counter_increment); + __ st_ptr(AT, counter_addr); + + __ b(*failure); + __ delayed()->nop(); + } + __ b(*success); + __ delayed()->nop(); +} + void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { LIR_Code code = op->code(); -// if (code == lir_store_check) { + if (code == lir_store_check) { Register value = op->object()->as_register(); Register array = op->array()->as_register(); Register k_RInfo = op->tmp1()->as_register(); @@ -3100,133 +3258,109 @@ Register tmp = op->tmp3()->as_register(); CodeStub* stub = op->stub(); + //check if it needs to be profiled ciMethodData* md; ciProfileData* data; + if (op->should_profile()) { ciMethod* method = op->profiled_method(); assert(method != NULL, "Should have method"); - int bci = op->profiled_bci(); + int bci = op->profiled_bci(); md = method->method_data_or_null(); assert(md != NULL, "Sanity"); data = md->bci_to_data(bci); - assert(data != NULL, "need data for type check"); + assert(data != NULL, "need data for type check"); assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); } Label profile_cast_success, profile_cast_failure, done; Label *success_target = op->should_profile() ? &profile_cast_success : &done; - Label *failure_target = op->should_profile() ? &profile_cast_failure : &done; - //__ cmpptr(value, (int32_t)NULL_WORD); + Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); + if(op->should_profile()) { - Label not_null; - __ bne(value, R0, not_null); - __ delayed()->nop(); - - // __ jcc(Assembler::notEqual, profile_done); - // __ bne(obj, R0, profile_done); - //__ delayed()->nop(); - - // Object is null; update methodDataOop - //ciMethodData* md = method->method_data(); - //if (md == NULL) { -// bailout("out of memory building methodDataOop"); -// return; - // } - // ciProfileData* data = md->bci_to_data(bci); - //assert(data != NULL, "need data for checkcast"); - // assert(data->is_BitData(), "need BitData for checkcast"); - Register mdo = klass_RInfo; - int oop_index = __ oop_recorder()->find_index(md->constant_encoding()); - RelocationHolder rspec = oop_Relocation::spec(oop_index); - __ relocate(rspec); -#ifndef _LP64 - //by_css - __ lui(mdo, Assembler::split_high((int)md->constant_encoding())); - __ addiu(mdo, mdo, Assembler::split_low((int)md->consant_encoding())); -#else - __ li48(mdo, (long)md->constant_encoding()); -#endif - - Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); - //FIXME, it very ineffictive to replace orl with 3 mips instruction @jerome, 12/27,06 - //__ orl(data_addr, BitData::null_flag_constant()); - int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); - __ lw(AT, data_addr); - __ ori(AT, AT, header_bits); - __ sw(AT,data_addr); - __ b(done); - __ delayed()->nop(); - __ bind(not_null); - } else { - __ beq(value, R0, done); - __ delayed()->nop(); - } - //__ verify_oop(obj); + Label not_null; + __ bne(value, R0, not_null); + __ delayed()->nop(); + + Register mdo = klass_RInfo; + __ mov_metadata(mdo, md->constant_encoding()); + Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); + int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); + __ lw(AT, data_addr); + __ ori(AT, AT, header_bits); + __ sw(AT,data_addr); + __ b(done); + __ delayed()->nop(); + __ bind(not_null); + } else { + __ beq(value, R0, done); + __ delayed()->nop(); + } + add_debug_info_for_null_check_here(op->info_for_exception()); __ load_klass(k_RInfo, array); __ load_klass(klass_RInfo, value); - // get instance klass (it's already uncompressed) - //__ movptr(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset())); - __ daddi (k_RInfo, k_RInfo, in_bytes(ObjArrayKlass::element_klass_offset())); - // perform the fast part of the checking logic - //__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); - // call out-of-line instance of __ check_klass_subtype_slow_path(...): -//1899 __ push(klass_RInfo); -//1900 __ push(k_RInfo); -//1901 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); -//1902 __ pop(klass_RInfo); -//1903 __ pop(k_RInfo); -//1904 // result is a boolean -///1905 __ cmpl(k_RInfo, 0); -//1906 __ jcc(Assembler::equal, *failure_target); -//1907 // fall through to the success case -//1908 -//1909 if (op->should_profile()) { -//1910 Register mdo = klass_RInfo, recv = k_RInfo; -//1911 __ bind(profile_cast_success); -//1912 __ mov_metadata(mdo, md->constant_encoding()); -//1913 __ load_klass(recv, value); -//1914 Label update_done; -//1915 type_profile_helper(mdo, md, data, recv, &done); -//1916 __ jmpb(done); -//1917 -//1918 __ bind(profile_cast_failure); -//1919 __ mov_metadata(mdo, md->constant_encoding()); -//1920 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); -//1921 __ subptr(counter_addr, DataLayout::counter_increment); -//1922 __ jmp(*stub->entry()); -//1923 } -//1925 __ bind(done); -//1926 } else -//1927 if (code == lir_checkcast) { -//1928 Register obj = op->object()->as_register(); -//1929 Register dst = op->result_opr()->as_register(); -//1930 Label success; -//1931 emit_typecheck_helper(op, &success, op->stub()->entry(), &success); -//1932 __ bind(success); -//1933 if (dst != obj) { -//1934 __ mov(dst, obj); -//1935 } -//1936 } else -//1937 if (code == lir_instanceof) { -//1938 Register obj = op->object()->as_register(); -///1939 Register dst = op->result_opr()->as_register(); -//1940 Label success, failure, done; -//1941 emit_typecheck_helper(op, &success, &failure, &failure); -///1942 __ bind(failure); -//1943 __ xorptr(dst, dst); -//1944 __ jmpb(done); -//1945 __ bind(success); -//1946 __ movptr(dst, 1); -//1947 __ bind(done); -//1948 } else { -//1949 ShouldNotReachHere(); -//1950 } -//FIXME:wuhui. - + // get instance klass (it's already uncompressed) + __ ld_ptr(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset())); + // perform the fast part of the checking logic + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, tmp, success_target, failure_target, NULL); + __ push(klass_RInfo); + __ push(k_RInfo); + __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); + __ pop(klass_RInfo); + __ pop(k_RInfo); + // result is a boolean + __ beq(k_RInfo, R0, *failure_target); + __ delayed()->nop(); + // fall through to the success case + + if (op->should_profile()) { + Register mdo = klass_RInfo, recv = k_RInfo; + __ bind(profile_cast_success); + __ mov_metadata(mdo, md->constant_encoding()); + __ load_klass(recv, value); + Label update_done; + type_profile_helper(mdo, md, data, recv, &done); + __ b(done); + __ delayed()->nop(); + + __ bind(profile_cast_failure); + __ mov_metadata(mdo, md->constant_encoding()); + Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); + __ ld_ptr(AT, counter_addr); + __ addi(AT, AT, -DataLayout::counter_increment); + __ st_ptr(AT, counter_addr); + __ b(*stub->entry()); + __ delayed()->nop(); + } + + __ bind(done); + } else if (code == lir_checkcast) { + Register obj = op->object()->as_register(); + Register dst = op->result_opr()->as_register(); + Label success; + emit_typecheck_helper(op, &success, op->stub()->entry(), &success); + __ bind(success); + if (dst != obj) { + __ move(dst, obj); + } + } else if (code == lir_instanceof) { + Register obj = op->object()->as_register(); + Register dst = op->result_opr()->as_register(); + Label success, failure, done; + emit_typecheck_helper(op, &success, &failure, &failure); + __ bind(failure); + __ move(dst, R0); + __ b(done); + __ delayed()->nop(); + __ bind(success); + __ addi(dst, R0, 1); + __ bind(done); + } else { + ShouldNotReachHere(); + } } - void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { if (op->code() == lir_cas_long) { #ifdef _LP64 @@ -3370,8 +3504,18 @@ Unimplemented(); } else if (right->is_constant()) { // cpu register - constant - Register res = dest->as_register(); - jint c = right->as_constant_ptr()->as_jint(); + Register res; + if (dest->is_double_cpu()) { + res = dest->as_register_lo(); + } else { + res = dest->as_register(); + } + jint c; + if (right->type() == T_INT) { + c = right->as_constant_ptr()->as_jint(); + } else { + c = right->as_constant_ptr()->as_jlong(); + } switch (code) { case lir_mul_strictfp: @@ -3763,43 +3907,43 @@ int val = right->as_constant_ptr()->as_jint(); __ move(AT, val); switch (code) { - case lir_logic_and: - __ andr (dstreg, reg, AT); - break; - case lir_logic_or: - __ orr(dstreg, reg, AT); - break; - case lir_logic_xor: - __ xorr(dstreg, reg, AT); - break; - default: ShouldNotReachHere(); + case lir_logic_and: + __ andr (dstreg, reg, AT); + break; + case lir_logic_or: + __ orr(dstreg, reg, AT); + break; + case lir_logic_xor: + __ xorr(dstreg, reg, AT); + break; + default: ShouldNotReachHere(); } } else if (right->is_stack()) { // added support for stack operands Address raddr = frame_map()->address_for_slot(right->single_stack_ix()); switch (code) { - case lir_logic_and: - //FIXME. lw or ld_ptr? - __ lw(AT, raddr); - __ andr(reg, reg,AT); - break; - case lir_logic_or: - __ lw(AT, raddr); - __ orr(reg, reg, AT); - break; - case lir_logic_xor: - __ lw(AT, raddr); - __ xorr(reg, reg, AT); - break; - default: ShouldNotReachHere(); + case lir_logic_and: + //FIXME. lw or ld_ptr? + __ lw(AT, raddr); + __ andr(reg, reg,AT); + break; + case lir_logic_or: + __ lw(AT, raddr); + __ orr(reg, reg, AT); + break; + case lir_logic_xor: + __ lw(AT, raddr); + __ xorr(reg, reg, AT); + break; + default: ShouldNotReachHere(); } } else { Register rright = right->as_register(); switch (code) { - case lir_logic_and: __ andr (dstreg, reg, rright); break; - case lir_logic_or : __ orr (dstreg, reg, rright); break; - case lir_logic_xor: __ xorr (dstreg, reg, rright); break; - default: ShouldNotReachHere(); + case lir_logic_and: __ andr (dstreg, reg, rright); break; + case lir_logic_or : __ orr (dstreg, reg, rright); break; + case lir_logic_xor: __ xorr (dstreg, reg, rright); break; + default: ShouldNotReachHere(); } } } else { @@ -3817,46 +3961,46 @@ int r_hi = right->as_constant_ptr()->as_jint_hi(); switch (code) { - case lir_logic_and: - __ move(AT, r_lo); - __ andr(dst_lo, l_lo, AT); - __ move(AT, r_hi); - __ andr(dst_hi, l_hi, AT); - break; - - case lir_logic_or: - __ move(AT, r_lo); - __ orr(dst_lo, l_lo, AT); - __ move(AT, r_hi); - __ orr(dst_hi, l_hi, AT); - break; - - case lir_logic_xor: - __ move(AT, r_lo); - __ xorr(dst_lo, l_lo, AT); - __ move(AT, r_hi); - __ xorr(dst_hi, l_hi, AT); - break; - - default: ShouldNotReachHere(); + case lir_logic_and: + __ move(AT, r_lo); + __ andr(dst_lo, l_lo, AT); + __ move(AT, r_hi); + __ andr(dst_hi, l_hi, AT); + break; + + case lir_logic_or: + __ move(AT, r_lo); + __ orr(dst_lo, l_lo, AT); + __ move(AT, r_hi); + __ orr(dst_hi, l_hi, AT); + break; + + case lir_logic_xor: + __ move(AT, r_lo); + __ xorr(dst_lo, l_lo, AT); + __ move(AT, r_hi); + __ xorr(dst_hi, l_hi, AT); + break; + + default: ShouldNotReachHere(); } #else __ li(AT, right->as_constant_ptr()->as_jlong()); switch (code) { - case lir_logic_and: - __ andr(dst_lo, l_lo, AT); - break; - - case lir_logic_or: - __ orr(dst_lo, l_lo, AT); - break; - - case lir_logic_xor: - __ xorr(dst_lo, l_lo, AT); - break; - - default: ShouldNotReachHere(); + case lir_logic_and: + __ andr(dst_lo, l_lo, AT); + break; + + case lir_logic_or: + __ orr(dst_lo, l_lo, AT); + break; + + case lir_logic_xor: + __ xorr(dst_lo, l_lo, AT); + break; + + default: ShouldNotReachHere(); } #endif @@ -3865,19 +4009,19 @@ Register r_hi = right->as_register_hi(); switch (code) { - case lir_logic_and: - __ andr(dst_lo, l_lo, r_lo); - NOT_LP64(__ andr(dst_hi, l_hi, r_hi);) - break; - case lir_logic_or: - __ orr(dst_lo, l_lo, r_lo); - NOT_LP64(__ orr(dst_hi, l_hi, r_hi);) - break; - case lir_logic_xor: - __ xorr(dst_lo, l_lo, r_lo); - NOT_LP64(__ xorr(dst_hi, l_hi, r_hi);) - break; - default: ShouldNotReachHere(); + case lir_logic_and: + __ andr(dst_lo, l_lo, r_lo); + NOT_LP64(__ andr(dst_hi, l_hi, r_hi);) + break; + case lir_logic_or: + __ orr(dst_lo, l_lo, r_lo); + NOT_LP64(__ orr(dst_hi, l_hi, r_hi);) + break; + case lir_logic_xor: + __ xorr(dst_lo, l_lo, r_lo); + NOT_LP64(__ xorr(dst_hi, l_hi, r_hi);) + break; + default: ShouldNotReachHere(); } } } @@ -4111,28 +4255,6 @@ void LIR_Assembler::align_call(LIR_Code code) { -//FIXME. aoqi, this right? -// do nothing since all instructions are word aligned on sparc -/* - if (os::is_MP()) { - // make sure that the displacement word of the call ends up word aligned - int offset = __ offset(); - switch (code) { - case lir_static_call: - case lir_optvirtual_call: - offset += NativeCall::displacement_offset; - break; - case lir_icvirtual_call: - offset += NativeCall::displacement_offset + NativeMovConstReg::instruction_size; - break; - case lir_virtual_call: // currently, sparc-specific for niagara - default: ShouldNotReachHere(); - } - while (offset++ % BytesPerWord != 0) { - __ nop(); - } - } -*/ } @@ -4145,26 +4267,8 @@ void LIR_Assembler::ic_call(LIR_OpJavaCall* op) { - RelocationHolder rh = virtual_call_Relocation::spec(pc()); -// int oop_index = __ oop_recorder()->allocate_oop_index((jobject)Universe::non_oop_word()); -// RelocationHolder rspec = oop_Relocation::spec(oop_index); -/// __ relocate(rspec); -#ifndef _LP64 -//by_css - __ lui(IC_Klass, Assembler::split_high((int)Universe::non_oop_word())); - __ addiu(IC_Klass, IC_Klass, Assembler::split_low((int)Universe::non_oop_word())); -#else - __ li48(IC_Klass, (long)Universe::non_oop_word()); -#endif - __ call(op->addr(), rh); - __ delayed()->nop(); -// add_call_info(code_offset(), info); - - add_call_info(code_offset(), op->info()); - assert(!os::is_MP() || - (__ offset() - NativeCall::instruction_size + NativeCall::displacement_offset) % BytesPerWord == 0, - "must be aligned"); - + __ ic_call(op->addr()); + add_call_info(code_offset(), op->info()); } @@ -4182,36 +4286,17 @@ bailout("static call stub overflow"); return; } - int start = __ offset(); - /* - if (os::is_MP()) { - // make sure that the displacement word of the call ends up word aligned - int offset = __ offset() + NativeMovConstReg::instruction_size + NativeCall::displacement_offset; - while (offset++ % BytesPerWord != 0) { - __ nop(); - } - } - */ __ relocate(static_stub_Relocation::spec(call_pc)); - jobject o=NULL; - int oop_index = __ oop_recorder()->allocate_oop_index((jobject)o); - RelocationHolder rspec = oop_Relocation::spec(oop_index); + + Metadata *o = NULL; + int index = __ oop_recorder()->allocate_metadata_index(o); + RelocationHolder rspec = metadata_Relocation::spec(index); __ relocate(rspec); //see set_to_interpreted -#ifndef _LP64 - __ lui(T7, Assembler::split_high((int)o)); - __ addiu(T7, T7, Assembler::split_low((int)o)); -#else - __ li48(Rmethod, (long)o); -#endif -#ifndef _LP64 - __ lui(AT, Assembler::split_high((int)-1)); - __ addiu(AT, AT, Assembler::split_low((int)-1)); -#else - __ li48(AT, (long)-1); -#endif - //assert(!os::is_MP() || ((__ offset() + 1) % BytesPerWord) == 0, "must be aligned on MP"); + __ patchable_set48(Rmethod, (long)o); + + __ patchable_set48(AT, (long)-1); __ jr(AT); __ delayed()->nop(); assert(__ offset() - start <= call_stub_size, "stub too big"); @@ -4227,52 +4312,29 @@ // (LinearScan assumes that no oops are in fixed registers) info->add_register_oop(exceptionOop); - //if (!unwind) { - // get current pc information - // pc is only needed if the method has an exception handler, the unwind code does not need it. -#ifndef _LP64 -//by_css - int pc_for_athrow = (int)__ pc(); - int pc_for_athrow_offset = __ offset(); - Register epc = exceptionPC->as_register(); - //__ nop(); - // pc_for_athrow can not point to itself (relocInfo restriction), no need now - __ relocate(relocInfo::internal_pc_type); - __ lui(epc, Assembler::split_high(pc_for_athrow)); - __ addiu(epc, epc, Assembler::split_low(pc_for_athrow)); -#else - long pc_for_athrow = (long)__ pc(); - int pc_for_athrow_offset = __ offset(); - Register epc = exceptionPC->as_register(); - //__ nop(); - // pc_for_athrow can not point to itself (relocInfo restriction), no need now - __ relocate(relocInfo::internal_pc_type); - __ li48(epc, pc_for_athrow); -#endif - add_call_info(pc_for_athrow_offset, info); // for exception handler - __ verify_not_null_oop(V0); - // search an exception handler (eax: exception oop, edx: throwing pc) - if (compilation()->has_fpu_code()) { - __ call(Runtime1::entry_for(Runtime1::handle_exception_id), - relocInfo::runtime_call_type); - } else { - __ call(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id), - relocInfo::runtime_call_type); - } -// } else { -// __ call(Runtime1::entry_for(Runtime1::unwind_exception_id), -// relocInfo::runtime_call_type); -// } - - // enough room for two byte trap + long pc_for_athrow = (long)__ pc(); + int pc_for_athrow_offset = __ offset(); + Register epc = exceptionPC->as_register(); + __ relocate(relocInfo::internal_pc_type); + __ li48(epc, pc_for_athrow); + add_call_info(pc_for_athrow_offset, info); // for exception handler + __ verify_not_null_oop(V0); + // search an exception handler (eax: exception oop, edx: throwing pc) + if (compilation()->has_fpu_code()) { + __ call(Runtime1::entry_for(Runtime1::handle_exception_id), + relocInfo::runtime_call_type); + } else { + __ call(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id), + relocInfo::runtime_call_type); + } __ delayed()->nop(); } -void LIR_Assembler::unwind_op(LIR_Opr exceptionOop){ - assert(exceptionOop->as_register()== FSR, "must match"); - __ b(_unwind_handler_entry); - __ delayed()->nop(); - } +void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) { + assert(exceptionOop->as_register()== FSR, "must match"); + __ b(_unwind_handler_entry); + __ delayed()->nop(); +} void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) { // optimized version for linear scan: @@ -4296,12 +4358,11 @@ assert_different_registers(count_reg, value_reg); switch (code) { case lir_shl: - if (dest->type() == T_INT) - __ sllv(dest_reg, value_reg, count_reg); - else - __ dsllv(dest_reg, value_reg, count_reg); - break; -//__ dsllv(dest_reg, value_reg, count_reg); break; + if (dest->type() == T_INT) + __ sllv(dest_reg, value_reg, count_reg); + else + __ dsllv(dest_reg, value_reg, count_reg); + break; case lir_shr: __ dsrav(dest_reg, value_reg, count_reg); break; case lir_ushr: #if 1 @@ -4325,15 +4386,14 @@ // // 108 ushift_right [a6|I] [a4|I] [a4|I] // 0x00000055646d2f70: dsll32 a4, a6, 0 \ -// 0x00000055646d2f74: dsrl32 a4, a4, 0 |- error! -// 0x00000055646d2f78: dsrl a4, a4, a4 / - if (left->type() == T_INT && dest->type() == T_INT) - { - __ dsll32(AT, value_reg, 0); // Omit the high 32 bits - __ dsrl32(AT, AT, 0); - __ dsrlv(dest_reg, AT, count_reg); // Unsigned right shift - break; - } +// 0x00000055646d2f74: dsrl32 a4, a4, 0 |- error! +// 0x00000055646d2f78: dsrl a4, a4, a4 / + if (left->type() == T_INT && dest->type() == T_INT) { + __ dsll32(AT, value_reg, 0); // Omit the high 32 bits + __ dsrl32(AT, AT, 0); + __ dsrlv(dest_reg, AT, count_reg); // Unsigned right shift + break; + } #endif __ dsrlv(dest_reg, value_reg, count_reg); break; default: ShouldNotReachHere(); @@ -4494,8 +4554,7 @@ case lir_shr: __ dsra(dest_reg, value_reg, count); break; case lir_ushr: #if 1 - if (left->type() == T_INT && dest->type() == T_INT) - { + if (left->type() == T_INT && dest->type() == T_INT) { /* Jin: in java, ushift_right requires 32-bit UNSIGNED operation! However, dsrl will shift in company with the highest 32 bits. Thus, if the source register contains a negative value, @@ -4790,13 +4849,12 @@ } if (flags & LIR_OpArrayCopy::type_check) { - if (UseCompressedOops) { - __ lw(AT, src_klass_addr); - __ lw(tmp, dst_klass_addr); - } else { - __ ld(AT, src_klass_addr); - __ ld(tmp, dst_klass_addr); - } + if (UseCompressedClassPointers) { + __ lw(AT, src_klass_addr); + __ lw(tmp, dst_klass_addr); + } else { + __ ld(AT, src_klass_addr); __ ld(tmp, dst_klass_addr); + } __ bne_far(AT, tmp, *stub->entry()); __ delayed()->nop(); } @@ -4810,36 +4868,37 @@ // a type check i needed then at this point the classes are known to be // the same but again which don't know which type so we can't check them. Label known_ok, halt; -//FIXME:wuhui. not finished. __ mov_metadata(tmp, default_type->constant_encoding()); + __ mov_metadata(tmp, default_type->constant_encoding()); #ifdef _LP64 - if (UseCompressedOops) { - __ encode_heap_oop(AT); - __ lw(tmp, dst_klass_addr); - } else + if (UseCompressedClassPointers) { + __ encode_klass_not_null(tmp); + } #endif - { - __ ld(tmp, dst_klass_addr); - } if (basic_type != T_OBJECT) { + if (UseCompressedClassPointers) { + __ lw(AT, dst_klass_addr); + } else { + __ ld(AT, dst_klass_addr); + } __ bne(AT, tmp, halt); __ delayed()->nop(); - if (UseCompressedOops) { - __ lw(tmp, src_klass_addr); + if (UseCompressedClassPointers) { + __ lw(AT, src_klass_addr); } else { - __ ld(tmp, src_klass_addr); + __ ld(AT, src_klass_addr); } __ beq(AT, tmp, known_ok); __ delayed()->nop(); } else { - if (UseCompressedOops) { - __ lw(tmp, dst_klass_addr); - } else { - __ ld(tmp, dst_klass_addr); - } - __ beq(AT, tmp, known_ok); - __ delayed()->nop(); - __ beq(src, dst, known_ok); - __ delayed()->nop(); + if (UseCompressedClassPointers) { + __ lw(AT, dst_klass_addr); + } else { + __ ld(AT, dst_klass_addr); + } + __ beq(AT, tmp, known_ok); + __ delayed()->nop(); + __ beq(src, dst, known_ok); + __ delayed()->nop(); } __ bind(halt); __ stop("incorrect type information in arraycopy"); @@ -4916,6 +4975,7 @@ Register lock = op->lock_opr()->is_single_cpu() ? op->lock_opr()->as_register(): op->lock_opr()->as_register_lo(); if (!UseFastLocking) { __ b_far(*op->stub()->entry()); + __ delayed()->nop(); } else if (op->code() == lir_lock) { Register scratch = noreg; if (UseBiasedLocking) { @@ -4957,21 +5017,12 @@ assert(op->mdo()->is_single_cpu(), "mdo must be allocated"); Register mdo = op->mdo()->as_register(); - int oop_index = __ oop_recorder()->find_index(md->constant_encoding()); - RelocationHolder rspec = oop_Relocation::spec(oop_index); - __ relocate(rspec); -#ifndef _LP64 - //by_css - __ lui(mdo, Assembler::split_high((int)md->constant_encoding())); - __ addiu(mdo, mdo, Assembler::split_low((int)md->constant_encoding())); -#else - __ li48(mdo, (long)md->constant_encoding()); -#endif + __ mov_metadata(mdo, md->constant_encoding()); Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); - __ lw(AT, counter_addr); - __ addi(AT,AT, DataLayout::counter_increment); - __ sw(AT,counter_addr); + __ ld_ptr(AT, counter_addr); + __ addi(AT, AT, DataLayout::counter_increment); + __ st_ptr(AT, counter_addr); Bytecodes::Code bc = method->java_code_at_bci(bci); const bool callee_is_static = callee->is_loaded() && callee->is_static(); @@ -4980,11 +5031,11 @@ if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) && !callee_is_static && //required for optimized MH invokes C1ProfileVirtualCalls) { - assert(op->recv()->is_single_cpu(), "recv must be allocated"); - Register recv = op->recv()->as_register(); - assert_different_registers(mdo, recv); - assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); - ciKlass* known_klass = op->known_holder(); + assert(op->recv()->is_single_cpu(), "recv must be allocated"); + Register recv = op->recv()->as_register(); + assert_different_registers(mdo, recv); + assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); + ciKlass* known_klass = op->known_holder(); if (C1OptimizeVirtualCallProfiling && known_klass != NULL) { // We know the type that will be seen at this call site; we can // statically update the methodDataOop rather than needing to do @@ -4995,14 +5046,14 @@ ciVirtualCallData* vc_data = (ciVirtualCallData*) data; uint i; for (i = 0; i < VirtualCallData::row_limit(); i++) { - ciKlass* receiver = vc_data->receiver(i); - if (known_klass->equals(receiver)) { - Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); - __ lw(AT, data_addr); - __ addi(AT, AT, DataLayout::counter_increment); - __ sw(AT, data_addr); - return; - } + ciKlass* receiver = vc_data->receiver(i); + if (known_klass->equals(receiver)) { + Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); + __ ld_ptr(AT, data_addr); + __ addi(AT, AT, DataLayout::counter_increment); + __ st_ptr(AT, data_addr); + return; + } } // Receiver type not found in profile data; select an empty slot @@ -5011,65 +5062,55 @@ // always does a write to the receiver part of the // VirtualCallData rather than just the first time for (i = 0; i < VirtualCallData::row_limit(); i++) { - ciKlass* receiver = vc_data->receiver(i); - if (receiver == NULL) { - Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); - int oop_index = __ oop_recorder()->find_index(known_klass->constant_encoding()); - RelocationHolder rspec = oop_Relocation::spec(oop_index); - __ relocate(rspec); -#ifndef _LP64 - //by_css - __ lui(AT, Assembler::split_high((int)known_klass->constant_encoding())); - __ addiu(AT, AT, Assembler::split_low((int)known_klass->constant_encoding())); -#else - __ li48(AT, (long)known_klass->constant_encoding()); -#endif - __ st_ptr(AT,recv_addr); - Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); - __ lw(AT, data_addr); - __ addi(AT, AT, DataLayout::counter_increment); - __ sw(AT, data_addr); - return; - } + ciKlass* receiver = vc_data->receiver(i); + if (receiver == NULL) { + Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); + __ mov_metadata(AT, known_klass->constant_encoding()); + __ st_ptr(AT,recv_addr); + Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); + __ ld_ptr(AT, data_addr); + __ addi(AT, AT, DataLayout::counter_increment); + __ st_ptr(AT, data_addr); + return; + } } } else { //__ ld_ptr(recv, Address(recv, oopDesc::klass_offset_in_bytes())); - __ load_klass(recv, recv); - Label update_done; - uint i; - for (i = 0; i < VirtualCallData::row_limit(); i++) { - Label next_test; + __ load_klass(recv, recv); + Label update_done; + uint i; + for (i = 0; i < VirtualCallData::row_limit(); i++) { + Label next_test; // See if the receiver is receiver[n]. - __ ld_ptr(AT, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)))); - __ bne(recv,AT,next_test); - __ delayed()->nop(); - Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); - __ lw(AT, data_addr); - __ addi(AT, AT, DataLayout::counter_increment); - __ sw(AT, data_addr); - __ b(update_done); - __ delayed()->nop(); - __ bind(next_test); - } + __ ld_ptr(AT, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)))); + __ bne(recv,AT,next_test); + __ delayed()->nop(); + Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); + __ ld_ptr(AT, data_addr); + __ addi(AT, AT, DataLayout::counter_increment); + __ st_ptr(AT, data_addr); + __ b(update_done); + __ delayed()->nop(); + __ bind(next_test); + } // Didn't find receiver; find next empty slot and fill it in - for (i = 0; i < VirtualCallData::row_limit(); i++) { - Label next_test; - Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); - __ ld_ptr(AT, recv_addr); - __ bne(AT, R0, next_test); - __ delayed()->nop(); - __ st_ptr(recv, recv_addr); - __ move(AT,DataLayout::counter_increment); - __ sw(AT,Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)))); - if (i < (VirtualCallData::row_limit() - 1)) { - __ b(update_done); - __ delayed()->nop(); - } - __ bind(next_test); - } - - __ bind(update_done); + for (i = 0; i < VirtualCallData::row_limit(); i++) { + Label next_test; + Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); + __ ld_ptr(AT, recv_addr); + __ bne(AT, R0, next_test); + __ delayed()->nop(); + __ st_ptr(recv, recv_addr); + __ move(AT, DataLayout::counter_increment); + __ st_ptr(AT, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)))); + if (i < (VirtualCallData::row_limit() - 1)) { + __ b(update_done); + __ delayed()->nop(); + } + __ bind(next_test); + } + __ bind(update_done); } } } @@ -5092,6 +5133,7 @@ } void LIR_Assembler::align_backward_branch_target() { + __ align(BytesPerWord); } @@ -5124,11 +5166,11 @@ } } - void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) { assert(addr->is_address() && dest->is_register(), "check"); - Register reg = dest->as_register(); - __ lea(dest->as_register(), as_Address(addr->as_address_ptr())); + Register reg; + reg = dest->as_pointer_register(); + __ lea(reg, as_Address(addr->as_address_ptr())); } @@ -5142,8 +5184,8 @@ __ lui(reg, Assembler::split_high((int)o)); __ addiu(reg, reg, Assembler::split_low((int)o)); #else - //__ li48(reg, (long)o); - __ li(reg, (long)o); + __ li48(reg, (long)o); + //__ patchable_set48(reg, (long)o); #endif } else { int oop_index = __ oop_recorder()->find_index(o); @@ -5154,8 +5196,8 @@ __ lui(reg, Assembler::split_high((int)o)); __ addiu(reg, reg, Assembler::split_low((int)o)); #else - //__ li48(reg, (long)o); - __ li(reg, (long)o); + __ li48(reg, (long)o); + //__ patchable_set48(reg, (long)o); #endif } } @@ -5321,6 +5363,7 @@ } else { ShouldNotReachHere(); }*/ + ShouldNotReachHere(); } #undef __ diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/c1_LIRAssembler_mips.hpp --- a/src/cpu/mips/vm/c1_LIRAssembler_mips.hpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/c1_LIRAssembler_mips.hpp Thu May 24 19:49:50 2018 +0800 @@ -23,12 +23,13 @@ * */ +#ifndef CPU_MIPS_VM_C1_LIRASSEMBLER_MIPS_HPP +#define CPU_MIPS_VM_C1_LIRASSEMBLER_MIPS_HPP + private: Address::ScaleFactor array_element_size(BasicType type) const; - void monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_hdr, int monitor_no, Register exception); - void arith_fpu_implementation(LIR_Code code, int left_index, int right_index, int dest_index, bool pop_fpu_stack); // helper functions which checks for overflow and sets bailout if it @@ -43,6 +44,10 @@ // method. Address as_Address(LIR_Address* addr, Register tmp); + // Record the type of the receiver in ReceiverTypeData + void type_profile_helper(Register mdo, + ciMethodData *md, ciProfileData *data, + Register recv, Label* update_done); public: @@ -50,8 +55,9 @@ void store_parameter(jint c, int offset_from_esp_in_words); void store_parameter(jobject c, int offset_from_esp_in_words); - //enum { call_stub_size = NOT_LP64(24) LP64_ONLY(40), - enum { call_stub_size = NOT_LP64(24) LP64_ONLY(500), //aoqi_test + enum { call_stub_size = NOT_LP64(24) LP64_ONLY(40), exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(175), deopt_handler_size = NOT_LP64(16) LP64_ONLY(32) }; + +#endif // CPU_MIPS_VM_C1_LIRASSEMBLER_MIPS_HPP diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/c1_LIRGenerator_mips.cpp --- a/src/cpu/mips/vm/c1_LIRGenerator_mips.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/c1_LIRGenerator_mips.cpp Thu May 24 19:49:50 2018 +0800 @@ -235,47 +235,57 @@ } } -LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,BasicType type, bool needs_card_mark) { - int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type); +LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, + BasicType type, bool needs_card_mark) { + int elem_size = type2aelembytes(type); + int shift = exact_log2(elem_size); - LIR_Address* addr; + LIR_Opr base_opr; + int offset = arrayOopDesc::base_offset_in_bytes(type); + if (index_opr->is_constant()) { - int elem_size = _type2aelembytes[type]; - addr = new LIR_Address(array_opr, - offset_in_bytes + index_opr->as_jint() * elem_size, type); - } else if( index_opr->is_register()){ + int i = index_opr->as_constant_ptr()->as_jint(); + int array_offset = i * elem_size; + if (Assembler::is_simm16(array_offset + offset)) { + base_opr = array_opr; + offset = array_offset + offset; + } else { + base_opr = new_pointer_register(); + if (Assembler::is_simm16(array_offset)) { + __ add(array_opr, LIR_OprFact::intptrConst(array_offset), base_opr); + } else { + __ move(LIR_OprFact::intptrConst(array_offset), base_opr); + __ add(base_opr, array_opr, base_opr); + } + } + } else { #ifdef _LP64 - LIR_Opr tmp = new_register(T_LONG); -#else - LIR_Opr tmp = new_register(T_INT); + if (index_opr->type() == T_INT) { + LIR_Opr tmp = new_register(T_LONG); + __ convert(Bytecodes::_i2l, index_opr, tmp); + index_opr = tmp; + } #endif - __ move(index_opr, tmp); - __ shift_left(tmp, LIR_Address::scale(type),tmp); - __ add(tmp, array_opr, tmp); - addr = new LIR_Address(tmp, offset_in_bytes,type); + base_opr = new_pointer_register(); + assert (index_opr->is_register(), "Must be register"); + if (shift > 0) { + __ shift_left(index_opr, shift, base_opr); + __ add(base_opr, array_opr, base_opr); + } else { + __ add(index_opr, array_opr, base_opr); + } } - else{ - addr = new LIR_Address(array_opr, - offset_in_bytes, type); - } - if (needs_card_mark) { // This store will need a precise card mark, so go ahead and // compute the full adddres instead of computing once for the // store and again for the card mark. -#ifdef _LP64 - LIR_Opr tmp = new_register(T_ADDRESS); -#else - LIR_Opr tmp = new_register(T_INT); -#endif - __ leal(LIR_OprFact::address(addr), tmp); - return new LIR_Address(tmp, 0, type); + LIR_Opr ptr = new_pointer_register(); + __ add(base_opr, LIR_OprFact::intptrConst(offset), ptr); + return new LIR_Address(ptr, type); } else { - return addr; + return new LIR_Address(base_opr, offset, type); } - - } @@ -292,21 +302,29 @@ } void LIRGenerator::increment_counter(address counter, BasicType type, int step) { - LIR_Opr temp = new_register(T_INT); +#ifdef _LP64 + LIR_Opr pointer = new_register(T_LONG); +#else LIR_Opr pointer = new_register(T_INT); -#ifndef _LP64 - __ move(LIR_OprFact::intConst((int)counter), pointer); -#else - __ move(LIR_OprFact::longConst((long)counter), pointer); #endif - LIR_Opr addr = (LIR_Opr)new LIR_Address(pointer, type); - LIR_Opr c = LIR_OprFact::intConst((int)step); - __ add(addr, c, addr); + __ move(LIR_OprFact::intptrConst(counter), pointer); + LIR_Address* addr = new LIR_Address(pointer, type); + increment_counter(addr, step); } +//void LIRGenerator::increment_counter(address counter, BasicType type, int step) { +// LIR_Opr pointer = new_register(T_LONG); +// __ move(LIR_OprFact::longConst((long)counter), pointer); +// LIR_Opr addr = (LIR_Opr)new LIR_Address(pointer, type); +// LIR_Opr c = LIR_OprFact::intConst((int)step); +// __ add(addr, c, addr); +//} void LIRGenerator::increment_counter(LIR_Address* addr, int step) { - Unimplemented(); + LIR_Opr temp = new_register(addr->type()); + __ move(addr, temp); + __ add(temp, load_immediate(step, addr->type()), temp); + __ move(temp, addr); } @@ -526,33 +544,14 @@ default: ShouldNotReachHere(); } + // order of arguments to runtime call is reversed. LIR_Opr result = call_runtime(x->y(), x->x(), entry, x->type(), NULL); set_result(x, result); break; } - /* _ladd, _lsub is delete in sharedRuntime.hpp case Bytecodes::_ladd: - case Bytecodes::_lsub: { - address entry; - switch (x->op()) { - case Bytecodes::_ladd: - entry = CAST_FROM_FN_PTR(address, SharedRuntime::ladd); - break; // check if dividend is 0 is done elsewhere - case Bytecodes::_lsub: - entry = CAST_FROM_FN_PTR(address, SharedRuntime::lsub); - break; // check if dividend is 0 is done elsewhere - default: - ShouldNotReachHere(); - } - - // order of arguments to runtime call is reversed. - LIR_Opr result = call_runtime(x->y(), x->x(), entry, x->type(), NULL); - set_result(x, result); - break; - }*/ - -/* { + case Bytecodes::_lsub: { LIRItem left(x->x(), this); LIRItem right(x->y(), this); left.load_item(); @@ -562,8 +561,8 @@ arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL); break; } -*/ - default: ShouldNotReachHere(); + default: + ShouldNotReachHere(); } } @@ -620,31 +619,6 @@ // _ishl, _lshl, _ishr, _lshr, _iushr, _lushr void LIRGenerator::do_ShiftOp(ShiftOp* x) { - if(x->op() == Bytecodes::_lshl - || x->op() == Bytecodes::_lshr - || x->op() == Bytecodes::_lushr) { - address entry; - /* lushr, lshr, lshl, is delete in ShredRuntime.hpp - switch (x->op()) { - case Bytecodes::_lshl: - entry = CAST_FROM_FN_PTR(address, SharedRuntime::lshl); - break; // check if dividend is 0 is done elsewhere - case Bytecodes::_lshr: - entry = CAST_FROM_FN_PTR(address, SharedRuntime::lshr); - break; // check if dividend is 0 is done elsewhere - case Bytecodes::_lushr: - entry = CAST_FROM_FN_PTR(address, SharedRuntime::lushr); - break; - default: - ShouldNotReachHere(); - } - */ - // order of arguments to runtime call is reversed. - LIR_Opr result = call_runtime(x->y(), x->x(), entry, x->type(), NULL); - set_result(x, result); - return; - } - // count must always be in rcx LIRItem value(x->x(), this); LIRItem count(x->y(), this); @@ -881,7 +855,6 @@ } void LIRGenerator::do_update_CRC32(Intrinsic* x) { // Fu: 20130832 - tty->print_cr("LIRGenerator::do_update_CRC32 unimplemented yet !"); Unimplemented(); } @@ -962,7 +935,8 @@ fixed_result = true; round_result = false; needs_stub = false; break; - default: ShouldNotReachHere(); + default: + ShouldNotReachHere(); } LIRItem value(x->value(), this); @@ -1015,15 +989,13 @@ // LIR_Opr tmp3 = new_register(T_INT); // LIR_Opr tmp4 = new_register(T_INT); #ifndef _LP64 - LIR_Opr klass_reg = FrameMap::_t4_oop_opr; + LIR_Opr klass_reg = FrameMap::_t4_metadata_opr; #else - LIR_Opr klass_reg = FrameMap::_a4_oop_opr; + LIR_Opr klass_reg = FrameMap::_a4_metadata_opr; #endif -// new_instance(reg, x->klass(), FrameMap::_t0_oop_opr, FrameMap::_t1_oop_opr,FrameMap::_t2_oop_opr, LIR_OprFact::illegalOpr, klass_reg, info); - guarantee(false, "not implemented yet."); -/* new_instance(reg, x->klass(), + x->is_unresolved(), FrameMap::_t0_oop_opr, FrameMap::_t1_oop_opr, FrameMap::_t2_oop_opr, @@ -1037,7 +1009,6 @@ #endif klass_reg, info); -*/ LIR_Opr result = rlock_result(x); __ move(reg, result); } @@ -1060,7 +1031,7 @@ #else LIR_Opr tmp4 = FrameMap::_a5_oop_opr; LIR_Opr tmp5 = FrameMap::_a6_oop_opr; - LIR_Opr klass_reg = FrameMap::_a4_oop_opr; + LIR_Opr klass_reg = FrameMap::_a4_metadata_opr; #endif LIR_Opr len = length.result(); BasicType elem_type = x->elt_type(); @@ -1097,7 +1068,7 @@ #else LIR_Opr tmp4 = FrameMap::_a5_oop_opr; LIR_Opr tmp5 = FrameMap::_a6_oop_opr; - LIR_Opr klass_reg = FrameMap::_a4_oop_opr; + LIR_Opr klass_reg = FrameMap::_a4_metadata_opr; #endif length.load_item_force(FrameMap::_t2_opr); @@ -1145,8 +1116,8 @@ store_stack_parameter(size->result(), in_ByteSize(i*4)); } - LIR_Opr reg = result_register_for(x->type()); - klass2reg_with_patching(reg, x->klass(), patching_info); + LIR_Opr klass_reg = FrameMap::_v0_metadata_opr; + klass2reg_with_patching(klass_reg, x->klass(), patching_info); // LIR_Opr rank = FrameMap::ebx_opr; LIR_Opr rank = FrameMap::_t2_opr; @@ -1155,12 +1126,14 @@ LIR_Opr varargs = FrameMap::_t0_opr; __ move(FrameMap::_sp_opr, varargs); LIR_OprList* args = new LIR_OprList(3); - args->append(reg); + args->append(klass_reg); args->append(rank); args->append(varargs); + LIR_Opr reg = result_register_for(x->type()); __ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id), LIR_OprFact::illegalOpr, reg, args, info); + LIR_Opr result = rlock_result(x); __ move(reg, result); } diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/c1_LinearScan_mips.hpp --- a/src/cpu/mips/vm/c1_LinearScan_mips.hpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/c1_LinearScan_mips.hpp Thu May 24 19:49:50 2018 +0800 @@ -23,6 +23,9 @@ * */ +#ifndef CPU_MIPS_VM_C1_LINEARSCAN_MIPS_HPP +#define CPU_MIPS_VM_C1_LINEARSCAN_MIPS_HPP + inline bool LinearScan::is_processed_reg_num(int reg_num) { return reg_num < 26 || reg_num > 30; } @@ -59,7 +62,7 @@ _first_reg = pd_first_callee_saved_reg; _last_reg = pd_last_callee_saved_reg; return true; - } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT) { + } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT || cur->type() == T_METADATA) { #ifdef _LP64 _first_reg = 12; /* From T0 */ #else @@ -70,3 +73,5 @@ } return false; } + +#endif // CPU_MIPS_VM_C1_LINEARSCAN_MIPS_HPP diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/c1_MacroAssembler_mips.cpp --- a/src/cpu/mips/vm/c1_MacroAssembler_mips.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/c1_MacroAssembler_mips.cpp Thu May 24 19:49:50 2018 +0800 @@ -140,8 +140,6 @@ biased_locking_exit(obj, hdr, done); } - - // load displaced header ld_ptr(hdr, disp_hdr, 0); // if the loaded hdr is NULL we had recursive locking @@ -178,21 +176,21 @@ } void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1 , Register t2) { - assert_different_registers(obj, klass, len, AT); + assert_different_registers(obj, klass, len, T9); if (UseBiasedLocking && !len->is_valid()) { assert_different_registers(obj, klass, len, t1, t2); ld_ptr(t1, klass, in_bytes(Klass::prototype_header_offset())); st_ptr(t1, obj, oopDesc::mark_offset_in_bytes()); } else { - li(AT, (intptr_t)markOopDesc::prototype()); - st_ptr(AT, obj, oopDesc::mark_offset_in_bytes()); + li(T9, (intptr_t)markOopDesc::prototype()); + st_ptr(T9, obj, oopDesc::mark_offset_in_bytes()); } //st_ptr(klass, obj, oopDesc::klass_offset_in_bytes()); #ifdef _LP64 - if (UseCompressedOops) { - move(AT, klass); - store_klass(obj, AT); + if (UseCompressedClassPointers) { + move(T9, klass); + store_klass(obj, T9); } else #endif { @@ -203,7 +201,7 @@ sw(len, obj, arrayOopDesc::length_offset_in_bytes()); } #ifdef _LP64 - else if (UseCompressedOops) { + else if (UseCompressedClassPointers) { store_klass_gap(obj, R0); } #endif @@ -426,14 +424,14 @@ #ifdef _LP64 //ld_ptr(AT, receiver, oopDesc::klass_offset_in_bytes()); //add for compressedoops - load_klass(AT, receiver); + load_klass(T9, receiver); #else - lw(AT, receiver, oopDesc::klass_offset_in_bytes()); + lw(T9, receiver, oopDesc::klass_offset_in_bytes()); #endif - beq(AT, iCache, L); + beq(T9, iCache, L); delayed()->nop(); // jmp(Runtime1::entry_for(Runtime1::handle_ic_miss_id), relocInfo::runtime_call_type); - jmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type); + jmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type); delayed()->nop(); bind(L); // assert(UseCompressedOops, "check alignment in emit_method_entry"); @@ -454,20 +452,25 @@ // ordering of C2's stack overflow check / esp decrement and allows // the SharedRuntime stack overflow handling to be consistent // between the two compilers. - generate_stack_overflow_check(frame_size_in_bytes); + generate_stack_overflow_check(bang_size_in_bytes); enter(); //FIXME #ifdef TIERED - // c2 leaves fpu stack dirty. Clean it on entry - // if (UseSSE < 2 ) { - empty_FPU_stack(); - // } +// c2 leaves fpu stack dirty. Clean it on entry +// if (UseSSE < 2 ) { + empty_FPU_stack(); +// } #endif // TIERED decrement(SP, frame_size_in_bytes); // does not emit code for frame_size == 0 } +void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) { + increment(SP, frame_size_in_bytes); // Does not emit code for frame_size == 0 + pop(FP); +} + void C1_MacroAssembler::unverified_entry(Register receiver, Register ic_klass) { if (C1Breakpoint) int3(); inline_cache_check(receiver, ic_klass); diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/c1_Runtime1_mips.cpp --- a/src/cpu/mips/vm/c1_Runtime1_mips.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/c1_Runtime1_mips.cpp Thu May 24 19:49:50 2018 +0800 @@ -60,9 +60,7 @@ // push java thread (becomes first argument of C function) -#ifndef OPT_THREAD get_thread(thread); -#endif move(A0, thread); set_last_Java_frame(thread, NOREG, FP, NULL); @@ -139,8 +137,7 @@ } else if (_stub_id == Runtime1::forward_exception_id) { should_not_reach_here(); } else { - jmp(Runtime1::entry_for(Runtime1::forward_exception_id), - relocInfo::runtime_call_type); + jmp(Runtime1::entry_for(Runtime1::forward_exception_id), relocInfo::runtime_call_type); delayed()->nop(); } bind(L); @@ -327,9 +324,10 @@ static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args, bool save_fpu_registers = true, bool describe_fpu_registers = false) { - /* Jin: num_rt_args is caculated by 8 bytes. */ - int frame_size_in_slots = reg_save_frame_size + num_rt_args * wordSize / SLOT_PER_WORD; // args + thread - sasm->set_frame_size(frame_size_in_slots / SLOT_PER_WORD); + LP64_ONLY(num_rt_args = 0); + LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");) + int frame_size_in_slots = reg_save_frame_size + num_rt_args * wordSize / VMRegImpl::slots_per_word; // args + thread + sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word); // record saved value locations in an OopMap // locations are offsets from sp after runtime call; num_rt_args is number of arguments @@ -407,9 +405,8 @@ } //FIXME, Is it enough to save this registers by yyq -static OopMap* save_live_registers(StubAssembler* sasm, - int num_rt_args, - bool save_fpu_registers = true, +static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args, + bool save_fpu_registers = true, bool describe_fpu_registers = false) { //const int reg_save_frame_size = return_off + 1 + num_rt_args; __ block_comment("save_live_registers"); @@ -607,57 +604,59 @@ //FIXME I do not know which reigster to use.should use T3 as real_return_addr @jerome OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) { - __ block_comment("generate_handle_exception"); - // incoming parameters + __ block_comment("generate_handle_exception"); + + // incoming parameters const Register exception_oop = V0; const Register exception_pc = V1; // other registers used in this stub -// const Register real_return_addr = T3; - const Register thread = T8; + // const Register real_return_addr = T3; + const Register thread = TREG; +#ifndef OPT_THREAD + __ get_thread(thread); +#endif // Save registers, if required. - OopMapSet* oop_maps = new OopMapSet(); - OopMap* oop_map = NULL; - switch (id) { - case forward_exception_id: - // We're handling an exception in the context of a compiled frame. - // The registers have been saved in the standard places. Perform - // an exception lookup in the caller and dispatch to the handler - // if found. Otherwise unwind and dispatch to the callers - // exception handler. - oop_map = generate_oop_map(sasm, 1 /*thread*/); + OopMapSet* oop_maps = new OopMapSet(); + OopMap* oop_map = NULL; + switch (id) { + case forward_exception_id: + // We're handling an exception in the context of a compiled frame. + // The registers have been saved in the standard places. Perform + // an exception lookup in the caller and dispatch to the handler + // if found. Otherwise unwind and dispatch to the callers + // exception handler. + oop_map = generate_oop_map(sasm, 1 /*thread*/); - // load and clear pending exception oop into RAX - __ ld(exception_oop, Address(thread, Thread::pending_exception_offset())); - __ sw(R0,Address(thread, Thread::pending_exception_offset())); + // load and clear pending exception oop into RAX + __ ld_ptr(exception_oop, Address(thread, Thread::pending_exception_offset())); + __ st_ptr(R0, Address(thread, Thread::pending_exception_offset())); - // load issuing PC (the return address for this stub) into rdx - __ ld(exception_pc, Address(FP, 1*BytesPerWord)); + // load issuing PC (the return address for this stub) into rdx + __ ld_ptr(exception_pc, Address(FP, 1*BytesPerWord)); - // make sure that the vm_results are cleared (may be unnecessary) - __ sw(R0,Address(thread, JavaThread::vm_result_offset())); - __ sw(R0,Address(thread, JavaThread::vm_result_2_offset())); - break; - case handle_exception_nofpu_id: - case handle_exception_id: - // At this point all registers MAY be live. - oop_map = save_live_registers(sasm, 1 /*thread*/, id == handle_exception_nofpu_id); - break; - case handle_exception_from_callee_id: { - // At this point all registers except exception oop (RAX) and - // exception pc (RDX) are dead. - const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/) WIN64_ONLY(+ frame::arg_reg_save_area_by tes / BytesPerWord); - oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0); - sasm->set_frame_size(frame_size); - WIN64_ONLY(__ subq(rsp, frame::arg_reg_save_area_bytes)); - break; - } - default: ShouldNotReachHere(); - } + // make sure that the vm_results are cleared (may be unnecessary) + __ st_ptr(R0, Address(thread, JavaThread::vm_result_offset())); + __ st_ptr(R0, Address(thread, JavaThread::vm_result_2_offset())); + break; + case handle_exception_nofpu_id: + case handle_exception_id: + // At this point all registers MAY be live. + oop_map = save_live_registers(sasm, 1 /*thread*/, id != handle_exception_nofpu_id); + break; + case handle_exception_from_callee_id: { + // At this point all registers except exception oop (RAX) and + // exception pc (RDX) are dead. + const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/); + oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0); + sasm->set_frame_size(frame_size); + break; + } + default: ShouldNotReachHere(); + } #ifdef TIERED // C2 can leave the fpu stack dirty __ empty_FPU_stack(); - //} #endif // TIERED // verify that only V0 and V1 is valid at this time @@ -689,16 +688,12 @@ __ st_ptr(exception_oop, Address(thread, in_bytes(JavaThread::exception_oop_offset()))); __ st_ptr(exception_pc, Address(thread, in_bytes(JavaThread::exception_pc_offset()))); - // save real return address (pc that called this stub) -// __ ld_ptr(real_return_addr, FP, 1*BytesPerWord); -// __ st_ptr(real_return_addr, SP, temp_1_off * BytesPerWord / SLOT_PER_WORD); + // patch throwing pc into return address (has bci & oop map) + __ st_ptr(exception_pc, Address(FP, 1*BytesPerWord)); - // patch throwing pc into return address (has bci & oop map) - __ st_ptr(exception_pc, FP, 1*BytesPerWord); // compute the exception handler. // the exception oop and the throwing pc are read from the fields in JavaThread - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, - exception_handler_for_pc)); + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); oop_maps->add_gc_map(call_offset, oop_map); // V0: handler address or NULL if no handler exists // will be the deopt blob if nmethod was deoptimized while we looked up @@ -707,75 +702,38 @@ // only V0 is valid at this time, all other registers have been destroyed by the // runtime call - // Do we have an exception handler in the nmethod? - /*Label no_handler; - Label done; - __ beq(V0, R0, no_handler); - __ delayed()->nop(); */ - // exception handler found // patch the return address -> the stub will directly return to the exception handler - __ st_ptr(V0, FP, 1 * BytesPerWord); + __ st_ptr(V0, Address(FP, 1 * BytesPerWord)); - // restore registers -// restore_live_registers(sasm, save_fpu_registers); + switch (id) { + case forward_exception_id: + case handle_exception_nofpu_id: + case handle_exception_id: + // Restore the registers that were saved at the beginning. + restore_live_registers(sasm, id != handle_exception_nofpu_id); + break; + case handle_exception_from_callee_id: + // WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP + // since we do a leave anyway. - // return to exception handler -// __ leave(); -// __ jr(RA); -// __ delayed()->nop(); -// __ bind(no_handler); - // no exception handler found in this method, so the exception is - // forwarded to the caller (using the unwind code of the nmethod) - // there is no need to restore the registers + // Pop the return address since we are possibly changing SP (restoring from BP). + __ leave(); + // Restore SP from BP if the exception PC is a method handle call site. + { + Label done; + __ ld(AT, Address(thread, JavaThread::is_method_handle_return_offset())); + __ beq(AT, R0, done); + __ delayed()->nop(); + __ bind(done); + } + __ jr(RA); // jump to exception handler + __ delayed()->nop(); + break; + default: ShouldNotReachHere(); + } - // restore the real return address that was saved before the RT-call -// __ ld_ptr(real_return_addr, SP, temp_1_off * BytesPerWord / SLOT_PER_WORD); -// __ st_ptr(real_return_addr, FP, 1 * BytesPerWord); - // load address of JavaThread object for thread-local data -// __ get_thread(thread); - // restore exception oop into eax (convention for unwind code) -// __ ld_ptr(exception_oop, thread, in_bytes(JavaThread::exception_oop_offset())); - - // clear exception fields in JavaThread because they are no longer needed - // (fields must be cleared because they are processed by GC otherwise) -// __ st_ptr(R0, thread, in_bytes(JavaThread::exception_oop_offset())); -// __ st_ptr(R0,thread, in_bytes(JavaThread::exception_pc_offset())); - // pop the stub frame off -// __ leave(); -// generate_unwind_exception(sasm); -// __ stop("should not reach here"); -//} - switch (id) { - case forward_exception_id: - case handle_exception_nofpu_id: - case handle_exception_id: - // Restore the registers that were saved at the beginning. - restore_live_registers(sasm, id == handle_exception_nofpu_id); - break; - case handle_exception_from_callee_id: - // WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP - // since we do a leave anyway. - - // Pop the return address since we are possibly changing SP (restoring from BP). - __ leave(); - // Restore SP from BP if the exception PC is a method handle call site. - NOT_LP64(__ get_thread(thread);) - /*__ ld(AT, Address(thread, JavaThread::is_method_handle_return_offset())); - __ beq(AT, R0, done); - __ move(SP, rbp_mh_SP_save); - __ bind(done); - __ jr(RA); // jump to exception handler - __ delayed()->nop();*/ -// 759 __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0); -// 760 __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save); -// 761 __ jmp(rcx); // jump to exception handler - - break; - default: ShouldNotReachHere(); - } - - return oop_maps; - } + return oop_maps; +} @@ -784,10 +742,12 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { // incoming parameters const Register exception_oop = V0; + // callee-saved copy of exception_oop during runtime call + const Register exception_oop_callee_saved = S0; // other registers used in this stub const Register exception_pc = V1; const Register handler_addr = T3; - const Register thread = T8; + const Register thread = TREG; // verify that only eax is valid at this time // __ invalidate_registers(false, true, true, true, true, true); @@ -804,7 +764,7 @@ Label pc_empty; __ ld_ptr(AT, thread, in_bytes(JavaThread::exception_pc_offset())); - __ beq(AT,R0, pc_empty); + __ beq(AT, R0, pc_empty); __ delayed()->nop(); __ stop("exception pc must be empty"); __ bind(pc_empty); @@ -812,35 +772,37 @@ // clear the FPU stack in case any FPU results are left behind __ empty_FPU_stack(); - // leave activation of nmethod - __ addi(SP, FP, wordSize); - __ ld_ptr(FP, SP, - wordSize); + // save exception_oop in callee-saved register to preserve it during runtime calls + __ verify_not_null_oop(exception_oop); + __ move(exception_oop_callee_saved, exception_oop); + +#ifndef OPT_THREAD + __ get_thread(thread); +#endif + // Get return address (is on top of stack after leave). // store return address (is on top of stack after leave) + __ ld_ptr(exception_pc, SP, 0); - __ verify_oop(exception_oop); - // save exception oop from eax to stack before call - __ push(exception_oop); // search the exception handler address of the caller (using the return address) - __ call_VM_leaf(CAST_FROM_FN_PTR(address, - SharedRuntime::exception_handler_for_return_address), exception_pc); - // eax: exception handler address of the caller + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc); + // V0: exception handler address of the caller // only eax is valid at this time, all other registers have been destroyed by the call // move result of call into correct register __ move(handler_addr, V0); - // restore exception oop in eax (required convention of exception handler) - __ super_pop(exception_oop); + // Restore exception oop to V0 (required convention of exception handler). + __ move(exception_oop, exception_oop_callee_saved); + + // verify that there is really a valid exception in V0 __ verify_oop(exception_oop); // get throwing pc (= return address). - // edx has been destroyed by the call, so it must be set again + // V1 has been destroyed by the call, so it must be set again // the pop is also necessary to simulate the effect of a ret(0) __ super_pop(exception_pc); - // verify that that there is really a valid exception in eax - __ verify_not_null_oop(exception_oop); // continue at exception handler (return address removed) // note: do *not* remove arguments when unwinding the @@ -848,9 +810,9 @@ // all arguments on the stack when entering the // runtime to determine the exception handler // (GC happens at call site with arguments!) - // eax: exception oop - // edx: throwing pc - // ebx: exception handler + // V0: exception oop + // V1: throwing pc + // T3: exception handler __ jr(handler_addr); __ delayed()->nop(); } @@ -867,9 +829,6 @@ // Note: This number affects also the RT-Call in generate_handle_exception because // the oop-map is shared for all calls. - - - DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); assert(deopt_blob != NULL, "deoptimization blob must have been created"); // assert(deopt_with_exception_entry_for_patch != NULL, @@ -877,13 +836,9 @@ //OopMap* oop_map = save_live_registers(sasm, num_rt_args); OopMap* oop_map = save_live_registers(sasm, 0); -#ifndef OPT_THREAD const Register thread = T8; // push java thread (becomes first argument of C function) __ get_thread(thread); -#else - const Register thread = TREG; -#endif __ move(A0, thread); @@ -922,9 +877,7 @@ OopMapSet* oop_maps = new OopMapSet(); oop_maps->add_gc_map(__ offset(), oop_map); -#ifndef OPT_THREAD __ get_thread(thread); -#endif __ ld_ptr (SP, thread, in_bytes(JavaThread::last_Java_sp_offset())); __ reset_last_Java_frame(thread, true,true); @@ -938,9 +891,8 @@ __ delayed()->nop(); // exception pending => remove activation and forward to exception handler - __ bne(V0,R0, skip); + __ bne(V0, R0, skip); __ delayed()->nop(); - // relocInfo::runtime_call_type); __ jmp(Runtime1::entry_for(Runtime1::forward_exception_id), relocInfo::runtime_call_type); __ delayed()->nop(); @@ -1039,40 +991,10 @@ switch (id) { case forward_exception_id: { - // we're handling an exception in the context of a compiled - // frame. The registers have been saved in the standard - // places. Perform an exception lookup in the caller and - // dispatch to the handler if found. Otherwise unwind and - // dispatch to the callers exception handler. - - const Register exception_oop = V0; - const Register exception_pc = V1; -#ifndef OPT_THREAD - const Register thread = T8; - __ get_thread(thread); -#else - const Register thread = TREG; -#endif - // load pending exception oop into eax - __ ld_ptr(exception_oop, thread, in_bytes(Thread::pending_exception_offset())); - // clear pending exception - __ st_ptr(R0, thread, in_bytes(Thread::pending_exception_offset())); - - // load issuing PC (the return address for this stub) into V1 - __ ld_ptr(exception_pc, FP, 1*BytesPerWord); - - // make sure that the vm_results are cleared (may be unnecessary) - __ st_ptr(R0, Address(thread, in_bytes(JavaThread::vm_result_offset()))); - __ st_ptr(R0, Address(thread, in_bytes(JavaThread::vm_result_2_offset()))); - - // verify that that there is really a valid exception in eax - __ verify_not_null_oop(exception_oop); - - - oop_maps = new OopMapSet(); - OopMap* oop_map = generate_oop_map(sasm, 0); - generate_handle_exception(id, sasm); - __ stop("should not reach here"); + oop_maps = generate_handle_exception(id, sasm); + __ leave(); + __ jr(RA); + __ delayed()->nop(); } break; @@ -1080,12 +1002,7 @@ case fast_new_instance_id: case fast_new_instance_init_check_id: { - // i use T4 as klass register, V0 as result register. MUST accord with NewInstanceStub::emit_code -#ifndef _LP64 - Register klass = T4; // Incoming -#else Register klass = A4; // Incoming -#endif Register obj = V0; // Result if (id == new_instance_id) { @@ -1106,7 +1023,7 @@ assert_different_registers(klass, obj, obj_size, t1, t2); if (id == fast_new_instance_init_check_id) { // make sure the klass is initialized - __ lw(AT, klass, in_bytes(InstanceKlass::init_state_offset())); + __ ld_ptr(AT, Address(klass, in_bytes(InstanceKlass::init_state_offset()))); __ move(t1, InstanceKlass::fully_initialized); __ bne(AT, t1, slow_path); __ delayed()->nop(); @@ -1180,11 +1097,13 @@ #else Register bci = A5; #endif + Register method = AT; __ enter(); OopMap* map = save_live_registers(sasm, 0); // Retrieve bci __ lw(bci, Address(FP, 2*BytesPerWord));// FIXME:wuhui.ebp==?? - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci); + __ ld(method, Address(FP, 3*BytesPerWord)); + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method); oop_maps = new OopMapSet(); oop_maps->add_gc_map(call_offset, map); restore_live_registers(sasm); @@ -1379,7 +1298,8 @@ // case range_check_failed_id: case throw_range_check_failed_id: - { StubFrame f(sasm, "range_check_failed", dont_gc_arguments); + { + StubFrame f(sasm, "range_check_failed", dont_gc_arguments); oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception),true); } @@ -1402,42 +1322,40 @@ break; case throw_null_pointer_exception_id: - { StubFrame f(sasm, "throw_null_pointer_exception", dont_gc_arguments); + { + StubFrame f(sasm, "throw_null_pointer_exception", dont_gc_arguments); oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception),false); } break; - case handle_exception_nofpu_id: + case handle_exception_nofpu_id: save_fpu_registers = false; // fall through case handle_exception_id: { - - StubFrame f(sasm, "handle_exception", dont_gc_arguments); - //OopMap* oop_map = save_live_registers(sasm, 1, save_fpu_registers); oop_maps = generate_handle_exception(id, sasm); } break; - case handle_exception_from_callee_id: - { - StubFrame f(sasm, "handle_exception_from_callee", dont_gc_arguments); - oop_maps = generate_handle_exception(id, sasm); - } - break; + case handle_exception_from_callee_id: + { + StubFrame f(sasm, "handle_exception_from_callee", dont_gc_arguments); + oop_maps = generate_handle_exception(id, sasm); + } + break; case unwind_exception_id: { __ set_info("unwind_exception", dont_gc_arguments); - generate_unwind_exception(sasm); } break; case throw_array_store_exception_id: - { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments); + { + StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments); // tos + 0: link // + 1: return address oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, @@ -1446,17 +1364,18 @@ break; case throw_class_cast_exception_id: - { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments); + { + StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments); oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, - throw_class_cast_exception), V0); + throw_class_cast_exception), true); } break; case throw_incompatible_class_change_error_id: { - StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments); - oop_maps = generate_exception_throw(sasm, - CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false); + StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments); + oop_maps = generate_exception_throw(sasm, + CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false); } break; @@ -1600,12 +1519,21 @@ oop_maps->add_gc_map(call_offset, map); restore_live_registers(sasm); }*/ - case load_mirror_patching_id: - { - StubFrame f(sasm, "load_mirror_patching" , dont_gc_arguments); - oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_mirror_patching)); - } + case load_mirror_patching_id: + { + StubFrame f(sasm, "load_mirror_patching" , dont_gc_arguments); + oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_mirror_patching)); + } break; + + case load_appendix_patching_id: + { + StubFrame f(sasm, "load_appendix_patching", dont_gc_arguments); + // we should set up register map + oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_appendix_patching)); + } + break; + case dtrace_object_alloc_id: { // V0:object @@ -1615,6 +1543,7 @@ save_live_registers(sasm, 0); __ push_reg(V0); + __ move(A0, V0); __ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), relocInfo::runtime_call_type); __ super_pop(V0); @@ -1622,12 +1551,51 @@ restore_live_registers(sasm); } break; + case fpu2long_stub_id: { - //FIXME, I hava no idea how to port this + //FIXME, I hava no idea how to port this + //tty->print_cr("fpu2long_stub_id unimplemented yet!"); } + break; + + case deoptimize_id: + { + StubFrame f(sasm, "deoptimize", dont_gc_arguments); + const int num_rt_args = 1; // thread + OopMap* oop_map = save_live_registers(sasm, num_rt_args); + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize)); + oop_maps = new OopMapSet(); + oop_maps->add_gc_map(call_offset, oop_map); + restore_live_registers(sasm); + DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); + assert(deopt_blob != NULL, "deoptimization blob must have been created"); + __ leave(); + __ jmp(deopt_blob->unpack_with_reexecution(), relocInfo::runtime_call_type); + } + break; + + case predicate_failed_trap_id: + { + StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments); + + OopMap* map = save_live_registers(sasm, 1); + + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap)); + oop_maps = new OopMapSet(); + oop_maps->add_gc_map(call_offset, map); + restore_live_registers(sasm); + __ leave(); + DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); + assert(deopt_blob != NULL, "deoptimization blob must have been created"); + + __ jmp(deopt_blob->unpack_with_reexecution(), relocInfo::runtime_call_type); + } + break; + default: - { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); + { + StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); __ move(A1, (int)id); __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), A1); __ should_not_reach_here(); diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/macroAssembler_mips.cpp --- a/src/cpu/mips/vm/macroAssembler_mips.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/macroAssembler_mips.cpp Thu May 24 19:49:50 2018 +0800 @@ -818,6 +818,28 @@ jr(T9); nop(); } +void MacroAssembler::mov_metadata(Address dst, Metadata* obj) { + int oop_index; + if (obj) { + oop_index = oop_recorder()->find_index(obj); + } else { + oop_index = oop_recorder()->allocate_metadata_index(obj); + } + relocate(metadata_Relocation::spec(oop_index)); + patchable_set48(AT, (long)obj); + sd(AT, dst); +} + +void MacroAssembler::mov_metadata(Register dst, Metadata* obj) { + int oop_index; + if (obj) { + oop_index = oop_recorder()->find_index(obj); + } else { + oop_index = oop_recorder()->allocate_metadata_index(obj); + } + relocate(metadata_Relocation::spec(oop_index)); + patchable_set48(dst, (long)obj); +} void MacroAssembler::call(address entry) { // c/c++ code assume T9 is entry point, so we just always move entry to t9 @@ -870,7 +892,7 @@ assert(entry != NULL, "call most probably wrong"); InstructionMark im(this); relocate(rh); - patchable_call(entry); + patchable_call(entry); } void MacroAssembler::c2bool(Register r) { @@ -1238,7 +1260,6 @@ move(A0, java_thread); call(entry_point, relocInfo::runtime_call_type); delayed()->nop(); - //MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments); // restore the thread (cannot use the pushed argument since arguments // may be overwritten by C code generated by an optimizing compiler); diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/macroAssembler_mips.hpp --- a/src/cpu/mips/vm/macroAssembler_mips.hpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/macroAssembler_mips.hpp Thu May 24 19:49:50 2018 +0800 @@ -712,6 +712,8 @@ void move(Register rd, Register rs) { add(rd, rs, R0); } #endif void dmove(Register rd, Register rs) { dadd(rd, rs, R0); } + void mov_metadata(Register dst, Metadata* obj); + void mov_metadata(Address dst, Metadata* obj); #ifndef PRODUCT diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/mips_64.ad --- a/src/cpu/mips/vm/mips_64.ad Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/mips_64.ad Thu May 24 19:49:50 2018 +0800 @@ -655,7 +655,7 @@ int offs = offset - br_size + 4; // To be conservative on MIPS const int safety_zone = 3 * BytesPerInstWord; - return Assembler::is_simm16((offs<0 ? offs-safety_zone : offs+safety_zone) >> 2); + return Assembler::is_simm16((offset<0 ? offset-safety_zone : offset+safety_zone) >> 2); } diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/nativeInst_mips.cpp --- a/src/cpu/mips/vm/nativeInst_mips.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/nativeInst_mips.cpp Thu May 24 19:49:50 2018 +0800 @@ -203,6 +203,18 @@ return; } + //daddiu dst, R0, imm16 + //nop + //nop + //nop + if ( is_op(Assembler::daddiu_op) && + nativeInstruction_at(addr_at(4))->is_nop() && + nativeInstruction_at(addr_at(8))->is_nop() && + nativeInstruction_at(addr_at(12))->is_nop() && + is_special_op(int_at(16), Assembler::jr_op) ) { + return; + } + //lui dst, imm16 //ori dst, dst, imm16 //nop @@ -728,7 +740,7 @@ __ lui(T9, Assembler::split_high((int)entry)); __ addiu(T9, T9, Assembler::split_low((int)entry)); #else - __ patchable_set48(T9, (long)entry); + __ li48(T9, (long)entry); #endif __ jalr (); __ delayed()->nop(); @@ -1099,6 +1111,7 @@ case Assembler::lh_op: case Assembler::lhu_op: case Assembler::lw_op: + case Assembler::lwu_op: LP64_ONLY(case Assembler::ld_op:) case Assembler::lwc1_op: LP64_ONLY(case Assembler::ldc1_op:) @@ -1579,7 +1592,7 @@ "note::Runtime1::patch_code uses NativeCall::instruction_size"); /* 2013/6/13 Jin: ensure 100% atomicity */ - guarantee(!os::is_MP() || (((long)instr_addr % BytesPerWord) == 0), "destination must be aligned for SD"); + //guarantee(!os::is_MP() || (((long)instr_addr % BytesPerWord) == 0), "destination must be aligned for SD"); int *p = (int *)instr_addr; int jr_word = p[4]; @@ -1594,7 +1607,7 @@ /* 2013/11/5 Jin: ensure 100% atomicity. * The destination is fixed and can be cached in JavaThread. */ - guarantee(!os::is_MP() || (((long)verified_entry % BytesPerWord) == 0), "destination must be aligned for SD"); + //guarantee(!os::is_MP() || (((long)verified_entry % BytesPerWord) == 0), "destination must be aligned for SD"); int code_buffer[4]; diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/nativeInst_mips.hpp --- a/src/cpu/mips/vm/nativeInst_mips.hpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/nativeInst_mips.hpp Thu May 24 19:49:50 2018 +0800 @@ -142,17 +142,17 @@ // lui rt, imm16 // addiu rt, rt, imm16 // jalr rt -// nop +// nop // // 64 bits: -// lui rd, imm(63...48); -// ori rd, rd, imm(47...32); -// dsll rd, rd, 16; -// ori rd, rd, imm(31...16); -// dsll rd, rd, 16; -// ori rd, rd, imm(15...0); -// jalr rd -// nop +// lui rd, imm(63...48); +// ori rd, rd, imm(47...32); +// dsll rd, rd, 16; +// ori rd, rd, imm(31...16); +// dsll rd, rd, 16; +// ori rd, rd, imm(15...0); +// jalr rd +// nop // // we just consider the above for instruction as one call instruction diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/relocInfo_mips.cpp --- a/src/cpu/mips/vm/relocInfo_mips.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/relocInfo_mips.cpp Thu May 24 19:49:50 2018 +0800 @@ -114,7 +114,7 @@ address* Relocation::pd_address_in_code() { - //ShouldNotReachHere(); +// ShouldNotReachHere(); return (address*)addr(); } @@ -127,11 +127,13 @@ void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { -// Unimplemented(); + //Unimplemented(); + //tty->print_cr("%s not finished yet!!!", __func__); } void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { -// Unimplemented(); + //Unimplemented(); + //tty->print_cr("%s not finished yet!!!", __func__); } void internal_pc_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { diff -r e4aeef458496 -r ffcdff41a92f src/cpu/mips/vm/runtime_mips_64.cpp --- a/src/cpu/mips/vm/runtime_mips_64.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/cpu/mips/vm/runtime_mips_64.cpp Thu May 24 19:49:50 2018 +0800 @@ -87,7 +87,6 @@ CodeBuffer buffer("exception_blob", 5120, 5120); MacroAssembler* masm = new MacroAssembler(&buffer); -// OopMapSet *oop_maps = new OopMapSet(); address start = __ pc(); @@ -154,13 +153,9 @@ // Pop self-frame. __ leave(); // Epilog! - // rax,: exception handler for given + // V0: exception handler - // We have a handler in rax, (could be deopt blob) - // rdx - throwing pc, deopt blob will need it. - /* FIXME: rdx? */ - - // rcx contains handler address + // We have a handler in V0, (could be deopt blob) __ move(T9, V0); #ifndef OPT_THREAD diff -r e4aeef458496 -r ffcdff41a92f src/share/vm/c1/c1_LIR.cpp --- a/src/share/vm/c1/c1_LIR.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/share/vm/c1/c1_LIR.cpp Thu May 24 19:49:50 2018 +0800 @@ -392,8 +392,7 @@ _stub(NULL) { } -#endif - +#endif void LIR_OpBranch::change_block(BlockBegin* b) { assert(_block != NULL, "must have old block"); assert(_block->label() == label(), "must be equal"); @@ -1342,7 +1341,10 @@ } void LIR_List::volatile_load_unsafe_reg(LIR_Opr base, LIR_Opr offset, LIR_Opr dst, BasicType type, CodeEmitInfo* info, LIR_PatchCode patch_code) { -#ifndef MIPS64 +#ifdef MIPS64 + add(base, offset, base); + offset = 0; +#endif append(new LIR_Op1( lir_move, LIR_OprFact::address(new LIR_Address(base, offset, type)), @@ -1350,16 +1352,6 @@ type, patch_code, info, lir_move_volatile)); -#else - add(base, offset, base); - append(new LIR_Op1( - lir_move, - LIR_OprFact::address(new LIR_Address(base, 0, type)), - dst, - type, - patch_code, - info, lir_move_volatile)); -#endif } @@ -1415,7 +1407,10 @@ } void LIR_List::volatile_store_unsafe_reg(LIR_Opr src, LIR_Opr base, LIR_Opr offset, BasicType type, CodeEmitInfo* info, LIR_PatchCode patch_code) { -#ifndef MIPS64 +#ifdef MIPS64 + add(base, offset, base); + offset = 0; +#endif append(new LIR_Op1( lir_move, src, @@ -1423,18 +1418,6 @@ type, patch_code, info, lir_move_volatile)); -#else - add(base, offset, base); - append(new LIR_Op1( - lir_move, - src, - LIR_OprFact::address(new LIR_Address(base, 0, type)), - type, - patch_code, - info, lir_move_volatile)); - -#endif - } #ifdef MIPS64 @@ -1503,18 +1486,6 @@ info)); } -void LIR_List::null_check(LIR_Opr opr, CodeEmitInfo* info, bool deoptimize_on_null) { - if (deoptimize_on_null) { - // Emit an explicit null check and deoptimize if opr is null - CodeStub* deopt = new DeoptimizeStub(info); - cmp(lir_cond_equal, opr, LIR_OprFact::oopConst(NULL)); - branch(lir_cond_equal, T_OBJECT, deopt); - } else { - // Emit an implicit null check - append(new LIR_Op1(lir_null_check, opr, info)); - } -} - void LIR_List::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Address* addr, CodeEmitInfo* info) { append(new LIR_Op2( lir_cmp, @@ -1523,7 +1494,26 @@ LIR_OprFact::address(addr), info)); } +#endif +void LIR_List::null_check(LIR_Opr opr, CodeEmitInfo* info, bool deoptimize_on_null) { + if (deoptimize_on_null) { + // Emit an explicit null check and deoptimize if opr is null + CodeStub* deopt = new DeoptimizeStub(info); +#ifndef MIPS64 + cmp(lir_cond_equal, opr, LIR_OprFact::oopConst(NULL)); + branch(lir_cond_equal, T_OBJECT, deopt); +#else + null_check_for_branch(lir_cond_equal, opr, LIR_OprFact::oopConst(NULL)); + branch(lir_cond_equal, opr, LIR_OprFact::oopConst(NULL), T_OBJECT, deopt); +#endif + } else { + // Emit an implicit null check + append(new LIR_Op1(lir_null_check, opr, info)); + } +} + +#ifndef MIPS64 void LIR_List::allocate_object(LIR_Opr dst, LIR_Opr t1, LIR_Opr t2, LIR_Opr t3, LIR_Opr t4, int header_size, int object_size, LIR_Opr klass, bool init_check, CodeStub* stub) { append(new LIR_OpAllocObj( @@ -1552,7 +1542,7 @@ stub)); } #else - void LIR_List::allocate_object(LIR_Opr dst, LIR_Opr t1, LIR_Opr t2, LIR_Opr t3, LIR_Opr t4, LIR_Opr t5, LIR_Opr t6, +void LIR_List::allocate_object(LIR_Opr dst, LIR_Opr t1, LIR_Opr t2, LIR_Opr t3, LIR_Opr t4, LIR_Opr t5, LIR_Opr t6, int header_size, int object_size, LIR_Opr klass, bool init_check, CodeStub* stub) { append(new LIR_OpAllocObj( klass, @@ -1674,6 +1664,7 @@ append(c); } + void LIR_List::store_check(LIR_Opr object, LIR_Opr array, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, CodeEmitInfo* info_for_exception, ciMethod* profiled_method, int profiled_bci) { LIR_OpTypeCheck* c = new LIR_OpTypeCheck(lir_store_check, object, array, tmp1, tmp2, tmp3, info_for_exception); @@ -1685,6 +1676,7 @@ append(c); } + #ifndef MIPS64 void LIR_List::cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2, LIR_Opr result) { diff -r e4aeef458496 -r ffcdff41a92f src/share/vm/c1/c1_LIRGenerator.cpp --- a/src/share/vm/c1/c1_LIRGenerator.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Thu May 24 19:49:50 2018 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, 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 @@ -312,12 +312,12 @@ void LIRGenerator::init() { _bs = Universe::heap()->barrier_set(); #ifdef MIPS64 - assert(_bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); - CardTableModRefBS* ct = (CardTableModRefBS*)_bs; - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); - //_card_table_base = new LIR_Const((intptr_t)ct->byte_map_base); - // //FIXME, untested in 32bit. by aoqi - _card_table_base = new LIR_Const(ct->byte_map_base); + assert(_bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); + CardTableModRefBS* ct = (CardTableModRefBS*)_bs; + assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); + //_card_table_base = new LIR_Const((intptr_t)ct->byte_map_base); + // //FIXME, untested in 32bit. by aoqi + _card_table_base = new LIR_Const(ct->byte_map_base); #endif } @@ -528,10 +528,10 @@ cmp_mem_int(lir_cond_belowEqual, buffer, java_nio_Buffer::limit_offset(), index->as_jint(), info); __ branch(lir_cond_belowEqual, T_INT, stub); // forward branch #else - LIR_Opr left = LIR_OprFact::address(new LIR_Address(buffer, java_nio_Buffer::limit_offset(),T_INT)); - LIR_Opr right = LIR_OprFact::intConst(index->as_jint()); - __ null_check_for_branch(lir_cond_belowEqual, left, right, info); - __ branch(lir_cond_belowEqual,left, right ,T_INT, stub); // forward branch + LIR_Opr left = LIR_OprFact::address(new LIR_Address(buffer, java_nio_Buffer::limit_offset(),T_INT)); + LIR_Opr right = LIR_OprFact::intConst(index->as_jint()); + __ null_check_for_branch(lir_cond_belowEqual, left, right, info); + __ branch(lir_cond_belowEqual,left, right ,T_INT, stub); // forward branch #endif } else { #ifndef MIPS64 @@ -716,7 +716,8 @@ #ifndef MIPS64 void LIRGenerator::new_instance(LIR_Opr dst, ciInstanceKlass* klass, bool is_unresolved, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info) { #else -void LIRGenerator::new_instance(LIR_Opr dst, ciInstanceKlass* klass, bool is_unresolved, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr scratch5, LIR_Opr scratch6, LIR_Opr klass_reg, CodeEmitInfo* info) { +void LIRGenerator::new_instance(LIR_Opr dst, ciInstanceKlass* klass, bool is_unresolved, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, + LIR_Opr scratch4, LIR_Opr scratch5, LIR_Opr scratch6,LIR_Opr klass_reg, CodeEmitInfo* info) { #endif klass2reg_with_patching(klass_reg, klass, info, is_unresolved); // If klass is not loaded we do not know if the klass has finalizers: @@ -1030,50 +1031,48 @@ } #else void LIRGenerator::profile_branch(If* if_instr, If::Condition cond , LIR_Opr left, LIR_Opr right) { - if (if_instr->should_profile()) { - ciMethod* method = if_instr->profiled_method(); - assert(method != NULL, "method should be set if branch is profiled"); - ciMethodData* md = method->method_data_or_null(); - if (md == NULL) { - bailout("out of memory building methodDataOop"); - return; - } - ciProfileData* data = md->bci_to_data(if_instr->profiled_bci()); - assert(data != NULL, "must have profiling data"); - assert(data->is_BranchData(), "need BranchData for two-way branches"); - int taken_count_offset = md->byte_offset_of_slot(data, BranchData::taken_offset()); - int not_taken_count_offset = md->byte_offset_of_slot(data, BranchData::not_taken_offset()); - if (if_instr->is_swapped()) { - int t = taken_count_offset; - taken_count_offset = not_taken_count_offset; - not_taken_count_offset = t; - } - LIR_Opr md_reg = new_register(T_METADATA); - __ metadata2reg(md->constant_encoding(), md_reg); - //__ move(LIR_OprFact::oopConst(md->constant_encoding()), md_reg); - LIR_Opr data_offset_reg = new_pointer_register(); - - LIR_Opr opr1 = LIR_OprFact::intConst(taken_count_offset); - LIR_Opr opr2 = LIR_OprFact::intConst(not_taken_count_offset); - LabelObj* skip = new LabelObj(); - - __ move(opr1, data_offset_reg); - __ branch( lir_cond(cond), left, right, skip->label()); - __ move(opr2, data_offset_reg); - __ branch_destination(skip->label()); - - LIR_Opr data_reg = new_pointer_register(); - LIR_Opr tmp_reg = new_pointer_register(); - // LIR_Address* data_addr = new LIR_Address(md_reg, data_offset_reg, T_INT); - __ move(data_offset_reg, tmp_reg); - __ add(tmp_reg, md_reg, tmp_reg); - LIR_Address* data_addr = new LIR_Address(tmp_reg, 0, T_INT); - __ move(LIR_OprFact::address(data_addr), data_reg); - LIR_Address* fake_incr_value = new LIR_Address(data_reg, DataLayout::counter_increment, T_INT); - // Use leal instead of add to avoid destroying condition codes on x86 - __ leal(LIR_OprFact::address(fake_incr_value), data_reg); - __ move(data_reg, LIR_OprFact::address(data_addr)); - } + if (if_instr->should_profile()) { + ciMethod* method = if_instr->profiled_method(); + assert(method != NULL, "method should be set if branch is profiled"); + ciMethodData* md = method->method_data_or_null(); + if (md == NULL) { + bailout("out of memory building methodDataOop"); + return; + } + ciProfileData* data = md->bci_to_data(if_instr->profiled_bci()); + assert(data != NULL, "must have profiling data"); + assert(data->is_BranchData(), "need BranchData for two-way branches"); + int taken_count_offset = md->byte_offset_of_slot(data, BranchData::taken_offset()); + int not_taken_count_offset = md->byte_offset_of_slot(data, BranchData::not_taken_offset()); + if (if_instr->is_swapped()) { + int t = taken_count_offset; + taken_count_offset = not_taken_count_offset; + not_taken_count_offset = t; + } + LIR_Opr md_reg = new_register(T_METADATA); + __ metadata2reg(md->constant_encoding(), md_reg); + LIR_Opr data_offset_reg = new_pointer_register(); + + LIR_Opr opr1 = LIR_OprFact::intptrConst(taken_count_offset); + LIR_Opr opr2 = LIR_OprFact::intptrConst(not_taken_count_offset); + LabelObj* skip = new LabelObj(); + + __ move(opr1, data_offset_reg); + __ branch( lir_cond(cond), left, right, skip->label()); + __ move(opr2, data_offset_reg); + __ branch_destination(skip->label()); + + LIR_Opr data_reg = new_pointer_register(); + LIR_Opr tmp_reg = new_pointer_register(); + __ move(data_offset_reg, tmp_reg); + __ add(tmp_reg, md_reg, tmp_reg); + LIR_Address* data_addr = new LIR_Address(tmp_reg, 0, data_reg->type()); + __ move(LIR_OprFact::address(data_addr), data_reg); + LIR_Address* fake_incr_value = new LIR_Address(data_reg, DataLayout::counter_increment, T_INT); + // Use leal instead of add to avoid destroying condition codes on x86 + __ leal(LIR_OprFact::address(fake_incr_value), data_reg); + __ move(data_reg, LIR_OprFact::address(data_addr)); + } } #endif @@ -1996,11 +1995,11 @@ cmp_mem_int(lir_cond_belowEqual, buf.result(), java_nio_Buffer::limit_offset(), index.result()->as_jint(), info); __ branch(lir_cond_belowEqual, T_INT, stub); #else - LIR_Opr left = LIR_OprFact::address(new LIR_Address( buf.result(), + LIR_Opr left = LIR_OprFact::address(new LIR_Address( buf.result(), java_nio_Buffer::limit_offset(),T_INT)); - LIR_Opr right = LIR_OprFact::intConst(index.result()->as_jint()); + LIR_Opr right = LIR_OprFact::intConst(index.result()->as_jint()); __ null_check_for_branch(lir_cond_belowEqual, left, right, info); - __ branch(lir_cond_belowEqual,left, right ,T_INT, stub); // forward branch + __ branch(lir_cond_belowEqual,left, right ,T_INT, stub); // forward branch #endif } else { @@ -2009,10 +2008,10 @@ java_nio_Buffer::limit_offset(), T_INT, info); __ branch(lir_cond_aboveEqual, T_INT, stub); #else - LIR_Opr right = LIR_OprFact::address(new LIR_Address( buf.result(), java_nio_Buffer::limit_offset(),T_INT)); - LIR_Opr left = index.result(); + LIR_Opr right = LIR_OprFact::address(new LIR_Address( buf.result(), java_nio_Buffer::limit_offset(),T_INT)); + LIR_Opr left = index.result(); __ null_check_for_branch(lir_cond_aboveEqual, left, right, info); - __ branch(lir_cond_aboveEqual, left, right , T_INT, stub); // forward branch + __ branch(lir_cond_aboveEqual, left, right , T_INT, stub); // forward branch #endif } __ move(index.result(), result); @@ -2093,8 +2092,8 @@ #ifndef MIPS64 __ branch(lir_cond_always, T_ILLEGAL, new RangeCheckStub(range_check_info, index.result())); #else - tty->print_cr("LIRGenerator::do_LoadIndexed(LoadIndexed* x) unimplemented yet!"); - Unimplemented(); + tty->print_cr("LIRGenerator::do_LoadIndexed(LoadIndexed* x) unimplemented yet!"); + Unimplemented(); #endif } else if (use_length) { // TODO: use a (modified) version of array_range_check that does not require a @@ -2826,7 +2825,6 @@ } LIR_Opr md_reg = new_register(T_METADATA); __ metadata2reg(md->constant_encoding(), md_reg); - increment_counter(new LIR_Address(md_reg, offset, NOT_LP64(T_INT) LP64_ONLY(T_LONG)), DataLayout::counter_increment); } diff -r e4aeef458496 -r ffcdff41a92f src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Sat Jan 06 16:30:58 2018 +0800 +++ b/src/share/vm/c1/c1_Runtime1.cpp Thu May 24 19:49:50 2018 +0800 @@ -979,27 +979,9 @@ address stub_location = caller_frame.pc() + PatchingStub::patch_info_offset(); -#if defined(MIPS32) && defined(_LP64) -/* Jin: In MIPS64, byte_skip is much larger than that in X86. It can not be contained in a byte: - * int bc = 0x20; - * int bs = 0x190; - * int bi = 0x1b0; - * - * To minimize the modification of share codes, the values are decreased 4 times when generated. - * See [mips/c1_CodeStubs_mips.cpp 307] PatchingStub::emit_code(). - */ - int bc = *(unsigned char*) (stub_location - 1) * 4; - int bs = *(unsigned char*) (stub_location - 2) * 4; - int bi = *(unsigned char*) (stub_location - 3) * 4; - - int *byte_count = &bc; - int *byte_skip = &bs; - int *being_initialized_entry_offset = &bi; -#else unsigned char* byte_count = (unsigned char*) (stub_location - 1); unsigned char* byte_skip = (unsigned char*) (stub_location - 2); unsigned char* being_initialized_entry_offset = (unsigned char*) (stub_location - 3); -#endif address copy_buff = stub_location - *byte_skip - *byte_count; address being_initialized_entry = stub_location - *being_initialized_entry_offset; @@ -1017,7 +999,7 @@ map->print(); tty->cr(); - Disassembler::decode(copy_buff, copy_buff + *byte_count, tty); + Disassembler::decode(copy_buff - *byte_count, copy_buff + *byte_count, tty); } // depending on the code below, do_patch says whether to copy the patch body back into the nmethod bool do_patch = true;