Commit 79fe6e3e authored by jgruber's avatar jgruber Committed by Commit Bot

[generator] Don't adapt arguments for next/return/throw

Mechanical change to remove argument adaption (should be a tad faster
this way). Especially next is called without arguments in the common
case.

Bug: v8:6354, v8:6369
Change-Id: I4180caabfc4c1bbf1a10a881dcbcd41e03614b27
Reviewed-on: https://chromium-review.googlesource.com/535453
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarCaitlin Potter <caitp@igalia.com>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46000}
parent a1baf265
......@@ -742,17 +742,17 @@ void Genesis::CreateIteratorMaps(Handle<JSFunction> empty) {
factory()->NewStringFromAsciiChecked("Generator"),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
SimpleInstallFunction(generator_object_prototype, "next",
Builtins::kGeneratorPrototypeNext, 1, true);
Builtins::kGeneratorPrototypeNext, 1, false);
SimpleInstallFunction(generator_object_prototype, "return",
Builtins::kGeneratorPrototypeReturn, 1, true);
Builtins::kGeneratorPrototypeReturn, 1, false);
SimpleInstallFunction(generator_object_prototype, "throw",
Builtins::kGeneratorPrototypeThrow, 1, true);
Builtins::kGeneratorPrototypeThrow, 1, false);
// Internal version of generator_prototype_next, flagged as non-native such
// that it doesn't show up in Error traces.
Handle<JSFunction> generator_next_internal =
SimpleCreateFunction(isolate(), factory()->next_string(),
Builtins::kGeneratorPrototypeNext, 1, true);
Builtins::kGeneratorPrototypeNext, 1, false);
generator_next_internal->shared()->set_native(false);
native_context()->set_generator_next_internal(*generator_next_internal);
......@@ -852,11 +852,11 @@ void Genesis::CreateAsyncIteratorMaps(Handle<JSFunction> empty) {
factory()->NewStringFromAsciiChecked("AsyncGenerator"),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
SimpleInstallFunction(async_generator_object_prototype, "next",
Builtins::kAsyncGeneratorPrototypeNext, 1, true);
Builtins::kAsyncGeneratorPrototypeNext, 1, false);
SimpleInstallFunction(async_generator_object_prototype, "return",
Builtins::kAsyncGeneratorPrototypeReturn, 1, true);
Builtins::kAsyncGeneratorPrototypeReturn, 1, false);
SimpleInstallFunction(async_generator_object_prototype, "throw",
Builtins::kAsyncGeneratorPrototypeThrow, 1, true);
Builtins::kAsyncGeneratorPrototypeThrow, 1, false);
// Create maps for generator functions and their prototypes. Store those
// maps in the native context. The "prototype" property descriptor is
......
......@@ -113,7 +113,8 @@ class AsyncGeneratorBuiltinsAssembler : public AsyncBuiltinsAssembler {
return SmiNotEqual(resume_type, SmiConstant(JSGeneratorObject::kNext));
}
void AsyncGeneratorEnqueue(Node* context, Node* generator, Node* value,
void AsyncGeneratorEnqueue(CodeStubArguments* args, Node* context,
Node* generator, Node* value,
JSAsyncGeneratorObject::ResumeMode resume_mode,
const char* method_name);
......@@ -138,7 +139,7 @@ class AsyncGeneratorBuiltinsAssembler : public AsyncBuiltinsAssembler {
// Shared implementation for the 3 Async Iterator protocol methods of Async
// Generators.
void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue(
Node* context, Node* generator, Node* value,
CodeStubArguments* args, Node* context, Node* generator, Node* value,
JSAsyncGeneratorObject::ResumeMode resume_mode, const char* method_name) {
// AsyncGeneratorEnqueue produces a new Promise, and appends it to the list
// of async generator requests to be executed. If the generator is not
......@@ -175,7 +176,7 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue(
Goto(&done);
BIND(&done);
Return(promise);
args->PopAndReturn(promise);
}
BIND(&if_receiverisincompatible);
......@@ -186,7 +187,7 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue(
CallBuiltin(Builtins::kRejectNativePromise, context, promise, error,
TrueConstant());
Return(promise);
args->PopAndReturn(promise);
}
}
......@@ -329,10 +330,17 @@ Node* AsyncGeneratorBuiltinsAssembler::TakeFirstAsyncGeneratorRequestFromQueue(
// https://tc39.github.io/proposal-async-iteration/
// Section #sec-asyncgenerator-prototype-next
TF_BUILTIN(AsyncGeneratorPrototypeNext, AsyncGeneratorBuiltinsAssembler) {
Node* const generator = Parameter(Descriptor::kReceiver);
Node* const value = Parameter(Descriptor::kValue);
Node* const context = Parameter(Descriptor::kContext);
AsyncGeneratorEnqueue(context, generator, value,
const int kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* generator = args.GetReceiver();
Node* value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
AsyncGeneratorEnqueue(&args, context, generator, value,
JSAsyncGeneratorObject::kNext,
"[AsyncGenerator].prototype.next");
}
......@@ -340,10 +348,17 @@ TF_BUILTIN(AsyncGeneratorPrototypeNext, AsyncGeneratorBuiltinsAssembler) {
// https://tc39.github.io/proposal-async-iteration/
// Section #sec-asyncgenerator-prototype-return
TF_BUILTIN(AsyncGeneratorPrototypeReturn, AsyncGeneratorBuiltinsAssembler) {
Node* generator = Parameter(Descriptor::kReceiver);
Node* value = Parameter(Descriptor::kValue);
Node* context = Parameter(Descriptor::kContext);
AsyncGeneratorEnqueue(context, generator, value,
const int kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* generator = args.GetReceiver();
Node* value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
AsyncGeneratorEnqueue(&args, context, generator, value,
JSAsyncGeneratorObject::kReturn,
"[AsyncGenerator].prototype.return");
}
......@@ -351,10 +366,17 @@ TF_BUILTIN(AsyncGeneratorPrototypeReturn, AsyncGeneratorBuiltinsAssembler) {
// https://tc39.github.io/proposal-async-iteration/
// Section #sec-asyncgenerator-prototype-throw
TF_BUILTIN(AsyncGeneratorPrototypeThrow, AsyncGeneratorBuiltinsAssembler) {
Node* generator = Parameter(Descriptor::kReceiver);
Node* value = Parameter(Descriptor::kValue);
Node* context = Parameter(Descriptor::kContext);
AsyncGeneratorEnqueue(context, generator, value,
const int kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* generator = args.GetReceiver();
Node* value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
AsyncGeneratorEnqueue(&args, context, generator, value,
JSAsyncGeneratorObject::kThrow,
"[AsyncGenerator].prototype.throw");
}
......
......@@ -528,11 +528,13 @@ namespace internal {
TFS(CreateGeneratorObject, kClosure, kReceiver) \
CPP(GeneratorFunctionConstructor) \
/* ES6 #sec-generator.prototype.next */ \
TFJ(GeneratorPrototypeNext, 1, kValue) \
TFJ(GeneratorPrototypeNext, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-generator.prototype.return */ \
TFJ(GeneratorPrototypeReturn, 1, kValue) \
TFJ(GeneratorPrototypeReturn, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-generator.prototype.throw */ \
TFJ(GeneratorPrototypeThrow, 1, kException) \
TFJ(GeneratorPrototypeThrow, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
CPP(AsyncFunctionConstructor) \
\
/* Global object */ \
......@@ -1027,13 +1029,16 @@ namespace internal {
CPP(AsyncGeneratorFunctionConstructor) \
/* AsyncGenerator.prototype.next ( value ) */ \
/* proposal-async-iteration/#sec-asyncgenerator-prototype-next */ \
TFJ(AsyncGeneratorPrototypeNext, 1, kValue) \
TFJ(AsyncGeneratorPrototypeNext, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* AsyncGenerator.prototype.return ( value ) */ \
/* proposal-async-iteration/#sec-asyncgenerator-prototype-return */ \
TFJ(AsyncGeneratorPrototypeReturn, 1, kValue) \
TFJ(AsyncGeneratorPrototypeReturn, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* AsyncGenerator.prototype.throw ( exception ) */ \
/* proposal-async-iteration/#sec-asyncgenerator-prototype-throw */ \
TFJ(AsyncGeneratorPrototypeThrow, 1, kValue) \
TFJ(AsyncGeneratorPrototypeThrow, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
\
/* Await (proposal-async-iteration/#await), with resume behaviour */ \
/* specific to Async Generators. Internal / Not exposed to JS code. */ \
......
......@@ -18,13 +18,14 @@ class GeneratorBuiltinsAssembler : public CodeStubAssembler {
: CodeStubAssembler(state) {}
protected:
void GeneratorPrototypeResume(Node* receiver, Node* value, Node* context,
void GeneratorPrototypeResume(CodeStubArguments* args, Node* receiver,
Node* value, Node* context,
JSGeneratorObject::ResumeMode resume_mode,
char const* const method_name);
};
void GeneratorBuiltinsAssembler::GeneratorPrototypeResume(
Node* receiver, Node* value, Node* context,
CodeStubArguments* args, Node* receiver, Node* value, Node* context,
JSGeneratorObject::ResumeMode resume_mode, char const* const method_name) {
// Check if the {receiver} is actually a JSGeneratorObject.
Label if_receiverisincompatible(this, Label::kDeferred);
......@@ -67,7 +68,7 @@ void GeneratorBuiltinsAssembler::GeneratorPrototypeResume(
Node* executing = SmiConstant(JSGeneratorObject::kGeneratorExecuting);
GotoIf(SmiEqual(result_continuation, executing), &if_final_return);
Return(result);
args->PopAndReturn(result);
BIND(&if_final_return);
{
......@@ -75,8 +76,8 @@ void GeneratorBuiltinsAssembler::GeneratorPrototypeResume(
StoreObjectFieldNoWriteBarrier(
receiver, JSGeneratorObject::kContinuationOffset, closed);
// Return the wrapped result.
Return(CallBuiltin(Builtins::kCreateIterResultObject, context, result,
TrueConstant()));
args->PopAndReturn(CallBuiltin(Builtins::kCreateIterResultObject, context,
result, TrueConstant()));
}
BIND(&if_receiverisincompatible);
......@@ -106,7 +107,7 @@ void GeneratorBuiltinsAssembler::GeneratorPrototypeResume(
result = CallRuntime(Runtime::kThrow, context, value);
break;
}
Return(result);
args->PopAndReturn(result);
}
BIND(&if_receiverisrunning);
......@@ -126,28 +127,51 @@ void GeneratorBuiltinsAssembler::GeneratorPrototypeResume(
// ES6 #sec-generator.prototype.next
TF_BUILTIN(GeneratorPrototypeNext, GeneratorBuiltinsAssembler) {
Node* receiver = Parameter(Descriptor::kReceiver);
Node* value = Parameter(Descriptor::kValue);
Node* context = Parameter(Descriptor::kContext);
GeneratorPrototypeResume(receiver, value, context, JSGeneratorObject::kNext,
const int kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* receiver = args.GetReceiver();
Node* value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
GeneratorPrototypeResume(&args, receiver, value, context,
JSGeneratorObject::kNext,
"[Generator].prototype.next");
}
// ES6 #sec-generator.prototype.return
TF_BUILTIN(GeneratorPrototypeReturn, GeneratorBuiltinsAssembler) {
Node* receiver = Parameter(Descriptor::kReceiver);
Node* value = Parameter(Descriptor::kValue);
Node* context = Parameter(Descriptor::kContext);
GeneratorPrototypeResume(receiver, value, context, JSGeneratorObject::kReturn,
const int kValueArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* receiver = args.GetReceiver();
Node* value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
GeneratorPrototypeResume(&args, receiver, value, context,
JSGeneratorObject::kReturn,
"[Generator].prototype.return");
}
// ES6 #sec-generator.prototype.throw
TF_BUILTIN(GeneratorPrototypeThrow, GeneratorBuiltinsAssembler) {
Node* receiver = Parameter(Descriptor::kReceiver);
Node* exception = Parameter(Descriptor::kException);
Node* context = Parameter(Descriptor::kContext);
GeneratorPrototypeResume(receiver, exception, context,
const int kExceptionArg = 0;
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
Node* receiver = args.GetReceiver();
Node* exception = args.GetOptionalArgumentValue(kExceptionArg);
Node* context = Parameter(BuiltinDescriptor::kContext);
GeneratorPrototypeResume(&args, receiver, exception, context,
JSGeneratorObject::kThrow,
"[Generator].prototype.throw");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment