< prev index next >

src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp

Print this page

 66     load_klass(hdr, obj);
 67     lbu(hdr, Address(hdr, Klass::misc_flags_offset()));
 68     test_bit(temp, hdr, exact_log2(KlassFlags::_misc_is_value_based_class));
 69     bnez(temp, slow_case, true /* is_far */);
 70   }
 71 
 72   if (LockingMode == LM_LIGHTWEIGHT) {
 73     lightweight_lock(disp_hdr, obj, hdr, temp, t1, slow_case);
 74   } else if (LockingMode == LM_LEGACY) {
 75     Label done;
 76     // Load object header
 77     ld(hdr, Address(obj, hdr_offset));
 78     // and mark it as unlocked
 79     ori(hdr, hdr, markWord::unlocked_value);
 80     // save unlocked object header into the displaced header location on the stack
 81     sd(hdr, Address(disp_hdr, 0));
 82     // test if object header is still the same (i.e. unlocked), and if so, store the
 83     // displaced header address in the object header - if it is not the same, get the
 84     // object header instead
 85     la(temp, Address(obj, hdr_offset));
 86     cmpxchgptr(hdr, disp_hdr, temp, t1, done, /*fallthough*/nullptr);
 87     // if the object header was the same, we're done

 88     // if the object header was not the same, it is now in the hdr register
 89     // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
 90     //
 91     // 1) (hdr & aligned_mask) == 0
 92     // 2) sp <= hdr
 93     // 3) hdr <= sp + page_size
 94     //
 95     // these 3 tests can be done by evaluating the following expression:
 96     //
 97     // (hdr -sp) & (aligned_mask - page_size)
 98     //
 99     // assuming both the stack pointer and page_size have their least
100     // significant 2 bits cleared and page_size is a power of 2
101     sub(hdr, hdr, sp);
102     mv(temp, aligned_mask - (int)os::vm_page_size());
103     andr(hdr, hdr, temp);
104     // for recursive locking, the result is zero => save it in the displaced header
105     // location (null in the displaced hdr location indicates recursive locking)
106     sd(hdr, Address(disp_hdr, 0));
107     // otherwise we don't care about the result and handle locking via runtime call
108     bnez(hdr, slow_case, /* is_far */ true);

109     // done
110     bind(done);

111   }
112 
113   increment(Address(xthread, JavaThread::held_monitor_count_offset()));
114   return null_check_offset;
115 }
116 
117 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
118   const int aligned_mask = BytesPerWord - 1;
119   const int hdr_offset = oopDesc::mark_offset_in_bytes();
120   assert_different_registers(hdr, obj, disp_hdr, temp, t0, t1);
121   Label done;
122 
123   if (LockingMode != LM_LIGHTWEIGHT) {
124     // load displaced header
125     ld(hdr, Address(disp_hdr, 0));
126     // if the loaded hdr is null we had recursive locking
127     // if we had recursive locking, we are done
128     beqz(hdr, done);
129   }
130 
131   // load object
132   ld(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
133   verify_oop(obj);
134 
135   if (LockingMode == LM_LIGHTWEIGHT) {
136     lightweight_unlock(obj, hdr, temp, t1, slow_case);
137   } else if (LockingMode == LM_LEGACY) {
138     // test if object header is pointing to the displaced header, and if so, restore
139     // the displaced header in the object - if the object header is not pointing to
140     // the displaced header, get the object header instead
141     // if the object header was not pointing to the displaced header,
142     // we do unlocking via runtime call
143     if (hdr_offset) {
144       la(temp, Address(obj, hdr_offset));
145       cmpxchgptr(disp_hdr, hdr, temp, t1, done, &slow_case);
146     } else {
147       cmpxchgptr(disp_hdr, hdr, obj, t1, done, &slow_case);
148     }

149     // done
150     bind(done);

151   }
152 
153   decrement(Address(xthread, JavaThread::held_monitor_count_offset()));
154 }
155 
156 // Defines obj, preserves var_size_in_bytes
157 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register tmp1, Register tmp2, Label& slow_case) {
158   if (UseTLAB) {
159     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, tmp1, tmp2, slow_case, /* is_far */ true);
160   } else {
161     j(slow_case);
162   }
163 }
164 
165 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register tmp1, Register tmp2) {
166   assert_different_registers(obj, klass, len, tmp1, tmp2);
167   // This assumes that all prototype bits fitr in an int32_t
168   mv(tmp1, (int32_t)(intptr_t)markWord::prototype().value());
169   sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
170 
171   if (UseCompressedClassPointers) { // Take care not to kill klass
172     encode_klass_not_null(tmp1, klass, tmp2);
173     sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));

 66     load_klass(hdr, obj);
 67     lbu(hdr, Address(hdr, Klass::misc_flags_offset()));
 68     test_bit(temp, hdr, exact_log2(KlassFlags::_misc_is_value_based_class));
 69     bnez(temp, slow_case, true /* is_far */);
 70   }
 71 
 72   if (LockingMode == LM_LIGHTWEIGHT) {
 73     lightweight_lock(disp_hdr, obj, hdr, temp, t1, slow_case);
 74   } else if (LockingMode == LM_LEGACY) {
 75     Label done;
 76     // Load object header
 77     ld(hdr, Address(obj, hdr_offset));
 78     // and mark it as unlocked
 79     ori(hdr, hdr, markWord::unlocked_value);
 80     // save unlocked object header into the displaced header location on the stack
 81     sd(hdr, Address(disp_hdr, 0));
 82     // test if object header is still the same (i.e. unlocked), and if so, store the
 83     // displaced header address in the object header - if it is not the same, get the
 84     // object header instead
 85     la(temp, Address(obj, hdr_offset));

 86     // if the object header was the same, we're done
 87     cmpxchgptr(hdr, disp_hdr, temp, t1, done, /*fallthough*/nullptr);
 88     // if the object header was not the same, it is now in the hdr register
 89     // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
 90     //
 91     // 1) (hdr & aligned_mask) == 0
 92     // 2) sp <= hdr
 93     // 3) hdr <= sp + page_size
 94     //
 95     // these 3 tests can be done by evaluating the following expression:
 96     //
 97     // (hdr -sp) & (aligned_mask - page_size)
 98     //
 99     // assuming both the stack pointer and page_size have their least
100     // significant 2 bits cleared and page_size is a power of 2
101     sub(hdr, hdr, sp);
102     mv(temp, aligned_mask - (int)os::vm_page_size());
103     andr(hdr, hdr, temp);
104     // for recursive locking, the result is zero => save it in the displaced header
105     // location (null in the displaced hdr location indicates recursive locking)
106     sd(hdr, Address(disp_hdr, 0));
107     // otherwise we don't care about the result and handle locking via runtime call
108     bnez(hdr, slow_case, /* is_far */ true);
109 
110     // done
111     bind(done);
112     inc_held_monitor_count();
113   }
114 

115   return null_check_offset;
116 }
117 
118 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
119   const int aligned_mask = BytesPerWord - 1;
120   const int hdr_offset = oopDesc::mark_offset_in_bytes();
121   assert_different_registers(hdr, obj, disp_hdr, temp, t0, t1);
122   Label done;
123 
124   if (LockingMode != LM_LIGHTWEIGHT) {
125     // load displaced header
126     ld(hdr, Address(disp_hdr, 0));
127     // if the loaded hdr is null we had recursive locking
128     // if we had recursive locking, we are done
129     beqz(hdr, done);
130   }
131 
132   // load object
133   ld(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
134   verify_oop(obj);
135 
136   if (LockingMode == LM_LIGHTWEIGHT) {
137     lightweight_unlock(obj, hdr, temp, t1, slow_case);
138   } else if (LockingMode == LM_LEGACY) {
139     // test if object header is pointing to the displaced header, and if so, restore
140     // the displaced header in the object - if the object header is not pointing to
141     // the displaced header, get the object header instead
142     // if the object header was not pointing to the displaced header,
143     // we do unlocking via runtime call
144     if (hdr_offset) {
145       la(temp, Address(obj, hdr_offset));
146       cmpxchgptr(disp_hdr, hdr, temp, t1, done, &slow_case);
147     } else {
148       cmpxchgptr(disp_hdr, hdr, obj, t1, done, &slow_case);
149     }
150 
151     // done
152     bind(done);
153     dec_held_monitor_count();
154   }


155 }
156 
157 // Defines obj, preserves var_size_in_bytes
158 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register tmp1, Register tmp2, Label& slow_case) {
159   if (UseTLAB) {
160     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, tmp1, tmp2, slow_case, /* is_far */ true);
161   } else {
162     j(slow_case);
163   }
164 }
165 
166 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register tmp1, Register tmp2) {
167   assert_different_registers(obj, klass, len, tmp1, tmp2);
168   // This assumes that all prototype bits fitr in an int32_t
169   mv(tmp1, (int32_t)(intptr_t)markWord::prototype().value());
170   sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
171 
172   if (UseCompressedClassPointers) { // Take care not to kill klass
173     encode_klass_not_null(tmp1, klass, tmp2);
174     sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
< prev index next >