[compiler,modules] Introduce JS operators for module loads and stores.
With this CL, the bytecode graph builder no longer translates module loads/stores as runtime calls but in terms of two new JS operators. These are lowered in typed-lowering to a sequence of LoadField's. R=bmeurer@chromium.org CC=adamk@chromium.org BUG=v8:1569 Review-Url: https://codereview.chromium.org/2489863003 Cr-Commit-Position: refs/heads/master@{#40881}
This commit is contained in:
parent
ade3bc6da9
commit
a9f593ef6b
@ -434,6 +434,27 @@ FieldAccess AccessBuilder::ForMapPrototype() {
|
||||
return access;
|
||||
}
|
||||
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForModuleRegularExports() {
|
||||
FieldAccess access = {kTaggedBase,
|
||||
Module::kRegularExportsOffset,
|
||||
Handle<Name>(),
|
||||
Type::OtherInternal(),
|
||||
MachineType::TaggedPointer(),
|
||||
kPointerWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForModuleRegularImports() {
|
||||
FieldAccess access = {kTaggedBase,
|
||||
Module::kRegularImportsOffset,
|
||||
Handle<Name>(),
|
||||
Type::OtherInternal(),
|
||||
MachineType::TaggedPointer(),
|
||||
kPointerWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForNameHashField() {
|
||||
@ -611,6 +632,14 @@ FieldAccess AccessBuilder::ForFixedArraySlot(size_t index) {
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForCellValue() {
|
||||
FieldAccess access = {
|
||||
kTaggedBase, Cell::kValueOffset, Handle<Name>(),
|
||||
Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForContextSlot(size_t index) {
|
||||
int offset = Context::kHeaderSize + static_cast<int>(index) * kPointerSize;
|
||||
|
@ -146,6 +146,12 @@ class V8_EXPORT_PRIVATE AccessBuilder final
|
||||
// Provides access to Map::prototype() field.
|
||||
static FieldAccess ForMapPrototype();
|
||||
|
||||
// Provides access to Module::regular_exports() field.
|
||||
static FieldAccess ForModuleRegularExports();
|
||||
|
||||
// Provides access to Module::regular_imports() field.
|
||||
static FieldAccess ForModuleRegularImports();
|
||||
|
||||
// Provides access to Name::hash_field() field.
|
||||
static FieldAccess ForNameHashField();
|
||||
|
||||
@ -194,6 +200,9 @@ class V8_EXPORT_PRIVATE AccessBuilder final
|
||||
// Provides access to JSValue::value() field.
|
||||
static FieldAccess ForValue();
|
||||
|
||||
// Provides access to Cell::value() field.
|
||||
static FieldAccess ForCellValue();
|
||||
|
||||
// Provides access to arguments object fields.
|
||||
static FieldAccess ForArgumentsLength();
|
||||
static FieldAccess ForArgumentsCallee();
|
||||
|
@ -1117,22 +1117,23 @@ void BytecodeGraphBuilder::VisitStaKeyedPropertyStrict() {
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitLdaModuleVariable() {
|
||||
// TODO(neis): Don't call the runtime.
|
||||
PrepareEagerCheckpoint();
|
||||
Node* index = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
|
||||
const Operator* op = javascript()->CallRuntime(Runtime::kLoadModuleVariable);
|
||||
Node* value = NewNode(op, index);
|
||||
environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
||||
int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
|
||||
uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
|
||||
Node* module =
|
||||
NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
|
||||
environment()->Context());
|
||||
Node* value = NewNode(javascript()->LoadModule(cell_index), module);
|
||||
environment()->BindAccumulator(value);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitStaModuleVariable() {
|
||||
// TODO(neis): Don't call the runtime.
|
||||
PrepareEagerCheckpoint();
|
||||
Node* index = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
|
||||
int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
|
||||
uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
|
||||
Node* module =
|
||||
NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
|
||||
environment()->Context());
|
||||
Node* value = environment()->LookupAccumulator();
|
||||
const Operator* op = javascript()->CallRuntime(Runtime::kStoreModuleVariable);
|
||||
Node* store = NewNode(op, index, value);
|
||||
environment()->RecordAfterState(store, Environment::kAttachFrameState);
|
||||
NewNode(javascript()->StoreModule(cell_index), module, value);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitPushContext() {
|
||||
|
@ -625,6 +625,14 @@ void JSGenericLowering::LowerJSStoreMessage(Node* node) {
|
||||
NodeProperties::ChangeOp(node, machine()->Store(representation));
|
||||
}
|
||||
|
||||
void JSGenericLowering::LowerJSLoadModule(Node* node) {
|
||||
UNREACHABLE(); // Eliminated in typed lowering.
|
||||
}
|
||||
|
||||
void JSGenericLowering::LowerJSStoreModule(Node* node) {
|
||||
UNREACHABLE(); // Eliminated in typed lowering.
|
||||
}
|
||||
|
||||
void JSGenericLowering::LowerJSGeneratorStore(Node* node) {
|
||||
UNREACHABLE(); // Eliminated in typed lowering.
|
||||
}
|
||||
|
@ -765,6 +765,23 @@ const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
|
||||
access); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::LoadModule(int32_t cell_index) {
|
||||
return new (zone()) Operator1<int32_t>( // --
|
||||
IrOpcode::kJSLoadModule, // opcode
|
||||
Operator::kNoWrite | Operator::kNoThrow, // flags
|
||||
"JSLoadModule", // name
|
||||
1, 1, 1, 1, 1, 0, // counts
|
||||
cell_index); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::StoreModule(int32_t cell_index) {
|
||||
return new (zone()) Operator1<int32_t>( // --
|
||||
IrOpcode::kJSStoreModule, // opcode
|
||||
Operator::kNoRead | Operator::kNoThrow, // flags
|
||||
"JSStoreModule", // name
|
||||
2, 1, 1, 0, 1, 0, // counts
|
||||
cell_index); // parameter
|
||||
}
|
||||
|
||||
const Operator* JSOperatorBuilder::CreateArguments(CreateArgumentsType type) {
|
||||
return new (zone()) Operator1<CreateArgumentsType>( // --
|
||||
|
@ -502,6 +502,9 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
|
||||
const Operator* LoadContext(size_t depth, size_t index, bool immutable);
|
||||
const Operator* StoreContext(size_t depth, size_t index);
|
||||
|
||||
const Operator* LoadModule(int32_t cell_index);
|
||||
const Operator* StoreModule(int32_t cell_index);
|
||||
|
||||
const Operator* TypeOf();
|
||||
const Operator* InstanceOf();
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "src/compiler/js-typed-lowering.h"
|
||||
|
||||
#include "src/ast/modules.h"
|
||||
#include "src/builtins/builtins-utils.h"
|
||||
#include "src/code-factory.h"
|
||||
#include "src/compilation-dependencies.h"
|
||||
@ -1489,6 +1490,81 @@ Reduction JSTypedLowering::ReduceJSStoreContext(Node* node) {
|
||||
return Changed(node);
|
||||
}
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSLoadModule(Node* node) {
|
||||
DCHECK_EQ(IrOpcode::kJSLoadModule, node->opcode());
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
|
||||
int32_t cell_index = OpParameter<int32_t>(node);
|
||||
Node* module = NodeProperties::GetValueInput(node, 0);
|
||||
|
||||
Node* array;
|
||||
int index;
|
||||
if (ModuleDescriptor::GetCellIndexKind(cell_index) ==
|
||||
ModuleDescriptor::kExport) {
|
||||
array = effect = graph()->NewNode(
|
||||
simplified()->LoadField(AccessBuilder::ForModuleRegularExports()),
|
||||
module, effect, control);
|
||||
index = cell_index - 1;
|
||||
} else {
|
||||
DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
|
||||
ModuleDescriptor::kImport);
|
||||
array = effect = graph()->NewNode(
|
||||
simplified()->LoadField(AccessBuilder::ForModuleRegularImports()),
|
||||
module, effect, control);
|
||||
index = -cell_index - 1;
|
||||
}
|
||||
|
||||
Node* cell = effect = graph()->NewNode(
|
||||
simplified()->LoadField(AccessBuilder::ForFixedArraySlot(index)), array,
|
||||
effect, control);
|
||||
|
||||
Node* value = effect =
|
||||
graph()->NewNode(simplified()->LoadField(AccessBuilder::ForCellValue()),
|
||||
cell, effect, control);
|
||||
|
||||
ReplaceWithValue(node, value, effect, control);
|
||||
return Changed(value);
|
||||
}
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSStoreModule(Node* node) {
|
||||
DCHECK_EQ(IrOpcode::kJSStoreModule, node->opcode());
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
|
||||
int32_t cell_index = OpParameter<int32_t>(node);
|
||||
Node* module = NodeProperties::GetValueInput(node, 0);
|
||||
Node* value = NodeProperties::GetValueInput(node, 1);
|
||||
|
||||
Node* array;
|
||||
int index;
|
||||
if (ModuleDescriptor::GetCellIndexKind(cell_index) ==
|
||||
ModuleDescriptor::kExport) {
|
||||
array = effect = graph()->NewNode(
|
||||
simplified()->LoadField(AccessBuilder::ForModuleRegularExports()),
|
||||
module, effect, control);
|
||||
index = cell_index - 1;
|
||||
} else {
|
||||
DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
|
||||
ModuleDescriptor::kImport);
|
||||
array = effect = graph()->NewNode(
|
||||
simplified()->LoadField(AccessBuilder::ForModuleRegularImports()),
|
||||
module, effect, control);
|
||||
index = -cell_index - 1;
|
||||
}
|
||||
|
||||
Node* cell = effect = graph()->NewNode(
|
||||
simplified()->LoadField(AccessBuilder::ForFixedArraySlot(index)), array,
|
||||
effect, control);
|
||||
|
||||
effect =
|
||||
graph()->NewNode(simplified()->StoreField(AccessBuilder::ForCellValue()),
|
||||
cell, value, effect, control);
|
||||
|
||||
ReplaceWithValue(node, effect, effect, control);
|
||||
return Changed(value);
|
||||
}
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
|
||||
DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode());
|
||||
ConvertReceiverMode mode = ConvertReceiverModeOf(node->op());
|
||||
@ -2126,6 +2202,10 @@ Reduction JSTypedLowering::Reduce(Node* node) {
|
||||
return ReduceJSLoadContext(node);
|
||||
case IrOpcode::kJSStoreContext:
|
||||
return ReduceJSStoreContext(node);
|
||||
case IrOpcode::kJSLoadModule:
|
||||
return ReduceJSLoadModule(node);
|
||||
case IrOpcode::kJSStoreModule:
|
||||
return ReduceJSStoreModule(node);
|
||||
case IrOpcode::kJSConvertReceiver:
|
||||
return ReduceJSConvertReceiver(node);
|
||||
case IrOpcode::kJSCallConstruct:
|
||||
|
@ -55,6 +55,8 @@ class V8_EXPORT_PRIVATE JSTypedLowering final
|
||||
Reduction ReduceJSInstanceOf(Node* node);
|
||||
Reduction ReduceJSLoadContext(Node* node);
|
||||
Reduction ReduceJSStoreContext(Node* node);
|
||||
Reduction ReduceJSLoadModule(Node* node);
|
||||
Reduction ReduceJSStoreModule(Node* node);
|
||||
Reduction ReduceJSEqualTypeOf(Node* node, bool invert);
|
||||
Reduction ReduceJSEqual(Node* node, bool invert);
|
||||
Reduction ReduceJSStrictEqual(Node* node, bool invert);
|
||||
|
@ -158,6 +158,8 @@
|
||||
V(JSForInPrepare) \
|
||||
V(JSLoadMessage) \
|
||||
V(JSStoreMessage) \
|
||||
V(JSLoadModule) \
|
||||
V(JSStoreModule) \
|
||||
V(JSGeneratorStore) \
|
||||
V(JSGeneratorRestoreContinuation) \
|
||||
V(JSGeneratorRestoreRegister) \
|
||||
|
@ -1488,6 +1488,13 @@ Type* Typer::Visitor::TypeJSStoreMessage(Node* node) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeJSLoadModule(Node* node) { return Type::Any(); }
|
||||
|
||||
Type* Typer::Visitor::TypeJSStoreModule(Node* node) {
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeJSGeneratorStore(Node* node) {
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
|
@ -660,6 +660,13 @@ void Verifier::Visitor::Check(Node* node) {
|
||||
case IrOpcode::kJSStoreMessage:
|
||||
break;
|
||||
|
||||
case IrOpcode::kJSLoadModule:
|
||||
CheckTypeIs(node, Type::Any());
|
||||
break;
|
||||
case IrOpcode::kJSStoreModule:
|
||||
CheckNotTyped(node);
|
||||
break;
|
||||
|
||||
case IrOpcode::kJSGeneratorStore:
|
||||
CheckNotTyped(node);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user