Mercurial > hg > graal-compiler
comparison src/share/vm/oops/instanceKlass.cpp @ 12355:cefad50507d8
Merge with hs25-b53
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Fri, 11 Oct 2013 10:38:03 +0200 |
parents | 6b0fd0964b87 36b97be47bde |
children | 096c224171c4 |
comparison
equal
deleted
inserted
replaced
12058:ccb4f2af2319 | 12355:cefad50507d8 |
---|---|
104 if (name != NULL) { \ | 104 if (name != NULL) { \ |
105 data = (char*)name->bytes(); \ | 105 data = (char*)name->bytes(); \ |
106 len = name->utf8_length(); \ | 106 len = name->utf8_length(); \ |
107 } \ | 107 } \ |
108 HS_DTRACE_PROBE4(hotspot, class__initialization__##type, \ | 108 HS_DTRACE_PROBE4(hotspot, class__initialization__##type, \ |
109 data, len, (clss)->class_loader(), thread_type); \ | 109 data, len, SOLARIS_ONLY((void *))(clss)->class_loader(), thread_type); \ |
110 } | 110 } |
111 | 111 |
112 #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \ | 112 #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \ |
113 { \ | 113 { \ |
114 char* data = NULL; \ | 114 char* data = NULL; \ |
117 if (name != NULL) { \ | 117 if (name != NULL) { \ |
118 data = (char*)name->bytes(); \ | 118 data = (char*)name->bytes(); \ |
119 len = name->utf8_length(); \ | 119 len = name->utf8_length(); \ |
120 } \ | 120 } \ |
121 HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \ | 121 HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \ |
122 data, len, (clss)->class_loader(), thread_type, wait); \ | 122 data, len, SOLARIS_ONLY((void *))(clss)->class_loader(), thread_type, wait); \ |
123 } | 123 } |
124 #else /* USDT2 */ | 124 #else /* USDT2 */ |
125 | 125 |
126 #define HOTSPOT_CLASS_INITIALIZATION_required HOTSPOT_CLASS_INITIALIZATION_REQUIRED | 126 #define HOTSPOT_CLASS_INITIALIZATION_required HOTSPOT_CLASS_INITIALIZATION_REQUIRED |
127 #define HOTSPOT_CLASS_INITIALIZATION_recursive HOTSPOT_CLASS_INITIALIZATION_RECURSIVE | 127 #define HOTSPOT_CLASS_INITIALIZATION_recursive HOTSPOT_CLASS_INITIALIZATION_RECURSIVE |
267 set_transitive_interfaces(NULL); | 267 set_transitive_interfaces(NULL); |
268 init_implementor(); | 268 init_implementor(); |
269 set_fields(NULL, 0); | 269 set_fields(NULL, 0); |
270 set_constants(NULL); | 270 set_constants(NULL); |
271 set_class_loader_data(NULL); | 271 set_class_loader_data(NULL); |
272 set_source_file_name(NULL); | 272 set_source_file_name_index(0); |
273 set_source_debug_extension(NULL, 0); | 273 set_source_debug_extension(NULL, 0); |
274 set_array_name(NULL); | 274 set_array_name(NULL); |
275 set_inner_classes(NULL); | 275 set_inner_classes(NULL); |
276 set_static_oop_field_count(0); | 276 set_static_oop_field_count(0); |
277 set_nonstatic_field_size(0); | 277 set_nonstatic_field_size(0); |
282 set_oop_map_cache(NULL); | 282 set_oop_map_cache(NULL); |
283 set_jni_ids(NULL); | 283 set_jni_ids(NULL); |
284 set_osr_nmethods_head(NULL); | 284 set_osr_nmethods_head(NULL); |
285 set_breakpoints(NULL); | 285 set_breakpoints(NULL); |
286 init_previous_versions(); | 286 init_previous_versions(); |
287 set_generic_signature(NULL); | 287 set_generic_signature_index(0); |
288 release_set_methods_jmethod_ids(NULL); | 288 release_set_methods_jmethod_ids(NULL); |
289 release_set_methods_cached_itable_indices(NULL); | |
290 set_annotations(NULL); | 289 set_annotations(NULL); |
291 set_jvmti_cached_class_field_map(NULL); | 290 set_jvmti_cached_class_field_map(NULL); |
292 set_initial_method_idnum(0); | 291 set_initial_method_idnum(0); |
293 _dependencies = NULL; | 292 _dependencies = NULL; |
294 set_jvmti_cached_class_field_map(NULL); | 293 set_jvmti_cached_class_field_map(NULL); |
1147 bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { | 1146 bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { |
1148 for (JavaFieldStream fs(this); !fs.done(); fs.next()) { | 1147 for (JavaFieldStream fs(this); !fs.done(); fs.next()) { |
1149 Symbol* f_name = fs.name(); | 1148 Symbol* f_name = fs.name(); |
1150 Symbol* f_sig = fs.signature(); | 1149 Symbol* f_sig = fs.signature(); |
1151 if (f_name == name && f_sig == sig) { | 1150 if (f_name == name && f_sig == sig) { |
1152 fd->initialize(const_cast<InstanceKlass*>(this), fs.index()); | 1151 fd->reinitialize(const_cast<InstanceKlass*>(this), fs.index()); |
1153 return true; | 1152 return true; |
1154 } | 1153 } |
1155 } | 1154 } |
1156 return false; | 1155 return false; |
1157 } | 1156 } |
1216 | 1215 |
1217 | 1216 |
1218 bool InstanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const { | 1217 bool InstanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const { |
1219 for (JavaFieldStream fs(this); !fs.done(); fs.next()) { | 1218 for (JavaFieldStream fs(this); !fs.done(); fs.next()) { |
1220 if (fs.offset() == offset) { | 1219 if (fs.offset() == offset) { |
1221 fd->initialize(const_cast<InstanceKlass*>(this), fs.index()); | 1220 fd->reinitialize(const_cast<InstanceKlass*>(this), fs.index()); |
1222 if (fd->is_static() == is_static) return true; | 1221 if (fd->is_static() == is_static) return true; |
1223 } | 1222 } |
1224 } | 1223 } |
1225 return false; | 1224 return false; |
1226 } | 1225 } |
1249 | 1248 |
1250 | 1249 |
1251 void InstanceKlass::do_local_static_fields(FieldClosure* cl) { | 1250 void InstanceKlass::do_local_static_fields(FieldClosure* cl) { |
1252 for (JavaFieldStream fs(this); !fs.done(); fs.next()) { | 1251 for (JavaFieldStream fs(this); !fs.done(); fs.next()) { |
1253 if (fs.access_flags().is_static()) { | 1252 if (fs.access_flags().is_static()) { |
1254 fieldDescriptor fd; | 1253 fieldDescriptor& fd = fs.field_descriptor(); |
1255 fd.initialize(this, fs.index()); | |
1256 cl->do_field(&fd); | 1254 cl->do_field(&fd); |
1257 } | 1255 } |
1258 } | 1256 } |
1259 } | 1257 } |
1260 | 1258 |
1266 | 1264 |
1267 | 1265 |
1268 void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS) { | 1266 void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS) { |
1269 for (JavaFieldStream fs(this_oop()); !fs.done(); fs.next()) { | 1267 for (JavaFieldStream fs(this_oop()); !fs.done(); fs.next()) { |
1270 if (fs.access_flags().is_static()) { | 1268 if (fs.access_flags().is_static()) { |
1271 fieldDescriptor fd; | 1269 fieldDescriptor& fd = fs.field_descriptor(); |
1272 fd.initialize(this_oop(), fs.index()); | |
1273 f(&fd, CHECK); | 1270 f(&fd, CHECK); |
1274 } | 1271 } |
1275 } | 1272 } |
1276 } | 1273 } |
1277 | 1274 |
1289 int length = java_fields_count(); | 1286 int length = java_fields_count(); |
1290 // In DebugInfo nonstatic fields are sorted by offset. | 1287 // In DebugInfo nonstatic fields are sorted by offset. |
1291 int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass); | 1288 int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass); |
1292 int j = 0; | 1289 int j = 0; |
1293 for (int i = 0; i < length; i += 1) { | 1290 for (int i = 0; i < length; i += 1) { |
1294 fd.initialize(this, i); | 1291 fd.reinitialize(this, i); |
1295 if (!fd.is_static()) { | 1292 if (!fd.is_static()) { |
1296 fields_sorted[j + 0] = fd.offset(); | 1293 fields_sorted[j + 0] = fd.offset(); |
1297 fields_sorted[j + 1] = i; | 1294 fields_sorted[j + 1] = i; |
1298 j += 2; | 1295 j += 2; |
1299 } | 1296 } |
1301 if (j > 0) { | 1298 if (j > 0) { |
1302 length = j; | 1299 length = j; |
1303 // _sort_Fn is defined in growableArray.hpp. | 1300 // _sort_Fn is defined in growableArray.hpp. |
1304 qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset); | 1301 qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset); |
1305 for (int i = 0; i < length; i += 2) { | 1302 for (int i = 0; i < length; i += 2) { |
1306 fd.initialize(this, fields_sorted[i + 1]); | 1303 fd.reinitialize(this, fields_sorted[i + 1]); |
1307 assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields"); | 1304 assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields"); |
1308 cl->do_field(&fd); | 1305 cl->do_field(&fd); |
1309 } | 1306 } |
1310 } | 1307 } |
1311 FREE_C_HEAP_ARRAY(int, fields_sorted, mtClass); | 1308 FREE_C_HEAP_ARRAY(int, fields_sorted, mtClass); |
1420 } | 1417 } |
1421 return NULL; | 1418 return NULL; |
1422 } | 1419 } |
1423 | 1420 |
1424 // lookup a method in all the interfaces that this class implements | 1421 // lookup a method in all the interfaces that this class implements |
1422 // Do NOT return private or static methods, new in JDK8 which are not externally visible | |
1423 // They should only be found in the initial InterfaceMethodRef | |
1425 Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name, | 1424 Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name, |
1426 Symbol* signature) const { | 1425 Symbol* signature) const { |
1427 Array<Klass*>* all_ifs = transitive_interfaces(); | 1426 Array<Klass*>* all_ifs = transitive_interfaces(); |
1428 int num_ifs = all_ifs->length(); | 1427 int num_ifs = all_ifs->length(); |
1429 InstanceKlass *ik = NULL; | 1428 InstanceKlass *ik = NULL; |
1430 for (int i = 0; i < num_ifs; i++) { | 1429 for (int i = 0; i < num_ifs; i++) { |
1431 ik = InstanceKlass::cast(all_ifs->at(i)); | 1430 ik = InstanceKlass::cast(all_ifs->at(i)); |
1432 Method* m = ik->lookup_method(name, signature); | 1431 Method* m = ik->lookup_method(name, signature); |
1433 if (m != NULL) { | 1432 if (m != NULL && m->is_public() && !m->is_static()) { |
1434 return m; | 1433 return m; |
1435 } | 1434 } |
1436 } | 1435 } |
1437 return NULL; | 1436 return NULL; |
1438 } | 1437 } |
1681 if (jmeths != NULL && // If there is a cache | 1680 if (jmeths != NULL && // If there is a cache |
1682 (length = (size_t)jmeths[0]) > idnum) { // and if it is long enough, | 1681 (length = (size_t)jmeths[0]) > idnum) { // and if it is long enough, |
1683 id = jmeths[idnum+1]; // Look up the id (may be NULL) | 1682 id = jmeths[idnum+1]; // Look up the id (may be NULL) |
1684 } | 1683 } |
1685 return id; | 1684 return id; |
1686 } | |
1687 | |
1688 | |
1689 // Cache an itable index | |
1690 void InstanceKlass::set_cached_itable_index(size_t idnum, int index) { | |
1691 int* indices = methods_cached_itable_indices_acquire(); | |
1692 int* to_dealloc_indices = NULL; | |
1693 | |
1694 // We use a double-check locking idiom here because this cache is | |
1695 // performance sensitive. In the normal system, this cache only | |
1696 // transitions from NULL to non-NULL which is safe because we use | |
1697 // release_set_methods_cached_itable_indices() to advertise the | |
1698 // new cache. A partially constructed cache should never be seen | |
1699 // by a racing thread. Cache reads and writes proceed without a | |
1700 // lock, but creation of the cache itself requires no leaks so a | |
1701 // lock is generally acquired in that case. | |
1702 // | |
1703 // If the RedefineClasses() API has been used, then this cache can | |
1704 // grow and we'll have transitions from non-NULL to bigger non-NULL. | |
1705 // Cache creation requires no leaks and we require safety between all | |
1706 // cache accesses and freeing of the old cache so a lock is generally | |
1707 // acquired when the RedefineClasses() API has been used. | |
1708 | |
1709 if (indices == NULL || idnum_can_increment()) { | |
1710 // we need a cache or the cache can grow | |
1711 MutexLocker ml(JNICachedItableIndex_lock); | |
1712 // reacquire the cache to see if another thread already did the work | |
1713 indices = methods_cached_itable_indices_acquire(); | |
1714 size_t length = 0; | |
1715 // cache size is stored in element[0], other elements offset by one | |
1716 if (indices == NULL || (length = (size_t)indices[0]) <= idnum) { | |
1717 size_t size = MAX2(idnum+1, (size_t)idnum_allocated_count()); | |
1718 int* new_indices = NEW_C_HEAP_ARRAY(int, size+1, mtClass); | |
1719 new_indices[0] = (int)size; | |
1720 // copy any existing entries | |
1721 size_t i; | |
1722 for (i = 0; i < length; i++) { | |
1723 new_indices[i+1] = indices[i+1]; | |
1724 } | |
1725 // Set all the rest to -1 | |
1726 for (i = length; i < size; i++) { | |
1727 new_indices[i+1] = -1; | |
1728 } | |
1729 if (indices != NULL) { | |
1730 // We have an old cache to delete so save it for after we | |
1731 // drop the lock. | |
1732 to_dealloc_indices = indices; | |
1733 } | |
1734 release_set_methods_cached_itable_indices(indices = new_indices); | |
1735 } | |
1736 | |
1737 if (idnum_can_increment()) { | |
1738 // this cache can grow so we have to write to it safely | |
1739 indices[idnum+1] = index; | |
1740 } | |
1741 } else { | |
1742 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); | |
1743 } | |
1744 | |
1745 if (!idnum_can_increment()) { | |
1746 // The cache cannot grow and this JNI itable index value does not | |
1747 // have to be unique like a jmethodID. If there is a race to set it, | |
1748 // it doesn't matter. | |
1749 indices[idnum+1] = index; | |
1750 } | |
1751 | |
1752 if (to_dealloc_indices != NULL) { | |
1753 // we allocated a new cache so free the old one | |
1754 FreeHeap(to_dealloc_indices); | |
1755 } | |
1756 } | |
1757 | |
1758 | |
1759 // Retrieve a cached itable index | |
1760 int InstanceKlass::cached_itable_index(size_t idnum) { | |
1761 int* indices = methods_cached_itable_indices_acquire(); | |
1762 if (indices != NULL && ((size_t)indices[0]) > idnum) { | |
1763 // indices exist and are long enough, retrieve possible cached | |
1764 return indices[idnum+1]; | |
1765 } | |
1766 return -1; | |
1767 } | 1685 } |
1768 | 1686 |
1769 | 1687 |
1770 // | 1688 // |
1771 // Walk the list of dependent nmethods searching for nmethods which | 1689 // Walk the list of dependent nmethods searching for nmethods which |
2324 delete mnt; | 2242 delete mnt; |
2325 set_member_names(NULL); | 2243 set_member_names(NULL); |
2326 } | 2244 } |
2327 } | 2245 } |
2328 | 2246 |
2329 int* indices = methods_cached_itable_indices_acquire(); | |
2330 if (indices != (int*)NULL) { | |
2331 release_set_methods_cached_itable_indices(NULL); | |
2332 FreeHeap(indices); | |
2333 } | |
2334 | |
2335 // release dependencies | 2247 // release dependencies |
2336 nmethodBucket* b = _dependencies; | 2248 nmethodBucket* b = _dependencies; |
2337 _dependencies = NULL; | 2249 _dependencies = NULL; |
2338 while (b != NULL) { | 2250 while (b != NULL) { |
2339 nmethodBucket* next = b->next(); | 2251 nmethodBucket* next = b->next(); |
2366 // Decrement symbol reference counts associated with the unloaded class. | 2278 // Decrement symbol reference counts associated with the unloaded class. |
2367 if (_name != NULL) _name->decrement_refcount(); | 2279 if (_name != NULL) _name->decrement_refcount(); |
2368 // unreference array name derived from this class name (arrays of an unloaded | 2280 // unreference array name derived from this class name (arrays of an unloaded |
2369 // class can't be referenced anymore). | 2281 // class can't be referenced anymore). |
2370 if (_array_name != NULL) _array_name->decrement_refcount(); | 2282 if (_array_name != NULL) _array_name->decrement_refcount(); |
2371 if (_source_file_name != NULL) _source_file_name->decrement_refcount(); | |
2372 if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass); | 2283 if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass); |
2373 | 2284 |
2374 assert(_total_instanceKlass_count >= 1, "Sanity check"); | 2285 assert(_total_instanceKlass_count >= 1, "Sanity check"); |
2375 Atomic::dec(&_total_instanceKlass_count); | 2286 Atomic::dec(&_total_instanceKlass_count); |
2376 } | |
2377 | |
2378 void InstanceKlass::set_source_file_name(Symbol* n) { | |
2379 _source_file_name = n; | |
2380 if (_source_file_name != NULL) _source_file_name->increment_refcount(); | |
2381 } | 2287 } |
2382 | 2288 |
2383 void InstanceKlass::set_source_debug_extension(char* array, int length) { | 2289 void InstanceKlass::set_source_debug_extension(char* array, int length) { |
2384 if (array == NULL) { | 2290 if (array == NULL) { |
2385 _source_debug_extension = NULL; | 2291 _source_debug_extension = NULL; |
2397 _source_debug_extension = sde; | 2303 _source_debug_extension = sde; |
2398 } | 2304 } |
2399 } | 2305 } |
2400 | 2306 |
2401 address InstanceKlass::static_field_addr(int offset) { | 2307 address InstanceKlass::static_field_addr(int offset) { |
2402 return (address)(offset + InstanceMirrorKlass::offset_of_static_fields() + (intptr_t)java_mirror()); | 2308 return (address)(offset + InstanceMirrorKlass::offset_of_static_fields() + cast_from_oop<intptr_t>(java_mirror())); |
2403 } | 2309 } |
2404 | 2310 |
2405 | 2311 |
2406 const char* InstanceKlass::signature_name() const { | 2312 const char* InstanceKlass::signature_name() const { |
2407 const char* src = (const char*) (name()->as_C_string()); | 2313 const char* src = (const char*) (name()->as_C_string()); |
2786 | 2692 |
2787 static const char* state_names[] = { | 2693 static const char* state_names[] = { |
2788 "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error" | 2694 "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error" |
2789 }; | 2695 }; |
2790 | 2696 |
2697 static void print_vtable(intptr_t* start, int len, outputStream* st) { | |
2698 for (int i = 0; i < len; i++) { | |
2699 intptr_t e = start[i]; | |
2700 st->print("%d : " INTPTR_FORMAT, i, e); | |
2701 if (e != 0 && ((Metadata*)e)->is_metaspace_object()) { | |
2702 st->print(" "); | |
2703 ((Metadata*)e)->print_value_on(st); | |
2704 } | |
2705 st->cr(); | |
2706 } | |
2707 } | |
2708 | |
2791 void InstanceKlass::print_on(outputStream* st) const { | 2709 void InstanceKlass::print_on(outputStream* st) const { |
2792 assert(is_klass(), "must be klass"); | 2710 assert(is_klass(), "must be klass"); |
2793 Klass::print_on(st); | 2711 Klass::print_on(st); |
2794 | 2712 |
2795 st->print(BULLET"instance size: %d", size_helper()); st->cr(); | 2713 st->print(BULLET"instance size: %d", size_helper()); st->cr(); |
2820 } | 2738 } |
2821 } | 2739 } |
2822 | 2740 |
2823 st->print(BULLET"arrays: "); array_klasses()->print_value_on_maybe_null(st); st->cr(); | 2741 st->print(BULLET"arrays: "); array_klasses()->print_value_on_maybe_null(st); st->cr(); |
2824 st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr(); | 2742 st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr(); |
2825 if (Verbose) { | 2743 if (Verbose || WizardMode) { |
2826 Array<Method*>* method_array = methods(); | 2744 Array<Method*>* method_array = methods(); |
2827 for(int i = 0; i < method_array->length(); i++) { | 2745 for(int i = 0; i < method_array->length(); i++) { |
2828 st->print("%d : ", i); method_array->at(i)->print_value(); st->cr(); | 2746 st->print("%d : ", i); method_array->at(i)->print_value(); st->cr(); |
2829 } | 2747 } |
2830 } | 2748 } |
2851 st->print(BULLET"class annotations: "); class_annotations()->print_value_on(st); st->cr(); | 2769 st->print(BULLET"class annotations: "); class_annotations()->print_value_on(st); st->cr(); |
2852 st->print(BULLET"class type annotations: "); class_type_annotations()->print_value_on(st); st->cr(); | 2770 st->print(BULLET"class type annotations: "); class_type_annotations()->print_value_on(st); st->cr(); |
2853 st->print(BULLET"field annotations: "); fields_annotations()->print_value_on(st); st->cr(); | 2771 st->print(BULLET"field annotations: "); fields_annotations()->print_value_on(st); st->cr(); |
2854 st->print(BULLET"field type annotations: "); fields_type_annotations()->print_value_on(st); st->cr(); | 2772 st->print(BULLET"field type annotations: "); fields_type_annotations()->print_value_on(st); st->cr(); |
2855 { | 2773 { |
2856 ResourceMark rm; | 2774 bool have_pv = false; |
2857 // PreviousVersionInfo objects returned via PreviousVersionWalker | 2775 PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this); |
2858 // contain a GrowableArray of handles. We have to clean up the | 2776 for (PreviousVersionNode * pv_node = pvw.next_previous_version(); |
2859 // GrowableArray _after_ the PreviousVersionWalker destructor | 2777 pv_node != NULL; pv_node = pvw.next_previous_version()) { |
2860 // has destroyed the handles. | 2778 if (!have_pv) |
2861 { | 2779 st->print(BULLET"previous version: "); |
2862 bool have_pv = false; | 2780 have_pv = true; |
2863 PreviousVersionWalker pvw((InstanceKlass*)this); | 2781 pv_node->prev_constant_pool()->print_value_on(st); |
2864 for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); | 2782 } |
2865 pv_info != NULL; pv_info = pvw.next_previous_version()) { | 2783 if (have_pv) st->cr(); |
2866 if (!have_pv) | 2784 } // pvw is cleaned up |
2867 st->print(BULLET"previous version: "); | |
2868 have_pv = true; | |
2869 pv_info->prev_constant_pool_handle()()->print_value_on(st); | |
2870 } | |
2871 if (have_pv) st->cr(); | |
2872 } // pvw is cleaned up | |
2873 } // rm is cleaned up | |
2874 | 2785 |
2875 if (generic_signature() != NULL) { | 2786 if (generic_signature() != NULL) { |
2876 st->print(BULLET"generic signature: "); | 2787 st->print(BULLET"generic signature: "); |
2877 generic_signature()->print_value_on(st); | 2788 generic_signature()->print_value_on(st); |
2878 st->cr(); | 2789 st->cr(); |
2879 } | 2790 } |
2880 st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr(); | 2791 st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr(); |
2881 st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr(); | 2792 st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr(); |
2882 st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), start_of_vtable()); st->cr(); | 2793 st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), start_of_vtable()); st->cr(); |
2794 if (vtable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_vtable(), vtable_length(), st); | |
2883 st->print(BULLET"itable length %d (start addr: " INTPTR_FORMAT ")", itable_length(), start_of_itable()); st->cr(); | 2795 st->print(BULLET"itable length %d (start addr: " INTPTR_FORMAT ")", itable_length(), start_of_itable()); st->cr(); |
2796 if (itable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_itable(), itable_length(), st); | |
2884 st->print_cr(BULLET"---- static fields (%d words):", static_field_size()); | 2797 st->print_cr(BULLET"---- static fields (%d words):", static_field_size()); |
2885 FieldPrinter print_static_field(st); | 2798 FieldPrinter print_static_field(st); |
2886 ((InstanceKlass*)this)->do_local_static_fields(&print_static_field); | 2799 ((InstanceKlass*)this)->do_local_static_fields(&print_static_field); |
2887 st->print_cr(BULLET"---- non-static fields (%d words):", nonstatic_field_size()); | 2800 st->print_cr(BULLET"---- non-static fields (%d words):", nonstatic_field_size()); |
2888 FieldPrinter print_nonstatic_field(st); | 2801 FieldPrinter print_nonstatic_field(st); |
2900 | 2813 |
2901 #endif //PRODUCT | 2814 #endif //PRODUCT |
2902 | 2815 |
2903 void InstanceKlass::print_value_on(outputStream* st) const { | 2816 void InstanceKlass::print_value_on(outputStream* st) const { |
2904 assert(is_klass(), "must be klass"); | 2817 assert(is_klass(), "must be klass"); |
2818 if (Verbose || WizardMode) access_flags().print_on(st); | |
2905 name()->print_value_on(st); | 2819 name()->print_value_on(st); |
2906 } | 2820 } |
2907 | 2821 |
2908 #ifndef PRODUCT | 2822 #ifndef PRODUCT |
2909 | 2823 |
3396 // we don't need to create a new PreviousVersionNode. However, | 3310 // we don't need to create a new PreviousVersionNode. However, |
3397 // we still need to examine older previous versions below. | 3311 // we still need to examine older previous versions below. |
3398 Array<Method*>* old_methods = ikh->methods(); | 3312 Array<Method*>* old_methods = ikh->methods(); |
3399 | 3313 |
3400 if (cp_ref->on_stack()) { | 3314 if (cp_ref->on_stack()) { |
3401 PreviousVersionNode * pv_node = NULL; | 3315 PreviousVersionNode * pv_node = NULL; |
3402 if (emcp_method_count == 0) { | 3316 if (emcp_method_count == 0) { |
3403 // non-shared ConstantPool gets a reference | 3317 // non-shared ConstantPool gets a reference |
3404 pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), NULL); | 3318 pv_node = new PreviousVersionNode(cp_ref, NULL); |
3405 RC_TRACE(0x00000400, | 3319 RC_TRACE(0x00000400, |
3406 ("add: all methods are obsolete; flushing any EMCP refs")); | 3320 ("add: all methods are obsolete; flushing any EMCP refs")); |
3407 } else { | 3321 } else { |
3408 int local_count = 0; | 3322 int local_count = 0; |
3409 GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass) | 3323 GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass) |
3410 GrowableArray<Method*>(emcp_method_count, true); | 3324 GrowableArray<Method*>(emcp_method_count, true); |
3411 for (int i = 0; i < old_methods->length(); i++) { | 3325 for (int i = 0; i < old_methods->length(); i++) { |
3412 if (emcp_methods->at(i)) { | 3326 if (emcp_methods->at(i)) { |
3413 // this old method is EMCP. Save it only if it's on the stack | 3327 // this old method is EMCP. Save it only if it's on the stack |
3414 Method* old_method = old_methods->at(i); | 3328 Method* old_method = old_methods->at(i); |
3415 if (old_method->on_stack()) { | 3329 if (old_method->on_stack()) { |
3416 method_refs->append(old_method); | 3330 method_refs->append(old_method); |
3331 } | |
3332 if (++local_count >= emcp_method_count) { | |
3333 // no more EMCP methods so bail out now | |
3334 break; | |
3417 } | 3335 } |
3418 if (++local_count >= emcp_method_count) { | |
3419 // no more EMCP methods so bail out now | |
3420 break; | |
3421 } | 3336 } |
3422 } | 3337 } |
3423 } | |
3424 // non-shared ConstantPool gets a reference | 3338 // non-shared ConstantPool gets a reference |
3425 pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), method_refs); | 3339 pv_node = new PreviousVersionNode(cp_ref, method_refs); |
3426 } | 3340 } |
3427 // append new previous version. | 3341 // append new previous version. |
3428 _previous_versions->append(pv_node); | 3342 _previous_versions->append(pv_node); |
3429 } | 3343 } |
3430 | 3344 |
3431 // Since the caller is the VMThread and we are at a safepoint, this | 3345 // Since the caller is the VMThread and we are at a safepoint, this |
3432 // is a good time to clear out unused references. | 3346 // is a good time to clear out unused references. |
3433 | 3347 |
3524 m = methods()->at(index); | 3438 m = methods()->at(index); |
3525 if (m->method_idnum() == idnum) { | 3439 if (m->method_idnum() == idnum) { |
3526 return m; | 3440 return m; |
3527 } | 3441 } |
3528 } | 3442 } |
3443 // None found, return null for the caller to handle. | |
3444 return NULL; | |
3529 } | 3445 } |
3530 return m; | 3446 return m; |
3531 } | 3447 } |
3532 | 3448 |
3533 jint InstanceKlass::get_cached_class_file_len() { | 3449 jint InstanceKlass::get_cached_class_file_len() { |
3540 | 3456 |
3541 | 3457 |
3542 // Construct a PreviousVersionNode entry for the array hung off | 3458 // Construct a PreviousVersionNode entry for the array hung off |
3543 // the InstanceKlass. | 3459 // the InstanceKlass. |
3544 PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool, | 3460 PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool, |
3545 bool prev_cp_is_weak, GrowableArray<Method*>* prev_EMCP_methods) { | 3461 GrowableArray<Method*>* prev_EMCP_methods) { |
3546 | 3462 |
3547 _prev_constant_pool = prev_constant_pool; | 3463 _prev_constant_pool = prev_constant_pool; |
3548 _prev_cp_is_weak = prev_cp_is_weak; | |
3549 _prev_EMCP_methods = prev_EMCP_methods; | 3464 _prev_EMCP_methods = prev_EMCP_methods; |
3550 } | 3465 } |
3551 | 3466 |
3552 | 3467 |
3553 // Destroy a PreviousVersionNode | 3468 // Destroy a PreviousVersionNode |
3559 if (_prev_EMCP_methods != NULL) { | 3474 if (_prev_EMCP_methods != NULL) { |
3560 delete _prev_EMCP_methods; | 3475 delete _prev_EMCP_methods; |
3561 } | 3476 } |
3562 } | 3477 } |
3563 | 3478 |
3564 | |
3565 // Construct a PreviousVersionInfo entry | |
3566 PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) { | |
3567 _prev_constant_pool_handle = constantPoolHandle(); // NULL handle | |
3568 _prev_EMCP_method_handles = NULL; | |
3569 | |
3570 ConstantPool* cp = pv_node->prev_constant_pool(); | |
3571 assert(cp != NULL, "constant pool ref was unexpectedly cleared"); | |
3572 if (cp == NULL) { | |
3573 return; // robustness | |
3574 } | |
3575 | |
3576 // make the ConstantPool* safe to return | |
3577 _prev_constant_pool_handle = constantPoolHandle(cp); | |
3578 | |
3579 GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods(); | |
3580 if (method_refs == NULL) { | |
3581 // the InstanceKlass did not have any EMCP methods | |
3582 return; | |
3583 } | |
3584 | |
3585 _prev_EMCP_method_handles = new GrowableArray<methodHandle>(10); | |
3586 | |
3587 int n_methods = method_refs->length(); | |
3588 for (int i = 0; i < n_methods; i++) { | |
3589 Method* method = method_refs->at(i); | |
3590 assert (method != NULL, "method has been cleared"); | |
3591 if (method == NULL) { | |
3592 continue; // robustness | |
3593 } | |
3594 // make the Method* safe to return | |
3595 _prev_EMCP_method_handles->append(methodHandle(method)); | |
3596 } | |
3597 } | |
3598 | |
3599 | |
3600 // Destroy a PreviousVersionInfo | |
3601 PreviousVersionInfo::~PreviousVersionInfo() { | |
3602 // Since _prev_EMCP_method_handles is not C-heap allocated, we | |
3603 // don't have to delete it. | |
3604 } | |
3605 | |
3606 | |
3607 // Construct a helper for walking the previous versions array | 3479 // Construct a helper for walking the previous versions array |
3608 PreviousVersionWalker::PreviousVersionWalker(InstanceKlass *ik) { | 3480 PreviousVersionWalker::PreviousVersionWalker(Thread* thread, InstanceKlass *ik) { |
3481 _thread = thread; | |
3609 _previous_versions = ik->previous_versions(); | 3482 _previous_versions = ik->previous_versions(); |
3610 _current_index = 0; | 3483 _current_index = 0; |
3611 // _hm needs no initialization | |
3612 _current_p = NULL; | 3484 _current_p = NULL; |
3613 } | 3485 _current_constant_pool_handle = constantPoolHandle(thread, ik->constants()); |
3614 | |
3615 | |
3616 // Destroy a PreviousVersionWalker | |
3617 PreviousVersionWalker::~PreviousVersionWalker() { | |
3618 // Delete the current info just in case the caller didn't walk to | |
3619 // the end of the previous versions list. No harm if _current_p is | |
3620 // already NULL. | |
3621 delete _current_p; | |
3622 | |
3623 // When _hm is destroyed, all the Handles returned in | |
3624 // PreviousVersionInfo objects will be destroyed. | |
3625 // Also, after this destructor is finished it will be | |
3626 // safe to delete the GrowableArray allocated in the | |
3627 // PreviousVersionInfo objects. | |
3628 } | 3486 } |
3629 | 3487 |
3630 | 3488 |
3631 // Return the interesting information for the next previous version | 3489 // Return the interesting information for the next previous version |
3632 // of the klass. Returns NULL if there are no more previous versions. | 3490 // of the klass. Returns NULL if there are no more previous versions. |
3633 PreviousVersionInfo* PreviousVersionWalker::next_previous_version() { | 3491 PreviousVersionNode* PreviousVersionWalker::next_previous_version() { |
3634 if (_previous_versions == NULL) { | 3492 if (_previous_versions == NULL) { |
3635 // no previous versions so nothing to return | 3493 // no previous versions so nothing to return |
3636 return NULL; | 3494 return NULL; |
3637 } | 3495 } |
3638 | 3496 |
3639 delete _current_p; // cleanup the previous info for the caller | 3497 _current_p = NULL; // reset to NULL |
3640 _current_p = NULL; // reset to NULL so we don't delete same object twice | 3498 _current_constant_pool_handle = NULL; |
3641 | 3499 |
3642 int length = _previous_versions->length(); | 3500 int length = _previous_versions->length(); |
3643 | 3501 |
3644 while (_current_index < length) { | 3502 while (_current_index < length) { |
3645 PreviousVersionNode * pv_node = _previous_versions->at(_current_index++); | 3503 PreviousVersionNode * pv_node = _previous_versions->at(_current_index++); |
3646 PreviousVersionInfo * pv_info = new (ResourceObj::C_HEAP, mtClass) | 3504 |
3647 PreviousVersionInfo(pv_node); | 3505 // Save a handle to the constant pool for this previous version, |
3648 | 3506 // which keeps all the methods from being deallocated. |
3649 constantPoolHandle cp_h = pv_info->prev_constant_pool_handle(); | 3507 _current_constant_pool_handle = constantPoolHandle(_thread, pv_node->prev_constant_pool()); |
3650 assert (!cp_h.is_null(), "null cp found in previous version"); | 3508 _current_p = pv_node; |
3651 | 3509 return pv_node; |
3652 // The caller will need to delete pv_info when they are done with it. | 3510 } |
3653 _current_p = pv_info; | 3511 |
3654 return pv_info; | |
3655 } | |
3656 | |
3657 // all of the underlying nodes' info has been deleted | |
3658 return NULL; | 3512 return NULL; |
3659 } // end next_previous_version() | 3513 } // end next_previous_version() |