Mercurial > hg > truffle
annotate src/share/vm/ci/ciInstanceKlass.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 | 0654ee04b214 e6b1331a51d2 |
rev | line source |
---|---|
0 | 1 /* |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2244
diff
changeset
|
2 * Copyright (c) 1999, 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:
1142
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1142
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:
1142
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "ci/ciField.hpp" | |
27 #include "ci/ciInstance.hpp" | |
28 #include "ci/ciInstanceKlass.hpp" | |
29 #include "ci/ciUtilities.hpp" | |
30 #include "classfile/systemDictionary.hpp" | |
31 #include "memory/allocation.hpp" | |
32 #include "memory/allocation.inline.hpp" | |
33 #include "oops/oop.inline.hpp" | |
34 #include "runtime/fieldDescriptor.hpp" | |
0 | 35 |
36 // ciInstanceKlass | |
37 // | |
38 // This class represents a klassOop in the HotSpot virtual machine | |
39 // whose Klass part in an instanceKlass. | |
40 | |
41 // ------------------------------------------------------------------ | |
42 // ciInstanceKlass::ciInstanceKlass | |
43 // | |
44 // Loaded instance klass. | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
45 ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
46 ciKlass(h_k), _non_static_fields(NULL) |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
47 { |
0 | 48 assert(get_Klass()->oop_is_instance(), "wrong type"); |
2244
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
49 assert(get_instanceKlass()->is_loaded(), "must be at least loaded"); |
0 | 50 instanceKlass* ik = get_instanceKlass(); |
51 | |
52 AccessFlags access_flags = ik->access_flags(); | |
53 _flags = ciFlags(access_flags); | |
54 _has_finalizer = access_flags.has_finalizer(); | |
55 _has_subklass = ik->subklass() != NULL; | |
1645
3941674cc7fa
6958668: repeated uncommon trapping for new of klass which is being initialized
never
parents:
1604
diff
changeset
|
56 _init_state = (instanceKlass::ClassState)ik->get_init_state(); |
0 | 57 _nonstatic_field_size = ik->nonstatic_field_size(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
58 _has_nonstatic_fields = ik->has_nonstatic_fields(); |
0 | 59 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: |
60 | |
61 _nof_implementors = ik->nof_implementors(); | |
62 for (int i = 0; i < implementors_limit; i++) { | |
63 _implementors[i] = NULL; // we will fill these lazily | |
64 } | |
65 | |
66 Thread *thread = Thread::current(); | |
67 if (ciObjectFactory::is_initialized()) { | |
68 _loader = JNIHandles::make_local(thread, ik->class_loader()); | |
69 _protection_domain = JNIHandles::make_local(thread, | |
70 ik->protection_domain()); | |
71 _is_shared = false; | |
72 } else { | |
73 Handle h_loader(thread, ik->class_loader()); | |
74 Handle h_protection_domain(thread, ik->protection_domain()); | |
75 _loader = JNIHandles::make_global(h_loader); | |
76 _protection_domain = JNIHandles::make_global(h_protection_domain); | |
77 _is_shared = true; | |
78 } | |
79 | |
80 // Lazy fields get filled in only upon request. | |
81 _super = NULL; | |
82 _java_mirror = NULL; | |
83 | |
84 if (is_shared()) { | |
1142 | 85 if (h_k() != SystemDictionary::Object_klass()) { |
0 | 86 super(); |
87 } | |
88 //compute_nonstatic_fields(); // done outside of constructor | |
89 } | |
90 | |
91 _field_cache = NULL; | |
92 } | |
93 | |
94 // Version for unloaded classes: | |
95 ciInstanceKlass::ciInstanceKlass(ciSymbol* name, | |
96 jobject loader, jobject protection_domain) | |
97 : ciKlass(name, ciInstanceKlassKlass::make()) | |
98 { | |
99 assert(name->byte_at(0) != '[', "not an instance klass"); | |
1645
3941674cc7fa
6958668: repeated uncommon trapping for new of klass which is being initialized
never
parents:
1604
diff
changeset
|
100 _init_state = (instanceKlass::ClassState)0; |
0 | 101 _nonstatic_field_size = -1; |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
102 _has_nonstatic_fields = false; |
0 | 103 _nonstatic_fields = NULL; |
104 _nof_implementors = -1; | |
105 _loader = loader; | |
106 _protection_domain = protection_domain; | |
107 _is_shared = false; | |
108 _super = NULL; | |
109 _java_mirror = NULL; | |
110 _field_cache = NULL; | |
111 } | |
112 | |
113 | |
114 | |
115 // ------------------------------------------------------------------ | |
116 // ciInstanceKlass::compute_shared_is_initialized | |
1645
3941674cc7fa
6958668: repeated uncommon trapping for new of klass which is being initialized
never
parents:
1604
diff
changeset
|
117 void ciInstanceKlass::compute_shared_init_state() { |
0 | 118 GUARDED_VM_ENTRY( |
119 instanceKlass* ik = get_instanceKlass(); | |
1645
3941674cc7fa
6958668: repeated uncommon trapping for new of klass which is being initialized
never
parents:
1604
diff
changeset
|
120 _init_state = (instanceKlass::ClassState)ik->get_init_state(); |
0 | 121 ) |
122 } | |
123 | |
124 // ------------------------------------------------------------------ | |
125 // ciInstanceKlass::compute_shared_has_subklass | |
126 bool ciInstanceKlass::compute_shared_has_subklass() { | |
127 GUARDED_VM_ENTRY( | |
128 instanceKlass* ik = get_instanceKlass(); | |
129 _has_subklass = ik->subklass() != NULL; | |
130 return _has_subklass; | |
131 ) | |
132 } | |
133 | |
134 // ------------------------------------------------------------------ | |
135 // ciInstanceKlass::compute_shared_nof_implementors | |
136 int ciInstanceKlass::compute_shared_nof_implementors() { | |
137 // We requery this property, since it is a very old ciObject. | |
138 GUARDED_VM_ENTRY( | |
139 instanceKlass* ik = get_instanceKlass(); | |
140 _nof_implementors = ik->nof_implementors(); | |
141 return _nof_implementors; | |
142 ) | |
143 } | |
144 | |
145 // ------------------------------------------------------------------ | |
146 // ciInstanceKlass::loader | |
147 oop ciInstanceKlass::loader() { | |
148 ASSERT_IN_VM; | |
149 return JNIHandles::resolve(_loader); | |
150 } | |
151 | |
152 // ------------------------------------------------------------------ | |
153 // ciInstanceKlass::loader_handle | |
154 jobject ciInstanceKlass::loader_handle() { | |
155 return _loader; | |
156 } | |
157 | |
158 // ------------------------------------------------------------------ | |
159 // ciInstanceKlass::protection_domain | |
160 oop ciInstanceKlass::protection_domain() { | |
161 ASSERT_IN_VM; | |
162 return JNIHandles::resolve(_protection_domain); | |
163 } | |
164 | |
165 // ------------------------------------------------------------------ | |
166 // ciInstanceKlass::protection_domain_handle | |
167 jobject ciInstanceKlass::protection_domain_handle() { | |
168 return _protection_domain; | |
169 } | |
170 | |
171 // ------------------------------------------------------------------ | |
172 // ciInstanceKlass::field_cache | |
173 // | |
174 // Get the field cache associated with this klass. | |
175 ciConstantPoolCache* ciInstanceKlass::field_cache() { | |
176 if (is_shared()) { | |
177 return NULL; | |
178 } | |
179 if (_field_cache == NULL) { | |
180 assert(!is_java_lang_Object(), "Object has no fields"); | |
181 Arena* arena = CURRENT_ENV->arena(); | |
182 _field_cache = new (arena) ciConstantPoolCache(arena, 5); | |
183 } | |
184 return _field_cache; | |
185 } | |
186 | |
187 // ------------------------------------------------------------------ | |
188 // ciInstanceKlass::get_canonical_holder | |
189 // | |
190 ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) { | |
191 #ifdef ASSERT | |
192 if (!(offset >= 0 && offset < layout_helper())) { | |
193 tty->print("*** get_canonical_holder(%d) on ", offset); | |
194 this->print(); | |
195 tty->print_cr(" ***"); | |
196 }; | |
197 assert(offset >= 0 && offset < layout_helper(), "offset must be tame"); | |
198 #endif | |
199 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
200 if (offset < instanceOopDesc::base_offset_in_bytes()) { |
0 | 201 // All header offsets belong properly to java/lang/Object. |
202 return CURRENT_ENV->Object_klass(); | |
203 } | |
204 | |
205 ciInstanceKlass* self = this; | |
206 for (;;) { | |
207 assert(self->is_loaded(), "must be loaded to have size"); | |
208 ciInstanceKlass* super = self->super(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
209 if (super == NULL || super->nof_nonstatic_fields() == 0 || |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
210 !super->contains_field_offset(offset)) { |
0 | 211 return self; |
212 } else { | |
213 self = super; // return super->get_canonical_holder(offset) | |
214 } | |
215 } | |
216 } | |
217 | |
218 // ------------------------------------------------------------------ | |
219 // ciInstanceKlass::is_java_lang_Object | |
220 // | |
221 // Is this klass java.lang.Object? | |
222 bool ciInstanceKlass::is_java_lang_Object() { | |
223 return equals(CURRENT_ENV->Object_klass()); | |
224 } | |
225 | |
226 // ------------------------------------------------------------------ | |
227 // ciInstanceKlass::uses_default_loader | |
228 bool ciInstanceKlass::uses_default_loader() { | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
229 // Note: We do not need to resolve the handle or enter the VM |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
230 // in order to test null-ness. |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
231 return _loader == NULL; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
232 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
233 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
234 // ------------------------------------------------------------------ |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
235 // ciInstanceKlass::is_in_package |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
236 // |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
237 // Is this klass in the given package? |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
238 bool ciInstanceKlass::is_in_package(const char* packagename, int len) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
239 // To avoid class loader mischief, this test always rejects application classes. |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
240 if (!uses_default_loader()) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
241 return false; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
242 GUARDED_VM_ENTRY( |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
243 return is_in_package_impl(packagename, len); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
244 ) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
245 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
246 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
247 bool ciInstanceKlass::is_in_package_impl(const char* packagename, int len) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
248 ASSERT_IN_VM; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
249 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
250 // If packagename contains trailing '/' exclude it from the |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
251 // prefix-test since we test for it explicitly. |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
252 if (packagename[len - 1] == '/') |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
253 len--; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
254 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
255 if (!name()->starts_with(packagename, len)) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
256 return false; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
257 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
258 // Test if the class name is something like "java/lang". |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
259 if ((len + 1) > name()->utf8_length()) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
260 return false; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
261 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
262 // Test for trailing '/' |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
263 if ((char) name()->byte_at(len) != '/') |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
264 return false; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
265 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
266 // Make sure it's not actually in a subpackage: |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
267 if (name()->index_of_at(len+1, "/", 1) >= 0) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
268 return false; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
269 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1080
diff
changeset
|
270 return true; |
0 | 271 } |
272 | |
273 // ------------------------------------------------------------------ | |
274 // ciInstanceKlass::print_impl | |
275 // | |
276 // Implementation of the print method. | |
277 void ciInstanceKlass::print_impl(outputStream* st) { | |
278 ciKlass::print_impl(st); | |
279 GUARDED_VM_ENTRY(st->print(" loader=0x%x", (address)loader());) | |
280 if (is_loaded()) { | |
281 st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=", | |
282 bool_to_str(is_initialized()), | |
283 bool_to_str(has_finalizer()), | |
284 bool_to_str(has_subklass()), | |
285 layout_helper()); | |
286 | |
287 _flags.print_klass_flags(); | |
288 | |
289 if (_super) { | |
290 st->print(" super="); | |
291 _super->print_name(); | |
292 } | |
293 if (_java_mirror) { | |
294 st->print(" mirror=PRESENT"); | |
295 } | |
296 } else { | |
297 st->print(" loaded=false"); | |
298 } | |
299 } | |
300 | |
301 // ------------------------------------------------------------------ | |
302 // ciInstanceKlass::super | |
303 // | |
304 // Get the superklass of this klass. | |
305 ciInstanceKlass* ciInstanceKlass::super() { | |
306 assert(is_loaded(), "must be loaded"); | |
307 if (_super == NULL && !is_java_lang_Object()) { | |
308 GUARDED_VM_ENTRY( | |
309 klassOop super_klass = get_instanceKlass()->super(); | |
310 _super = CURRENT_ENV->get_object(super_klass)->as_instance_klass(); | |
311 ) | |
312 } | |
313 return _super; | |
314 } | |
315 | |
316 // ------------------------------------------------------------------ | |
317 // ciInstanceKlass::java_mirror | |
318 // | |
319 // Get the instance of java.lang.Class corresponding to this klass. | |
1604
b918d354830a
6960865: ldc of unloaded class throws an assert in ciTypeFlow
jrose
parents:
1602
diff
changeset
|
320 // Cache it on this->_java_mirror. |
0 | 321 ciInstance* ciInstanceKlass::java_mirror() { |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2244
diff
changeset
|
322 if (is_shared()) { |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2244
diff
changeset
|
323 return ciKlass::java_mirror(); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2244
diff
changeset
|
324 } |
0 | 325 if (_java_mirror == NULL) { |
1604
b918d354830a
6960865: ldc of unloaded class throws an assert in ciTypeFlow
jrose
parents:
1602
diff
changeset
|
326 _java_mirror = ciKlass::java_mirror(); |
0 | 327 } |
328 return _java_mirror; | |
329 } | |
330 | |
331 // ------------------------------------------------------------------ | |
332 // ciInstanceKlass::unique_concrete_subklass | |
333 ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() { | |
334 if (!is_loaded()) return NULL; // No change if class is not loaded | |
335 if (!is_abstract()) return NULL; // Only applies to abstract classes. | |
336 if (!has_subklass()) return NULL; // Must have at least one subklass. | |
337 VM_ENTRY_MARK; | |
338 instanceKlass* ik = get_instanceKlass(); | |
339 Klass* up = ik->up_cast_abstract(); | |
340 assert(up->oop_is_instance(), "must be instanceKlass"); | |
341 if (ik == up) { | |
342 return NULL; | |
343 } | |
344 return CURRENT_THREAD_ENV->get_object(up->as_klassOop())->as_instance_klass(); | |
345 } | |
346 | |
347 // ------------------------------------------------------------------ | |
348 // ciInstanceKlass::has_finalizable_subclass | |
349 bool ciInstanceKlass::has_finalizable_subclass() { | |
350 if (!is_loaded()) return true; | |
351 VM_ENTRY_MARK; | |
352 return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL; | |
353 } | |
354 | |
355 // ------------------------------------------------------------------ | |
356 // ciInstanceKlass::get_field_by_offset | |
357 ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) { | |
358 if (!is_static) { | |
359 for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) { | |
360 ciField* field = _nonstatic_fields->at(i); | |
361 int field_off = field->offset_in_bytes(); | |
362 if (field_off == field_offset) | |
363 return field; | |
364 if (field_off > field_offset) | |
365 break; | |
366 // could do binary search or check bins, but probably not worth it | |
367 } | |
368 return NULL; | |
369 } | |
370 VM_ENTRY_MARK; | |
371 instanceKlass* k = get_instanceKlass(); | |
372 fieldDescriptor fd; | |
373 if (!k->find_field_from_offset(field_offset, is_static, &fd)) { | |
374 return NULL; | |
375 } | |
376 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); | |
377 return field; | |
378 } | |
379 | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
380 // ------------------------------------------------------------------ |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
381 // ciInstanceKlass::get_field_by_name |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
382 ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
383 VM_ENTRY_MARK; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
384 instanceKlass* k = get_instanceKlass(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
385 fieldDescriptor fd; |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
386 klassOop def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd); |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
387 if (def == NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
388 return NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
389 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
390 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
391 return field; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
392 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
393 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
394 // ------------------------------------------------------------------ |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
395 // ciInstanceKlass::non_static_fields. |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
396 |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
397 class NonStaticFieldFiller: public FieldClosure { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
398 GrowableArray<ciField*>* _arr; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
399 ciEnv* _curEnv; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
400 public: |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
401 NonStaticFieldFiller(ciEnv* curEnv, GrowableArray<ciField*>* arr) : |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
402 _curEnv(curEnv), _arr(arr) |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
403 {} |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
404 void do_field(fieldDescriptor* fd) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
405 ciField* field = new (_curEnv->arena()) ciField(fd); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
406 _arr->append(field); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
407 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
408 }; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
409 |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
410 GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
411 if (_non_static_fields == NULL) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
412 VM_ENTRY_MARK; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
413 ciEnv* curEnv = ciEnv::current(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
414 instanceKlass* ik = get_instanceKlass(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
415 int max_n_fields = ik->fields()->length()/instanceKlass::next_offset; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
416 |
1685 | 417 Arena* arena = curEnv->arena(); |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
418 _non_static_fields = |
1685 | 419 new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL); |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
420 NonStaticFieldFiller filler(curEnv, _non_static_fields); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
421 ik->do_nonstatic_fields(&filler); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
422 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
423 return _non_static_fields; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
424 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
425 |
0 | 426 static int sort_field_by_offset(ciField** a, ciField** b) { |
427 return (*a)->offset_in_bytes() - (*b)->offset_in_bytes(); | |
428 // (no worries about 32-bit overflow...) | |
429 } | |
430 | |
431 // ------------------------------------------------------------------ | |
432 // ciInstanceKlass::compute_nonstatic_fields | |
433 int ciInstanceKlass::compute_nonstatic_fields() { | |
434 assert(is_loaded(), "must be loaded"); | |
435 | |
436 if (_nonstatic_fields != NULL) | |
437 return _nonstatic_fields->length(); | |
438 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
439 if (!has_nonstatic_fields()) { |
0 | 440 Arena* arena = CURRENT_ENV->arena(); |
441 _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL); | |
442 return 0; | |
443 } | |
444 assert(!is_java_lang_Object(), "bootstrap OK"); | |
445 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
446 // Size in bytes of my fields, including inherited fields. |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
113
diff
changeset
|
447 int fsize = nonstatic_field_size() * heapOopSize; |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
448 |
0 | 449 ciInstanceKlass* super = this->super(); |
450 GrowableArray<ciField*>* super_fields = NULL; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
451 if (super != NULL && super->has_nonstatic_fields()) { |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
113
diff
changeset
|
452 int super_fsize = super->nonstatic_field_size() * heapOopSize; |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
453 int super_flen = super->nof_nonstatic_fields(); |
0 | 454 super_fields = super->_nonstatic_fields; |
455 assert(super_flen == 0 || super_fields != NULL, "first get nof_fields"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
456 // See if I am no larger than my super; if so, I can use his fields. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
457 if (fsize == super_fsize) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
458 _nonstatic_fields = super_fields; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
459 return super_fields->length(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
460 } |
0 | 461 } |
462 | |
463 GrowableArray<ciField*>* fields = NULL; | |
464 GUARDED_VM_ENTRY({ | |
465 fields = compute_nonstatic_fields_impl(super_fields); | |
466 }); | |
467 | |
468 if (fields == NULL) { | |
469 // This can happen if this class (java.lang.Class) has invisible fields. | |
470 _nonstatic_fields = super_fields; | |
471 return super_fields->length(); | |
472 } | |
473 | |
474 int flen = fields->length(); | |
475 | |
476 // Now sort them by offset, ascending. | |
477 // (In principle, they could mix with superclass fields.) | |
478 fields->sort(sort_field_by_offset); | |
479 #ifdef ASSERT | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
480 int last_offset = instanceOopDesc::base_offset_in_bytes(); |
0 | 481 for (int i = 0; i < fields->length(); i++) { |
482 ciField* field = fields->at(i); | |
483 int offset = field->offset_in_bytes(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
484 int size = (field->_type == NULL) ? heapOopSize : field->size_in_bytes(); |
1846 | 485 assert(last_offset <= offset, err_msg("no field overlap: %d <= %d", last_offset, offset)); |
0 | 486 if (last_offset > (int)sizeof(oopDesc)) |
487 assert((offset - last_offset) < BytesPerLong, "no big holes"); | |
488 // Note: Two consecutive T_BYTE fields will be separated by wordSize-1 | |
489 // padding bytes if one of them is declared by a superclass. | |
490 // This is a minor inefficiency classFileParser.cpp. | |
491 last_offset = offset + size; | |
492 } | |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
113
diff
changeset
|
493 assert(last_offset <= (int)instanceOopDesc::base_offset_in_bytes() + fsize, "no overflow"); |
0 | 494 #endif |
495 | |
496 _nonstatic_fields = fields; | |
497 return flen; | |
498 } | |
499 | |
500 GrowableArray<ciField*>* | |
501 ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>* | |
502 super_fields) { | |
503 ASSERT_IN_VM; | |
504 Arena* arena = CURRENT_ENV->arena(); | |
505 int flen = 0; | |
506 GrowableArray<ciField*>* fields = NULL; | |
507 instanceKlass* k = get_instanceKlass(); | |
508 typeArrayOop fields_array = k->fields(); | |
509 for (int pass = 0; pass <= 1; pass++) { | |
510 for (int i = 0, alen = fields_array->length(); i < alen; i += instanceKlass::next_offset) { | |
511 fieldDescriptor fd; | |
512 fd.initialize(k->as_klassOop(), i); | |
513 if (fd.is_static()) continue; | |
514 if (pass == 0) { | |
515 flen += 1; | |
516 } else { | |
517 ciField* field = new (arena) ciField(&fd); | |
518 fields->append(field); | |
519 } | |
520 } | |
521 | |
522 // Between passes, allocate the array: | |
523 if (pass == 0) { | |
524 if (flen == 0) { | |
525 return NULL; // return nothing if none are locally declared | |
526 } | |
527 if (super_fields != NULL) { | |
528 flen += super_fields->length(); | |
529 } | |
530 fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL); | |
531 if (super_fields != NULL) { | |
532 fields->appendAll(super_fields); | |
533 } | |
534 } | |
535 } | |
536 assert(fields->length() == flen, "sanity"); | |
537 return fields; | |
538 } | |
539 | |
540 // ------------------------------------------------------------------ | |
541 // ciInstanceKlass::find_method | |
542 // | |
543 // Find a method in this klass. | |
544 ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) { | |
545 VM_ENTRY_MARK; | |
546 instanceKlass* k = get_instanceKlass(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
547 Symbol* name_sym = name->get_symbol(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
548 Symbol* sig_sym= signature->get_symbol(); |
0 | 549 |
550 methodOop m = k->find_method(name_sym, sig_sym); | |
551 if (m == NULL) return NULL; | |
552 | |
553 return CURRENT_THREAD_ENV->get_object(m)->as_method(); | |
554 } | |
555 | |
556 // ------------------------------------------------------------------ | |
557 // ciInstanceKlass::is_leaf_type | |
558 bool ciInstanceKlass::is_leaf_type() { | |
559 assert(is_loaded(), "must be loaded"); | |
560 if (is_shared()) { | |
561 return is_final(); // approximately correct | |
562 } else { | |
563 return !_has_subklass && (_nof_implementors == 0); | |
564 } | |
565 } | |
566 | |
567 // ------------------------------------------------------------------ | |
568 // ciInstanceKlass::implementor | |
569 // | |
570 // Report an implementor of this interface. | |
571 // Returns NULL if exact information is not available. | |
572 // Note that there are various races here, since my copy | |
573 // of _nof_implementors might be out of date with respect | |
574 // to results returned by instanceKlass::implementor. | |
575 // This is OK, since any dependencies we decide to assert | |
576 // will be checked later under the Compile_lock. | |
577 ciInstanceKlass* ciInstanceKlass::implementor(int n) { | |
1924 | 578 if (n >= implementors_limit) { |
0 | 579 return NULL; |
580 } | |
581 ciInstanceKlass* impl = _implementors[n]; | |
582 if (impl == NULL) { | |
583 if (_nof_implementors > implementors_limit) { | |
584 return NULL; | |
585 } | |
586 // Go into the VM to fetch the implementor. | |
587 { | |
588 VM_ENTRY_MARK; | |
589 klassOop k = get_instanceKlass()->implementor(n); | |
590 if (k != NULL) { | |
591 impl = CURRENT_THREAD_ENV->get_object(k)->as_instance_klass(); | |
592 } | |
593 } | |
594 // Memoize this result. | |
595 if (!is_shared()) { | |
596 _implementors[n] = (impl == NULL)? this: impl; | |
597 } | |
598 } else if (impl == this) { | |
599 impl = NULL; // memoized null result from a VM query | |
600 } | |
601 return impl; | |
602 } |