4296 adrp(rscratch1, src2, offset);
4297 ldr(rscratch1, Address(rscratch1, offset));
4298 cmp(src1, rscratch1);
4299 }
4300
4301 void MacroAssembler::cmpoop(Register obj1, Register obj2) {
4302 cmp(obj1, obj2);
4303 }
4304
4305 void MacroAssembler::load_method_holder_cld(Register rresult, Register rmethod) {
4306 load_method_holder(rresult, rmethod);
4307 ldr(rresult, Address(rresult, InstanceKlass::class_loader_data_offset()));
4308 }
4309
4310 void MacroAssembler::load_method_holder(Register holder, Register method) {
4311 ldr(holder, Address(method, Method::const_offset())); // ConstMethod*
4312 ldr(holder, Address(holder, ConstMethod::constants_offset())); // ConstantPool*
4313 ldr(holder, Address(holder, ConstantPool::pool_holder_offset())); // InstanceKlass*
4314 }
4315
4316 void MacroAssembler::load_klass(Register dst, Register src) {
4317 if (UseCompressedClassPointers) {
4318 ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
4319 decode_klass_not_null(dst);
4320 } else {
4321 ldr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
4322 }
4323 }
4324
4325 // ((OopHandle)result).resolve();
4326 void MacroAssembler::resolve_oop_handle(Register result, Register tmp1, Register tmp2) {
4327 // OopHandle::resolve is an indirection.
4328 access_load_at(T_OBJECT, IN_NATIVE, result, Address(result, 0), tmp1, tmp2);
4329 }
4330
4331 // ((WeakHandle)result).resolve();
4332 void MacroAssembler::resolve_weak_handle(Register result, Register tmp1, Register tmp2) {
4333 assert_different_registers(result, tmp1, tmp2);
4334 Label resolved;
4335
4336 // A null weak handle resolves to null.
4337 cbz(result, resolved);
4338
4339 // Only 64 bit platforms support GCs that require a tmp register
4340 // WeakHandle::resolve is an indirection like jweak.
4341 access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF,
4342 result, Address(result), tmp1, tmp2);
4343 bind(resolved);
4344 }
4345
4346 void MacroAssembler::load_mirror(Register dst, Register method, Register tmp1, Register tmp2) {
4347 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
4348 ldr(dst, Address(rmethod, Method::const_offset()));
4349 ldr(dst, Address(dst, ConstMethod::constants_offset()));
4350 ldr(dst, Address(dst, ConstantPool::pool_holder_offset()));
4351 ldr(dst, Address(dst, mirror_offset));
4352 resolve_oop_handle(dst, tmp1, tmp2);
4353 }
4354
4355 void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) {
4356 if (UseCompressedClassPointers) {
4357 ldrw(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
4358 if (CompressedKlassPointers::base() == nullptr) {
4359 cmp(trial_klass, tmp, LSL, CompressedKlassPointers::shift());
4360 return;
4361 } else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
4362 && CompressedKlassPointers::shift() == 0) {
4363 // Only the bottom 32 bits matter
4364 cmpw(trial_klass, tmp);
4365 return;
4366 }
4367 decode_klass_not_null(tmp);
4368 } else {
4369 ldr(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
4370 }
4371 cmp(trial_klass, tmp);
4372 }
4373
4374 void MacroAssembler::store_klass(Register dst, Register src) {
4375 // FIXME: Should this be a store release? concurrent gcs assumes
4376 // klass length is valid if klass field is not null.
4377 if (UseCompressedClassPointers) {
4378 encode_klass_not_null(src);
4379 strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
4380 } else {
4381 str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
4382 }
4383 }
4384
4385 void MacroAssembler::store_klass_gap(Register dst, Register src) {
4386 if (UseCompressedClassPointers) {
4387 // Store to klass gap in destination
4388 strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
4389 }
4390 }
4391
4392 // Algorithm must match CompressedOops::encode.
4393 void MacroAssembler::encode_heap_oop(Register d, Register s) {
4394 #ifdef ASSERT
4395 verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
4396 #endif
4397 verify_oop_msg(s, "broken oop in encode_heap_oop");
4398 if (CompressedOops::base() == nullptr) {
4399 if (CompressedOops::shift() != 0) {
4400 assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
4401 lsr(d, s, LogMinObjAlignmentInBytes);
4402 } else {
4403 mov(d, s);
4404 }
4405 } else {
|
4296 adrp(rscratch1, src2, offset);
4297 ldr(rscratch1, Address(rscratch1, offset));
4298 cmp(src1, rscratch1);
4299 }
4300
4301 void MacroAssembler::cmpoop(Register obj1, Register obj2) {
4302 cmp(obj1, obj2);
4303 }
4304
4305 void MacroAssembler::load_method_holder_cld(Register rresult, Register rmethod) {
4306 load_method_holder(rresult, rmethod);
4307 ldr(rresult, Address(rresult, InstanceKlass::class_loader_data_offset()));
4308 }
4309
4310 void MacroAssembler::load_method_holder(Register holder, Register method) {
4311 ldr(holder, Address(method, Method::const_offset())); // ConstMethod*
4312 ldr(holder, Address(holder, ConstMethod::constants_offset())); // ConstantPool*
4313 ldr(holder, Address(holder, ConstantPool::pool_holder_offset())); // InstanceKlass*
4314 }
4315
4316 // Loads the obj's Klass* into dst.
4317 // Preserves all registers (incl src, rscratch1 and rscratch2).
4318 void MacroAssembler::load_nklass_compact(Register dst, Register src) {
4319 assert(UseCompactObjectHeaders, "expects UseCompactObjectHeaders");
4320
4321 Label fast;
4322
4323 // Check if we can take the (common) fast path, if obj is unlocked.
4324 ldr(dst, Address(src, oopDesc::mark_offset_in_bytes()));
4325 tbz(dst, exact_log2(markWord::monitor_value), fast);
4326
4327 // Fetch displaced header
4328 ldr(dst, Address(dst, OM_OFFSET_NO_MONITOR_VALUE_TAG(header)));
4329
4330 // Fast-path: shift to get narrowKlass.
4331 bind(fast);
4332 lsr(dst, dst, markWord::klass_shift);
4333 }
4334
4335 void MacroAssembler::load_klass(Register dst, Register src) {
4336 if (UseCompactObjectHeaders) {
4337 load_nklass_compact(dst, src);
4338 decode_klass_not_null(dst);
4339 } else if (UseCompressedClassPointers) {
4340 ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
4341 decode_klass_not_null(dst);
4342 } else {
4343 ldr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
4344 }
4345 }
4346
4347 // ((OopHandle)result).resolve();
4348 void MacroAssembler::resolve_oop_handle(Register result, Register tmp1, Register tmp2) {
4349 // OopHandle::resolve is an indirection.
4350 access_load_at(T_OBJECT, IN_NATIVE, result, Address(result, 0), tmp1, tmp2);
4351 }
4352
4353 // ((WeakHandle)result).resolve();
4354 void MacroAssembler::resolve_weak_handle(Register result, Register tmp1, Register tmp2) {
4355 assert_different_registers(result, tmp1, tmp2);
4356 Label resolved;
4357
4358 // A null weak handle resolves to null.
4359 cbz(result, resolved);
4360
4361 // Only 64 bit platforms support GCs that require a tmp register
4362 // WeakHandle::resolve is an indirection like jweak.
4363 access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF,
4364 result, Address(result), tmp1, tmp2);
4365 bind(resolved);
4366 }
4367
4368 void MacroAssembler::load_mirror(Register dst, Register method, Register tmp1, Register tmp2) {
4369 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
4370 ldr(dst, Address(rmethod, Method::const_offset()));
4371 ldr(dst, Address(dst, ConstMethod::constants_offset()));
4372 ldr(dst, Address(dst, ConstantPool::pool_holder_offset()));
4373 ldr(dst, Address(dst, mirror_offset));
4374 resolve_oop_handle(dst, tmp1, tmp2);
4375 }
4376
4377 void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) {
4378 assert_different_registers(oop, trial_klass, tmp);
4379 if (UseCompressedClassPointers) {
4380 if (UseCompactObjectHeaders) {
4381 load_nklass_compact(tmp, oop);
4382 } else {
4383 ldrw(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
4384 }
4385 if (CompressedKlassPointers::base() == nullptr) {
4386 cmp(trial_klass, tmp, LSL, CompressedKlassPointers::shift());
4387 return;
4388 } else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
4389 && CompressedKlassPointers::shift() == 0) {
4390 // Only the bottom 32 bits matter
4391 cmpw(trial_klass, tmp);
4392 return;
4393 }
4394 decode_klass_not_null(tmp);
4395 } else {
4396 ldr(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
4397 }
4398 cmp(trial_klass, tmp);
4399 }
4400
4401 void MacroAssembler::cmp_klass(Register src, Register dst, Register tmp1, Register tmp2) {
4402 if (UseCompactObjectHeaders) {
4403 load_nklass_compact(tmp1, src);
4404 load_nklass_compact(tmp2, dst);
4405 cmpw(tmp1, tmp2);
4406 } else if (UseCompressedClassPointers) {
4407 ldrw(tmp1, Address(src, oopDesc::klass_offset_in_bytes()));
4408 ldrw(tmp2, Address(dst, oopDesc::klass_offset_in_bytes()));
4409 cmpw(tmp1, tmp2);
4410 } else {
4411 ldr(tmp1, Address(src, oopDesc::klass_offset_in_bytes()));
4412 ldr(tmp2, Address(dst, oopDesc::klass_offset_in_bytes()));
4413 cmp(tmp1, tmp2);
4414 }
4415 }
4416
4417 void MacroAssembler::store_klass(Register dst, Register src) {
4418 // FIXME: Should this be a store release? concurrent gcs assumes
4419 // klass length is valid if klass field is not null.
4420 assert(!UseCompactObjectHeaders, "not with compact headers");
4421 if (UseCompressedClassPointers) {
4422 encode_klass_not_null(src);
4423 strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
4424 } else {
4425 str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
4426 }
4427 }
4428
4429 void MacroAssembler::store_klass_gap(Register dst, Register src) {
4430 assert(!UseCompactObjectHeaders, "not with compact headers");
4431 if (UseCompressedClassPointers) {
4432 // Store to klass gap in destination
4433 strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
4434 }
4435 }
4436
4437 // Algorithm must match CompressedOops::encode.
4438 void MacroAssembler::encode_heap_oop(Register d, Register s) {
4439 #ifdef ASSERT
4440 verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
4441 #endif
4442 verify_oop_msg(s, "broken oop in encode_heap_oop");
4443 if (CompressedOops::base() == nullptr) {
4444 if (CompressedOops::shift() != 0) {
4445 assert (LogMinObjAlignmentInBytes == CompressedOops::shift(), "decode alg wrong");
4446 lsr(d, s, LogMinObjAlignmentInBytes);
4447 } else {
4448 mov(d, s);
4449 }
4450 } else {
|