28 #include "ci/ciClassList.hpp"
29 #include "ci/ciKlass.hpp"
30 #include "ci/ciObject.hpp"
31 #include "ci/ciUtilities.hpp"
32 #include "oops/methodData.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "runtime/deoptimization.hpp"
35
36 class ciBitData;
37 class ciCounterData;
38 class ciJumpData;
39 class ciReceiverTypeData;
40 class ciRetData;
41 class ciBranchData;
42 class ciArrayData;
43 class ciMultiBranchData;
44 class ciArgInfoData;
45 class ciCallTypeData;
46 class ciVirtualCallTypeData;
47 class ciParametersTypeData;
48 class ciSpeculativeTrapData;;
49
50 typedef ProfileData ciProfileData;
51
52 class ciBitData : public BitData {
53 public:
54 ciBitData(DataLayout* layout) : BitData(layout) {};
55 };
56
57 class ciCounterData : public CounterData {
58 public:
59 ciCounterData(DataLayout* layout) : CounterData(layout) {};
60 };
61
62 class ciJumpData : public JumpData {
63 public:
64 ciJumpData(DataLayout* layout) : JumpData(layout) {};
65 };
66
67 class ciTypeEntries {
68 protected:
158
159 intptr_t return_type() const {
160 assert(has_return(), "no ret type profiling data");
161 return ret()->type();
162 }
163
164 ciKlass* valid_return_type() const {
165 assert(has_return(), "no ret type profiling data");
166 return ret()->valid_type();
167 }
168
169 bool argument_maybe_null(int i) const {
170 return args()->maybe_null(i);
171 }
172
173 bool return_maybe_null() const {
174 return ret()->maybe_null();
175 }
176
177 #ifndef PRODUCT
178 void print_data_on(outputStream* st, const char* extra) const;
179 #endif
180 };
181
182 class ciReceiverTypeData : public ReceiverTypeData {
183 public:
184 ciReceiverTypeData(DataLayout* layout) : ReceiverTypeData(layout) {};
185
186 void set_receiver(uint row, ciKlass* recv) {
187 assert((uint)row < row_limit(), "oob");
188 set_intptr_at(receiver0_offset + row * receiver_type_row_cell_count,
189 (intptr_t) recv);
190 }
191
192 ciKlass* receiver(uint row) const {
193 assert((uint)row < row_limit(), "oob");
194 ciKlass* recv = (ciKlass*)intptr_at(receiver0_offset + row * receiver_type_row_cell_count);
195 assert(recv == NULL || recv->is_klass(), "wrong type");
196 return recv;
197 }
198
199 // Copy & translate from oop based ReceiverTypeData
200 virtual void translate_from(const ProfileData* data) {
201 translate_receiver_data_from(data);
202 }
203 void translate_receiver_data_from(const ProfileData* data);
204 #ifndef PRODUCT
205 void print_data_on(outputStream* st, const char* extra) const;
206 void print_receiver_data_on(outputStream* st) const;
207 #endif
208 };
209
210 class ciVirtualCallData : public VirtualCallData {
211 // Fake multiple inheritance... It's a ciReceiverTypeData also.
212 ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; }
213
214 public:
215 ciVirtualCallData(DataLayout* layout) : VirtualCallData(layout) {};
216
217 void set_receiver(uint row, ciKlass* recv) {
218 rtd_super()->set_receiver(row, recv);
219 }
220
221 ciKlass* receiver(uint row) {
222 return rtd_super()->receiver(row);
223 }
224
225 // Copy & translate from oop based VirtualCallData
226 virtual void translate_from(const ProfileData* data) {
227 rtd_super()->translate_receiver_data_from(data);
228 }
229 #ifndef PRODUCT
230 void print_data_on(outputStream* st, const char* extra) const;
231 #endif
232 };
233
234 class ciVirtualCallTypeData : public VirtualCallTypeData {
235 private:
236 // Fake multiple inheritance... It's a ciReceiverTypeData also.
237 ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; }
238 public:
239 ciVirtualCallTypeData(DataLayout* layout) : VirtualCallTypeData(layout) {}
240
241 void set_receiver(uint row, ciKlass* recv) {
242 rtd_super()->set_receiver(row, recv);
243 }
244
245 ciKlass* receiver(uint row) const {
246 return rtd_super()->receiver(row);
247 }
248
249 ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)VirtualCallTypeData::args(); }
250 ciReturnTypeEntry* ret() const { return (ciReturnTypeEntry*)VirtualCallTypeData::ret(); }
272
273 intptr_t return_type() const {
274 assert(has_return(), "no ret type profiling data");
275 return ret()->type();
276 }
277
278 ciKlass* valid_return_type() const {
279 assert(has_return(), "no ret type profiling data");
280 return ret()->valid_type();
281 }
282
283 bool argument_maybe_null(int i) const {
284 return args()->maybe_null(i);
285 }
286
287 bool return_maybe_null() const {
288 return ret()->maybe_null();
289 }
290
291 #ifndef PRODUCT
292 void print_data_on(outputStream* st, const char* extra) const;
293 #endif
294 };
295
296
297 class ciRetData : public RetData {
298 public:
299 ciRetData(DataLayout* layout) : RetData(layout) {};
300 };
301
302 class ciBranchData : public BranchData {
303 public:
304 ciBranchData(DataLayout* layout) : BranchData(layout) {};
305 };
306
307 class ciArrayData : public ArrayData {
308 public:
309 ciArrayData(DataLayout* layout) : ArrayData(layout) {};
310 };
311
312 class ciMultiBranchData : public MultiBranchData {
321
322 class ciParametersTypeData : public ParametersTypeData {
323 public:
324 ciParametersTypeData(DataLayout* layout) : ParametersTypeData(layout) {}
325
326 virtual void translate_from(const ProfileData* data) {
327 parameters()->translate_type_data_from(data->as_ParametersTypeData()->parameters());
328 }
329
330 ciTypeStackSlotEntries* parameters() const { return (ciTypeStackSlotEntries*)ParametersTypeData::parameters(); }
331
332 ciKlass* valid_parameter_type(int i) const {
333 return parameters()->valid_type(i);
334 }
335
336 bool parameter_maybe_null(int i) const {
337 return parameters()->maybe_null(i);
338 }
339
340 #ifndef PRODUCT
341 void print_data_on(outputStream* st, const char* extra) const;
342 #endif
343 };
344
345 class ciSpeculativeTrapData : public SpeculativeTrapData {
346 public:
347 ciSpeculativeTrapData(DataLayout* layout) : SpeculativeTrapData(layout) {}
348
349 virtual void translate_from(const ProfileData* data);
350
351 ciMethod* method() const {
352 return (ciMethod*)intptr_at(method_offset);
353 }
354
355 void set_method(ciMethod* m) {
356 set_intptr_at(method_offset, (intptr_t)m);
357 }
358
359 #ifndef PRODUCT
360 void print_data_on(outputStream* st, const char* extra) const;
361 #endif
362 };
363
364 // ciMethodData
365 //
366 // This class represents a MethodData* in the HotSpot virtual
367 // machine.
368
369 class ciMethodData : public ciMetadata {
370 CI_PACKAGE_ACCESS
371 friend class ciReplay;
372
373 private:
374 // Size in bytes
375 int _data_size;
376 int _extra_data_size;
377
378 // Data entries
379 intptr_t* _data;
380
389 u_char _saw_free_extra_data;
390
391 // Support for interprocedural escape analysis
392 intx _eflags; // flags on escape information
393 intx _arg_local; // bit set of non-escaping arguments
394 intx _arg_stack; // bit set of stack-allocatable arguments
395 intx _arg_returned; // bit set of returned arguments
396
397 // Maturity of the oop when the snapshot is taken.
398 int _current_mileage;
399
400 // These counters hold the age of MDO in tiered. In tiered we can have the same method
401 // running at different compilation levels concurrently. So, in order to precisely measure
402 // its maturity we need separate counters.
403 int _invocation_counter;
404 int _backedge_counter;
405
406 // Coherent snapshot of original header.
407 MethodData _orig;
408
409 // Dedicated area dedicated to parameters. Null if no parameter
410 // profiling for this method.
411 DataLayout* _parameters;
412
413 ciMethodData(MethodData* md);
414 ciMethodData();
415
416 // Accessors
417 int data_size() const { return _data_size; }
418 int extra_data_size() const { return _extra_data_size; }
419 intptr_t * data() const { return _data; }
420
421 MethodData* get_MethodData() const {
422 return (MethodData*)_metadata;
423 }
424
425 const char* type_string() { return "ciMethodData"; }
426
427 void print_impl(outputStream* st);
428
429 DataLayout* data_layout_at(int data_index) const {
430 assert(data_index % sizeof(intptr_t) == 0, "unaligned");
449 if (data_layout_at(hint)->bci() <= bci)
450 return data_at(hint);
451 return first_data();
452 }
453
454
455 // What is the index of the first data entry?
456 int first_di() { return 0; }
457
458 ciArgInfoData *arg_info() const;
459
460 address data_base() const {
461 return (address) _data;
462 }
463 DataLayout* limit_data_position() const {
464 return (DataLayout*)((address)data_base() + _data_size);
465 }
466
467 void load_extra_data();
468 ciProfileData* bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots);
469
470 public:
471 bool is_method_data() const { return true; }
472
473 bool is_empty() { return _state == empty_state; }
474 bool is_mature() { return _state == mature_state; }
475
476 int creation_mileage() { return _orig.creation_mileage(); }
477 int current_mileage() { return _current_mileage; }
478
479 int invocation_count() { return _invocation_counter; }
480 int backedge_count() { return _backedge_counter; }
481 // Transfer information about the method to MethodData*.
482 // would_profile means we would like to profile this method,
483 // meaning it's not trivial.
484 void set_would_profile(bool p);
485 // Also set the numer of loops and blocks in the method.
486 // Again, this is used to determine if a method is trivial.
487 void set_compilation_stats(short loops, short blocks);
488 // If the compiler finds a profiled type that is known statically
|
28 #include "ci/ciClassList.hpp"
29 #include "ci/ciKlass.hpp"
30 #include "ci/ciObject.hpp"
31 #include "ci/ciUtilities.hpp"
32 #include "oops/methodData.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "runtime/deoptimization.hpp"
35
36 class ciBitData;
37 class ciCounterData;
38 class ciJumpData;
39 class ciReceiverTypeData;
40 class ciRetData;
41 class ciBranchData;
42 class ciArrayData;
43 class ciMultiBranchData;
44 class ciArgInfoData;
45 class ciCallTypeData;
46 class ciVirtualCallTypeData;
47 class ciParametersTypeData;
48 class ciSpeculativeTrapData;
49
50 typedef ProfileData ciProfileData;
51
52 class ciBitData : public BitData {
53 public:
54 ciBitData(DataLayout* layout) : BitData(layout) {};
55 };
56
57 class ciCounterData : public CounterData {
58 public:
59 ciCounterData(DataLayout* layout) : CounterData(layout) {};
60 };
61
62 class ciJumpData : public JumpData {
63 public:
64 ciJumpData(DataLayout* layout) : JumpData(layout) {};
65 };
66
67 class ciTypeEntries {
68 protected:
158
159 intptr_t return_type() const {
160 assert(has_return(), "no ret type profiling data");
161 return ret()->type();
162 }
163
164 ciKlass* valid_return_type() const {
165 assert(has_return(), "no ret type profiling data");
166 return ret()->valid_type();
167 }
168
169 bool argument_maybe_null(int i) const {
170 return args()->maybe_null(i);
171 }
172
173 bool return_maybe_null() const {
174 return ret()->maybe_null();
175 }
176
177 #ifndef PRODUCT
178 void print_data_on(outputStream* st, const char* extra = NULL) const;
179 #endif
180 };
181
182 class ciReceiverTypeData : public ReceiverTypeData {
183 public:
184 ciReceiverTypeData(DataLayout* layout) : ReceiverTypeData(layout) {};
185
186 void set_receiver(uint row, ciKlass* recv) {
187 assert((uint)row < row_limit(), "oob");
188 set_intptr_at(receiver0_offset + row * receiver_type_row_cell_count,
189 (intptr_t) recv);
190 }
191
192 ciKlass* receiver(uint row) const {
193 assert((uint)row < row_limit(), "oob");
194 ciKlass* recv = (ciKlass*)intptr_at(receiver0_offset + row * receiver_type_row_cell_count);
195 assert(recv == NULL || recv->is_klass(), "wrong type");
196 return recv;
197 }
198
199 // Copy & translate from oop based ReceiverTypeData
200 virtual void translate_from(const ProfileData* data) {
201 translate_receiver_data_from(data);
202 }
203 void translate_receiver_data_from(const ProfileData* data);
204 #ifndef PRODUCT
205 void print_data_on(outputStream* st, const char* extra = NULL) const;
206 void print_receiver_data_on(outputStream* st) const;
207 #endif
208 };
209
210 class ciVirtualCallData : public VirtualCallData {
211 // Fake multiple inheritance... It's a ciReceiverTypeData also.
212 ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; }
213
214 public:
215 ciVirtualCallData(DataLayout* layout) : VirtualCallData(layout) {};
216
217 void set_receiver(uint row, ciKlass* recv) {
218 rtd_super()->set_receiver(row, recv);
219 }
220
221 ciKlass* receiver(uint row) {
222 return rtd_super()->receiver(row);
223 }
224
225 // Copy & translate from oop based VirtualCallData
226 virtual void translate_from(const ProfileData* data) {
227 rtd_super()->translate_receiver_data_from(data);
228 }
229 #ifndef PRODUCT
230 void print_data_on(outputStream* st, const char* extra = NULL) const;
231 #endif
232 };
233
234 class ciVirtualCallTypeData : public VirtualCallTypeData {
235 private:
236 // Fake multiple inheritance... It's a ciReceiverTypeData also.
237 ciReceiverTypeData* rtd_super() const { return (ciReceiverTypeData*) this; }
238 public:
239 ciVirtualCallTypeData(DataLayout* layout) : VirtualCallTypeData(layout) {}
240
241 void set_receiver(uint row, ciKlass* recv) {
242 rtd_super()->set_receiver(row, recv);
243 }
244
245 ciKlass* receiver(uint row) const {
246 return rtd_super()->receiver(row);
247 }
248
249 ciTypeStackSlotEntries* args() const { return (ciTypeStackSlotEntries*)VirtualCallTypeData::args(); }
250 ciReturnTypeEntry* ret() const { return (ciReturnTypeEntry*)VirtualCallTypeData::ret(); }
272
273 intptr_t return_type() const {
274 assert(has_return(), "no ret type profiling data");
275 return ret()->type();
276 }
277
278 ciKlass* valid_return_type() const {
279 assert(has_return(), "no ret type profiling data");
280 return ret()->valid_type();
281 }
282
283 bool argument_maybe_null(int i) const {
284 return args()->maybe_null(i);
285 }
286
287 bool return_maybe_null() const {
288 return ret()->maybe_null();
289 }
290
291 #ifndef PRODUCT
292 void print_data_on(outputStream* st, const char* extra = NULL) const;
293 #endif
294 };
295
296
297 class ciRetData : public RetData {
298 public:
299 ciRetData(DataLayout* layout) : RetData(layout) {};
300 };
301
302 class ciBranchData : public BranchData {
303 public:
304 ciBranchData(DataLayout* layout) : BranchData(layout) {};
305 };
306
307 class ciArrayData : public ArrayData {
308 public:
309 ciArrayData(DataLayout* layout) : ArrayData(layout) {};
310 };
311
312 class ciMultiBranchData : public MultiBranchData {
321
322 class ciParametersTypeData : public ParametersTypeData {
323 public:
324 ciParametersTypeData(DataLayout* layout) : ParametersTypeData(layout) {}
325
326 virtual void translate_from(const ProfileData* data) {
327 parameters()->translate_type_data_from(data->as_ParametersTypeData()->parameters());
328 }
329
330 ciTypeStackSlotEntries* parameters() const { return (ciTypeStackSlotEntries*)ParametersTypeData::parameters(); }
331
332 ciKlass* valid_parameter_type(int i) const {
333 return parameters()->valid_type(i);
334 }
335
336 bool parameter_maybe_null(int i) const {
337 return parameters()->maybe_null(i);
338 }
339
340 #ifndef PRODUCT
341 void print_data_on(outputStream* st, const char* extra = NULL) const;
342 #endif
343 };
344
345 class ciSpeculativeTrapData : public SpeculativeTrapData {
346 public:
347 ciSpeculativeTrapData(DataLayout* layout) : SpeculativeTrapData(layout) {}
348
349 virtual void translate_from(const ProfileData* data);
350
351 ciMethod* method() const {
352 return (ciMethod*)intptr_at(speculative_trap_method);
353 }
354
355 void set_method(ciMethod* m) {
356 set_intptr_at(speculative_trap_method, (intptr_t)m);
357 }
358
359 #ifndef PRODUCT
360 void print_data_on(outputStream* st, const char* extra = NULL) const;
361 #endif
362 };
363
364 // ciMethodData
365 //
366 // This class represents a MethodData* in the HotSpot virtual
367 // machine.
368
369 class ciMethodData : public ciMetadata {
370 CI_PACKAGE_ACCESS
371 friend class ciReplay;
372
373 private:
374 // Size in bytes
375 int _data_size;
376 int _extra_data_size;
377
378 // Data entries
379 intptr_t* _data;
380
389 u_char _saw_free_extra_data;
390
391 // Support for interprocedural escape analysis
392 intx _eflags; // flags on escape information
393 intx _arg_local; // bit set of non-escaping arguments
394 intx _arg_stack; // bit set of stack-allocatable arguments
395 intx _arg_returned; // bit set of returned arguments
396
397 // Maturity of the oop when the snapshot is taken.
398 int _current_mileage;
399
400 // These counters hold the age of MDO in tiered. In tiered we can have the same method
401 // running at different compilation levels concurrently. So, in order to precisely measure
402 // its maturity we need separate counters.
403 int _invocation_counter;
404 int _backedge_counter;
405
406 // Coherent snapshot of original header.
407 MethodData _orig;
408
409 // Area dedicated to parameters. NULL if no parameter profiling for
410 // this method.
411 DataLayout* _parameters;
412
413 ciMethodData(MethodData* md);
414 ciMethodData();
415
416 // Accessors
417 int data_size() const { return _data_size; }
418 int extra_data_size() const { return _extra_data_size; }
419 intptr_t * data() const { return _data; }
420
421 MethodData* get_MethodData() const {
422 return (MethodData*)_metadata;
423 }
424
425 const char* type_string() { return "ciMethodData"; }
426
427 void print_impl(outputStream* st);
428
429 DataLayout* data_layout_at(int data_index) const {
430 assert(data_index % sizeof(intptr_t) == 0, "unaligned");
449 if (data_layout_at(hint)->bci() <= bci)
450 return data_at(hint);
451 return first_data();
452 }
453
454
455 // What is the index of the first data entry?
456 int first_di() { return 0; }
457
458 ciArgInfoData *arg_info() const;
459
460 address data_base() const {
461 return (address) _data;
462 }
463 DataLayout* limit_data_position() const {
464 return (DataLayout*)((address)data_base() + _data_size);
465 }
466
467 void load_extra_data();
468 ciProfileData* bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots);
469
470 void dump_replay_data_type_helper(outputStream* out, int round, int& count, ProfileData* pdata, ByteSize offset, ciKlass* k);
471 template<class T> void dump_replay_data_call_type_helper(outputStream* out, int round, int& count, T* call_type_data);
472 template<class T> void dump_replay_data_receiver_type_helper(outputStream* out, int round, int& count, T* call_type_data);
473 void dump_replay_data_extra_data_helper(outputStream* out, int round, int& count);
474
475 public:
476 bool is_method_data() const { return true; }
477
478 bool is_empty() { return _state == empty_state; }
479 bool is_mature() { return _state == mature_state; }
480
481 int creation_mileage() { return _orig.creation_mileage(); }
482 int current_mileage() { return _current_mileage; }
483
484 int invocation_count() { return _invocation_counter; }
485 int backedge_count() { return _backedge_counter; }
486 // Transfer information about the method to MethodData*.
487 // would_profile means we would like to profile this method,
488 // meaning it's not trivial.
489 void set_would_profile(bool p);
490 // Also set the numer of loops and blocks in the method.
491 // Again, this is used to determine if a method is trivial.
492 void set_compilation_stats(short loops, short blocks);
493 // If the compiler finds a profiled type that is known statically
|