[vm, interpreter] noSuchMethod dispatchers as a bytecode.
Change-Id: I0e105a56b733322737b6f22a7641f7c6b8afac79
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100283
Reviewed-by: RĂ©gis Crelier <regis@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 2086352..033ffbc 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -4699,6 +4699,8 @@
"<invoke closure>");
AddBaseObject(Object::invoke_field_bytecode().raw(), "Bytecode",
"<invoke field>");
+ AddBaseObject(Object::nsm_dispatcher_bytecode().raw(), "Bytecode",
+ "<nsm dispatcher>");
for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i],
@@ -5160,6 +5162,7 @@
AddBaseObject(Object::method_extractor_bytecode().raw());
AddBaseObject(Object::invoke_closure_bytecode().raw());
AddBaseObject(Object::invoke_field_bytecode().raw());
+ AddBaseObject(Object::nsm_dispatcher_bytecode().raw());
for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i]);
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 8cdb6d1..eb7f7d8 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -74,8 +74,11 @@
function.AttachBytecode(Object::invoke_field_bytecode());
}
return;
- default: {
- }
+ case RawFunction::kNoSuchMethodDispatcher:
+ function.AttachBytecode(Object::nsm_dispatcher_bytecode());
+ return;
+ default:
+ break;
}
intptr_t code_offset = 0;
@@ -118,7 +121,8 @@
(function.kind() != RawFunction::kImplicitSetter) &&
(function.kind() != RawFunction::kImplicitStaticGetter) &&
(function.kind() != RawFunction::kMethodExtractor) &&
- (function.kind() != RawFunction::kInvokeFieldDispatcher)) {
+ (function.kind() != RawFunction::kInvokeFieldDispatcher) &&
+ (function.kind() != RawFunction::kNoSuchMethodDispatcher)) {
return;
}
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 4d7919f..6d34295 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -946,6 +946,8 @@
return B->BuildGraphOfDynamicInvocationForwarder(function);
case RawFunction::kMethodExtractor:
return B->BuildGraphOfMethodExtractor(function);
+ case RawFunction::kNoSuchMethodDispatcher:
+ return B->BuildGraphOfNoSuchMethodDispatcher(function);
default:
break;
}
@@ -970,7 +972,8 @@
(function.kind() != RawFunction::kImplicitSetter) &&
(function.kind() != RawFunction::kImplicitStaticGetter) &&
(function.kind() != RawFunction::kMethodExtractor) &&
- (function.kind() != RawFunction::kInvokeFieldDispatcher)) {
+ (function.kind() != RawFunction::kInvokeFieldDispatcher) &&
+ (function.kind() != RawFunction::kNoSuchMethodDispatcher)) {
BytecodeFlowGraphBuilder bytecode_compiler(
flow_graph_builder_, parsed_function(),
&(flow_graph_builder_->ic_data_array_));
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 8038fbd..efd4d67 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -837,7 +837,7 @@
// R2: Smi-tagged arguments array length.
PushArrayOfArguments(assembler);
const intptr_t kNumArgs = 4;
- __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
+ __ CallRuntime(kNoSuchMethodFromCallStubRuntimeEntry, kNumArgs);
__ Drop(4);
__ Pop(R0); // Return value.
__ LeaveStubFrame();
@@ -1768,11 +1768,14 @@
__ ldr(R8, Address(IP, target::frame_layout.param_end_from_fp *
target::kWordSize));
+ // Load the function.
+ __ ldr(R6, FieldAddress(R8, target::Closure::function_offset()));
+
// Push space for the return value.
// Push the receiver.
// Push arguments descriptor array.
__ LoadImmediate(IP, 0);
- __ PushList((1 << R4) | (1 << R8) | (1 << IP));
+ __ PushList((1 << R4) | (1 << R6) | (1 << R8) | (1 << IP));
// Adjust arguments count.
__ ldr(R3,
@@ -1784,8 +1787,8 @@
// R2: Smi-tagged arguments array length.
PushArrayOfArguments(assembler);
- const intptr_t kNumArgs = 3;
- __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
+ const intptr_t kNumArgs = 4;
+ __ CallRuntime(kNoSuchMethodFromPrologueRuntimeEntry, kNumArgs);
// noSuchMethod on closures always throws an error, so it will never return.
__ bkpt(0);
}
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 01a0e20..cfc7edc 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -887,7 +887,7 @@
// R2: Smi-tagged arguments array length.
PushArrayOfArguments(assembler);
const intptr_t kNumArgs = 4;
- __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
+ __ CallRuntime(kNoSuchMethodFromCallStubRuntimeEntry, kNumArgs);
__ Drop(4);
__ Pop(R0); // Return value.
__ LeaveStubFrame();
@@ -1827,12 +1827,13 @@
__ LoadFromOffset(R6, TMP,
target::frame_layout.param_end_from_fp * target::kWordSize);
- // Push space for the return value.
- // Push the receiver.
- // Push arguments descriptor array.
- __ Push(ZR);
- __ Push(R6);
- __ Push(R4);
+ // Load the function.
+ __ LoadFieldFromOffset(TMP, R6, target::Closure::function_offset());
+
+ __ Push(ZR); // Result slot.
+ __ Push(R6); // Receiver.
+ __ Push(TMP); // Function
+ __ Push(R4); // Arguments descriptor.
// Adjust arguments count.
__ LoadFieldFromOffset(R3, R4,
@@ -1844,8 +1845,8 @@
// R2: Smi-tagged arguments array length.
PushArrayOfArguments(assembler);
- const intptr_t kNumArgs = 3;
- __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
+ const intptr_t kNumArgs = 4;
+ __ CallRuntime(kNoSuchMethodFromPrologueRuntimeEntry, kNumArgs);
// noSuchMethod on closures always throws an error, so it will never return.
__ brk(0);
}
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 570d2f8..c899725 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -627,7 +627,7 @@
// EDX: Smi-tagged arguments array length.
PushArrayOfArguments(assembler);
const intptr_t kNumArgs = 4;
- __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
+ __ CallRuntime(kNoSuchMethodFromCallStubRuntimeEntry, kNumArgs);
__ Drop(4);
__ popl(EAX); // Return value.
__ LeaveFrame();
@@ -1471,8 +1471,12 @@
Address(EBP, EDI, TIMES_2,
target::frame_layout.param_end_from_fp * target::kWordSize));
+ // Load the function.
+ __ movl(EBX, FieldAddress(EAX, target::Closure::function_offset()));
+
__ pushl(Immediate(0)); // Setup space on stack for result from noSuchMethod.
__ pushl(EAX); // Receiver.
+ __ pushl(EBX); // Function.
__ pushl(EDX); // Arguments descriptor array.
// Adjust arguments count.
@@ -1488,8 +1492,8 @@
// EDX: Smi-tagged arguments array length.
PushArrayOfArguments(assembler);
- const intptr_t kNumArgs = 3;
- __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
+ const intptr_t kNumArgs = 4;
+ __ CallRuntime(kNoSuchMethodFromPrologueRuntimeEntry, kNumArgs);
// noSuchMethod on closures always throws an error, so it will never return.
__ int3();
}
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 8c8e0be..1d14115 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -847,7 +847,7 @@
// R10: Smi-tagged arguments array length.
PushArrayOfArguments(assembler);
const intptr_t kNumArgs = 4;
- __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
+ __ CallRuntime(kNoSuchMethodFromCallStubRuntimeEntry, kNumArgs);
__ Drop(4);
__ popq(RAX); // Return value.
__ LeaveStubFrame();
@@ -1804,8 +1804,12 @@
Address(RBP, R13, TIMES_4,
target::frame_layout.param_end_from_fp * target::kWordSize));
+ // Load the function.
+ __ movq(RBX, FieldAddress(RAX, target::Closure::function_offset()));
+
__ pushq(Immediate(0)); // Result slot.
__ pushq(RAX); // Receiver.
+ __ pushq(RBX); // Function.
__ pushq(R10); // Arguments descriptor array.
// Adjust arguments count.
@@ -1821,8 +1825,8 @@
// R10: Smi-tagged arguments array length.
PushArrayOfArguments(assembler);
- const intptr_t kNumArgs = 3;
- __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
+ const intptr_t kNumArgs = 4;
+ __ CallRuntime(kNoSuchMethodFromPrologueRuntimeEntry, kNumArgs);
// noSuchMethod on closures always throws an error, so it will never return.
__ int3();
}
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index 126a2f4..bc25ff8 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -538,7 +538,7 @@
V(VMInternal_InvokeClosure, 0, ___, ___, ___) \
V(VMInternal_InvokeField, 0, ___, ___, ___) \
V(VMInternal_ForwardDynamicInvocation, 0, ___, ___, ___) \
- V(VMInternal_DispatchNoSuchMethod, 0, ___, ___, ___) \
+ V(VMInternal_NoSuchMethodDispatcher, 0, ___, ___, ___) \
V(VMInternal_ImplicitStaticClosure, 0, ___, ___, ___) \
V(VMInternal_ImplicitInstanceClosure, 0, ___, ___, ___) \
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index e7ac7c1..2b821ed 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -1425,10 +1425,6 @@
RawBool* false_value = Bool::False().raw();
RawObject* null_value = Object::null();
-#if defined(DEBUG)
- Function& function_h = Function::Handle();
-#endif
-
#ifdef DART_HAS_COMPUTED_GOTO
static const void* dispatch[] = {
#define TARGET(name, fmt, fmta, fmtb, fmtc) &&bc##name,
@@ -1472,7 +1468,7 @@
const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_);
const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_);
if ((arg_count != num_fixed_params) || (pos_count != num_fixed_params)) {
- goto ClosureNoSuchMethod;
+ goto NoSuchMethodFromPrologue;
}
// Initialize locals with null & set SP.
@@ -1499,7 +1495,7 @@
// Check that got the right number of positional parameters.
if ((min_num_pos_args > pos_count) || (pos_count > max_num_pos_args)) {
- goto ClosureNoSuchMethod;
+ goto NoSuchMethodFromPrologue;
}
// Copy all passed position arguments.
@@ -1562,7 +1558,7 @@
// between formal parameters and concrete arguments. This can only
// occur if the current function is a closure.
if (i != -1) {
- goto ClosureNoSuchMethod;
+ goto NoSuchMethodFromPrologue;
}
// Skip LoadConstant-s encoding information about named parameters.
@@ -1576,7 +1572,7 @@
// Function can't have both named and optional positional parameters.
// This kind of mismatch can only occur if the current function
// is a closure.
- goto ClosureNoSuchMethod;
+ goto NoSuchMethodFromPrologue;
}
// Process the list of default values encoded as a sequence of
@@ -1659,7 +1655,7 @@
const intptr_t type_args_len =
InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
if ((type_args_len != declared_type_args_len) && (type_args_len != 0)) {
- goto ClosureNoSuchMethod;
+ goto NoSuchMethodFromPrologue;
}
if (type_args_len > 0) {
// Decode arguments descriptor's argument count (excluding type args).
@@ -3362,11 +3358,10 @@
}
{
- BYTECODE(VMInternal_DispatchNoSuchMethod, 0);
+ BYTECODE(VMInternal_NoSuchMethodDispatcher, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) == RawFunction::kNoSuchMethodDispatcher);
- UNIMPLEMENTED();
- DISPATCH();
+ goto NoSuchMethodFromPrologue;
}
{
@@ -3444,62 +3439,47 @@
// Helper used to handle noSuchMethod on closures.
{
- ClosureNoSuchMethod:
-#if defined(DEBUG)
- function_h ^= FrameFunction(FP);
- ASSERT(function_h.IsNull() || function_h.IsClosureFunction());
-#endif
+ NoSuchMethodFromPrologue:
+ RawFunction* function = FrameFunction(FP);
- // Restore caller context as we are going to throw NoSuchMethod.
- pc = SavedCallerPC(FP);
-
- const bool has_dart_caller = !IsEntryFrameMarker(pc);
const intptr_t type_args_len =
InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
const intptr_t argc =
InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
+ RawObject** args = FrameArguments(FP, argc);
- SP = FrameArguments(FP, 0);
- RawObject** args = SP - argc;
- FP = SavedCallerFP(FP);
- NOT_IN_PRODUCT(fp_ = FP); // For the profiler.
- if (has_dart_caller) {
- pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_;
- }
-
- *++SP = null_value;
- *++SP = args[receiver_idx]; // Closure object.
- *++SP = argdesc_;
- *++SP = null_value; // Array of arguments (will be filled).
+ SP[1] = null_value;
+ SP[2] = args[receiver_idx];
+ SP[3] = function;
+ SP[4] = argdesc_;
+ SP[5] = null_value; // Array of arguments (will be filled).
// Allocate array of arguments.
{
- SP[1] = Smi::New(argc); // length
- SP[2] = null_value; // type
- Exit(thread, FP, SP + 3, pc);
- NativeArguments native_args(thread, 2, SP + 1, SP);
+ SP[6] = Smi::New(argc); // length
+ SP[7] = null_value; // type
+ Exit(thread, FP, SP + 8, pc);
+ NativeArguments native_args(thread, 2, SP + 6, SP + 5);
if (!InvokeRuntime(thread, this, DRT_AllocateArray, native_args)) {
HANDLE_EXCEPTION;
- } else if (has_dart_caller) {
- HANDLE_RETURN;
}
// Copy arguments into the newly allocated array.
- RawArray* array = static_cast<RawArray*>(SP[0]);
+ RawArray* array = static_cast<RawArray*>(SP[5]);
ASSERT(array->GetClassId() == kArrayCid);
for (intptr_t i = 0; i < argc; i++) {
array->ptr()->data()[i] = args[i];
}
}
- // Invoke noSuchMethod passing down closure, argument descriptor and
- // array of arguments.
+ // Invoke noSuchMethod passing down receiver, function, argument descriptor
+ // and array of arguments.
{
- Exit(thread, FP, SP + 1, pc);
- NativeArguments native_args(thread, 3, SP - 2, SP - 3);
- INVOKE_RUNTIME(DRT_InvokeClosureNoSuchMethod, native_args);
- UNREACHABLE();
+ Exit(thread, FP, SP + 6, pc);
+ NativeArguments native_args(thread, 4, SP + 2, SP + 1);
+ INVOKE_RUNTIME(DRT_NoSuchMethodFromPrologue, native_args);
+ ++SP; // Result at SP[0]
}
DISPATCH();
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index b77157f..e25bf06 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -947,6 +947,18 @@
invoke_field_bytecode_->set_exception_handlers(
Object::empty_exception_handlers());
+ static const KBCInstr nsm_dispatcher_instr[2] = {
+ KernelBytecode::Encode(
+ KernelBytecode::kVMInternal_NoSuchMethodDispatcher),
+ KernelBytecode::Encode(KernelBytecode::kReturnTOS),
+ };
+ *nsm_dispatcher_bytecode_ = Bytecode::New(
+ reinterpret_cast<uword>(nsm_dispatcher_instr),
+ sizeof(nsm_dispatcher_instr), -1, Object::empty_object_pool());
+ nsm_dispatcher_bytecode_->set_pc_descriptors(Object::empty_descriptors());
+ nsm_dispatcher_bytecode_->set_exception_handlers(
+ Object::empty_exception_handlers());
+
// Some thread fields need to be reinitialized as null constants have not been
// initialized until now.
Thread* thr = Thread::Current();
@@ -1016,6 +1028,8 @@
ASSERT(invoke_closure_bytecode_->IsBytecode());
ASSERT(!invoke_field_bytecode_->IsSmi());
ASSERT(invoke_field_bytecode_->IsBytecode());
+ ASSERT(!nsm_dispatcher_bytecode_->IsSmi());
+ ASSERT(nsm_dispatcher_bytecode_->IsBytecode());
}
void Object::FinishInit(Isolate* isolate) {
@@ -5732,7 +5746,6 @@
}
}
switch (kind()) {
- case RawFunction::kNoSuchMethodDispatcher:
case RawFunction::kDynamicInvocationForwarder:
case RawFunction::kImplicitClosureFunction:
case RawFunction::kIrregexpFunction:
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index bdf8c35..f0040cf 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -402,6 +402,7 @@
V(Bytecode, method_extractor_bytecode) \
V(Bytecode, invoke_closure_bytecode) \
V(Bytecode, invoke_field_bytecode) \
+ V(Bytecode, nsm_dispatcher_bytecode) \
V(Instance, sentinel) \
V(Instance, transition_sentinel) \
V(Instance, unknown_constant) \
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index da70f90..1f889cc 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1067,7 +1067,7 @@
result = target_function.raw();
}
// May be null if --no-lazy-dispatchers, in which case dispatch will be
- // handled by InvokeNoSuchMethodDispatcher.
+ // handled by NoSuchMethodFromCallStub.
ASSERT(!result.IsNull() || !FLAG_lazy_dispatchers);
return result.raw();
}
@@ -1670,7 +1670,7 @@
// Arg1: ICData or MegamorphicCache
// Arg2: arguments descriptor array
// Arg3: arguments array
-DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) {
+DEFINE_RUNTIME_ENTRY(NoSuchMethodFromCallStub, 4) {
ASSERT(!FLAG_lazy_dispatchers);
const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
const Object& ic_data_or_cache = Object::Handle(zone, arguments.ArgAt(1));
@@ -1778,24 +1778,31 @@
}
// Invoke appropriate noSuchMethod function.
-// Arg0: receiver (closure object)
+// Arg0: receiver
+// Arg1: function
// Arg1: arguments descriptor array.
-// Arg2: arguments array.
-DEFINE_RUNTIME_ENTRY(InvokeClosureNoSuchMethod, 3) {
- const Closure& receiver = Closure::CheckedHandle(zone, arguments.ArgAt(0));
+// Arg3: arguments array.
+DEFINE_RUNTIME_ENTRY(NoSuchMethodFromPrologue, 4) {
+ const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+ const Function& function = Function::CheckedHandle(zone, arguments.ArgAt(1));
const Array& orig_arguments_desc =
- Array::CheckedHandle(zone, arguments.ArgAt(1));
- const Array& orig_arguments = Array::CheckedHandle(zone, arguments.ArgAt(2));
+ Array::CheckedHandle(zone, arguments.ArgAt(2));
+ const Array& orig_arguments = Array::CheckedHandle(zone, arguments.ArgAt(3));
- // For closure the function name is always 'call'. Replace it with the
- // name of the closurized function so that exception contains more
- // relevant information.
- const Function& function = Function::Handle(receiver.function());
- ASSERT(!function.IsNull());
- const String& original_function_name =
- String::Handle(function.QualifiedUserVisibleName());
- const Object& result = Object::Handle(DartEntry::InvokeNoSuchMethod(
- receiver, original_function_name, orig_arguments, orig_arguments_desc));
+ String& orig_function_name = String::Handle(zone);
+ if ((function.kind() == RawFunction::kClosureFunction) ||
+ (function.kind() == RawFunction::kImplicitClosureFunction)) {
+ // For closure the function name is always 'call'. Replace it with the
+ // name of the closurized function so that exception contains more
+ // relevant information.
+ orig_function_name = function.QualifiedUserVisibleName();
+ } else {
+ orig_function_name = function.name();
+ }
+
+ const Object& result = Object::Handle(
+ zone, DartEntry::InvokeNoSuchMethod(receiver, orig_function_name,
+ orig_arguments, orig_arguments_desc));
ThrowIfError(result);
arguments.SetReturn(result);
}
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index 5ab459b..dd4159d 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -31,9 +31,9 @@
V(NonBoolTypeError) \
V(InstantiateType) \
V(InstantiateTypeArguments) \
- V(InvokeClosureNoSuchMethod) \
+ V(NoSuchMethodFromCallStub) \
+ V(NoSuchMethodFromPrologue) \
V(InvokeNoSuchMethod) \
- V(InvokeNoSuchMethodDispatcher) \
V(MegamorphicCacheMissHandler) \
V(OptimizeInvokedFunction) \
V(TraceICCall) \
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 6f2defd..9251eac 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -4095,8 +4095,11 @@
pp_ = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_;
}
+ RawClosure* closure =
+ Closure::RawCast(args[has_function_type_args ? 1 : 0]);
*++SP = null_value;
- *++SP = args[has_function_type_args ? 1 : 0]; // Closure object.
+ *++SP = closure;
+ *++SP = closure->ptr()->function_;
*++SP = argdesc_;
*++SP = null_value; // Array of arguments (will be filled).
@@ -4124,8 +4127,8 @@
// array of arguments.
{
Exit(thread, FP, SP + 1, pc);
- NativeArguments native_args(thread, 3, SP - 2, SP - 3);
- INVOKE_RUNTIME(DRT_InvokeClosureNoSuchMethod, native_args);
+ NativeArguments native_args(thread, 4, SP - 3, SP - 4);
+ INVOKE_RUNTIME(DRT_NoSuchMethodFromPrologue, native_args);
UNREACHABLE();
}
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index 9b89101..fa77c7d 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -306,7 +306,7 @@
" * dart frame corresponding to StackFrame.frameCount"
" * dart frame corresponding to StackFrame2Test.noSuchMethod"
" * entry frame"
- " * exit frame (call to runtime InvokeNoSuchMethodDispatcher)"
+ " * exit frame (call to runtime NoSuchMethodFromCallStub)"
" * IC stub"
" * dart frame corresponding to StackFrame2Test.testMain"
" * entry frame"