hotspot/src/share/vm/oops/methodDataOop.hpp

Print this page
rev 611 : Merge
   1 #ifdef USE_PRAGMA_IDENT_HDR
   2 #pragma ident "@(#)methodDataOop.hpp    1.54 07/08/29 13:42:27 JVM"
   3 #endif
   4 /*
   5  * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  


  87 
  88 public:
  89   enum {
  90     counter_increment = 1
  91   };
  92 
  93   enum {
  94     cell_size = sizeof(intptr_t)
  95   };
  96 
  97   // Tag values
  98   enum {
  99     no_tag,
 100     bit_data_tag,
 101     counter_data_tag,
 102     jump_data_tag,
 103     receiver_type_data_tag,
 104     virtual_call_data_tag,
 105     ret_data_tag,
 106     branch_data_tag,
 107     multi_branch_data_tag

 108   };
 109 
 110   enum {
 111     // The _struct._flags word is formatted as [trap_state:4 | flags:4].
 112     // The trap state breaks down further as [recompile:1 | reason:3].
 113     // This further breakdown is defined in deoptimization.cpp.
 114     // See Deoptimization::trap_state_reason for an assert that
 115     // trap_bits is big enough to hold reasons < Reason_RECORDED_LIMIT.
 116     //
 117     // The trap_state is collected only if ProfileTraps is true.
 118     trap_bits = 1+3,  // 3: enough to distinguish [0..Reason_RECORDED_LIMIT].
 119     trap_shift = BitsPerByte - trap_bits,
 120     trap_mask = right_n_bits(trap_bits),
 121     trap_mask_in_place = (trap_mask << trap_shift),
 122     flag_limit = trap_shift,
 123     flag_mask = right_n_bits(flag_limit),
 124     first_flag = 0
 125   };
 126 
 127   // Size computation


 143   u1 tag() {
 144     return _header._struct._tag;
 145   }
 146 
 147   // Return a few bits of trap state.  Range is [0..trap_mask].
 148   // The state tells if traps with zero, one, or many reasons have occurred.
 149   // It also tells whether zero or many recompilations have occurred.
 150   // The associated trap histogram in the MDO itself tells whether
 151   // traps are common or not.  If a BCI shows that a trap X has
 152   // occurred, and the MDO shows N occurrences of X, we make the
 153   // simplifying assumption that all N occurrences can be blamed
 154   // on that BCI.
 155   int trap_state() {
 156     return ((_header._struct._flags >> trap_shift) & trap_mask);
 157   }
 158 
 159   void set_trap_state(int new_state) {
 160     assert(ProfileTraps, "used only under +ProfileTraps");
 161     uint old_flags = (_header._struct._flags & flag_mask);
 162     _header._struct._flags = (new_state << trap_shift) | old_flags;
 163     assert(trap_state() == new_state, "sanity");
 164   }
 165 
 166   u1 flags() {
 167     return _header._struct._flags;
 168   }
 169 
 170   u2 bci() {
 171     return _header._struct._bci;
 172   }
 173 
 174   void set_header(intptr_t value) {
 175     _header._bits = value;
 176   }
 177   void release_set_header(intptr_t value) {
 178     OrderAccess::release_store_ptr(&_header._bits, value);
 179   }
 180   intptr_t header() {
 181     return _header._bits;
 182   }
 183   void set_cell_at(int index, intptr_t value) {


 231   // Return a value which, when or-ed as a word into _header, sets the flag.
 232   static intptr_t flag_mask_to_header_mask(int byte_constant) {
 233     DataLayout temp; temp.set_header(0);
 234     temp._header._struct._flags = byte_constant;
 235     return temp._header._bits;
 236   }
 237 };
 238 
 239 
 240 // ProfileData class hierarchy
 241 class ProfileData;
 242 class   BitData;
 243 class     CounterData;
 244 class       ReceiverTypeData;
 245 class         VirtualCallData;
 246 class       RetData;
 247 class   JumpData;
 248 class     BranchData;
 249 class   ArrayData;
 250 class     MultiBranchData;

 251 
 252 
 253 // ProfileData
 254 //
 255 // A ProfileData object is created to refer to a section of profiling
 256 // data in a structured way.
 257 class ProfileData : public ResourceObj {
 258 private:
 259 #ifndef PRODUCT
 260   enum {
 261     tab_width_one = 16,
 262     tab_width_two = 36
 263   };
 264 #endif // !PRODUCT
 265 
 266   // This is a pointer to a section of profiling data.
 267   DataLayout* _data;
 268 
 269 protected:
 270   DataLayout* data() { return _data; }


 362     return (address)_data;
 363   }
 364 
 365   int trap_state() {
 366     return data()->trap_state();
 367   }
 368   void set_trap_state(int new_state) {
 369     data()->set_trap_state(new_state);
 370   }
 371 
 372   // Type checking
 373   virtual bool is_BitData()         { return false; }
 374   virtual bool is_CounterData()     { return false; }
 375   virtual bool is_JumpData()        { return false; }
 376   virtual bool is_ReceiverTypeData(){ return false; }
 377   virtual bool is_VirtualCallData() { return false; }
 378   virtual bool is_RetData()         { return false; }
 379   virtual bool is_BranchData()      { return false; }
 380   virtual bool is_ArrayData()       { return false; }
 381   virtual bool is_MultiBranchData() { return false; }


 382 
 383   BitData* as_BitData() {
 384     assert(is_BitData(), "wrong type");
 385     return is_BitData()         ? (BitData*)        this : NULL;
 386   }
 387   CounterData* as_CounterData() {
 388     assert(is_CounterData(), "wrong type");
 389     return is_CounterData()     ? (CounterData*)    this : NULL;
 390   }
 391   JumpData* as_JumpData() {
 392     assert(is_JumpData(), "wrong type");
 393     return is_JumpData()        ? (JumpData*)       this : NULL;
 394   }
 395   ReceiverTypeData* as_ReceiverTypeData() {
 396     assert(is_ReceiverTypeData(), "wrong type");
 397     return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL;
 398   }
 399   VirtualCallData* as_VirtualCallData() {
 400     assert(is_VirtualCallData(), "wrong type");
 401     return is_VirtualCallData() ? (VirtualCallData*)this : NULL;
 402   }
 403   RetData* as_RetData() {
 404     assert(is_RetData(), "wrong type");
 405     return is_RetData()         ? (RetData*)        this : NULL;
 406   }
 407   BranchData* as_BranchData() {
 408     assert(is_BranchData(), "wrong type");
 409     return is_BranchData()      ? (BranchData*)     this : NULL;
 410   }
 411   ArrayData* as_ArrayData() {
 412     assert(is_ArrayData(), "wrong type");
 413     return is_ArrayData()       ? (ArrayData*)      this : NULL;        
 414   }
 415   MultiBranchData* as_MultiBranchData() {
 416     assert(is_MultiBranchData(), "wrong type");
 417     return is_MultiBranchData() ? (MultiBranchData*)this : NULL;
 418   }




 419 
 420 
 421   // Subclass specific initialization
 422   virtual void post_initialize(BytecodeStream* stream, methodDataOop mdo) {}
 423 
 424   // GC support
 425   virtual void follow_contents() {}
 426   virtual void oop_iterate(OopClosure* blk) {}
 427   virtual void oop_iterate_m(OopClosure* blk, MemRegion mr) {}
 428   virtual void adjust_pointers() {}
 429 
 430 #ifndef SERIALGC
 431   // Parallel old support
 432   virtual void follow_contents(ParCompactionManager* cm) {}
 433   virtual void update_pointers() {}
 434   virtual void update_pointers(HeapWord* beg_addr, HeapWord* end_addr) {}
 435 #endif // SERIALGC
 436 
 437   // CI translation: ProfileData can represent both MethodDataOop data 
 438   // as well as CIMethodData data. This function is provided for translating 


1033     return array_element_offset(case_array_start);
1034   }
1035   static ByteSize per_case_size() {
1036     return in_ByteSize(per_case_cell_count) * cell_size;
1037   }
1038   static ByteSize relative_count_offset() {
1039     return in_ByteSize(relative_count_off_set) * cell_size;
1040   }
1041   static ByteSize relative_displacement_offset() {
1042     return in_ByteSize(relative_displacement_off_set) * cell_size;
1043   }
1044 
1045   // Specific initialization.
1046   void post_initialize(BytecodeStream* stream, methodDataOop mdo);
1047 
1048 #ifndef PRODUCT
1049   void print_data_on(outputStream* st);
1050 #endif
1051 };
1052 



























1053 // methodDataOop
1054 //
1055 // A methodDataOop holds information which has been collected about
1056 // a method.  Its layout looks like this:
1057 //
1058 // -----------------------------
1059 // | header                    |
1060 // | klass                     |
1061 // -----------------------------
1062 // | method                    |
1063 // | size of the methodDataOop |
1064 // -----------------------------
1065 // | Data entries...           |
1066 // |   (variable size)         |
1067 // |                           |
1068 // .                           .
1069 // .                           .
1070 // .                           .
1071 // |                           |
1072 // -----------------------------


1169   void set_hint_di(int di)  { 
1170     assert(!out_of_bounds(di), "hint_di out of bounds");
1171     _hint_di = di; 
1172   }
1173   ProfileData* data_before(int bci) {
1174     // avoid SEGV on this edge case
1175     if (data_size() == 0)
1176       return NULL;
1177     int hint = hint_di();
1178     if (data_layout_at(hint)->bci() <= bci)
1179       return data_at(hint);
1180     return first_data();
1181   }
1182 
1183   // What is the index of the first data entry?
1184   int first_di() { return 0; }
1185 
1186   // Find or create an extra ProfileData:
1187   ProfileData* bci_to_extra_data(int bci, bool create_if_missing);
1188 



1189 public:
1190   static int header_size() {
1191     return sizeof(methodDataOopDesc)/wordSize;
1192   }
1193 
1194   // Compute the size of a methodDataOop before it is created.
1195   static int compute_allocation_size_in_bytes(methodHandle method);
1196   static int compute_allocation_size_in_words(methodHandle method);
1197   static int compute_extra_data_count(int data_size, int empty_bc_count);
1198 
1199   // Determine if a given bytecode can have profile information.
1200   static bool bytecode_has_profile(Bytecodes::Code code) {
1201     return bytecode_cell_count(code) != no_profile_data;
1202   }
1203 
1204   // Perform initialization of a new methodDataOop
1205   void initialize(methodHandle method);
1206 
1207   // My size
1208   int object_size_in_bytes() { return _size; }
1209   int object_size() {
1210     return align_object_size(align_size_up(_size, BytesPerWord)/BytesPerWord);
1211   }
1212 
1213   int      creation_mileage() const  { return _creation_mileage; }
1214   void set_creation_mileage(int x)   { _creation_mileage = x; }
1215   bool is_mature() const;  // consult mileage and ProfileMaturityPercentage
1216   static int mileage_of(methodOop m);
1217 
1218   // Support for interprocedural escape analysis, from Thomas Kotzmann.
1219   enum EscapeFlag {
1220     estimated    = 1 << 0,
1221     return_local = 1 << 1



1222   };
1223 
1224   intx eflags()                                  { return _eflags; }
1225   intx arg_local()                               { return _arg_local; }
1226   intx arg_stack()                               { return _arg_stack; }
1227   intx arg_returned()                            { return _arg_returned; }



1228 
1229   void set_eflags(intx v)                        { _eflags = v; }
1230   void set_arg_local(intx v)                     { _arg_local = v; }
1231   void set_arg_stack(intx v)                     { _arg_stack = v; }
1232   void set_arg_returned(intx v)                  { _arg_returned = v; }




1233 
1234   void clear_escape_info()                       { _eflags = _arg_local = _arg_stack = _arg_returned = 0; }
1235 
1236   // Location and size of data area
1237   address data_base() const {
1238     return (address) _data;
1239   }
1240   int data_size() {
1241     return _data_size;
1242   }
1243 
1244   // Accessors
1245   methodOop method() { return _method; }
1246 
1247   // Get the data at an arbitrary (sort of) data index.
1248   ProfileData* data_at(int data_index);
1249 
1250   // Walk through the data in order.
1251   ProfileData* first_data() { return data_at(first_di()); }
1252   ProfileData* next_data(ProfileData* current);


   1 #ifdef USE_PRAGMA_IDENT_HDR
   2 #pragma ident "@(#)methodDataOop.hpp    1.54 07/08/29 13:42:27 JVM"
   3 #endif
   4 /*
   5  * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  


  87 
  88 public:
  89   enum {
  90     counter_increment = 1
  91   };
  92 
  93   enum {
  94     cell_size = sizeof(intptr_t)
  95   };
  96 
  97   // Tag values
  98   enum {
  99     no_tag,
 100     bit_data_tag,
 101     counter_data_tag,
 102     jump_data_tag,
 103     receiver_type_data_tag,
 104     virtual_call_data_tag,
 105     ret_data_tag,
 106     branch_data_tag,
 107     multi_branch_data_tag,
 108     arg_info_data_tag
 109   };
 110 
 111   enum {
 112     // The _struct._flags word is formatted as [trap_state:4 | flags:4].
 113     // The trap state breaks down further as [recompile:1 | reason:3].
 114     // This further breakdown is defined in deoptimization.cpp.
 115     // See Deoptimization::trap_state_reason for an assert that
 116     // trap_bits is big enough to hold reasons < Reason_RECORDED_LIMIT.
 117     //
 118     // The trap_state is collected only if ProfileTraps is true.
 119     trap_bits = 1+3,  // 3: enough to distinguish [0..Reason_RECORDED_LIMIT].
 120     trap_shift = BitsPerByte - trap_bits,
 121     trap_mask = right_n_bits(trap_bits),
 122     trap_mask_in_place = (trap_mask << trap_shift),
 123     flag_limit = trap_shift,
 124     flag_mask = right_n_bits(flag_limit),
 125     first_flag = 0
 126   };
 127 
 128   // Size computation


 144   u1 tag() {
 145     return _header._struct._tag;
 146   }
 147 
 148   // Return a few bits of trap state.  Range is [0..trap_mask].
 149   // The state tells if traps with zero, one, or many reasons have occurred.
 150   // It also tells whether zero or many recompilations have occurred.
 151   // The associated trap histogram in the MDO itself tells whether
 152   // traps are common or not.  If a BCI shows that a trap X has
 153   // occurred, and the MDO shows N occurrences of X, we make the
 154   // simplifying assumption that all N occurrences can be blamed
 155   // on that BCI.
 156   int trap_state() {
 157     return ((_header._struct._flags >> trap_shift) & trap_mask);
 158   }
 159 
 160   void set_trap_state(int new_state) {
 161     assert(ProfileTraps, "used only under +ProfileTraps");
 162     uint old_flags = (_header._struct._flags & flag_mask);
 163     _header._struct._flags = (new_state << trap_shift) | old_flags;

 164   }
 165 
 166   u1 flags() {
 167     return _header._struct._flags;
 168   }
 169 
 170   u2 bci() {
 171     return _header._struct._bci;
 172   }
 173 
 174   void set_header(intptr_t value) {
 175     _header._bits = value;
 176   }
 177   void release_set_header(intptr_t value) {
 178     OrderAccess::release_store_ptr(&_header._bits, value);
 179   }
 180   intptr_t header() {
 181     return _header._bits;
 182   }
 183   void set_cell_at(int index, intptr_t value) {


 231   // Return a value which, when or-ed as a word into _header, sets the flag.
 232   static intptr_t flag_mask_to_header_mask(int byte_constant) {
 233     DataLayout temp; temp.set_header(0);
 234     temp._header._struct._flags = byte_constant;
 235     return temp._header._bits;
 236   }
 237 };
 238 
 239 
 240 // ProfileData class hierarchy
 241 class ProfileData;
 242 class   BitData;
 243 class     CounterData;
 244 class       ReceiverTypeData;
 245 class         VirtualCallData;
 246 class       RetData;
 247 class   JumpData;
 248 class     BranchData;
 249 class   ArrayData;
 250 class     MultiBranchData;
 251 class     ArgInfoData;
 252 
 253 
 254 // ProfileData
 255 //
 256 // A ProfileData object is created to refer to a section of profiling
 257 // data in a structured way.
 258 class ProfileData : public ResourceObj {
 259 private:
 260 #ifndef PRODUCT
 261   enum {
 262     tab_width_one = 16,
 263     tab_width_two = 36
 264   };
 265 #endif // !PRODUCT
 266 
 267   // This is a pointer to a section of profiling data.
 268   DataLayout* _data;
 269 
 270 protected:
 271   DataLayout* data() { return _data; }


 363     return (address)_data;
 364   }
 365 
 366   int trap_state() {
 367     return data()->trap_state();
 368   }
 369   void set_trap_state(int new_state) {
 370     data()->set_trap_state(new_state);
 371   }
 372 
 373   // Type checking
 374   virtual bool is_BitData()         { return false; }
 375   virtual bool is_CounterData()     { return false; }
 376   virtual bool is_JumpData()        { return false; }
 377   virtual bool is_ReceiverTypeData(){ return false; }
 378   virtual bool is_VirtualCallData() { return false; }
 379   virtual bool is_RetData()         { return false; }
 380   virtual bool is_BranchData()      { return false; }
 381   virtual bool is_ArrayData()       { return false; }
 382   virtual bool is_MultiBranchData() { return false; }
 383   virtual bool is_ArgInfoData()     { return false; }
 384 
 385 
 386   BitData* as_BitData() {
 387     assert(is_BitData(), "wrong type");
 388     return is_BitData()         ? (BitData*)        this : NULL;
 389   }
 390   CounterData* as_CounterData() {
 391     assert(is_CounterData(), "wrong type");
 392     return is_CounterData()     ? (CounterData*)    this : NULL;
 393   }
 394   JumpData* as_JumpData() {
 395     assert(is_JumpData(), "wrong type");
 396     return is_JumpData()        ? (JumpData*)       this : NULL;
 397   }
 398   ReceiverTypeData* as_ReceiverTypeData() {
 399     assert(is_ReceiverTypeData(), "wrong type");
 400     return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL;
 401   }
 402   VirtualCallData* as_VirtualCallData() {
 403     assert(is_VirtualCallData(), "wrong type");
 404     return is_VirtualCallData() ? (VirtualCallData*)this : NULL;
 405   }
 406   RetData* as_RetData() {
 407     assert(is_RetData(), "wrong type");
 408     return is_RetData()         ? (RetData*)        this : NULL;
 409   }
 410   BranchData* as_BranchData() {
 411     assert(is_BranchData(), "wrong type");
 412     return is_BranchData()      ? (BranchData*)     this : NULL;
 413   }
 414   ArrayData* as_ArrayData() {
 415     assert(is_ArrayData(), "wrong type");
 416     return is_ArrayData()       ? (ArrayData*)      this : NULL;        
 417   }
 418   MultiBranchData* as_MultiBranchData() {
 419     assert(is_MultiBranchData(), "wrong type");
 420     return is_MultiBranchData() ? (MultiBranchData*)this : NULL;
 421   }
 422   ArgInfoData* as_ArgInfoData() {
 423     assert(is_ArgInfoData(), "wrong type");
 424     return is_ArgInfoData() ? (ArgInfoData*)this : NULL;
 425   }
 426 
 427 
 428   // Subclass specific initialization
 429   virtual void post_initialize(BytecodeStream* stream, methodDataOop mdo) {}
 430 
 431   // GC support
 432   virtual void follow_contents() {}
 433   virtual void oop_iterate(OopClosure* blk) {}
 434   virtual void oop_iterate_m(OopClosure* blk, MemRegion mr) {}
 435   virtual void adjust_pointers() {}
 436 
 437 #ifndef SERIALGC
 438   // Parallel old support
 439   virtual void follow_contents(ParCompactionManager* cm) {}
 440   virtual void update_pointers() {}
 441   virtual void update_pointers(HeapWord* beg_addr, HeapWord* end_addr) {}
 442 #endif // SERIALGC
 443 
 444   // CI translation: ProfileData can represent both MethodDataOop data 
 445   // as well as CIMethodData data. This function is provided for translating 


1040     return array_element_offset(case_array_start);
1041   }
1042   static ByteSize per_case_size() {
1043     return in_ByteSize(per_case_cell_count) * cell_size;
1044   }
1045   static ByteSize relative_count_offset() {
1046     return in_ByteSize(relative_count_off_set) * cell_size;
1047   }
1048   static ByteSize relative_displacement_offset() {
1049     return in_ByteSize(relative_displacement_off_set) * cell_size;
1050   }
1051 
1052   // Specific initialization.
1053   void post_initialize(BytecodeStream* stream, methodDataOop mdo);
1054 
1055 #ifndef PRODUCT
1056   void print_data_on(outputStream* st);
1057 #endif
1058 };
1059 
1060 class ArgInfoData : public ArrayData {
1061 
1062 public:
1063   ArgInfoData(DataLayout* layout) : ArrayData(layout) {
1064     assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type");
1065   }
1066 
1067   virtual bool is_ArgInfoData() { return true; }
1068 
1069 
1070   int number_of_args() {
1071     return array_len();
1072   }
1073 
1074   uint arg_modified(int arg) {
1075     return array_uint_at(arg);
1076   }
1077 
1078   void set_arg_modified(int arg, uint val) {
1079     array_set_int_at(arg, val);
1080   }
1081 
1082 #ifndef PRODUCT
1083   void print_data_on(outputStream* st);
1084 #endif
1085 };
1086 
1087 // methodDataOop
1088 //
1089 // A methodDataOop holds information which has been collected about
1090 // a method.  Its layout looks like this:
1091 //
1092 // -----------------------------
1093 // | header                    |
1094 // | klass                     |
1095 // -----------------------------
1096 // | method                    |
1097 // | size of the methodDataOop |
1098 // -----------------------------
1099 // | Data entries...           |
1100 // |   (variable size)         |
1101 // |                           |
1102 // .                           .
1103 // .                           .
1104 // .                           .
1105 // |                           |
1106 // -----------------------------


1203   void set_hint_di(int di)  { 
1204     assert(!out_of_bounds(di), "hint_di out of bounds");
1205     _hint_di = di; 
1206   }
1207   ProfileData* data_before(int bci) {
1208     // avoid SEGV on this edge case
1209     if (data_size() == 0)
1210       return NULL;
1211     int hint = hint_di();
1212     if (data_layout_at(hint)->bci() <= bci)
1213       return data_at(hint);
1214     return first_data();
1215   }
1216 
1217   // What is the index of the first data entry?
1218   int first_di() { return 0; }
1219 
1220   // Find or create an extra ProfileData:
1221   ProfileData* bci_to_extra_data(int bci, bool create_if_missing);
1222 
1223   // return the argument info cell
1224   ArgInfoData *arg_info();
1225 
1226 public:
1227   static int header_size() {
1228     return sizeof(methodDataOopDesc)/wordSize;
1229   }
1230 
1231   // Compute the size of a methodDataOop before it is created.
1232   static int compute_allocation_size_in_bytes(methodHandle method);
1233   static int compute_allocation_size_in_words(methodHandle method);
1234   static int compute_extra_data_count(int data_size, int empty_bc_count);
1235 
1236   // Determine if a given bytecode can have profile information.
1237   static bool bytecode_has_profile(Bytecodes::Code code) {
1238     return bytecode_cell_count(code) != no_profile_data;
1239   }
1240 
1241   // Perform initialization of a new methodDataOop
1242   void initialize(methodHandle method);
1243 
1244   // My size
1245   int object_size_in_bytes() { return _size; }
1246   int object_size() {
1247     return align_object_size(align_size_up(_size, BytesPerWord)/BytesPerWord);
1248   }
1249 
1250   int      creation_mileage() const  { return _creation_mileage; }
1251   void set_creation_mileage(int x)   { _creation_mileage = x; }
1252   bool is_mature() const;  // consult mileage and ProfileMaturityPercentage
1253   static int mileage_of(methodOop m);
1254 
1255   // Support for interprocedural escape analysis, from Thomas Kotzmann.
1256   enum EscapeFlag {
1257     estimated    = 1 << 0,
1258     return_local = 1 << 1,
1259     return_allocated = 1 << 2,
1260     allocated_escapes = 1 << 3,
1261     unknown_modified = 1 << 4
1262   };
1263 
1264   intx eflags()                                  { return _eflags; }
1265   intx arg_local()                               { return _arg_local; }
1266   intx arg_stack()                               { return _arg_stack; }
1267   intx arg_returned()                            { return _arg_returned; }
1268   uint arg_modified(int a)                       { ArgInfoData *aid = arg_info();
1269                                                    assert(a >= 0 && a < aid->number_of_args(), "valid argument number");
1270                                                    return aid->arg_modified(a); }
1271 
1272   void set_eflags(intx v)                        { _eflags = v; }
1273   void set_arg_local(intx v)                     { _arg_local = v; }
1274   void set_arg_stack(intx v)                     { _arg_stack = v; }
1275   void set_arg_returned(intx v)                  { _arg_returned = v; }
1276   void set_arg_modified(int a, uint v)           { ArgInfoData *aid = arg_info();
1277                                                    assert(a >= 0 && a < aid->number_of_args(), "valid argument number");
1278 
1279                                                    aid->set_arg_modified(a, v); }
1280 
1281   void clear_escape_info()                       { _eflags = _arg_local = _arg_stack = _arg_returned = 0; }
1282 
1283   // Location and size of data area
1284   address data_base() const {
1285     return (address) _data;
1286   }
1287   int data_size() {
1288     return _data_size;
1289   }
1290 
1291   // Accessors
1292   methodOop method() { return _method; }
1293 
1294   // Get the data at an arbitrary (sort of) data index.
1295   ProfileData* data_at(int data_index);
1296 
1297   // Walk through the data in order.
1298   ProfileData* first_data() { return data_at(first_di()); }
1299   ProfileData* next_data(ProfileData* current);