< prev index next >

src/hotspot/cpu/arm/macroAssembler_arm.cpp

Print this page




  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 


< prev index next >