1.1 --- a/src/share/vm/oops/methodData.hpp Fri Oct 11 19:51:31 2013 -0700 1.2 +++ b/src/share/vm/oops/methodData.hpp Sat Oct 12 12:12:59 2013 +0200 1.3 @@ -271,6 +271,7 @@ 1.4 // data in a structured way. 1.5 class ProfileData : public ResourceObj { 1.6 friend class TypeEntries; 1.7 + friend class ReturnTypeEntry; 1.8 friend class TypeStackSlotEntries; 1.9 private: 1.10 #ifndef PRODUCT 1.11 @@ -748,119 +749,60 @@ 1.12 per_arg_cell_count 1.13 }; 1.14 1.15 - // Start with a header if needed. It stores the number of cells used 1.16 - // for this call type information. Unless we collect only profiling 1.17 - // for a single argument the number of cells is unknown statically. 1.18 - static int header_cell_count() { 1.19 - return (TypeProfileArgsLimit > 1) ? 1 : 0; 1.20 - } 1.21 - 1.22 - static int cell_count_local_offset() { 1.23 - assert(arguments_profiling_enabled() && TypeProfileArgsLimit > 1, "no cell count"); 1.24 - return 0; 1.25 - } 1.26 - 1.27 - int cell_count_global_offset() const { 1.28 - return _base_off + cell_count_local_offset(); 1.29 - } 1.30 - 1.31 // offset of cell for stack slot for entry i within ProfileData object 1.32 - int stack_slot_global_offset(int i) const { 1.33 + int stack_slot_offset(int i) const { 1.34 return _base_off + stack_slot_local_offset(i); 1.35 } 1.36 1.37 - void check_number_of_arguments(int total) { 1.38 - assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); 1.39 - } 1.40 - 1.41 - // number of cells not counting the header 1.42 - int cell_count_no_header() const { 1.43 - return _pd->uint_at(cell_count_global_offset()); 1.44 - } 1.45 - 1.46 - static bool arguments_profiling_enabled(); 1.47 - static void assert_arguments_profiling_enabled() { 1.48 - assert(arguments_profiling_enabled(), "args profiling should be on"); 1.49 - } 1.50 - 1.51 protected: 1.52 + const int _number_of_entries; 1.53 1.54 // offset of cell for type for entry i within ProfileData object 1.55 - int type_global_offset(int i) const { 1.56 + int type_offset(int i) const { 1.57 return _base_off + type_local_offset(i); 1.58 } 1.59 1.60 public: 1.61 1.62 - TypeStackSlotEntries(int base_off) 1.63 - : TypeEntries(base_off) {} 1.64 + TypeStackSlotEntries(int base_off, int nb_entries) 1.65 + : TypeEntries(base_off), _number_of_entries(nb_entries) {} 1.66 1.67 - static int compute_cell_count(BytecodeStream* stream); 1.68 + static int compute_cell_count(Symbol* signature, int max); 1.69 1.70 - static void initialize(DataLayout* dl, int base, int cell_count) { 1.71 - if (TypeProfileArgsLimit > 1) { 1.72 - int off = base + cell_count_local_offset(); 1.73 - dl->set_cell_at(off, cell_count - base - header_cell_count()); 1.74 - } 1.75 - } 1.76 - 1.77 - void post_initialize(BytecodeStream* stream); 1.78 - 1.79 - int number_of_arguments() const { 1.80 - assert_arguments_profiling_enabled(); 1.81 - if (TypeProfileArgsLimit > 1) { 1.82 - int cell_count = cell_count_no_header(); 1.83 - int nb = cell_count / TypeStackSlotEntries::per_arg_count(); 1.84 - assert(nb > 0 && nb <= TypeProfileArgsLimit , "only when we profile args"); 1.85 - return nb; 1.86 - } else { 1.87 - assert(TypeProfileArgsLimit == 1, "at least one arg"); 1.88 - return 1; 1.89 - } 1.90 - } 1.91 - 1.92 - int cell_count() const { 1.93 - assert_arguments_profiling_enabled(); 1.94 - if (TypeProfileArgsLimit > 1) { 1.95 - return _base_off + header_cell_count() + _pd->int_at_unchecked(cell_count_global_offset()); 1.96 - } else { 1.97 - return _base_off + TypeStackSlotEntries::per_arg_count(); 1.98 - } 1.99 - } 1.100 + void post_initialize(Symbol* signature, bool has_receiver); 1.101 1.102 // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries 1.103 static int stack_slot_local_offset(int i) { 1.104 - assert_arguments_profiling_enabled(); 1.105 - return header_cell_count() + i * per_arg_cell_count + stack_slot_entry; 1.106 + return i * per_arg_cell_count + stack_slot_entry; 1.107 } 1.108 1.109 // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries 1.110 static int type_local_offset(int i) { 1.111 - return header_cell_count() + i * per_arg_cell_count + type_entry; 1.112 + return i * per_arg_cell_count + type_entry; 1.113 } 1.114 1.115 // stack slot for entry i 1.116 uint stack_slot(int i) const { 1.117 - assert(i >= 0 && i < number_of_arguments(), "oob"); 1.118 - return _pd->uint_at(stack_slot_global_offset(i)); 1.119 + assert(i >= 0 && i < _number_of_entries, "oob"); 1.120 + return _pd->uint_at(stack_slot_offset(i)); 1.121 } 1.122 1.123 // set stack slot for entry i 1.124 void set_stack_slot(int i, uint num) { 1.125 - assert(i >= 0 && i < number_of_arguments(), "oob"); 1.126 - _pd->set_uint_at(stack_slot_global_offset(i), num); 1.127 + assert(i >= 0 && i < _number_of_entries, "oob"); 1.128 + _pd->set_uint_at(stack_slot_offset(i), num); 1.129 } 1.130 1.131 // type for entry i 1.132 intptr_t type(int i) const { 1.133 - assert(i >= 0 && i < number_of_arguments(), "oob"); 1.134 - return _pd->intptr_at(type_global_offset(i)); 1.135 + assert(i >= 0 && i < _number_of_entries, "oob"); 1.136 + return _pd->intptr_at(type_offset(i)); 1.137 } 1.138 1.139 // set type for entry i 1.140 void set_type(int i, intptr_t k) { 1.141 - assert(i >= 0 && i < number_of_arguments(), "oob"); 1.142 - _pd->set_intptr_at(type_global_offset(i), k); 1.143 + assert(i >= 0 && i < _number_of_entries, "oob"); 1.144 + _pd->set_intptr_at(type_offset(i), k); 1.145 } 1.146 1.147 static ByteSize per_arg_size() { 1.148 @@ -871,22 +813,50 @@ 1.149 return per_arg_cell_count ; 1.150 } 1.151 1.152 - // Code generation support 1.153 - static ByteSize cell_count_offset() { 1.154 - return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size); 1.155 - } 1.156 + // GC support 1.157 + void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); 1.158 1.159 - static ByteSize args_data_offset() { 1.160 - return in_ByteSize(header_cell_count() * DataLayout::cell_size); 1.161 - } 1.162 +#ifndef PRODUCT 1.163 + void print_data_on(outputStream* st) const; 1.164 +#endif 1.165 +}; 1.166 1.167 - static ByteSize stack_slot_offset(int i) { 1.168 - return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size); 1.169 - } 1.170 +// Type entry used for return from a call. A single cell to record the 1.171 +// type. 1.172 +class ReturnTypeEntry : public TypeEntries { 1.173 1.174 - static ByteSize type_offset(int i) { 1.175 - return in_ByteSize(type_local_offset(i) * DataLayout::cell_size); 1.176 - } 1.177 +private: 1.178 + enum { 1.179 + cell_count = 1 1.180 + }; 1.181 + 1.182 +public: 1.183 + ReturnTypeEntry(int base_off) 1.184 + : TypeEntries(base_off) {} 1.185 + 1.186 + void post_initialize() { 1.187 + set_type(type_none()); 1.188 + } 1.189 + 1.190 + intptr_t type() const { 1.191 + return _pd->intptr_at(_base_off); 1.192 + } 1.193 + 1.194 + void set_type(intptr_t k) { 1.195 + _pd->set_intptr_at(_base_off, k); 1.196 + } 1.197 + 1.198 + static int static_cell_count() { 1.199 + return cell_count; 1.200 + } 1.201 + 1.202 + static ByteSize size() { 1.203 + return in_ByteSize(cell_count * DataLayout::cell_size); 1.204 + } 1.205 + 1.206 + ByteSize type_offset() { 1.207 + return DataLayout::cell_offset(_base_off); 1.208 + } 1.209 1.210 // GC support 1.211 void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); 1.212 @@ -896,23 +866,118 @@ 1.213 #endif 1.214 }; 1.215 1.216 +// Entries to collect type information at a call: contains arguments 1.217 +// (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a 1.218 +// number of cells. Because the number of cells for the return type is 1.219 +// smaller than the number of cells for the type of an arguments, the 1.220 +// number of cells is used to tell how many arguments are profiled and 1.221 +// whether a return value is profiled. See has_arguments() and 1.222 +// has_return(). 1.223 +class TypeEntriesAtCall { 1.224 +private: 1.225 + static int stack_slot_local_offset(int i) { 1.226 + return header_cell_count() + TypeStackSlotEntries::stack_slot_local_offset(i); 1.227 + } 1.228 + 1.229 + static int argument_type_local_offset(int i) { 1.230 + return header_cell_count() + TypeStackSlotEntries::type_local_offset(i);; 1.231 + } 1.232 + 1.233 +public: 1.234 + 1.235 + static int header_cell_count() { 1.236 + return 1; 1.237 + } 1.238 + 1.239 + static int cell_count_local_offset() { 1.240 + return 0; 1.241 + } 1.242 + 1.243 + static int compute_cell_count(BytecodeStream* stream); 1.244 + 1.245 + static void initialize(DataLayout* dl, int base, int cell_count) { 1.246 + int off = base + cell_count_local_offset(); 1.247 + dl->set_cell_at(off, cell_count - base - header_cell_count()); 1.248 + } 1.249 + 1.250 + static bool arguments_profiling_enabled(); 1.251 + static bool return_profiling_enabled(); 1.252 + 1.253 + // Code generation support 1.254 + static ByteSize cell_count_offset() { 1.255 + return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size); 1.256 + } 1.257 + 1.258 + static ByteSize args_data_offset() { 1.259 + return in_ByteSize(header_cell_count() * DataLayout::cell_size); 1.260 + } 1.261 + 1.262 + static ByteSize stack_slot_offset(int i) { 1.263 + return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size); 1.264 + } 1.265 + 1.266 + static ByteSize argument_type_offset(int i) { 1.267 + return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size); 1.268 + } 1.269 +}; 1.270 + 1.271 // CallTypeData 1.272 // 1.273 // A CallTypeData is used to access profiling information about a non 1.274 -// virtual call for which we collect type information about arguments. 1.275 +// virtual call for which we collect type information about arguments 1.276 +// and return value. 1.277 class CallTypeData : public CounterData { 1.278 private: 1.279 + // entries for arguments if any 1.280 TypeStackSlotEntries _args; 1.281 + // entry for return type if any 1.282 + ReturnTypeEntry _ret; 1.283 + 1.284 + int cell_count_global_offset() const { 1.285 + return CounterData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset(); 1.286 + } 1.287 + 1.288 + // number of cells not counting the header 1.289 + int cell_count_no_header() const { 1.290 + return uint_at(cell_count_global_offset()); 1.291 + } 1.292 + 1.293 + void check_number_of_arguments(int total) { 1.294 + assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); 1.295 + } 1.296 + 1.297 +protected: 1.298 + // An entry for a return value takes less space than an entry for an 1.299 + // argument so if the number of cells exceeds the number of cells 1.300 + // needed for an argument, this object contains type information for 1.301 + // at least one argument. 1.302 + bool has_arguments() const { 1.303 + bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); 1.304 + assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); 1.305 + return res; 1.306 + } 1.307 1.308 public: 1.309 CallTypeData(DataLayout* layout) : 1.310 - CounterData(layout), _args(CounterData::static_cell_count()) { 1.311 + CounterData(layout), 1.312 + _args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), 1.313 + _ret(cell_count() - ReturnTypeEntry::static_cell_count()) 1.314 + { 1.315 assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type"); 1.316 // Some compilers (VC++) don't want this passed in member initialization list 1.317 _args.set_profile_data(this); 1.318 + _ret.set_profile_data(this); 1.319 } 1.320 1.321 - const TypeStackSlotEntries* args() const { return &_args; } 1.322 + const TypeStackSlotEntries* args() const { 1.323 + assert(has_arguments(), "no profiling of arguments"); 1.324 + return &_args; 1.325 + } 1.326 + 1.327 + const ReturnTypeEntry* ret() const { 1.328 + assert(has_return(), "no profiling of return value"); 1.329 + return &_ret; 1.330 + } 1.331 1.332 virtual bool is_CallTypeData() const { return true; } 1.333 1.334 @@ -921,38 +986,60 @@ 1.335 } 1.336 1.337 static int compute_cell_count(BytecodeStream* stream) { 1.338 - return CounterData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream); 1.339 + return CounterData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream); 1.340 } 1.341 1.342 static void initialize(DataLayout* dl, int cell_count) { 1.343 - TypeStackSlotEntries::initialize(dl, CounterData::static_cell_count(), cell_count); 1.344 + TypeEntriesAtCall::initialize(dl, CounterData::static_cell_count(), cell_count); 1.345 } 1.346 1.347 - virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) { 1.348 - _args.post_initialize(stream); 1.349 + virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); 1.350 + 1.351 + virtual int cell_count() const { 1.352 + return CounterData::static_cell_count() + 1.353 + TypeEntriesAtCall::header_cell_count() + 1.354 + int_at_unchecked(cell_count_global_offset()); 1.355 } 1.356 1.357 - virtual int cell_count() const { 1.358 - return _args.cell_count(); 1.359 - } 1.360 - 1.361 - uint number_of_arguments() const { 1.362 - return args()->number_of_arguments(); 1.363 + int number_of_arguments() const { 1.364 + return cell_count_no_header() / TypeStackSlotEntries::per_arg_count(); 1.365 } 1.366 1.367 void set_argument_type(int i, Klass* k) { 1.368 + assert(has_arguments(), "no arguments!"); 1.369 intptr_t current = _args.type(i); 1.370 _args.set_type(i, TypeEntries::with_status(k, current)); 1.371 } 1.372 1.373 + void set_return_type(Klass* k) { 1.374 + assert(has_return(), "no return!"); 1.375 + intptr_t current = _ret.type(); 1.376 + _ret.set_type(TypeEntries::with_status(k, current)); 1.377 + } 1.378 + 1.379 + // An entry for a return value takes less space than an entry for an 1.380 + // argument, so if the remainder of the number of cells divided by 1.381 + // the number of cells for an argument is not null, a return value 1.382 + // is profiled in this object. 1.383 + bool has_return() const { 1.384 + bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; 1.385 + assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); 1.386 + return res; 1.387 + } 1.388 + 1.389 // Code generation support 1.390 static ByteSize args_data_offset() { 1.391 - return cell_offset(CounterData::static_cell_count()) + TypeStackSlotEntries::args_data_offset(); 1.392 + return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); 1.393 } 1.394 1.395 // GC support 1.396 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { 1.397 - _args.clean_weak_klass_links(is_alive_closure); 1.398 + if (has_arguments()) { 1.399 + _args.clean_weak_klass_links(is_alive_closure); 1.400 + } 1.401 + if (has_return()) { 1.402 + _ret.clean_weak_klass_links(is_alive_closure); 1.403 + } 1.404 } 1.405 1.406 #ifndef PRODUCT 1.407 @@ -1105,20 +1192,59 @@ 1.408 // 1.409 // A VirtualCallTypeData is used to access profiling information about 1.410 // a virtual call for which we collect type information about 1.411 -// arguments. 1.412 +// arguments and return value. 1.413 class VirtualCallTypeData : public VirtualCallData { 1.414 private: 1.415 + // entries for arguments if any 1.416 TypeStackSlotEntries _args; 1.417 + // entry for return type if any 1.418 + ReturnTypeEntry _ret; 1.419 + 1.420 + int cell_count_global_offset() const { 1.421 + return VirtualCallData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset(); 1.422 + } 1.423 + 1.424 + // number of cells not counting the header 1.425 + int cell_count_no_header() const { 1.426 + return uint_at(cell_count_global_offset()); 1.427 + } 1.428 + 1.429 + void check_number_of_arguments(int total) { 1.430 + assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); 1.431 + } 1.432 + 1.433 +protected: 1.434 + // An entry for a return value takes less space than an entry for an 1.435 + // argument so if the number of cells exceeds the number of cells 1.436 + // needed for an argument, this object contains type information for 1.437 + // at least one argument. 1.438 + bool has_arguments() const { 1.439 + bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); 1.440 + assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); 1.441 + return res; 1.442 + } 1.443 1.444 public: 1.445 VirtualCallTypeData(DataLayout* layout) : 1.446 - VirtualCallData(layout), _args(VirtualCallData::static_cell_count()) { 1.447 + VirtualCallData(layout), 1.448 + _args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()), 1.449 + _ret(cell_count() - ReturnTypeEntry::static_cell_count()) 1.450 + { 1.451 assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type"); 1.452 // Some compilers (VC++) don't want this passed in member initialization list 1.453 _args.set_profile_data(this); 1.454 + _ret.set_profile_data(this); 1.455 } 1.456 1.457 - const TypeStackSlotEntries* args() const { return &_args; } 1.458 + const TypeStackSlotEntries* args() const { 1.459 + assert(has_arguments(), "no profiling of arguments"); 1.460 + return &_args; 1.461 + } 1.462 + 1.463 + const ReturnTypeEntry* ret() const { 1.464 + assert(has_return(), "no profiling of return value"); 1.465 + return &_ret; 1.466 + } 1.467 1.468 virtual bool is_VirtualCallTypeData() const { return true; } 1.469 1.470 @@ -1127,39 +1253,61 @@ 1.471 } 1.472 1.473 static int compute_cell_count(BytecodeStream* stream) { 1.474 - return VirtualCallData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream); 1.475 + return VirtualCallData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream); 1.476 } 1.477 1.478 static void initialize(DataLayout* dl, int cell_count) { 1.479 - TypeStackSlotEntries::initialize(dl, VirtualCallData::static_cell_count(), cell_count); 1.480 + TypeEntriesAtCall::initialize(dl, VirtualCallData::static_cell_count(), cell_count); 1.481 } 1.482 1.483 - virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) { 1.484 - _args.post_initialize(stream); 1.485 + virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); 1.486 + 1.487 + virtual int cell_count() const { 1.488 + return VirtualCallData::static_cell_count() + 1.489 + TypeEntriesAtCall::header_cell_count() + 1.490 + int_at_unchecked(cell_count_global_offset()); 1.491 } 1.492 1.493 - virtual int cell_count() const { 1.494 - return _args.cell_count(); 1.495 - } 1.496 - 1.497 - uint number_of_arguments() const { 1.498 - return args()->number_of_arguments(); 1.499 + int number_of_arguments() const { 1.500 + return cell_count_no_header() / TypeStackSlotEntries::per_arg_count(); 1.501 } 1.502 1.503 void set_argument_type(int i, Klass* k) { 1.504 + assert(has_arguments(), "no arguments!"); 1.505 intptr_t current = _args.type(i); 1.506 _args.set_type(i, TypeEntries::with_status(k, current)); 1.507 } 1.508 1.509 + void set_return_type(Klass* k) { 1.510 + assert(has_return(), "no return!"); 1.511 + intptr_t current = _ret.type(); 1.512 + _ret.set_type(TypeEntries::with_status(k, current)); 1.513 + } 1.514 + 1.515 + // An entry for a return value takes less space than an entry for an 1.516 + // argument, so if the remainder of the number of cells divided by 1.517 + // the number of cells for an argument is not null, a return value 1.518 + // is profiled in this object. 1.519 + bool has_return() const { 1.520 + bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0; 1.521 + assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values"); 1.522 + return res; 1.523 + } 1.524 + 1.525 // Code generation support 1.526 static ByteSize args_data_offset() { 1.527 - return cell_offset(VirtualCallData::static_cell_count()) + TypeStackSlotEntries::args_data_offset(); 1.528 + return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); 1.529 } 1.530 1.531 // GC support 1.532 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { 1.533 ReceiverTypeData::clean_weak_klass_links(is_alive_closure); 1.534 - _args.clean_weak_klass_links(is_alive_closure); 1.535 + if (has_arguments()) { 1.536 + _args.clean_weak_klass_links(is_alive_closure); 1.537 + } 1.538 + if (has_return()) { 1.539 + _ret.clean_weak_klass_links(is_alive_closure); 1.540 + } 1.541 } 1.542 1.543 #ifndef PRODUCT 1.544 @@ -1691,6 +1839,9 @@ 1.545 static bool profile_arguments_jsr292_only(); 1.546 static bool profile_all_arguments(); 1.547 static bool profile_arguments_for_invoke(methodHandle m, int bci); 1.548 + static int profile_return_flag(); 1.549 + static bool profile_all_return(); 1.550 + static bool profile_return_for_invoke(methodHandle m, int bci); 1.551 1.552 public: 1.553 static int header_size() { 1.554 @@ -1933,6 +2084,8 @@ 1.555 void verify_data_on(outputStream* st); 1.556 1.557 static bool profile_arguments(); 1.558 + static bool profile_return(); 1.559 + static bool profile_return_jsr292_only(); 1.560 }; 1.561 1.562 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP