Mercurial > hg > graal-compiler
comparison src/share/vm/oops/instanceKlass.cpp @ 12264:b2e698d2276c
8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation
Summary: Enhance method resolution and resulting data structures, plus some refactoring.
Reviewed-by: twisti, acorn, jrose
author | drchase |
---|---|
date | Fri, 13 Sep 2013 22:38:02 -0400 |
parents | e22ee8e7ae62 |
children | 0f37d1badced |
comparison
equal
deleted
inserted
replaced
12261:2c98370f2611 | 12264:b2e698d2276c |
---|---|
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_index(0); | 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); |
1681 if (jmeths != NULL && // If there is a cache | 1678 if (jmeths != NULL && // If there is a cache |
1682 (length = (size_t)jmeths[0]) > idnum) { // and if it is long enough, | 1679 (length = (size_t)jmeths[0]) > idnum) { // and if it is long enough, |
1683 id = jmeths[idnum+1]; // Look up the id (may be NULL) | 1680 id = jmeths[idnum+1]; // Look up the id (may be NULL) |
1684 } | 1681 } |
1685 return id; | 1682 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 } | 1683 } |
1768 | 1684 |
1769 | 1685 |
1770 // | 1686 // |
1771 // Walk the list of dependent nmethods searching for nmethods which | 1687 // Walk the list of dependent nmethods searching for nmethods which |
2324 delete mnt; | 2240 delete mnt; |
2325 set_member_names(NULL); | 2241 set_member_names(NULL); |
2326 } | 2242 } |
2327 } | 2243 } |
2328 | 2244 |
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 | 2245 // release dependencies |
2336 nmethodBucket* b = _dependencies; | 2246 nmethodBucket* b = _dependencies; |
2337 _dependencies = NULL; | 2247 _dependencies = NULL; |
2338 while (b != NULL) { | 2248 while (b != NULL) { |
2339 nmethodBucket* next = b->next(); | 2249 nmethodBucket* next = b->next(); |
2780 | 2690 |
2781 static const char* state_names[] = { | 2691 static const char* state_names[] = { |
2782 "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error" | 2692 "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error" |
2783 }; | 2693 }; |
2784 | 2694 |
2695 static void print_vtable(intptr_t* start, int len, outputStream* st) { | |
2696 for (int i = 0; i < len; i++) { | |
2697 intptr_t e = start[i]; | |
2698 st->print("%d : " INTPTR_FORMAT, i, e); | |
2699 if (e != 0 && ((Metadata*)e)->is_metaspace_object()) { | |
2700 st->print(" "); | |
2701 ((Metadata*)e)->print_value_on(st); | |
2702 } | |
2703 st->cr(); | |
2704 } | |
2705 } | |
2706 | |
2785 void InstanceKlass::print_on(outputStream* st) const { | 2707 void InstanceKlass::print_on(outputStream* st) const { |
2786 assert(is_klass(), "must be klass"); | 2708 assert(is_klass(), "must be klass"); |
2787 Klass::print_on(st); | 2709 Klass::print_on(st); |
2788 | 2710 |
2789 st->print(BULLET"instance size: %d", size_helper()); st->cr(); | 2711 st->print(BULLET"instance size: %d", size_helper()); st->cr(); |
2814 } | 2736 } |
2815 } | 2737 } |
2816 | 2738 |
2817 st->print(BULLET"arrays: "); array_klasses()->print_value_on_maybe_null(st); st->cr(); | 2739 st->print(BULLET"arrays: "); array_klasses()->print_value_on_maybe_null(st); st->cr(); |
2818 st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr(); | 2740 st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr(); |
2819 if (Verbose) { | 2741 if (Verbose || WizardMode) { |
2820 Array<Method*>* method_array = methods(); | 2742 Array<Method*>* method_array = methods(); |
2821 for(int i = 0; i < method_array->length(); i++) { | 2743 for(int i = 0; i < method_array->length(); i++) { |
2822 st->print("%d : ", i); method_array->at(i)->print_value(); st->cr(); | 2744 st->print("%d : ", i); method_array->at(i)->print_value(); st->cr(); |
2823 } | 2745 } |
2824 } | 2746 } |
2872 st->cr(); | 2794 st->cr(); |
2873 } | 2795 } |
2874 st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr(); | 2796 st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr(); |
2875 st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr(); | 2797 st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr(); |
2876 st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), start_of_vtable()); st->cr(); | 2798 st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), start_of_vtable()); st->cr(); |
2799 if (vtable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_vtable(), vtable_length(), st); | |
2877 st->print(BULLET"itable length %d (start addr: " INTPTR_FORMAT ")", itable_length(), start_of_itable()); st->cr(); | 2800 st->print(BULLET"itable length %d (start addr: " INTPTR_FORMAT ")", itable_length(), start_of_itable()); st->cr(); |
2801 if (itable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_itable(), itable_length(), st); | |
2878 st->print_cr(BULLET"---- static fields (%d words):", static_field_size()); | 2802 st->print_cr(BULLET"---- static fields (%d words):", static_field_size()); |
2879 FieldPrinter print_static_field(st); | 2803 FieldPrinter print_static_field(st); |
2880 ((InstanceKlass*)this)->do_local_static_fields(&print_static_field); | 2804 ((InstanceKlass*)this)->do_local_static_fields(&print_static_field); |
2881 st->print_cr(BULLET"---- non-static fields (%d words):", nonstatic_field_size()); | 2805 st->print_cr(BULLET"---- non-static fields (%d words):", nonstatic_field_size()); |
2882 FieldPrinter print_nonstatic_field(st); | 2806 FieldPrinter print_nonstatic_field(st); |
2894 | 2818 |
2895 #endif //PRODUCT | 2819 #endif //PRODUCT |
2896 | 2820 |
2897 void InstanceKlass::print_value_on(outputStream* st) const { | 2821 void InstanceKlass::print_value_on(outputStream* st) const { |
2898 assert(is_klass(), "must be klass"); | 2822 assert(is_klass(), "must be klass"); |
2823 if (Verbose || WizardMode) access_flags().print_on(st); | |
2899 name()->print_value_on(st); | 2824 name()->print_value_on(st); |
2900 } | 2825 } |
2901 | 2826 |
2902 #ifndef PRODUCT | 2827 #ifndef PRODUCT |
2903 | 2828 |