182 if (c == Bytecodes::_goto_w || c == Bytecodes::_jsr_w) { 183 target = stream->dest_w(); 184 } else { 185 target = stream->dest(); 186 } 187 int my_di = mdo->dp_to_di(dp()); 188 int target_di = mdo->bci_to_di(target); 189 int offset = target_di - my_di; 190 set_displacement(offset); 191 } 192 193 void JumpData::print_data_on(outputStream* st, const char* extra) const { 194 print_shared(st, "JumpData", extra); 195 st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); 196 } 197 198 int TypeStackSlotEntries::compute_cell_count(Symbol* signature, bool include_receiver, int max) { 199 // Parameter profiling include the receiver 200 int args_count = include_receiver ? 1 : 0; 201 ResourceMark rm; 202 SignatureStream ss(signature); 203 args_count += ss.reference_parameter_count(); 204 args_count = MIN2(args_count, max); 205 return args_count * per_arg_cell_count; 206 } 207 208 int TypeEntriesAtCall::compute_cell_count(BytecodeStream* stream) { 209 assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); 210 assert(TypeStackSlotEntries::per_arg_count() > ReturnTypeEntry::static_cell_count(), "code to test for arguments/results broken"); 211 const methodHandle m = stream->method(); 212 int bci = stream->bci(); 213 Bytecode_invoke inv(m, bci); 214 int args_cell = 0; 215 if (MethodData::profile_arguments_for_invoke(m, bci)) { 216 args_cell = TypeStackSlotEntries::compute_cell_count(inv.signature(), false, TypeProfileArgsLimit); 217 } 218 int ret_cell = 0; 219 if (MethodData::profile_return_for_invoke(m, bci) && is_reference_type(inv.result_type())) { 220 ret_cell = ReturnTypeEntry::static_cell_count(); 221 } 222 int header_cell = 0; 223 if (args_cell + ret_cell > 0) { 224 header_cell = header_cell_count(); 225 } 226 227 return header_cell + args_cell + ret_cell; 228 } 229 230 class ArgumentOffsetComputer : public SignatureInfo { 231 private: 232 int _max; 233 GrowableArray<int> _offsets; 234 235 void set(int size, BasicType type) { _size += size; } 236 void do_object(int begin, int end) { 237 if (_offsets.length() < _max) { 238 _offsets.push(_size); 239 } 240 SignatureInfo::do_object(begin, end); 241 } 242 void do_array (int begin, int end) { 243 if (_offsets.length() < _max) { 244 _offsets.push(_size); 245 } 246 SignatureInfo::do_array(begin, end); 247 } 248 249 public: 250 ArgumentOffsetComputer(Symbol* signature, int max) 251 : SignatureInfo(signature), _max(max), _offsets(Thread::current(), max) { 252 } 253 254 int total() { lazy_iterate_parameters(); return _size; } 255 256 int off_at(int i) const { return _offsets.at(i); } 257 }; 258 259 void TypeStackSlotEntries::post_initialize(Symbol* signature, bool has_receiver, bool include_receiver) { 260 ResourceMark rm; 261 int start = 0; 262 // Parameter profiling include the receiver 263 if (include_receiver && has_receiver) { 264 set_stack_slot(0, 0); 265 set_type(0, type_none()); 266 start += 1; 267 } 268 ArgumentOffsetComputer aos(signature, _number_of_entries-start); 269 aos.total(); 270 for (int i = start; i < _number_of_entries; i++) { 271 set_stack_slot(i, aos.off_at(i-start) + (has_receiver ? 1 : 0)); 272 set_type(i, type_none()); 273 } 274 } 275 276 void CallTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) { 277 assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); 278 Bytecode_invoke inv(stream->method(), stream->bci()); 279 280 SignatureStream ss(inv.signature()); 281 if (has_arguments()) { 282 #ifdef ASSERT 283 ResourceMark rm; 284 int count = MIN2(ss.reference_parameter_count(), (int)TypeProfileArgsLimit); 285 assert(count > 0, "room for args type but none found?"); 286 check_number_of_arguments(count); 287 #endif 288 _args.post_initialize(inv.signature(), inv.has_receiver(), false); 289 } 290 291 if (has_return()) { 292 assert(is_reference_type(inv.result_type()), "room for a ret type but doesn't return obj?"); 293 _ret.post_initialize(); 294 } 295 } 296 297 void VirtualCallTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) { 298 assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); 299 Bytecode_invoke inv(stream->method(), stream->bci()); 300 301 if (has_arguments()) { 302 #ifdef ASSERT 303 ResourceMark rm; 304 SignatureStream ss(inv.signature()); 305 int count = MIN2(ss.reference_parameter_count(), (int)TypeProfileArgsLimit); 306 assert(count > 0, "room for args type but none found?"); 307 check_number_of_arguments(count); 308 #endif 309 _args.post_initialize(inv.signature(), inv.has_receiver(), false); 310 } 311 312 if (has_return()) { 313 assert(is_reference_type(inv.result_type()), "room for a ret type but doesn't return obj?"); 314 _ret.post_initialize(); 315 } 316 } 317 318 void TypeStackSlotEntries::clean_weak_klass_links(bool always_clean) { 319 for (int i = 0; i < _number_of_entries; i++) { 320 intptr_t p = type(i); 321 Klass* k = (Klass*)klass_part(p); 322 if (k != NULL && (always_clean || !k->is_loader_alive())) { 323 set_type(i, with_status((Klass*)NULL, p)); 324 } 325 } | 182 if (c == Bytecodes::_goto_w || c == Bytecodes::_jsr_w) { 183 target = stream->dest_w(); 184 } else { 185 target = stream->dest(); 186 } 187 int my_di = mdo->dp_to_di(dp()); 188 int target_di = mdo->bci_to_di(target); 189 int offset = target_di - my_di; 190 set_displacement(offset); 191 } 192 193 void JumpData::print_data_on(outputStream* st, const char* extra) const { 194 print_shared(st, "JumpData", extra); 195 st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); 196 } 197 198 int TypeStackSlotEntries::compute_cell_count(Symbol* signature, bool include_receiver, int max) { 199 // Parameter profiling include the receiver 200 int args_count = include_receiver ? 1 : 0; 201 ResourceMark rm; 202 ReferenceArgumentCount rac(signature); 203 args_count += rac.count(); 204 args_count = MIN2(args_count, max); 205 return args_count * per_arg_cell_count; 206 } 207 208 int TypeEntriesAtCall::compute_cell_count(BytecodeStream* stream) { 209 assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); 210 assert(TypeStackSlotEntries::per_arg_count() > ReturnTypeEntry::static_cell_count(), "code to test for arguments/results broken"); 211 const methodHandle m = stream->method(); 212 int bci = stream->bci(); 213 Bytecode_invoke inv(m, bci); 214 int args_cell = 0; 215 if (MethodData::profile_arguments_for_invoke(m, bci)) { 216 args_cell = TypeStackSlotEntries::compute_cell_count(inv.signature(), false, TypeProfileArgsLimit); 217 } 218 int ret_cell = 0; 219 if (MethodData::profile_return_for_invoke(m, bci) && is_reference_type(inv.result_type())) { 220 ret_cell = ReturnTypeEntry::static_cell_count(); 221 } 222 int header_cell = 0; 223 if (args_cell + ret_cell > 0) { 224 header_cell = header_cell_count(); 225 } 226 227 return header_cell + args_cell + ret_cell; 228 } 229 230 class ArgumentOffsetComputer : public SignatureIterator { 231 private: 232 int _max; 233 int _offset; 234 GrowableArray<int> _offsets; 235 236 friend class SignatureIterator; // so do_parameters_on can call do_type 237 void do_type(BasicType type) { 238 if (is_reference_type(type) && _offsets.length() < _max) { 239 _offsets.push(_offset); 240 } 241 _offset += parameter_type_word_count(type); 242 } 243 244 public: 245 ArgumentOffsetComputer(Symbol* signature, int max) 246 : SignatureIterator(signature), 247 _max(max), _offset(0), 248 _offsets(Thread::current(), max) { 249 do_parameters_on(this); // non-virtual template execution 250 } 251 252 int off_at(int i) const { return _offsets.at(i); } 253 }; 254 255 void TypeStackSlotEntries::post_initialize(Symbol* signature, bool has_receiver, bool include_receiver) { 256 ResourceMark rm; 257 int start = 0; 258 // Parameter profiling include the receiver 259 if (include_receiver && has_receiver) { 260 set_stack_slot(0, 0); 261 set_type(0, type_none()); 262 start += 1; 263 } 264 ArgumentOffsetComputer aos(signature, _number_of_entries-start); 265 for (int i = start; i < _number_of_entries; i++) { 266 set_stack_slot(i, aos.off_at(i-start) + (has_receiver ? 1 : 0)); 267 set_type(i, type_none()); 268 } 269 } 270 271 void CallTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) { 272 assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); 273 Bytecode_invoke inv(stream->method(), stream->bci()); 274 275 if (has_arguments()) { 276 #ifdef ASSERT 277 ResourceMark rm; 278 ReferenceArgumentCount rac(inv.signature()); 279 int count = MIN2(rac.count(), (int)TypeProfileArgsLimit); 280 assert(count > 0, "room for args type but none found?"); 281 check_number_of_arguments(count); 282 #endif 283 _args.post_initialize(inv.signature(), inv.has_receiver(), false); 284 } 285 286 if (has_return()) { 287 assert(is_reference_type(inv.result_type()), "room for a ret type but doesn't return obj?"); 288 _ret.post_initialize(); 289 } 290 } 291 292 void VirtualCallTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) { 293 assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); 294 Bytecode_invoke inv(stream->method(), stream->bci()); 295 296 if (has_arguments()) { 297 #ifdef ASSERT 298 ResourceMark rm; 299 ReferenceArgumentCount rac(inv.signature()); 300 int count = MIN2(rac.count(), (int)TypeProfileArgsLimit); 301 assert(count > 0, "room for args type but none found?"); 302 check_number_of_arguments(count); 303 #endif 304 _args.post_initialize(inv.signature(), inv.has_receiver(), false); 305 } 306 307 if (has_return()) { 308 assert(is_reference_type(inv.result_type()), "room for a ret type but doesn't return obj?"); 309 _ret.post_initialize(); 310 } 311 } 312 313 void TypeStackSlotEntries::clean_weak_klass_links(bool always_clean) { 314 for (int i = 0; i < _number_of_entries; i++) { 315 intptr_t p = type(i); 316 Klass* k = (Klass*)klass_part(p); 317 if (k != NULL && (always_clean || !k->is_loader_alive())) { 318 set_type(i, with_status((Klass*)NULL, p)); 319 } 320 } |