src/cpu/sparc/vm/copy_sparc.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 3092
baf763f388e6
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) 2003, 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_COPY_SPARC_HPP
stefank@2314 26 #define CPU_SPARC_VM_COPY_SPARC_HPP
stefank@2314 27
duke@435 28 // Inline functions for memory copy and fill.
duke@435 29
duke@435 30 static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
duke@435 31 (void)memmove(to, from, count * HeapWordSize);
duke@435 32 }
duke@435 33
duke@435 34 static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
duke@435 35 switch (count) {
duke@435 36 case 8: to[7] = from[7];
duke@435 37 case 7: to[6] = from[6];
duke@435 38 case 6: to[5] = from[5];
duke@435 39 case 5: to[4] = from[4];
duke@435 40 case 4: to[3] = from[3];
duke@435 41 case 3: to[2] = from[2];
duke@435 42 case 2: to[1] = from[1];
duke@435 43 case 1: to[0] = from[0];
duke@435 44 case 0: break;
duke@435 45 default: (void)memcpy(to, from, count * HeapWordSize);
duke@435 46 break;
duke@435 47 }
duke@435 48 }
duke@435 49
duke@435 50 static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
duke@435 51 switch (count) {
duke@435 52 case 8: to[7] = from[7];
duke@435 53 case 7: to[6] = from[6];
duke@435 54 case 6: to[5] = from[5];
duke@435 55 case 5: to[4] = from[4];
duke@435 56 case 4: to[3] = from[3];
duke@435 57 case 3: to[2] = from[2];
duke@435 58 case 2: to[1] = from[1];
duke@435 59 case 1: to[0] = from[0];
duke@435 60 case 0: break;
duke@435 61 default: while (count-- > 0) {
duke@435 62 *to++ = *from++;
duke@435 63 }
duke@435 64 break;
duke@435 65 }
duke@435 66 }
duke@435 67
duke@435 68 static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
duke@435 69 (void)memmove(to, from, count * HeapWordSize);
duke@435 70 }
duke@435 71
duke@435 72 static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
duke@435 73 pd_disjoint_words(from, to, count);
duke@435 74 }
duke@435 75
duke@435 76 static void pd_conjoint_bytes(void* from, void* to, size_t count) {
duke@435 77 (void)memmove(to, from, count);
duke@435 78 }
duke@435 79
duke@435 80 static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
duke@435 81 (void)memmove(to, from, count);
duke@435 82 }
duke@435 83
duke@435 84 static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
duke@435 85 // FIXME
duke@435 86 (void)memmove(to, from, count << LogBytesPerShort);
duke@435 87 }
duke@435 88
duke@435 89 static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
duke@435 90 // FIXME
duke@435 91 (void)memmove(to, from, count << LogBytesPerInt);
duke@435 92 }
duke@435 93
duke@435 94 static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
duke@435 95 #ifdef _LP64
duke@435 96 assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
duke@435 97 pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
duke@435 98 #else
duke@435 99 // Guarantee use of ldd/std via some asm code, because compiler won't.
duke@435 100 // See solaris_sparc.il.
duke@435 101 _Copy_conjoint_jlongs_atomic(from, to, count);
duke@435 102 #endif
duke@435 103 }
duke@435 104
duke@435 105 static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
duke@435 106 // Do better than this: inline memmove body NEEDS CLEANUP
duke@435 107 if (from > to) {
duke@435 108 while (count-- > 0) {
duke@435 109 // Copy forwards
duke@435 110 *to++ = *from++;
duke@435 111 }
duke@435 112 } else {
duke@435 113 from += count - 1;
duke@435 114 to += count - 1;
duke@435 115 while (count-- > 0) {
duke@435 116 // Copy backwards
duke@435 117 *to-- = *from--;
duke@435 118 }
duke@435 119 }
duke@435 120 }
duke@435 121
duke@435 122 static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
duke@435 123 pd_conjoint_bytes_atomic(from, to, count);
duke@435 124 }
duke@435 125
duke@435 126 static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
duke@435 127 pd_conjoint_jshorts_atomic((jshort*)from, (jshort*)to, count);
duke@435 128 }
duke@435 129
duke@435 130 static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
duke@435 131 pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
duke@435 132 }
duke@435 133
duke@435 134 static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
duke@435 135 pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
duke@435 136 }
duke@435 137
duke@435 138 static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
duke@435 139 pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
duke@435 140 }
duke@435 141
duke@435 142 static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
coleenp@548 143 #ifdef _LP64
coleenp@548 144 guarantee(mask_bits((uintptr_t)tohw, right_n_bits(LogBytesPerLong)) == 0,
coleenp@548 145 "unaligned fill words");
coleenp@548 146 julong* to = (julong*)tohw;
coleenp@548 147 julong v = ((julong)value << 32) | value;
coleenp@548 148 while (count-- > 0) {
coleenp@548 149 *to++ = v;
coleenp@548 150 }
coleenp@548 151 #else // _LP64
coleenp@548 152 juint* to = (juint*)tohw;
coleenp@548 153 while (count-- > 0) {
coleenp@548 154 *to++ = value;
coleenp@548 155 }
coleenp@548 156 #endif // _LP64
duke@435 157 }
duke@435 158
duke@435 159 static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) {
kvn@1926 160 assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation");
duke@435 161
duke@435 162 julong* to = (julong*)tohw;
duke@435 163 julong v = ((julong)value << 32) | value;
duke@435 164 // If count is odd, odd will be equal to 1 on 32-bit platform
duke@435 165 // and be equal to 0 on 64-bit platform.
duke@435 166 size_t odd = count % (BytesPerLong / HeapWordSize) ;
duke@435 167
kvn@1926 168 size_t aligned_count = align_object_offset(count - odd) / HeapWordsPerLong;
duke@435 169 julong* end = ((julong*)tohw) + aligned_count - 1;
duke@435 170 while (to <= end) {
duke@435 171 DEBUG_ONLY(count -= BytesPerLong / HeapWordSize ;)
duke@435 172 *to++ = v;
duke@435 173 }
duke@435 174 assert(count == odd, "bad bounds on loop filling to aligned words");
duke@435 175 if (odd) {
duke@435 176 *((juint*)to) = value;
duke@435 177
duke@435 178 }
duke@435 179 }
duke@435 180
duke@435 181 static void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
duke@435 182 (void)memset(to, value, count);
duke@435 183 }
duke@435 184
duke@435 185 static void pd_zero_to_words(HeapWord* tohw, size_t count) {
duke@435 186 pd_fill_to_words(tohw, count, 0);
duke@435 187 }
duke@435 188
duke@435 189 static void pd_zero_to_bytes(void* to, size_t count) {
duke@435 190 (void)memset(to, 0, count);
duke@435 191 }
stefank@2314 192
stefank@2314 193 #endif // CPU_SPARC_VM_COPY_SPARC_HPP

mercurial