Mercurial > hg > truffle
comparison src/share/vm/ci/ciMethodData.hpp @ 14500:fdad2932c73f
8031752: Failed speculative optimizations should be reattempted when root of compilation is different
Summary: support for speculative traps that keep track of the root of the compilation in which a trap occurs.
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Tue, 25 Feb 2014 18:16:24 +0100 |
parents | de6a9e811145 |
children | 4ca6dc0799b6 606acabe7b5c |
comparison
equal
deleted
inserted
replaced
14498:04e7587c97dc | 14500:fdad2932c73f |
---|---|
29 #include "ci/ciKlass.hpp" | 29 #include "ci/ciKlass.hpp" |
30 #include "ci/ciObject.hpp" | 30 #include "ci/ciObject.hpp" |
31 #include "ci/ciUtilities.hpp" | 31 #include "ci/ciUtilities.hpp" |
32 #include "oops/methodData.hpp" | 32 #include "oops/methodData.hpp" |
33 #include "oops/oop.inline.hpp" | 33 #include "oops/oop.inline.hpp" |
34 #include "runtime/deoptimization.hpp" | |
34 | 35 |
35 class ciBitData; | 36 class ciBitData; |
36 class ciCounterData; | 37 class ciCounterData; |
37 class ciJumpData; | 38 class ciJumpData; |
38 class ciReceiverTypeData; | 39 class ciReceiverTypeData; |
42 class ciMultiBranchData; | 43 class ciMultiBranchData; |
43 class ciArgInfoData; | 44 class ciArgInfoData; |
44 class ciCallTypeData; | 45 class ciCallTypeData; |
45 class ciVirtualCallTypeData; | 46 class ciVirtualCallTypeData; |
46 class ciParametersTypeData; | 47 class ciParametersTypeData; |
48 class ciSpeculativeTrapData;; | |
47 | 49 |
48 typedef ProfileData ciProfileData; | 50 typedef ProfileData ciProfileData; |
49 | 51 |
50 class ciBitData : public BitData { | 52 class ciBitData : public BitData { |
51 public: | 53 public: |
171 bool return_maybe_null() const { | 173 bool return_maybe_null() const { |
172 return ret()->maybe_null(); | 174 return ret()->maybe_null(); |
173 } | 175 } |
174 | 176 |
175 #ifndef PRODUCT | 177 #ifndef PRODUCT |
176 void print_data_on(outputStream* st) const; | 178 void print_data_on(outputStream* st, const char* extra) const; |
177 #endif | 179 #endif |
178 }; | 180 }; |
179 | 181 |
180 class ciReceiverTypeData : public ReceiverTypeData { | 182 class ciReceiverTypeData : public ReceiverTypeData { |
181 public: | 183 public: |
198 virtual void translate_from(const ProfileData* data) { | 200 virtual void translate_from(const ProfileData* data) { |
199 translate_receiver_data_from(data); | 201 translate_receiver_data_from(data); |
200 } | 202 } |
201 void translate_receiver_data_from(const ProfileData* data); | 203 void translate_receiver_data_from(const ProfileData* data); |
202 #ifndef PRODUCT | 204 #ifndef PRODUCT |
203 void print_data_on(outputStream* st) const; | 205 void print_data_on(outputStream* st, const char* extra) const; |
204 void print_receiver_data_on(outputStream* st) const; | 206 void print_receiver_data_on(outputStream* st) const; |
205 #endif | 207 #endif |
206 }; | 208 }; |
207 | 209 |
208 class ciVirtualCallData : public VirtualCallData { | 210 class ciVirtualCallData : public VirtualCallData { |
223 // Copy & translate from oop based VirtualCallData | 225 // Copy & translate from oop based VirtualCallData |
224 virtual void translate_from(const ProfileData* data) { | 226 virtual void translate_from(const ProfileData* data) { |
225 rtd_super()->translate_receiver_data_from(data); | 227 rtd_super()->translate_receiver_data_from(data); |
226 } | 228 } |
227 #ifndef PRODUCT | 229 #ifndef PRODUCT |
228 void print_data_on(outputStream* st) const; | 230 void print_data_on(outputStream* st, const char* extra) const; |
229 #endif | 231 #endif |
230 }; | 232 }; |
231 | 233 |
232 class ciVirtualCallTypeData : public VirtualCallTypeData { | 234 class ciVirtualCallTypeData : public VirtualCallTypeData { |
233 private: | 235 private: |
285 bool return_maybe_null() const { | 287 bool return_maybe_null() const { |
286 return ret()->maybe_null(); | 288 return ret()->maybe_null(); |
287 } | 289 } |
288 | 290 |
289 #ifndef PRODUCT | 291 #ifndef PRODUCT |
290 void print_data_on(outputStream* st) const; | 292 void print_data_on(outputStream* st, const char* extra) const; |
291 #endif | 293 #endif |
292 }; | 294 }; |
293 | 295 |
294 | 296 |
295 class ciRetData : public RetData { | 297 class ciRetData : public RetData { |
334 bool parameter_maybe_null(int i) const { | 336 bool parameter_maybe_null(int i) const { |
335 return parameters()->maybe_null(i); | 337 return parameters()->maybe_null(i); |
336 } | 338 } |
337 | 339 |
338 #ifndef PRODUCT | 340 #ifndef PRODUCT |
339 void print_data_on(outputStream* st) const; | 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; | |
340 #endif | 361 #endif |
341 }; | 362 }; |
342 | 363 |
343 // ciMethodData | 364 // ciMethodData |
344 // | 365 // |
433 | 454 |
434 // What is the index of the first data entry? | 455 // What is the index of the first data entry? |
435 int first_di() { return 0; } | 456 int first_di() { return 0; } |
436 | 457 |
437 ciArgInfoData *arg_info() const; | 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); | |
438 | 469 |
439 public: | 470 public: |
440 bool is_method_data() const { return true; } | 471 bool is_method_data() const { return true; } |
441 | 472 |
442 bool is_empty() { return _state == empty_state; } | 473 bool is_empty() { return _state == empty_state; } |
473 // Walk through the data in order. | 504 // Walk through the data in order. |
474 ciProfileData* first_data() { return data_at(first_di()); } | 505 ciProfileData* first_data() { return data_at(first_di()); } |
475 ciProfileData* next_data(ciProfileData* current); | 506 ciProfileData* next_data(ciProfileData* current); |
476 bool is_valid(ciProfileData* current) { return current != NULL; } | 507 bool is_valid(ciProfileData* current) { return current != NULL; } |
477 | 508 |
478 // Get the data at an arbitrary bci, or NULL if there is none. | 509 DataLayout* extra_data_base() const { return limit_data_position(); } |
479 ciProfileData* bci_to_data(int bci); | 510 |
480 ciProfileData* bci_to_extra_data(int bci, bool create_if_missing); | 511 // Get the data at an arbitrary bci, or NULL if there is none. If m |
512 // is not NULL look for a SpeculativeTrapData if any first. | |
513 ciProfileData* bci_to_data(int bci, ciMethod* m = NULL); | |
481 | 514 |
482 uint overflow_trap_count() const { | 515 uint overflow_trap_count() const { |
483 return _orig.overflow_trap_count(); | 516 return _orig.overflow_trap_count(); |
484 } | 517 } |
485 uint overflow_recompile_count() const { | 518 uint overflow_recompile_count() const { |
494 uint trap_reason_limit() const { return _orig.trap_reason_limit(); } | 527 uint trap_reason_limit() const { return _orig.trap_reason_limit(); } |
495 uint trap_count_limit() const { return _orig.trap_count_limit(); } | 528 uint trap_count_limit() const { return _orig.trap_count_limit(); } |
496 | 529 |
497 // Helpful query functions that decode trap_state. | 530 // Helpful query functions that decode trap_state. |
498 int has_trap_at(ciProfileData* data, int reason); | 531 int has_trap_at(ciProfileData* data, int reason); |
499 int has_trap_at(int bci, int reason) { | 532 int has_trap_at(int bci, ciMethod* m, int reason) { |
500 return has_trap_at(bci_to_data(bci), reason); | 533 assert((m != NULL) == Deoptimization::reason_is_speculate(reason), "inconsistent method/reason"); |
534 return has_trap_at(bci_to_data(bci, m), reason); | |
501 } | 535 } |
502 int trap_recompiled_at(ciProfileData* data); | 536 int trap_recompiled_at(ciProfileData* data); |
503 int trap_recompiled_at(int bci) { | 537 int trap_recompiled_at(int bci, ciMethod* m) { |
504 return trap_recompiled_at(bci_to_data(bci)); | 538 return trap_recompiled_at(bci_to_data(bci, m)); |
505 } | 539 } |
506 | 540 |
507 void clear_escape_info(); | 541 void clear_escape_info(); |
508 bool has_escape_info(); | 542 bool has_escape_info(); |
509 void update_escape_info(); | 543 void update_escape_info(); |