00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef DELTA_COMPILER
00025
00026
00027
00028
00029 struct nmFlags {
00030 unsigned int version:8;
00031 unsigned int level:4;
00032 unsigned int age:4;
00033
00034 unsigned int state:2;
00035
00036 unsigned int isUncommonRecompiled:1;
00037 unsigned int isYoung:1;
00038 unsigned int isToBeRecompiled:1;
00039 unsigned int is_block:1;
00040
00041 unsigned int markedForDeoptimization:1;
00042
00043 void clear();
00044 };
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 class nmethod : public OopNCode {
00055 protected:
00056 uint16 _special_handler_call_offset;
00057 uint16 _entry_point_offset;
00058 uint16 _verified_entry_point_offset;
00059 uint16 _scopeLen;
00060 uint16 _number_of_noninlined_blocks;
00061 uint16 _number_of_links;
00062 uint16 _number_of_float_temporaries;
00063 uint16 _float_section_size;
00064 uint16 _float_section_start_offset;
00065
00066 int _invocation_count;
00067 int _uncommon_trap_counter;
00068 nmFlags flags;
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 enum { alive = 0, zombie = 1, dead = 2 };
00081
00082 public:
00083 char* insts() const { return (char*)(this + 1); }
00084 char* specialHandlerCall() const { return insts() + _special_handler_call_offset; }
00085 char* entryPoint() const { return insts() + _entry_point_offset; }
00086 char* verifiedEntryPoint() const { return insts() + _verified_entry_point_offset; }
00087
00088
00089 nmethodScopes* scopes() const { return (nmethodScopes*) locsEnd(); }
00090 PcDesc* pcs() const { return (PcDesc*) scopes()->pcs(); }
00091 PcDesc* pcsEnd() const { return (PcDesc*) scopes()->pcsEnd(); }
00092
00093 methodOop method() const;
00094 klassOop receiver_klass() const;
00095
00096 uint16* noninlined_block_offsets() const { return (uint16*) pcsEnd(); }
00097
00098
00099 public:
00100 LookupKey key;
00101
00102 jumpTableID main_id;
00103 jumpTableID promoted_id;
00104
00105 int number_of_float_temporaries() const { return _number_of_float_temporaries; }
00106 int float_section_size() const { return _float_section_size; }
00107 int float_section_start_offset() const { return _float_section_start_offset; }
00108
00109
00110 int number_of_links() const { return _number_of_links; }
00111 void inc_number_of_links() { _number_of_links++; }
00112 void dec_number_of_links() { _number_of_links--; }
00113
00114
00115 int uncommon_trap_counter() const { return _uncommon_trap_counter; }
00116 void inc_uncommon_trap_counter() { _uncommon_trap_counter++; }
00117
00118
00119 nmethod* parent();
00120
00121 nmethod* outermost();
00122
00123 protected:
00124 nmethod(Compiler* c);
00125 void* operator new(size_t size);
00126
00127 public:
00128 friend nmethod* new_nmethod(Compiler* c);
00129
00130 int size() const { return instsEnd() - insts(); }
00131
00132
00133
00134 void fix_relocation_at_move(int delta);
00135
00136 void moveTo(void* to, int size);
00137
00138 public:
00139 bool isNMethod() const { return true; }
00140
00141
00142 bool isAlive() const { return flags.state == alive; }
00143 bool isZombie() const { return flags.state == zombie; }
00144 bool isDead() const { return flags.state == dead; }
00145
00146 void makeZombie(bool clearInlineCaches);
00147
00148 bool isUncommonRecompiled() const { return flags.isUncommonRecompiled; }
00149
00150 bool isYoung();
00151 void makeYoung() { flags.isYoung = 1; }
00152 void makeOld();
00153
00154 int age() const { return flags.age; }
00155 void incrementAge() { const int MaxAge = 15; flags.age = min(flags.age + 1, MaxAge); }
00156
00157 bool is_marked_for_deoptimization() const{ return flags.markedForDeoptimization; }
00158 void mark_for_deoptimization() { flags.markedForDeoptimization = 1; }
00159 void unmark_for_deoptimization() { flags.markedForDeoptimization = 0; }
00160
00161 bool isToBeRecompiled() const { return flags.isToBeRecompiled; }
00162 void makeToBeRecompiled() { flags.isToBeRecompiled = 1; }
00163
00164 bool is_block() const { return flags.is_block == 1; }
00165 bool is_method() const { return flags.is_block == 0; }
00166
00167 int level() const;
00168 void setLevel(int newLevel) { flags.level = newLevel; }
00169
00170 int version() const { return flags.version; }
00171 void setVersion(int v);
00172
00173 public:
00174 int estimatedInvocationCount() const;
00175 int ncallers() const;
00176
00177 bool encompasses(void* p) const;
00178
00179
00180 int lastUsed() const { return LRUtable[0].lastUsed; }
00181
00182 void clear_inline_caches();
00183
00184 void cleanup_inline_caches();
00185
00186 void forwardLinkedSends(nmethod* to);
00187
00188 void unlink();
00189
00190
00191 void flush();
00192
00193
00194
00195 GrowableArray<nmethod*>* invalidation_family();
00196
00197
00198 bool depends_on_invalid_klass();
00199
00200 private:
00201
00202 void add_family(GrowableArray<nmethod*>* result);
00203
00204 protected:
00205 void check_store();
00206 public:
00207
00208 void oops_do(void f(oop*));
00209
00210 bool switch_pointers(oop from, oop to,
00211 GrowableArray<nmethod*>* nmethods_to_invalidate);
00212 void relocate();
00213
00214
00215 void verify();
00216 void verify_expression_stacks();
00217 void verify_expression_stacks_at(char* pc);
00218
00219
00220 void CompiledICs_do(void f(CompiledIC*));
00221
00222
00223 void PrimitiveICs_do(void f(PrimitiveIC*));
00224
00225
00226 PcDesc* containingPcDesc(char* pc, PcDesc* start = NULL) const;
00227 protected:
00228 PcDesc* containingPcDescOrNULL(char* pc, PcDesc* start = NULL) const;
00229 public:
00230
00231 ScopeDesc* containingScopeDesc(char* pc) const;
00232 #ifdef DEBUG
00233 PcDesc* correspondingPC(ScopeDesc* sd, int bci) const;
00234 #endif
00235
00236
00237 CompiledIC* IC_at(char* p) const;
00238 PrimitiveIC* primitiveIC_at(char* p) const;
00239 oop* embeddedOop_at(char* p) const;
00240
00241 jumpTableEntry* jump_table_entry() const;
00242
00243
00244 bool has_noninlined_blocks() const;
00245 int number_of_noninlined_blocks() const;
00246
00247 protected:
00248 void validate_noninlined_block_scope_index(int index) const;
00249
00250 public:
00251 NonInlinedBlockScopeDesc* noninlined_block_scope_at(int noninlined_block_index) const;
00252 methodOop noninlined_block_method_at(int noninlined_block_index) const;
00253 void noninlined_block_at_put(int noninlined_block_index, int offset) const;
00254 jumpTableEntry* noninlined_block_jumpEntry_at(int noninlined_block_index) const;
00255
00256
00257
00258 bool has_frame_at(char* pc) const;
00259
00260
00261 bool in_delta_code_at(char* pc) const;
00262
00263
00264 void print();
00265 void printCode();
00266 void printLocs();
00267 void printPcs();
00268
00269 void print_value_on(outputStream* st);
00270
00271
00272 void print_inlining_database();
00273 void print_inlining_database_on(outputStream* st);
00274 GrowableArray<PcDesc*>* uncommonBranchList();
00275
00276
00277 void print_inlining(outputStream* st = NULL, bool with_debug_info = false);
00278
00279 friend nmethod* nmethodContaining(char* pc, char* likelyEntryPoint);
00280 friend nmethod* findNMethod(void* start);
00281 friend nmethod* findNMethod_maybe(void* start);
00282
00283 friend nmethod* nmethod_from_insts(char* insts);
00284
00285 public:
00286
00287 int invocation_count() const { return _invocation_count; }
00288 void set_invocation_count(int c) { _invocation_count = c; }
00289
00290
00291 void sweeper_step(double decay_factor);
00292 private:
00293 inline void decay_invocation_count(double decay_factor);
00294
00295 public:
00296 static int invocationCountOffset() { return (int)&((nmethod*)0)->_invocation_count; }
00297
00298
00299
00300
00301
00302 void overwrite_for_trapping(nmethod_patch* data);
00303
00304
00305 void restore_from_patch(nmethod_patch* data);
00306 };
00307
00308
00309 #endif