Commit d8bc4702 authored by legendecas's avatar legendecas Committed by V8 LUCI CQ

[builtins] Use builtin context for SourceTextModule closures

Invoking a JSBoundFunction is slightly slower than a normal
JSFunction (since we don't have to first jump to the
target_function).

The closure steps in SourceTextModule ExecuteAsyncModule is
controlled by the engine so it is better to create dedicated
context slots for the captured values.

Change-Id: I8163fc4b302d6d22906e578164470c9e28e768e0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3584601Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Chengzhong Wu <legendecas@gmail.com>
Cr-Commit-Position: refs/heads/main@{#80155}
parent 19a991d5
......@@ -11,17 +11,23 @@ namespace internal {
BUILTIN(CallAsyncModuleFulfilled) {
HandleScope handle_scope(isolate);
Handle<SourceTextModule> module(args.at<SourceTextModule>(0));
Handle<SourceTextModule> module = Handle<SourceTextModule>(
SourceTextModule::cast(isolate->context().get(
SourceTextModule::ExecuteAsyncModuleContextSlots::kModule)),
isolate);
SourceTextModule::AsyncModuleExecutionFulfilled(isolate, module);
return ReadOnlyRoots(isolate).undefined_value();
}
BUILTIN(CallAsyncModuleRejected) {
HandleScope handle_scope(isolate);
Handle<SourceTextModule> module = Handle<SourceTextModule>(
SourceTextModule::cast(isolate->context().get(
SourceTextModule::ExecuteAsyncModuleContextSlots::kModule)),
isolate);
// Arguments should be a SourceTextModule and an exception object.
// Arguments should be an exception object, with receiver.
DCHECK_EQ(args.length(), 2);
Handle<SourceTextModule> module(args.at<SourceTextModule>(0));
Handle<Object> exception(args.at(1));
SourceTextModule::AsyncModuleExecutionRejected(isolate, module, exception);
return ReadOnlyRoots(isolate).undefined_value();
......
......@@ -1074,6 +1074,17 @@ void Heap::CreateInitialObjects() {
isolate_, Builtin::kShadowRealmImportValueFulfilled, 0);
set_shadow_realm_import_value_fulfilled_sfi(*info);
}
// SourceTextModule:
{
Handle<SharedFunctionInfo> info = CreateSharedFunctionInfo(
isolate_, Builtin::kCallAsyncModuleFulfilled, 0);
set_source_text_module_execute_async_module_fulfilled_sfi(*info);
info = CreateSharedFunctionInfo(isolate_, Builtin::kCallAsyncModuleRejected,
0);
set_source_text_module_execute_async_module_rejected_sfi(*info);
}
}
void Heap::CreateInternalAccessorInfoObjects() {
......
......@@ -967,20 +967,6 @@ void Genesis::CreateIteratorMaps(Handle<JSFunction> empty) {
async_module_evaluate_internal->shared().set_native(false);
native_context()->set_async_module_evaluate_internal(
*async_module_evaluate_internal);
Handle<JSFunction> call_async_module_fulfilled =
SimpleCreateFunction(isolate(), factory()->empty_string(),
Builtin::kCallAsyncModuleFulfilled, 1, false);
call_async_module_fulfilled->shared().set_native(false);
native_context()->set_call_async_module_fulfilled(
*call_async_module_fulfilled);
Handle<JSFunction> call_async_module_rejected =
SimpleCreateFunction(isolate(), factory()->empty_string(),
Builtin::kCallAsyncModuleRejected, 1, false);
call_async_module_rejected->shared().set_native(false);
native_context()->set_call_async_module_rejected(
*call_async_module_rejected);
}
// Create maps for generator functions and their prototypes. Store those
......
......@@ -105,8 +105,6 @@ enum ContextLookupFlags {
V(CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, JSFunction, \
call_as_constructor_delegate) \
V(CALL_AS_FUNCTION_DELEGATE_INDEX, JSFunction, call_as_function_delegate) \
V(CALL_ASYNC_MODULE_FULFILLED, JSFunction, call_async_module_fulfilled) \
V(CALL_ASYNC_MODULE_REJECTED, JSFunction, call_async_module_rejected) \
V(CALLSITE_FUNCTION_INDEX, JSFunction, callsite_function) \
V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \
V(DATA_PROPERTY_DESCRIPTOR_MAP_INDEX, Map, data_property_descriptor_map) \
......
......@@ -920,30 +920,35 @@ void SourceTextModule::ExecuteAsyncModule(Isolate* isolate,
// 4. Let capability be ! NewPromiseCapability(%Promise%).
Handle<JSPromise> capability = isolate->factory()->NewJSPromise();
// 5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled
Handle<JSFunction> steps_fulfilled(
isolate->native_context()->call_async_module_fulfilled(), isolate);
base::ScopedVector<Handle<Object>> empty_argv(0);
Handle<Context> execute_async_module_context =
isolate->factory()->NewBuiltinContext(
isolate->native_context(),
ExecuteAsyncModuleContextSlots::kContextLength);
execute_async_module_context->set(ExecuteAsyncModuleContextSlots::kModule,
*module);
// 5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled
// 6. Let onFulfilled be CreateBuiltinFunction(stepsFulfilled,
// «[[Module]]»).
// 7. Set onFulfilled.[[Module]] to module.
Handle<JSBoundFunction> on_fulfilled =
isolate->factory()
->NewJSBoundFunction(steps_fulfilled, module, empty_argv)
.ToHandleChecked();
Handle<JSFunction> on_fulfilled =
Factory::JSFunctionBuilder{
isolate,
isolate->factory()
->source_text_module_execute_async_module_fulfilled_sfi(),
execute_async_module_context}
.Build();
// 8. Let stepsRejected be the steps of a CallAsyncModuleRejected.
Handle<JSFunction> steps_rejected(
isolate->native_context()->call_async_module_rejected(), isolate);
// 9. Let onRejected be CreateBuiltinFunction(stepsRejected, «[[Module]]»).
// 10. Set onRejected.[[Module]] to module.
Handle<JSBoundFunction> on_rejected =
isolate->factory()
->NewJSBoundFunction(steps_rejected, module, empty_argv)
.ToHandleChecked();
Handle<JSFunction> on_rejected =
Factory::JSFunctionBuilder{
isolate,
isolate->factory()
->source_text_module_execute_async_module_rejected_sfi(),
execute_async_module_context}
.Build();
// 11. Perform ! PerformPromiseThen(capability.[[Promise]],
// onFulfilled, onRejected).
......
......@@ -5,6 +5,7 @@
#ifndef V8_OBJECTS_SOURCE_TEXT_MODULE_H_
#define V8_OBJECTS_SOURCE_TEXT_MODULE_H_
#include "src/objects/contexts.h"
#include "src/objects/module.h"
#include "src/objects/promise.h"
#include "src/zone/zone-containers.h"
......@@ -77,6 +78,11 @@ class SourceTextModule
static constexpr unsigned kFirstAsyncEvaluatingOrdinal = 2;
enum ExecuteAsyncModuleContextSlots {
kModule = Context::MIN_CONTEXT_SLOTS,
kContextLength,
};
private:
friend class Factory;
friend class Module;
......
......@@ -294,7 +294,11 @@ class Symbol;
PromiseValueThunkFinallySharedFun) \
V(SharedFunctionInfo, proxy_revoke_shared_fun, ProxyRevokeSharedFun) \
V(SharedFunctionInfo, shadow_realm_import_value_fulfilled_sfi, \
ShadowRealmImportValueFulfilledSFI)
ShadowRealmImportValueFulfilledSFI) \
V(SharedFunctionInfo, source_text_module_execute_async_module_fulfilled_sfi, \
SourceTextModuleExecuteAsyncModuleFulfilledSFI) \
V(SharedFunctionInfo, source_text_module_execute_async_module_rejected_sfi, \
SourceTextModuleExecuteAsyncModuleRejectedSFI)
// These root references can be updated by the mutator.
#define STRONG_MUTABLE_MOVABLE_ROOT_LIST(V) \
......
......@@ -560,6 +560,8 @@ KNOWN_OBJECTS = {
("old_space", 0x05a29): "PromiseValueThunkFinallySharedFun",
("old_space", 0x05a4d): "ProxyRevokeSharedFun",
("old_space", 0x05a71): "ShadowRealmImportValueFulfilledSFI",
("old_space", 0x05a95): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
("old_space", 0x05ab9): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
}
# Lower 32 bits of first page addresses for various heap spaces.
......
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