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); |