00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 const int method_size_mask_bitno = 2;
00027 const int method_size_mask_size = 18;
00028
00029 const int method_args_mask_bitno = method_size_mask_bitno + method_size_mask_size;
00030 const int method_args_mask_size = 4;
00031
00032 const int method_flags_mask_bitno = method_args_mask_bitno + method_args_mask_size;
00033 const int method_flags_mask_size = 8;
00034
00035
00036 class methodOopDesc : public memOopDesc {
00037 private:
00038 objArrayOop _debugInfo;
00039 oop _selector_or_method;
00040 int _counters;
00041 smiOop _size_and_flags;
00042
00043 methodOopDesc* addr() const { return (methodOopDesc*)memOopDesc::addr(); }
00044
00045
00046 static int header_size() { return sizeof(methodOopDesc)/oopSize; }
00047
00048 public:
00049
00050 static int selector_or_method_byte_offset() { return int(&(((methodOopDesc*)NULL)->_selector_or_method)) - Mem_Tag; }
00051 static int counters_byte_offset() { return int(&(((methodOopDesc*)NULL)->_counters)) - Mem_Tag; }
00052 static int codes_byte_offset() { return sizeof(methodOopDesc) - Mem_Tag; }
00053
00054 smiOop size_and_flags() const { return addr()->_size_and_flags; }
00055 void set_size_and_flags(int size, int nofArgs, int flags) {
00056 addr()->_size_and_flags = (smiOop)
00057 ((flags << method_flags_mask_bitno) + (nofArgs << method_args_mask_bitno) + (size << method_size_mask_bitno));
00058 }
00059
00060 int flags() const {
00061 return get_unsigned_bitfield((int)size_and_flags(), method_flags_mask_bitno, method_flags_mask_size);
00062 }
00063
00064 void set_flags(int flags) {
00065 set_size_and_flags(size_of_codes(), nofArgs(), flags);
00066 }
00067
00068 int nofArgs() const {
00069 return get_unsigned_bitfield((int)size_and_flags(), method_args_mask_bitno, method_args_mask_size); }
00070
00071 public:
00072 friend methodOop as_methodOop(void* p) { return methodOop(as_memOop(p)); }
00073
00074 void bootstrap_object(bootstrap* st);
00075
00076
00077 bool is_blockMethod() const { return !selector_or_method()->is_symbol(); }
00078
00079 objArrayOop debugInfo() const { return addr()->_debugInfo; }
00080 void set_debugInfo(objArrayOop d) { addr()->_debugInfo = d; }
00081
00082 symbolOop selector() const;
00083 methodOop parent() const;
00084 methodOop home() const;
00085
00086 oop selector_or_method() const { return addr()->_selector_or_method; }
00087 void set_selector_or_method(oop value){ addr()->_selector_or_method = value; }
00088
00089
00090 symbolOop enclosing_method_selector() const;
00091
00092
00093 byteArrayOop source();
00094
00095
00096 objArrayOop tempInfo();
00097
00098
00099
00100
00101
00102 objArrayOop fileout_body();
00103
00104
00105
00106
00107
00108 enum {
00109 _short_size = 16,
00110 _invocation_count_offset = _short_size,
00111 _invocation_count_width = _short_size,
00112 _invocation_count_max = (1 << _short_size) - 1,
00113
00114 _sharing_count_offset = 0,
00115 _sharing_count_width = _short_size,
00116 _sharing_count_max = (1 << _short_size) - 1
00117 };
00118
00119 int counters() const { return addr()->_counters; }
00120 void set_counters(int inv, int share) { addr()->_counters = (inv << _invocation_count_offset) | share; }
00121
00122
00123 int invocation_count() const { return get_unsigned_bitfield(counters(), _invocation_count_offset, _invocation_count_width); }
00124 void set_invocation_count(int value) { set_counters(value, sharing_count()); }
00125
00126 void decay_invocation_count(double decay_factor);
00127
00128
00129 int sharing_count() const { return get_unsigned_bitfield(counters(), _sharing_count_offset, _sharing_count_width); }
00130 void set_sharing_count(int value) { set_counters(invocation_count(), value); }
00131 void inc_sharing_count();
00132 void dec_sharing_count();
00133
00134 bool was_never_executed();
00135
00136 int size_of_codes() const {
00137 return get_unsigned_bitfield((int) size_and_flags(), method_size_mask_bitno, method_size_mask_size);
00138 }
00139
00140 void set_size_of_code(int size) {
00141 set_size_and_flags(size, nofArgs(), flags());
00142 }
00143
00144
00145 u_char* codes(int offset = 1) const {
00146 return (u_char*) addr() + sizeof(methodOopDesc) + offset - 1;
00147 }
00148
00149 u_char* codes_end() const {
00150 return codes() + size_of_codes() * oopSize;
00151 }
00152
00153
00154 static methodOop methodOop_from_hcode(u_char* hp);
00155
00156 u_char byte_at(int offset) const { return *codes(offset); }
00157 void byte_at_put(int offset,u_char c) { *codes(offset) = c; }
00158
00159 long word_at(int offset) const { return * (long*) codes(offset); }
00160 void word_at_put(int offset,unsigned long w) { * (long*) codes(offset) = w; }
00161
00162 oop oop_at(int offset) const { return * (oop*) codes(offset); }
00163 void oop_at_put(int offset,oop obj) { * (oop*) codes(offset) = obj; }
00164
00165
00166 int next_bci_from(u_char* hp) const;
00167
00168
00169 int bci_from(u_char* hp) const;
00170
00171 int number_of_arguments() const;
00172
00173
00174
00175 int number_of_stack_temporaries() const;
00176
00177
00178 bool has_float_temporaries() const { return *codes(1) == Bytecodes::float_allocate; }
00179 int number_of_float_temporaries() const { return has_float_temporaries() ? *codes(3) : 0; }
00180 int float_expression_stack_size() const { return has_float_temporaries() ? *codes(4) : 0; }
00181 int total_number_of_floats() const { return number_of_float_temporaries() + float_expression_stack_size(); }
00182
00183
00184 int float_offset(int float_no) const;
00185 int float_section_start_offset() const { return frame_temp_offset - number_of_stack_temporaries(); }
00186 int float_section_size() const { return total_number_of_floats()*floatSize/oopSize; }
00187
00188
00189 bool is_accessMethod() const { return *codes() == Bytecodes::return_instVar; }
00190 bool is_primitiveMethod() const;
00191
00192
00193 bool is_special_primitiveMethod() const { return *codes(1) == Bytecodes::special_primitive_send_1_hint; }
00194 Bytecodes::Code special_primitive_code() const;
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 enum Flags {
00210
00211 containsNLRFlag = 0,
00212 allocatesContextFlag= 1,
00213 mustBeCustomizedFlag= 2,
00214 isCustomizedFlag = 3,
00215
00216
00217 methodInfoFlags = isCustomizedFlag + 1,
00218 methodInfoSize = 2,
00219
00220
00221 blockInfoFlags = methodInfoFlags,
00222 blockInfoSize = methodInfoSize
00223 };
00224
00225
00226 enum Method_Inlining_Info {
00227 never_inline = 0,
00228 normal_inline = 1,
00229 always_inline = 2,
00230 } method_inlining_info() const;
00231
00232 void set_method_inlining_info(Method_Inlining_Info info);
00233
00234 enum Block_Info {
00235 expects_nil = 0,
00236 expects_self = 1,
00237 expects_parameter = 2,
00238 expects_context = 3
00239 } block_info() const;
00240
00241
00242 bool activation_has_context() const {
00243 return allocatesInterpretedContext()
00244 || (is_blockMethod() && expectsContext());
00245 }
00246
00247
00248 bool in_context_allocation(int bci) const;
00249
00250 bool containsNLR() const { return isSet(flags(), containsNLRFlag); }
00251 bool allocatesInterpretedContext() const { return isSet(flags(), allocatesContextFlag); }
00252 bool mustBeCustomizedToClass() const { return isSet(flags(), mustBeCustomizedFlag); }
00253 bool expectsContext() const { return block_info() == expects_context; }
00254 bool hasNestedBlocks() const;
00255 bool is_clean_block() const { return block_info() == expects_nil; }
00256 bool is_copying_block() const { return block_info() == expects_self || block_info() == expects_parameter; }
00257 bool is_full_block() const { return block_info() == expects_context; }
00258
00259
00260 bool has_instVar_access() const { return true; }
00261 bool has_classVar_access() const { return true; }
00262 bool has_inlineCache() const { return true; }
00263 bool is_customized() const { return isSet(flags(), isCustomizedFlag); }
00264 bool should_be_customized() const { return has_instVar_access() || has_classVar_access() || has_inlineCache(); }
00265
00266
00267 methodOop copy_for_customization() const;
00268
00269
00270 void customize_for(klassOop klass, mixinOop mixin);
00271 void uncustomize_for(mixinOop mixin);
00272
00273
00274 int lexicalDistance(int contextNo);
00275 int contextNo(int lexicalDistance);
00276
00277
00278 int context_chain_length() const;
00279
00280
00281 void clear_inline_caches();
00282
00283
00284 void cleanup_inline_caches();
00285
00286
00287
00288 int estimated_inline_cost(klassOop receiverKlass);
00289
00290
00291
00292 int find_bci_from(int nbci) const;
00293
00294
00295 int next_bci(int bci) const;
00296
00297
00298 int end_bci() const;
00299
00300
00301 InterpretedIC* ic_at(int bci) const;
00302
00303
00304 GrowableArray<int>* expression_stack_mapping(int bci);
00305
00306
00307 void print_codes();
00308 void pretty_print();
00309
00310
00311 void print_value_for(klassOop receiver_klass, outputStream* st = NULL);
00312
00313
00314 void print_inlining_database_on(outputStream* st);
00315 int bci_for_block_method(methodOop inner);
00316 methodOop block_method_at(int bci);
00317
00318
00319
00320
00321
00322 int number_of_context_temporaries(bool* self_in_context = NULL);
00323
00324
00325 void verify_context(contextOop con);
00326
00327
00328 objArrayOop referenced_instance_variable_names(mixinOop mixin) const;
00329 objArrayOop referenced_class_variable_names() const;
00330 objArrayOop referenced_global_names() const;
00331 objArrayOop senders() const;
00332
00333 friend methodKlass;
00334 };