comparison src/share/vm/classfile/javaClasses.cpp @ 2177:3582bf76420e

6990754: Use native memory and reference counting to implement SymbolTable Summary: move symbols from permgen into C heap and reference count them Reviewed-by: never, acorn, jmasa, stefank
author coleenp
date Thu, 27 Jan 2011 16:11:27 -0800
parents 017cd8bce8a8
children 72dee110246f
comparison
equal deleted inserted replaced
2176:27e4ea99855d 2177:3582bf76420e
34 #include "memory/universe.inline.hpp" 34 #include "memory/universe.inline.hpp"
35 #include "oops/instanceKlass.hpp" 35 #include "oops/instanceKlass.hpp"
36 #include "oops/klass.hpp" 36 #include "oops/klass.hpp"
37 #include "oops/klassOop.hpp" 37 #include "oops/klassOop.hpp"
38 #include "oops/methodOop.hpp" 38 #include "oops/methodOop.hpp"
39 #include "oops/symbolOop.hpp" 39 #include "oops/symbol.hpp"
40 #include "oops/typeArrayOop.hpp" 40 #include "oops/typeArrayOop.hpp"
41 #include "runtime/fieldDescriptor.hpp" 41 #include "runtime/fieldDescriptor.hpp"
42 #include "runtime/handles.inline.hpp" 42 #include "runtime/handles.inline.hpp"
43 #include "runtime/interfaceSupport.hpp" 43 #include "runtime/interfaceSupport.hpp"
44 #include "runtime/java.hpp" 44 #include "runtime/java.hpp"
55 #ifdef TARGET_OS_FAMILY_windows 55 #ifdef TARGET_OS_FAMILY_windows
56 # include "thread_windows.inline.hpp" 56 # include "thread_windows.inline.hpp"
57 #endif 57 #endif
58 58
59 static bool find_field(instanceKlass* ik, 59 static bool find_field(instanceKlass* ik,
60 symbolOop name_symbol, symbolOop signature_symbol, 60 Symbol* name_symbol, Symbol* signature_symbol,
61 fieldDescriptor* fd, 61 fieldDescriptor* fd,
62 bool allow_super = false) { 62 bool allow_super = false) {
63 if (allow_super) 63 if (allow_super)
64 return ik->find_field(name_symbol, signature_symbol, fd) != NULL; 64 return ik->find_field(name_symbol, signature_symbol, fd) != NULL;
65 else 65 else
67 } 67 }
68 68
69 // Helpful routine for computing field offsets at run time rather than hardcoding them 69 // Helpful routine for computing field offsets at run time rather than hardcoding them
70 static void 70 static void
71 compute_offset(int &dest_offset, 71 compute_offset(int &dest_offset,
72 klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol, 72 klassOop klass_oop, Symbol* name_symbol, Symbol* signature_symbol,
73 bool allow_super = false) { 73 bool allow_super = false) {
74 fieldDescriptor fd; 74 fieldDescriptor fd;
75 instanceKlass* ik = instanceKlass::cast(klass_oop); 75 instanceKlass* ik = instanceKlass::cast(klass_oop);
76 if (!find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) { 76 if (!find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) {
77 ResourceMark rm; 77 ResourceMark rm;
82 } 82 }
83 83
84 // Same as above but for "optional" offsets that might not be present in certain JDK versions 84 // Same as above but for "optional" offsets that might not be present in certain JDK versions
85 static void 85 static void
86 compute_optional_offset(int& dest_offset, 86 compute_optional_offset(int& dest_offset,
87 klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol, 87 klassOop klass_oop, Symbol* name_symbol, Symbol* signature_symbol,
88 bool allow_super = false) { 88 bool allow_super = false) {
89 fieldDescriptor fd; 89 fieldDescriptor fd;
90 instanceKlass* ik = instanceKlass::cast(klass_oop); 90 instanceKlass* ik = instanceKlass::cast(klass_oop);
91 if (find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) { 91 if (find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) {
92 dest_offset = fd.offset(); 92 dest_offset = fd.offset();
162 oop java_lang_String::create_oop_from_str(const char* utf8_str, TRAPS) { 162 oop java_lang_String::create_oop_from_str(const char* utf8_str, TRAPS) {
163 Handle h_obj = create_from_str(utf8_str, CHECK_0); 163 Handle h_obj = create_from_str(utf8_str, CHECK_0);
164 return h_obj(); 164 return h_obj();
165 } 165 }
166 166
167 Handle java_lang_String::create_from_symbol(symbolHandle symbol, TRAPS) { 167 Handle java_lang_String::create_from_symbol(Symbol* symbol, TRAPS) {
168 int length = UTF8::unicode_length((char*)symbol->bytes(), symbol->utf8_length()); 168 int length = UTF8::unicode_length((char*)symbol->bytes(), symbol->utf8_length());
169 Handle h_obj = basic_create(length, false, CHECK_NH); 169 Handle h_obj = basic_create(length, false, CHECK_NH);
170 if (length > 0) { 170 if (length > 0) {
171 UTF8::convert_to_unicode((char*)symbol->bytes(), value(h_obj())->char_at_addr(0), length); 171 UTF8::convert_to_unicode((char*)symbol->bytes(), value(h_obj())->char_at_addr(0), length);
172 } 172 }
276 result[index] = value->char_at(index + offset); 276 result[index] = value->char_at(index + offset);
277 } 277 }
278 return result; 278 return result;
279 } 279 }
280 280
281 symbolHandle java_lang_String::as_symbol(Handle java_string, TRAPS) { 281 Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) {
282 oop obj = java_string(); 282 oop obj = java_string();
283 typeArrayOop value = java_lang_String::value(obj); 283 typeArrayOop value = java_lang_String::value(obj);
284 int offset = java_lang_String::offset(obj); 284 int offset = java_lang_String::offset(obj);
285 int length = java_lang_String::length(obj); 285 int length = java_lang_String::length(obj);
286 jchar* base = (length == 0) ? NULL : value->char_at_addr(offset); 286 jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
287 symbolOop sym = SymbolTable::lookup_unicode(base, length, THREAD); 287 Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD);
288 return symbolHandle(THREAD, sym); 288 return sym;
289 } 289 }
290 290
291 symbolOop java_lang_String::as_symbol_or_null(oop java_string) { 291 Symbol* java_lang_String::as_symbol_or_null(oop java_string) {
292 typeArrayOop value = java_lang_String::value(java_string); 292 typeArrayOop value = java_lang_String::value(java_string);
293 int offset = java_lang_String::offset(java_string); 293 int offset = java_lang_String::offset(java_string);
294 int length = java_lang_String::length(java_string); 294 int length = java_lang_String::length(java_string);
295 jchar* base = (length == 0) ? NULL : value->char_at_addr(offset); 295 jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
296 return SymbolTable::probe_unicode(base, length); 296 return SymbolTable::probe_unicode(base, length);
435 } 435 }
436 436
437 437
438 void java_lang_Class::print_signature(oop java_class, outputStream* st) { 438 void java_lang_Class::print_signature(oop java_class, outputStream* st) {
439 assert(java_lang_Class::is_instance(java_class), "must be a Class object"); 439 assert(java_lang_Class::is_instance(java_class), "must be a Class object");
440 symbolOop name = NULL; 440 Symbol* name = NULL;
441 bool is_instance = false; 441 bool is_instance = false;
442 if (is_primitive(java_class)) { 442 if (is_primitive(java_class)) {
443 name = vmSymbols::type_signature(primitive_type(java_class)); 443 name = vmSymbols::type_signature(primitive_type(java_class));
444 } else { 444 } else {
445 klassOop k = as_klassOop(java_class); 445 klassOop k = as_klassOop(java_class);
453 if (is_instance) st->print("L"); 453 if (is_instance) st->print("L");
454 st->write((char*) name->base(), (int) name->utf8_length()); 454 st->write((char*) name->base(), (int) name->utf8_length());
455 if (is_instance) st->print(";"); 455 if (is_instance) st->print(";");
456 } 456 }
457 457
458 symbolOop java_lang_Class::as_signature(oop java_class, bool intern_if_not_found, TRAPS) { 458 Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found, TRAPS) {
459 assert(java_lang_Class::is_instance(java_class), "must be a Class object"); 459 assert(java_lang_Class::is_instance(java_class), "must be a Class object");
460 symbolOop name = NULL; 460 Symbol* name;
461 if (is_primitive(java_class)) { 461 if (is_primitive(java_class)) {
462 return vmSymbols::type_signature(primitive_type(java_class)); 462 name = vmSymbols::type_signature(primitive_type(java_class));
463 // Because this can create a new symbol, the caller has to decrement
464 // the refcount, so make adjustment here and below for symbols returned
465 // that are not created or incremented due to a successful lookup.
466 name->increment_refcount();
463 } else { 467 } else {
464 klassOop k = as_klassOop(java_class); 468 klassOop k = as_klassOop(java_class);
465 if (!Klass::cast(k)->oop_is_instance()) { 469 if (!Klass::cast(k)->oop_is_instance()) {
466 return Klass::cast(k)->name(); 470 name = Klass::cast(k)->name();
471 name->increment_refcount();
467 } else { 472 } else {
468 ResourceMark rm; 473 ResourceMark rm;
469 const char* sigstr = Klass::cast(k)->signature_name(); 474 const char* sigstr = Klass::cast(k)->signature_name();
470 int siglen = (int) strlen(sigstr); 475 int siglen = (int) strlen(sigstr);
471 if (!intern_if_not_found) 476 if (!intern_if_not_found) {
472 return SymbolTable::probe(sigstr, siglen); 477 name = SymbolTable::probe(sigstr, siglen);
473 else 478 } else {
474 return oopFactory::new_symbol(sigstr, siglen, THREAD); 479 name = SymbolTable::new_symbol(sigstr, siglen, THREAD);
480 }
475 } 481 }
476 } 482 }
483 return name;
477 } 484 }
478 485
479 486
480 klassOop java_lang_Class::array_klass(oop java_class) { 487 klassOop java_lang_Class::array_klass(oop java_class) {
481 klassOop k = klassOop(java_class->obj_field(array_klass_offset)); 488 klassOop k = klassOop(java_class->obj_field(array_klass_offset));
1020 Handle arg (THREAD, oopFactory::new_charArray(str, THREAD)); 1027 Handle arg (THREAD, oopFactory::new_charArray(str, THREAD));
1021 if (!HAS_PENDING_EXCEPTION) { 1028 if (!HAS_PENDING_EXCEPTION) {
1022 JavaCalls::call_virtual(&result, 1029 JavaCalls::call_virtual(&result,
1023 stream, 1030 stream,
1024 KlassHandle(THREAD, stream->klass()), 1031 KlassHandle(THREAD, stream->klass()),
1025 vmSymbolHandles::println_name(), 1032 vmSymbols::println_name(),
1026 vmSymbolHandles::char_array_void_signature(), 1033 vmSymbols::char_array_void_signature(),
1027 arg, 1034 arg,
1028 THREAD); 1035 THREAD);
1029 } 1036 }
1030 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. 1037 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
1031 if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION; 1038 if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION;
1075 EXCEPTION_MARK; 1082 EXCEPTION_MARK;
1076 JavaValue result(T_OBJECT); 1083 JavaValue result(T_OBJECT);
1077 JavaCalls::call_virtual(&result, 1084 JavaCalls::call_virtual(&result,
1078 h_throwable, 1085 h_throwable,
1079 KlassHandle(THREAD, h_throwable->klass()), 1086 KlassHandle(THREAD, h_throwable->klass()),
1080 vmSymbolHandles::getCause_name(), 1087 vmSymbols::getCause_name(),
1081 vmSymbolHandles::void_throwable_signature(), 1088 vmSymbols::void_throwable_signature(),
1082 THREAD); 1089 THREAD);
1083 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. 1090 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
1084 if (HAS_PENDING_EXCEPTION) { 1091 if (HAS_PENDING_EXCEPTION) {
1085 CLEAR_PENDING_EXCEPTION; 1092 CLEAR_PENDING_EXCEPTION;
1086 h_throwable = Handle(); 1093 h_throwable = Handle();
1514 java_lang_StackTraceElement::set_declaringClass(element(), classname); 1521 java_lang_StackTraceElement::set_declaringClass(element(), classname);
1515 // Fill in method name 1522 // Fill in method name
1516 oop methodname = StringTable::intern(method->name(), CHECK_0); 1523 oop methodname = StringTable::intern(method->name(), CHECK_0);
1517 java_lang_StackTraceElement::set_methodName(element(), methodname); 1524 java_lang_StackTraceElement::set_methodName(element(), methodname);
1518 // Fill in source file name 1525 // Fill in source file name
1519 symbolOop source = instanceKlass::cast(method->method_holder())->source_file_name(); 1526 Symbol* source = instanceKlass::cast(method->method_holder())->source_file_name();
1520 oop filename = StringTable::intern(source, CHECK_0); 1527 oop filename = StringTable::intern(source, CHECK_0);
1521 java_lang_StackTraceElement::set_fileName(element(), filename); 1528 java_lang_StackTraceElement::set_fileName(element(), filename);
1522 // File in source line number 1529 // File in source line number
1523 int line_number; 1530 int line_number;
1524 if (method->is_native()) { 1531 if (method->is_native()) {
1730 compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); 1737 compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature());
1731 } 1738 }
1732 1739
1733 Handle java_lang_reflect_Constructor::create(TRAPS) { 1740 Handle java_lang_reflect_Constructor::create(TRAPS) {
1734 assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 1741 assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
1735 symbolHandle name = vmSymbolHandles::java_lang_reflect_Constructor(); 1742 Symbol* name = vmSymbols::java_lang_reflect_Constructor();
1736 klassOop k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); 1743 klassOop k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH);
1737 instanceKlassHandle klass (THREAD, k); 1744 instanceKlassHandle klass (THREAD, k);
1738 // Ensure it is initialized 1745 // Ensure it is initialized
1739 klass->initialize(CHECK_NH); 1746 klass->initialize(CHECK_NH);
1740 return klass->allocate_instance_handle(CHECK_NH); 1747 return klass->allocate_instance_handle(CHECK_NH);
1852 compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); 1859 compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature());
1853 } 1860 }
1854 1861
1855 Handle java_lang_reflect_Field::create(TRAPS) { 1862 Handle java_lang_reflect_Field::create(TRAPS) {
1856 assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 1863 assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
1857 symbolHandle name = vmSymbolHandles::java_lang_reflect_Field(); 1864 Symbol* name = vmSymbols::java_lang_reflect_Field();
1858 klassOop k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); 1865 klassOop k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH);
1859 instanceKlassHandle klass (THREAD, k); 1866 instanceKlassHandle klass (THREAD, k);
1860 // Ensure it is initialized 1867 // Ensure it is initialized
1861 klass->initialize(CHECK_NH); 1868 klass->initialize(CHECK_NH);
1862 return klass->allocate_instance_handle(CHECK_NH); 1869 return klass->allocate_instance_handle(CHECK_NH);
2420 } 2427 }
2421 st->print(")"); 2428 st->print(")");
2422 java_lang_Class::print_signature(rtype(mt), st); 2429 java_lang_Class::print_signature(rtype(mt), st);
2423 } 2430 }
2424 2431
2425 symbolOop java_dyn_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) { 2432 Symbol* java_dyn_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) {
2426 ResourceMark rm; 2433 ResourceMark rm;
2427 stringStream buffer(128); 2434 stringStream buffer(128);
2428 print_signature(mt, &buffer); 2435 print_signature(mt, &buffer);
2429 const char* sigstr = buffer.base(); 2436 const char* sigstr = buffer.base();
2430 int siglen = (int) buffer.size(); 2437 int siglen = (int) buffer.size();
2431 if (!intern_if_not_found) 2438 Symbol *name;
2432 return SymbolTable::probe(sigstr, siglen); 2439 if (!intern_if_not_found) {
2433 else 2440 name = SymbolTable::probe(sigstr, siglen);
2434 return oopFactory::new_symbol(sigstr, siglen, THREAD); 2441 } else {
2442 name = SymbolTable::new_symbol(sigstr, siglen, THREAD);
2443 }
2444 return name;
2435 } 2445 }
2436 2446
2437 oop java_dyn_MethodType::rtype(oop mt) { 2447 oop java_dyn_MethodType::rtype(oop mt) {
2438 assert(is_instance(mt), "must be a MethodType"); 2448 assert(is_instance(mt), "must be a MethodType");
2439 return mt->obj_field(_rtype_offset); 2449 return mt->obj_field(_rtype_offset);
2906 // against changes in the class files 2916 // against changes in the class files
2907 2917
2908 bool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) { 2918 bool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) {
2909 EXCEPTION_MARK; 2919 EXCEPTION_MARK;
2910 fieldDescriptor fd; 2920 fieldDescriptor fd;
2911 symbolHandle klass_sym = oopFactory::new_symbol_handle(klass_name, CATCH); 2921 TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH);
2912 klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH); 2922 klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
2913 instanceKlassHandle h_klass (THREAD, k); 2923 instanceKlassHandle h_klass (THREAD, k);
2914 //instanceKlassHandle h_klass(klass); 2924 TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
2915 symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH); 2925 TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH);
2916 symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH); 2926 if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
2917 if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) {
2918 tty->print_cr("Nonstatic field %s.%s not found", klass_name, field_name); 2927 tty->print_cr("Nonstatic field %s.%s not found", klass_name, field_name);
2919 return false; 2928 return false;
2920 } 2929 }
2921 if (fd.is_static()) { 2930 if (fd.is_static()) {
2922 tty->print_cr("Nonstatic field %s.%s appears to be static", klass_name, field_name); 2931 tty->print_cr("Nonstatic field %s.%s appears to be static", klass_name, field_name);
2933 2942
2934 2943
2935 bool JavaClasses::check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) { 2944 bool JavaClasses::check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) {
2936 EXCEPTION_MARK; 2945 EXCEPTION_MARK;
2937 fieldDescriptor fd; 2946 fieldDescriptor fd;
2938 symbolHandle klass_sym = oopFactory::new_symbol_handle(klass_name, CATCH); 2947 TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH);
2939 klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH); 2948 klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
2940 instanceKlassHandle h_klass (THREAD, k); 2949 instanceKlassHandle h_klass (THREAD, k);
2941 symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH); 2950 TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
2942 symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH); 2951 TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH);
2943 if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) { 2952 if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
2944 tty->print_cr("Static field %s.%s not found", klass_name, field_name); 2953 tty->print_cr("Static field %s.%s not found", klass_name, field_name);
2945 return false; 2954 return false;
2946 } 2955 }
2947 if (!fd.is_static()) { 2956 if (!fd.is_static()) {
2948 tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name); 2957 tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name);
2958 2967
2959 2968
2960 bool JavaClasses::check_constant(const char *klass_name, int hardcoded_constant, const char *field_name, const char* field_sig) { 2969 bool JavaClasses::check_constant(const char *klass_name, int hardcoded_constant, const char *field_name, const char* field_sig) {
2961 EXCEPTION_MARK; 2970 EXCEPTION_MARK;
2962 fieldDescriptor fd; 2971 fieldDescriptor fd;
2963 symbolHandle klass_sym = oopFactory::new_symbol_handle(klass_name, CATCH); 2972 TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH);
2964 klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH); 2973 klassOop k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
2965 instanceKlassHandle h_klass (THREAD, k); 2974 instanceKlassHandle h_klass (THREAD, k);
2966 symbolHandle f_name = oopFactory::new_symbol_handle(field_name, CATCH); 2975 TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
2967 symbolHandle f_sig = oopFactory::new_symbol_handle(field_sig, CATCH); 2976 TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH);
2968 if (!h_klass->find_local_field(f_name(), f_sig(), &fd)) { 2977 if (!h_klass->find_local_field(f_name, f_sig, &fd)) {
2969 tty->print_cr("Static field %s.%s not found", klass_name, field_name); 2978 tty->print_cr("Static field %s.%s not found", klass_name, field_name);
2970 return false; 2979 return false;
2971 } 2980 }
2972 if (!fd.is_static() || !fd.has_initial_value()) { 2981 if (!fd.is_static() || !fd.has_initial_value()) {
2973 tty->print_cr("Static field %s.%s appears to be non-constant", klass_name, field_name); 2982 tty->print_cr("Static field %s.%s appears to be non-constant", klass_name, field_name);