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