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

mercurial