src/cpu/sparc/vm/bytecodeInterpreter_sparc.inline.hpp

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 6876
710a3c8b516e
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) 2002, 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 #ifndef CPU_SPARC_VM_BYTECODEINTERPRETER_SPARC_INLINE_HPP
stefank@2314 26 #define CPU_SPARC_VM_BYTECODEINTERPRETER_SPARC_INLINE_HPP
stefank@2314 27
duke@435 28 // Inline interpreter functions for sparc
duke@435 29
duke@435 30 inline jfloat BytecodeInterpreter::VMfloatAdd(jfloat op1, jfloat op2) { return op1 + op2; }
duke@435 31 inline jfloat BytecodeInterpreter::VMfloatSub(jfloat op1, jfloat op2) { return op1 - op2; }
duke@435 32 inline jfloat BytecodeInterpreter::VMfloatMul(jfloat op1, jfloat op2) { return op1 * op2; }
duke@435 33 inline jfloat BytecodeInterpreter::VMfloatDiv(jfloat op1, jfloat op2) { return op1 / op2; }
duke@435 34 inline jfloat BytecodeInterpreter::VMfloatRem(jfloat op1, jfloat op2) { return fmod(op1, op2); }
duke@435 35
duke@435 36 inline jfloat BytecodeInterpreter::VMfloatNeg(jfloat op) { return -op; }
duke@435 37
duke@435 38 inline int32_t BytecodeInterpreter::VMfloatCompare(jfloat op1, jfloat op2, int32_t direction) {
duke@435 39 return ( op1 < op2 ? -1 :
duke@435 40 op1 > op2 ? 1 :
duke@435 41 op1 == op2 ? 0 :
duke@435 42 (direction == -1 || direction == 1) ? direction : 0);
duke@435 43
duke@435 44 }
duke@435 45
duke@435 46 inline void BytecodeInterpreter::VMmemCopy64(uint32_t to[2], const uint32_t from[2]) {
duke@435 47 // x86 can do unaligned copies but not 64bits at a time
duke@435 48 to[0] = from[0]; to[1] = from[1];
duke@435 49 }
duke@435 50
duke@435 51 // The long operations depend on compiler support for "long long" on x86
duke@435 52
duke@435 53 inline jlong BytecodeInterpreter::VMlongAdd(jlong op1, jlong op2) {
duke@435 54 return op1 + op2;
duke@435 55 }
duke@435 56
duke@435 57 inline jlong BytecodeInterpreter::VMlongAnd(jlong op1, jlong op2) {
duke@435 58 return op1 & op2;
duke@435 59 }
duke@435 60
duke@435 61 inline jlong BytecodeInterpreter::VMlongDiv(jlong op1, jlong op2) {
duke@435 62 // QQQ what about check and throw...
duke@435 63 return op1 / op2;
duke@435 64 }
duke@435 65
duke@435 66 inline jlong BytecodeInterpreter::VMlongMul(jlong op1, jlong op2) {
duke@435 67 return op1 * op2;
duke@435 68 }
duke@435 69
duke@435 70 inline jlong BytecodeInterpreter::VMlongOr(jlong op1, jlong op2) {
duke@435 71 return op1 | op2;
duke@435 72 }
duke@435 73
duke@435 74 inline jlong BytecodeInterpreter::VMlongSub(jlong op1, jlong op2) {
duke@435 75 return op1 - op2;
duke@435 76 }
duke@435 77
duke@435 78 inline jlong BytecodeInterpreter::VMlongXor(jlong op1, jlong op2) {
duke@435 79 return op1 ^ op2;
duke@435 80 }
duke@435 81
duke@435 82 inline jlong BytecodeInterpreter::VMlongRem(jlong op1, jlong op2) {
duke@435 83 return op1 % op2;
duke@435 84 }
duke@435 85
duke@435 86 inline jlong BytecodeInterpreter::VMlongUshr(jlong op1, jint op2) {
duke@435 87 // CVM did this 0x3f mask, is the really needed??? QQQ
duke@435 88 return ((unsigned long long) op1) >> (op2 & 0x3F);
duke@435 89 }
duke@435 90
duke@435 91 inline jlong BytecodeInterpreter::VMlongShr(jlong op1, jint op2) {
duke@435 92 return op1 >> (op2 & 0x3F);
duke@435 93 }
duke@435 94
duke@435 95 inline jlong BytecodeInterpreter::VMlongShl(jlong op1, jint op2) {
duke@435 96 return op1 << (op2 & 0x3F);
duke@435 97 }
duke@435 98
duke@435 99 inline jlong BytecodeInterpreter::VMlongNeg(jlong op) {
duke@435 100 return -op;
duke@435 101 }
duke@435 102
duke@435 103 inline jlong BytecodeInterpreter::VMlongNot(jlong op) {
duke@435 104 return ~op;
duke@435 105 }
duke@435 106
duke@435 107 inline int32_t BytecodeInterpreter::VMlongLtz(jlong op) {
duke@435 108 return (op <= 0);
duke@435 109 }
duke@435 110
duke@435 111 inline int32_t BytecodeInterpreter::VMlongGez(jlong op) {
duke@435 112 return (op >= 0);
duke@435 113 }
duke@435 114
duke@435 115 inline int32_t BytecodeInterpreter::VMlongEqz(jlong op) {
duke@435 116 return (op == 0);
duke@435 117 }
duke@435 118
duke@435 119 inline int32_t BytecodeInterpreter::VMlongEq(jlong op1, jlong op2) {
duke@435 120 return (op1 == op2);
duke@435 121 }
duke@435 122
duke@435 123 inline int32_t BytecodeInterpreter::VMlongNe(jlong op1, jlong op2) {
duke@435 124 return (op1 != op2);
duke@435 125 }
duke@435 126
duke@435 127 inline int32_t BytecodeInterpreter::VMlongGe(jlong op1, jlong op2) {
duke@435 128 return (op1 >= op2);
duke@435 129 }
duke@435 130
duke@435 131 inline int32_t BytecodeInterpreter::VMlongLe(jlong op1, jlong op2) {
duke@435 132 return (op1 <= op2);
duke@435 133 }
duke@435 134
duke@435 135 inline int32_t BytecodeInterpreter::VMlongLt(jlong op1, jlong op2) {
duke@435 136 return (op1 < op2);
duke@435 137 }
duke@435 138
duke@435 139 inline int32_t BytecodeInterpreter::VMlongGt(jlong op1, jlong op2) {
duke@435 140 return (op1 > op2);
duke@435 141 }
duke@435 142
duke@435 143 inline int32_t BytecodeInterpreter::VMlongCompare(jlong op1, jlong op2) {
duke@435 144 return (VMlongLt(op1, op2) ? -1 : VMlongGt(op1, op2) ? 1 : 0);
duke@435 145 }
duke@435 146
duke@435 147 // Long conversions
duke@435 148
duke@435 149 inline jdouble BytecodeInterpreter::VMlong2Double(jlong val) {
duke@435 150 return (jdouble) val;
duke@435 151 }
duke@435 152
duke@435 153 inline jfloat BytecodeInterpreter::VMlong2Float(jlong val) {
duke@435 154 return (jfloat) val;
duke@435 155 }
duke@435 156
duke@435 157 inline jint BytecodeInterpreter::VMlong2Int(jlong val) {
duke@435 158 return (jint) val;
duke@435 159 }
duke@435 160
duke@435 161 // Double Arithmetic
duke@435 162
duke@435 163 inline jdouble BytecodeInterpreter::VMdoubleAdd(jdouble op1, jdouble op2) {
duke@435 164 return op1 + op2;
duke@435 165 }
duke@435 166
duke@435 167 inline jdouble BytecodeInterpreter::VMdoubleDiv(jdouble op1, jdouble op2) {
duke@435 168 // Divide by zero... QQQ
duke@435 169 return op1 / op2;
duke@435 170 }
duke@435 171
duke@435 172 inline jdouble BytecodeInterpreter::VMdoubleMul(jdouble op1, jdouble op2) {
duke@435 173 return op1 * op2;
duke@435 174 }
duke@435 175
duke@435 176 inline jdouble BytecodeInterpreter::VMdoubleNeg(jdouble op) {
duke@435 177 return -op;
duke@435 178 }
duke@435 179
duke@435 180 inline jdouble BytecodeInterpreter::VMdoubleRem(jdouble op1, jdouble op2) {
duke@435 181 return fmod(op1, op2);
duke@435 182 }
duke@435 183
duke@435 184 inline jdouble BytecodeInterpreter::VMdoubleSub(jdouble op1, jdouble op2) {
duke@435 185 return op1 - op2;
duke@435 186 }
duke@435 187
duke@435 188 inline int32_t BytecodeInterpreter::VMdoubleCompare(jdouble op1, jdouble op2, int32_t direction) {
duke@435 189 return ( op1 < op2 ? -1 :
duke@435 190 op1 > op2 ? 1 :
duke@435 191 op1 == op2 ? 0 :
duke@435 192 (direction == -1 || direction == 1) ? direction : 0);
duke@435 193 }
duke@435 194
duke@435 195 // Double Conversions
duke@435 196
duke@435 197 inline jfloat BytecodeInterpreter::VMdouble2Float(jdouble val) {
duke@435 198 return (jfloat) val;
duke@435 199 }
duke@435 200
duke@435 201 // Float Conversions
duke@435 202
duke@435 203 inline jdouble BytecodeInterpreter::VMfloat2Double(jfloat op) {
duke@435 204 return (jdouble) op;
duke@435 205 }
duke@435 206
duke@435 207 // Integer Arithmetic
duke@435 208
duke@435 209 inline jint BytecodeInterpreter::VMintAdd(jint op1, jint op2) {
duke@435 210 return op1 + op2;
duke@435 211 }
duke@435 212
duke@435 213 inline jint BytecodeInterpreter::VMintAnd(jint op1, jint op2) {
duke@435 214 return op1 & op2;
duke@435 215 }
duke@435 216
duke@435 217 inline jint BytecodeInterpreter::VMintDiv(jint op1, jint op2) {
duke@435 218 /* it's possible we could catch this special case implicitly */
duke@435 219 if (op1 == 0x80000000 && op2 == -1) return op1;
duke@435 220 else return op1 / op2;
duke@435 221 }
duke@435 222
duke@435 223 inline jint BytecodeInterpreter::VMintMul(jint op1, jint op2) {
duke@435 224 return op1 * op2;
duke@435 225 }
duke@435 226
duke@435 227 inline jint BytecodeInterpreter::VMintNeg(jint op) {
duke@435 228 return -op;
duke@435 229 }
duke@435 230
duke@435 231 inline jint BytecodeInterpreter::VMintOr(jint op1, jint op2) {
duke@435 232 return op1 | op2;
duke@435 233 }
duke@435 234
duke@435 235 inline jint BytecodeInterpreter::VMintRem(jint op1, jint op2) {
duke@435 236 /* it's possible we could catch this special case implicitly */
duke@435 237 if (op1 == 0x80000000 && op2 == -1) return 0;
duke@435 238 else return op1 % op2;
duke@435 239 }
duke@435 240
duke@435 241 inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) {
bobv@2036 242 return op1 << (op2 & 0x1f);
duke@435 243 }
duke@435 244
duke@435 245 inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) {
bobv@2036 246 return op1 >> (op2 & 0x1f);
duke@435 247 }
duke@435 248
duke@435 249 inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) {
duke@435 250 return op1 - op2;
duke@435 251 }
duke@435 252
bobv@2036 253 inline juint BytecodeInterpreter::VMintUshr(jint op1, jint op2) {
bobv@2036 254 return ((juint) op1) >> (op2 & 0x1f);
duke@435 255 }
duke@435 256
duke@435 257 inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) {
duke@435 258 return op1 ^ op2;
duke@435 259 }
duke@435 260
duke@435 261 inline jdouble BytecodeInterpreter::VMint2Double(jint val) {
duke@435 262 return (jdouble) val;
duke@435 263 }
duke@435 264
duke@435 265 inline jfloat BytecodeInterpreter::VMint2Float(jint val) {
duke@435 266 return (jfloat) val;
duke@435 267 }
duke@435 268
duke@435 269 inline jlong BytecodeInterpreter::VMint2Long(jint val) {
duke@435 270 return (jlong) val;
duke@435 271 }
duke@435 272
duke@435 273 inline jchar BytecodeInterpreter::VMint2Char(jint val) {
duke@435 274 return (jchar) val;
duke@435 275 }
duke@435 276
duke@435 277 inline jshort BytecodeInterpreter::VMint2Short(jint val) {
duke@435 278 return (jshort) val;
duke@435 279 }
duke@435 280
duke@435 281 inline jbyte BytecodeInterpreter::VMint2Byte(jint val) {
duke@435 282 return (jbyte) val;
duke@435 283 }
duke@435 284
duke@435 285 // The implementations are platform dependent. We have to worry about alignment
duke@435 286 // issues on some machines which can change on the same platform depending on
duke@435 287 // whether it is an LP64 machine also.
duke@435 288
duke@435 289 // We know that on LP32 mode that longs/doubles are the only thing that gives
duke@435 290 // us alignment headaches. We also know that the worst we have is 32bit alignment
duke@435 291 // so thing are not really too bad.
duke@435 292 // (Also sparcworks compiler does the right thing for free if we don't use -arch..
duke@435 293 // switches. Only gcc gives us a hard time. In LP64 mode I think we have no issue
duke@435 294 // with alignment.
duke@435 295
duke@435 296 #ifdef _GNU_SOURCE
duke@435 297 #define ALIGN_CONVERTER /* Needs alignment converter */
duke@435 298 #else
duke@435 299 #undef ALIGN_CONVERTER /* No alignment converter */
duke@435 300 #endif /* _GNU_SOURCE */
duke@435 301
duke@435 302 #ifdef ALIGN_CONVERTER
duke@435 303 class u8_converter {
duke@435 304
duke@435 305 private:
duke@435 306
duke@435 307 public:
duke@435 308 static jdouble get_jdouble(address p) {
duke@435 309 VMJavaVal64 tmp;
duke@435 310 tmp.v[0] = ((uint32_t*)p)[0];
duke@435 311 tmp.v[1] = ((uint32_t*)p)[1];
duke@435 312 return tmp.d;
duke@435 313 }
duke@435 314
duke@435 315 static void put_jdouble(address p, jdouble d) {
duke@435 316 VMJavaVal64 tmp;
duke@435 317 tmp.d = d;
duke@435 318 ((uint32_t*)p)[0] = tmp.v[0];
duke@435 319 ((uint32_t*)p)[1] = tmp.v[1];
duke@435 320 }
duke@435 321
duke@435 322 static jlong get_jlong(address p) {
duke@435 323 VMJavaVal64 tmp;
duke@435 324 tmp.v[0] = ((uint32_t*)p)[0];
duke@435 325 tmp.v[1] = ((uint32_t*)p)[1];
duke@435 326 return tmp.l;
duke@435 327 }
duke@435 328
duke@435 329 static void put_jlong(address p, jlong l) {
duke@435 330 VMJavaVal64 tmp;
duke@435 331 tmp.l = l;
duke@435 332 ((uint32_t*)p)[0] = tmp.v[0];
duke@435 333 ((uint32_t*)p)[1] = tmp.v[1];
duke@435 334 }
duke@435 335 };
duke@435 336 #endif /* ALIGN_CONVERTER */
stefank@2314 337
stefank@2314 338 #endif // CPU_SPARC_VM_BYTECODEINTERPRETER_SPARC_INLINE_HPP

mercurial