3256 cmp(trial_klass, tmp, LSL, Universe::narrow_klass_shift());
3257 return;
3258 } else if (((uint64_t)Universe::narrow_klass_base() & 0xffffffff) == 0
3259 && Universe::narrow_klass_shift() == 0) {
3260 // Only the bottom 32 bits matter
3261 cmpw(trial_klass, tmp);
3262 return;
3263 }
3264 decode_klass_not_null(tmp);
3265 } else {
3266 ldr(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
3267 }
3268 cmp(trial_klass, tmp);
3269 }
3270
3271 void MacroAssembler::load_prototype_header(Register dst, Register src) {
3272 load_klass(dst, src);
3273 ldr(dst, Address(dst, Klass::prototype_header_offset()));
3274 }
3275
3276 void MacroAssembler::store_klass(Register dst, Register src) {
3277 // FIXME: Should this be a store release? concurrent gcs assumes
3278 // klass length is valid if klass field is not null.
3279 if (UseCompressedClassPointers) {
3280 encode_klass_not_null(src);
3281 strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3282 } else {
3283 str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3284 }
3285 }
3286
3287 void MacroAssembler::store_klass_gap(Register dst, Register src) {
3288 if (UseCompressedClassPointers) {
3289 // Store to klass gap in destination
3290 strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
3291 }
3292 }
3293
3294 // Algorithm must match oop.inline.hpp encode_heap_oop.
3295 void MacroAssembler::encode_heap_oop(Register d, Register s) {
3296 #ifdef ASSERT
3297 verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
3298 #endif
3299 verify_oop(s, "broken oop in encode_heap_oop");
3300 if (Universe::narrow_oop_base() == NULL) {
3301 if (Universe::narrow_oop_shift() != 0) {
3302 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
3303 lsr(d, s, LogMinObjAlignmentInBytes);
3304 } else {
3890 cbz(top, do_refill);
3891
3892 // set up the mark word
3893 mov(rscratch1, (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
3894 str(rscratch1, Address(top, oopDesc::mark_offset_in_bytes()));
3895 // set the length to the remaining space
3896 sub(t1, t1, typeArrayOopDesc::header_size(T_INT));
3897 add(t1, t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
3898 lsl(t1, t1, log2_intptr(HeapWordSize/sizeof(jint)));
3899 strw(t1, Address(top, arrayOopDesc::length_offset_in_bytes()));
3900 // set klass to intArrayKlass
3901 {
3902 unsigned long offset;
3903 // dubious reloc why not an oop reloc?
3904 adrp(rscratch1, ExternalAddress((address)Universe::intArrayKlassObj_addr()),
3905 offset);
3906 ldr(t1, Address(rscratch1, offset));
3907 }
3908 // store klass last. concurrent gcs assumes klass length is valid if
3909 // klass field is not null.
3910 store_klass(top, t1);
3911
3912 mov(t1, top);
3913 ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
3914 sub(t1, t1, rscratch1);
3915 incr_allocated_bytes(rthread, t1, 0, rscratch1);
3916
3917 // refill the tlab with an eden allocation
3918 bind(do_refill);
3919 ldr(t1, Address(rthread, in_bytes(JavaThread::tlab_size_offset())));
3920 lsl(t1, t1, LogHeapWordSize);
3921 // allocate new tlab, address returned in top
3922 eden_allocate(top, t1, 0, t2, slow_case);
3923
3924 // Check that t1 was preserved in eden_allocate.
3925 #ifdef ASSERT
3926 if (UseTLAB) {
3927 Label ok;
3928 Register tsize = r4;
3929 assert_different_registers(tsize, rthread, t1);
3930 str(tsize, Address(pre(sp, -16)));
|
3256 cmp(trial_klass, tmp, LSL, Universe::narrow_klass_shift());
3257 return;
3258 } else if (((uint64_t)Universe::narrow_klass_base() & 0xffffffff) == 0
3259 && Universe::narrow_klass_shift() == 0) {
3260 // Only the bottom 32 bits matter
3261 cmpw(trial_klass, tmp);
3262 return;
3263 }
3264 decode_klass_not_null(tmp);
3265 } else {
3266 ldr(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
3267 }
3268 cmp(trial_klass, tmp);
3269 }
3270
3271 void MacroAssembler::load_prototype_header(Register dst, Register src) {
3272 load_klass(dst, src);
3273 ldr(dst, Address(dst, Klass::prototype_header_offset()));
3274 }
3275
3276 void MacroAssembler::store_klass(Register dst, Register src, Register tmp) {
3277 // concurrent gcs assumes klass length is valid if klass field is not null.
3278 bool is_concurrentGC = UseG1GC || UseConcMarkSweepGC;
3279
3280 if (is_concurrentGC) {
3281 add(tmp, dst, oopDesc::klass_offset_in_bytes());
3282 if (UseCompressedClassPointers) {
3283 encode_klass_not_null(src);
3284 stlrw(src, tmp);
3285 } else {
3286 stlr(src, tmp);
3287 }
3288 } else {
3289 if (UseCompressedClassPointers) {
3290 encode_klass_not_null(src);
3291 strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3292 } else {
3293 str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3294 }
3295 }
3296 }
3297
3298 void MacroAssembler::store_klass_gap(Register dst, Register src) {
3299 if (UseCompressedClassPointers) {
3300 // Store to klass gap in destination
3301 strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
3302 }
3303 }
3304
3305 // Algorithm must match oop.inline.hpp encode_heap_oop.
3306 void MacroAssembler::encode_heap_oop(Register d, Register s) {
3307 #ifdef ASSERT
3308 verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
3309 #endif
3310 verify_oop(s, "broken oop in encode_heap_oop");
3311 if (Universe::narrow_oop_base() == NULL) {
3312 if (Universe::narrow_oop_shift() != 0) {
3313 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
3314 lsr(d, s, LogMinObjAlignmentInBytes);
3315 } else {
3901 cbz(top, do_refill);
3902
3903 // set up the mark word
3904 mov(rscratch1, (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
3905 str(rscratch1, Address(top, oopDesc::mark_offset_in_bytes()));
3906 // set the length to the remaining space
3907 sub(t1, t1, typeArrayOopDesc::header_size(T_INT));
3908 add(t1, t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
3909 lsl(t1, t1, log2_intptr(HeapWordSize/sizeof(jint)));
3910 strw(t1, Address(top, arrayOopDesc::length_offset_in_bytes()));
3911 // set klass to intArrayKlass
3912 {
3913 unsigned long offset;
3914 // dubious reloc why not an oop reloc?
3915 adrp(rscratch1, ExternalAddress((address)Universe::intArrayKlassObj_addr()),
3916 offset);
3917 ldr(t1, Address(rscratch1, offset));
3918 }
3919 // store klass last. concurrent gcs assumes klass length is valid if
3920 // klass field is not null.
3921 store_klass(top, t1, rscratch1);
3922
3923 mov(t1, top);
3924 ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
3925 sub(t1, t1, rscratch1);
3926 incr_allocated_bytes(rthread, t1, 0, rscratch1);
3927
3928 // refill the tlab with an eden allocation
3929 bind(do_refill);
3930 ldr(t1, Address(rthread, in_bytes(JavaThread::tlab_size_offset())));
3931 lsl(t1, t1, LogHeapWordSize);
3932 // allocate new tlab, address returned in top
3933 eden_allocate(top, t1, 0, t2, slow_case);
3934
3935 // Check that t1 was preserved in eden_allocate.
3936 #ifdef ASSERT
3937 if (UseTLAB) {
3938 Label ok;
3939 Register tsize = r4;
3940 assert_different_registers(tsize, rthread, t1);
3941 str(tsize, Address(pre(sp, -16)));
|