hotspot/src/share/vm/code/nmethod.hpp
changeset 5924 dc9d04930c82
parent 5896 c60924a89622
child 6176 4d9030fe341f
equal deleted inserted replaced
5915:406168b53eb0 5924:dc9d04930c82
    76   PcDesc* last_pc_desc() { return _last_pc_desc; }
    76   PcDesc* last_pc_desc() { return _last_pc_desc; }
    77 };
    77 };
    78 
    78 
    79 
    79 
    80 // nmethods (native methods) are the compiled code versions of Java methods.
    80 // nmethods (native methods) are the compiled code versions of Java methods.
    81 
    81 //
    82 struct nmFlags {
    82 // An nmethod contains:
    83   friend class VMStructs;
       
    84   unsigned int version:8;                    // version number (0 = first version)
       
    85   unsigned int age:4;                        // age (in # of sweep steps)
       
    86 
       
    87   unsigned int state:2;                      // {alive, zombie, unloaded)
       
    88 
       
    89   unsigned int isUncommonRecompiled:1;       // recompiled because of uncommon trap?
       
    90   unsigned int isToBeRecompiled:1;           // to be recompiled as soon as it matures
       
    91   unsigned int hasFlushedDependencies:1;     // Used for maintenance of dependencies
       
    92   unsigned int markedForReclamation:1;       // Used by NMethodSweeper
       
    93 
       
    94   unsigned int has_unsafe_access:1;          // May fault due to unsafe access.
       
    95   unsigned int has_method_handle_invokes:1;  // Has this method MethodHandle invokes?
       
    96 
       
    97   unsigned int speculatively_disconnected:1; // Marked for potential unload
       
    98 
       
    99   void clear();
       
   100 };
       
   101 
       
   102 
       
   103 // A nmethod contains:
       
   104 //  - header                 (the nmethod structure)
    83 //  - header                 (the nmethod structure)
   105 //  [Relocation]
    84 //  [Relocation]
   106 //  - relocation information
    85 //  - relocation information
   107 //  - constant part          (doubles, longs and floats used in nmethod)
    86 //  - constant part          (doubles, longs and floats used in nmethod)
   108 //  - oop table
    87 //  - oop table
   129   friend class VMStructs;
   108   friend class VMStructs;
   130   friend class NMethodSweeper;
   109   friend class NMethodSweeper;
   131   friend class CodeCache;  // non-perm oops
   110   friend class CodeCache;  // non-perm oops
   132  private:
   111  private:
   133   // Shared fields for all nmethod's
   112   // Shared fields for all nmethod's
   134   static int _zombie_instruction_size;
       
   135 
       
   136   methodOop _method;
   113   methodOop _method;
   137   int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
   114   int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
   138   jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
   115   jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
   139 
   116 
   140   // To support simple linked-list chaining of nmethods:
   117   // To support simple linked-list chaining of nmethods:
   144 
   121 
   145   static nmethod* volatile _oops_do_mark_nmethods;
   122   static nmethod* volatile _oops_do_mark_nmethods;
   146   nmethod*        volatile _oops_do_mark_link;
   123   nmethod*        volatile _oops_do_mark_link;
   147 
   124 
   148   AbstractCompiler* _compiler; // The compiler which compiled this nmethod
   125   AbstractCompiler* _compiler; // The compiler which compiled this nmethod
       
   126 
       
   127   // offsets for entry points
       
   128   address _entry_point;                      // entry point with class check
       
   129   address _verified_entry_point;             // entry point without class check
       
   130   address _osr_entry_point;                  // entry point for on stack replacement
   149 
   131 
   150   // Offsets for different nmethod parts
   132   // Offsets for different nmethod parts
   151   int _exception_offset;
   133   int _exception_offset;
   152   // All deoptee's will resume execution at this location described by
   134   // All deoptee's will resume execution at this location described by
   153   // this offset.
   135   // this offset.
   173 
   155 
   174   // location in frame (offset for sp) that deopt can store the original
   156   // location in frame (offset for sp) that deopt can store the original
   175   // pc during a deopt.
   157   // pc during a deopt.
   176   int _orig_pc_offset;
   158   int _orig_pc_offset;
   177 
   159 
   178   int _compile_id;                     // which compilation made this nmethod
   160   int _compile_id;                           // which compilation made this nmethod
   179   int _comp_level;                     // compilation level
   161   int _comp_level;                           // compilation level
   180 
   162 
   181   // offsets for entry points
   163   // protected by CodeCache_lock
   182   address _entry_point;                // entry point with class check
   164   bool _has_flushed_dependencies;            // Used for maintenance of dependencies (CodeCache_lock)
   183   address _verified_entry_point;       // entry point without class check
   165   bool _speculatively_disconnected;          // Marked for potential unload
   184   address _osr_entry_point;            // entry point for on stack replacement
   166 
   185 
   167   bool _marked_for_reclamation;              // Used by NMethodSweeper (set only by sweeper)
   186   nmFlags flags;           // various flags to keep track of nmethod state
   168   bool _marked_for_deoptimization;           // Used for stack deoptimization
   187   bool _markedForDeoptimization;       // Used for stack deoptimization
   169 
       
   170   // used by jvmti to track if an unload event has been posted for this nmethod.
       
   171   bool _unload_reported;
       
   172 
       
   173   // set during construction
       
   174   unsigned int _has_unsafe_access:1;         // May fault due to unsafe access.
       
   175   unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes?
       
   176 
       
   177   // Protected by Patching_lock
       
   178   unsigned char _state;                      // {alive, not_entrant, zombie, unloaded)
       
   179 
   188   enum { alive        = 0,
   180   enum { alive        = 0,
   189          not_entrant  = 1, // uncommon trap has happened but activations may still exist
   181          not_entrant  = 1, // uncommon trap has happened but activations may still exist
   190          zombie       = 2,
   182          zombie       = 2,
   191          unloaded     = 3 };
   183          unloaded     = 3 };
   192 
   184 
   193   // used by jvmti to track if an unload event has been posted for this nmethod.
       
   194   bool _unload_reported;
       
   195 
   185 
   196   jbyte _scavenge_root_state;
   186   jbyte _scavenge_root_state;
   197 
   187 
   198   NOT_PRODUCT(bool _has_debug_info; )
   188   NOT_PRODUCT(bool _has_debug_info; )
   199 
   189 
   268   // Returns true if this thread changed the state of the nmethod or
   258   // Returns true if this thread changed the state of the nmethod or
   269   // false if another thread performed the transition.
   259   // false if another thread performed the transition.
   270   bool make_not_entrant_or_zombie(unsigned int state);
   260   bool make_not_entrant_or_zombie(unsigned int state);
   271   void inc_decompile_count();
   261   void inc_decompile_count();
   272 
   262 
   273   // used to check that writes to nmFlags are done consistently.
       
   274   static void check_safepoint() PRODUCT_RETURN;
       
   275 
       
   276   // Used to manipulate the exception cache
   263   // Used to manipulate the exception cache
   277   void add_exception_cache_entry(ExceptionCache* new_entry);
   264   void add_exception_cache_entry(ExceptionCache* new_entry);
   278   ExceptionCache* exception_cache_entry_for_exception(Handle exception);
   265   ExceptionCache* exception_cache_entry_for_exception(Handle exception);
   279 
   266 
   280   // Inform external interfaces that a compiled method has been unloaded
   267   // Inform external interfaces that a compiled method has been unloaded
   281   inline void post_compiled_method_unload();
   268   void post_compiled_method_unload();
       
   269 
       
   270   // Initailize fields to their default values
       
   271   void init_defaults();
   282 
   272 
   283  public:
   273  public:
   284   // create nmethod with entry_bci
   274   // create nmethod with entry_bci
   285   static nmethod* new_nmethod(methodHandle method,
   275   static nmethod* new_nmethod(methodHandle method,
   286                               int compile_id,
   276                               int compile_id,
   391   // entry points
   381   // entry points
   392   address entry_point() const                     { return _entry_point;             } // normal entry point
   382   address entry_point() const                     { return _entry_point;             } // normal entry point
   393   address verified_entry_point() const            { return _verified_entry_point;    } // if klass is correct
   383   address verified_entry_point() const            { return _verified_entry_point;    } // if klass is correct
   394 
   384 
   395   // flag accessing and manipulation
   385   // flag accessing and manipulation
   396   bool  is_in_use() const                         { return flags.state == alive; }
   386   bool  is_in_use() const                         { return _state == alive; }
   397   bool  is_alive() const                          { return flags.state == alive || flags.state == not_entrant; }
   387   bool  is_alive() const                          { return _state == alive || _state == not_entrant; }
   398   bool  is_not_entrant() const                    { return flags.state == not_entrant; }
   388   bool  is_not_entrant() const                    { return _state == not_entrant; }
   399   bool  is_zombie() const                         { return flags.state == zombie; }
   389   bool  is_zombie() const                         { return _state == zombie; }
   400   bool  is_unloaded() const                       { return flags.state == unloaded;   }
   390   bool  is_unloaded() const                       { return _state == unloaded;   }
   401 
   391 
   402   // Make the nmethod non entrant. The nmethod will continue to be
   392   // Make the nmethod non entrant. The nmethod will continue to be
   403   // alive.  It is used when an uncommon trap happens.  Returns true
   393   // alive.  It is used when an uncommon trap happens.  Returns true
   404   // if this thread changed the state of the nmethod or false if
   394   // if this thread changed the state of the nmethod or false if
   405   // another thread performed the transition.
   395   // another thread performed the transition.
   408 
   398 
   409   // used by jvmti to track if the unload event has been reported
   399   // used by jvmti to track if the unload event has been reported
   410   bool  unload_reported()                         { return _unload_reported; }
   400   bool  unload_reported()                         { return _unload_reported; }
   411   void  set_unload_reported()                     { _unload_reported = true; }
   401   void  set_unload_reported()                     { _unload_reported = true; }
   412 
   402 
   413   bool  is_marked_for_deoptimization() const      { return _markedForDeoptimization; }
   403   bool  is_marked_for_deoptimization() const      { return _marked_for_deoptimization; }
   414   void  mark_for_deoptimization()                 { _markedForDeoptimization = true; }
   404   void  mark_for_deoptimization()                 { _marked_for_deoptimization = true; }
   415 
   405 
   416   void  make_unloaded(BoolObjectClosure* is_alive, oop cause);
   406   void  make_unloaded(BoolObjectClosure* is_alive, oop cause);
   417 
   407 
   418   bool has_dependencies()                         { return dependencies_size() != 0; }
   408   bool has_dependencies()                         { return dependencies_size() != 0; }
   419   void flush_dependencies(BoolObjectClosure* is_alive);
   409   void flush_dependencies(BoolObjectClosure* is_alive);
   420   bool  has_flushed_dependencies()                { return flags.hasFlushedDependencies; }
   410   bool has_flushed_dependencies()                 { return _has_flushed_dependencies; }
   421   void  set_has_flushed_dependencies()            {
   411   void set_has_flushed_dependencies()             {
   422     assert(!has_flushed_dependencies(), "should only happen once");
   412     assert(!has_flushed_dependencies(), "should only happen once");
   423     flags.hasFlushedDependencies = 1;
   413     _has_flushed_dependencies = 1;
   424   }
   414   }
   425 
   415 
   426   bool  is_marked_for_reclamation() const         { return flags.markedForReclamation; }
   416   bool  is_marked_for_reclamation() const         { return _marked_for_reclamation; }
   427   void  mark_for_reclamation()                    { flags.markedForReclamation = 1; }
   417   void  mark_for_reclamation()                    { _marked_for_reclamation = 1; }
   428   void  unmark_for_reclamation()                  { flags.markedForReclamation = 0; }
   418 
   429 
   419   bool  has_unsafe_access() const                 { return _has_unsafe_access; }
   430   bool  has_unsafe_access() const                 { return flags.has_unsafe_access; }
   420   void  set_has_unsafe_access(bool z)             { _has_unsafe_access = z; }
   431   void  set_has_unsafe_access(bool z)             { flags.has_unsafe_access = z; }
   421 
   432 
   422   bool  has_method_handle_invokes() const         { return _has_method_handle_invokes; }
   433   bool  has_method_handle_invokes() const         { return flags.has_method_handle_invokes; }
   423   void  set_has_method_handle_invokes(bool z)     { _has_method_handle_invokes = z; }
   434   void  set_has_method_handle_invokes(bool z)     { flags.has_method_handle_invokes = z; }
   424 
   435 
   425   bool  is_speculatively_disconnected() const     { return _speculatively_disconnected; }
   436   bool  is_speculatively_disconnected() const     { return flags.speculatively_disconnected; }
   426   void  set_speculatively_disconnected(bool z)     { _speculatively_disconnected = z; }
   437   void  set_speculatively_disconnected(bool z)     { flags.speculatively_disconnected = z; }
       
   438 
   427 
   439   int   comp_level() const                        { return _comp_level; }
   428   int   comp_level() const                        { return _comp_level; }
   440 
       
   441   int   version() const                           { return flags.version; }
       
   442   void  set_version(int v);
       
   443 
   429 
   444   // Support for oops in scopes and relocs:
   430   // Support for oops in scopes and relocs:
   445   // Note: index 0 is reserved for null.
   431   // Note: index 0 is reserved for null.
   446   oop   oop_at(int index) const                   { return index == 0 ? (oop) NULL: *oop_addr_at(index); }
   432   oop   oop_at(int index) const                   { return index == 0 ? (oop) NULL: *oop_addr_at(index); }
   447   oop*  oop_addr_at(int index) const {  // for GC
   433   oop*  oop_addr_at(int index) const {  // for GC