< prev index next >

src/cpu/aarch64/vm/aarch64.ad

Print this page
rev 10278 : 8150394: aarch64: add support for 8.1 LSE CAS instructions
Reviewed-by: duke
Contributed-by: ananth.jasty@caviumnetworks.com, edward.nevill@gmail.com


4662     if ((EmitSync & 0x02) == 0) {
4663       // we can use AArch64's bit test and branch here but
4664       // markoopDesc does not define a bit index just the bit value
4665       // so assert in case the bit pos changes
4666 #     define __monitor_value_log2 1
4667       assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position");
4668       __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor);
4669 #     undef __monitor_value_log2
4670     }
4671 
4672     // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
4673     __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value);
4674 
4675     // Load Compare Value application register.
4676 
4677     // Initialize the box. (Must happen before we update the object mark!)
4678     __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
4679 
4680     // Compare object markOop with mark and if equal exchange scratch1
4681     // with object markOop.
4682     {





4683       Label retry_load;
4684       __ bind(retry_load);
4685       __ ldaxr(tmp, oop);
4686       __ cmp(tmp, disp_hdr);
4687       __ br(Assembler::NE, cas_failed);
4688       // use stlxr to ensure update is immediately visible
4689       __ stlxr(tmp, box, oop);
4690       __ cbzw(tmp, cont);
4691       __ b(retry_load);
4692     }
4693 
4694     // Formerly:
4695     // __ cmpxchgptr(/*oldv=*/disp_hdr,
4696     //               /*newv=*/box,
4697     //               /*addr=*/oop,
4698     //               /*tmp=*/tmp,
4699     //               cont,
4700     //               /*fail*/NULL);
4701 
4702     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");


4712     __ mov(rscratch1, sp);
4713     __ sub(disp_hdr, disp_hdr, rscratch1);
4714     __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place));
4715     // If condition is true we are cont and hence we can store 0 as the
4716     // displaced header in the box, which indicates that it is a recursive lock.
4717     __ ands(tmp/*==0?*/, disp_hdr, tmp);
4718     __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
4719 
4720     // Handle existing monitor.
4721     if ((EmitSync & 0x02) == 0) {
4722       __ b(cont);
4723 
4724       __ bind(object_has_monitor);
4725       // The object's monitor m is unlocked iff m->owner == NULL,
4726       // otherwise m->owner may contain a thread or a stack address.
4727       //
4728       // Try to CAS m->owner from NULL to current thread.
4729       __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value));
4730       __ mov(disp_hdr, zr);
4731 
4732       {




4733         Label retry_load, fail;
4734         __ bind(retry_load);
4735         __ ldaxr(rscratch1, tmp);
4736         __ cmp(disp_hdr, rscratch1);
4737         __ br(Assembler::NE, fail);
4738         // use stlxr to ensure update is immediately visible
4739         __ stlxr(rscratch1, rthread, tmp);
4740         __ cbnzw(rscratch1, retry_load);
4741         __ bind(fail);
4742       }
4743 
4744       // Label next;
4745       // __ cmpxchgptr(/*oldv=*/disp_hdr,
4746       //               /*newv=*/rthread,
4747       //               /*addr=*/tmp,
4748       //               /*tmp=*/rscratch1,
4749       //               /*succeed*/next,
4750       //               /*fail*/NULL);
4751       // __ bind(next);
4752 


4801     }
4802 
4803     // Find the lock address and load the displaced header from the stack.
4804     __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
4805 
4806     // If the displaced header is 0, we have a recursive unlock.
4807     __ cmp(disp_hdr, zr);
4808     __ br(Assembler::EQ, cont);
4809 
4810 
4811     // Handle existing monitor.
4812     if ((EmitSync & 0x02) == 0) {
4813       __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
4814       __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor);
4815     }
4816 
4817     // Check if it is still a light weight lock, this is is true if we
4818     // see the stack address of the basicLock in the markOop of the
4819     // object.
4820 
4821       {




4822         Label retry_load;
4823         __ bind(retry_load);
4824         __ ldxr(tmp, oop);
4825         __ cmp(box, tmp);
4826         __ br(Assembler::NE, cas_failed);
4827         // use stlxr to ensure update is immediately visible
4828         __ stlxr(tmp, disp_hdr, oop);
4829         __ cbzw(tmp, cont);
4830         __ b(retry_load);
4831       }
4832 
4833     // __ cmpxchgptr(/*compare_value=*/box,
4834     //               /*exchange_value=*/disp_hdr,
4835     //               /*where=*/oop,
4836     //               /*result=*/tmp,
4837     //               cont,
4838     //               /*cas_failed*/NULL);
4839     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
4840 
4841     __ bind(cas_failed);




