src/share/vm/oops/instanceKlass.cpp

changeset 5755
0f37d1badced
parent 5732
b2e698d2276c
parent 5749
4f9a42c33738
child 5784
190899198332
equal deleted inserted replaced
5739:bf13c3da3d11 5755:0f37d1badced
2767 st->print(BULLET"class annotations: "); class_annotations()->print_value_on(st); st->cr(); 2767 st->print(BULLET"class annotations: "); class_annotations()->print_value_on(st); st->cr();
2768 st->print(BULLET"class type annotations: "); class_type_annotations()->print_value_on(st); st->cr(); 2768 st->print(BULLET"class type annotations: "); class_type_annotations()->print_value_on(st); st->cr();
2769 st->print(BULLET"field annotations: "); fields_annotations()->print_value_on(st); st->cr(); 2769 st->print(BULLET"field annotations: "); fields_annotations()->print_value_on(st); st->cr();
2770 st->print(BULLET"field type annotations: "); fields_type_annotations()->print_value_on(st); st->cr(); 2770 st->print(BULLET"field type annotations: "); fields_type_annotations()->print_value_on(st); st->cr();
2771 { 2771 {
2772 ResourceMark rm; 2772 bool have_pv = false;
2773 // PreviousVersionInfo objects returned via PreviousVersionWalker 2773 PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this);
2774 // contain a GrowableArray of handles. We have to clean up the 2774 for (PreviousVersionNode * pv_node = pvw.next_previous_version();
2775 // GrowableArray _after_ the PreviousVersionWalker destructor 2775 pv_node != NULL; pv_node = pvw.next_previous_version()) {
2776 // has destroyed the handles. 2776 if (!have_pv)
2777 { 2777 st->print(BULLET"previous version: ");
2778 bool have_pv = false; 2778 have_pv = true;
2779 PreviousVersionWalker pvw((InstanceKlass*)this); 2779 pv_node->prev_constant_pool()->print_value_on(st);
2780 for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); 2780 }
2781 pv_info != NULL; pv_info = pvw.next_previous_version()) { 2781 if (have_pv) st->cr();
2782 if (!have_pv) 2782 } // pvw is cleaned up
2783 st->print(BULLET"previous version: ");
2784 have_pv = true;
2785 pv_info->prev_constant_pool_handle()()->print_value_on(st);
2786 }
2787 if (have_pv) st->cr();
2788 } // pvw is cleaned up
2789 } // rm is cleaned up
2790 2783
2791 if (generic_signature() != NULL) { 2784 if (generic_signature() != NULL) {
2792 st->print(BULLET"generic signature: "); 2785 st->print(BULLET"generic signature: ");
2793 generic_signature()->print_value_on(st); 2786 generic_signature()->print_value_on(st);
2794 st->cr(); 2787 st->cr();
3315 // we don't need to create a new PreviousVersionNode. However, 3308 // we don't need to create a new PreviousVersionNode. However,
3316 // we still need to examine older previous versions below. 3309 // we still need to examine older previous versions below.
3317 Array<Method*>* old_methods = ikh->methods(); 3310 Array<Method*>* old_methods = ikh->methods();
3318 3311
3319 if (cp_ref->on_stack()) { 3312 if (cp_ref->on_stack()) {
3320 PreviousVersionNode * pv_node = NULL; 3313 PreviousVersionNode * pv_node = NULL;
3321 if (emcp_method_count == 0) { 3314 if (emcp_method_count == 0) {
3322 // non-shared ConstantPool gets a reference 3315 // non-shared ConstantPool gets a reference
3323 pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), NULL); 3316 pv_node = new PreviousVersionNode(cp_ref, NULL);
3324 RC_TRACE(0x00000400, 3317 RC_TRACE(0x00000400,
3325 ("add: all methods are obsolete; flushing any EMCP refs")); 3318 ("add: all methods are obsolete; flushing any EMCP refs"));
3326 } else { 3319 } else {
3327 int local_count = 0; 3320 int local_count = 0;
3328 GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass) 3321 GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass)
3329 GrowableArray<Method*>(emcp_method_count, true); 3322 GrowableArray<Method*>(emcp_method_count, true);
3330 for (int i = 0; i < old_methods->length(); i++) { 3323 for (int i = 0; i < old_methods->length(); i++) {
3331 if (emcp_methods->at(i)) { 3324 if (emcp_methods->at(i)) {
3332 // this old method is EMCP. Save it only if it's on the stack 3325 // this old method is EMCP. Save it only if it's on the stack
3333 Method* old_method = old_methods->at(i); 3326 Method* old_method = old_methods->at(i);
3334 if (old_method->on_stack()) { 3327 if (old_method->on_stack()) {
3335 method_refs->append(old_method); 3328 method_refs->append(old_method);
3329 }
3330 if (++local_count >= emcp_method_count) {
3331 // no more EMCP methods so bail out now
3332 break;
3336 } 3333 }
3337 if (++local_count >= emcp_method_count) {
3338 // no more EMCP methods so bail out now
3339 break;
3340 } 3334 }
3341 } 3335 }
3342 }
3343 // non-shared ConstantPool gets a reference 3336 // non-shared ConstantPool gets a reference
3344 pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), method_refs); 3337 pv_node = new PreviousVersionNode(cp_ref, method_refs);
3345 } 3338 }
3346 // append new previous version. 3339 // append new previous version.
3347 _previous_versions->append(pv_node); 3340 _previous_versions->append(pv_node);
3348 } 3341 }
3349 3342
3350 // Since the caller is the VMThread and we are at a safepoint, this 3343 // Since the caller is the VMThread and we are at a safepoint, this
3351 // is a good time to clear out unused references. 3344 // is a good time to clear out unused references.
3352 3345
3443 m = methods()->at(index); 3436 m = methods()->at(index);
3444 if (m->method_idnum() == idnum) { 3437 if (m->method_idnum() == idnum) {
3445 return m; 3438 return m;
3446 } 3439 }
3447 } 3440 }
3441 // None found, return null for the caller to handle.
3442 return NULL;
3448 } 3443 }
3449 return m; 3444 return m;
3450 } 3445 }
3451 3446
3452 jint InstanceKlass::get_cached_class_file_len() { 3447 jint InstanceKlass::get_cached_class_file_len() {
3459 3454
3460 3455
3461 // Construct a PreviousVersionNode entry for the array hung off 3456 // Construct a PreviousVersionNode entry for the array hung off
3462 // the InstanceKlass. 3457 // the InstanceKlass.
3463 PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool, 3458 PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool,
3464 bool prev_cp_is_weak, GrowableArray<Method*>* prev_EMCP_methods) { 3459 GrowableArray<Method*>* prev_EMCP_methods) {
3465 3460
3466 _prev_constant_pool = prev_constant_pool; 3461 _prev_constant_pool = prev_constant_pool;
3467 _prev_cp_is_weak = prev_cp_is_weak;
3468 _prev_EMCP_methods = prev_EMCP_methods; 3462 _prev_EMCP_methods = prev_EMCP_methods;
3469 } 3463 }
3470 3464
3471 3465
3472 // Destroy a PreviousVersionNode 3466 // Destroy a PreviousVersionNode
3478 if (_prev_EMCP_methods != NULL) { 3472 if (_prev_EMCP_methods != NULL) {
3479 delete _prev_EMCP_methods; 3473 delete _prev_EMCP_methods;
3480 } 3474 }
3481 } 3475 }
3482 3476
3483
3484 // Construct a PreviousVersionInfo entry
3485 PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) {
3486 _prev_constant_pool_handle = constantPoolHandle(); // NULL handle
3487 _prev_EMCP_method_handles = NULL;
3488
3489 ConstantPool* cp = pv_node->prev_constant_pool();
3490 assert(cp != NULL, "constant pool ref was unexpectedly cleared");
3491 if (cp == NULL) {
3492 return; // robustness
3493 }
3494
3495 // make the ConstantPool* safe to return
3496 _prev_constant_pool_handle = constantPoolHandle(cp);
3497
3498 GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods();
3499 if (method_refs == NULL) {
3500 // the InstanceKlass did not have any EMCP methods
3501 return;
3502 }
3503
3504 _prev_EMCP_method_handles = new GrowableArray<methodHandle>(10);
3505
3506 int n_methods = method_refs->length();
3507 for (int i = 0; i < n_methods; i++) {
3508 Method* method = method_refs->at(i);
3509 assert (method != NULL, "method has been cleared");
3510 if (method == NULL) {
3511 continue; // robustness
3512 }
3513 // make the Method* safe to return
3514 _prev_EMCP_method_handles->append(methodHandle(method));
3515 }
3516 }
3517
3518
3519 // Destroy a PreviousVersionInfo
3520 PreviousVersionInfo::~PreviousVersionInfo() {
3521 // Since _prev_EMCP_method_handles is not C-heap allocated, we
3522 // don't have to delete it.
3523 }
3524
3525
3526 // Construct a helper for walking the previous versions array 3477 // Construct a helper for walking the previous versions array
3527 PreviousVersionWalker::PreviousVersionWalker(InstanceKlass *ik) { 3478 PreviousVersionWalker::PreviousVersionWalker(Thread* thread, InstanceKlass *ik) {
3479 _thread = thread;
3528 _previous_versions = ik->previous_versions(); 3480 _previous_versions = ik->previous_versions();
3529 _current_index = 0; 3481 _current_index = 0;
3530 // _hm needs no initialization
3531 _current_p = NULL; 3482 _current_p = NULL;
3532 } 3483 _current_constant_pool_handle = constantPoolHandle(thread, ik->constants());
3533
3534
3535 // Destroy a PreviousVersionWalker
3536 PreviousVersionWalker::~PreviousVersionWalker() {
3537 // Delete the current info just in case the caller didn't walk to
3538 // the end of the previous versions list. No harm if _current_p is
3539 // already NULL.
3540 delete _current_p;
3541
3542 // When _hm is destroyed, all the Handles returned in
3543 // PreviousVersionInfo objects will be destroyed.
3544 // Also, after this destructor is finished it will be
3545 // safe to delete the GrowableArray allocated in the
3546 // PreviousVersionInfo objects.
3547 } 3484 }
3548 3485
3549 3486
3550 // Return the interesting information for the next previous version 3487 // Return the interesting information for the next previous version
3551 // of the klass. Returns NULL if there are no more previous versions. 3488 // of the klass. Returns NULL if there are no more previous versions.
3552 PreviousVersionInfo* PreviousVersionWalker::next_previous_version() { 3489 PreviousVersionNode* PreviousVersionWalker::next_previous_version() {
3553 if (_previous_versions == NULL) { 3490 if (_previous_versions == NULL) {
3554 // no previous versions so nothing to return 3491 // no previous versions so nothing to return
3555 return NULL; 3492 return NULL;
3556 } 3493 }
3557 3494
3558 delete _current_p; // cleanup the previous info for the caller 3495 _current_p = NULL; // reset to NULL
3559 _current_p = NULL; // reset to NULL so we don't delete same object twice 3496 _current_constant_pool_handle = NULL;
3560 3497
3561 int length = _previous_versions->length(); 3498 int length = _previous_versions->length();
3562 3499
3563 while (_current_index < length) { 3500 while (_current_index < length) {
3564 PreviousVersionNode * pv_node = _previous_versions->at(_current_index++); 3501 PreviousVersionNode * pv_node = _previous_versions->at(_current_index++);
3565 PreviousVersionInfo * pv_info = new (ResourceObj::C_HEAP, mtClass) 3502
3566 PreviousVersionInfo(pv_node); 3503 // Save a handle to the constant pool for this previous version,
3567 3504 // which keeps all the methods from being deallocated.
3568 constantPoolHandle cp_h = pv_info->prev_constant_pool_handle(); 3505 _current_constant_pool_handle = constantPoolHandle(_thread, pv_node->prev_constant_pool());
3569 assert (!cp_h.is_null(), "null cp found in previous version"); 3506 _current_p = pv_node;
3570 3507 return pv_node;
3571 // The caller will need to delete pv_info when they are done with it. 3508 }
3572 _current_p = pv_info; 3509
3573 return pv_info;
3574 }
3575
3576 // all of the underlying nodes' info has been deleted
3577 return NULL; 3510 return NULL;
3578 } // end next_previous_version() 3511 } // end next_previous_version()

mercurial