< prev index next >

src/hotspot/share/runtime/continuationHelper.inline.hpp

Print this page

 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_VM_RUNTIME_CONTINUATIONHELPER_INLINE_HPP
 26 #define SHARE_VM_RUNTIME_CONTINUATIONHELPER_INLINE_HPP
 27 
 28 #include "runtime/continuationHelper.hpp"
 29 
 30 #include "code/scopeDesc.hpp"
 31 #include "compiler/oopMap.hpp"
 32 #include "compiler/oopMap.inline.hpp"
 33 #include "interpreter/oopMapCache.hpp"
 34 #include "runtime/frame.inline.hpp"

 35 #include "runtime/stackValue.hpp"
 36 #include "utilities/macros.hpp"
 37 
 38 #include CPU_HEADER_INLINE(continuationHelper)
 39 
 40 #ifndef CPU_OVERRIDES_RETURN_ADDRESS_ACCESSORS
 41 inline address ContinuationHelper::return_address_at(intptr_t* sp) {
 42   return *(address*)sp;
 43 }
 44 
 45 inline void ContinuationHelper::patch_return_address_at(intptr_t* sp,
 46                                                         address pc) {
 47   *(address*)sp = pc;
 48 }
 49 #endif // !CPU_OVERRIDES_RETURN_ADDRESS_ACCESSORS
 50 
 51 inline bool ContinuationHelper::NonInterpretedUnknownFrame::is_instance(const frame& f) {
 52   return !f.is_interpreted_frame();
 53 }
 54 
 55 inline bool ContinuationHelper::Frame::is_stub(CodeBlob* cb) {
 56   return cb != nullptr && (cb->is_safepoint_stub() || cb->is_runtime_stub());
 57 }
 58 
 59 inline Method* ContinuationHelper::Frame::frame_method(const frame& f) {
 60   return f.is_interpreted_frame() ? f.interpreter_frame_method() : f.cb()->as_nmethod()->method();
 61 }
 62 
 63 inline address ContinuationHelper::Frame::return_pc(const frame& f) {
 64   return return_address_at((intptr_t *)return_pc_address(f));
 65 }
 66 
 67 #ifdef ASSERT
 68 inline intptr_t* ContinuationHelper::Frame::frame_top(const frame &f) {
 69   if (f.is_interpreted_frame()) {
 70     ResourceMark rm;
 71     InterpreterOopMap mask;
 72     f.interpreted_frame_oop_map(&mask);
 73     return InterpretedFrame::frame_top(f, &mask);
 74   } else {
 75     return CompiledFrame::frame_top(f);
 76   }

 91 
 92 inline address ContinuationHelper::InterpretedFrame::return_pc(const frame& f) {
 93   return return_address_at((intptr_t *)return_pc_address(f));
 94 }
 95 
 96 inline int ContinuationHelper::InterpretedFrame::size(const frame&f) {
 97   return pointer_delta_as_int(InterpretedFrame::frame_bottom(f), InterpretedFrame::frame_top(f));
 98 }
 99 
100 inline int ContinuationHelper::InterpretedFrame::stack_argsize(const frame& f) {
101   return f.interpreter_frame_method()->size_of_parameters();
102 }
103 
104 inline int ContinuationHelper::InterpretedFrame::expression_stack_size(const frame &f, InterpreterOopMap* mask) {
105   int size = mask->expression_stack_size();
106   assert(size <= f.interpreter_frame_expression_stack_size(), "size1: %d size2: %d", size, f.interpreter_frame_expression_stack_size());
107   return size;
108 }
109 
110 #ifdef ASSERT
111 inline bool ContinuationHelper::InterpretedFrame::is_owning_locks(const frame& f) {
112   assert(f.interpreter_frame_monitor_end() <= f.interpreter_frame_monitor_begin(), "must be");
113   if (f.interpreter_frame_monitor_end() == f.interpreter_frame_monitor_begin()) {
114     return false;




115   }
116 
117   for (BasicObjectLock* current = f.previous_monitor_in_interpreter_frame(f.interpreter_frame_monitor_begin());
118         current >= f.interpreter_frame_monitor_end();
119         current = f.previous_monitor_in_interpreter_frame(current)) {
120 
121       oop obj = current->obj();
122       if (obj != nullptr) {
123         return true;
























124       }

125   }
126   return false;
127 }
128 #endif
129 
130 inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f) { // inclusive; this will be copied with the frame
131   return f.unextended_sp();
132 }
133 
134 inline intptr_t* ContinuationHelper::NonInterpretedFrame::frame_top(const frame& f, int callee_argsize, bool callee_interpreted) {
135   return f.unextended_sp() + (callee_interpreted ? 0 : callee_argsize);
136 }
137 
138 inline intptr_t* ContinuationHelper::NonInterpretedFrame::frame_top(const frame& f) { // inclusive; this will be copied with the frame
139   return f.unextended_sp();
140 }
141 
142 inline intptr_t* ContinuationHelper::NonInterpretedFrame::frame_bottom(const frame& f) { // exclusive; this will not be copied with the frame
143   return f.unextended_sp() + f.cb()->frame_size();
144 }
145 
146 inline int ContinuationHelper::NonInterpretedFrame::size(const frame& f) {
147   assert(!f.is_interpreted_frame(), "");
148   return f.cb()->frame_size();
149 }
150 
151 inline int ContinuationHelper::NonInterpretedFrame::stack_argsize(const frame& f) {
152   return f.compiled_frame_stack_argsize();
153 }
154 
155 inline bool ContinuationHelper::CompiledFrame::is_instance(const frame& f) {
156   return f.is_compiled_frame();
157 }
158 




