hotspot/src/share/vm/oops/instanceKlass.cpp
changeset 20059 c26474fd5ac0
parent 19326 14cb6cf26a96
child 20065 59ad80fc24f9
equal deleted inserted replaced
20057:7131f20389fb 20059:c26474fd5ac0
  2845   st->print(BULLET"class annotations:       "); class_annotations()->print_value_on(st); st->cr();
  2845   st->print(BULLET"class annotations:       "); class_annotations()->print_value_on(st); st->cr();
  2846   st->print(BULLET"class type annotations:  "); class_type_annotations()->print_value_on(st); st->cr();
  2846   st->print(BULLET"class type annotations:  "); class_type_annotations()->print_value_on(st); st->cr();
  2847   st->print(BULLET"field annotations:       "); fields_annotations()->print_value_on(st); st->cr();
  2847   st->print(BULLET"field annotations:       "); fields_annotations()->print_value_on(st); st->cr();
  2848   st->print(BULLET"field type annotations:  "); fields_type_annotations()->print_value_on(st); st->cr();
  2848   st->print(BULLET"field type annotations:  "); fields_type_annotations()->print_value_on(st); st->cr();
  2849   {
  2849   {
  2850     ResourceMark rm;
  2850     bool have_pv = false;
  2851     // PreviousVersionInfo objects returned via PreviousVersionWalker
  2851     PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this);
  2852     // contain a GrowableArray of handles. We have to clean up the
  2852     for (PreviousVersionNode * pv_node = pvw.next_previous_version();
  2853     // GrowableArray _after_ the PreviousVersionWalker destructor
  2853          pv_node != NULL; pv_node = pvw.next_previous_version()) {
  2854     // has destroyed the handles.
  2854       if (!have_pv)
  2855     {
  2855         st->print(BULLET"previous version:  ");
  2856       bool have_pv = false;
  2856       have_pv = true;
  2857       PreviousVersionWalker pvw((InstanceKlass*)this);
  2857       pv_node->prev_constant_pool()->print_value_on(st);
  2858       for (PreviousVersionInfo * pv_info = pvw.next_previous_version();
  2858     }
  2859            pv_info != NULL; pv_info = pvw.next_previous_version()) {
  2859     if (have_pv) st->cr();
  2860         if (!have_pv)
  2860   } // pvw is cleaned up
  2861           st->print(BULLET"previous version:  ");
       
  2862         have_pv = true;
       
  2863         pv_info->prev_constant_pool_handle()()->print_value_on(st);
       
  2864       }
       
  2865       if (have_pv)  st->cr();
       
  2866     } // pvw is cleaned up
       
  2867   } // rm is cleaned up
       
  2868 
  2861 
  2869   if (generic_signature() != NULL) {
  2862   if (generic_signature() != NULL) {
  2870     st->print(BULLET"generic signature: ");
  2863     st->print(BULLET"generic signature: ");
  2871     generic_signature()->print_value_on(st);
  2864     generic_signature()->print_value_on(st);
  2872     st->cr();
  2865     st->cr();
  3390   // we don't need to create a new PreviousVersionNode. However,
  3383   // we don't need to create a new PreviousVersionNode. However,
  3391   // we still need to examine older previous versions below.
  3384   // we still need to examine older previous versions below.
  3392   Array<Method*>* old_methods = ikh->methods();
  3385   Array<Method*>* old_methods = ikh->methods();
  3393 
  3386 
  3394   if (cp_ref->on_stack()) {
  3387   if (cp_ref->on_stack()) {
  3395   PreviousVersionNode * pv_node = NULL;
  3388     PreviousVersionNode * pv_node = NULL;
  3396   if (emcp_method_count == 0) {
  3389     if (emcp_method_count == 0) {
  3397       // non-shared ConstantPool gets a reference
  3390       // non-shared ConstantPool gets a reference
  3398       pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), NULL);
  3391       pv_node = new PreviousVersionNode(cp_ref, NULL);
  3399     RC_TRACE(0x00000400,
  3392       RC_TRACE(0x00000400,
  3400         ("add: all methods are obsolete; flushing any EMCP refs"));
  3393           ("add: all methods are obsolete; flushing any EMCP refs"));
  3401   } else {
  3394     } else {
  3402     int local_count = 0;
  3395       int local_count = 0;
  3403       GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass)
  3396       GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass)
  3404         GrowableArray<Method*>(emcp_method_count, true);
  3397           GrowableArray<Method*>(emcp_method_count, true);
  3405     for (int i = 0; i < old_methods->length(); i++) {
  3398       for (int i = 0; i < old_methods->length(); i++) {
  3406       if (emcp_methods->at(i)) {
  3399         if (emcp_methods->at(i)) {
  3407           // this old method is EMCP. Save it only if it's on the stack
  3400             // this old method is EMCP. Save it only if it's on the stack
  3408           Method* old_method = old_methods->at(i);
  3401             Method* old_method = old_methods->at(i);
  3409           if (old_method->on_stack()) {
  3402             if (old_method->on_stack()) {
  3410             method_refs->append(old_method);
  3403               method_refs->append(old_method);
       
  3404             }
       
  3405           if (++local_count >= emcp_method_count) {
       
  3406             // no more EMCP methods so bail out now
       
  3407             break;
  3411           }
  3408           }
  3412         if (++local_count >= emcp_method_count) {
       
  3413           // no more EMCP methods so bail out now
       
  3414           break;
       
  3415         }
  3409         }
  3416       }
  3410       }
  3417     }
       
  3418       // non-shared ConstantPool gets a reference
  3411       // non-shared ConstantPool gets a reference
  3419       pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), method_refs);
  3412       pv_node = new PreviousVersionNode(cp_ref, method_refs);
  3420     }
  3413     }
  3421     // append new previous version.
  3414     // append new previous version.
  3422   _previous_versions->append(pv_node);
  3415     _previous_versions->append(pv_node);
  3423   }
  3416   }
  3424 
  3417 
  3425   // Since the caller is the VMThread and we are at a safepoint, this
  3418   // Since the caller is the VMThread and we are at a safepoint, this
  3426   // is a good time to clear out unused references.
  3419   // is a good time to clear out unused references.
  3427 
  3420 
  3518       m = methods()->at(index);
  3511       m = methods()->at(index);
  3519       if (m->method_idnum() == idnum) {
  3512       if (m->method_idnum() == idnum) {
  3520         return m;
  3513         return m;
  3521       }
  3514       }
  3522     }
  3515     }
       
  3516     // None found, return null for the caller to handle.
       
  3517     return NULL;
  3523   }
  3518   }
  3524   return m;
  3519   return m;
  3525 }
  3520 }
  3526 
  3521 
  3527 jint InstanceKlass::get_cached_class_file_len() {
  3522 jint InstanceKlass::get_cached_class_file_len() {
  3534 
  3529 
  3535 
  3530 
  3536 // Construct a PreviousVersionNode entry for the array hung off
  3531 // Construct a PreviousVersionNode entry for the array hung off
  3537 // the InstanceKlass.
  3532 // the InstanceKlass.
  3538 PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool,
  3533 PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool,
  3539   bool prev_cp_is_weak, GrowableArray<Method*>* prev_EMCP_methods) {
  3534   GrowableArray<Method*>* prev_EMCP_methods) {
  3540 
  3535 
  3541   _prev_constant_pool = prev_constant_pool;
  3536   _prev_constant_pool = prev_constant_pool;
  3542   _prev_cp_is_weak = prev_cp_is_weak;
       
  3543   _prev_EMCP_methods = prev_EMCP_methods;
  3537   _prev_EMCP_methods = prev_EMCP_methods;
  3544 }
  3538 }
  3545 
  3539 
  3546 
  3540 
  3547 // Destroy a PreviousVersionNode
  3541 // Destroy a PreviousVersionNode
  3553   if (_prev_EMCP_methods != NULL) {
  3547   if (_prev_EMCP_methods != NULL) {
  3554     delete _prev_EMCP_methods;
  3548     delete _prev_EMCP_methods;
  3555   }
  3549   }
  3556 }
  3550 }
  3557 
  3551 
  3558 
       
  3559 // Construct a PreviousVersionInfo entry
       
  3560 PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) {
       
  3561   _prev_constant_pool_handle = constantPoolHandle();  // NULL handle
       
  3562   _prev_EMCP_method_handles = NULL;
       
  3563 
       
  3564   ConstantPool* cp = pv_node->prev_constant_pool();
       
  3565   assert(cp != NULL, "constant pool ref was unexpectedly cleared");
       
  3566   if (cp == NULL) {
       
  3567     return;  // robustness
       
  3568   }
       
  3569 
       
  3570   // make the ConstantPool* safe to return
       
  3571   _prev_constant_pool_handle = constantPoolHandle(cp);
       
  3572 
       
  3573   GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods();
       
  3574   if (method_refs == NULL) {
       
  3575     // the InstanceKlass did not have any EMCP methods
       
  3576     return;
       
  3577   }
       
  3578 
       
  3579   _prev_EMCP_method_handles = new GrowableArray<methodHandle>(10);
       
  3580 
       
  3581   int n_methods = method_refs->length();
       
  3582   for (int i = 0; i < n_methods; i++) {
       
  3583     Method* method = method_refs->at(i);
       
  3584     assert (method != NULL, "method has been cleared");
       
  3585     if (method == NULL) {
       
  3586       continue;  // robustness
       
  3587     }
       
  3588     // make the Method* safe to return
       
  3589     _prev_EMCP_method_handles->append(methodHandle(method));
       
  3590   }
       
  3591 }
       
  3592 
       
  3593 
       
  3594 // Destroy a PreviousVersionInfo
       
  3595 PreviousVersionInfo::~PreviousVersionInfo() {
       
  3596   // Since _prev_EMCP_method_handles is not C-heap allocated, we
       
  3597   // don't have to delete it.
       
  3598 }
       
  3599 
       
  3600 
       
  3601 // Construct a helper for walking the previous versions array
  3552 // Construct a helper for walking the previous versions array
  3602 PreviousVersionWalker::PreviousVersionWalker(InstanceKlass *ik) {
  3553 PreviousVersionWalker::PreviousVersionWalker(Thread* thread, InstanceKlass *ik) {
       
  3554   _thread = thread;
  3603   _previous_versions = ik->previous_versions();
  3555   _previous_versions = ik->previous_versions();
  3604   _current_index = 0;
  3556   _current_index = 0;
  3605   // _hm needs no initialization
       
  3606   _current_p = NULL;
  3557   _current_p = NULL;
  3607 }
  3558   _current_constant_pool_handle = constantPoolHandle(thread, ik->constants());
  3608 
       
  3609 
       
  3610 // Destroy a PreviousVersionWalker
       
  3611 PreviousVersionWalker::~PreviousVersionWalker() {
       
  3612   // Delete the current info just in case the caller didn't walk to
       
  3613   // the end of the previous versions list. No harm if _current_p is
       
  3614   // already NULL.
       
  3615   delete _current_p;
       
  3616 
       
  3617   // When _hm is destroyed, all the Handles returned in
       
  3618   // PreviousVersionInfo objects will be destroyed.
       
  3619   // Also, after this destructor is finished it will be
       
  3620   // safe to delete the GrowableArray allocated in the
       
  3621   // PreviousVersionInfo objects.
       
  3622 }
  3559 }
  3623 
  3560 
  3624 
  3561 
  3625 // Return the interesting information for the next previous version
  3562 // Return the interesting information for the next previous version
  3626 // of the klass. Returns NULL if there are no more previous versions.
  3563 // of the klass. Returns NULL if there are no more previous versions.
  3627 PreviousVersionInfo* PreviousVersionWalker::next_previous_version() {
  3564 PreviousVersionNode* PreviousVersionWalker::next_previous_version() {
  3628   if (_previous_versions == NULL) {
  3565   if (_previous_versions == NULL) {
  3629     // no previous versions so nothing to return
  3566     // no previous versions so nothing to return
  3630     return NULL;
  3567     return NULL;
  3631   }
  3568   }
  3632 
  3569 
  3633   delete _current_p;  // cleanup the previous info for the caller
  3570   _current_p = NULL;  // reset to NULL
  3634   _current_p = NULL;  // reset to NULL so we don't delete same object twice
  3571   _current_constant_pool_handle = NULL;
  3635 
  3572 
  3636   int length = _previous_versions->length();
  3573   int length = _previous_versions->length();
  3637 
  3574 
  3638   while (_current_index < length) {
  3575   while (_current_index < length) {
  3639     PreviousVersionNode * pv_node = _previous_versions->at(_current_index++);
  3576     PreviousVersionNode * pv_node = _previous_versions->at(_current_index++);
  3640     PreviousVersionInfo * pv_info = new (ResourceObj::C_HEAP, mtClass)
  3577 
  3641                                           PreviousVersionInfo(pv_node);
  3578     // Save a handle to the constant pool for this previous version,
  3642 
  3579     // which keeps all the methods from being deallocated.
  3643     constantPoolHandle cp_h = pv_info->prev_constant_pool_handle();
  3580     _current_constant_pool_handle = constantPoolHandle(_thread, pv_node->prev_constant_pool());
  3644     assert (!cp_h.is_null(), "null cp found in previous version");
  3581     _current_p = pv_node;
  3645 
  3582     return pv_node;
  3646     // The caller will need to delete pv_info when they are done with it.
  3583   }
  3647     _current_p = pv_info;
  3584 
  3648     return pv_info;
       
  3649   }
       
  3650 
       
  3651   // all of the underlying nodes' info has been deleted
       
  3652   return NULL;
  3585   return NULL;
  3653 } // end next_previous_version()
  3586 } // end next_previous_version()