7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.inline.hpp"
27 #include "gc/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1BarrierSetAssembler.hpp"
29 #include "gc/g1/g1BarrierSetRuntime.hpp"
30 #include "gc/g1/g1CardTable.hpp"
31 #include "gc/g1/g1HeapRegion.hpp"
32 #include "gc/g1/g1ThreadLocalData.hpp"
33 #include "interpreter/interp_masm.hpp"
34 #include "runtime/sharedRuntime.hpp"
35 #include "utilities/debug.hpp"
36 #include "utilities/macros.hpp"
37 #ifdef COMPILER1
38 #include "c1/c1_LIRAssembler.hpp"
39 #include "c1/c1_MacroAssembler.hpp"
40 #include "gc/g1/c1/g1BarrierSetC1.hpp"
41 #endif
42
43 #define __ masm->
44
45 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
46 Register addr, Register count) {
286
287 __ movptr(tmp, store_addr);
288 __ xorptr(tmp, new_val);
289 __ shrptr(tmp, HeapRegion::LogOfHRGrainBytes);
290 __ jcc(Assembler::equal, done);
291
292 // crosses regions, storing null?
293
294 __ cmpptr(new_val, NULL_WORD);
295 __ jcc(Assembler::equal, done);
296
297 // storing region crossing non-null, is card already dirty?
298
299 const Register card_addr = tmp;
300 const Register cardtable = tmp2;
301
302 __ movptr(card_addr, store_addr);
303 __ shrptr(card_addr, CardTable::card_shift());
304 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
305 // a valid address and therefore is not properly handled by the relocation code.
306 __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
307 __ addptr(card_addr, cardtable);
308
309 __ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
310 __ jcc(Assembler::equal, done);
311
312 __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
313 __ cmpb(Address(card_addr, 0), G1CardTable::dirty_card_val());
314 __ jcc(Assembler::equal, done);
315
316
317 // storing a region crossing, non-null oop, card is clean.
318 // dirty card and log.
319
320 __ movb(Address(card_addr, 0), G1CardTable::dirty_card_val());
321
322 // The code below assumes that buffer index is pointer sized.
323 STATIC_ASSERT(in_bytes(G1DirtyCardQueue::byte_width_of_index()) == sizeof(intptr_t));
324
325 __ movptr(tmp2, queue_index);
326 __ testptr(tmp2, tmp2);
521 Label runtime;
522
523 // At this point we know new_value is non-null and the new_value crosses regions.
524 // Must check to see if card is already dirty
525
526 const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
527
528 Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
529 Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
530
531 __ push(rax);
532 __ push(rcx);
533
534 const Register cardtable = rax;
535 const Register card_addr = rcx;
536
537 __ load_parameter(0, card_addr);
538 __ shrptr(card_addr, CardTable::card_shift());
539 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
540 // a valid address and therefore is not properly handled by the relocation code.
541 __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
542 __ addptr(card_addr, cardtable);
543
544 NOT_LP64(__ get_thread(thread);)
545
546 __ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
547 __ jcc(Assembler::equal, done);
548
549 __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
550 __ cmpb(Address(card_addr, 0), CardTable::dirty_card_val());
551 __ jcc(Assembler::equal, done);
552
553 // storing region crossing non-null, card is clean.
554 // dirty card and log.
555
556 __ movb(Address(card_addr, 0), CardTable::dirty_card_val());
557
558 const Register tmp = rdx;
559 __ push(rdx);
560
561 __ movptr(tmp, queue_index);
|
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.inline.hpp"
27 #include "code/SCCache.hpp"
28 #include "gc/g1/g1BarrierSet.hpp"
29 #include "gc/g1/g1BarrierSetAssembler.hpp"
30 #include "gc/g1/g1BarrierSetRuntime.hpp"
31 #include "gc/g1/g1CardTable.hpp"
32 #include "gc/g1/g1HeapRegion.hpp"
33 #include "gc/g1/g1ThreadLocalData.hpp"
34 #include "interpreter/interp_masm.hpp"
35 #include "runtime/sharedRuntime.hpp"
36 #include "utilities/debug.hpp"
37 #include "utilities/macros.hpp"
38 #ifdef COMPILER1
39 #include "c1/c1_LIRAssembler.hpp"
40 #include "c1/c1_MacroAssembler.hpp"
41 #include "gc/g1/c1/g1BarrierSetC1.hpp"
42 #endif
43
44 #define __ masm->
45
46 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
47 Register addr, Register count) {
287
288 __ movptr(tmp, store_addr);
289 __ xorptr(tmp, new_val);
290 __ shrptr(tmp, HeapRegion::LogOfHRGrainBytes);
291 __ jcc(Assembler::equal, done);
292
293 // crosses regions, storing null?
294
295 __ cmpptr(new_val, NULL_WORD);
296 __ jcc(Assembler::equal, done);
297
298 // storing region crossing non-null, is card already dirty?
299
300 const Register card_addr = tmp;
301 const Register cardtable = tmp2;
302
303 __ movptr(card_addr, store_addr);
304 __ shrptr(card_addr, CardTable::card_shift());
305 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
306 // a valid address and therefore is not properly handled by the relocation code.
307 if (SCCache::is_on_for_write()) {
308 // SCA needs relocation info for this address
309 __ lea(cardtable, ExternalAddress((address)ct->card_table()->byte_map_base()));
310 } else {
311 __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
312 }
313 __ addptr(card_addr, cardtable);
314
315 __ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
316 __ jcc(Assembler::equal, done);
317
318 __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
319 __ cmpb(Address(card_addr, 0), G1CardTable::dirty_card_val());
320 __ jcc(Assembler::equal, done);
321
322
323 // storing a region crossing, non-null oop, card is clean.
324 // dirty card and log.
325
326 __ movb(Address(card_addr, 0), G1CardTable::dirty_card_val());
327
328 // The code below assumes that buffer index is pointer sized.
329 STATIC_ASSERT(in_bytes(G1DirtyCardQueue::byte_width_of_index()) == sizeof(intptr_t));
330
331 __ movptr(tmp2, queue_index);
332 __ testptr(tmp2, tmp2);
527 Label runtime;
528
529 // At this point we know new_value is non-null and the new_value crosses regions.
530 // Must check to see if card is already dirty
531
532 const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
533
534 Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
535 Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
536
537 __ push(rax);
538 __ push(rcx);
539
540 const Register cardtable = rax;
541 const Register card_addr = rcx;
542
543 __ load_parameter(0, card_addr);
544 __ shrptr(card_addr, CardTable::card_shift());
545 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
546 // a valid address and therefore is not properly handled by the relocation code.
547 if (SCCache::is_on()) {
548 // SCA needs relocation info for this address
549 __ lea(cardtable, ExternalAddress((address)ct->card_table()->byte_map_base()));
550 } else {
551 __ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
552 }
553 __ addptr(card_addr, cardtable);
554
555 NOT_LP64(__ get_thread(thread);)
556
557 __ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
558 __ jcc(Assembler::equal, done);
559
560 __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
561 __ cmpb(Address(card_addr, 0), CardTable::dirty_card_val());
562 __ jcc(Assembler::equal, done);
563
564 // storing region crossing non-null, card is clean.
565 // dirty card and log.
566
567 __ movb(Address(card_addr, 0), CardTable::dirty_card_val());
568
569 const Register tmp = rdx;
570 __ push(rdx);
571
572 __ movptr(tmp, queue_index);
|