521 // Find the result object 522 Node* result = C->top(); 523 int result_size = method()->return_type()->size(); 524 if (result_size != 0 && !kit.stopped()) { 525 result = (result_size == 1) ? kit.pop() : kit.pop_pair(); 526 } 527 528 C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops()); 529 C->env()->notice_inlined_method(_inline_cg->method()); 530 C->set_inlining_progress(true); 531 C->set_do_cleanup(kit.stopped()); // path is dead; needs cleanup 532 533 // Handle value type returns 534 bool returned_as_fields = call->tf()->returns_value_type_as_fields(); 535 if (result->is_ValueType()) { 536 // Only possible if is_mh_late_inline() when the callee does not "know" that the caller expects an oop 537 assert(is_mh_late_inline() && !returned_as_fields, "sanity"); 538 assert(buffer_oop != NULL, "should have allocated a buffer"); 539 ValueTypeNode* vt = result->as_ValueType(); 540 vt->store(&kit, buffer_oop, buffer_oop, vt->type()->value_klass(), 0); 541 result = buffer_oop; 542 } else if (result->is_ValueTypePtr() && returned_as_fields) { 543 result->as_ValueTypePtr()->replace_call_results(&kit, call, C); 544 } 545 546 kit.replace_call(call, result, true); 547 } 548 } 549 550 551 CallGenerator* CallGenerator::for_late_inline(ciMethod* method, CallGenerator* inline_cg) { 552 return new LateInlineCallGenerator(method, inline_cg); 553 } 554 555 class LateInlineMHCallGenerator : public LateInlineCallGenerator { 556 ciMethod* _caller; 557 int _attempt; 558 bool _input_not_const; 559 560 virtual bool do_late_inline_check(JVMState* jvms); | 521 // Find the result object 522 Node* result = C->top(); 523 int result_size = method()->return_type()->size(); 524 if (result_size != 0 && !kit.stopped()) { 525 result = (result_size == 1) ? kit.pop() : kit.pop_pair(); 526 } 527 528 C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops()); 529 C->env()->notice_inlined_method(_inline_cg->method()); 530 C->set_inlining_progress(true); 531 C->set_do_cleanup(kit.stopped()); // path is dead; needs cleanup 532 533 // Handle value type returns 534 bool returned_as_fields = call->tf()->returns_value_type_as_fields(); 535 if (result->is_ValueType()) { 536 // Only possible if is_mh_late_inline() when the callee does not "know" that the caller expects an oop 537 assert(is_mh_late_inline() && !returned_as_fields, "sanity"); 538 assert(buffer_oop != NULL, "should have allocated a buffer"); 539 ValueTypeNode* vt = result->as_ValueType(); 540 vt->store(&kit, buffer_oop, buffer_oop, vt->type()->value_klass(), 0); 541 // Do not let stores that initialize this buffer be reordered with a subsequent 542 // store that would make this buffer accessible by other threads. 543 AllocateNode* alloc = AllocateNode::Ideal_allocation(buffer_oop, &kit.gvn()); 544 assert(alloc != NULL, "must have an allocation node"); 545 kit.insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out_or_null(AllocateNode::RawAddress)); 546 result = buffer_oop; 547 } else if (result->is_ValueTypePtr() && returned_as_fields) { 548 result->as_ValueTypePtr()->replace_call_results(&kit, call, C); 549 } 550 551 kit.replace_call(call, result, true); 552 } 553 } 554 555 556 CallGenerator* CallGenerator::for_late_inline(ciMethod* method, CallGenerator* inline_cg) { 557 return new LateInlineCallGenerator(method, inline_cg); 558 } 559 560 class LateInlineMHCallGenerator : public LateInlineCallGenerator { 561 ciMethod* _caller; 562 int _attempt; 563 bool _input_not_const; 564 565 virtual bool do_late_inline_check(JVMState* jvms); |