Commit 86832486 authored by Jan Krems's avatar Jan Krems Committed by Commit Bot

[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/716536Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48801}
parent 35b6aa38
......@@ -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);
......
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