49 // - pcs |
49 // - pcs |
50 // [Exception handler table] |
50 // [Exception handler table] |
51 // - handler entry point array |
51 // - handler entry point array |
52 // [Implicit Null Pointer exception table] |
52 // [Implicit Null Pointer exception table] |
53 // - implicit null table array |
53 // - implicit null table array |
|
54 // [Speculations] |
|
55 // - encoded speculations array |
|
56 // [JVMCINMethodData] |
|
57 // - meta data for JVMCI compiled nmethod |
|
58 |
|
59 #if INCLUDE_JVMCI |
|
60 class FailedSpeculation; |
|
61 class JVMCINMethodData; |
|
62 #endif |
54 |
63 |
55 class nmethod : public CompiledMethod { |
64 class nmethod : public CompiledMethod { |
56 friend class VMStructs; |
65 friend class VMStructs; |
57 friend class JVMCIVMStructs; |
66 friend class JVMCIVMStructs; |
58 friend class NMethodSweeper; |
67 friend class NMethodSweeper; |
59 friend class CodeCache; // scavengable oops |
68 friend class CodeCache; // scavengable oops |
|
69 friend class JVMCINMethodData; |
60 private: |
70 private: |
61 |
71 |
62 // Shared fields for all nmethod's |
72 // Shared fields for all nmethod's |
63 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 |
64 jmethodID _jmethod_id; // Cache of method()->jmethod_id() |
74 jmethodID _jmethod_id; // Cache of method()->jmethod_id() |
65 |
|
66 #if INCLUDE_JVMCI |
|
67 // A weak reference to an InstalledCode object associated with |
|
68 // this nmethod. |
|
69 jweak _jvmci_installed_code; |
|
70 |
|
71 // A weak reference to a SpeculationLog object associated with |
|
72 // this nmethod. |
|
73 jweak _speculation_log; |
|
74 |
|
75 // Determines whether this nmethod is unloaded when the |
|
76 // referent in _jvmci_installed_code is cleared. This |
|
77 // will be false if the referent is initialized to a |
|
78 // HotSpotNMethod object whose isDefault field is true. |
|
79 // That is, installed code other than a "default" |
|
80 // HotSpotNMethod causes nmethod unloading. |
|
81 // This field is ignored once _jvmci_installed_code is NULL. |
|
82 bool _jvmci_installed_code_triggers_invalidation; |
|
83 #endif |
|
84 |
75 |
85 // To support simple linked-list chaining of nmethods: |
76 // To support simple linked-list chaining of nmethods: |
86 nmethod* _osr_link; // from InstanceKlass::osr_nmethods_head |
77 nmethod* _osr_link; // from InstanceKlass::osr_nmethods_head |
87 |
78 |
88 static nmethod* volatile _oops_do_mark_nmethods; |
79 static nmethod* volatile _oops_do_mark_nmethods; |
105 int _scopes_data_offset; |
96 int _scopes_data_offset; |
106 int _scopes_pcs_offset; |
97 int _scopes_pcs_offset; |
107 int _dependencies_offset; |
98 int _dependencies_offset; |
108 int _handler_table_offset; |
99 int _handler_table_offset; |
109 int _nul_chk_table_offset; |
100 int _nul_chk_table_offset; |
|
101 #if INCLUDE_JVMCI |
|
102 int _speculations_offset; |
|
103 int _jvmci_data_offset; |
|
104 #endif |
110 int _nmethod_end_offset; |
105 int _nmethod_end_offset; |
111 |
106 |
112 int code_offset() const { return (address) code_begin() - header_begin(); } |
107 int code_offset() const { return (address) code_begin() - header_begin(); } |
113 |
108 |
114 // location in frame (offset for sp) that deopt can store the original |
109 // location in frame (offset for sp) that deopt can store the original |
205 ExceptionHandlerTable* handler_table, |
200 ExceptionHandlerTable* handler_table, |
206 ImplicitExceptionTable* nul_chk_table, |
201 ImplicitExceptionTable* nul_chk_table, |
207 AbstractCompiler* compiler, |
202 AbstractCompiler* compiler, |
208 int comp_level |
203 int comp_level |
209 #if INCLUDE_JVMCI |
204 #if INCLUDE_JVMCI |
210 , jweak installed_code, |
205 , char* speculations, |
211 jweak speculation_log |
206 int speculations_len, |
|
207 int jvmci_data_size |
212 #endif |
208 #endif |
213 ); |
209 ); |
214 |
210 |
215 // helper methods |
211 // helper methods |
216 void* operator new(size_t size, int nmethod_size, int comp_level) throw(); |
212 void* operator new(size_t size, int nmethod_size, int comp_level) throw(); |
249 ExceptionHandlerTable* handler_table, |
245 ExceptionHandlerTable* handler_table, |
250 ImplicitExceptionTable* nul_chk_table, |
246 ImplicitExceptionTable* nul_chk_table, |
251 AbstractCompiler* compiler, |
247 AbstractCompiler* compiler, |
252 int comp_level |
248 int comp_level |
253 #if INCLUDE_JVMCI |
249 #if INCLUDE_JVMCI |
254 , jweak installed_code = NULL, |
250 , char* speculations = NULL, |
255 jweak speculation_log = NULL |
251 int speculations_len = 0, |
|
252 int nmethod_mirror_index = -1, |
|
253 const char* nmethod_mirror_name = NULL, |
|
254 FailedSpeculation** failed_speculations = NULL |
256 #endif |
255 #endif |
257 ); |
256 ); |
258 |
257 |
259 // Only used for unit tests. |
258 // Only used for unit tests. |
260 nmethod() |
259 nmethod() |
297 address dependencies_begin () const { return header_begin() + _dependencies_offset ; } |
296 address dependencies_begin () const { return header_begin() + _dependencies_offset ; } |
298 address dependencies_end () const { return header_begin() + _handler_table_offset ; } |
297 address dependencies_end () const { return header_begin() + _handler_table_offset ; } |
299 address handler_table_begin () const { return header_begin() + _handler_table_offset ; } |
298 address handler_table_begin () const { return header_begin() + _handler_table_offset ; } |
300 address handler_table_end () const { return header_begin() + _nul_chk_table_offset ; } |
299 address handler_table_end () const { return header_begin() + _nul_chk_table_offset ; } |
301 address nul_chk_table_begin () const { return header_begin() + _nul_chk_table_offset ; } |
300 address nul_chk_table_begin () const { return header_begin() + _nul_chk_table_offset ; } |
|
301 #if INCLUDE_JVMCI |
|
302 address nul_chk_table_end () const { return header_begin() + _speculations_offset ; } |
|
303 address speculations_begin () const { return header_begin() + _speculations_offset ; } |
|
304 address speculations_end () const { return header_begin() + _jvmci_data_offset ; } |
|
305 address jvmci_data_begin () const { return header_begin() + _jvmci_data_offset ; } |
|
306 address jvmci_data_end () const { return header_begin() + _nmethod_end_offset ; } |
|
307 #else |
302 address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; } |
308 address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; } |
|
309 #endif |
303 |
310 |
304 // Sizes |
311 // Sizes |
305 int oops_size () const { return (address) oops_end () - (address) oops_begin (); } |
312 int oops_size () const { return (address) oops_end () - (address) oops_begin (); } |
306 int metadata_size () const { return (address) metadata_end () - (address) metadata_begin (); } |
313 int metadata_size () const { return (address) metadata_end () - (address) metadata_begin (); } |
307 int dependencies_size () const { return dependencies_end () - dependencies_begin (); } |
314 int dependencies_size () const { return dependencies_end () - dependencies_begin (); } |
|
315 #if INCLUDE_JVMCI |
|
316 int speculations_size () const { return speculations_end () - speculations_begin (); } |
|
317 int jvmci_data_size () const { return jvmci_data_end () - jvmci_data_begin (); } |
|
318 #endif |
308 |
319 |
309 int oops_count() const { assert(oops_size() % oopSize == 0, ""); return (oops_size() / oopSize) + 1; } |
320 int oops_count() const { assert(oops_size() % oopSize == 0, ""); return (oops_size() / oopSize) + 1; } |
310 int metadata_count() const { assert(metadata_size() % wordSize == 0, ""); return (metadata_size() / wordSize) + 1; } |
321 int metadata_count() const { assert(metadata_size() % wordSize == 0, ""); return (metadata_size() / wordSize) + 1; } |
311 |
322 |
312 int total_size () const; |
323 int total_size () const; |
444 |
455 |
445 // Evolution support. We make old (discarded) compiled methods point to new Method*s. |
456 // Evolution support. We make old (discarded) compiled methods point to new Method*s. |
446 void set_method(Method* method) { _method = method; } |
457 void set_method(Method* method) { _method = method; } |
447 |
458 |
448 #if INCLUDE_JVMCI |
459 #if INCLUDE_JVMCI |
449 // Gets the InstalledCode object associated with this nmethod |
460 // Gets the JVMCI name of this nmethod. |
450 // which may be NULL if this nmethod was not compiled by JVMCI |
461 const char* jvmci_name(); |
451 // or the weak reference has been cleared. |
462 |
452 oop jvmci_installed_code(); |
463 // Records the pending failed speculation in the |
453 |
464 // JVMCI speculation log associated with this nmethod. |
454 // Copies the value of the name field in the InstalledCode |
465 void update_speculation(JavaThread* thread); |
455 // object (if any) associated with this nmethod into buf. |
466 |
456 // Returns the value of buf if it was updated otherwise NULL. |
467 // Gets the data specific to a JVMCI compiled method. |
457 char* jvmci_installed_code_name(char* buf, size_t buflen) const; |
468 // This returns a non-NULL value iff this nmethod was |
458 |
469 // compiled by the JVMCI compiler. |
459 // Updates the state of the InstalledCode (if any) associated with |
470 JVMCINMethodData* jvmci_nmethod_data() const { |
460 // this nmethod based on the current value of _state. |
471 return jvmci_data_size() == 0 ? NULL : (JVMCINMethodData*) jvmci_data_begin(); |
461 void maybe_invalidate_installed_code(); |
472 } |
462 |
|
463 // Deoptimizes the nmethod (if any) in the address field of a given |
|
464 // InstalledCode object. The address field is zeroed upon return. |
|
465 static void invalidate_installed_code(Handle installed_code, TRAPS); |
|
466 |
|
467 // Gets the SpeculationLog object associated with this nmethod |
|
468 // which may be NULL if this nmethod was not compiled by JVMCI |
|
469 // or the weak reference has been cleared. |
|
470 oop speculation_log(); |
|
471 |
|
472 private: |
|
473 // Deletes the weak reference (if any) to the InstalledCode object |
|
474 // associated with this nmethod. |
|
475 void clear_jvmci_installed_code(); |
|
476 |
|
477 // Deletes the weak reference (if any) to the SpeculationLog object |
|
478 // associated with this nmethod. |
|
479 void clear_speculation_log(); |
|
480 |
|
481 public: |
|
482 #endif |
473 #endif |
483 |
474 |
484 public: |
475 public: |
485 void oops_do(OopClosure* f) { oops_do(f, false); } |
476 void oops_do(OopClosure* f) { oops_do(f, false); } |
486 void oops_do(OopClosure* f, bool allow_zombie); |
477 void oops_do(OopClosure* f, bool allow_zombie); |