4465 fmv_d(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister());
4466 } else {
4467 ShouldNotReachHere();
4468 }
4469 }
4470 }
4471
4472 void MacroAssembler::rt_call(address dest, Register tmp) {
4473 CodeBlob *cb = CodeCache::find_blob(dest);
4474 RuntimeAddress target(dest);
4475 if (cb) {
4476 far_call(target);
4477 } else {
4478 relocate(target.rspec(), [&] {
4479 int32_t offset;
4480 la_patchable(tmp, target, offset);
4481 jalr(x1, tmp, offset);
4482 });
4483 }
4484 }
|
4465 fmv_d(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister());
4466 } else {
4467 ShouldNotReachHere();
4468 }
4469 }
4470 }
4471
4472 void MacroAssembler::rt_call(address dest, Register tmp) {
4473 CodeBlob *cb = CodeCache::find_blob(dest);
4474 RuntimeAddress target(dest);
4475 if (cb) {
4476 far_call(target);
4477 } else {
4478 relocate(target.rspec(), [&] {
4479 int32_t offset;
4480 la_patchable(tmp, target, offset);
4481 jalr(x1, tmp, offset);
4482 });
4483 }
4484 }
4485
4486 // Attempt to fast-lock an object. Fall-through on success, branch to slow label
4487 // on failure.
4488 // Registers:
4489 // - obj: the object to be locked
4490 // - hdr: the header, already loaded from obj, will be destroyed
4491 // - tmp1, tmp2: temporary registers, will be destroyed
4492 void MacroAssembler::fast_lock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow) {
4493 assert(UseFastLocking, "only used with fast-locking");
4494 assert_different_registers(obj, hdr, tmp1, tmp2);
4495
4496 // Check if we would have space on lock-stack for the object.
4497 ld(tmp1, Address(xthread, JavaThread::lock_stack_current_offset()));
4498 ld(tmp2, Address(xthread, JavaThread::lock_stack_limit_offset()));
4499 bge(tmp1, tmp2, slow, true);
4500
4501 // Load (object->mark() | 1) into hdr
4502 ori(hdr, hdr, markWord::unlocked_value);
4503 // Clear lock-bits, into tmp2
4504 xori(tmp2, hdr, markWord::unlocked_value);
4505 // Try to swing header from unlocked to locked
4506 Label success;
4507 cmpxchgptr(hdr, tmp2, obj, tmp1, success, &slow);
4508 bind(success);
4509
4510 // After successful lock, push object on lock-stack
4511 // TODO: Can we avoid re-loading the current offset? The CAS above clobbers it.
4512 // Maybe we could ensure that we have enough space on the lock stack more cleverly.
4513 ld(tmp1, Address(xthread, JavaThread::lock_stack_current_offset()));
4514 sd(obj, Address(tmp1, 0));
4515 add(tmp1, tmp1, oopSize);
4516 sd(tmp1, Address(xthread, JavaThread::lock_stack_current_offset()));
4517 }
4518
4519 void MacroAssembler::fast_unlock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow) {
4520 assert(UseFastLocking, "only used with fast-locking");
4521 assert_different_registers(obj, hdr, tmp1, tmp2);
4522
4523 // Load the expected old header (lock-bits cleared to indicate 'locked') into hdr
4524 mv(tmp1, ~markWord::lock_mask_in_place);
4525 andr(hdr, hdr, tmp1);
4526
4527 // Load the new header (unlocked) into tmp1
4528 ori(tmp1, hdr, markWord::unlocked_value);
4529
4530 // Try to swing header from locked to unlocked
4531 Label success;
4532 cmpxchgptr(hdr, tmp1, obj, tmp2, success, &slow);
4533 bind(success);
4534
4535 // After successful unlock, pop object from lock-stack
4536 ld(tmp1, Address(xthread, JavaThread::lock_stack_current_offset()));
4537 sub(tmp1, tmp1, oopSize);
4538 sd(tmp1, Address(xthread, JavaThread::lock_stack_current_offset()));
4539 }
|