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

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

mercurial