Mercurial > hg > truffle
annotate src/share/vm/ci/ciInstanceKlass.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 06f017f7daa7 3582bf76420e |
rev | line source |
---|---|
0 | 1 /* |
1645
3941674cc7fa
6958668: repeated uncommon trapping for new of klass which is being initialized
never
parents:
1604
diff
changeset
|
2 * Copyright (c) 1999, 2010, 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"); |
49 instanceKlass* ik = get_instanceKlass(); | |
50 | |
51 AccessFlags access_flags = ik->access_flags(); | |
52 _flags = ciFlags(access_flags); | |
53 _has_finalizer = access_flags.has_finalizer(); | |
54 _has_subklass = ik->subklass() != NULL; | |
1645
3941674cc7fa
6958668: repeated uncommon trapping for new of klass which is being initialized
never
parents:
1604
diff
changeset
|
55 _init_state = (instanceKlass::ClassState)ik->get_init_state(); |
0 | 56 _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
|
57 _has_nonstatic_fields = ik->has_nonstatic_fields(); |
0 | 58 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: |
59 | |
60 _nof_implementors = ik->nof_implementors(); | |
61 for (int i = 0; i < implementors_limit; i++) { | |
62 _implementors[i] = NULL; // we will fill these lazily | |
63 } | |
64 | |
65 Thread *thread = Thread::current(); | |
66 if (ciObjectFactory::is_initialized()) { | |
67 _loader = JNIHandles::make_local(thread, ik->class_loader()); | |
68 _protection_domain = JNIHandles::make_local(thread, | |
69 ik->protection_domain()); | |
70 _is_shared = false; | |
71 } else { | |
72 Handle h_loader(thread, ik->class_loader()); | |
73 Handle h_protection_domain(thread, ik->protection_domain()); | |
74 _loader = JNIHandles::make_global(h_loader); | |
75 _protection_domain = JNIHandles::make_global(h_protection_domain); | |
76 _is_shared = true; | |
77 } | |
78 | |
79 // Lazy fields get filled in only upon request. | |
80 _super = NULL; | |
81 _java_mirror = NULL; | |
82 | |
83 if (is_shared()) { | |
1142 | 84 if (h_k() != SystemDictionary::Object_klass()) { |
0 | 85 super(); |
86 } | |
87 java_mirror(); | |
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() { |
322 if (_java_mirror == NULL) { | |
1604
b918d354830a
6960865: ldc of unloaded class throws an assert in ciTypeFlow
jrose
parents:
1602
diff
changeset
|
323 _java_mirror = ciKlass::java_mirror(); |
0 | 324 } |
325 return _java_mirror; | |
326 } | |
327 | |
328 // ------------------------------------------------------------------ | |
329 // ciInstanceKlass::unique_concrete_subklass | |
330 ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() { | |
331 if (!is_loaded()) return NULL; // No change if class is not loaded | |
332 if (!is_abstract()) return NULL; // Only applies to abstract classes. | |
333 if (!has_subklass()) return NULL; // Must have at least one subklass. | |
334 VM_ENTRY_MARK; | |
335 instanceKlass* ik = get_instanceKlass(); | |
336 Klass* up = ik->up_cast_abstract(); | |
337 assert(up->oop_is_instance(), "must be instanceKlass"); | |
338 if (ik == up) { | |
339 return NULL; | |
340 } | |
341 return CURRENT_THREAD_ENV->get_object(up->as_klassOop())->as_instance_klass(); | |
342 } | |
343 | |
344 // ------------------------------------------------------------------ | |
345 // ciInstanceKlass::has_finalizable_subclass | |
346 bool ciInstanceKlass::has_finalizable_subclass() { | |
347 if (!is_loaded()) return true; | |
348 VM_ENTRY_MARK; | |
349 return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL; | |
350 } | |
351 | |
352 // ------------------------------------------------------------------ | |
353 // ciInstanceKlass::get_field_by_offset | |
354 ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) { | |
355 if (!is_static) { | |
356 for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) { | |
357 ciField* field = _nonstatic_fields->at(i); | |
358 int field_off = field->offset_in_bytes(); | |
359 if (field_off == field_offset) | |
360 return field; | |
361 if (field_off > field_offset) | |
362 break; | |
363 // could do binary search or check bins, but probably not worth it | |
364 } | |
365 return NULL; | |
366 } | |
367 VM_ENTRY_MARK; | |
368 instanceKlass* k = get_instanceKlass(); | |
369 fieldDescriptor fd; | |
370 if (!k->find_field_from_offset(field_offset, is_static, &fd)) { | |
371 return NULL; | |
372 } | |
373 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); | |
374 return field; | |
375 } | |
376 | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
377 // ------------------------------------------------------------------ |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
378 // ciInstanceKlass::get_field_by_name |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
379 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
|
380 VM_ENTRY_MARK; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
381 instanceKlass* k = get_instanceKlass(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
382 fieldDescriptor fd; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
383 klassOop def = k->find_field(name->get_symbolOop(), signature->get_symbolOop(), is_static, &fd); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
384 if (def == NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
385 return NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
386 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
387 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
388 return field; |
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 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
391 // ------------------------------------------------------------------ |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
392 // ciInstanceKlass::non_static_fields. |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
393 |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
394 class NonStaticFieldFiller: public FieldClosure { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
395 GrowableArray<ciField*>* _arr; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
396 ciEnv* _curEnv; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
397 public: |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
398 NonStaticFieldFiller(ciEnv* curEnv, GrowableArray<ciField*>* arr) : |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
399 _curEnv(curEnv), _arr(arr) |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
400 {} |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
401 void do_field(fieldDescriptor* fd) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
402 ciField* field = new (_curEnv->arena()) ciField(fd); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
403 _arr->append(field); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
404 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
405 }; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
406 |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
407 GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
408 if (_non_static_fields == NULL) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
409 VM_ENTRY_MARK; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
410 ciEnv* curEnv = ciEnv::current(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
411 instanceKlass* ik = get_instanceKlass(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
412 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
|
413 |
1685 | 414 Arena* arena = curEnv->arena(); |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
415 _non_static_fields = |
1685 | 416 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
|
417 NonStaticFieldFiller filler(curEnv, _non_static_fields); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
418 ik->do_nonstatic_fields(&filler); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
419 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
420 return _non_static_fields; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
421 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
422 |
0 | 423 static int sort_field_by_offset(ciField** a, ciField** b) { |
424 return (*a)->offset_in_bytes() - (*b)->offset_in_bytes(); | |
425 // (no worries about 32-bit overflow...) | |
426 } | |
427 | |
428 // ------------------------------------------------------------------ | |
429 // ciInstanceKlass::compute_nonstatic_fields | |
430 int ciInstanceKlass::compute_nonstatic_fields() { | |
431 assert(is_loaded(), "must be loaded"); | |
432 | |
433 if (_nonstatic_fields != NULL) | |
434 return _nonstatic_fields->length(); | |
435 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
436 if (!has_nonstatic_fields()) { |
0 | 437 Arena* arena = CURRENT_ENV->arena(); |
438 _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL); | |
439 return 0; | |
440 } | |
441 assert(!is_java_lang_Object(), "bootstrap OK"); | |
442 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
443 // 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
|
444 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
|
445 |
0 | 446 ciInstanceKlass* super = this->super(); |
447 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
|
448 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
|
449 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
|
450 int super_flen = super->nof_nonstatic_fields(); |
0 | 451 super_fields = super->_nonstatic_fields; |
452 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
|
453 // 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
|
454 if (fsize == super_fsize) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
455 _nonstatic_fields = super_fields; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
456 return super_fields->length(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
457 } |
0 | 458 } |
459 | |
460 GrowableArray<ciField*>* fields = NULL; | |
461 GUARDED_VM_ENTRY({ | |
462 fields = compute_nonstatic_fields_impl(super_fields); | |
463 }); | |
464 | |
465 if (fields == NULL) { | |
466 // This can happen if this class (java.lang.Class) has invisible fields. | |
467 _nonstatic_fields = super_fields; | |
468 return super_fields->length(); | |
469 } | |
470 | |
471 int flen = fields->length(); | |
472 | |
473 // Now sort them by offset, ascending. | |
474 // (In principle, they could mix with superclass fields.) | |
475 fields->sort(sort_field_by_offset); | |
476 #ifdef ASSERT | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
44
diff
changeset
|
477 int last_offset = instanceOopDesc::base_offset_in_bytes(); |
0 | 478 for (int i = 0; i < fields->length(); i++) { |
479 ciField* field = fields->at(i); | |
480 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
|
481 int size = (field->_type == NULL) ? heapOopSize : field->size_in_bytes(); |
1846 | 482 assert(last_offset <= offset, err_msg("no field overlap: %d <= %d", last_offset, offset)); |
0 | 483 if (last_offset > (int)sizeof(oopDesc)) |
484 assert((offset - last_offset) < BytesPerLong, "no big holes"); | |
485 // Note: Two consecutive T_BYTE fields will be separated by wordSize-1 | |
486 // padding bytes if one of them is declared by a superclass. | |
487 // This is a minor inefficiency classFileParser.cpp. | |
488 last_offset = offset + size; | |
489 } | |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
113
diff
changeset
|
490 assert(last_offset <= (int)instanceOopDesc::base_offset_in_bytes() + fsize, "no overflow"); |
0 | 491 #endif |
492 | |
493 _nonstatic_fields = fields; | |
494 return flen; | |
495 } | |
496 | |
497 GrowableArray<ciField*>* | |
498 ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>* | |
499 super_fields) { | |
500 ASSERT_IN_VM; | |
501 Arena* arena = CURRENT_ENV->arena(); | |
502 int flen = 0; | |
503 GrowableArray<ciField*>* fields = NULL; | |
504 instanceKlass* k = get_instanceKlass(); | |
505 typeArrayOop fields_array = k->fields(); | |
506 for (int pass = 0; pass <= 1; pass++) { | |
507 for (int i = 0, alen = fields_array->length(); i < alen; i += instanceKlass::next_offset) { | |
508 fieldDescriptor fd; | |
509 fd.initialize(k->as_klassOop(), i); | |
510 if (fd.is_static()) continue; | |
511 if (pass == 0) { | |
512 flen += 1; | |
513 } else { | |
514 ciField* field = new (arena) ciField(&fd); | |
515 fields->append(field); | |
516 } | |
517 } | |
518 | |
519 // Between passes, allocate the array: | |
520 if (pass == 0) { | |
521 if (flen == 0) { | |
522 return NULL; // return nothing if none are locally declared | |
523 } | |
524 if (super_fields != NULL) { | |
525 flen += super_fields->length(); | |
526 } | |
527 fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL); | |
528 if (super_fields != NULL) { | |
529 fields->appendAll(super_fields); | |
530 } | |
531 } | |
532 } | |
533 assert(fields->length() == flen, "sanity"); | |
534 return fields; | |
535 } | |
536 | |
537 // ------------------------------------------------------------------ | |
538 // ciInstanceKlass::find_method | |
539 // | |
540 // Find a method in this klass. | |
541 ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) { | |
542 VM_ENTRY_MARK; | |
543 instanceKlass* k = get_instanceKlass(); | |
544 symbolOop name_sym = name->get_symbolOop(); | |
545 symbolOop sig_sym= signature->get_symbolOop(); | |
546 | |
547 methodOop m = k->find_method(name_sym, sig_sym); | |
548 if (m == NULL) return NULL; | |
549 | |
550 return CURRENT_THREAD_ENV->get_object(m)->as_method(); | |
551 } | |
552 | |
553 // ------------------------------------------------------------------ | |
554 // ciInstanceKlass::is_leaf_type | |
555 bool ciInstanceKlass::is_leaf_type() { | |
556 assert(is_loaded(), "must be loaded"); | |
557 if (is_shared()) { | |
558 return is_final(); // approximately correct | |
559 } else { | |
560 return !_has_subklass && (_nof_implementors == 0); | |
561 } | |
562 } | |
563 | |
564 // ------------------------------------------------------------------ | |
565 // ciInstanceKlass::implementor | |
566 // | |
567 // Report an implementor of this interface. | |
568 // Returns NULL if exact information is not available. | |
569 // Note that there are various races here, since my copy | |
570 // of _nof_implementors might be out of date with respect | |
571 // to results returned by instanceKlass::implementor. | |
572 // This is OK, since any dependencies we decide to assert | |
573 // will be checked later under the Compile_lock. | |
574 ciInstanceKlass* ciInstanceKlass::implementor(int n) { | |
1924 | 575 if (n >= implementors_limit) { |
0 | 576 return NULL; |
577 } | |
578 ciInstanceKlass* impl = _implementors[n]; | |
579 if (impl == NULL) { | |
580 if (_nof_implementors > implementors_limit) { | |
581 return NULL; | |
582 } | |
583 // Go into the VM to fetch the implementor. | |
584 { | |
585 VM_ENTRY_MARK; | |
586 klassOop k = get_instanceKlass()->implementor(n); | |
587 if (k != NULL) { | |
588 impl = CURRENT_THREAD_ENV->get_object(k)->as_instance_klass(); | |
589 } | |
590 } | |
591 // Memoize this result. | |
592 if (!is_shared()) { | |
593 _implementors[n] = (impl == NULL)? this: impl; | |
594 } | |
595 } else if (impl == this) { | |
596 impl = NULL; // memoized null result from a VM query | |
597 } | |
598 return impl; | |
599 } |