| Index: runtime/vm/stub_code_x64.cc
|
| diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
|
| index 19cee0b6f154f23d9449a9919d8d6379bbebab58..2a158222cceacba8e4f233ba829acfc03f0989bf 100644
|
| --- a/runtime/vm/stub_code_x64.cc
|
| +++ b/runtime/vm/stub_code_x64.cc
|
| @@ -28,6 +28,7 @@ DEFINE_FLAG(bool, use_slow_path, false,
|
| DECLARE_FLAG(bool, trace_optimized_ic_calls);
|
| DECLARE_FLAG(int, optimization_counter_threshold);
|
| DECLARE_FLAG(bool, support_debugger);
|
| +DECLARE_FLAG(bool, lazy_dispatchers);
|
|
|
| // Input parameters:
|
| // RSP : points to return address.
|
| @@ -527,6 +528,36 @@ void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
|
| }
|
|
|
|
|
| +static void GenerateDispatcherCode(Assembler* assembler,
|
| + Label* call_target_function) {
|
| + __ Comment("NoSuchMethodDispatch");
|
| + // When lazily generated invocation dispatchers are disabled, the
|
| + // miss-handler may return null.
|
| + const Immediate& raw_null =
|
| + Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| + __ cmpq(RAX, raw_null);
|
| + __ j(NOT_EQUAL, call_target_function);
|
| + __ EnterStubFrame();
|
| + // Load the receiver.
|
| + __ movq(RDI, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
|
| + __ movq(RAX, Address(
|
| + RBP, RDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize));
|
| + __ pushq(raw_null); // Setup space on stack for result.
|
| + __ pushq(RAX); // Receiver.
|
| + __ pushq(RBX);
|
| + __ pushq(R10); // Arguments descriptor array.
|
| + __ movq(R10, RDI);
|
| + // EDX: Smi-tagged arguments array length.
|
| + PushArgumentsArray(assembler);
|
| + const intptr_t kNumArgs = 4;
|
| + __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
|
| + __ Drop(4);
|
| + __ popq(RAX); // Return value.
|
| + __ LeaveStubFrame();
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
|
| __ EnterStubFrame();
|
| // Load the receiver into RAX. The argument count in the arguments
|
| @@ -555,6 +586,12 @@ void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
|
| __ popq(RBX); // Restore IC data.
|
| __ LeaveStubFrame();
|
|
|
| + if (!FLAG_lazy_dispatchers) {
|
| + Label call_target_function;
|
| + GenerateDispatcherCode(assembler, &call_target_function);
|
| + __ Bind(&call_target_function);
|
| + }
|
| +
|
| __ movq(RCX, FieldAddress(RAX, Function::instructions_offset()));
|
| __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
|
| __ jmp(RCX);
|
| @@ -1459,7 +1496,11 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
|
| __ popq(R10); // Restore arguments descriptor array.
|
| __ LeaveStubFrame();
|
| Label call_target_function;
|
| - __ jmp(&call_target_function);
|
| + if (!FLAG_lazy_dispatchers) {
|
| + GenerateDispatcherCode(assembler, &call_target_function);
|
| + } else {
|
| + __ jmp(&call_target_function);
|
| + }
|
|
|
| __ Bind(&found);
|
| // R12: Pointer to an IC data check group.
|
|
|