1.1 --- a/src/share/vm/code/nmethod.hpp Wed Jul 07 12:40:01 2010 -0700 1.2 +++ b/src/share/vm/code/nmethod.hpp Thu Jul 08 14:29:44 2010 -0700 1.3 @@ -78,29 +78,8 @@ 1.4 1.5 1.6 // nmethods (native methods) are the compiled code versions of Java methods. 1.7 - 1.8 -struct nmFlags { 1.9 - friend class VMStructs; 1.10 - unsigned int version:8; // version number (0 = first version) 1.11 - unsigned int age:4; // age (in # of sweep steps) 1.12 - 1.13 - unsigned int state:2; // {alive, zombie, unloaded) 1.14 - 1.15 - unsigned int isUncommonRecompiled:1; // recompiled because of uncommon trap? 1.16 - unsigned int isToBeRecompiled:1; // to be recompiled as soon as it matures 1.17 - unsigned int hasFlushedDependencies:1; // Used for maintenance of dependencies 1.18 - unsigned int markedForReclamation:1; // Used by NMethodSweeper 1.19 - 1.20 - unsigned int has_unsafe_access:1; // May fault due to unsafe access. 1.21 - unsigned int has_method_handle_invokes:1; // Has this method MethodHandle invokes? 1.22 - 1.23 - unsigned int speculatively_disconnected:1; // Marked for potential unload 1.24 - 1.25 - void clear(); 1.26 -}; 1.27 - 1.28 - 1.29 -// A nmethod contains: 1.30 +// 1.31 +// An nmethod contains: 1.32 // - header (the nmethod structure) 1.33 // [Relocation] 1.34 // - relocation information 1.35 @@ -131,8 +110,6 @@ 1.36 friend class CodeCache; // non-perm oops 1.37 private: 1.38 // Shared fields for all nmethod's 1.39 - static int _zombie_instruction_size; 1.40 - 1.41 methodOop _method; 1.42 int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method 1.43 jmethodID _jmethod_id; // Cache of method()->jmethod_id() 1.44 @@ -147,6 +124,11 @@ 1.45 1.46 AbstractCompiler* _compiler; // The compiler which compiled this nmethod 1.47 1.48 + // offsets for entry points 1.49 + address _entry_point; // entry point with class check 1.50 + address _verified_entry_point; // entry point without class check 1.51 + address _osr_entry_point; // entry point for on stack replacement 1.52 + 1.53 // Offsets for different nmethod parts 1.54 int _exception_offset; 1.55 // All deoptee's will resume execution at this location described by 1.56 @@ -175,23 +157,31 @@ 1.57 // pc during a deopt. 1.58 int _orig_pc_offset; 1.59 1.60 - int _compile_id; // which compilation made this nmethod 1.61 - int _comp_level; // compilation level 1.62 + int _compile_id; // which compilation made this nmethod 1.63 + int _comp_level; // compilation level 1.64 1.65 - // offsets for entry points 1.66 - address _entry_point; // entry point with class check 1.67 - address _verified_entry_point; // entry point without class check 1.68 - address _osr_entry_point; // entry point for on stack replacement 1.69 + // protected by CodeCache_lock 1.70 + bool _has_flushed_dependencies; // Used for maintenance of dependencies (CodeCache_lock) 1.71 + bool _speculatively_disconnected; // Marked for potential unload 1.72 1.73 - nmFlags flags; // various flags to keep track of nmethod state 1.74 - bool _markedForDeoptimization; // Used for stack deoptimization 1.75 + bool _marked_for_reclamation; // Used by NMethodSweeper (set only by sweeper) 1.76 + bool _marked_for_deoptimization; // Used for stack deoptimization 1.77 + 1.78 + // used by jvmti to track if an unload event has been posted for this nmethod. 1.79 + bool _unload_reported; 1.80 + 1.81 + // set during construction 1.82 + unsigned int _has_unsafe_access:1; // May fault due to unsafe access. 1.83 + unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes? 1.84 + 1.85 + // Protected by Patching_lock 1.86 + unsigned char _state; // {alive, not_entrant, zombie, unloaded) 1.87 + 1.88 enum { alive = 0, 1.89 not_entrant = 1, // uncommon trap has happened but activations may still exist 1.90 zombie = 2, 1.91 unloaded = 3 }; 1.92 1.93 - // used by jvmti to track if an unload event has been posted for this nmethod. 1.94 - bool _unload_reported; 1.95 1.96 jbyte _scavenge_root_state; 1.97 1.98 @@ -270,15 +260,15 @@ 1.99 bool make_not_entrant_or_zombie(unsigned int state); 1.100 void inc_decompile_count(); 1.101 1.102 - // used to check that writes to nmFlags are done consistently. 1.103 - static void check_safepoint() PRODUCT_RETURN; 1.104 - 1.105 // Used to manipulate the exception cache 1.106 void add_exception_cache_entry(ExceptionCache* new_entry); 1.107 ExceptionCache* exception_cache_entry_for_exception(Handle exception); 1.108 1.109 // Inform external interfaces that a compiled method has been unloaded 1.110 - inline void post_compiled_method_unload(); 1.111 + void post_compiled_method_unload(); 1.112 + 1.113 + // Initailize fields to their default values 1.114 + void init_defaults(); 1.115 1.116 public: 1.117 // create nmethod with entry_bci 1.118 @@ -393,11 +383,11 @@ 1.119 address verified_entry_point() const { return _verified_entry_point; } // if klass is correct 1.120 1.121 // flag accessing and manipulation 1.122 - bool is_in_use() const { return flags.state == alive; } 1.123 - bool is_alive() const { return flags.state == alive || flags.state == not_entrant; } 1.124 - bool is_not_entrant() const { return flags.state == not_entrant; } 1.125 - bool is_zombie() const { return flags.state == zombie; } 1.126 - bool is_unloaded() const { return flags.state == unloaded; } 1.127 + bool is_in_use() const { return _state == alive; } 1.128 + bool is_alive() const { return _state == alive || _state == not_entrant; } 1.129 + bool is_not_entrant() const { return _state == not_entrant; } 1.130 + bool is_zombie() const { return _state == zombie; } 1.131 + bool is_unloaded() const { return _state == unloaded; } 1.132 1.133 // Make the nmethod non entrant. The nmethod will continue to be 1.134 // alive. It is used when an uncommon trap happens. Returns true 1.135 @@ -410,37 +400,33 @@ 1.136 bool unload_reported() { return _unload_reported; } 1.137 void set_unload_reported() { _unload_reported = true; } 1.138 1.139 - bool is_marked_for_deoptimization() const { return _markedForDeoptimization; } 1.140 - void mark_for_deoptimization() { _markedForDeoptimization = true; } 1.141 + bool is_marked_for_deoptimization() const { return _marked_for_deoptimization; } 1.142 + void mark_for_deoptimization() { _marked_for_deoptimization = true; } 1.143 1.144 void make_unloaded(BoolObjectClosure* is_alive, oop cause); 1.145 1.146 bool has_dependencies() { return dependencies_size() != 0; } 1.147 void flush_dependencies(BoolObjectClosure* is_alive); 1.148 - bool has_flushed_dependencies() { return flags.hasFlushedDependencies; } 1.149 - void set_has_flushed_dependencies() { 1.150 + bool has_flushed_dependencies() { return _has_flushed_dependencies; } 1.151 + void set_has_flushed_dependencies() { 1.152 assert(!has_flushed_dependencies(), "should only happen once"); 1.153 - flags.hasFlushedDependencies = 1; 1.154 + _has_flushed_dependencies = 1; 1.155 } 1.156 1.157 - bool is_marked_for_reclamation() const { return flags.markedForReclamation; } 1.158 - void mark_for_reclamation() { flags.markedForReclamation = 1; } 1.159 - void unmark_for_reclamation() { flags.markedForReclamation = 0; } 1.160 + bool is_marked_for_reclamation() const { return _marked_for_reclamation; } 1.161 + void mark_for_reclamation() { _marked_for_reclamation = 1; } 1.162 1.163 - bool has_unsafe_access() const { return flags.has_unsafe_access; } 1.164 - void set_has_unsafe_access(bool z) { flags.has_unsafe_access = z; } 1.165 + bool has_unsafe_access() const { return _has_unsafe_access; } 1.166 + void set_has_unsafe_access(bool z) { _has_unsafe_access = z; } 1.167 1.168 - bool has_method_handle_invokes() const { return flags.has_method_handle_invokes; } 1.169 - void set_has_method_handle_invokes(bool z) { flags.has_method_handle_invokes = z; } 1.170 + bool has_method_handle_invokes() const { return _has_method_handle_invokes; } 1.171 + void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; } 1.172 1.173 - bool is_speculatively_disconnected() const { return flags.speculatively_disconnected; } 1.174 - void set_speculatively_disconnected(bool z) { flags.speculatively_disconnected = z; } 1.175 + bool is_speculatively_disconnected() const { return _speculatively_disconnected; } 1.176 + void set_speculatively_disconnected(bool z) { _speculatively_disconnected = z; } 1.177 1.178 int comp_level() const { return _comp_level; } 1.179 1.180 - int version() const { return flags.version; } 1.181 - void set_version(int v); 1.182 - 1.183 // Support for oops in scopes and relocs: 1.184 // Note: index 0 is reserved for null. 1.185 oop oop_at(int index) const { return index == 0 ? (oop) NULL: *oop_addr_at(index); }