264 } 265 266 // Method that knows how to preserve outgoing arguments at call. This method must be 267 // called with a frame corresponding to a Java invoke 268 void CompiledMethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { 269 if (method() != NULL && !method()->is_native()) { 270 address pc = fr.pc(); 271 SimpleScopeDesc ssd(this, pc); 272 Bytecode_invoke call(ssd.method(), ssd.bci()); 273 bool has_receiver = call.has_receiver(); 274 bool has_appendix = call.has_appendix(); 275 Symbol* signature = call.signature(); 276 277 // The method attached by JIT-compilers should be used, if present. 278 // Bytecode can be inaccurate in such case. 279 Method* callee = attached_method_before_pc(pc); 280 if (callee != NULL) { 281 has_receiver = !(callee->access_flags().is_static()); 282 has_appendix = false; 283 signature = callee->signature(); 284 } 285 286 // If value types are passed as fields, use the extended signature 287 // which contains the types of all (oop) fields of the value type. 288 if (ValueTypePassFieldsAsArgs && callee != NULL) { 289 // Get the extended signature from the callee's adapter through the attached method 290 Symbol* sig_ext = callee->adapter()->get_sig_extended(); 291 #ifdef ASSERT 292 // Check if receiver or one of the arguments is a value type 293 bool has_value_receiver = has_receiver && callee->method_holder()->is_value(); 294 bool has_value_argument = has_value_receiver; 295 for (SignatureStream ss(signature); !has_value_argument && !ss.at_return_type(); ss.next()) { 296 if (ss.type() == T_VALUETYPE) { 297 has_value_argument = true; 298 break; 299 } 300 } 301 assert(has_value_argument == (sig_ext != NULL), "Signature is inconsistent"); 302 #endif 303 if (sig_ext != NULL) { 304 signature = sig_ext; 305 has_receiver = false; // The extended signature contains the receiver type 306 } 307 } 308 309 fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f); 310 } 311 } 312 313 Method* CompiledMethod::attached_method(address call_instr) { 314 assert(code_contains(call_instr), "not part of the nmethod"); 315 RelocIterator iter(this, call_instr, call_instr + 1); 316 while (iter.next()) { 317 if (iter.addr() == call_instr) { 318 switch(iter.type()) { 319 case relocInfo::static_call_type: return iter.static_call_reloc()->method_value(); 320 case relocInfo::opt_virtual_call_type: return iter.opt_virtual_call_reloc()->method_value(); 321 case relocInfo::virtual_call_type: return iter.virtual_call_reloc()->method_value(); 322 default: break; 323 } 324 } | 264 } 265 266 // Method that knows how to preserve outgoing arguments at call. This method must be 267 // called with a frame corresponding to a Java invoke 268 void CompiledMethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { 269 if (method() != NULL && !method()->is_native()) { 270 address pc = fr.pc(); 271 SimpleScopeDesc ssd(this, pc); 272 Bytecode_invoke call(ssd.method(), ssd.bci()); 273 bool has_receiver = call.has_receiver(); 274 bool has_appendix = call.has_appendix(); 275 Symbol* signature = call.signature(); 276 277 // The method attached by JIT-compilers should be used, if present. 278 // Bytecode can be inaccurate in such case. 279 Method* callee = attached_method_before_pc(pc); 280 if (callee != NULL) { 281 has_receiver = !(callee->access_flags().is_static()); 282 has_appendix = false; 283 signature = callee->signature(); 284 285 // If value types are passed as fields, use the extended signature 286 // which contains the types of all (oop) fields of the value type. 287 if (callee->has_scalarized_args()) { 288 const GrowableArray<SigEntry>* sig = callee->adapter()->get_sig_cc(); 289 signature = SigEntry::create_symbol(sig); 290 has_receiver = false; // The extended signature contains the receiver type 291 } 292 } 293 294 fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f); 295 } 296 } 297 298 Method* CompiledMethod::attached_method(address call_instr) { 299 assert(code_contains(call_instr), "not part of the nmethod"); 300 RelocIterator iter(this, call_instr, call_instr + 1); 301 while (iter.next()) { 302 if (iter.addr() == call_instr) { 303 switch(iter.type()) { 304 case relocInfo::static_call_type: return iter.static_call_reloc()->method_value(); 305 case relocInfo::opt_virtual_call_type: return iter.opt_virtual_call_reloc()->method_value(); 306 case relocInfo::virtual_call_type: return iter.virtual_call_reloc()->method_value(); 307 default: break; 308 } 309 } |