1 /* |
1 /* |
2 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
31 #include "c1/c1_Runtime1.hpp" |
31 #include "c1/c1_Runtime1.hpp" |
32 #include "c1/c1_ValueStack.hpp" |
32 #include "c1/c1_ValueStack.hpp" |
33 #include "ci/ciArray.hpp" |
33 #include "ci/ciArray.hpp" |
34 #include "ci/ciObjArrayKlass.hpp" |
34 #include "ci/ciObjArrayKlass.hpp" |
35 #include "ci/ciTypeArrayKlass.hpp" |
35 #include "ci/ciTypeArrayKlass.hpp" |
|
36 #include "ci/ciUtilities.hpp" |
|
37 #include "gc/shared/cardTable.hpp" |
36 #include "gc/shared/cardTableModRefBS.hpp" |
38 #include "gc/shared/cardTableModRefBS.hpp" |
37 #include "runtime/sharedRuntime.hpp" |
39 #include "runtime/sharedRuntime.hpp" |
38 #include "runtime/stubRoutines.hpp" |
40 #include "runtime/stubRoutines.hpp" |
39 #include "vmreg_arm.inline.hpp" |
41 #include "vmreg_arm.inline.hpp" |
40 |
42 |
473 assert(item->type() == T_INT, "other types are not expected"); |
475 assert(item->type() == T_INT, "other types are not expected"); |
474 __ store(item, new LIR_Address(FrameMap::SP_opr, in_bytes(offset_from_sp), item->type())); |
476 __ store(item, new LIR_Address(FrameMap::SP_opr, in_bytes(offset_from_sp), item->type())); |
475 } |
477 } |
476 |
478 |
477 void LIRGenerator::set_card(LIR_Opr value, LIR_Address* card_addr) { |
479 void LIRGenerator::set_card(LIR_Opr value, LIR_Address* card_addr) { |
478 assert(CardTableModRefBS::dirty_card_val() == 0, |
480 assert(CardTable::dirty_card_val() == 0, |
479 "Cannot use ZR register (aarch64) or the register containing the card table base address directly (aarch32) otherwise"); |
481 "Cannot use ZR register (aarch64) or the register containing the card table base address directly (aarch32) otherwise"); |
480 #ifdef AARCH64 |
482 #ifdef AARCH64 |
481 // AARCH64 has a register that is constant zero. We can use that one to set the |
483 // AARCH64 has a register that is constant zero. We can use that one to set the |
482 // value in the card table to dirty. |
484 // value in the card table to dirty. |
483 __ move(FrameMap::ZR_opr, card_addr); |
485 __ move(FrameMap::ZR_opr, card_addr); |
484 #else // AARCH64 |
486 #else // AARCH64 |
485 CardTableModRefBS* ct = (CardTableModRefBS*)_bs; |
487 if((ci_card_table_address_as<intx>() & 0xff) == 0) { |
486 if(((intx)ct->byte_map_base & 0xff) == 0) { |
|
487 // If the card table base address is aligned to 256 bytes, we can use the register |
488 // If the card table base address is aligned to 256 bytes, we can use the register |
488 // that contains the card_table_base_address. |
489 // that contains the card_table_base_address. |
489 __ move(value, card_addr); |
490 __ move(value, card_addr); |
490 } else { |
491 } else { |
491 // Otherwise we need to create a register containing that value. |
492 // Otherwise we need to create a register containing that value. |
492 LIR_Opr tmp_zero = new_register(T_INT); |
493 LIR_Opr tmp_zero = new_register(T_INT); |
493 __ move(LIR_OprFact::intConst(CardTableModRefBS::dirty_card_val()), tmp_zero); |
494 __ move(LIR_OprFact::intConst(CardTable::dirty_card_val()), tmp_zero); |
494 __ move(tmp_zero, card_addr); |
495 __ move(tmp_zero, card_addr); |
495 } |
496 } |
496 #endif // AARCH64 |
497 #endif // AARCH64 |
497 } |
498 } |
498 |
499 |
508 } else { |
509 } else { |
509 __ move(new LIR_Address(FrameMap::Rthread_opr, in_bytes(JavaThread::card_table_base_offset()), T_ADDRESS), tmp); |
510 __ move(new LIR_Address(FrameMap::Rthread_opr, in_bytes(JavaThread::card_table_base_offset()), T_ADDRESS), tmp); |
510 } |
511 } |
511 |
512 |
512 #ifdef AARCH64 |
513 #ifdef AARCH64 |
513 LIR_Address* shifted_reg_operand = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTableModRefBS::card_shift, 0, T_BYTE); |
514 LIR_Address* shifted_reg_operand = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift, 0, T_BYTE); |
514 LIR_Opr tmp2 = tmp; |
515 LIR_Opr tmp2 = tmp; |
515 __ add(tmp, LIR_OprFact::address(shifted_reg_operand), tmp2); // tmp2 = tmp + (addr >> CardTableModRefBS::card_shift) |
516 __ add(tmp, LIR_OprFact::address(shifted_reg_operand), tmp2); // tmp2 = tmp + (addr >> CardTable::card_shift) |
516 LIR_Address* card_addr = new LIR_Address(tmp2, T_BYTE); |
517 LIR_Address* card_addr = new LIR_Address(tmp2, T_BYTE); |
517 #else |
518 #else |
518 // Use unsigned type T_BOOLEAN here rather than (signed) T_BYTE since signed load |
519 // Use unsigned type T_BOOLEAN here rather than (signed) T_BYTE since signed load |
519 // byte instruction does not support the addressing mode we need. |
520 // byte instruction does not support the addressing mode we need. |
520 LIR_Address* card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTableModRefBS::card_shift, 0, T_BOOLEAN); |
521 LIR_Address* card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift, 0, T_BOOLEAN); |
521 #endif |
522 #endif |
522 if (UseCondCardMark) { |
523 if (UseCondCardMark) { |
523 if (UseConcMarkSweepGC) { |
524 if (UseConcMarkSweepGC) { |
524 __ membar_storeload(); |
525 __ membar_storeload(); |
525 } |
526 } |
526 LIR_Opr cur_value = new_register(T_INT); |
527 LIR_Opr cur_value = new_register(T_INT); |
527 __ move(card_addr, cur_value); |
528 __ move(card_addr, cur_value); |
528 |
529 |
529 LabelObj* L_already_dirty = new LabelObj(); |
530 LabelObj* L_already_dirty = new LabelObj(); |
530 __ cmp(lir_cond_equal, cur_value, LIR_OprFact::intConst(CardTableModRefBS::dirty_card_val())); |
531 __ cmp(lir_cond_equal, cur_value, LIR_OprFact::intConst(CardTable::dirty_card_val())); |
531 __ branch(lir_cond_equal, T_BYTE, L_already_dirty->label()); |
532 __ branch(lir_cond_equal, T_BYTE, L_already_dirty->label()); |
532 set_card(tmp, card_addr); |
533 set_card(tmp, card_addr); |
533 __ branch_destination(L_already_dirty->label()); |
534 __ branch_destination(L_already_dirty->label()); |
534 } else { |
535 } else { |
535 if (UseConcMarkSweepGC && CMSPrecleaningEnabled) { |
536 if (UseConcMarkSweepGC && CMSPrecleaningEnabled) { |