159 #ifdef ASSERT
160 template<typename RegisterMapT>
161 bool ContinuationHelper::CompiledFrame::is_owning_locks(JavaThread* thread, RegisterMapT* map, const frame& f) {
162   assert(!f.is_interpreted_frame(), "");
163   assert(CompiledFrame::is_instance(f), "");
164 
165   nmethod* nm = f.cb()->as_nmethod();
166   assert(!nm->is_native_method(), ""); // See compiledVFrame::compiledVFrame(...) in vframe_hp.cpp
167 
168   if (!nm->has_monitors()) {
169     return false;

170   }
171 
172   frame::update_map_with_saved_link(map, Frame::callee_link_address(f)); // the monitor object could be stored in the link register
173   ResourceMark rm;

174   for (ScopeDesc* scope = nm->scope_desc_at(f.pc()); scope != nullptr; scope = scope->sender()) {
175     GrowableArray<MonitorValue*>* mons = scope->monitors();
176     if (mons == nullptr || mons->is_empty()) {
177       continue;
178     }
179 
180     for (int index = (mons->length()-1); index >= 0; index--) { // see compiledVFrame::monitors()
181       MonitorValue* mon = mons->at(index);
182       if (mon->eliminated()) {
183         continue; // we ignore scalar-replaced monitors
184       }

185       ScopeValue* ov = mon->owner();
186       StackValue* owner_sv = StackValue::create_stack_value(&f, map, ov); // it is an oop
187       oop owner = owner_sv->get_obj()();
188       if (owner != nullptr) {
189         //assert(nm->has_monitors(), "");
190         return true;











191       }
192     }
193   }
194   return false;




































195 }
196 #endif
197 
198 inline bool ContinuationHelper::StubFrame::is_instance(const frame& f) {
199   return !f.is_interpreted_frame() && is_stub(f.cb());
200 }
201 
202 #endif // SHARE_VM_RUNTIME_CONTINUATIONHELPER_INLINE_HPP

 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_VM_RUNTIME_CONTINUATIONHELPER_INLINE_HPP
 26 #define SHARE_VM_RUNTIME_CONTINUATIONHELPER_INLINE_HPP
 27 
 28 #include "runtime/continuationHelper.hpp"
 29 
 30 #include "code/scopeDesc.hpp"
 31 #include "compiler/oopMap.hpp"
 32 #include "compiler/oopMap.inline.hpp"
 33 #include "interpreter/oopMapCache.hpp"
 34 #include "runtime/frame.inline.hpp"
 35 #include "runtime/objectMonitor.hpp"
 36 #include "runtime/stackValue.hpp"
 37 #include "utilities/macros.hpp"
 38 
 39 #include CPU_HEADER_INLINE(continuationHelper)
 40 
 41 #ifndef CPU_OVERRIDES_RETURN_ADDRESS_ACCESSORS
 42 inline address ContinuationHelper::return_address_at(intptr_t* sp) {
 43   return *(address*)sp;
 44 }
 45 
 46 inline void ContinuationHelper::patch_return_address_at(intptr_t* sp,
 47                                                         address pc) {
 48   *(address*)sp = pc;
 49 }
 50 #endif // !CPU_OVERRIDES_RETURN_ADDRESS_ACCESSORS
 51 
 52 inline bool ContinuationHelper::NonInterpretedUnknownFrame::is_instance(const frame& f) {
 53   return !f.is_interpreted_frame();
 54 }
 55 
 56 inline bool ContinuationHelper::Frame::is_stub(CodeBlob* cb) {
 57   return cb != nullptr && cb->is_runtime_stub();
 58 }
 59 
 60 inline Method* ContinuationHelper::Frame::frame_method(const frame& f) {
 61   return f.is_interpreted_frame() ? f.interpreter_frame_method() : f.cb()->as_nmethod()->method();
 62 }
 63 
 64 inline address ContinuationHelper::Frame::return_pc(const frame& f) {
 65   return return_address_at((intptr_t *)return_pc_address(f));
 66 }
 67 
 68 #ifdef ASSERT
 69 inline intptr_t* ContinuationHelper::Frame::frame_top(const frame &f) {
 70   if (f.is_interpreted_frame()) {
 71     ResourceMark rm;
 72     InterpreterOopMap mask;
 73     f.interpreted_frame_oop_map(&mask);
 74     return InterpretedFrame::frame_top(f, &mask);
 75   } else {
 76     return CompiledFrame::frame_top(f);
 77   }

 92 
 93 inline address ContinuationHelper::InterpretedFrame::return_pc(const frame& f) {
 94   return return_address_at((intptr_t *)return_pc_address(f));
 95 }
 96 
 97 inline int ContinuationHelper::InterpretedFrame::size(const frame&f) {
 98   return pointer_delta_as_int(InterpretedFrame::frame_bottom(f), InterpretedFrame::frame_top(f));
 99 }
100 
101 inline int ContinuationHelper::InterpretedFrame::stack_argsize(const frame& f) {
102   return f.interpreter_frame_method()->size_of_parameters();
103 }
104 
105 inline int ContinuationHelper::InterpretedFrame::expression_stack_size(const frame &f, InterpreterOopMap* mask) {
106   int size = mask->expression_stack_size();
107   assert(size <= f.interpreter_frame_expression_stack_size(), "size1: %d size2: %d", size, f.interpreter_frame_expression_stack_size());
108   return size;
109 }
110 
111 #ifdef ASSERT
112 inline int ContinuationHelper::InterpretedFrame::monitors_to_fix(JavaThread* thread, const frame& f, ResourceHashtable<oopDesc*, bool> &table, stackChunkOop chunk) {
113   BasicObjectLock* first_mon = f.interpreter_frame_monitor_begin();
114   BasicObjectLock* last_mon = f.interpreter_frame_monitor_end();
115   assert(last_mon <= first_mon, "must be");
116 
117   if (first_mon == last_mon) {
118     // No monitors in this frame
119     return 0;
120   }
121 
122   int monitor_count = 0;
123   oop monitorenter_oop = thread->is_on_monitorenter() ? thread->current_pending_monitor()->object() : nullptr;

124 
125   for (BasicObjectLock* current = f.previous_monitor_in_interpreter_frame(first_mon);
126        current >= last_mon; current = f.previous_monitor_in_interpreter_frame(current)) {
127     oop* obj_adr = current->obj_adr();
128 
129     oop obj;
130     if (f.is_heap_frame()) {
131       assert(chunk != nullptr, "null stackChunk");
132       obj = chunk->has_bitmap() && UseCompressedOops ? chunk->load_oop((narrowOop*)obj_adr) : chunk->load_oop(obj_adr);
133     } else {
134       // We have already processed oops when getting this frame.
135       obj = *obj_adr;
136     }
137     assert(obj == nullptr || dbg_is_good_oop(obj), "obj_adr: " PTR_FORMAT " obj: " PTR_FORMAT, p2i(obj_adr), p2i(obj));
138 
139     if (obj != nullptr && obj != monitorenter_oop) {
140       markWord mark = obj->mark();
141       if (mark.has_monitor() && !mark.monitor()->is_owner_anonymous()) {
142         // Nothing to do
143         assert(mark.monitor()->is_owner(thread), "invariant");
144         continue;
145       }
146       assert(!f.is_heap_frame() || LockingMode == LM_LIGHTWEIGHT,
147              "monitors found on heap frame that need to be fixed should only be those saved in the LockStack");
148       bool created;
149       table.put_if_absent(obj, true, &created);
150       if (created) {
151         monitor_count++;
152       }
153     }
154   }
155   return monitor_count;
156 }
157 #endif
158 
159 inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f) { // inclusive; this will be copied with the frame
160   return f.unextended_sp();
161 }
162 
163 inline intptr_t* ContinuationHelper::NonInterpretedFrame::frame_top(const frame& f, int callee_argsize, bool callee_interpreted) {
164   return f.unextended_sp() + (callee_interpreted ? 0 : callee_argsize);
165 }
166 
167 inline intptr_t* ContinuationHelper::NonInterpretedFrame::frame_top(const frame& f) { // inclusive; this will be copied with the frame
168   return f.unextended_sp();
169 }
170 
171 inline intptr_t* ContinuationHelper::NonInterpretedFrame::frame_bottom(const frame& f) { // exclusive; this will not be copied with the frame
172   return f.unextended_sp() + f.cb()->frame_size();
173 }
174 
175 inline int ContinuationHelper::NonInterpretedFrame::size(const frame& f) {
176   assert(!f.is_interpreted_frame(), "");
177   return f.cb()->frame_size();
178 }
179 
180 inline int ContinuationHelper::NonInterpretedFrame::stack_argsize(const frame& f) {
181   return f.compiled_frame_stack_argsize();
182 }
183 
184 inline bool ContinuationHelper::CompiledFrame::is_instance(const frame& f) {
185   return f.is_compiled_frame();
186 }
187 
188 inline bool ContinuationHelper::NativeFrame::is_instance(const frame& f) {
189   return f.is_native_frame();
190 }
191 
192 #ifdef ASSERT
193 template<typename RegisterMapT>
194 int ContinuationHelper::CompiledFrame::monitors_to_fix(JavaThread* thread, RegisterMapT* map, const frame& f, ResourceHashtable<oopDesc*, bool> &table) {
195   assert(!f.is_interpreted_frame(), "");
196   assert(CompiledFrame::is_instance(f), "");
197 
198   nmethod* nm = f.cb()->as_nmethod();
199   assert(!nm->is_nmethod() || !nm->as_nmethod()->is_native_method(), ""); // See compiledVFrame::compiledVFrame(...) in vframe_hp.cpp
200 
201   if (!nm->has_monitors()) {
202     // No monitors in this frame
203     return 0;
204   }
205 
206   int monitor_count = 0;
207   oop monitorenter_oop = thread->is_on_monitorenter() ? thread->current_pending_monitor()->object() : nullptr;
208 
209   for (ScopeDesc* scope = nm->scope_desc_at(f.pc()); scope != nullptr; scope = scope->sender()) {
210     GrowableArray<MonitorValue*>* mons = scope->monitors();
211     if (mons == nullptr || mons->is_empty()) {
212       continue;
213     }
214 
215     for (int index = (mons->length()-1); index >= 0; index--) { // see compiledVFrame::monitors()
216       MonitorValue* mon = mons->at(index);
217       if (mon->eliminated()) {
218         continue; // we ignore eliminated monitors
219       }
220 
221       ScopeValue* ov = mon->owner();
222       StackValue* owner_sv = StackValue::create_stack_value(&f, map, ov); // it is an oop
223       oop owner = owner_sv->get_obj()();
224       if (owner != nullptr && owner != monitorenter_oop) {
225         markWord mark = owner->mark();
226         if (mark.has_monitor() && !mark.monitor()->is_owner_anonymous()) {
227           // Nothing to do
228           assert(mark.monitor()->is_owner(thread), "invariant");
229           continue;
230         }
231         assert(!f.is_heap_frame() || LockingMode == LM_LIGHTWEIGHT,
232              "monitors found on heap frame that need to be fixed should only be those saved in the LockStack");
233         bool created;
234         table.put_if_absent(owner, true, &created);
235         if (created) {
236           monitor_count++;
237         }
238       }
239     }
240   }
241   return monitor_count;
242 }
243 
244 inline int ContinuationHelper::NativeFrame::monitors_to_fix(JavaThread* thread, const frame& f, ResourceHashtable<oopDesc*, bool> &table) {
245   assert(NativeFrame::is_instance(f), "");
246 
247   Method* method = f.cb()->as_nmethod()->method();
248   if (!method->is_synchronized()) {
249     return 0;
250   }
251 
252   oop synced_obj = f.get_native_receiver();
253   oop monitorenter_oop = thread->is_on_monitorenter() ? thread->current_pending_monitor()->object() : nullptr;
254 
255   bool is_first_frame = f.sp() == thread->last_Java_sp();
256   if (!is_first_frame) {
257     assert(ObjectSynchronizer::current_thread_holds_lock(thread, Handle(thread, synced_obj)), "must be owner");
258     assert(monitorenter_oop == nullptr || monitorenter_oop != synced_obj, "owner already, should not be contended");
259 
260     markWord mark = synced_obj->mark();
261     if (mark.has_monitor() && !mark.monitor()->is_owner_anonymous()) {
262       // Nothing to do
263       assert(mark.monitor()->is_owner(thread), "invariant");
264       return 0;
265     }
266     assert(!f.is_heap_frame(), "native frame on the heap???");
267     bool created;
268     table.put_if_absent(synced_obj, true, &created);
269     if (created) {
270       return 1;
271     }
272   } else {
273     assert(thread->is_on_monitorenter() && monitorenter_oop != nullptr && monitorenter_oop == synced_obj,
274            "should be freeze case due to preempt on monitorenter contention");
275     assert(!ObjectSynchronizer::current_thread_holds_lock(thread, Handle(thread, synced_obj)), "should not be owner");
276   }
277   return 0;
278 }
279 #endif
280 
281 inline bool ContinuationHelper::StubFrame::is_instance(const frame& f) {
282   return !f.is_interpreted_frame() && is_stub(f.cb());
283 }
284 
285 #endif // SHARE_VM_RUNTIME_CONTINUATIONHELPER_INLINE_HPP
< prev index next >