src/hotspot/share/code/compiledMethod.cpp
changeset 52659 8b26bd8b1832
parent 52453 6e99148dbf33
child 52660 9cb53c505acd
equal deleted inserted replaced
52658:2d18e5ed0f8d 52659:8b26bd8b1832
    42 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, const CodeBlobLayout& layout,
    42 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, const CodeBlobLayout& layout,
    43                                int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps,
    43                                int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps,
    44                                bool caller_must_gc_arguments)
    44                                bool caller_must_gc_arguments)
    45   : CodeBlob(name, type, layout, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
    45   : CodeBlob(name, type, layout, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
    46     _mark_for_deoptimization_status(not_marked),
    46     _mark_for_deoptimization_status(not_marked),
    47     _is_unloading_state(0),
       
    48     _method(method)
    47     _method(method)
    49 {
    48 {
    50   init_defaults();
    49   init_defaults();
    51   clear_unloading_state();
       
    52 }
    50 }
    53 
    51 
    54 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, int size,
    52 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, int size,
    55                                int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size,
    53                                int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size,
    56                                OopMapSet* oop_maps, bool caller_must_gc_arguments)
    54                                OopMapSet* oop_maps, bool caller_must_gc_arguments)
    57   : CodeBlob(name, type, CodeBlobLayout((address) this, size, header_size, cb), cb,
    55   : CodeBlob(name, type, CodeBlobLayout((address) this, size, header_size, cb), cb,
    58              frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
    56              frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
    59     _mark_for_deoptimization_status(not_marked),
    57     _mark_for_deoptimization_status(not_marked),
    60     _is_unloading_state(0),
       
    61     _method(method)
    58     _method(method)
    62 {
    59 {
    63   init_defaults();
    60   init_defaults();
    64   clear_unloading_state();
       
    65 }
    61 }
    66 
    62 
    67 void CompiledMethod::init_defaults() {
    63 void CompiledMethod::init_defaults() {
    68   _has_unsafe_access          = 0;
    64   _has_unsafe_access          = 0;
    69   _has_method_handle_invokes  = 0;
    65   _has_method_handle_invokes  = 0;
   544 
   540 
   545   // Check that the metadata embedded in the nmethod is alive
   541   // Check that the metadata embedded in the nmethod is alive
   546   DEBUG_ONLY(metadata_do(check_class));
   542   DEBUG_ONLY(metadata_do(check_class));
   547 }
   543 }
   548 
   544 
   549 // The _is_unloading_state encodes a tuple comprising the unloading cycle
       
   550 // and the result of IsUnloadingBehaviour::is_unloading() fpr that cycle.
       
   551 // This is the bit layout of the _is_unloading_state byte: 00000CCU
       
   552 // CC refers to the cycle, which has 2 bits, and U refers to the result of
       
   553 // IsUnloadingBehaviour::is_unloading() for that unloading cycle.
       
   554 
       
   555 class IsUnloadingState: public AllStatic {
       
   556   static const uint8_t _is_unloading_mask = 1;
       
   557   static const uint8_t _is_unloading_shift = 0;
       
   558   static const uint8_t _unloading_cycle_mask = 6;
       
   559   static const uint8_t _unloading_cycle_shift = 1;
       
   560 
       
   561   static uint8_t set_is_unloading(uint8_t state, bool value) {
       
   562     state &= ~_is_unloading_mask;
       
   563     if (value) {
       
   564       state |= 1 << _is_unloading_shift;
       
   565     }
       
   566     assert(is_unloading(state) == value, "unexpected unloading cycle overflow");
       
   567     return state;
       
   568   }
       
   569 
       
   570   static uint8_t set_unloading_cycle(uint8_t state, uint8_t value) {
       
   571     state &= ~_unloading_cycle_mask;
       
   572     state |= value << _unloading_cycle_shift;
       
   573     assert(unloading_cycle(state) == value, "unexpected unloading cycle overflow");
       
   574     return state;
       
   575   }
       
   576 
       
   577 public:
       
   578   static bool is_unloading(uint8_t state) { return (state & _is_unloading_mask) >> _is_unloading_shift == 1; }
       
   579   static uint8_t unloading_cycle(uint8_t state) { return (state & _unloading_cycle_mask) >> _unloading_cycle_shift; }
       
   580 
       
   581   static uint8_t create(bool is_unloading, uint8_t unloading_cycle) {
       
   582     uint8_t state = 0;
       
   583     state = set_is_unloading(state, is_unloading);
       
   584     state = set_unloading_cycle(state, unloading_cycle);
       
   585     return state;
       
   586   }
       
   587 };
       
   588 
       
   589 bool CompiledMethod::is_unloading() {
       
   590   uint8_t state = RawAccess<MO_RELAXED>::load(&_is_unloading_state);
       
   591   bool state_is_unloading = IsUnloadingState::is_unloading(state);
       
   592   uint8_t state_unloading_cycle = IsUnloadingState::unloading_cycle(state);
       
   593   if (state_is_unloading) {
       
   594     return true;
       
   595   }
       
   596   if (state_unloading_cycle == CodeCache::unloading_cycle()) {
       
   597     return false;
       
   598   }
       
   599 
       
   600   // The IsUnloadingBehaviour is responsible for checking if there are any dead
       
   601   // oops in the CompiledMethod, by calling oops_do on it.
       
   602   state_unloading_cycle = CodeCache::unloading_cycle();
       
   603   state_is_unloading = IsUnloadingBehaviour::current()->is_unloading(this);
       
   604 
       
   605   state = IsUnloadingState::create(state_is_unloading, state_unloading_cycle);
       
   606 
       
   607   RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
       
   608 
       
   609   return state_is_unloading;
       
   610 }
       
   611 
       
   612 void CompiledMethod::clear_unloading_state() {
       
   613   uint8_t state = IsUnloadingState::create(false, CodeCache::unloading_cycle());
       
   614   RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
       
   615 }
       
   616 
       
   617 // Called to clean up after class unloading for live nmethods and from the sweeper
   545 // Called to clean up after class unloading for live nmethods and from the sweeper
   618 // for all methods.
   546 // for all methods.
   619 void CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) {
   547 void CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) {
   620   assert(CompiledICLocker::is_safe(this), "mt unsafe call");
   548   assert(CompiledICLocker::is_safe(this), "mt unsafe call");
   621   ResourceMark rm;
   549   ResourceMark rm;