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

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

mercurial