Thu, 07 Apr 2011 09:53:20 -0700
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
1 /*
2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
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 */
25 #include "precompiled.hpp"
26 #include "interpreter/interpreter.hpp"
27 #include "interpreter/interpreterRuntime.hpp"
28 #include "memory/allocation.inline.hpp"
29 #include "memory/universe.inline.hpp"
30 #include "oops/methodOop.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "runtime/handles.inline.hpp"
33 #include "runtime/icache.hpp"
34 #include "runtime/interfaceSupport.hpp"
35 #include "runtime/signature.hpp"
38 #define __ _masm->
41 // Implementation of SignatureHandlerGenerator
43 void InterpreterRuntime::SignatureHandlerGenerator::pass_word(int size_of_arg, int offset_in_arg) {
44 Argument jni_arg(jni_offset() + offset_in_arg, false);
45 Register Rtmp = O0;
46 __ ld(Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp);
48 __ store_argument(Rtmp, jni_arg);
49 }
51 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
52 Argument jni_arg(jni_offset(), false);
53 Register Rtmp = O0;
55 #ifdef _LP64
56 __ ldx(Llocals, Interpreter::local_offset_in_bytes(offset() + 1), Rtmp);
57 __ store_long_argument(Rtmp, jni_arg);
58 #else
59 __ ld(Llocals, Interpreter::local_offset_in_bytes(offset() + 1), Rtmp);
60 __ store_argument(Rtmp, jni_arg);
61 __ ld(Llocals, Interpreter::local_offset_in_bytes(offset() + 0), Rtmp);
62 Argument successor(jni_arg.successor());
63 __ store_argument(Rtmp, successor);
64 #endif
65 }
68 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
69 Argument jni_arg(jni_offset(), false);
70 #ifdef _LP64
71 FloatRegister Rtmp = F0;
72 __ ldf(FloatRegisterImpl::S, Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp);
73 __ store_float_argument(Rtmp, jni_arg);
74 #else
75 Register Rtmp = O0;
76 __ ld(Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp);
77 __ store_argument(Rtmp, jni_arg);
78 #endif
79 }
82 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
83 Argument jni_arg(jni_offset(), false);
84 #ifdef _LP64
85 FloatRegister Rtmp = F0;
86 __ ldf(FloatRegisterImpl::D, Llocals, Interpreter::local_offset_in_bytes(offset() + 1), Rtmp);
87 __ store_double_argument(Rtmp, jni_arg);
88 #else
89 Register Rtmp = O0;
90 __ ld(Llocals, Interpreter::local_offset_in_bytes(offset() + 1), Rtmp);
91 __ store_argument(Rtmp, jni_arg);
92 __ ld(Llocals, Interpreter::local_offset_in_bytes(offset()), Rtmp);
93 Argument successor(jni_arg.successor());
94 __ store_argument(Rtmp, successor);
95 #endif
96 }
98 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
99 Argument jni_arg(jni_offset(), false);
100 Argument java_arg( offset(), true);
101 Register Rtmp1 = O0;
102 Register Rtmp2 = jni_arg.is_register() ? jni_arg.as_register() : O0;
103 Register Rtmp3 = G3_scratch;
105 // the handle for a receiver will never be null
106 bool do_NULL_check = offset() != 0 || is_static();
108 Address h_arg = Address(Llocals, Interpreter::local_offset_in_bytes(offset()));
109 __ ld_ptr(h_arg, Rtmp1);
110 if (!do_NULL_check) {
111 __ add(h_arg.base(), h_arg.disp(), Rtmp2);
112 } else {
113 if (Rtmp1 == Rtmp2)
114 __ tst(Rtmp1);
115 else __ addcc(G0, Rtmp1, Rtmp2); // optimize mov/test pair
116 Label L;
117 __ brx(Assembler::notZero, true, Assembler::pt, L);
118 __ delayed()->add(h_arg.base(), h_arg.disp(), Rtmp2);
119 __ bind(L);
120 }
121 __ store_ptr_argument(Rtmp2, jni_arg); // this is often a no-op
122 }
125 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
127 // generate code to handle arguments
128 iterate(fingerprint);
130 // return result handler
131 AddressLiteral result_handler(Interpreter::result_handler(method()->result_type()));
132 __ sethi(result_handler, Lscratch);
133 __ retl();
134 __ delayed()->add(Lscratch, result_handler.low10(), Lscratch);
136 __ flush();
137 }
140 // Implementation of SignatureHandlerLibrary
142 void SignatureHandlerLibrary::pd_set_handler(address handler) {}
145 class SlowSignatureHandler: public NativeSignatureIterator {
146 private:
147 address _from;
148 intptr_t* _to;
149 intptr_t* _RegArgSignature; // Signature of first Arguments to be passed in Registers
150 uint _argcount;
152 enum { // We need to differenciate float from non floats in reg args
153 non_float = 0,
154 float_sig = 1,
155 double_sig = 2,
156 long_sig = 3
157 };
159 virtual void pass_int() {
160 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
161 _from -= Interpreter::stackElementSize;
162 add_signature( non_float );
163 }
165 virtual void pass_object() {
166 // pass address of from
167 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
168 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
169 _from -= Interpreter::stackElementSize;
170 add_signature( non_float );
171 }
173 #ifdef _LP64
174 virtual void pass_float() {
175 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
176 _from -= Interpreter::stackElementSize;
177 add_signature( float_sig );
178 }
180 virtual void pass_double() {
181 *_to++ = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
182 _from -= 2*Interpreter::stackElementSize;
183 add_signature( double_sig );
184 }
186 virtual void pass_long() {
187 _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
188 _to += 1;
189 _from -= 2*Interpreter::stackElementSize;
190 add_signature( long_sig );
191 }
192 #else
193 // pass_double() is pass_long() and pass_float() only _LP64
194 virtual void pass_long() {
195 _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
196 _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
197 _to += 2;
198 _from -= 2*Interpreter::stackElementSize;
199 add_signature( non_float );
200 }
202 virtual void pass_float() {
203 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
204 _from -= Interpreter::stackElementSize;
205 add_signature( non_float );
206 }
208 #endif // _LP64
210 virtual void add_signature( intptr_t sig_type ) {
211 if ( _argcount < (sizeof (intptr_t))*4 ) {
212 *_RegArgSignature |= (sig_type << (_argcount*2) );
213 _argcount++;
214 }
215 }
218 public:
219 SlowSignatureHandler(methodHandle method, address from, intptr_t* to, intptr_t *RegArgSig) : NativeSignatureIterator(method) {
220 _from = from;
221 _to = to;
222 _RegArgSignature = RegArgSig;
223 *_RegArgSignature = 0;
224 _argcount = method->is_static() ? 2 : 1;
225 }
226 };
229 IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(
230 JavaThread* thread,
231 methodOopDesc* method,
232 intptr_t* from,
233 intptr_t* to ))
234 methodHandle m(thread, method);
235 assert(m->is_native(), "sanity check");
236 // handle arguments
237 // Warning: We use reg arg slot 00 temporarily to return the RegArgSignature
238 // back to the code that pops the arguments into the CPU registers
239 SlowSignatureHandler(m, (address)from, m->is_static() ? to+2 : to+1, to).iterate(UCONST64(-1));
240 // return result handler
241 return Interpreter::result_handler(m->result_type());
242 IRT_END