src/hotspot/share/code/nmethod.hpp
changeset 58777 18c246ad2ff9
parent 58226 408c445d04e8
equal deleted inserted replaced
58776:ea153023d832 58777:18c246ad2ff9
    65   friend class VMStructs;
    65   friend class VMStructs;
    66   friend class JVMCIVMStructs;
    66   friend class JVMCIVMStructs;
    67   friend class NMethodSweeper;
    67   friend class NMethodSweeper;
    68   friend class CodeCache;  // scavengable oops
    68   friend class CodeCache;  // scavengable oops
    69   friend class JVMCINMethodData;
    69   friend class JVMCINMethodData;
       
    70 
    70  private:
    71  private:
    71 
       
    72   // Shared fields for all nmethod's
    72   // Shared fields for all nmethod's
    73   int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
    73   int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
    74   jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
    74   jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
    75 
    75 
    76   // To support simple linked-list chaining of nmethods:
    76   // To support simple linked-list chaining of nmethods:
    77   nmethod*  _osr_link;         // from InstanceKlass::osr_nmethods_head
    77   nmethod*  _osr_link;         // from InstanceKlass::osr_nmethods_head
    78 
    78 
       
    79   // STW two-phase nmethod root processing helpers.
       
    80   //
       
    81   // When determining liveness of a given nmethod to do code cache unloading,
       
    82   // some collectors need to to different things depending on whether the nmethods
       
    83   // need to absolutely be kept alive during root processing; "strong"ly reachable
       
    84   // nmethods are known to be kept alive at root processing, but the liveness of
       
    85   // "weak"ly reachable ones is to be determined later.
       
    86   //
       
    87   // We want to allow strong and weak processing of nmethods by different threads
       
    88   // at the same time without heavy synchronization. Additional constraints are
       
    89   // to make sure that every nmethod is processed a minimal amount of time, and
       
    90   // nmethods themselves are always iterated at most once at a particular time.
       
    91   //
       
    92   // Note that strong processing work must be a superset of weak processing work
       
    93   // for this code to work.
       
    94   //
       
    95   // We store state and claim information in the _oops_do_mark_link member, using
       
    96   // the two LSBs for the state and the remaining upper bits for linking together
       
    97   // nmethods that were already visited.
       
    98   // The last element is self-looped, i.e. points to itself to avoid some special
       
    99   // "end-of-list" sentinel value.
       
   100   //
       
   101   // _oops_do_mark_link special values:
       
   102   //
       
   103   //   _oops_do_mark_link == NULL: the nmethod has not been visited at all yet, i.e.
       
   104   //      is Unclaimed.
       
   105   //
       
   106   // For other values, its lowest two bits indicate the following states of the nmethod:
       
   107   //
       
   108   //   weak_request (WR): the nmethod has been claimed by a thread for weak processing
       
   109   //   weak_done (WD): weak processing has been completed for this nmethod.
       
   110   //   strong_request (SR): the nmethod has been found to need strong processing while
       
   111   //       being weak processed.
       
   112   //   strong_done (SD): strong processing has been completed for this nmethod .
       
   113   //
       
   114   // The following shows the _only_ possible progressions of the _oops_do_mark_link
       
   115   // pointer.
       
   116   //
       
   117   // Given
       
   118   //   N as the nmethod
       
   119   //   X the current next value of _oops_do_mark_link
       
   120   //
       
   121   // Unclaimed (C)-> N|WR (C)-> X|WD: the nmethod has been processed weakly by
       
   122   //   a single thread.
       
   123   // Unclaimed (C)-> N|WR (C)-> X|WD (O)-> X|SD: after weak processing has been
       
   124   //   completed (as above) another thread found that the nmethod needs strong
       
   125   //   processing after all.
       
   126   // Unclaimed (C)-> N|WR (O)-> N|SR (C)-> X|SD: during weak processing another
       
   127   //   thread finds that the nmethod needs strong processing, marks it as such and
       
   128   //   terminates. The original thread completes strong processing.
       
   129   // Unclaimed (C)-> N|SD (C)-> X|SD: the nmethod has been processed strongly from
       
   130   //   the beginning by a single thread.
       
   131   //
       
   132   // "|" describes the concatentation of bits in _oops_do_mark_link.
       
   133   //
       
   134   // The diagram also describes the threads responsible for changing the nmethod to
       
   135   // the next state by marking the _transition_ with (C) and (O), which mean "current"
       
   136   // and "other" thread respectively.
       
   137   //
       
   138   struct oops_do_mark_link; // Opaque data type.
       
   139 
       
   140   // States used for claiming nmethods during root processing.
       
   141   static const uint claim_weak_request_tag = 0;
       
   142   static const uint claim_weak_done_tag = 1;
       
   143   static const uint claim_strong_request_tag = 2;
       
   144   static const uint claim_strong_done_tag = 3;
       
   145 
       
   146   static oops_do_mark_link* mark_link(nmethod* nm, uint tag) {
       
   147     assert(tag <= claim_strong_done_tag, "invalid tag %u", tag);
       
   148     assert(is_aligned(nm, 4), "nmethod pointer must have zero lower two LSB");
       
   149     return (oops_do_mark_link*)(((uintptr_t)nm & ~0x3) | tag);
       
   150   }
       
   151 
       
   152   static uint extract_state(oops_do_mark_link* link) {
       
   153     return (uint)((uintptr_t)link & 0x3);
       
   154   }
       
   155 
       
   156   static nmethod* extract_nmethod(oops_do_mark_link* link) {
       
   157     return (nmethod*)((uintptr_t)link & ~0x3);
       
   158   }
       
   159 
       
   160   void oops_do_log_change(const char* state);
       
   161 
       
   162   static bool oops_do_has_weak_request(oops_do_mark_link* next) {
       
   163     return extract_state(next) == claim_weak_request_tag;
       
   164   }
       
   165 
       
   166   static bool oops_do_has_any_strong_state(oops_do_mark_link* next) {
       
   167     return extract_state(next) >= claim_strong_request_tag;
       
   168   }
       
   169 
       
   170   // Attempt Unclaimed -> N|WR transition. Returns true if successful.
       
   171   bool oops_do_try_claim_weak_request();
       
   172 
       
   173   // Attempt Unclaimed -> N|SD transition. Returns the current link.
       
   174   oops_do_mark_link* oops_do_try_claim_strong_done();
       
   175   // Attempt N|WR -> X|WD transition. Returns NULL if successful, X otherwise.
       
   176   nmethod* oops_do_try_add_to_list_as_weak_done();
       
   177 
       
   178   // Attempt X|WD -> N|SR transition. Returns the current link.
       
   179   oops_do_mark_link* oops_do_try_add_strong_request(oops_do_mark_link* next);
       
   180   // Attempt X|WD -> X|SD transition. Returns true if successful.
       
   181   bool oops_do_try_claim_weak_done_as_strong_done(oops_do_mark_link* next);
       
   182 
       
   183   // Do the N|SD -> X|SD transition.
       
   184   void oops_do_add_to_list_as_strong_done();
       
   185 
       
   186   // Sets this nmethod as strongly claimed (as part of N|SD -> X|SD and N|SR -> X|SD
       
   187   // transitions).
       
   188   void oops_do_set_strong_done(nmethod* old_head);
       
   189 
    79   static nmethod* volatile _oops_do_mark_nmethods;
   190   static nmethod* volatile _oops_do_mark_nmethods;
    80   nmethod*        volatile _oops_do_mark_link;
   191   oops_do_mark_link* volatile _oops_do_mark_link;
    81 
   192 
    82   // offsets for entry points
   193   // offsets for entry points
    83   address _entry_point;                      // entry point with class check
   194   address _entry_point;                      // entry point with class check
    84   address _verified_entry_point;             // entry point without class check
   195   address _verified_entry_point;             // entry point without class check
    85   address _osr_entry_point;                  // entry point for on stack replacement
   196   address _osr_entry_point;                  // entry point for on stack replacement
   478 
   589 
   479  public:
   590  public:
   480   void oops_do(OopClosure* f) { oops_do(f, false); }
   591   void oops_do(OopClosure* f) { oops_do(f, false); }
   481   void oops_do(OopClosure* f, bool allow_dead);
   592   void oops_do(OopClosure* f, bool allow_dead);
   482 
   593 
   483   bool test_set_oops_do_mark();
   594   // All-in-one claiming of nmethods: returns true if the caller successfully claimed that
       
   595   // nmethod.
       
   596   bool oops_do_try_claim();
       
   597 
       
   598   // Class containing callbacks for the oops_do_process_weak/strong() methods
       
   599   // below.
       
   600   class OopsDoProcessor {
       
   601   public:
       
   602     // Process the oops of the given nmethod based on whether it has been called
       
   603     // in a weak or strong processing context, i.e. apply either weak or strong
       
   604     // work on it.
       
   605     virtual void do_regular_processing(nmethod* nm) = 0;
       
   606     // Assuming that the oops of the given nmethod has already been its weak
       
   607     // processing applied, apply the remaining strong processing part.
       
   608     virtual void do_remaining_strong_processing(nmethod* nm) = 0;
       
   609   };
       
   610 
       
   611   // The following two methods do the work corresponding to weak/strong nmethod
       
   612   // processing.
       
   613   void oops_do_process_weak(OopsDoProcessor* p);
       
   614   void oops_do_process_strong(OopsDoProcessor* p);
       
   615 
   484   static void oops_do_marking_prologue();
   616   static void oops_do_marking_prologue();
   485   static void oops_do_marking_epilogue();
   617   static void oops_do_marking_epilogue();
   486   static bool oops_do_marking_is_active() { return _oops_do_mark_nmethods != NULL; }
       
   487   bool test_oops_do_mark() { return _oops_do_mark_link != NULL; }
       
   488 
   618 
   489  private:
   619  private:
   490   ScopeDesc* scope_desc_in(address begin, address end);
   620   ScopeDesc* scope_desc_in(address begin, address end);
   491 
   621 
   492   address* orig_pc_addr(const frame* fr);
   622   address* orig_pc_addr(const frame* fr);