4662     if ((EmitSync & 0x02) == 0) {
4663       // we can use AArch64's bit test and branch here but
4664       // markoopDesc does not define a bit index just the bit value
4665       // so assert in case the bit pos changes
4666 #     define __monitor_value_log2 1
4667       assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position");
4668       __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor);
4669 #     undef __monitor_value_log2
4670     }
4671 
4672     // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
4673     __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value);
4674 
4675     // Load Compare Value application register.
4676 
4677     // Initialize the box. (Must happen before we update the object mark!)
4678     __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
4679 
4680     // Compare object markOop with mark and if equal exchange scratch1
4681     // with object markOop.
4682     if (UseLSE) {
4683       __ mov(tmp, disp_hdr);
4684       __ casal(disp_hdr, box, oop);
4685       __ cmp(tmp, disp_hdr);
4686       __ br(Assembler::EQ, cont);
4687     } else {
4688       Label retry_load;
4689       __ bind(retry_load);
4690       __ ldaxr(tmp, oop);
4691       __ cmp(tmp, disp_hdr);
4692       __ br(Assembler::NE, cas_failed);
4693       // use stlxr to ensure update is immediately visible
4694       __ stlxr(tmp, box, oop);
4695       __ cbzw(tmp, cont);
4696       __ b(retry_load);
4697     }
4698 
4699     // Formerly:
4700     // __ cmpxchgptr(/*oldv=*/disp_hdr,
4701     //               /*newv=*/box,
4702     //               /*addr=*/oop,
4703     //               /*tmp=*/tmp,
4704     //               cont,
4705     //               /*fail*/NULL);
4706 
4707     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");


4717     __ mov(rscratch1, sp);
4718     __ sub(disp_hdr, disp_hdr, rscratch1);
4719     __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place));
4720     // If condition is true we are cont and hence we can store 0 as the
4721     // displaced header in the box, which indicates that it is a recursive lock.
4722     __ ands(tmp/*==0?*/, disp_hdr, tmp);
4723     __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
4724 
4725     // Handle existing monitor.
4726     if ((EmitSync & 0x02) == 0) {
4727       __ b(cont);
4728 
4729       __ bind(object_has_monitor);
4730       // The object's monitor m is unlocked iff m->owner == NULL,
4731       // otherwise m->owner may contain a thread or a stack address.
4732       //
4733       // Try to CAS m->owner from NULL to current thread.
4734       __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value));
4735       __ mov(disp_hdr, zr);
4736 
4737       if (UseLSE) {
4738         __ mov(rscratch1, disp_hdr);
4739         __ casal(disp_hdr, rthread, tmp);
4740         __ cmp(rscratch1, disp_hdr);
4741       } else {
4742         Label retry_load, fail;
4743         __ bind(retry_load);
4744         __ ldaxr(rscratch1, tmp);
4745         __ cmp(disp_hdr, rscratch1);
4746         __ br(Assembler::NE, fail);
4747         // use stlxr to ensure update is immediately visible
4748         __ stlxr(rscratch1, rthread, tmp);
4749         __ cbnzw(rscratch1, retry_load);
4750         __ bind(fail);
4751       }
4752 
4753       // Label next;
4754       // __ cmpxchgptr(/*oldv=*/disp_hdr,
4755       //               /*newv=*/rthread,
4756       //               /*addr=*/tmp,
4757       //               /*tmp=*/rscratch1,
4758       //               /*succeed*/next,
4759       //               /*fail*/NULL);
4760       // __ bind(next);
4761 


4810     }
4811 
4812     // Find the lock address and load the displaced header from the stack.
4813     __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
4814 
4815     // If the displaced header is 0, we have a recursive unlock.
4816     __ cmp(disp_hdr, zr);
4817     __ br(Assembler::EQ, cont);
4818 
4819 
4820     // Handle existing monitor.
4821     if ((EmitSync & 0x02) == 0) {
4822       __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
4823       __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor);
4824     }
4825 
4826     // Check if it is still a light weight lock, this is is true if we
4827     // see the stack address of the basicLock in the markOop of the
4828     // object.
4829 
4830       if (UseLSE) {
4831         __ mov(tmp, box);
4832         __ casl(box, disp_hdr, oop);
4833         __ cmp(tmp, box);
4834       } else {
4835         Label retry_load;
4836         __ bind(retry_load);
4837         __ ldxr(tmp, oop);
4838         __ cmp(box, tmp);
4839         __ br(Assembler::NE, cas_failed);
4840         // use stlxr to ensure update is immediately visible
4841         __ stlxr(tmp, disp_hdr, oop);
4842         __ cbzw(tmp, cont);
4843         __ b(retry_load);
4844       }
4845 
4846     // __ cmpxchgptr(/*compare_value=*/box,
4847     //               /*exchange_value=*/disp_hdr,
4848     //               /*where=*/oop,
4849     //               /*result=*/tmp,
4850     //               cont,
4851     //               /*cas_failed*/NULL);
4852     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
4853 
4854     __ bind(cas_failed);


< prev index next >