src/cpu/sparc/vm/relocInfo_sparc.cpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2657
d673ef06fe96
child 2708
1d1603768966
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

duke@435 1 /*
stefank@2314 2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #include "precompiled.hpp"
stefank@2314 26 #include "asm/assembler.inline.hpp"
stefank@2314 27 #include "assembler_sparc.inline.hpp"
stefank@2314 28 #include "code/relocInfo.hpp"
stefank@2314 29 #include "nativeInst_sparc.hpp"
stefank@2314 30 #include "oops/oop.inline.hpp"
stefank@2314 31 #include "runtime/safepoint.hpp"
duke@435 32
never@2657 33 void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
duke@435 34 NativeInstruction* ip = nativeInstruction_at(addr());
duke@435 35 jint inst = ip->long_at(0);
duke@435 36 assert(inst != NativeInstruction::illegal_instruction(), "no breakpoint");
duke@435 37 switch (Assembler::inv_op(inst)) {
duke@435 38
duke@435 39 case Assembler::ldst_op:
duke@435 40 #ifdef ASSERT
duke@435 41 switch (Assembler::inv_op3(inst)) {
duke@435 42 case Assembler::lduw_op3:
duke@435 43 case Assembler::ldub_op3:
duke@435 44 case Assembler::lduh_op3:
duke@435 45 case Assembler::ldd_op3:
duke@435 46 case Assembler::ldsw_op3:
duke@435 47 case Assembler::ldsb_op3:
duke@435 48 case Assembler::ldsh_op3:
duke@435 49 case Assembler::ldx_op3:
duke@435 50 case Assembler::ldf_op3:
duke@435 51 case Assembler::lddf_op3:
duke@435 52 case Assembler::stw_op3:
duke@435 53 case Assembler::stb_op3:
duke@435 54 case Assembler::sth_op3:
duke@435 55 case Assembler::std_op3:
duke@435 56 case Assembler::stx_op3:
duke@435 57 case Assembler::stf_op3:
duke@435 58 case Assembler::stdf_op3:
duke@435 59 case Assembler::casa_op3:
duke@435 60 case Assembler::casxa_op3:
duke@435 61 break;
duke@435 62 default:
duke@435 63 ShouldNotReachHere();
duke@435 64 }
duke@435 65 goto do_non_sethi;
duke@435 66 #endif
duke@435 67
duke@435 68 case Assembler::arith_op:
duke@435 69 #ifdef ASSERT
duke@435 70 switch (Assembler::inv_op3(inst)) {
duke@435 71 case Assembler::or_op3:
duke@435 72 case Assembler::add_op3:
duke@435 73 case Assembler::jmpl_op3:
duke@435 74 break;
duke@435 75 default:
duke@435 76 ShouldNotReachHere();
duke@435 77 }
duke@435 78 do_non_sethi:;
duke@435 79 #endif
duke@435 80 {
duke@435 81 guarantee(Assembler::inv_immed(inst), "must have a simm13 field");
duke@435 82 int simm13 = Assembler::low10((intptr_t)x) + o;
duke@435 83 guarantee(Assembler::is_simm13(simm13), "offset can't overflow simm13");
duke@435 84 inst &= ~Assembler::simm( -1, 13);
duke@435 85 inst |= Assembler::simm(simm13, 13);
never@2657 86 if (verify_only) {
never@2657 87 assert(ip->long_at(0) == inst, "instructions must match");
never@2657 88 } else {
never@2657 89 ip->set_long_at(0, inst);
never@2657 90 }
duke@435 91 }
duke@435 92 break;
duke@435 93
duke@435 94 case Assembler::branch_op:
duke@435 95 {
duke@435 96 #ifdef _LP64
duke@435 97 jint inst2;
duke@435 98 guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
kvn@599 99 if (format() != 0) {
kvn@599 100 assert(type() == relocInfo::oop_type, "only narrow oops case");
kvn@599 101 jint np = oopDesc::encode_heap_oop((oop)x);
kvn@599 102 inst &= ~Assembler::hi22(-1);
kvn@599 103 inst |= Assembler::hi22((intptr_t)np);
never@2657 104 if (verify_only) {
never@2657 105 assert(ip->long_at(0) == inst, "instructions must match");
never@2657 106 } else {
never@2657 107 ip->set_long_at(0, inst);
never@2657 108 }
kvn@599 109 inst2 = ip->long_at( NativeInstruction::nop_instruction_size );
kvn@599 110 guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op");
never@2657 111 if (verify_only) {
never@2657 112 assert(ip->long_at(NativeInstruction::nop_instruction_size) == NativeInstruction::set_data32_simm13( inst2, (intptr_t)np),
never@2657 113 "instructions must match");
never@2657 114 } else {
never@2657 115 ip->set_long_at(NativeInstruction::nop_instruction_size, NativeInstruction::set_data32_simm13( inst2, (intptr_t)np));
never@2657 116 }
kvn@599 117 break;
kvn@599 118 }
never@2657 119 if (verify_only) {
never@2657 120 ip->verify_data64_sethi( ip->addr_at(0), (intptr_t)x );
never@2657 121 } else {
never@2657 122 ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
never@2657 123 }
duke@435 124 #else
duke@435 125 guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
duke@435 126 inst &= ~Assembler::hi22( -1);
duke@435 127 inst |= Assembler::hi22((intptr_t)x);
duke@435 128 // (ignore offset; it doesn't play into the sethi)
never@2657 129 if (verify_only) {
never@2657 130 assert(ip->long_at(0) == inst, "instructions must match");
never@2657 131 } else {
never@2657 132 ip->set_long_at(0, inst);
never@2657 133 }
duke@435 134 #endif
duke@435 135 }
duke@435 136 break;
duke@435 137
duke@435 138 default:
duke@435 139 guarantee(false, "instruction must perform arithmetic or memory access");
duke@435 140 }
duke@435 141 }
duke@435 142
duke@435 143
duke@435 144 address Relocation::pd_call_destination(address orig_addr) {
duke@435 145 intptr_t adj = 0;
duke@435 146 if (orig_addr != NULL) {
duke@435 147 // We just moved this call instruction from orig_addr to addr().
duke@435 148 // This means its target will appear to have grown by addr() - orig_addr.
duke@435 149 adj = -( addr() - orig_addr );
duke@435 150 }
duke@435 151 if (NativeCall::is_call_at(addr())) {
duke@435 152 NativeCall* call = nativeCall_at(addr());
duke@435 153 return call->destination() + adj;
duke@435 154 }
duke@435 155 if (NativeFarCall::is_call_at(addr())) {
duke@435 156 NativeFarCall* call = nativeFarCall_at(addr());
duke@435 157 return call->destination() + adj;
duke@435 158 }
duke@435 159 // Special case: Patchable branch local to the code cache.
duke@435 160 // This will break badly if the code cache grows larger than a few Mb.
duke@435 161 NativeGeneralJump* br = nativeGeneralJump_at(addr());
duke@435 162 return br->jump_destination() + adj;
duke@435 163 }
duke@435 164
duke@435 165
duke@435 166 void Relocation::pd_set_call_destination(address x) {
duke@435 167 if (NativeCall::is_call_at(addr())) {
duke@435 168 NativeCall* call = nativeCall_at(addr());
duke@435 169 call->set_destination(x);
duke@435 170 return;
duke@435 171 }
duke@435 172 if (NativeFarCall::is_call_at(addr())) {
duke@435 173 NativeFarCall* call = nativeFarCall_at(addr());
duke@435 174 call->set_destination(x);
duke@435 175 return;
duke@435 176 }
duke@435 177 // Special case: Patchable branch local to the code cache.
duke@435 178 // This will break badly if the code cache grows larger than a few Mb.
duke@435 179 NativeGeneralJump* br = nativeGeneralJump_at(addr());
duke@435 180 br->set_jump_destination(x);
duke@435 181 }
duke@435 182
duke@435 183
duke@435 184 address* Relocation::pd_address_in_code() {
duke@435 185 // SPARC never embeds addresses in code, at present.
duke@435 186 //assert(type() == relocInfo::oop_type, "only oops are inlined at present");
duke@435 187 return (address*)addr();
duke@435 188 }
duke@435 189
duke@435 190
duke@435 191 address Relocation::pd_get_address_from_code() {
duke@435 192 // SPARC never embeds addresses in code, at present.
duke@435 193 //assert(type() == relocInfo::oop_type, "only oops are inlined at present");
duke@435 194 return *(address*)addr();
duke@435 195 }
duke@435 196
duke@435 197
duke@435 198 int Relocation::pd_breakpoint_size() {
duke@435 199 // minimum breakpoint size, in short words
duke@435 200 return NativeIllegalInstruction::instruction_size / sizeof(short);
duke@435 201 }
duke@435 202
duke@435 203 void Relocation::pd_swap_in_breakpoint(address x, short* instrs, int instrlen) {
duke@435 204 Untested("pd_swap_in_breakpoint");
duke@435 205 // %%% probably do not need a general instrlen; just use the trap size
duke@435 206 if (instrs != NULL) {
duke@435 207 assert(instrlen * sizeof(short) == NativeIllegalInstruction::instruction_size, "enough instrlen in reloc. data");
duke@435 208 for (int i = 0; i < instrlen; i++) {
duke@435 209 instrs[i] = ((short*)x)[i];
duke@435 210 }
duke@435 211 }
duke@435 212 NativeIllegalInstruction::insert(x);
duke@435 213 }
duke@435 214
duke@435 215
duke@435 216 void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) {
duke@435 217 Untested("pd_swap_out_breakpoint");
duke@435 218 assert(instrlen * sizeof(short) == sizeof(int), "enough buf");
duke@435 219 union { int l; short s[1]; } u;
duke@435 220 for (int i = 0; i < instrlen; i++) {
duke@435 221 u.s[i] = instrs[i];
duke@435 222 }
duke@435 223 NativeInstruction* ni = nativeInstruction_at(x);
duke@435 224 ni->set_long_at(0, u.l);
duke@435 225 }
never@739 226
never@739 227 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
never@739 228 }
never@739 229
never@739 230 void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
never@739 231 }

mercurial