Mercurial > hg > truffle
annotate src/share/vm/oops/objArrayKlassKlass.cpp @ 3762:5c0a3c1858b1
7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
Summary: The LNC array is sized before the start of a scavenge, while the heap may expand during a scavenge. With CMS, the last block of an arbitrary suffice of the LNC array may expand due to coalition with the expansion delta. We now take care not to attempt access past the end of the LNC array. LNC array code will be cleaned up and suitably encapsulated as part of the forthcoming performance RFE 7043675.
Reviewed-by: brutisso
author | ysr |
---|---|
date | Thu, 02 Jun 2011 10:23:36 -0700 |
parents | c7f3d0b4570f |
children | fc9d8850ab8b |
rev | line source |
---|---|
0 | 1 /* |
2227 | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "gc_implementation/shared/markSweep.inline.hpp" | |
29 #include "gc_interface/collectedHeap.inline.hpp" | |
30 #include "oops/instanceKlass.hpp" | |
31 #include "oops/objArrayKlassKlass.hpp" | |
32 #include "oops/oop.inline.hpp" | |
33 #include "oops/oop.inline2.hpp" | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
34 #ifndef SERIALGC |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
35 #include "gc_implementation/parNew/parOopClosures.inline.hpp" |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
36 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
37 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
38 #include "memory/cardTableRS.hpp" |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
39 #include "oops/oop.pcgc.inline.hpp" |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
40 #endif |
0 | 41 |
42 klassOop objArrayKlassKlass::create_klass(TRAPS) { | |
43 objArrayKlassKlass o; | |
44 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); | |
45 KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_0); | |
46 assert(k()->size() == align_object_size(header_size()), "wrong size for object"); | |
47 java_lang_Class::create_mirror(k, CHECK_0); // Allocate mirror | |
48 return k(); | |
49 } | |
50 | |
51 klassOop objArrayKlassKlass::allocate_system_objArray_klass(TRAPS) { | |
52 // system_objArrays have no instance klass, so allocate with fake class, then reset to NULL | |
53 KlassHandle kk(THREAD, Universe::intArrayKlassObj()); | |
54 klassOop k = allocate_objArray_klass(1, kk, CHECK_0); | |
55 objArrayKlass* tk = (objArrayKlass*) k->klass_part(); | |
56 tk->set_element_klass(NULL); | |
57 tk->set_bottom_klass(NULL); | |
58 return k; | |
59 } | |
60 | |
61 | |
62 klassOop objArrayKlassKlass::allocate_objArray_klass(int n, KlassHandle element_klass, TRAPS) { | |
63 objArrayKlassKlassHandle this_oop(THREAD, as_klassOop()); | |
64 return allocate_objArray_klass_impl(this_oop, n, element_klass, THREAD); | |
65 } | |
66 | |
67 klassOop objArrayKlassKlass::allocate_objArray_klass_impl(objArrayKlassKlassHandle this_oop, | |
68 int n, KlassHandle element_klass, TRAPS) { | |
69 | |
70 // Eagerly allocate the direct array supertype. | |
71 KlassHandle super_klass = KlassHandle(); | |
72 if (!Universe::is_bootstrapping()) { | |
73 KlassHandle element_super (THREAD, element_klass->super()); | |
74 if (element_super.not_null()) { | |
75 // The element type has a direct super. E.g., String[] has direct super of Object[]. | |
76 super_klass = KlassHandle(THREAD, element_super->array_klass_or_null()); | |
77 bool supers_exist = super_klass.not_null(); | |
78 // Also, see if the element has secondary supertypes. | |
79 // We need an array type for each. | |
80 objArrayHandle element_supers = objArrayHandle(THREAD, | |
81 element_klass->secondary_supers()); | |
82 for( int i = element_supers->length()-1; i >= 0; i-- ) { | |
83 klassOop elem_super = (klassOop) element_supers->obj_at(i); | |
84 if (Klass::cast(elem_super)->array_klass_or_null() == NULL) { | |
85 supers_exist = false; | |
86 break; | |
87 } | |
88 } | |
89 if (!supers_exist) { | |
90 // Oops. Not allocated yet. Back out, allocate it, and retry. | |
91 #ifndef PRODUCT | |
92 if (WizardMode) { | |
93 tty->print_cr("Must retry array klass creation for depth %d",n); | |
94 } | |
95 #endif | |
96 KlassHandle ek; | |
97 { | |
98 MutexUnlocker mu(MultiArray_lock); | |
99 MutexUnlocker mc(Compile_lock); // for vtables | |
100 klassOop sk = element_super->array_klass(CHECK_0); | |
101 super_klass = KlassHandle(THREAD, sk); | |
102 for( int i = element_supers->length()-1; i >= 0; i-- ) { | |
103 KlassHandle elem_super (THREAD, element_supers->obj_at(i)); | |
104 elem_super->array_klass(CHECK_0); | |
105 } | |
106 // Now retry from the beginning | |
107 klassOop klass_oop = element_klass->array_klass(n, CHECK_0); | |
108 // Create a handle because the enclosing brace, when locking | |
109 // can cause a gc. Better to have this function return a Handle. | |
110 ek = KlassHandle(THREAD, klass_oop); | |
111 } // re-lock | |
112 return ek(); | |
113 } | |
114 } else { | |
115 // The element type is already Object. Object[] has direct super of Object. | |
1142 | 116 super_klass = KlassHandle(THREAD, SystemDictionary::Object_klass()); |
0 | 117 } |
118 } | |
119 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
120 // Create type name for klass. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
121 Symbol* name = NULL; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
122 if (!element_klass->oop_is_instance() || |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
123 (name = instanceKlass::cast(element_klass())->array_name()) == NULL) { |
0 | 124 |
125 ResourceMark rm(THREAD); | |
126 char *name_str = element_klass->name()->as_C_string(); | |
127 int len = element_klass->name()->utf8_length(); | |
128 char *new_str = NEW_RESOURCE_ARRAY(char, len + 4); | |
129 int idx = 0; | |
130 new_str[idx++] = '['; | |
131 if (element_klass->oop_is_instance()) { // it could be an array or simple type | |
132 new_str[idx++] = 'L'; | |
133 } | |
134 memcpy(&new_str[idx], name_str, len * sizeof(char)); | |
135 idx += len; | |
136 if (element_klass->oop_is_instance()) { | |
137 new_str[idx++] = ';'; | |
138 } | |
139 new_str[idx++] = '\0'; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
140 name = SymbolTable::new_symbol(new_str, CHECK_0); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
141 if (element_klass->oop_is_instance()) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
142 instanceKlass* ik = instanceKlass::cast(element_klass()); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
143 ik->set_array_name(name); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
144 } |
0 | 145 } |
146 | |
147 objArrayKlass o; | |
148 arrayKlassHandle k = arrayKlass::base_create_array_klass(o.vtbl_value(), | |
149 objArrayKlass::header_size(), | |
150 this_oop, | |
151 CHECK_0); | |
152 | |
153 // Initialize instance variables | |
154 objArrayKlass* oak = objArrayKlass::cast(k()); | |
155 oak->set_dimension(n); | |
156 oak->set_element_klass(element_klass()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
157 oak->set_name(name); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
158 // decrement refcount because object arrays are not explicitly freed. The |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
159 // instanceKlass array_name() keeps the name counted while the klass is |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
160 // loaded. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
161 name->decrement_refcount(); |
0 | 162 |
163 klassOop bk; | |
164 if (element_klass->oop_is_objArray()) { | |
165 bk = objArrayKlass::cast(element_klass())->bottom_klass(); | |
166 } else { | |
167 bk = element_klass(); | |
168 } | |
169 assert(bk != NULL && (Klass::cast(bk)->oop_is_instance() || Klass::cast(bk)->oop_is_typeArray()), "invalid bottom klass"); | |
170 oak->set_bottom_klass(bk); | |
171 | |
172 oak->set_layout_helper(array_layout_helper(T_OBJECT)); | |
173 assert(oak->oop_is_javaArray(), "sanity"); | |
174 assert(oak->oop_is_objArray(), "sanity"); | |
175 | |
176 // Call complete_create_array_klass after all instance variables has been initialized. | |
177 arrayKlass::complete_create_array_klass(k, super_klass, CHECK_0); | |
178 | |
179 return k(); | |
180 } | |
181 | |
182 | |
183 void objArrayKlassKlass::oop_follow_contents(oop obj) { | |
184 assert(obj->is_klass(), "must be klass"); | |
185 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); | |
186 | |
187 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); | |
188 MarkSweep::mark_and_push(oak->element_klass_addr()); | |
189 MarkSweep::mark_and_push(oak->bottom_klass_addr()); | |
190 | |
191 arrayKlassKlass::oop_follow_contents(obj); | |
192 } | |
193 | |
194 #ifndef SERIALGC | |
195 void objArrayKlassKlass::oop_follow_contents(ParCompactionManager* cm, | |
196 oop obj) { | |
197 assert(obj->is_klass(), "must be klass"); | |
198 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); | |
199 | |
200 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); | |
201 PSParallelCompact::mark_and_push(cm, oak->element_klass_addr()); | |
202 PSParallelCompact::mark_and_push(cm, oak->bottom_klass_addr()); | |
203 | |
204 arrayKlassKlass::oop_follow_contents(cm, obj); | |
205 } | |
206 #endif // SERIALGC | |
207 | |
208 | |
209 int objArrayKlassKlass::oop_adjust_pointers(oop obj) { | |
210 assert(obj->is_klass(), "must be klass"); | |
211 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); | |
212 | |
213 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); | |
214 MarkSweep::adjust_pointer(oak->element_klass_addr()); | |
215 MarkSweep::adjust_pointer(oak->bottom_klass_addr()); | |
216 | |
217 return arrayKlassKlass::oop_adjust_pointers(obj); | |
218 } | |
219 | |
220 | |
221 | |
222 int objArrayKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) { | |
223 assert(obj->is_klass(), "must be klass"); | |
224 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); | |
225 | |
226 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); | |
227 blk->do_oop(oak->element_klass_addr()); | |
228 blk->do_oop(oak->bottom_klass_addr()); | |
229 | |
230 return arrayKlassKlass::oop_oop_iterate(obj, blk); | |
231 } | |
232 | |
233 | |
234 int | |
235 objArrayKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { | |
236 assert(obj->is_klass(), "must be klass"); | |
237 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); | |
238 | |
239 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); | |
240 oop* addr; | |
241 addr = oak->element_klass_addr(); | |
242 if (mr.contains(addr)) blk->do_oop(addr); | |
243 addr = oak->bottom_klass_addr(); | |
244 if (mr.contains(addr)) blk->do_oop(addr); | |
245 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
246 return arrayKlassKlass::oop_oop_iterate_m(obj, blk, mr); |
0 | 247 } |
248 | |
249 #ifndef SERIALGC | |
250 void objArrayKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { | |
251 assert(obj->blueprint()->oop_is_objArrayKlass(),"must be an obj array klass"); | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
252 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
253 oop* p = oak->element_klass_addr(); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
254 if (PSScavenge::should_scavenge(p)) { |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
255 pm->claim_or_forward_depth(p); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
256 } |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
257 p = oak->bottom_klass_addr(); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
258 if (PSScavenge::should_scavenge(p)) { |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
259 pm->claim_or_forward_depth(p); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
260 } |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
261 |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
262 arrayKlassKlass::oop_push_contents(pm, obj); |
0 | 263 } |
264 | |
265 int objArrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { | |
266 assert(obj->is_klass(), "must be klass"); | |
267 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); | |
268 | |
269 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); | |
270 PSParallelCompact::adjust_pointer(oak->element_klass_addr()); | |
271 PSParallelCompact::adjust_pointer(oak->bottom_klass_addr()); | |
272 | |
273 return arrayKlassKlass::oop_update_pointers(cm, obj); | |
274 } | |
275 #endif // SERIALGC | |
276 | |
277 #ifndef PRODUCT | |
278 | |
279 // Printing | |
280 | |
281 void objArrayKlassKlass::oop_print_on(oop obj, outputStream* st) { | |
282 assert(obj->is_klass(), "must be klass"); | |
283 objArrayKlass* oak = (objArrayKlass*) klassOop(obj)->klass_part(); | |
284 klassKlass::oop_print_on(obj, st); | |
285 st->print(" - instance klass: "); | |
286 oak->element_klass()->print_value_on(st); | |
287 st->cr(); | |
288 } | |
289 | |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
1142
diff
changeset
|
290 #endif //PRODUCT |
0 | 291 |
292 void objArrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) { | |
293 assert(obj->is_klass(), "must be klass"); | |
294 objArrayKlass* oak = (objArrayKlass*) klassOop(obj)->klass_part(); | |
295 | |
296 oak->element_klass()->print_value_on(st); | |
297 st->print("[]"); | |
298 } | |
299 | |
300 const char* objArrayKlassKlass::internal_name() const { | |
301 return "{object array class}"; | |
302 } | |
303 | |
304 | |
305 // Verification | |
306 | |
307 void objArrayKlassKlass::oop_verify_on(oop obj, outputStream* st) { | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2227
diff
changeset
|
308 arrayKlassKlass::oop_verify_on(obj, st); |
0 | 309 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); |
310 guarantee(oak->element_klass()->is_perm(), "should be in permspace"); | |
311 guarantee(oak->element_klass()->is_klass(), "should be klass"); | |
312 guarantee(oak->bottom_klass()->is_perm(), "should be in permspace"); | |
313 guarantee(oak->bottom_klass()->is_klass(), "should be klass"); | |
314 Klass* bk = Klass::cast(oak->bottom_klass()); | |
315 guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(), "invalid bottom klass"); | |
316 } |