< prev index next >

src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp

Print this page

        

*** 26,35 **** --- 26,37 ---- #include "precompiled.hpp" #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_Runtime1.hpp" #include "classfile/systemDictionary.hpp" #include "gc/shared/collectedHeap.hpp" + #include "gc/shared/barrierSet.hpp" + #include "gc/shared/barrierSetAssembler.hpp" #include "interpreter/interpreter.hpp" #include "oops/arrayOop.hpp" #include "oops/markOop.hpp" #include "runtime/basicLock.hpp" #include "runtime/biasedLocking.hpp"
*** 81,90 **** --- 83,98 ---- // Load object header ldr(hdr, Address(obj, hdr_offset)); // and mark it as unlocked orr(hdr, hdr, markOopDesc::unlocked_value); + + if (EnableValhalla && !UseBiasedLocking) { + // Mask always_locked bit such that we go to the slow path if object is a value type + andr(hdr, hdr, ~markOopDesc::biased_lock_bit_in_place); + } + // save unlocked object header into the displaced header location on the stack str(hdr, Address(disp_hdr, 0)); // test if object header is still the same (i.e. unlocked), and if so, store the // displaced header address in the object header - if it is not the same, get the // object header instead
*** 328,364 **** cmp_klass(receiver, iCache, rscratch1); } ! void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes) { // If we have to make this method not-entrant we'll overwrite its // first instruction with a jump. For this action to be legal we // must ensure that this first instruction is a B, BL, NOP, BKPT, // SVC, HVC, or SMC. Make it a NOP. nop(); assert(bang_size_in_bytes >= framesize, "stack bang size incorrect"); // Make sure there is enough stack space for this method's activation. // Note that we do this before doing an enter(). generate_stack_overflow_check(bang_size_in_bytes); MacroAssembler::build_frame(framesize + 2 * wordSize); if (NotifySimulator) { notify(Assembler::method_entry); } } ! void C1_MacroAssembler::remove_frame(int framesize) { MacroAssembler::remove_frame(framesize + 2 * wordSize); if (NotifySimulator) { notify(Assembler::method_reentry); } } ! void C1_MacroAssembler::verified_entry() { } void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) { // rbp, + 0: link // + 1: return address // + 2: argument with offset 0 // + 3: argument with offset 1 --- 336,475 ---- cmp_klass(receiver, iCache, rscratch1); } ! void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes, bool needs_stack_repair, Label* verified_value_entry_label) { ! ! // If we have to make this method not-entrant we'll overwrite its // first instruction with a jump. For this action to be legal we // must ensure that this first instruction is a B, BL, NOP, BKPT, // SVC, HVC, or SMC. Make it a NOP. nop(); assert(bang_size_in_bytes >= framesize, "stack bang size incorrect"); // Make sure there is enough stack space for this method's activation. // Note that we do this before doing an enter(). generate_stack_overflow_check(bang_size_in_bytes); + + guarantee(needs_stack_repair == false, "Stack repair should not be true"); + if (verified_value_entry_label != NULL) { + bind(*verified_value_entry_label); + } + MacroAssembler::build_frame(framesize + 2 * wordSize); if (NotifySimulator) { notify(Assembler::method_entry); } } ! void C1_MacroAssembler::remove_frame(int framesize, bool needs_stack_repair) { ! ! guarantee(needs_stack_repair == false, "Stack repair should not be true"); ! MacroAssembler::remove_frame(framesize + 2 * wordSize); if (NotifySimulator) { notify(Assembler::method_reentry); } } + void C1_MacroAssembler::verified_value_entry() { + if (C1Breakpoint || VerifyFPU || !UseStackBanging) { + // Verified Entry first instruction should be 5 bytes long for correct + // patching by patch_verified_entry(). + // + // C1Breakpoint and VerifyFPU have one byte first instruction. + // Also first instruction will be one byte "push(rbp)" if stack banging + // code is not generated (see build_frame() above). + // For all these cases generate long instruction first. + nop(); + } + + // build frame + // verify_FPU(0, "method_entry"); + } + + int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature *ces, int frame_size_in_bytes, int bang_size_in_bytes, Label& verified_value_entry_label, bool is_value_ro_entry) { + // This function required to support for ValueTypePassFieldsAsArgs + if (C1Breakpoint || VerifyFPU || !UseStackBanging) { + // Verified Entry first instruction should be 5 bytes long for correct + // patching by patch_verified_entry(). + // + // C1Breakpoint and VerifyFPU have one byte first instruction. + // Also first instruction will be one byte "push(rbp)" if stack banging + // code is not generated (see build_frame() above). + // For all these cases generate long instruction first. + nop(); + } + + // verify_FPU(0, "method_entry"); + + assert(ValueTypePassFieldsAsArgs, "sanity"); + + GrowableArray<SigEntry>* sig = &ces->sig(); + GrowableArray<SigEntry>* sig_cc = is_value_ro_entry ? &ces->sig_cc_ro() : &ces->sig_cc(); + VMRegPair* regs = ces->regs(); + VMRegPair* regs_cc = is_value_ro_entry ? ces->regs_cc_ro() : ces->regs_cc(); + int args_on_stack = ces->args_on_stack(); + int args_on_stack_cc = is_value_ro_entry ? ces->args_on_stack_cc_ro() : ces->args_on_stack_cc(); + + assert(sig->length() <= sig_cc->length(), "Zero-sized value class not allowed!"); + BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sig_cc->length()); + int args_passed = sig->length(); + int args_passed_cc = SigEntry::fill_sig_bt(sig_cc, sig_bt); + + int extra_stack_offset = wordSize; // tos is return address. + + // Create a temp frame so we can call into runtime. It must be properly set up to accomodate GC. + int sp_inc = (args_on_stack - args_on_stack_cc) * VMRegImpl::stack_slot_size; + if (sp_inc > 0) { + sp_inc = align_up(sp_inc, StackAlignmentInBytes); + sub(sp, sp, sp_inc); + } else { + sp_inc = 0; + } + + sub(sp, sp, frame_size_in_bytes); + if (sp_inc > 0) { + int real_frame_size = frame_size_in_bytes + + + wordSize // pushed rbp + + wordSize // returned address pushed by the stack extension code + + sp_inc; // stack extension + mov(rscratch1, real_frame_size); + str(rscratch1, Address(sp, frame_size_in_bytes - wordSize)); + } + + // FIXME -- call runtime only if we cannot in-line allocate all the incoming value args. + mov(r1, (intptr_t) ces->method()); + if (is_value_ro_entry) { + far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_value_args_no_receiver_id))); + } else { + far_call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_value_args_id))); + } + int rt_call_offset = offset(); + + // Remove the temp frame + add(sp, sp, frame_size_in_bytes); ! int n = shuffle_value_args(true, is_value_ro_entry, extra_stack_offset, sig_bt, sig_cc, ! args_passed_cc, args_on_stack_cc, regs_cc, // from ! args_passed, args_on_stack, regs); // to ! assert(sp_inc == n, "must be"); ! ! if (sp_inc != 0) { ! // Do the stack banging here, and skip over the stack repair code in the ! // verified_value_entry (which has a different real_frame_size). ! assert(sp_inc > 0, "stack should not shrink"); ! generate_stack_overflow_check(bang_size_in_bytes); ! decrement(sp, frame_size_in_bytes); ! } ! ! b(verified_value_entry_label); ! return rt_call_offset; } + void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) { // rbp, + 0: link // + 1: return address // + 2: argument with offset 0 // + 3: argument with offset 1
< prev index next >