Mercurial > hg > graal-jvmci-8
comparison src/share/vm/ci/ciEnv.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 | 9afee0b9fc1d |
children | d25d4ca69222 4f26f535a225 |
comparison
equal
deleted
inserted
replaced
2176:27e4ea99855d | 2177:3582bf76420e |
---|---|
66 // This class is the top level broker for requests from the compiler | 66 // This class is the top level broker for requests from the compiler |
67 // to the VM. | 67 // to the VM. |
68 | 68 |
69 ciObject* ciEnv::_null_object_instance; | 69 ciObject* ciEnv::_null_object_instance; |
70 ciMethodKlass* ciEnv::_method_klass_instance; | 70 ciMethodKlass* ciEnv::_method_klass_instance; |
71 ciSymbolKlass* ciEnv::_symbol_klass_instance; | |
72 ciKlassKlass* ciEnv::_klass_klass_instance; | 71 ciKlassKlass* ciEnv::_klass_klass_instance; |
73 ciInstanceKlassKlass* ciEnv::_instance_klass_klass_instance; | 72 ciInstanceKlassKlass* ciEnv::_instance_klass_klass_instance; |
74 ciTypeArrayKlassKlass* ciEnv::_type_array_klass_klass_instance; | 73 ciTypeArrayKlassKlass* ciEnv::_type_array_klass_klass_instance; |
75 ciObjArrayKlassKlass* ciEnv::_obj_array_klass_klass_instance; | 74 ciObjArrayKlassKlass* ciEnv::_obj_array_klass_klass_instance; |
76 | 75 |
200 _the_min_jint_string = NULL; | 199 _the_min_jint_string = NULL; |
201 } | 200 } |
202 | 201 |
203 ciEnv::~ciEnv() { | 202 ciEnv::~ciEnv() { |
204 CompilerThread* current_thread = CompilerThread::current(); | 203 CompilerThread* current_thread = CompilerThread::current(); |
204 _factory->remove_symbols(); | |
205 current_thread->set_env(NULL); | 205 current_thread->set_env(NULL); |
206 } | 206 } |
207 | 207 |
208 // ------------------------------------------------------------------ | 208 // ------------------------------------------------------------------ |
209 // Cache Jvmti state | 209 // Cache Jvmti state |
232 } | 232 } |
233 } | 233 } |
234 | 234 |
235 // ------------------------------------------------------------------ | 235 // ------------------------------------------------------------------ |
236 // helper for lazy exception creation | 236 // helper for lazy exception creation |
237 ciInstance* ciEnv::get_or_create_exception(jobject& handle, symbolHandle name) { | 237 ciInstance* ciEnv::get_or_create_exception(jobject& handle, Symbol* name) { |
238 VM_ENTRY_MARK; | 238 VM_ENTRY_MARK; |
239 if (handle == NULL) { | 239 if (handle == NULL) { |
240 // Cf. universe.cpp, creation of Universe::_null_ptr_exception_instance. | 240 // Cf. universe.cpp, creation of Universe::_null_ptr_exception_instance. |
241 klassOop k = SystemDictionary::find(name, Handle(), Handle(), THREAD); | 241 klassOop k = SystemDictionary::find(name, Handle(), Handle(), THREAD); |
242 jobject objh = NULL; | 242 jobject objh = NULL; |
259 // ciEnv::ArrayIndexOutOfBoundsException_instance, etc. | 259 // ciEnv::ArrayIndexOutOfBoundsException_instance, etc. |
260 ciInstance* ciEnv::ArrayIndexOutOfBoundsException_instance() { | 260 ciInstance* ciEnv::ArrayIndexOutOfBoundsException_instance() { |
261 if (_ArrayIndexOutOfBoundsException_instance == NULL) { | 261 if (_ArrayIndexOutOfBoundsException_instance == NULL) { |
262 _ArrayIndexOutOfBoundsException_instance | 262 _ArrayIndexOutOfBoundsException_instance |
263 = get_or_create_exception(_ArrayIndexOutOfBoundsException_handle, | 263 = get_or_create_exception(_ArrayIndexOutOfBoundsException_handle, |
264 vmSymbolHandles::java_lang_ArrayIndexOutOfBoundsException()); | 264 vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); |
265 } | 265 } |
266 return _ArrayIndexOutOfBoundsException_instance; | 266 return _ArrayIndexOutOfBoundsException_instance; |
267 } | 267 } |
268 ciInstance* ciEnv::ArrayStoreException_instance() { | 268 ciInstance* ciEnv::ArrayStoreException_instance() { |
269 if (_ArrayStoreException_instance == NULL) { | 269 if (_ArrayStoreException_instance == NULL) { |
270 _ArrayStoreException_instance | 270 _ArrayStoreException_instance |
271 = get_or_create_exception(_ArrayStoreException_handle, | 271 = get_or_create_exception(_ArrayStoreException_handle, |
272 vmSymbolHandles::java_lang_ArrayStoreException()); | 272 vmSymbols::java_lang_ArrayStoreException()); |
273 } | 273 } |
274 return _ArrayStoreException_instance; | 274 return _ArrayStoreException_instance; |
275 } | 275 } |
276 ciInstance* ciEnv::ClassCastException_instance() { | 276 ciInstance* ciEnv::ClassCastException_instance() { |
277 if (_ClassCastException_instance == NULL) { | 277 if (_ClassCastException_instance == NULL) { |
278 _ClassCastException_instance | 278 _ClassCastException_instance |
279 = get_or_create_exception(_ClassCastException_handle, | 279 = get_or_create_exception(_ClassCastException_handle, |
280 vmSymbolHandles::java_lang_ClassCastException()); | 280 vmSymbols::java_lang_ClassCastException()); |
281 } | 281 } |
282 return _ClassCastException_instance; | 282 return _ClassCastException_instance; |
283 } | 283 } |
284 | 284 |
285 ciInstance* ciEnv::the_null_string() { | 285 ciInstance* ciEnv::the_null_string() { |
375 bool require_local) { | 375 bool require_local) { |
376 ASSERT_IN_VM; | 376 ASSERT_IN_VM; |
377 EXCEPTION_CONTEXT; | 377 EXCEPTION_CONTEXT; |
378 | 378 |
379 // Now we need to check the SystemDictionary | 379 // Now we need to check the SystemDictionary |
380 symbolHandle sym(THREAD, name->get_symbolOop()); | 380 Symbol* sym = name->get_symbol(); |
381 if (sym->byte_at(0) == 'L' && | 381 if (sym->byte_at(0) == 'L' && |
382 sym->byte_at(sym->utf8_length()-1) == ';') { | 382 sym->byte_at(sym->utf8_length()-1) == ';') { |
383 // This is a name from a signature. Strip off the trimmings. | 383 // This is a name from a signature. Strip off the trimmings. |
384 sym = oopFactory::new_symbol_handle(sym->as_utf8()+1, | 384 // Call recursive to keep scope of strippedsym. |
385 sym->utf8_length()-2, | 385 TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1, |
386 KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); | 386 sym->utf8_length()-2, |
387 name = get_object(sym())->as_symbol(); | 387 KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); |
388 ciSymbol* strippedname = get_symbol(strippedsym); | |
389 return get_klass_by_name_impl(accessing_klass, strippedname, require_local); | |
388 } | 390 } |
389 | 391 |
390 // Check for prior unloaded klass. The SystemDictionary's answers | 392 // Check for prior unloaded klass. The SystemDictionary's answers |
391 // can vary over time but the compiler needs consistency. | 393 // can vary over time but the compiler needs consistency. |
392 ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name); | 394 ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name); |
428 // is exhausted. | 430 // is exhausted. |
429 if (sym->byte_at(0) == '[' && | 431 if (sym->byte_at(0) == '[' && |
430 (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { | 432 (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { |
431 // We have an unloaded array. | 433 // We have an unloaded array. |
432 // Build it on the fly if the element class exists. | 434 // Build it on the fly if the element class exists. |
433 symbolOop elem_sym = oopFactory::new_symbol(sym->as_utf8()+1, | 435 TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1, |
434 sym->utf8_length()-1, | 436 sym->utf8_length()-1, |
435 KILL_COMPILE_ON_FATAL_(fail_type)); | 437 KILL_COMPILE_ON_FATAL_(fail_type)); |
438 | |
436 // Get element ciKlass recursively. | 439 // Get element ciKlass recursively. |
437 ciKlass* elem_klass = | 440 ciKlass* elem_klass = |
438 get_klass_by_name_impl(accessing_klass, | 441 get_klass_by_name_impl(accessing_klass, |
439 get_object(elem_sym)->as_symbol(), | 442 get_symbol(elem_sym), |
440 require_local); | 443 require_local); |
441 if (elem_klass != NULL && elem_klass->is_loaded()) { | 444 if (elem_klass != NULL && elem_klass->is_loaded()) { |
442 // Now make an array for it | 445 // Now make an array for it |
443 return ciObjArrayKlass::make_impl(elem_klass); | 446 return ciObjArrayKlass::make_impl(elem_klass); |
444 } | 447 } |
473 int index, | 476 int index, |
474 bool& is_accessible, | 477 bool& is_accessible, |
475 ciInstanceKlass* accessor) { | 478 ciInstanceKlass* accessor) { |
476 EXCEPTION_CONTEXT; | 479 EXCEPTION_CONTEXT; |
477 KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index)); | 480 KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index)); |
478 symbolHandle klass_name; | 481 Symbol* klass_name = NULL; |
479 if (klass.is_null()) { | 482 if (klass.is_null()) { |
480 // The klass has not been inserted into the constant pool. | 483 // The klass has not been inserted into the constant pool. |
481 // Try to look it up by name. | 484 // Try to look it up by name. |
482 { | 485 { |
483 // We have to lock the cpool to keep the oop from being resolved | 486 // We have to lock the cpool to keep the oop from being resolved |
488 if (tag.is_klass()) { | 491 if (tag.is_klass()) { |
489 // The klass has been inserted into the constant pool | 492 // The klass has been inserted into the constant pool |
490 // very recently. | 493 // very recently. |
491 klass = KlassHandle(THREAD, cpool->resolved_klass_at(index)); | 494 klass = KlassHandle(THREAD, cpool->resolved_klass_at(index)); |
492 } else if (tag.is_symbol()) { | 495 } else if (tag.is_symbol()) { |
493 klass_name = symbolHandle(THREAD, cpool->symbol_at(index)); | 496 klass_name = cpool->symbol_at(index); |
494 } else { | 497 } else { |
495 assert(cpool->tag_at(index).is_unresolved_klass(), "wrong tag"); | 498 assert(cpool->tag_at(index).is_unresolved_klass(), "wrong tag"); |
496 klass_name = symbolHandle(THREAD, cpool->unresolved_klass_at(index)); | 499 klass_name = cpool->unresolved_klass_at(index); |
497 } | 500 } |
498 } | 501 } |
499 } | 502 } |
500 | 503 |
501 if (klass.is_null()) { | 504 if (klass.is_null()) { |
502 // Not found in constant pool. Use the name to do the lookup. | 505 // Not found in constant pool. Use the name to do the lookup. |
503 ciKlass* k = get_klass_by_name_impl(accessor, | 506 ciKlass* k = get_klass_by_name_impl(accessor, |
504 get_object(klass_name())->as_symbol(), | 507 get_symbol(klass_name), |
505 false); | 508 false); |
506 // Calculate accessibility the hard way. | 509 // Calculate accessibility the hard way. |
507 if (!k->is_loaded()) { | 510 if (!k->is_loaded()) { |
508 is_accessible = false; | 511 is_accessible = false; |
509 } else if (k->loader() != accessor->loader() && | 512 } else if (k->loader() != accessor->loader() && |
517 return k; | 520 return k; |
518 } | 521 } |
519 | 522 |
520 // Check for prior unloaded klass. The SystemDictionary's answers | 523 // Check for prior unloaded klass. The SystemDictionary's answers |
521 // can vary over time but the compiler needs consistency. | 524 // can vary over time but the compiler needs consistency. |
522 ciSymbol* name = get_object(klass()->klass_part()->name())->as_symbol(); | 525 ciSymbol* name = get_symbol(klass()->klass_part()->name()); |
523 ciKlass* unloaded_klass = check_get_unloaded_klass(accessor, name); | 526 ciKlass* unloaded_klass = check_get_unloaded_klass(accessor, name); |
524 if (unloaded_klass != NULL) { | 527 if (unloaded_klass != NULL) { |
525 is_accessible = false; | 528 is_accessible = false; |
526 return unloaded_klass; | 529 return unloaded_klass; |
527 } | 530 } |
603 assert(obj->is_instance(), "must be an instance"); | 606 assert(obj->is_instance(), "must be an instance"); |
604 ciObject* ciobj = get_object(obj); | 607 ciObject* ciobj = get_object(obj); |
605 return ciConstant(T_OBJECT, ciobj); | 608 return ciConstant(T_OBJECT, ciobj); |
606 } else if (tag.is_method_type()) { | 609 } else if (tag.is_method_type()) { |
607 // must execute Java code to link this CP entry into cache[i].f1 | 610 // must execute Java code to link this CP entry into cache[i].f1 |
608 ciSymbol* signature = get_object(cpool->method_type_signature_at(index))->as_symbol(); | 611 ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index)); |
609 ciObject* ciobj = get_unloaded_method_type_constant(signature); | 612 ciObject* ciobj = get_unloaded_method_type_constant(signature); |
610 return ciConstant(T_OBJECT, ciobj); | 613 return ciConstant(T_OBJECT, ciobj); |
611 } else if (tag.is_method_handle()) { | 614 } else if (tag.is_method_handle()) { |
612 // must execute Java code to link this CP entry into cache[i].f1 | 615 // must execute Java code to link this CP entry into cache[i].f1 |
613 int ref_kind = cpool->method_handle_ref_kind_at(index); | 616 int ref_kind = cpool->method_handle_ref_kind_at(index); |
614 int callee_index = cpool->method_handle_klass_index_at(index); | 617 int callee_index = cpool->method_handle_klass_index_at(index); |
615 ciKlass* callee = get_klass_by_index_impl(cpool, callee_index, ignore_will_link, accessor); | 618 ciKlass* callee = get_klass_by_index_impl(cpool, callee_index, ignore_will_link, accessor); |
616 ciSymbol* name = get_object(cpool->method_handle_name_ref_at(index))->as_symbol(); | 619 ciSymbol* name = get_symbol(cpool->method_handle_name_ref_at(index)); |
617 ciSymbol* signature = get_object(cpool->method_handle_signature_ref_at(index))->as_symbol(); | 620 ciSymbol* signature = get_symbol(cpool->method_handle_signature_ref_at(index)); |
618 ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind); | 621 ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind); |
619 return ciConstant(T_OBJECT, ciobj); | 622 return ciConstant(T_OBJECT, ciobj); |
620 } else { | 623 } else { |
621 ShouldNotReachHere(); | 624 ShouldNotReachHere(); |
622 return ciConstant(); | 625 return ciConstant(); |
672 // | 675 // |
673 // Perform an appropriate method lookup based on accessor, holder, | 676 // Perform an appropriate method lookup based on accessor, holder, |
674 // name, signature, and bytecode. | 677 // name, signature, and bytecode. |
675 methodOop ciEnv::lookup_method(instanceKlass* accessor, | 678 methodOop ciEnv::lookup_method(instanceKlass* accessor, |
676 instanceKlass* holder, | 679 instanceKlass* holder, |
677 symbolOop name, | 680 Symbol* name, |
678 symbolOop sig, | 681 Symbol* sig, |
679 Bytecodes::Code bc) { | 682 Bytecodes::Code bc) { |
680 EXCEPTION_CONTEXT; | 683 EXCEPTION_CONTEXT; |
681 KlassHandle h_accessor(THREAD, accessor); | 684 KlassHandle h_accessor(THREAD, accessor); |
682 KlassHandle h_holder(THREAD, holder); | 685 KlassHandle h_holder(THREAD, holder); |
683 symbolHandle h_name(THREAD, name); | |
684 symbolHandle h_sig(THREAD, sig); | |
685 LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL)); | 686 LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL)); |
686 methodHandle dest_method; | 687 methodHandle dest_method; |
687 switch (bc) { | 688 switch (bc) { |
688 case Bytecodes::_invokestatic: | 689 case Bytecodes::_invokestatic: |
689 dest_method = | 690 dest_method = |
690 LinkResolver::resolve_static_call_or_null(h_holder, h_name, h_sig, h_accessor); | 691 LinkResolver::resolve_static_call_or_null(h_holder, name, sig, h_accessor); |
691 break; | 692 break; |
692 case Bytecodes::_invokespecial: | 693 case Bytecodes::_invokespecial: |
693 dest_method = | 694 dest_method = |
694 LinkResolver::resolve_special_call_or_null(h_holder, h_name, h_sig, h_accessor); | 695 LinkResolver::resolve_special_call_or_null(h_holder, name, sig, h_accessor); |
695 break; | 696 break; |
696 case Bytecodes::_invokeinterface: | 697 case Bytecodes::_invokeinterface: |
697 dest_method = | 698 dest_method = |
698 LinkResolver::linktime_resolve_interface_method_or_null(h_holder, h_name, h_sig, | 699 LinkResolver::linktime_resolve_interface_method_or_null(h_holder, name, sig, |
699 h_accessor, true); | 700 h_accessor, true); |
700 break; | 701 break; |
701 case Bytecodes::_invokevirtual: | 702 case Bytecodes::_invokevirtual: |
702 dest_method = | 703 dest_method = |
703 LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, h_name, h_sig, | 704 LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, name, sig, |
704 h_accessor, true); | 705 h_accessor, true); |
705 break; | 706 break; |
706 default: ShouldNotReachHere(); | 707 default: ShouldNotReachHere(); |
707 } | 708 } |
708 | 709 |
719 bool holder_is_accessible; | 720 bool holder_is_accessible; |
720 ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor); | 721 ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor); |
721 ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder); | 722 ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder); |
722 | 723 |
723 // Get the method's name and signature. | 724 // Get the method's name and signature. |
724 symbolOop name_sym = cpool->name_ref_at(index); | 725 Symbol* name_sym = cpool->name_ref_at(index); |
725 symbolOop sig_sym = cpool->signature_ref_at(index); | 726 Symbol* sig_sym = cpool->signature_ref_at(index); |
726 | 727 |
727 if (holder_is_accessible) { // Our declared holder is loaded. | 728 if (holder_is_accessible) { // Our declared holder is loaded. |
728 instanceKlass* lookup = declared_holder->get_instanceKlass(); | 729 instanceKlass* lookup = declared_holder->get_instanceKlass(); |
729 methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); | 730 methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); |
730 if (m != NULL) { | 731 if (m != NULL) { |
736 // Either the declared holder was not loaded, or the method could | 737 // Either the declared holder was not loaded, or the method could |
737 // not be found. Create a dummy ciMethod to represent the failed | 738 // not be found. Create a dummy ciMethod to represent the failed |
738 // lookup. | 739 // lookup. |
739 | 740 |
740 return get_unloaded_method(declared_holder, | 741 return get_unloaded_method(declared_holder, |
741 get_object(name_sym)->as_symbol(), | 742 get_symbol(name_sym), |
742 get_object(sig_sym)->as_symbol()); | 743 get_symbol(sig_sym)); |
743 } | 744 } |
744 | 745 |
745 | 746 |
746 // ------------------------------------------------------------------ | 747 // ------------------------------------------------------------------ |
747 // ciEnv::get_fake_invokedynamic_method_impl | 748 // ciEnv::get_fake_invokedynamic_method_impl |
757 | 758 |
758 // Call site might not be resolved yet. We could create a real invoker method from the | 759 // Call site might not be resolved yet. We could create a real invoker method from the |
759 // compiler, but it is simpler to stop the code path here with an unlinked method. | 760 // compiler, but it is simpler to stop the code path here with an unlinked method. |
760 if (!is_resolved) { | 761 if (!is_resolved) { |
761 ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass(); | 762 ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass(); |
762 ciSymbol* sig_sym = get_object(cpool->signature_ref_at(index))->as_symbol(); | 763 ciSymbol* sig_sym = get_symbol(cpool->signature_ref_at(index)); |
763 return get_unloaded_method(mh_klass, ciSymbol::invokeExact_name(), sig_sym); | 764 return get_unloaded_method(mh_klass, ciSymbol::invokeExact_name(), sig_sym); |
764 } | 765 } |
765 | 766 |
766 // Get the invoker methodOop from the constant pool. | 767 // Get the invoker methodOop from the constant pool. |
767 oop f1_value = cpool->cache()->main_entry_at(index)->f1(); | 768 oop f1_value = cpool->cache()->main_entry_at(index)->f1(); |