1 /*
2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
3016 barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
3017 assert(bs->kind() == BarrierSet::CardTableForRS ||
3018 bs->kind() == BarrierSet::CardTableExtension, "wrong barrier");
3019 #ifdef ASSERT
3020 cmpdi(CCR0, Rnew_val, 0);
3021 asm_assert_ne("null oop not allowed", 0x321);
3022 #endif
3023 card_table_write(bs->byte_map_base, Rtmp, Rstore_addr);
3024 }
3025
3026 // Write the card table byte.
3027 void MacroAssembler::card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj) {
3028 assert_different_registers(Robj, Rtmp, R0);
3029 load_const_optimized(Rtmp, (address)byte_map_base, R0);
3030 srdi(Robj, Robj, CardTableModRefBS::card_shift);
3031 li(R0, 0); // dirty
3032 if (UseConcMarkSweepGC) membar(Assembler::StoreStore);
3033 stbx(R0, Rtmp, Robj);
3034 }
3035
3036 // Kills R31 if value is a volatile register.
3037 void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp2, bool needs_frame) {
3038 Label done;
3039 cmpdi(CCR0, value, 0);
3040 beq(CCR0, done); // Use NULL as-is.
3041
3042 clrrdi(tmp1, value, JNIHandles::weak_tag_size);
3043 #if INCLUDE_ALL_GCS
3044 if (UseG1GC) { andi_(tmp2, value, JNIHandles::weak_tag_mask); }
3045 #endif
3046 ld(value, 0, tmp1); // Resolve (untagged) jobject.
3047
3048 #if INCLUDE_ALL_GCS
3049 if (UseG1GC) {
3050 Label not_weak;
3051 beq(CCR0, not_weak); // Test for jweak tag.
3052 verify_oop(value);
3053 g1_write_barrier_pre(noreg, // obj
3054 noreg, // offset
3055 value, // pre_val
3056 tmp1, tmp2, needs_frame);
3057 bind(not_weak);
3058 }
3059 #endif // INCLUDE_ALL_GCS
3060 verify_oop(value);
3061 bind(done);
3062 }
3063
3064 #if INCLUDE_ALL_GCS
3065 // General G1 pre-barrier generator.
3066 // Goal: record the previous value if it is not null.
3067 void MacroAssembler::g1_write_barrier_pre(Register Robj, RegisterOrConstant offset, Register Rpre_val,
3068 Register Rtmp1, Register Rtmp2, bool needs_frame) {
3069 Label runtime, filtered;
3070
3071 // Is marking active?
3072 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
3073 lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
3074 } else {
3075 guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
3076 lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
3077 }
3078 cmpdi(CCR0, Rtmp1, 0);
3079 beq(CCR0, filtered);
3080
3081 // Do we need to load the previous value?
3082 if (Robj != noreg) {
3083 // Load the previous value...
3105
3106 // Can we store original value in the thread's buffer?
3107 // Is index == 0?
3108 // (The index field is typed as size_t.)
3109 const Register Rbuffer = Rtmp1, Rindex = Rtmp2;
3110
3111 ld(Rindex, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_index()), R16_thread);
3112 cmpdi(CCR0, Rindex, 0);
3113 beq(CCR0, runtime); // If index == 0, goto runtime.
3114 ld(Rbuffer, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_buf()), R16_thread);
3115
3116 addi(Rindex, Rindex, -wordSize); // Decrement index.
3117 std(Rindex, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_index()), R16_thread);
3118
3119 // Record the previous value.
3120 stdx(Rpre_val, Rbuffer, Rindex);
3121 b(filtered);
3122
3123 bind(runtime);
3124
3125 // May need to preserve LR. Also needed if current frame is not compatible with C calling convention.
3126 if (needs_frame) {
3127 save_LR_CR(Rtmp1);
3128 push_frame_reg_args(0, Rtmp2);
3129 }
3130
3131 if (Rpre_val->is_volatile() && Robj == noreg) mr(R31, Rpre_val); // Save pre_val across C call if it was preloaded.
3132 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), Rpre_val, R16_thread);
3133 if (Rpre_val->is_volatile() && Robj == noreg) mr(Rpre_val, R31); // restore
3134
3135 if (needs_frame) {
3136 pop_frame();
3137 restore_LR_CR(Rtmp1);
3138 }
3139
3140 bind(filtered);
3141 }
3142
3143 // General G1 post-barrier generator
3144 // Store cross-region card.
3145 void MacroAssembler::g1_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp1, Register Rtmp2, Register Rtmp3, Label *filtered_ext) {
|
1 /*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
3016 barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
3017 assert(bs->kind() == BarrierSet::CardTableForRS ||
3018 bs->kind() == BarrierSet::CardTableExtension, "wrong barrier");
3019 #ifdef ASSERT
3020 cmpdi(CCR0, Rnew_val, 0);
3021 asm_assert_ne("null oop not allowed", 0x321);
3022 #endif
3023 card_table_write(bs->byte_map_base, Rtmp, Rstore_addr);
3024 }
3025
3026 // Write the card table byte.
3027 void MacroAssembler::card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj) {
3028 assert_different_registers(Robj, Rtmp, R0);
3029 load_const_optimized(Rtmp, (address)byte_map_base, R0);
3030 srdi(Robj, Robj, CardTableModRefBS::card_shift);
3031 li(R0, 0); // dirty
3032 if (UseConcMarkSweepGC) membar(Assembler::StoreStore);
3033 stbx(R0, Rtmp, Robj);
3034 }
3035
3036 #if INCLUDE_ALL_GCS
3037 // General G1 pre-barrier generator.
3038 // Goal: record the previous value if it is not null.
3039 void MacroAssembler::g1_write_barrier_pre(Register Robj, RegisterOrConstant offset, Register Rpre_val,
3040 Register Rtmp1, Register Rtmp2, bool needs_frame) {
3041 Label runtime, filtered;
3042
3043 // Is marking active?
3044 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
3045 lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
3046 } else {
3047 guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
3048 lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
3049 }
3050 cmpdi(CCR0, Rtmp1, 0);
3051 beq(CCR0, filtered);
3052
3053 // Do we need to load the previous value?
3054 if (Robj != noreg) {
3055 // Load the previous value...
3077
3078 // Can we store original value in the thread's buffer?
3079 // Is index == 0?
3080 // (The index field is typed as size_t.)
3081 const Register Rbuffer = Rtmp1, Rindex = Rtmp2;
3082
3083 ld(Rindex, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_index()), R16_thread);
3084 cmpdi(CCR0, Rindex, 0);
3085 beq(CCR0, runtime); // If index == 0, goto runtime.
3086 ld(Rbuffer, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_buf()), R16_thread);
3087
3088 addi(Rindex, Rindex, -wordSize); // Decrement index.
3089 std(Rindex, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_index()), R16_thread);
3090
3091 // Record the previous value.
3092 stdx(Rpre_val, Rbuffer, Rindex);
3093 b(filtered);
3094
3095 bind(runtime);
3096
3097 // VM call need frame to access(write) O register.
3098 if (needs_frame) {
3099 save_LR_CR(Rtmp1);
3100 push_frame_reg_args(0, Rtmp2);
3101 }
3102
3103 if (Rpre_val->is_volatile() && Robj == noreg) mr(R31, Rpre_val); // Save pre_val across C call if it was preloaded.
3104 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), Rpre_val, R16_thread);
3105 if (Rpre_val->is_volatile() && Robj == noreg) mr(Rpre_val, R31); // restore
3106
3107 if (needs_frame) {
3108 pop_frame();
3109 restore_LR_CR(Rtmp1);
3110 }
3111
3112 bind(filtered);
3113 }
3114
3115 // General G1 post-barrier generator
3116 // Store cross-region card.
3117 void MacroAssembler::g1_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp1, Register Rtmp2, Register Rtmp3, Label *filtered_ext) {
|