[builtins] Separate Array.prototype.* CSA builtins into two parts
Previous to this CL, CSA-optimized Array builtins--like forEach, some, and every--were written in a single, monolithic block of CSA code. This CL teases the code for each of these builtins apart into two chunks, a main body with optimizations for fast cases, and a "continuation" builtin that performs a spec-compliant, but slower version of the main loop of the builtin. The general idea is that when the "fast" main body builtin encounters an unexpected condition that invalidates assumptions allowing fast-case code, it tail calls to the slow, correct version of the loop that finishes the builtin execution. This separation currently doens't really provide any specific advantage over the combined version. However, it paves the way to TF-optimized inlined Array builtins. Inlined Array builtins may trigger deopts during the execution of the builtin's loop, and those deopt must continue execution from the point at which they failed. With some massaging of the deoptimizer, it will be possible to make those deopt points create an extra frame on the top of the stack which resumes execution in the slow-loop builtin created in this CL. BUG=v8:1956 LOG=N Review-Url: https://codereview.chromium.org/2753793002 Cr-Commit-Position: refs/heads/master@{#43867}
This commit is contained in:
parent
947a043766
commit
7de21c4d3b
@ -18,10 +18,16 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
|
||||
typedef std::function<void(Node* a, Node* pK, Node* value)>
|
||||
CallResultProcessor;
|
||||
|
||||
void GenerateArrayIteratingBuiltinBody(
|
||||
const char* name, Node* receiver, Node* callbackfn, Node* this_arg,
|
||||
Node* context, const BuiltinResultGenerator& generator,
|
||||
const CallResultProcessor& processor) {
|
||||
void GenerateIteratingArrayBuiltinBody(
|
||||
const char* name, const BuiltinResultGenerator& generator,
|
||||
const CallResultProcessor& processor,
|
||||
const Callable& slow_case_continuation) {
|
||||
Node* receiver = Parameter(IteratingArrayBuiltinDescriptor::kReceiver);
|
||||
Node* callbackfn = Parameter(IteratingArrayBuiltinDescriptor::kCallback);
|
||||
Node* this_arg = Parameter(IteratingArrayBuiltinDescriptor::kThisArg);
|
||||
Node* context = Parameter(IteratingArrayBuiltinDescriptor::kContext);
|
||||
Node* new_target = Parameter(IteratingArrayBuiltinDescriptor::kNewTarget);
|
||||
|
||||
Variable k(this, MachineRepresentation::kTagged, SmiConstant(0));
|
||||
Label non_array(this), slow(this, &k), array_changes(this, &k);
|
||||
|
||||
@ -91,47 +97,89 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
|
||||
// Already done above in initialization of the Variable k
|
||||
|
||||
Bind(&slow);
|
||||
|
||||
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
|
||||
MachineType::TaggedPointer());
|
||||
TailCallStub(
|
||||
slow_case_continuation, context, target, new_target,
|
||||
Int32Constant(IteratingArrayBuiltinLoopContinuationDescriptor::kArity),
|
||||
receiver, callbackfn, this_arg, a, o, k.value(), len);
|
||||
}
|
||||
|
||||
void GenerateIteratingArrayBuiltinLoopContinuation(
|
||||
const CallResultProcessor& processor) {
|
||||
Node* callbackfn =
|
||||
Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kCallback);
|
||||
Node* this_arg =
|
||||
Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kThisArg);
|
||||
Node* a =
|
||||
Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kArray);
|
||||
Node* o =
|
||||
Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kObject);
|
||||
Node* initial_k =
|
||||
Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kInitialK);
|
||||
Node* len =
|
||||
Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kLength);
|
||||
Node* context =
|
||||
Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kContext);
|
||||
|
||||
// 8. Repeat, while k < len
|
||||
Variable k(this, MachineRepresentation::kTagged, initial_k);
|
||||
Label loop(this, &k);
|
||||
Label after_loop(this);
|
||||
Goto(&loop);
|
||||
Bind(&loop);
|
||||
{
|
||||
// 8. Repeat, while k < len
|
||||
Label loop(this, &k);
|
||||
Label after_loop(this);
|
||||
GotoUnlessNumberLessThan(k.value(), len, &after_loop);
|
||||
|
||||
Label done_element(this);
|
||||
// a. Let Pk be ToString(k).
|
||||
Node* p_k = ToString(context, k.value());
|
||||
|
||||
// b. Let kPresent be HasProperty(O, Pk).
|
||||
// c. ReturnIfAbrupt(kPresent).
|
||||
Node* k_present = HasProperty(o, p_k, context);
|
||||
|
||||
// d. If kPresent is true, then
|
||||
GotoIf(WordNotEqual(k_present, TrueConstant()), &done_element);
|
||||
|
||||
// i. Let kValue be Get(O, Pk).
|
||||
// ii. ReturnIfAbrupt(kValue).
|
||||
Node* k_value = GetProperty(context, o, k.value());
|
||||
|
||||
// iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»).
|
||||
// iv. ReturnIfAbrupt(funcResult).
|
||||
Node* result = CallJS(CodeFactory::Call(isolate()), context, callbackfn,
|
||||
this_arg, k_value, k.value(), o);
|
||||
|
||||
processor(a, p_k, result);
|
||||
Goto(&done_element);
|
||||
Bind(&done_element);
|
||||
|
||||
// e. Increase k by 1.
|
||||
k.Bind(NumberInc(k.value()));
|
||||
Goto(&loop);
|
||||
Bind(&loop);
|
||||
{
|
||||
GotoUnlessNumberLessThan(k.value(), len, &after_loop);
|
||||
|
||||
Label done_element(this);
|
||||
// a. Let Pk be ToString(k).
|
||||
Node* p_k = ToString(context, k.value());
|
||||
|
||||
// b. Let kPresent be HasProperty(O, Pk).
|
||||
// c. ReturnIfAbrupt(kPresent).
|
||||
Node* k_present =
|
||||
CallStub(CodeFactory::HasProperty(isolate()), context, p_k, o);
|
||||
|
||||
// d. If kPresent is true, then
|
||||
GotoIf(WordNotEqual(k_present, TrueConstant()), &done_element);
|
||||
|
||||
// i. Let kValue be Get(O, Pk).
|
||||
// ii. ReturnIfAbrupt(kValue).
|
||||
Node* k_value = GetProperty(context, o, k.value());
|
||||
|
||||
// iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»).
|
||||
// iv. ReturnIfAbrupt(funcResult).
|
||||
Node* result = CallJS(CodeFactory::Call(isolate()), context, callbackfn,
|
||||
this_arg, k_value, k.value(), o);
|
||||
|
||||
processor(a, p_k, result);
|
||||
Goto(&done_element);
|
||||
Bind(&done_element);
|
||||
|
||||
// e. Increase k by 1.
|
||||
k.Bind(NumberInc(k.value()));
|
||||
Goto(&loop);
|
||||
}
|
||||
Bind(&after_loop);
|
||||
Return(a);
|
||||
}
|
||||
Bind(&after_loop);
|
||||
Return(a);
|
||||
}
|
||||
|
||||
void ForEachProcessor(Node* a, Node* p_k, Node* value) {}
|
||||
|
||||
void SomeProcessor(Node* a, Node* p_k, Node* value) {
|
||||
Label false_continue(this), return_true(this);
|
||||
BranchIfToBooleanIsTrue(value, &return_true, &false_continue);
|
||||
Bind(&return_true);
|
||||
Return(TrueConstant());
|
||||
Bind(&false_continue);
|
||||
}
|
||||
|
||||
void EveryProcessor(Node* a, Node* p_k, Node* value) {
|
||||
Label true_continue(this), return_false(this);
|
||||
BranchIfToBooleanIsTrue(value, &true_continue, &return_false);
|
||||
Bind(&return_false);
|
||||
Return(FalseConstant());
|
||||
Bind(&true_continue);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -414,54 +462,53 @@ TF_BUILTIN(FastArrayPush, CodeStubAssembler) {
|
||||
}
|
||||
}
|
||||
|
||||
TF_BUILTIN(ArrayForEach, ArrayBuiltinCodeStubAssembler) {
|
||||
Node* receiver = Parameter(ForEachDescriptor::kReceiver);
|
||||
Node* callbackfn = Parameter(ForEachDescriptor::kCallback);
|
||||
Node* this_arg = Parameter(ForEachDescriptor::kThisArg);
|
||||
Node* context = Parameter(ForEachDescriptor::kContext);
|
||||
|
||||
GenerateArrayIteratingBuiltinBody(
|
||||
"Array.prototype.forEach", receiver, callbackfn, this_arg, context,
|
||||
[=](Node*, Node*) { return UndefinedConstant(); },
|
||||
[](Node* a, Node* p_k, Node* value) {});
|
||||
TF_BUILTIN(ArrayForEachLoopContinuation, ArrayBuiltinCodeStubAssembler) {
|
||||
GenerateIteratingArrayBuiltinLoopContinuation(
|
||||
[this](Node* a, Node* p_k, Node* value) {
|
||||
ForEachProcessor(a, p_k, value);
|
||||
});
|
||||
}
|
||||
|
||||
TF_BUILTIN(ArrayEvery, ArrayBuiltinCodeStubAssembler) {
|
||||
Node* receiver = Parameter(ForEachDescriptor::kReceiver);
|
||||
Node* callbackfn = Parameter(ForEachDescriptor::kCallback);
|
||||
Node* this_arg = Parameter(ForEachDescriptor::kThisArg);
|
||||
Node* context = Parameter(ForEachDescriptor::kContext);
|
||||
TF_BUILTIN(ArrayForEach, ArrayBuiltinCodeStubAssembler) {
|
||||
GenerateIteratingArrayBuiltinBody(
|
||||
"Array.prototype.forEach",
|
||||
[=](Node*, Node*) { return UndefinedConstant(); },
|
||||
[this](Node* a, Node* p_k, Node* value) {
|
||||
ForEachProcessor(a, p_k, value);
|
||||
},
|
||||
CodeFactory::ArrayForEachLoopContinuation(isolate()));
|
||||
}
|
||||
|
||||
GenerateArrayIteratingBuiltinBody(
|
||||
"Array.prototype.every", receiver, callbackfn, this_arg, context,
|
||||
[=](Node*, Node*) { return TrueConstant(); },
|
||||
[=](Node* a, Node* p_k, Node* value) {
|
||||
Label true_continue(this), return_false(this);
|
||||
BranchIfToBooleanIsTrue(value, &true_continue, &return_false);
|
||||
Bind(&return_false);
|
||||
Return(FalseConstant());
|
||||
Bind(&true_continue);
|
||||
TF_BUILTIN(ArraySomeLoopContinuation, ArrayBuiltinCodeStubAssembler) {
|
||||
GenerateIteratingArrayBuiltinLoopContinuation(
|
||||
[this](Node* a, Node* p_k, Node* value) {
|
||||
SomeProcessor(a, p_k, value);
|
||||
});
|
||||
}
|
||||
|
||||
TF_BUILTIN(ArraySome, ArrayBuiltinCodeStubAssembler) {
|
||||
Node* receiver = Parameter(ForEachDescriptor::kReceiver);
|
||||
Node* callbackfn = Parameter(ForEachDescriptor::kCallback);
|
||||
Node* this_arg = Parameter(ForEachDescriptor::kThisArg);
|
||||
Node* context = Parameter(ForEachDescriptor::kContext);
|
||||
GenerateIteratingArrayBuiltinBody(
|
||||
"Array.prototype.some", [=](Node*, Node*) { return FalseConstant(); },
|
||||
[this](Node* a, Node* p_k, Node* value) { SomeProcessor(a, p_k, value); },
|
||||
CodeFactory::ArraySomeLoopContinuation(isolate()));
|
||||
}
|
||||
|
||||
GenerateArrayIteratingBuiltinBody(
|
||||
"Array.prototype.some", receiver, callbackfn, this_arg, context,
|
||||
[=](Node*, Node*) { return FalseConstant(); },
|
||||
[=](Node* a, Node* p_k, Node* value) {
|
||||
Label false_continue(this), return_true(this);
|
||||
BranchIfToBooleanIsTrue(value, &return_true, &false_continue);
|
||||
Bind(&return_true);
|
||||
Return(TrueConstant());
|
||||
Bind(&false_continue);
|
||||
TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) {
|
||||
GenerateIteratingArrayBuiltinLoopContinuation(
|
||||
[this](Node* a, Node* p_k, Node* value) {
|
||||
EveryProcessor(a, p_k, value);
|
||||
});
|
||||
}
|
||||
|
||||
TF_BUILTIN(ArrayEvery, ArrayBuiltinCodeStubAssembler) {
|
||||
GenerateIteratingArrayBuiltinBody(
|
||||
"Array.prototype.every", [=](Node*, Node*) { return TrueConstant(); },
|
||||
[this](Node* a, Node* p_k, Node* value) {
|
||||
EveryProcessor(a, p_k, value);
|
||||
},
|
||||
CodeFactory::ArrayEveryLoopContinuation(isolate()));
|
||||
}
|
||||
|
||||
TF_BUILTIN(ArrayIsArray, CodeStubAssembler) {
|
||||
Node* object = Parameter(1);
|
||||
Node* context = Parameter(4);
|
||||
|
@ -277,6 +277,9 @@ class Isolate;
|
||||
CPP(ArraySlice) \
|
||||
CPP(ArraySplice) \
|
||||
CPP(ArrayUnshift) \
|
||||
TFJ(ArrayForEachLoopContinuation, 6) \
|
||||
TFJ(ArrayEveryLoopContinuation, 6) \
|
||||
TFJ(ArraySomeLoopContinuation, 6) \
|
||||
TFJ(ArrayForEach, 2) \
|
||||
TFJ(ArrayEvery, 2) \
|
||||
TFJ(ArraySome, 2) \
|
||||
|
@ -508,6 +508,24 @@ Callable CodeFactory::ArrayPush(Isolate* isolate) {
|
||||
return Callable(isolate->builtins()->ArrayPush(), BuiltinDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ArrayForEachLoopContinuation(Isolate* isolate) {
|
||||
return Callable(isolate->builtins()->ArrayForEachLoopContinuation(),
|
||||
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ArraySomeLoopContinuation(Isolate* isolate) {
|
||||
return Callable(isolate->builtins()->ArraySomeLoopContinuation(),
|
||||
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::ArrayEveryLoopContinuation(Isolate* isolate) {
|
||||
return Callable(isolate->builtins()->ArrayEveryLoopContinuation(),
|
||||
IteratingArrayBuiltinLoopContinuationDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::FunctionPrototypeBind(Isolate* isolate) {
|
||||
return Callable(isolate->builtins()->FunctionPrototypeBind(),
|
||||
|
@ -180,6 +180,9 @@ class V8_EXPORT_PRIVATE CodeFactory final {
|
||||
|
||||
static Callable ArrayConstructor(Isolate* isolate);
|
||||
static Callable ArrayPush(Isolate* isolate);
|
||||
static Callable ArrayForEachLoopContinuation(Isolate* isolate);
|
||||
static Callable ArraySomeLoopContinuation(Isolate* isolate);
|
||||
static Callable ArrayEveryLoopContinuation(Isolate* isolate);
|
||||
static Callable FunctionPrototypeBind(Isolate* isolate);
|
||||
static Callable PromiseHandleReject(Isolate* isolate);
|
||||
};
|
||||
|
@ -31,6 +31,9 @@
|
||||
#define REPEAT_1_TO_7(V, T) REPEAT_1_TO_6(V, T) V(T, T, T, T, T, T, T)
|
||||
#define REPEAT_1_TO_8(V, T) REPEAT_1_TO_7(V, T) V(T, T, T, T, T, T, T, T)
|
||||
#define REPEAT_1_TO_9(V, T) REPEAT_1_TO_8(V, T) V(T, T, T, T, T, T, T, T, T)
|
||||
#define REPEAT_1_TO_10(V, T) REPEAT_1_TO_9(V, T) V(T, T, T, T, T, T, T, T, T, T)
|
||||
#define REPEAT_1_TO_11(V, T) \
|
||||
REPEAT_1_TO_10(V, T) V(T, T, T, T, T, T, T, T, T, T, T)
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -532,7 +535,7 @@ Node* CodeAssembler::CallRuntime(Runtime::FunctionId function, Node* context,
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// Instantiate CallRuntime() with up to 6 arguments.
|
||||
// Instantiate CallRuntime() for argument counts used by CSA-generated code
|
||||
#define INSTANTIATE(...) \
|
||||
template V8_EXPORT_PRIVATE Node* CodeAssembler::CallRuntime( \
|
||||
Runtime::FunctionId, __VA_ARGS__);
|
||||
@ -558,7 +561,7 @@ Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function,
|
||||
return raw_assembler()->TailCallN(desc, arraysize(nodes), nodes);
|
||||
}
|
||||
|
||||
// Instantiate TailCallRuntime() with up to 6 arguments.
|
||||
// Instantiate TailCallRuntime() for argument counts used by CSA-generated code
|
||||
#define INSTANTIATE(...) \
|
||||
template V8_EXPORT_PRIVATE Node* CodeAssembler::TailCallRuntime( \
|
||||
Runtime::FunctionId, __VA_ARGS__);
|
||||
@ -573,7 +576,7 @@ Node* CodeAssembler::CallStubR(const CallInterfaceDescriptor& descriptor,
|
||||
return CallStubN(descriptor, result_size, arraysize(nodes), nodes);
|
||||
}
|
||||
|
||||
// Instantiate CallStubR() with up to 6 arguments.
|
||||
// Instantiate CallStubR() for argument counts used by CSA-generated code.
|
||||
#define INSTANTIATE(...) \
|
||||
template V8_EXPORT_PRIVATE Node* CodeAssembler::CallStubR( \
|
||||
const CallInterfaceDescriptor& descriptor, size_t, Node*, __VA_ARGS__);
|
||||
@ -612,15 +615,15 @@ Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
|
||||
MachineType::AnyTagged(), result_size);
|
||||
|
||||
Node* nodes[] = {target, args..., context};
|
||||
|
||||
CHECK_EQ(descriptor.GetParameterCount() + 2, arraysize(nodes));
|
||||
return raw_assembler()->TailCallN(desc, arraysize(nodes), nodes);
|
||||
}
|
||||
|
||||
// Instantiate TailCallStub() with up to 6 arguments.
|
||||
// Instantiate TailCallStub() for argument counts used by CSA-generated code
|
||||
#define INSTANTIATE(...) \
|
||||
template V8_EXPORT_PRIVATE Node* CodeAssembler::TailCallStub( \
|
||||
const CallInterfaceDescriptor& descriptor, Node*, __VA_ARGS__);
|
||||
REPEAT_1_TO_7(INSTANTIATE, Node*)
|
||||
REPEAT_1_TO_11(INSTANTIATE, Node*)
|
||||
#undef INSTANTIATE
|
||||
|
||||
template <class... TArgs>
|
||||
@ -631,10 +634,12 @@ Node* CodeAssembler::TailCallBytecodeDispatch(
|
||||
isolate(), zone(), descriptor, descriptor.GetStackParameterCount());
|
||||
|
||||
Node* nodes[] = {target, args...};
|
||||
CHECK_EQ(descriptor.GetParameterCount() + 1, arraysize(nodes));
|
||||
return raw_assembler()->TailCallN(desc, arraysize(nodes), nodes);
|
||||
}
|
||||
|
||||
// Instantiate TailCallBytecodeDispatch() with 4 arguments.
|
||||
// Instantiate TailCallBytecodeDispatch() for argument counts used by
|
||||
// CSA-generated code
|
||||
template V8_EXPORT_PRIVATE Node* CodeAssembler::TailCallBytecodeDispatch(
|
||||
const CallInterfaceDescriptor& descriptor, Node* target, Node*, Node*,
|
||||
Node*, Node*);
|
||||
|
@ -16,86 +16,87 @@ namespace internal {
|
||||
|
||||
class PlatformInterfaceDescriptor;
|
||||
|
||||
#define INTERFACE_DESCRIPTOR_LIST(V) \
|
||||
V(Void) \
|
||||
V(ContextOnly) \
|
||||
V(Load) \
|
||||
V(LoadWithVector) \
|
||||
V(LoadField) \
|
||||
V(LoadICProtoArray) \
|
||||
V(LoadGlobal) \
|
||||
V(LoadGlobalWithVector) \
|
||||
V(Store) \
|
||||
V(StoreWithVector) \
|
||||
V(StoreNamedTransition) \
|
||||
V(StoreTransition) \
|
||||
V(VarArgFunction) \
|
||||
V(FastNewClosure) \
|
||||
V(FastNewFunctionContext) \
|
||||
V(FastNewObject) \
|
||||
V(FastNewArguments) \
|
||||
V(TypeConversion) \
|
||||
V(Typeof) \
|
||||
V(FastCloneRegExp) \
|
||||
V(FastCloneShallowArray) \
|
||||
V(FastCloneShallowObject) \
|
||||
V(CreateAllocationSite) \
|
||||
V(CreateWeakCell) \
|
||||
V(CallFunction) \
|
||||
V(CallIC) \
|
||||
V(CallICTrampoline) \
|
||||
V(CallForwardVarargs) \
|
||||
V(CallConstruct) \
|
||||
V(CallTrampoline) \
|
||||
V(ConstructStub) \
|
||||
V(ConstructTrampoline) \
|
||||
V(RegExpExec) \
|
||||
V(RegExpReplace) \
|
||||
V(RegExpSplit) \
|
||||
V(CopyFastSmiOrObjectElements) \
|
||||
V(TransitionElementsKind) \
|
||||
V(AllocateHeapNumber) \
|
||||
V(Builtin) \
|
||||
V(ArrayConstructor) \
|
||||
V(ForEach) \
|
||||
V(ArrayNoArgumentConstructor) \
|
||||
V(ArraySingleArgumentConstructor) \
|
||||
V(ArrayNArgumentsConstructor) \
|
||||
V(Compare) \
|
||||
V(BinaryOp) \
|
||||
V(BinaryOpWithAllocationSite) \
|
||||
V(BinaryOpWithVector) \
|
||||
V(CountOp) \
|
||||
V(StringAdd) \
|
||||
V(StringCharAt) \
|
||||
V(StringCharCodeAt) \
|
||||
V(StringCompare) \
|
||||
V(StringIndexOf) \
|
||||
V(SubString) \
|
||||
V(Keyed) \
|
||||
V(Named) \
|
||||
V(CreateIterResultObject) \
|
||||
V(HasProperty) \
|
||||
V(ForInFilter) \
|
||||
V(ForInNext) \
|
||||
V(ForInPrepare) \
|
||||
V(GetProperty) \
|
||||
V(CallHandler) \
|
||||
V(ArgumentAdaptor) \
|
||||
V(ApiCallback) \
|
||||
V(ApiGetter) \
|
||||
V(MathPowTagged) \
|
||||
V(MathPowInteger) \
|
||||
V(GrowArrayElements) \
|
||||
V(NewArgumentsElements) \
|
||||
V(InterpreterDispatch) \
|
||||
V(InterpreterPushArgsAndCall) \
|
||||
V(InterpreterPushArgsAndConstruct) \
|
||||
V(InterpreterPushArgsAndConstructArray) \
|
||||
V(InterpreterCEntry) \
|
||||
V(ResumeGenerator) \
|
||||
V(FrameDropperTrampoline) \
|
||||
V(PromiseHandleReject) \
|
||||
#define INTERFACE_DESCRIPTOR_LIST(V) \
|
||||
V(Void) \
|
||||
V(ContextOnly) \
|
||||
V(Load) \
|
||||
V(LoadWithVector) \
|
||||
V(LoadField) \
|
||||
V(LoadICProtoArray) \
|
||||
V(LoadGlobal) \
|
||||
V(LoadGlobalWithVector) \
|
||||
V(Store) \
|
||||
V(StoreWithVector) \
|
||||
V(StoreNamedTransition) \
|
||||
V(StoreTransition) \
|
||||
V(VarArgFunction) \
|
||||
V(FastNewClosure) \
|
||||
V(FastNewFunctionContext) \
|
||||
V(FastNewObject) \
|
||||
V(FastNewArguments) \
|
||||
V(TypeConversion) \
|
||||
V(Typeof) \
|
||||
V(FastCloneRegExp) \
|
||||
V(FastCloneShallowArray) \
|
||||
V(FastCloneShallowObject) \
|
||||
V(CreateAllocationSite) \
|
||||
V(CreateWeakCell) \
|
||||
V(CallFunction) \
|
||||
V(CallIC) \
|
||||
V(CallICTrampoline) \
|
||||
V(CallForwardVarargs) \
|
||||
V(CallConstruct) \
|
||||
V(CallTrampoline) \
|
||||
V(ConstructStub) \
|
||||
V(ConstructTrampoline) \
|
||||
V(RegExpExec) \
|
||||
V(RegExpReplace) \
|
||||
V(RegExpSplit) \
|
||||
V(CopyFastSmiOrObjectElements) \
|
||||
V(TransitionElementsKind) \
|
||||
V(AllocateHeapNumber) \
|
||||
V(Builtin) \
|
||||
V(ArrayConstructor) \
|
||||
V(IteratingArrayBuiltin) \
|
||||
V(IteratingArrayBuiltinLoopContinuation) \
|
||||
V(ArrayNoArgumentConstructor) \
|
||||
V(ArraySingleArgumentConstructor) \
|
||||
V(ArrayNArgumentsConstructor) \
|
||||
V(Compare) \
|
||||
V(BinaryOp) \
|
||||
V(BinaryOpWithAllocationSite) \
|
||||
V(BinaryOpWithVector) \
|
||||
V(CountOp) \
|
||||
V(StringAdd) \
|
||||
V(StringCharAt) \
|
||||
V(StringCharCodeAt) \
|
||||
V(StringCompare) \
|
||||
V(StringIndexOf) \
|
||||
V(SubString) \
|
||||
V(Keyed) \
|
||||
V(Named) \
|
||||
V(CreateIterResultObject) \
|
||||
V(HasProperty) \
|
||||
V(ForInFilter) \
|
||||
V(ForInNext) \
|
||||
V(ForInPrepare) \
|
||||
V(GetProperty) \
|
||||
V(CallHandler) \
|
||||
V(ArgumentAdaptor) \
|
||||
V(ApiCallback) \
|
||||
V(ApiGetter) \
|
||||
V(MathPowTagged) \
|
||||
V(MathPowInteger) \
|
||||
V(GrowArrayElements) \
|
||||
V(NewArgumentsElements) \
|
||||
V(InterpreterDispatch) \
|
||||
V(InterpreterPushArgsAndCall) \
|
||||
V(InterpreterPushArgsAndConstruct) \
|
||||
V(InterpreterPushArgsAndConstructArray) \
|
||||
V(InterpreterCEntry) \
|
||||
V(ResumeGenerator) \
|
||||
V(FrameDropperTrampoline) \
|
||||
V(PromiseHandleReject) \
|
||||
V(WasmRuntimeCall)
|
||||
|
||||
class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
|
||||
@ -286,39 +287,38 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
|
||||
kContext = kParameterCount /* implicit parameter */ \
|
||||
};
|
||||
|
||||
#define DECLARE_BUILTIN_DESCRIPTOR(name) \
|
||||
DECLARE_DESCRIPTOR_WITH_BASE(name, BuiltinDescriptor) \
|
||||
protected: \
|
||||
void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
|
||||
override { \
|
||||
MachineType machine_types[] = {MachineType::AnyTagged(), \
|
||||
MachineType::AnyTagged(), \
|
||||
MachineType::Int32()}; \
|
||||
int argc = kStackParameterCount + 1 - arraysize(machine_types); \
|
||||
data->InitializePlatformIndependent(arraysize(machine_types), argc, \
|
||||
machine_types); \
|
||||
} \
|
||||
void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \
|
||||
override { \
|
||||
Register registers[] = {TargetRegister(), NewTargetRegister(), \
|
||||
ArgumentsCountRegister()}; \
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers); \
|
||||
} \
|
||||
\
|
||||
#define DECLARE_BUILTIN_DESCRIPTOR(name) \
|
||||
DECLARE_DESCRIPTOR_WITH_BASE(name, BuiltinDescriptor) \
|
||||
protected: \
|
||||
void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
|
||||
override { \
|
||||
MachineType machine_types[] = {MachineType::AnyTagged(), \
|
||||
MachineType::AnyTagged(), \
|
||||
MachineType::Int32()}; \
|
||||
data->InitializePlatformIndependent(arraysize(machine_types), \
|
||||
kStackParameterCount, machine_types); \
|
||||
} \
|
||||
void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \
|
||||
override { \
|
||||
Register registers[] = {TargetRegister(), NewTargetRegister(), \
|
||||
ArgumentsCountRegister()}; \
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers); \
|
||||
} \
|
||||
\
|
||||
public:
|
||||
|
||||
#define DEFINE_BUILTIN_PARAMETERS(...) \
|
||||
enum ParameterIndices { \
|
||||
kReceiver, \
|
||||
kBeforeFirstStackParameter = kReceiver, \
|
||||
__VA_ARGS__, \
|
||||
kAfterLastStackParameter, \
|
||||
kNewTarget = kAfterLastStackParameter, \
|
||||
kArgumentsCount, \
|
||||
kContext, /* implicit parameter */ \
|
||||
kParameterCount = kContext, \
|
||||
kStackParameterCount = \
|
||||
kAfterLastStackParameter - kBeforeFirstStackParameter - 1, \
|
||||
#define DEFINE_BUILTIN_PARAMETERS(...) \
|
||||
enum ParameterIndices { \
|
||||
kReceiver, \
|
||||
kBeforeFirstStackParameter = kReceiver, \
|
||||
__VA_ARGS__, \
|
||||
kAfterLastStackParameter, \
|
||||
kNewTarget = kAfterLastStackParameter, \
|
||||
kArgumentsCount, \
|
||||
kContext, /* implicit parameter */ \
|
||||
kParameterCount = kContext, \
|
||||
kArity = kAfterLastStackParameter - kBeforeFirstStackParameter - 1, \
|
||||
kStackParameterCount = kArity + 1 \
|
||||
};
|
||||
|
||||
class VoidDescriptor : public CallInterfaceDescriptor {
|
||||
@ -702,10 +702,18 @@ class BuiltinDescriptor : public CallInterfaceDescriptor {
|
||||
static const Register TargetRegister();
|
||||
};
|
||||
|
||||
class ForEachDescriptor : public BuiltinDescriptor {
|
||||
class IteratingArrayBuiltinDescriptor : public BuiltinDescriptor {
|
||||
public:
|
||||
DEFINE_BUILTIN_PARAMETERS(kCallback, kThisArg)
|
||||
DECLARE_BUILTIN_DESCRIPTOR(ForEachDescriptor)
|
||||
DECLARE_BUILTIN_DESCRIPTOR(IteratingArrayBuiltinDescriptor)
|
||||
};
|
||||
|
||||
class IteratingArrayBuiltinLoopContinuationDescriptor
|
||||
: public BuiltinDescriptor {
|
||||
public:
|
||||
DEFINE_BUILTIN_PARAMETERS(kCallback, kThisArg, kArray, kObject, kInitialK,
|
||||
kLength)
|
||||
DECLARE_BUILTIN_DESCRIPTOR(IteratingArrayBuiltinLoopContinuationDescriptor)
|
||||
};
|
||||
|
||||
class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
|
||||
|
Loading…
Reference in New Issue
Block a user