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