34 #include "oops/fieldStreams.hpp" |
34 #include "oops/fieldStreams.hpp" |
35 #include "runtime/fieldDescriptor.hpp" |
35 #include "runtime/fieldDescriptor.hpp" |
36 |
36 |
37 // ciInstanceKlass |
37 // ciInstanceKlass |
38 // |
38 // |
39 // This class represents a klassOop in the HotSpot virtual machine |
39 // This class represents a Klass* in the HotSpot virtual machine |
40 // whose Klass part in an instanceKlass. |
40 // whose Klass part in an InstanceKlass. |
41 |
41 |
42 // ------------------------------------------------------------------ |
42 // ------------------------------------------------------------------ |
43 // ciInstanceKlass::ciInstanceKlass |
43 // ciInstanceKlass::ciInstanceKlass |
44 // |
44 // |
45 // Loaded instance klass. |
45 // Loaded instance klass. |
46 ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : |
46 ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : |
47 ciKlass(h_k), _non_static_fields(NULL) |
47 ciKlass(h_k), _non_static_fields(NULL) |
48 { |
48 { |
49 assert(get_Klass()->oop_is_instance(), "wrong type"); |
49 assert(get_Klass()->oop_is_instance(), "wrong type"); |
50 assert(get_instanceKlass()->is_loaded(), "must be at least loaded"); |
50 assert(get_instanceKlass()->is_loaded(), "must be at least loaded"); |
51 instanceKlass* ik = get_instanceKlass(); |
51 InstanceKlass* ik = get_instanceKlass(); |
52 |
52 |
53 AccessFlags access_flags = ik->access_flags(); |
53 AccessFlags access_flags = ik->access_flags(); |
54 _flags = ciFlags(access_flags); |
54 _flags = ciFlags(access_flags); |
55 _has_finalizer = access_flags.has_finalizer(); |
55 _has_finalizer = access_flags.has_finalizer(); |
56 _has_subklass = ik->subklass() != NULL; |
56 _has_subklass = ik->subklass() != NULL; |
90 } |
90 } |
91 |
91 |
92 // Version for unloaded classes: |
92 // Version for unloaded classes: |
93 ciInstanceKlass::ciInstanceKlass(ciSymbol* name, |
93 ciInstanceKlass::ciInstanceKlass(ciSymbol* name, |
94 jobject loader, jobject protection_domain) |
94 jobject loader, jobject protection_domain) |
95 : ciKlass(name, ciInstanceKlassKlass::make()) |
95 : ciKlass(name, T_OBJECT) |
96 { |
96 { |
97 assert(name->byte_at(0) != '[', "not an instance klass"); |
97 assert(name->byte_at(0) != '[', "not an instance klass"); |
98 _init_state = (instanceKlass::ClassState)0; |
98 _init_state = (InstanceKlass::ClassState)0; |
99 _nonstatic_field_size = -1; |
99 _nonstatic_field_size = -1; |
100 _has_nonstatic_fields = false; |
100 _has_nonstatic_fields = false; |
101 _nonstatic_fields = NULL; |
101 _nonstatic_fields = NULL; |
102 _loader = loader; |
102 _loader = loader; |
103 _protection_domain = protection_domain; |
103 _protection_domain = protection_domain; |
111 |
111 |
112 // ------------------------------------------------------------------ |
112 // ------------------------------------------------------------------ |
113 // ciInstanceKlass::compute_shared_is_initialized |
113 // ciInstanceKlass::compute_shared_is_initialized |
114 void ciInstanceKlass::compute_shared_init_state() { |
114 void ciInstanceKlass::compute_shared_init_state() { |
115 GUARDED_VM_ENTRY( |
115 GUARDED_VM_ENTRY( |
116 instanceKlass* ik = get_instanceKlass(); |
116 InstanceKlass* ik = get_instanceKlass(); |
117 _init_state = ik->init_state(); |
117 _init_state = ik->init_state(); |
118 ) |
118 ) |
119 } |
119 } |
120 |
120 |
121 // ------------------------------------------------------------------ |
121 // ------------------------------------------------------------------ |
122 // ciInstanceKlass::compute_shared_has_subklass |
122 // ciInstanceKlass::compute_shared_has_subklass |
123 bool ciInstanceKlass::compute_shared_has_subklass() { |
123 bool ciInstanceKlass::compute_shared_has_subklass() { |
124 GUARDED_VM_ENTRY( |
124 GUARDED_VM_ENTRY( |
125 instanceKlass* ik = get_instanceKlass(); |
125 InstanceKlass* ik = get_instanceKlass(); |
126 _has_subklass = ik->subklass() != NULL; |
126 _has_subklass = ik->subklass() != NULL; |
127 return _has_subklass; |
127 return _has_subklass; |
128 ) |
128 ) |
129 } |
129 } |
130 |
130 |
203 |
203 |
204 // ------------------------------------------------------------------ |
204 // ------------------------------------------------------------------ |
205 // ciInstanceKlass::is_java_lang_Object |
205 // ciInstanceKlass::is_java_lang_Object |
206 // |
206 // |
207 // Is this klass java.lang.Object? |
207 // Is this klass java.lang.Object? |
208 bool ciInstanceKlass::is_java_lang_Object() { |
208 bool ciInstanceKlass::is_java_lang_Object() const { |
209 return equals(CURRENT_ENV->Object_klass()); |
209 return equals(CURRENT_ENV->Object_klass()); |
210 } |
210 } |
211 |
211 |
212 // ------------------------------------------------------------------ |
212 // ------------------------------------------------------------------ |
213 // ciInstanceKlass::uses_default_loader |
213 // ciInstanceKlass::uses_default_loader |
290 // Get the superklass of this klass. |
290 // Get the superklass of this klass. |
291 ciInstanceKlass* ciInstanceKlass::super() { |
291 ciInstanceKlass* ciInstanceKlass::super() { |
292 assert(is_loaded(), "must be loaded"); |
292 assert(is_loaded(), "must be loaded"); |
293 if (_super == NULL && !is_java_lang_Object()) { |
293 if (_super == NULL && !is_java_lang_Object()) { |
294 GUARDED_VM_ENTRY( |
294 GUARDED_VM_ENTRY( |
295 klassOop super_klass = get_instanceKlass()->super(); |
295 Klass* super_klass = get_instanceKlass()->super(); |
296 _super = CURRENT_ENV->get_object(super_klass)->as_instance_klass(); |
296 _super = CURRENT_ENV->get_instance_klass(super_klass); |
297 ) |
297 ) |
298 } |
298 } |
299 return _super; |
299 return _super; |
300 } |
300 } |
301 |
301 |
319 ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() { |
319 ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() { |
320 if (!is_loaded()) return NULL; // No change if class is not loaded |
320 if (!is_loaded()) return NULL; // No change if class is not loaded |
321 if (!is_abstract()) return NULL; // Only applies to abstract classes. |
321 if (!is_abstract()) return NULL; // Only applies to abstract classes. |
322 if (!has_subklass()) return NULL; // Must have at least one subklass. |
322 if (!has_subklass()) return NULL; // Must have at least one subklass. |
323 VM_ENTRY_MARK; |
323 VM_ENTRY_MARK; |
324 instanceKlass* ik = get_instanceKlass(); |
324 InstanceKlass* ik = get_instanceKlass(); |
325 Klass* up = ik->up_cast_abstract(); |
325 Klass* up = ik->up_cast_abstract(); |
326 assert(up->oop_is_instance(), "must be instanceKlass"); |
326 assert(up->oop_is_instance(), "must be InstanceKlass"); |
327 if (ik == up) { |
327 if (ik == up) { |
328 return NULL; |
328 return NULL; |
329 } |
329 } |
330 return CURRENT_THREAD_ENV->get_object(up->as_klassOop())->as_instance_klass(); |
330 return CURRENT_THREAD_ENV->get_instance_klass(up); |
331 } |
331 } |
332 |
332 |
333 // ------------------------------------------------------------------ |
333 // ------------------------------------------------------------------ |
334 // ciInstanceKlass::has_finalizable_subclass |
334 // ciInstanceKlass::has_finalizable_subclass |
335 bool ciInstanceKlass::has_finalizable_subclass() { |
335 bool ciInstanceKlass::has_finalizable_subclass() { |
352 // could do binary search or check bins, but probably not worth it |
352 // could do binary search or check bins, but probably not worth it |
353 } |
353 } |
354 return NULL; |
354 return NULL; |
355 } |
355 } |
356 VM_ENTRY_MARK; |
356 VM_ENTRY_MARK; |
357 instanceKlass* k = get_instanceKlass(); |
357 InstanceKlass* k = get_instanceKlass(); |
358 fieldDescriptor fd; |
358 fieldDescriptor fd; |
359 if (!k->find_field_from_offset(field_offset, is_static, &fd)) { |
359 if (!k->find_field_from_offset(field_offset, is_static, &fd)) { |
360 return NULL; |
360 return NULL; |
361 } |
361 } |
362 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); |
362 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); |
365 |
365 |
366 // ------------------------------------------------------------------ |
366 // ------------------------------------------------------------------ |
367 // ciInstanceKlass::get_field_by_name |
367 // ciInstanceKlass::get_field_by_name |
368 ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) { |
368 ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) { |
369 VM_ENTRY_MARK; |
369 VM_ENTRY_MARK; |
370 instanceKlass* k = get_instanceKlass(); |
370 InstanceKlass* k = get_instanceKlass(); |
371 fieldDescriptor fd; |
371 fieldDescriptor fd; |
372 klassOop def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd); |
372 Klass* def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd); |
373 if (def == NULL) { |
373 if (def == NULL) { |
374 return NULL; |
374 return NULL; |
375 } |
375 } |
376 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); |
376 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); |
377 return field; |
377 return field; |
395 |
395 |
396 GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() { |
396 GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() { |
397 if (_non_static_fields == NULL) { |
397 if (_non_static_fields == NULL) { |
398 VM_ENTRY_MARK; |
398 VM_ENTRY_MARK; |
399 ciEnv* curEnv = ciEnv::current(); |
399 ciEnv* curEnv = ciEnv::current(); |
400 instanceKlass* ik = get_instanceKlass(); |
400 InstanceKlass* ik = get_instanceKlass(); |
401 int max_n_fields = ik->java_fields_count(); |
401 int max_n_fields = ik->java_fields_count(); |
402 |
402 |
403 Arena* arena = curEnv->arena(); |
403 Arena* arena = curEnv->arena(); |
404 _non_static_fields = |
404 _non_static_fields = |
405 new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL); |
405 new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL); |
471 super_fields) { |
471 super_fields) { |
472 ASSERT_IN_VM; |
472 ASSERT_IN_VM; |
473 Arena* arena = CURRENT_ENV->arena(); |
473 Arena* arena = CURRENT_ENV->arena(); |
474 int flen = 0; |
474 int flen = 0; |
475 GrowableArray<ciField*>* fields = NULL; |
475 GrowableArray<ciField*>* fields = NULL; |
476 instanceKlass* k = get_instanceKlass(); |
476 InstanceKlass* k = get_instanceKlass(); |
477 for (JavaFieldStream fs(k); !fs.done(); fs.next()) { |
477 for (JavaFieldStream fs(k); !fs.done(); fs.next()) { |
478 if (fs.access_flags().is_static()) continue; |
478 if (fs.access_flags().is_static()) continue; |
479 flen += 1; |
479 flen += 1; |
480 } |
480 } |
481 |
481 |
492 } |
492 } |
493 |
493 |
494 for (JavaFieldStream fs(k); !fs.done(); fs.next()) { |
494 for (JavaFieldStream fs(k); !fs.done(); fs.next()) { |
495 if (fs.access_flags().is_static()) continue; |
495 if (fs.access_flags().is_static()) continue; |
496 fieldDescriptor fd; |
496 fieldDescriptor fd; |
497 fd.initialize(k->as_klassOop(), fs.index()); |
497 fd.initialize(k, fs.index()); |
498 ciField* field = new (arena) ciField(&fd); |
498 ciField* field = new (arena) ciField(&fd); |
499 fields->append(field); |
499 fields->append(field); |
500 } |
500 } |
501 assert(fields->length() == flen, "sanity"); |
501 assert(fields->length() == flen, "sanity"); |
502 return fields; |
502 return fields; |
506 // ciInstanceKlass::find_method |
506 // ciInstanceKlass::find_method |
507 // |
507 // |
508 // Find a method in this klass. |
508 // Find a method in this klass. |
509 ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) { |
509 ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) { |
510 VM_ENTRY_MARK; |
510 VM_ENTRY_MARK; |
511 instanceKlass* k = get_instanceKlass(); |
511 InstanceKlass* k = get_instanceKlass(); |
512 Symbol* name_sym = name->get_symbol(); |
512 Symbol* name_sym = name->get_symbol(); |
513 Symbol* sig_sym= signature->get_symbol(); |
513 Symbol* sig_sym= signature->get_symbol(); |
514 |
514 |
515 methodOop m = k->find_method(name_sym, sig_sym); |
515 Method* m = k->find_method(name_sym, sig_sym); |
516 if (m == NULL) return NULL; |
516 if (m == NULL) return NULL; |
517 |
517 |
518 return CURRENT_THREAD_ENV->get_object(m)->as_method(); |
518 return CURRENT_THREAD_ENV->get_method(m); |
519 } |
519 } |
520 |
520 |
521 // ------------------------------------------------------------------ |
521 // ------------------------------------------------------------------ |
522 // ciInstanceKlass::is_leaf_type |
522 // ciInstanceKlass::is_leaf_type |
523 bool ciInstanceKlass::is_leaf_type() { |
523 bool ciInstanceKlass::is_leaf_type() { |
533 // ciInstanceKlass::implementor |
533 // ciInstanceKlass::implementor |
534 // |
534 // |
535 // Report an implementor of this interface. |
535 // Report an implementor of this interface. |
536 // Note that there are various races here, since my copy |
536 // Note that there are various races here, since my copy |
537 // of _nof_implementors might be out of date with respect |
537 // of _nof_implementors might be out of date with respect |
538 // to results returned by instanceKlass::implementor. |
538 // to results returned by InstanceKlass::implementor. |
539 // This is OK, since any dependencies we decide to assert |
539 // This is OK, since any dependencies we decide to assert |
540 // will be checked later under the Compile_lock. |
540 // will be checked later under the Compile_lock. |
541 ciInstanceKlass* ciInstanceKlass::implementor() { |
541 ciInstanceKlass* ciInstanceKlass::implementor() { |
542 ciInstanceKlass* impl = _implementor; |
542 ciInstanceKlass* impl = _implementor; |
543 if (impl == NULL) { |
543 if (impl == NULL) { |
544 // Go into the VM to fetch the implementor. |
544 // Go into the VM to fetch the implementor. |
545 { |
545 { |
546 VM_ENTRY_MARK; |
546 VM_ENTRY_MARK; |
547 klassOop k = get_instanceKlass()->implementor(); |
547 Klass* k = get_instanceKlass()->implementor(); |
548 if (k != NULL) { |
548 if (k != NULL) { |
549 if (k == get_instanceKlass()->as_klassOop()) { |
549 if (k == get_instanceKlass()) { |
550 // More than one implementors. Use 'this' in this case. |
550 // More than one implementors. Use 'this' in this case. |
551 impl = this; |
551 impl = this; |
552 } else { |
552 } else { |
553 impl = CURRENT_THREAD_ENV->get_object(k)->as_instance_klass(); |
553 impl = CURRENT_THREAD_ENV->get_instance_klass(k); |
554 } |
554 } |
555 } |
555 } |
556 } |
556 } |
557 // Memoize this result. |
557 // Memoize this result. |
558 if (!is_shared()) { |
558 if (!is_shared()) { |