128 };
129
130
131 class IRScope;
132 typedef GrowableArray<IRScope*> IRScopeList;
133
134 class Compilation;
135 class IRScope: public CompilationResourceObj {
136 private:
137 // hierarchy
138 Compilation* _compilation; // the current compilation
139 IRScope* _caller; // the caller scope, or null
140 int _level; // the inlining level
141 ciMethod* _method; // the corresponding method
142 IRScopeList _callees; // the inlined method scopes
143
144 // graph
145 XHandlers* _xhandlers; // the exception handlers
146 int _number_of_locks; // the number of monitor lock slots needed
147 bool _monitor_pairing_ok; // the monitor pairing info
148 bool _wrote_final; // has written final field
149 bool _wrote_fields; // has written fields
150 bool _wrote_volatile; // has written volatile field
151 bool _wrote_stable; // has written @Stable field
152 BlockBegin* _start; // the start block, successsors are method entries
153
154 ResourceBitMap _requires_phi_function; // bit is set if phi functions at loop headers are necessary for a local variable
155
156 // helper functions
157 BlockBegin* build_graph(Compilation* compilation, int osr_bci);
158
159 public:
160 // creation
161 IRScope(Compilation* compilation, IRScope* caller, int caller_bci, ciMethod* method, int osr_bci, bool create_graph = false);
162
163 // accessors
164 Compilation* compilation() const { return _compilation; }
165 IRScope* caller() const { return _caller; }
166 int level() const { return _level; }
167 ciMethod* method() const { return _method; }
168 int max_stack() const; // NOTE: expensive
169 BitMap& requires_phi_function() { return _requires_phi_function; }
170
171 // hierarchy
172 bool is_top_scope() const { return _caller == nullptr; }
173 void add_callee(IRScope* callee) { _callees.append(callee); }
174 int number_of_callees() const { return _callees.length(); }
175 IRScope* callee_no(int i) const { return _callees.at(i); }
176
177 // accessors, graph
178 bool is_valid() const { return start() != nullptr; }
179 XHandlers* xhandlers() const { return _xhandlers; }
180 int number_of_locks() const { return _number_of_locks; }
181 void set_min_number_of_locks(int n) { if (n > _number_of_locks) _number_of_locks = n; }
182 bool monitor_pairing_ok() const { return _monitor_pairing_ok; }
183 BlockBegin* start() const { return _start; }
184 void set_wrote_final() { _wrote_final = true; }
185 bool wrote_final () const { return _wrote_final; }
186 void set_wrote_fields() { _wrote_fields = true; }
187 bool wrote_fields () const { return _wrote_fields; }
188 void set_wrote_volatile() { _wrote_volatile = true; }
189 bool wrote_volatile () const { return _wrote_volatile; }
190 void set_wrote_stable() { _wrote_stable = true; }
191 bool wrote_stable() const { return _wrote_stable; }
192 };
193
194
195 //
196 // IRScopeDebugInfo records the debug information for a particular IRScope
197 // in a particular CodeEmitInfo. This allows the information to be computed
198 // once early enough for the OopMap to be available to the LIR and also to be
199 // reemited for different pcs using the same CodeEmitInfo without recomputing
200 // everything.
201 //
202
203 class IRScopeDebugInfo: public CompilationResourceObj {
204 private:
205 IRScope* _scope;
206 int _bci;
207 GrowableArray<ScopeValue*>* _locals;
208 GrowableArray<ScopeValue*>* _expressions;
209 GrowableArray<MonitorValue*>* _monitors;
210 IRScopeDebugInfo* _caller;
211
212 public:
213 IRScopeDebugInfo(IRScope* scope,
214 int bci,
215 GrowableArray<ScopeValue*>* locals,
216 GrowableArray<ScopeValue*>* expressions,
217 GrowableArray<MonitorValue*>* monitors,
218 IRScopeDebugInfo* caller):
219 _scope(scope)
220 , _bci(bci)
221 , _locals(locals)
222 , _expressions(expressions)
223 , _monitors(monitors)
224 , _caller(caller) {}
225
226
227 IRScope* scope() { return _scope; }
228 int bci() { return _bci; }
229 GrowableArray<ScopeValue*>* locals() { return _locals; }
230 GrowableArray<ScopeValue*>* expressions() { return _expressions; }
231 GrowableArray<MonitorValue*>* monitors() { return _monitors; }
232 IRScopeDebugInfo* caller() { return _caller; }
233
234 //Whether we should reexecute this bytecode for deopt
235 bool should_reexecute();
236
237 void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool reexecute) {
238 if (caller() != nullptr) {
239 // Order is significant: Must record caller first.
240 caller()->record_debug_info(recorder, pc_offset, false/*reexecute*/);
241 }
242 DebugToken* locvals = recorder->create_scope_values(locals());
243 DebugToken* expvals = recorder->create_scope_values(expressions());
244 DebugToken* monvals = recorder->create_monitor_values(monitors());
245 // reexecute allowed only for the topmost frame
246 bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
247 bool rethrow_exception = false;
248 bool has_ea_local_in_scope = false;
249 bool arg_escape = false;
250 recorder->describe_scope(pc_offset, methodHandle(), scope()->method(), bci(),
251 reexecute, rethrow_exception, return_oop,
252 has_ea_local_in_scope, arg_escape, locvals, expvals, monvals);
253 }
254 };
255
256
257 class CodeEmitInfo: public CompilationResourceObj {
258 friend class LinearScan;
259 private:
260 IRScopeDebugInfo* _scope_debug_info;
261 IRScope* _scope;
262 XHandlers* _exception_handlers;
263 OopMap* _oop_map;
264 ValueStack* _stack; // used by deoptimization (contains also monitors
265 bool _deoptimize_on_exception;
266 bool _force_reexecute; // force the reexecute flag on, used for patching stub
267
268 FrameMap* frame_map() const { return scope()->compilation()->frame_map(); }
269 Compilation* compilation() const { return scope()->compilation(); }
270
271 public:
272
273 // use scope from ValueStack
274 CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, bool deoptimize_on_exception = false);
275
276 // make a copy
277 CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack = nullptr);
278
279 // accessors
280 OopMap* oop_map() { return _oop_map; }
281 ciMethod* method() const { return _scope->method(); }
282 IRScope* scope() const { return _scope; }
283 XHandlers* exception_handlers() const { return _exception_handlers; }
284 ValueStack* stack() const { return _stack; }
285 bool deoptimize_on_exception() const { return _deoptimize_on_exception; }
286
287 void add_register_oop(LIR_Opr opr);
288 void record_debug_info(DebugInformationRecorder* recorder, int pc_offset);
289
290 bool force_reexecute() const { return _force_reexecute; }
291 void set_force_reexecute() { _force_reexecute = true; }
292
293 int interpreter_frame_size() const;
294
295 };
296
297
298 class IR: public CompilationResourceObj {
299 private:
300 Compilation* _compilation; // the current compilation
301 IRScope* _top_scope; // the root of the scope hierarchy
302 int _num_loops; // Total number of loops
303 BlockList* _code; // the blocks in code generation order w/ use counts
304
305 public:
306 // creation
307 IR(Compilation* compilation, ciMethod* method, int osr_bci);
308
|
128 };
129
130
131 class IRScope;
132 typedef GrowableArray<IRScope*> IRScopeList;
133
134 class Compilation;
135 class IRScope: public CompilationResourceObj {
136 private:
137 // hierarchy
138 Compilation* _compilation; // the current compilation
139 IRScope* _caller; // the caller scope, or null
140 int _level; // the inlining level
141 ciMethod* _method; // the corresponding method
142 IRScopeList _callees; // the inlined method scopes
143
144 // graph
145 XHandlers* _xhandlers; // the exception handlers
146 int _number_of_locks; // the number of monitor lock slots needed
147 bool _monitor_pairing_ok; // the monitor pairing info
148 bool _wrote_non_strict_final; // has written non-strict final field
149 bool _wrote_fields; // has written fields
150 bool _wrote_volatile; // has written volatile field
151 bool _wrote_stable; // has written @Stable field
152 BlockBegin* _start; // the start block, successsors are method entries
153
154 ResourceBitMap _requires_phi_function; // bit is set if phi functions at loop headers are necessary for a local variable
155
156 // helper functions
157 BlockBegin* build_graph(Compilation* compilation, int osr_bci);
158
159 public:
160 // creation
161 IRScope(Compilation* compilation, IRScope* caller, int caller_bci, ciMethod* method, int osr_bci, bool create_graph = false);
162
163 // accessors
164 Compilation* compilation() const { return _compilation; }
165 IRScope* caller() const { return _caller; }
166 int level() const { return _level; }
167 ciMethod* method() const { return _method; }
168 int max_stack() const; // NOTE: expensive
169 BitMap& requires_phi_function() { return _requires_phi_function; }
170
171 // hierarchy
172 bool is_top_scope() const { return _caller == nullptr; }
173 void add_callee(IRScope* callee) { _callees.append(callee); }
174 int number_of_callees() const { return _callees.length(); }
175 IRScope* callee_no(int i) const { return _callees.at(i); }
176
177 // accessors, graph
178 bool is_valid() const { return start() != nullptr; }
179 XHandlers* xhandlers() const { return _xhandlers; }
180 int number_of_locks() const { return _number_of_locks; }
181 void set_min_number_of_locks(int n) { if (n > _number_of_locks) _number_of_locks = n; }
182 bool monitor_pairing_ok() const { return _monitor_pairing_ok; }
183 BlockBegin* start() const { return _start; }
184 void set_wrote_non_strict_final() { _wrote_non_strict_final = true; }
185 bool wrote_non_strict_final() const { return _wrote_non_strict_final; }
186 void set_wrote_fields() { _wrote_fields = true; }
187 bool wrote_fields () const { return _wrote_fields; }
188 void set_wrote_volatile() { _wrote_volatile = true; }
189 bool wrote_volatile () const { return _wrote_volatile; }
190 void set_wrote_stable() { _wrote_stable = true; }
191 bool wrote_stable() const { return _wrote_stable; }
192 };
193
194
195 //
196 // IRScopeDebugInfo records the debug information for a particular IRScope
197 // in a particular CodeEmitInfo. This allows the information to be computed
198 // once early enough for the OopMap to be available to the LIR and also to be
199 // reemited for different pcs using the same CodeEmitInfo without recomputing
200 // everything.
201 //
202
203 class IRScopeDebugInfo: public CompilationResourceObj {
204 private:
205 IRScope* _scope;
206 int _bci;
207 GrowableArray<ScopeValue*>* _locals;
208 GrowableArray<ScopeValue*>* _expressions;
209 GrowableArray<MonitorValue*>* _monitors;
210 IRScopeDebugInfo* _caller;
211 bool _should_reexecute;
212
213 public:
214 IRScopeDebugInfo(IRScope* scope,
215 int bci,
216 GrowableArray<ScopeValue*>* locals,
217 GrowableArray<ScopeValue*>* expressions,
218 GrowableArray<MonitorValue*>* monitors,
219 IRScopeDebugInfo* caller,
220 bool should_reexecute):
221 _scope(scope)
222 , _bci(bci)
223 , _locals(locals)
224 , _expressions(expressions)
225 , _monitors(monitors)
226 , _caller(caller)
227 , _should_reexecute(should_reexecute) {}
228
229
230 IRScope* scope() { return _scope; }
231 int bci() { return _bci; }
232 GrowableArray<ScopeValue*>* locals() { return _locals; }
233 GrowableArray<ScopeValue*>* expressions() { return _expressions; }
234 GrowableArray<MonitorValue*>* monitors() { return _monitors; }
235 IRScopeDebugInfo* caller() { return _caller; }
236
237 //Whether we should reexecute this bytecode for deopt
238 bool should_reexecute();
239
240 void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool reexecute, bool maybe_return_as_fields = false) {
241 if (caller() != nullptr) {
242 // Order is significant: Must record caller first.
243 caller()->record_debug_info(recorder, pc_offset, false/*reexecute*/);
244 }
245 DebugToken* locvals = recorder->create_scope_values(locals());
246 DebugToken* expvals = recorder->create_scope_values(expressions());
247 DebugToken* monvals = recorder->create_monitor_values(monitors());
248 // reexecute allowed only for the topmost frame
249 bool return_oop = false;
250 bool return_scalarized = false;
251 if (maybe_return_as_fields) {
252 return_oop = true;
253 return_scalarized = true;
254 }
255 bool rethrow_exception = false;
256 bool has_ea_local_in_scope = false;
257 bool arg_escape = false;
258 recorder->describe_scope(pc_offset, methodHandle(), scope()->method(), bci(),
259 reexecute, rethrow_exception, return_oop, return_scalarized,
260 has_ea_local_in_scope, arg_escape, locvals, expvals, monvals);
261 }
262 };
263
264
265 class CodeEmitInfo: public CompilationResourceObj {
266 friend class LinearScan;
267 private:
268 IRScopeDebugInfo* _scope_debug_info;
269 IRScope* _scope;
270 XHandlers* _exception_handlers;
271 OopMap* _oop_map;
272 ValueStack* _stack; // used by deoptimization (contains also monitors
273 bool _deoptimize_on_exception;
274 bool _force_reexecute; // force the reexecute flag on, used for patching stub
275
276 FrameMap* frame_map() const { return scope()->compilation()->frame_map(); }
277 Compilation* compilation() const { return scope()->compilation(); }
278
279 public:
280
281 // use scope from ValueStack
282 CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, bool deoptimize_on_exception = false);
283
284 // make a copy
285 CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack = nullptr);
286
287 // accessors
288 OopMap* oop_map() { return _oop_map; }
289 ciMethod* method() const { return _scope->method(); }
290 IRScope* scope() const { return _scope; }
291 XHandlers* exception_handlers() const { return _exception_handlers; }
292 ValueStack* stack() const { return _stack; }
293 bool deoptimize_on_exception() const { return _deoptimize_on_exception; }
294
295 void add_register_oop(LIR_Opr opr);
296 void record_debug_info(DebugInformationRecorder* recorder, int pc_offset, bool maybe_return_as_fields = false);
297
298 bool force_reexecute() const { return _force_reexecute; }
299 void set_force_reexecute() { _force_reexecute = true; }
300
301 int interpreter_frame_size() const;
302
303 };
304
305
306 class IR: public CompilationResourceObj {
307 private:
308 Compilation* _compilation; // the current compilation
309 IRScope* _top_scope; // the root of the scope hierarchy
310 int _num_loops; // Total number of loops
311 BlockList* _code; // the blocks in code generation order w/ use counts
312
313 public:
314 // creation
315 IR(Compilation* compilation, ciMethod* method, int osr_bci);
316
|