src/share/vm/oops/typeArrayOop.hpp

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

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2508
b92c45f2bc75
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

     1 /*
     2  * Copyright (c) 1997, 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 SHARE_VM_OOPS_TYPEARRAYOOP_HPP
    26 #define SHARE_VM_OOPS_TYPEARRAYOOP_HPP
    28 #include "oops/arrayOop.hpp"
    29 #include "oops/typeArrayKlass.hpp"
    30 #ifdef TARGET_OS_ARCH_linux_x86
    31 # include "orderAccess_linux_x86.inline.hpp"
    32 #endif
    33 #ifdef TARGET_OS_ARCH_linux_sparc
    34 # include "orderAccess_linux_sparc.inline.hpp"
    35 #endif
    36 #ifdef TARGET_OS_ARCH_linux_zero
    37 # include "orderAccess_linux_zero.inline.hpp"
    38 #endif
    39 #ifdef TARGET_OS_ARCH_solaris_x86
    40 # include "orderAccess_solaris_x86.inline.hpp"
    41 #endif
    42 #ifdef TARGET_OS_ARCH_solaris_sparc
    43 # include "orderAccess_solaris_sparc.inline.hpp"
    44 #endif
    45 #ifdef TARGET_OS_ARCH_windows_x86
    46 # include "orderAccess_windows_x86.inline.hpp"
    47 #endif
    48 #ifdef TARGET_OS_ARCH_linux_arm
    49 # include "orderAccess_linux_arm.inline.hpp"
    50 #endif
    51 #ifdef TARGET_OS_ARCH_linux_ppc
    52 # include "orderAccess_linux_ppc.inline.hpp"
    53 #endif
    55 // A typeArrayOop is an array containing basic types (non oop elements).
    56 // It is used for arrays of {characters, singles, doubles, bytes, shorts, integers, longs}
    57 #include <limits.h>
    59 class typeArrayOopDesc : public arrayOopDesc {
    60  protected:
    61   jchar*    char_base()   const { return (jchar*)   base(T_CHAR); }
    62   jboolean* bool_base()   const { return (jboolean*)base(T_BOOLEAN); }
    63   jbyte*    byte_base()   const { return (jbyte*)   base(T_BYTE); }
    64   jint*     int_base()    const { return (jint*)    base(T_INT); }
    65   jlong*    long_base()   const { return (jlong*)   base(T_LONG); }
    66   jshort*   short_base()  const { return (jshort*)  base(T_SHORT); }
    67   jfloat*   float_base()  const { return (jfloat*)  base(T_FLOAT); }
    68   jdouble*  double_base() const { return (jdouble*) base(T_DOUBLE); }
    70   friend class typeArrayKlass;
    72  public:
    73   jbyte* byte_at_addr(int which) const {
    74     assert(is_within_bounds(which), "index out of bounds");
    75     return &byte_base()[which];
    76   }
    78   jboolean* bool_at_addr(int which) const {
    79     assert(is_within_bounds(which), "index out of bounds");
    80     return &bool_base()[which];
    81   }
    83   jchar* char_at_addr(int which) const {
    84     assert(is_within_bounds(which), "index out of bounds");
    85     return &char_base()[which];
    86   }
    88   jint* int_at_addr(int which) const {
    89     assert(is_within_bounds(which), "index out of bounds");
    90     return &int_base()[which];
    91   }
    93   jshort* short_at_addr(int which) const {
    94     assert(is_within_bounds(which), "index out of bounds");
    95     return &short_base()[which];
    96   }
    98   jushort* ushort_at_addr(int which) const {  // for field descriptor arrays
    99     assert(is_within_bounds(which), "index out of bounds");
   100     return (jushort*) &short_base()[which];
   101   }
   103   jlong* long_at_addr(int which) const {
   104     assert(is_within_bounds(which), "index out of bounds");
   105     return &long_base()[which];
   106   }
   108   jfloat* float_at_addr(int which) const {
   109     assert(is_within_bounds(which), "index out of bounds");
   110     return &float_base()[which];
   111   }
   113   jdouble* double_at_addr(int which) const {
   114     assert(is_within_bounds(which), "index out of bounds");
   115     return &double_base()[which];
   116   }
   118   jbyte byte_at(int which) const                  { return *byte_at_addr(which); }
   119   void byte_at_put(int which, jbyte contents)     { *byte_at_addr(which) = contents; }
   121   jboolean bool_at(int which) const               { return *bool_at_addr(which); }
   122   void bool_at_put(int which, jboolean contents)  { *bool_at_addr(which) = contents; }
   124   jchar char_at(int which) const                  { return *char_at_addr(which); }
   125   void char_at_put(int which, jchar contents)     { *char_at_addr(which) = contents; }
   127   jint int_at(int which) const                    { return *int_at_addr(which); }
   128   void int_at_put(int which, jint contents)       { *int_at_addr(which) = contents; }
   130   jshort short_at(int which) const                { return *short_at_addr(which); }
   131   void short_at_put(int which, jshort contents)   { *short_at_addr(which) = contents; }
   133   jushort ushort_at(int which) const              { return *ushort_at_addr(which); }
   134   void ushort_at_put(int which, jushort contents) { *ushort_at_addr(which) = contents; }
   136   jlong long_at(int which) const                  { return *long_at_addr(which); }
   137   void long_at_put(int which, jlong contents)     { *long_at_addr(which) = contents; }
   139   jfloat float_at(int which) const                { return *float_at_addr(which); }
   140   void float_at_put(int which, jfloat contents)   { *float_at_addr(which) = contents; }
   142   jdouble double_at(int which) const              { return *double_at_addr(which); }
   143   void double_at_put(int which, jdouble contents) { *double_at_addr(which) = contents; }
   145   jbyte byte_at_acquire(int which) const              { return OrderAccess::load_acquire(byte_at_addr(which)); }
   146   void release_byte_at_put(int which, jbyte contents) { OrderAccess::release_store(byte_at_addr(which), contents); }
   148   // Sizing
   150   // Returns the number of words necessary to hold an array of "len"
   151   // elements each of the given "byte_size".
   152  private:
   153   static int object_size(int lh, int length) {
   154     int instance_header_size = Klass::layout_helper_header_size(lh);
   155     int element_shift = Klass::layout_helper_log2_element_size(lh);
   156     DEBUG_ONLY(BasicType etype = Klass::layout_helper_element_type(lh));
   157     assert(length <= arrayOopDesc::max_array_length(etype), "no overflow");
   159     julong size_in_bytes = length;
   160     size_in_bytes <<= element_shift;
   161     size_in_bytes += instance_header_size;
   162     julong size_in_words = ((size_in_bytes + (HeapWordSize-1)) >> LogHeapWordSize);
   163     assert(size_in_words <= (julong)max_jint, "no overflow");
   165     return align_object_size((intptr_t)size_in_words);
   166   }
   168  public:
   169   int object_size() {
   170     typeArrayKlass* tk = typeArrayKlass::cast(klass());
   171     return object_size(tk->layout_helper(), length());
   172   }
   173 };
   175 #endif // SHARE_VM_OOPS_TYPEARRAYOOP_HPP

mercurial