Index: runtime/vm/intermediate_language_x64.cc |
=================================================================== |
--- runtime/vm/intermediate_language_x64.cc (revision 34916) |
+++ runtime/vm/intermediate_language_x64.cc (working copy) |
@@ -5414,31 +5414,53 @@ |
LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { |
- const intptr_t kNumInputs = 0; |
- const intptr_t kNumTemps = 1; |
- LocationSummary* result = |
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
- result->set_out(0, Location::RegisterLocation(RAX)); |
- result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. |
- return result; |
+ return MakeCallSummary(); |
} |
void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- // The arguments to the stub include the closure, as does the arguments |
- // descriptor. |
- Register temp_reg = locs()->temp(0).reg(); |
- int argument_count = ArgumentCount(); |
+ // Load closure object (first argument) in R13. |
+ intptr_t argument_count = ArgumentCount(); |
+ __ movq(R13, Address(RSP, (argument_count - 1) * kWordSize)); |
+ |
+ // Arguments descriptor is expected in R10. |
const Array& arguments_descriptor = |
Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, |
argument_names())); |
- __ LoadObject(temp_reg, arguments_descriptor, PP); |
- ASSERT(temp_reg == R10); |
- compiler->GenerateDartCall(deopt_id(), |
- token_pos(), |
- &StubCode::CallClosureFunctionLabel(), |
- PcDescriptors::kClosureCall, |
- locs()); |
+ __ LoadObject(R10, arguments_descriptor, PP); |
+ |
+ // Load the actual closure function. |
+ __ movq(RAX, FieldAddress(R13, Closure::function_offset())); |
+ |
+ // Load closure context in CTX; note that CTX has already been preserved. |
+ __ movq(CTX, FieldAddress(R13, Closure::context_offset())); |
+ |
+ // Load closure function code in RAX. |
+ __ movq(RCX, FieldAddress(RAX, Function::code_offset())); |
+ |
+ // RAX: Function. |
+ // R10: Arguments descriptor array. |
+ // RBX: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value). |
+ __ xorq(RBX, RBX); |
+ __ movq(RCX, FieldAddress(RCX, Code::instructions_offset())); |
+ __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
+ __ call(RCX); |
+ compiler->AddCurrentDescriptor(PcDescriptors::kClosureCall, |
+ deopt_id(), |
+ token_pos()); |
+ compiler->RecordSafepoint(locs()); |
+ // Marks either the continuation point in unoptimized code or the |
+ // deoptimization point in optimized code, after call. |
+ const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id()); |
+ if (compiler->is_optimizing()) { |
+ compiler->AddDeoptIndexAtCall(deopt_id_after, token_pos()); |
+ } else { |
+ // Add deoptimization continuation point after the call and before the |
+ // arguments are removed. |
+ compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
+ deopt_id_after, |
+ token_pos()); |
+ } |
__ Drop(argument_count); |
} |