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);
|