[modules] Optimize import.meta in the interpreter
Use an intrinsic for GetImportMetaObject and generate bytecode for the case where import.meta has been initialized already. This way the runtime method will only be called once per module. Bug: v8:6693 Change-Id: If661e88e6accfb1c5795e37a80582d04f6dd87dd Reviewed-on: https://chromium-review.googlesource.com/716536 Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Cr-Commit-Position: refs/heads/master@{#48801}
This commit is contained in:
parent
35b6aa3849
commit
8683248625
2
AUTHORS
2
AUTHORS
@ -31,6 +31,7 @@ StrongLoop, Inc. <*@strongloop.com>
|
||||
Facebook, Inc. <*@fb.com>
|
||||
Facebook, Inc. <*@oculus.com>
|
||||
Vewd Software AS <*@vewd.com>
|
||||
Groupon <*@groupon.com>
|
||||
|
||||
Aaron Bieber <deftly@gmail.com>
|
||||
Abdulla Kamar <abdulla.kamar@gmail.com>
|
||||
@ -75,6 +76,7 @@ Ioseb Dzmanashvili <ioseb.dzmanashvili@gmail.com>
|
||||
Isiah Meadows <impinball@gmail.com>
|
||||
Jaime Bernardo <jaime@janeasystems.com>
|
||||
Jan de Mooij <jandemooij@gmail.com>
|
||||
Jan Krems <jan.krems@gmail.com>
|
||||
Jay Freeman <saurik@saurik.com>
|
||||
James Pike <g00gle@chilon.net>
|
||||
Jianghua Yang <jianghua.yjh@alibaba-inc.com>
|
||||
|
@ -1678,6 +1678,33 @@ TNode<Context> CodeStubAssembler::LoadNativeContext(
|
||||
LoadContextElement(context, Context::NATIVE_CONTEXT_INDEX));
|
||||
}
|
||||
|
||||
TNode<Context> CodeStubAssembler::LoadModuleContext(
|
||||
SloppyTNode<Context> context) {
|
||||
Node* module_map = LoadRoot(Heap::kModuleContextMapRootIndex);
|
||||
Variable cur_context(this, MachineRepresentation::kTaggedPointer);
|
||||
cur_context.Bind(context);
|
||||
|
||||
Label context_found(this);
|
||||
|
||||
Variable* context_search_loop_variables[1] = {&cur_context};
|
||||
Label context_search(this, 1, context_search_loop_variables);
|
||||
|
||||
// Loop until cur_context->map() is module_map.
|
||||
Goto(&context_search);
|
||||
BIND(&context_search);
|
||||
{
|
||||
CSA_ASSERT(this, Word32BinaryNot(IsNativeContext(cur_context.value())));
|
||||
GotoIf(WordEqual(LoadMap(cur_context.value()), module_map), &context_found);
|
||||
|
||||
cur_context.Bind(
|
||||
LoadContextElement(cur_context.value(), Context::PREVIOUS_INDEX));
|
||||
Goto(&context_search);
|
||||
}
|
||||
|
||||
BIND(&context_found);
|
||||
return UncheckedCast<Context>(cur_context.value());
|
||||
}
|
||||
|
||||
TNode<Map> CodeStubAssembler::LoadJSArrayElementsMap(
|
||||
SloppyTNode<Int32T> kind, SloppyTNode<Context> native_context) {
|
||||
CSA_ASSERT(this, IsFastElementsKind(kind));
|
||||
|
@ -594,6 +594,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
int slot_index,
|
||||
SloppyTNode<Object> value);
|
||||
TNode<Context> LoadNativeContext(SloppyTNode<Context> context);
|
||||
// Calling this is only valid if there's a module context in the chain.
|
||||
TNode<Context> LoadModuleContext(SloppyTNode<Context> context);
|
||||
|
||||
TNode<Map> LoadJSArrayElementsMap(ElementsKind kind,
|
||||
SloppyTNode<Context> native_context);
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "src/interpreter/bytecodes.h"
|
||||
#include "src/interpreter/interpreter-assembler.h"
|
||||
#include "src/interpreter/interpreter-intrinsics.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/module.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -427,6 +429,28 @@ Node* IntrinsicsGenerator::GeneratorClose(Node* args_reg, Node* arg_count,
|
||||
return __ UndefinedConstant();
|
||||
}
|
||||
|
||||
Node* IntrinsicsGenerator::GetImportMetaObject(Node* args_reg, Node* arg_count,
|
||||
Node* context) {
|
||||
Node* const module_context = __ LoadModuleContext(context);
|
||||
Node* const module =
|
||||
__ LoadContextElement(module_context, Context::EXTENSION_INDEX);
|
||||
Node* const import_meta =
|
||||
__ LoadObjectField(module, Module::kImportMetaOffset);
|
||||
|
||||
InterpreterAssembler::Variable return_value(assembler_,
|
||||
MachineRepresentation::kTagged);
|
||||
return_value.Bind(import_meta);
|
||||
|
||||
InterpreterAssembler::Label end(assembler_);
|
||||
__ GotoIfNot(__ IsTheHole(import_meta), &end);
|
||||
|
||||
return_value.Bind(__ CallRuntime(Runtime::kGetImportMetaObject, context));
|
||||
__ Goto(&end);
|
||||
|
||||
__ BIND(&end);
|
||||
return return_value.value();
|
||||
}
|
||||
|
||||
Node* IntrinsicsGenerator::AsyncGeneratorReject(Node* input, Node* arg_count,
|
||||
Node* context) {
|
||||
return IntrinsicAsBuiltinCall(input, context,
|
||||
|
@ -22,6 +22,7 @@ namespace interpreter {
|
||||
V(GeneratorGetResumeMode, generator_get_resume_mode, 1) \
|
||||
V(GeneratorGetInputOrDebugPos, generator_get_input_or_debug_pos, 1) \
|
||||
V(GeneratorClose, generator_close, 1) \
|
||||
V(GetImportMetaObject, get_import_meta_object, 0) \
|
||||
V(Call, call, -1) \
|
||||
V(ClassOf, class_of, 1) \
|
||||
V(CreateIterResultObject, create_iter_result_object, 2) \
|
||||
|
@ -385,7 +385,7 @@ Expression* Parser::FunctionSentExpression(int pos) {
|
||||
|
||||
Expression* Parser::ImportMetaExpression(int pos) {
|
||||
return factory()->NewCallRuntime(
|
||||
Runtime::kGetImportMetaObject,
|
||||
Runtime::kInlineGetImportMetaObject,
|
||||
new (zone()) ZoneList<Expression*>(0, zone()), pos);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
// MODULE
|
||||
// Flags: --harmony-import-meta
|
||||
// Flags: --harmony-import-meta --no-lazy
|
||||
|
||||
import foreign, { url as otherUrl } from './modules-skip-export-import-meta.js';
|
||||
|
||||
@ -11,6 +11,18 @@ assertEquals("object", typeof import.meta);
|
||||
assertEquals(null, Object.getPrototypeOf(import.meta));
|
||||
assertSame(import.meta, import.meta);
|
||||
|
||||
const loadImportMetaArrow = () => import.meta;
|
||||
assertSame(loadImportMetaArrow(), import.meta);
|
||||
function loadImportMetaFn() {
|
||||
try {
|
||||
throw new Error('force catch code path for nested context');
|
||||
} catch (e) {
|
||||
return import.meta;
|
||||
}
|
||||
}
|
||||
loadImportMetaFn();
|
||||
assertSame(loadImportMetaFn(), import.meta);
|
||||
|
||||
// This property isn't part of the spec itself but is mentioned as an example
|
||||
assertMatches(/\/modules-import-meta\.js$/, import.meta.url);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user