1.1 --- a/src/share/vm/oops/methodData.hpp Mon Oct 21 17:34:27 2013 -0700 1.2 +++ b/src/share/vm/oops/methodData.hpp Tue Oct 22 09:51:47 2013 +0200 1.3 @@ -119,7 +119,8 @@ 1.4 multi_branch_data_tag, 1.5 arg_info_data_tag, 1.6 call_type_data_tag, 1.7 - virtual_call_type_data_tag 1.8 + virtual_call_type_data_tag, 1.9 + parameters_type_data_tag 1.10 }; 1.11 1.12 enum { 1.13 @@ -264,6 +265,7 @@ 1.14 class ArrayData; 1.15 class MultiBranchData; 1.16 class ArgInfoData; 1.17 +class ParametersTypeData; 1.18 1.19 // ProfileData 1.20 // 1.21 @@ -397,6 +399,7 @@ 1.22 virtual bool is_ArgInfoData() const { return false; } 1.23 virtual bool is_CallTypeData() const { return false; } 1.24 virtual bool is_VirtualCallTypeData()const { return false; } 1.25 + virtual bool is_ParametersTypeData() const { return false; } 1.26 1.27 1.28 BitData* as_BitData() const { 1.29 @@ -447,6 +450,10 @@ 1.30 assert(is_VirtualCallTypeData(), "wrong type"); 1.31 return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL; 1.32 } 1.33 + ParametersTypeData* as_ParametersTypeData() const { 1.34 + assert(is_ParametersTypeData(), "wrong type"); 1.35 + return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL; 1.36 + } 1.37 1.38 1.39 // Subclass specific initialization 1.40 @@ -767,9 +774,9 @@ 1.41 TypeStackSlotEntries(int base_off, int nb_entries) 1.42 : TypeEntries(base_off), _number_of_entries(nb_entries) {} 1.43 1.44 - static int compute_cell_count(Symbol* signature, int max); 1.45 + static int compute_cell_count(Symbol* signature, bool include_receiver, int max); 1.46 1.47 - void post_initialize(Symbol* signature, bool has_receiver); 1.48 + void post_initialize(Symbol* signature, bool has_receiver, bool include_receiver); 1.49 1.50 // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries 1.51 static int stack_slot_local_offset(int i) { 1.52 @@ -946,17 +953,6 @@ 1.53 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); 1.54 } 1.55 1.56 -protected: 1.57 - // An entry for a return value takes less space than an entry for an 1.58 - // argument so if the number of cells exceeds the number of cells 1.59 - // needed for an argument, this object contains type information for 1.60 - // at least one argument. 1.61 - bool has_arguments() const { 1.62 - bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); 1.63 - assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); 1.64 - return res; 1.65 - } 1.66 - 1.67 public: 1.68 CallTypeData(DataLayout* layout) : 1.69 CounterData(layout), 1.70 @@ -1018,6 +1014,16 @@ 1.71 } 1.72 1.73 // An entry for a return value takes less space than an entry for an 1.74 + // argument so if the number of cells exceeds the number of cells 1.75 + // needed for an argument, this object contains type information for 1.76 + // at least one argument. 1.77 + bool has_arguments() const { 1.78 + bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); 1.79 + assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); 1.80 + return res; 1.81 + } 1.82 + 1.83 + // An entry for a return value takes less space than an entry for an 1.84 // argument, so if the remainder of the number of cells divided by 1.85 // the number of cells for an argument is not null, a return value 1.86 // is profiled in this object. 1.87 @@ -1213,17 +1219,6 @@ 1.88 assert(number_of_arguments() == total, "should be set in DataLayout::initialize"); 1.89 } 1.90 1.91 -protected: 1.92 - // An entry for a return value takes less space than an entry for an 1.93 - // argument so if the number of cells exceeds the number of cells 1.94 - // needed for an argument, this object contains type information for 1.95 - // at least one argument. 1.96 - bool has_arguments() const { 1.97 - bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); 1.98 - assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); 1.99 - return res; 1.100 - } 1.101 - 1.102 public: 1.103 VirtualCallTypeData(DataLayout* layout) : 1.104 VirtualCallData(layout), 1.105 @@ -1294,6 +1289,16 @@ 1.106 return res; 1.107 } 1.108 1.109 + // An entry for a return value takes less space than an entry for an 1.110 + // argument so if the number of cells exceeds the number of cells 1.111 + // needed for an argument, this object contains type information for 1.112 + // at least one argument. 1.113 + bool has_arguments() const { 1.114 + bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count(); 1.115 + assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments"); 1.116 + return res; 1.117 + } 1.118 + 1.119 // Code generation support 1.120 static ByteSize args_data_offset() { 1.121 return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset(); 1.122 @@ -1662,6 +1667,75 @@ 1.123 #endif 1.124 }; 1.125 1.126 +// ParametersTypeData 1.127 +// 1.128 +// A ParametersTypeData is used to access profiling information about 1.129 +// types of parameters to a method 1.130 +class ParametersTypeData : public ArrayData { 1.131 + 1.132 +private: 1.133 + TypeStackSlotEntries _parameters; 1.134 + 1.135 + static int stack_slot_local_offset(int i) { 1.136 + assert_profiling_enabled(); 1.137 + return array_start_off_set + TypeStackSlotEntries::stack_slot_local_offset(i); 1.138 + } 1.139 + 1.140 + static int type_local_offset(int i) { 1.141 + assert_profiling_enabled(); 1.142 + return array_start_off_set + TypeStackSlotEntries::type_local_offset(i); 1.143 + } 1.144 + 1.145 + static bool profiling_enabled(); 1.146 + static void assert_profiling_enabled() { 1.147 + assert(profiling_enabled(), "method parameters profiling should be on"); 1.148 + } 1.149 + 1.150 +public: 1.151 + ParametersTypeData(DataLayout* layout) : ArrayData(layout), _parameters(1, number_of_parameters()) { 1.152 + assert(layout->tag() == DataLayout::parameters_type_data_tag, "wrong type"); 1.153 + // Some compilers (VC++) don't want this passed in member initialization list 1.154 + _parameters.set_profile_data(this); 1.155 + } 1.156 + 1.157 + static int compute_cell_count(Method* m); 1.158 + 1.159 + virtual bool is_ParametersTypeData() const { return true; } 1.160 + 1.161 + virtual void post_initialize(BytecodeStream* stream, MethodData* mdo); 1.162 + 1.163 + int number_of_parameters() const { 1.164 + return array_len() / TypeStackSlotEntries::per_arg_count(); 1.165 + } 1.166 + 1.167 + const TypeStackSlotEntries* parameters() const { return &_parameters; } 1.168 + 1.169 + uint stack_slot(int i) const { 1.170 + return _parameters.stack_slot(i); 1.171 + } 1.172 + 1.173 + void set_type(int i, Klass* k) { 1.174 + intptr_t current = _parameters.type(i); 1.175 + _parameters.set_type(i, TypeEntries::with_status((intptr_t)k, current)); 1.176 + } 1.177 + 1.178 + virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { 1.179 + _parameters.clean_weak_klass_links(is_alive_closure); 1.180 + } 1.181 + 1.182 +#ifndef PRODUCT 1.183 + virtual void print_data_on(outputStream* st) const; 1.184 +#endif 1.185 + 1.186 + static ByteSize stack_slot_offset(int i) { 1.187 + return cell_offset(stack_slot_local_offset(i)); 1.188 + } 1.189 + 1.190 + static ByteSize type_offset(int i) { 1.191 + return cell_offset(type_local_offset(i)); 1.192 + } 1.193 +}; 1.194 + 1.195 // MethodData* 1.196 // 1.197 // A MethodData* holds information which has been collected about 1.198 @@ -1773,6 +1847,10 @@ 1.199 // Size of _data array in bytes. (Excludes header and extra_data fields.) 1.200 int _data_size; 1.201 1.202 + // data index for the area dedicated to parameters. -1 if no 1.203 + // parameter profiling. 1.204 + int _parameters_type_data_di; 1.205 + 1.206 // Beginning of the data entries 1.207 intptr_t _data[1]; 1.208 1.209 @@ -1842,6 +1920,9 @@ 1.210 static int profile_return_flag(); 1.211 static bool profile_all_return(); 1.212 static bool profile_return_for_invoke(methodHandle m, int bci); 1.213 + static int profile_parameters_flag(); 1.214 + static bool profile_parameters_jsr292_only(); 1.215 + static bool profile_all_parameters(); 1.216 1.217 public: 1.218 static int header_size() { 1.219 @@ -2048,6 +2129,16 @@ 1.220 } 1.221 } 1.222 1.223 + // Return pointer to area dedicated to parameters in MDO 1.224 + ParametersTypeData* parameters_type_data() const { 1.225 + return _parameters_type_data_di != -1 ? data_layout_at(_parameters_type_data_di)->data_in()->as_ParametersTypeData() : NULL; 1.226 + } 1.227 + 1.228 + int parameters_type_data_di() const { 1.229 + assert(_parameters_type_data_di != -1, "no args type data"); 1.230 + return _parameters_type_data_di; 1.231 + } 1.232 + 1.233 // Support for code generation 1.234 static ByteSize data_offset() { 1.235 return byte_offset_of(MethodData, _data[0]); 1.236 @@ -2060,6 +2151,10 @@ 1.237 return byte_offset_of(MethodData, _backedge_counter); 1.238 } 1.239 1.240 + static ByteSize parameters_type_data_di_offset() { 1.241 + return byte_offset_of(MethodData, _parameters_type_data_di); 1.242 + } 1.243 + 1.244 // Deallocation support - no pointer fields to deallocate 1.245 void deallocate_contents(ClassLoaderData* loader_data) {} 1.246 1.247 @@ -2083,8 +2178,10 @@ 1.248 void verify_on(outputStream* st); 1.249 void verify_data_on(outputStream* st); 1.250 1.251 + static bool profile_parameters_for_method(methodHandle m); 1.252 static bool profile_arguments(); 1.253 static bool profile_return(); 1.254 + static bool profile_parameters(); 1.255 static bool profile_return_jsr292_only(); 1.256 }; 1.257