29 #include "ci/ciEnv.hpp"
30 #include "code/nativeInst.hpp"
31 #include "compiler/disassembler.hpp"
32 #include "gc/shared/cardTable.hpp"
33 #include "gc/shared/cardTableBarrierSet.hpp"
34 #include "gc/shared/collectedHeap.inline.hpp"
35 #include "interpreter/interpreter.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "oops/klass.inline.hpp"
38 #include "prims/methodHandles.hpp"
39 #include "runtime/biasedLocking.hpp"
40 #include "runtime/interfaceSupport.inline.hpp"
41 #include "runtime/objectMonitor.hpp"
42 #include "runtime/os.hpp"
43 #include "runtime/sharedRuntime.hpp"
44 #include "runtime/stubRoutines.hpp"
45 #include "utilities/macros.hpp"
46 #if INCLUDE_ALL_GCS
47 #include "gc/g1/g1BarrierSet.hpp"
48 #include "gc/g1/g1CardTable.hpp"
49 #include "gc/g1/heapRegion.hpp"
50 #endif
51
52 // Implementation of AddressLiteral
53
54 void AddressLiteral::set_rspec(relocInfo::relocType rtype) {
55 switch (rtype) {
56 case relocInfo::oop_type:
57 // Oops are a special case. Normally they would be their own section
58 // but in cases like icBuffer they are literals in the code stream that
59 // we don't have a section for. We use none so that we get a literal address
60 // which is always patchable.
61 break;
62 case relocInfo::external_word_type:
63 _rspec = external_word_Relocation::spec(_target);
64 break;
65 case relocInfo::internal_word_type:
66 _rspec = internal_word_Relocation::spec(_target);
67 break;
68 case relocInfo::opt_virtual_call_type:
2157 // G1 pre-barrier.
2158 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
2159 // If store_addr != noreg, then previous value is loaded from [store_addr];
2160 // in such case store_addr and new_val registers are preserved;
2161 // otherwise pre_val register is preserved.
2162 void MacroAssembler::g1_write_barrier_pre(Register store_addr,
2163 Register new_val,
2164 Register pre_val,
2165 Register tmp1,
2166 Register tmp2) {
2167 Label done;
2168 Label runtime;
2169
2170 if (store_addr != noreg) {
2171 assert_different_registers(store_addr, new_val, pre_val, tmp1, tmp2, noreg);
2172 } else {
2173 assert (new_val == noreg, "should be");
2174 assert_different_registers(pre_val, tmp1, tmp2, noreg);
2175 }
2176
2177 Address in_progress(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
2178 SATBMarkQueue::byte_offset_of_active()));
2179 Address index(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
2180 SATBMarkQueue::byte_offset_of_index()));
2181 Address buffer(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
2182 SATBMarkQueue::byte_offset_of_buf()));
2183
2184 // Is marking active?
2185 assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "adjust this code");
2186 ldrb(tmp1, in_progress);
2187 cbz(tmp1, done);
2188
2189 // Do we need to load the previous value?
2190 if (store_addr != noreg) {
2191 load_heap_oop(pre_val, Address(store_addr, 0));
2192 }
2193
2194 // Is the previous value null?
2195 cbz(pre_val, done);
2196
2197 // Can we store original value in the thread's buffer?
2198 // Is index == 0?
2199 // (The index field is typed as size_t.)
2200
2201 ldr(tmp1, index); // tmp1 := *index_adr
2202 ldr(tmp2, buffer);
2243 }
2244 #else
2245 if (store_addr != noreg) {
2246 pop(RegisterSet(store_addr) | RegisterSet(new_val));
2247 } else {
2248 pop(pre_val);
2249 }
2250 #endif // AARCH64
2251
2252 bind(done);
2253 }
2254
2255 // G1 post-barrier.
2256 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
2257 void MacroAssembler::g1_write_barrier_post(Register store_addr,
2258 Register new_val,
2259 Register tmp1,
2260 Register tmp2,
2261 Register tmp3) {
2262
2263 Address queue_index(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
2264 DirtyCardQueue::byte_offset_of_index()));
2265 Address buffer(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
2266 DirtyCardQueue::byte_offset_of_buf()));
2267
2268 BarrierSet* bs = Universe::heap()->barrier_set();
2269 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
2270 CardTable* ct = ctbs->card_table();
2271 Label done;
2272 Label runtime;
2273
2274 // Does store cross heap regions?
2275
2276 eor(tmp1, store_addr, new_val);
2277 #ifdef AARCH64
2278 logical_shift_right(tmp1, tmp1, HeapRegion::LogOfHRGrainBytes);
2279 cbz(tmp1, done);
2280 #else
2281 movs(tmp1, AsmOperand(tmp1, lsr, HeapRegion::LogOfHRGrainBytes));
2282 b(done, eq);
2283 #endif
2284
2285 // crosses regions, storing NULL?
2286
|
29 #include "ci/ciEnv.hpp"
30 #include "code/nativeInst.hpp"
31 #include "compiler/disassembler.hpp"
32 #include "gc/shared/cardTable.hpp"
33 #include "gc/shared/cardTableBarrierSet.hpp"
34 #include "gc/shared/collectedHeap.inline.hpp"
35 #include "interpreter/interpreter.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "oops/klass.inline.hpp"
38 #include "prims/methodHandles.hpp"
39 #include "runtime/biasedLocking.hpp"
40 #include "runtime/interfaceSupport.inline.hpp"
41 #include "runtime/objectMonitor.hpp"
42 #include "runtime/os.hpp"
43 #include "runtime/sharedRuntime.hpp"
44 #include "runtime/stubRoutines.hpp"
45 #include "utilities/macros.hpp"
46 #if INCLUDE_ALL_GCS
47 #include "gc/g1/g1BarrierSet.hpp"
48 #include "gc/g1/g1CardTable.hpp"
49 #include "gc/g1/g1ThreadLocalData.hpp"
50 #include "gc/g1/heapRegion.hpp"
51 #endif
52
53 // Implementation of AddressLiteral
54
55 void AddressLiteral::set_rspec(relocInfo::relocType rtype) {
56 switch (rtype) {
57 case relocInfo::oop_type:
58 // Oops are a special case. Normally they would be their own section
59 // but in cases like icBuffer they are literals in the code stream that
60 // we don't have a section for. We use none so that we get a literal address
61 // which is always patchable.
62 break;
63 case relocInfo::external_word_type:
64 _rspec = external_word_Relocation::spec(_target);
65 break;
66 case relocInfo::internal_word_type:
67 _rspec = internal_word_Relocation::spec(_target);
68 break;
69 case relocInfo::opt_virtual_call_type:
2158 // G1 pre-barrier.
2159 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
2160 // If store_addr != noreg, then previous value is loaded from [store_addr];
2161 // in such case store_addr and new_val registers are preserved;
2162 // otherwise pre_val register is preserved.
2163 void MacroAssembler::g1_write_barrier_pre(Register store_addr,
2164 Register new_val,
2165 Register pre_val,
2166 Register tmp1,
2167 Register tmp2) {
2168 Label done;
2169 Label runtime;
2170
2171 if (store_addr != noreg) {
2172 assert_different_registers(store_addr, new_val, pre_val, tmp1, tmp2, noreg);
2173 } else {
2174 assert (new_val == noreg, "should be");
2175 assert_different_registers(pre_val, tmp1, tmp2, noreg);
2176 }
2177
2178 Address in_progress(Rthread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()));
2179 Address index(Rthread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()));
2180 Address buffer(Rthread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()));
2181
2182 // Is marking active?
2183 assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "adjust this code");
2184 ldrb(tmp1, in_progress);
2185 cbz(tmp1, done);
2186
2187 // Do we need to load the previous value?
2188 if (store_addr != noreg) {
2189 load_heap_oop(pre_val, Address(store_addr, 0));
2190 }
2191
2192 // Is the previous value null?
2193 cbz(pre_val, done);
2194
2195 // Can we store original value in the thread's buffer?
2196 // Is index == 0?
2197 // (The index field is typed as size_t.)
2198
2199 ldr(tmp1, index); // tmp1 := *index_adr
2200 ldr(tmp2, buffer);
2241 }
2242 #else
2243 if (store_addr != noreg) {
2244 pop(RegisterSet(store_addr) | RegisterSet(new_val));
2245 } else {
2246 pop(pre_val);
2247 }
2248 #endif // AARCH64
2249
2250 bind(done);
2251 }
2252
2253 // G1 post-barrier.
2254 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
2255 void MacroAssembler::g1_write_barrier_post(Register store_addr,
2256 Register new_val,
2257 Register tmp1,
2258 Register tmp2,
2259 Register tmp3) {
2260
2261 Address queue_index(Rthread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
2262 Address buffer(Rthread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
2263
2264 BarrierSet* bs = Universe::heap()->barrier_set();
2265 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
2266 CardTable* ct = ctbs->card_table();
2267 Label done;
2268 Label runtime;
2269
2270 // Does store cross heap regions?
2271
2272 eor(tmp1, store_addr, new_val);
2273 #ifdef AARCH64
2274 logical_shift_right(tmp1, tmp1, HeapRegion::LogOfHRGrainBytes);
2275 cbz(tmp1, done);
2276 #else
2277 movs(tmp1, AsmOperand(tmp1, lsr, HeapRegion::LogOfHRGrainBytes));
2278 b(done, eq);
2279 #endif
2280
2281 // crosses regions, storing NULL?
2282
|