[storeic] Drop duplicate stubs for each LanguageMode
Only the error cases of overwriting readonly properties need the language_mode to decide whether to throw or be silent. Reading it from the feedback vector's metadata (just like the C++ code in ic.cc does) removes the need to duplicate each stub for each language_mode ("StoreIC" + "StoreICStrict" etc.). Change-Id: Ic0c67f9d40ca36c65e41b4f162b2ab70d155e549 Reviewed-on: https://chromium-review.googlesource.com/647373 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Commit-Queue: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/master@{#47836}
This commit is contained in:
parent
62fee3b64c
commit
cfcdeab002
@ -206,8 +206,6 @@ namespace internal {
|
||||
TFH(KeyedLoadIC_Slow, HANDLER, Code::LOAD_IC, LoadWithVector) \
|
||||
TFH(KeyedLoadIC_IndexedString, HANDLER, Code::LOAD_IC, LoadWithVector) \
|
||||
TFH(KeyedStoreIC_Megamorphic, BUILTIN, kNoExtraICState, StoreWithVector) \
|
||||
TFH(KeyedStoreIC_Megamorphic_Strict, BUILTIN, kNoExtraICState, \
|
||||
StoreWithVector) \
|
||||
TFH(KeyedStoreIC_Miss, BUILTIN, kNoExtraICState, StoreWithVector) \
|
||||
TFH(KeyedStoreIC_Slow, HANDLER, Code::STORE_IC, StoreWithVector) \
|
||||
TFH(LoadGlobalIC_Miss, BUILTIN, kNoExtraICState, LoadGlobalWithVector) \
|
||||
@ -221,7 +219,6 @@ namespace internal {
|
||||
TFH(StoreIC_Miss, BUILTIN, kNoExtraICState, StoreWithVector) \
|
||||
ASM(StoreIC_Setter_ForDeopt) \
|
||||
TFH(StoreIC_Uninitialized, BUILTIN, kNoExtraICState, StoreWithVector) \
|
||||
TFH(StoreICStrict_Uninitialized, BUILTIN, kNoExtraICState, StoreWithVector) \
|
||||
\
|
||||
/* Promise helpers */ \
|
||||
TFS(ResolveNativePromise, kPromise, kValue) \
|
||||
@ -541,12 +538,8 @@ namespace internal {
|
||||
TFH(KeyedLoadICTrampoline, KEYED_LOAD_IC, kNoExtraICState, Load) \
|
||||
TFH(StoreIC, STORE_IC, kNoExtraICState, StoreWithVector) \
|
||||
TFH(StoreICTrampoline, STORE_IC, kNoExtraICState, Store) \
|
||||
TFH(StoreICStrict, STORE_IC, kNoExtraICState, StoreWithVector) \
|
||||
TFH(StoreICStrictTrampoline, STORE_IC, kNoExtraICState, Store) \
|
||||
TFH(KeyedStoreIC, KEYED_STORE_IC, kNoExtraICState, StoreWithVector) \
|
||||
TFH(KeyedStoreICTrampoline, KEYED_STORE_IC, kNoExtraICState, Store) \
|
||||
TFH(KeyedStoreICStrict, KEYED_STORE_IC, kNoExtraICState, StoreWithVector) \
|
||||
TFH(KeyedStoreICStrictTrampoline, KEYED_STORE_IC, kNoExtraICState, Store) \
|
||||
TFH(LoadGlobalIC, LOAD_GLOBAL_IC, kNoExtraICState, LoadGlobalWithVector) \
|
||||
TFH(LoadGlobalICInsideTypeof, LOAD_GLOBAL_IC, kNoExtraICState, \
|
||||
LoadGlobalWithVector) \
|
||||
|
@ -56,22 +56,12 @@ TF_BUILTIN(KeyedLoadIC_Slow, CodeStubAssembler) {
|
||||
|
||||
void Builtins::Generate_KeyedStoreIC_Megamorphic(
|
||||
compiler::CodeAssemblerState* state) {
|
||||
KeyedStoreGenericGenerator::Generate(state, SLOPPY);
|
||||
}
|
||||
|
||||
void Builtins::Generate_KeyedStoreIC_Megamorphic_Strict(
|
||||
compiler::CodeAssemblerState* state) {
|
||||
KeyedStoreGenericGenerator::Generate(state, STRICT);
|
||||
KeyedStoreGenericGenerator::Generate(state);
|
||||
}
|
||||
|
||||
void Builtins::Generate_StoreIC_Uninitialized(
|
||||
compiler::CodeAssemblerState* state) {
|
||||
StoreICUninitializedGenerator::Generate(state, SLOPPY);
|
||||
}
|
||||
|
||||
void Builtins::Generate_StoreICStrict_Uninitialized(
|
||||
compiler::CodeAssemblerState* state) {
|
||||
StoreICUninitializedGenerator::Generate(state, STRICT);
|
||||
StoreICUninitializedGenerator::Generate(state);
|
||||
}
|
||||
|
||||
TF_BUILTIN(KeyedStoreIC_Miss, CodeStubAssembler) {
|
||||
|
@ -28,15 +28,11 @@ IC_BUILTIN(LoadICTrampoline)
|
||||
IC_BUILTIN(LoadField)
|
||||
IC_BUILTIN(KeyedLoadICTrampoline)
|
||||
IC_BUILTIN(KeyedLoadIC_Megamorphic)
|
||||
IC_BUILTIN(StoreIC)
|
||||
IC_BUILTIN(StoreICTrampoline)
|
||||
IC_BUILTIN(KeyedStoreIC)
|
||||
IC_BUILTIN(KeyedStoreICTrampoline)
|
||||
|
||||
IC_BUILTIN_PARAM(StoreIC, StoreIC, SLOPPY)
|
||||
IC_BUILTIN_PARAM(StoreICTrampoline, StoreICTrampoline, SLOPPY)
|
||||
IC_BUILTIN_PARAM(StoreICStrict, StoreIC, STRICT)
|
||||
IC_BUILTIN_PARAM(StoreICStrictTrampoline, StoreICTrampoline, STRICT)
|
||||
IC_BUILTIN_PARAM(KeyedStoreIC, KeyedStoreIC, SLOPPY)
|
||||
IC_BUILTIN_PARAM(KeyedStoreICTrampoline, KeyedStoreICTrampoline, SLOPPY)
|
||||
IC_BUILTIN_PARAM(KeyedStoreICStrict, KeyedStoreIC, STRICT)
|
||||
IC_BUILTIN_PARAM(KeyedStoreICStrictTrampoline, KeyedStoreICTrampoline, STRICT)
|
||||
IC_BUILTIN_PARAM(LoadGlobalIC, LoadGlobalIC, NOT_INSIDE_TYPEOF)
|
||||
IC_BUILTIN_PARAM(LoadGlobalICInsideTypeof, LoadGlobalIC, INSIDE_TYPEOF)
|
||||
IC_BUILTIN_PARAM(LoadGlobalICTrampoline, LoadGlobalICTrampoline,
|
||||
|
@ -63,42 +63,17 @@ Callable CodeFactory::LoadGlobalICInOptimizedCode(Isolate* isolate,
|
||||
LoadGlobalWithVectorDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::StoreIC(Isolate* isolate, LanguageMode language_mode) {
|
||||
return Callable(language_mode == STRICT
|
||||
? BUILTIN_CODE(isolate, StoreICStrictTrampoline)
|
||||
: BUILTIN_CODE(isolate, StoreICTrampoline),
|
||||
StoreDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::StoreICInOptimizedCode(Isolate* isolate,
|
||||
LanguageMode language_mode) {
|
||||
return Callable(language_mode == STRICT ? BUILTIN_CODE(isolate, StoreICStrict)
|
||||
: BUILTIN_CODE(isolate, StoreIC),
|
||||
StoreWithVectorDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::StoreIC_Uninitialized(Isolate* isolate,
|
||||
LanguageMode language_mode) {
|
||||
return Callable(language_mode == STRICT
|
||||
? BUILTIN_CODE(isolate, StoreICStrict_Uninitialized)
|
||||
: BUILTIN_CODE(isolate, StoreIC_Uninitialized),
|
||||
StoreWithVectorDescriptor(isolate));
|
||||
}
|
||||
|
||||
Callable CodeFactory::StoreOwnIC(Isolate* isolate) {
|
||||
// TODO(ishell): Currently we use StoreOwnIC only for storing properties that
|
||||
// already exist in the boilerplate therefore we can use StoreIC.
|
||||
return Callable(BUILTIN_CODE(isolate, StoreICStrictTrampoline),
|
||||
return Callable(BUILTIN_CODE(isolate, StoreICTrampoline),
|
||||
StoreDescriptor(isolate));
|
||||
}
|
||||
|
||||
Callable CodeFactory::StoreOwnICInOptimizedCode(Isolate* isolate) {
|
||||
// TODO(ishell): Currently we use StoreOwnIC only for storing properties that
|
||||
// already exist in the boilerplate therefore we can use StoreIC.
|
||||
return Callable(BUILTIN_CODE(isolate, StoreICStrict),
|
||||
return Callable(BUILTIN_CODE(isolate, StoreIC),
|
||||
StoreWithVectorDescriptor(isolate));
|
||||
}
|
||||
|
||||
@ -106,9 +81,7 @@ Callable CodeFactory::StoreOwnICInOptimizedCode(Isolate* isolate) {
|
||||
Callable CodeFactory::StoreGlobalIC(Isolate* isolate,
|
||||
LanguageMode language_mode) {
|
||||
// TODO(ishell): Use StoreGlobalIC[Strict]Trampoline when it's ready.
|
||||
return Callable(language_mode == STRICT
|
||||
? BUILTIN_CODE(isolate, StoreICStrictTrampoline)
|
||||
: BUILTIN_CODE(isolate, StoreICTrampoline),
|
||||
return Callable(BUILTIN_CODE(isolate, StoreICTrampoline),
|
||||
StoreDescriptor(isolate));
|
||||
}
|
||||
|
||||
@ -116,35 +89,7 @@ Callable CodeFactory::StoreGlobalIC(Isolate* isolate,
|
||||
Callable CodeFactory::StoreGlobalICInOptimizedCode(Isolate* isolate,
|
||||
LanguageMode language_mode) {
|
||||
// TODO(ishell): Use StoreGlobalIC[Strict] when it's ready.
|
||||
return Callable(language_mode == STRICT ? BUILTIN_CODE(isolate, StoreICStrict)
|
||||
: BUILTIN_CODE(isolate, StoreIC),
|
||||
StoreWithVectorDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::KeyedStoreIC(Isolate* isolate,
|
||||
LanguageMode language_mode) {
|
||||
return Callable(language_mode == STRICT
|
||||
? BUILTIN_CODE(isolate, KeyedStoreICStrictTrampoline)
|
||||
: BUILTIN_CODE(isolate, KeyedStoreICTrampoline),
|
||||
StoreDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::KeyedStoreICInOptimizedCode(Isolate* isolate,
|
||||
LanguageMode language_mode) {
|
||||
return Callable(language_mode == STRICT
|
||||
? BUILTIN_CODE(isolate, KeyedStoreICStrict)
|
||||
: BUILTIN_CODE(isolate, KeyedStoreIC),
|
||||
StoreWithVectorDescriptor(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::KeyedStoreIC_Megamorphic(Isolate* isolate,
|
||||
LanguageMode language_mode) {
|
||||
return Callable(language_mode == STRICT
|
||||
? BUILTIN_CODE(isolate, KeyedStoreIC_Megamorphic_Strict)
|
||||
: BUILTIN_CODE(isolate, KeyedStoreIC_Megamorphic),
|
||||
return Callable(BUILTIN_CODE(isolate, StoreIC),
|
||||
StoreWithVectorDescriptor(isolate));
|
||||
}
|
||||
|
||||
|
@ -32,15 +32,8 @@ class V8_EXPORT_PRIVATE CodeFactory final {
|
||||
static Callable StoreGlobalIC(Isolate* isolate, LanguageMode mode);
|
||||
static Callable StoreGlobalICInOptimizedCode(Isolate* isolate,
|
||||
LanguageMode mode);
|
||||
static Callable StoreIC(Isolate* isolate, LanguageMode mode);
|
||||
static Callable StoreICInOptimizedCode(Isolate* isolate, LanguageMode mode);
|
||||
static Callable StoreIC_Uninitialized(Isolate* isolate, LanguageMode mode);
|
||||
static Callable StoreOwnIC(Isolate* isolate);
|
||||
static Callable StoreOwnICInOptimizedCode(Isolate* isolate);
|
||||
static Callable KeyedStoreIC(Isolate* isolate, LanguageMode mode);
|
||||
static Callable KeyedStoreICInOptimizedCode(Isolate* isolate,
|
||||
LanguageMode mode);
|
||||
static Callable KeyedStoreIC_Megamorphic(Isolate* isolate, LanguageMode mode);
|
||||
|
||||
static Callable ResumeGenerator(Isolate* isolate);
|
||||
|
||||
|
@ -1291,8 +1291,7 @@ void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
|
||||
environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode,
|
||||
StoreMode store_mode) {
|
||||
void BytecodeGraphBuilder::BuildNamedStore(StoreMode store_mode) {
|
||||
PrepareEagerCheckpoint();
|
||||
Node* value = environment()->LookupAccumulator();
|
||||
Node* object =
|
||||
@ -1309,8 +1308,8 @@ void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode,
|
||||
op = javascript()->StoreNamedOwn(name, feedback);
|
||||
} else {
|
||||
DCHECK(store_mode == StoreMode::kNormal);
|
||||
DCHECK_EQ(feedback.vector()->GetLanguageMode(feedback.slot()),
|
||||
language_mode);
|
||||
LanguageMode language_mode =
|
||||
feedback.vector()->GetLanguageMode(feedback.slot());
|
||||
op = javascript()->StoreNamed(language_mode, name, feedback);
|
||||
}
|
||||
|
||||
@ -1328,19 +1327,15 @@ void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode,
|
||||
environment()->RecordAfterState(node, Environment::kAttachFrameState);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitStaNamedPropertySloppy() {
|
||||
BuildNamedStore(LanguageMode::SLOPPY, StoreMode::kNormal);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitStaNamedPropertyStrict() {
|
||||
BuildNamedStore(LanguageMode::STRICT, StoreMode::kNormal);
|
||||
void BytecodeGraphBuilder::VisitStaNamedProperty() {
|
||||
BuildNamedStore(StoreMode::kNormal);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitStaNamedOwnProperty() {
|
||||
BuildNamedStore(LanguageMode::STRICT, StoreMode::kOwn);
|
||||
BuildNamedStore(StoreMode::kOwn);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
|
||||
void BytecodeGraphBuilder::VisitStaKeyedProperty() {
|
||||
PrepareEagerCheckpoint();
|
||||
Node* value = environment()->LookupAccumulator();
|
||||
Node* object =
|
||||
@ -1349,7 +1344,8 @@ void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
|
||||
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
|
||||
VectorSlotPair feedback =
|
||||
CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
|
||||
DCHECK_EQ(feedback.vector()->GetLanguageMode(feedback.slot()), language_mode);
|
||||
LanguageMode language_mode =
|
||||
feedback.vector()->GetLanguageMode(feedback.slot());
|
||||
const Operator* op = javascript()->StoreProperty(language_mode, feedback);
|
||||
|
||||
JSTypeHintLowering::LoweringResult lowering =
|
||||
@ -1367,14 +1363,6 @@ void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
|
||||
environment()->RecordAfterState(node, Environment::kAttachFrameState);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitStaKeyedPropertySloppy() {
|
||||
BuildKeyedStore(LanguageMode::SLOPPY);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitStaKeyedPropertyStrict() {
|
||||
BuildKeyedStore(LanguageMode::STRICT);
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::VisitLdaModuleVariable() {
|
||||
int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
|
||||
uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
|
||||
|
@ -157,8 +157,7 @@ class BytecodeGraphBuilder {
|
||||
// Store value to the receiver without checking the prototype chain.
|
||||
kOwn,
|
||||
};
|
||||
void BuildNamedStore(LanguageMode language_mode, StoreMode store_mode);
|
||||
void BuildKeyedStore(LanguageMode language_mode);
|
||||
void BuildNamedStore(StoreMode store_mode);
|
||||
void BuildLdaLookupSlot(TypeofMode typeof_mode);
|
||||
void BuildLdaLookupContextSlot(TypeofMode typeof_mode);
|
||||
void BuildLdaLookupGlobalSlot(TypeofMode typeof_mode);
|
||||
|
@ -220,11 +220,12 @@ void JSGenericLowering::LowerJSStoreProperty(Node* node) {
|
||||
Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
|
||||
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
|
||||
if (outer_state->opcode() != IrOpcode::kFrameState) {
|
||||
Callable callable = CodeFactory::KeyedStoreIC(isolate(), p.language_mode());
|
||||
Callable callable =
|
||||
Builtins::CallableFor(isolate(), Builtins::kKeyedStoreICTrampoline);
|
||||
ReplaceWithStubCall(node, callable, flags);
|
||||
} else {
|
||||
Callable callable =
|
||||
CodeFactory::KeyedStoreICInOptimizedCode(isolate(), p.language_mode());
|
||||
Builtins::CallableFor(isolate(), Builtins::kKeyedStoreIC);
|
||||
Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
|
||||
node->InsertInput(zone(), 4, vector);
|
||||
ReplaceWithStubCall(node, callable, flags);
|
||||
@ -239,11 +240,11 @@ void JSGenericLowering::LowerJSStoreNamed(Node* node) {
|
||||
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
|
||||
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
|
||||
if (outer_state->opcode() != IrOpcode::kFrameState) {
|
||||
Callable callable = CodeFactory::StoreIC(isolate(), p.language_mode());
|
||||
Callable callable =
|
||||
Builtins::CallableFor(isolate(), Builtins::kStoreICTrampoline);
|
||||
ReplaceWithStubCall(node, callable, flags);
|
||||
} else {
|
||||
Callable callable =
|
||||
CodeFactory::StoreICInOptimizedCode(isolate(), p.language_mode());
|
||||
Callable callable = Builtins::CallableFor(isolate(), Builtins::kStoreIC);
|
||||
Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
|
||||
node->InsertInput(zone(), 4, vector);
|
||||
ReplaceWithStubCall(node, callable, flags);
|
||||
|
@ -652,7 +652,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) {
|
||||
|
||||
Reduction JSNativeContextSpecialization::ReduceNamedAccess(
|
||||
Node* node, Node* value, MapHandles const& receiver_maps, Handle<Name> name,
|
||||
AccessMode access_mode, LanguageMode language_mode, Node* index) {
|
||||
AccessMode access_mode, Node* index) {
|
||||
DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
|
||||
node->opcode() == IrOpcode::kJSStoreNamed ||
|
||||
node->opcode() == IrOpcode::kJSLoadProperty ||
|
||||
@ -731,7 +731,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
|
||||
// Generate the actual property access.
|
||||
ValueEffectControl continuation = BuildPropertyAccess(
|
||||
receiver, value, context, frame_state, effect, control, name,
|
||||
if_exceptions, access_info, access_mode, language_mode);
|
||||
if_exceptions, access_info, access_mode);
|
||||
value = continuation.value();
|
||||
effect = continuation.effect();
|
||||
control = continuation.control();
|
||||
@ -836,10 +836,9 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
|
||||
}
|
||||
|
||||
// Generate the actual property access.
|
||||
ValueEffectControl continuation =
|
||||
BuildPropertyAccess(this_receiver, this_value, context, frame_state,
|
||||
this_effect, this_control, name, if_exceptions,
|
||||
access_info, access_mode, language_mode);
|
||||
ValueEffectControl continuation = BuildPropertyAccess(
|
||||
this_receiver, this_value, context, frame_state, this_effect,
|
||||
this_control, name, if_exceptions, access_info, access_mode);
|
||||
values.push_back(continuation.value());
|
||||
effects.push_back(continuation.effect());
|
||||
controls.push_back(continuation.control());
|
||||
@ -891,7 +890,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
|
||||
|
||||
Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus(
|
||||
Node* node, Node* value, FeedbackNexus const& nexus, Handle<Name> name,
|
||||
AccessMode access_mode, LanguageMode language_mode) {
|
||||
AccessMode access_mode) {
|
||||
DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
|
||||
node->opcode() == IrOpcode::kJSStoreNamed ||
|
||||
node->opcode() == IrOpcode::kJSStoreNamedOwn);
|
||||
@ -929,8 +928,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus(
|
||||
}
|
||||
|
||||
// Try to lower the named access based on the {receiver_maps}.
|
||||
return ReduceNamedAccess(node, value, receiver_maps, name, access_mode,
|
||||
language_mode);
|
||||
return ReduceNamedAccess(node, value, receiver_maps, name, access_mode);
|
||||
}
|
||||
|
||||
Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) {
|
||||
@ -974,7 +972,7 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) {
|
||||
|
||||
// Try to lower the named access based on the {receiver_maps}.
|
||||
return ReduceNamedAccessFromNexus(node, value, nexus, p.name(),
|
||||
AccessMode::kLoad, p.language_mode());
|
||||
AccessMode::kLoad);
|
||||
}
|
||||
|
||||
|
||||
@ -989,7 +987,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) {
|
||||
|
||||
// Try to lower the named access based on the {receiver_maps}.
|
||||
return ReduceNamedAccessFromNexus(node, value, nexus, p.name(),
|
||||
AccessMode::kStore, p.language_mode());
|
||||
AccessMode::kStore);
|
||||
}
|
||||
|
||||
Reduction JSNativeContextSpecialization::ReduceJSStoreNamedOwn(Node* node) {
|
||||
@ -1003,13 +1001,12 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamedOwn(Node* node) {
|
||||
|
||||
// Try to lower the creation of a named property based on the {receiver_maps}.
|
||||
return ReduceNamedAccessFromNexus(node, value, nexus, p.name(),
|
||||
AccessMode::kStoreInLiteral, STRICT);
|
||||
AccessMode::kStoreInLiteral);
|
||||
}
|
||||
|
||||
Reduction JSNativeContextSpecialization::ReduceElementAccess(
|
||||
Node* node, Node* index, Node* value, MapHandles const& receiver_maps,
|
||||
AccessMode access_mode, LanguageMode language_mode,
|
||||
KeyedAccessStoreMode store_mode) {
|
||||
AccessMode access_mode, KeyedAccessStoreMode store_mode) {
|
||||
DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
|
||||
node->opcode() == IrOpcode::kJSStoreProperty);
|
||||
Node* receiver = NodeProperties::GetValueInput(node, 0);
|
||||
@ -1250,8 +1247,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
|
||||
template <typename KeyedICNexus>
|
||||
Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
|
||||
Node* node, Node* index, Node* value, KeyedICNexus const& nexus,
|
||||
AccessMode access_mode, LanguageMode language_mode,
|
||||
KeyedAccessStoreMode store_mode) {
|
||||
AccessMode access_mode, KeyedAccessStoreMode store_mode) {
|
||||
DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
|
||||
node->opcode() == IrOpcode::kJSStoreProperty);
|
||||
Node* receiver = NodeProperties::GetValueInput(node, 0);
|
||||
@ -1332,8 +1328,7 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
|
||||
index = jsgraph()->Constant(static_cast<double>(array_index));
|
||||
} else {
|
||||
name = factory()->InternalizeName(name);
|
||||
return ReduceNamedAccess(node, value, receiver_maps, name, access_mode,
|
||||
language_mode);
|
||||
return ReduceNamedAccess(node, value, receiver_maps, name, access_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1341,8 +1336,7 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
|
||||
// Check if we have feedback for a named access.
|
||||
if (Name* name = nexus.FindFirstName()) {
|
||||
return ReduceNamedAccess(node, value, receiver_maps,
|
||||
handle(name, isolate()), access_mode,
|
||||
language_mode, index);
|
||||
handle(name, isolate()), access_mode, index);
|
||||
} else if (nexus.GetKeyType() != ELEMENT) {
|
||||
// The KeyedLoad/StoreIC has seen non-element accesses, so we cannot assume
|
||||
// that the {index} is a valid array index, thus we just let the IC continue
|
||||
@ -1358,7 +1352,7 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
|
||||
|
||||
// Try to lower the element access based on the {receiver_maps}.
|
||||
return ReduceElementAccess(node, index, value, receiver_maps, access_mode,
|
||||
language_mode, store_mode);
|
||||
store_mode);
|
||||
}
|
||||
|
||||
Reduction JSNativeContextSpecialization::ReduceSoftDeoptimize(
|
||||
@ -1447,7 +1441,7 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadProperty(Node* node) {
|
||||
|
||||
// Try to lower the keyed access based on the {nexus}.
|
||||
return ReduceKeyedAccess(node, name, value, nexus, AccessMode::kLoad,
|
||||
p.language_mode(), STANDARD_STORE);
|
||||
STANDARD_STORE);
|
||||
}
|
||||
|
||||
Reduction JSNativeContextSpecialization::ReduceJSStoreProperty(Node* node) {
|
||||
@ -1465,7 +1459,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreProperty(Node* node) {
|
||||
|
||||
// Try to lower the keyed access based on the {nexus}.
|
||||
return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kStore,
|
||||
p.language_mode(), store_mode);
|
||||
store_mode);
|
||||
}
|
||||
|
||||
Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
|
||||
@ -1626,7 +1620,7 @@ JSNativeContextSpecialization::ValueEffectControl
|
||||
JSNativeContextSpecialization::BuildPropertyLoad(
|
||||
Node* receiver, Node* context, Node* frame_state, Node* effect,
|
||||
Node* control, Handle<Name> name, ZoneVector<Node*>* if_exceptions,
|
||||
PropertyAccessInfo const& access_info, LanguageMode language_mode) {
|
||||
PropertyAccessInfo const& access_info) {
|
||||
// Determine actual holder and perform prototype chain checks.
|
||||
Handle<JSObject> holder;
|
||||
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
|
||||
@ -1658,17 +1652,16 @@ JSNativeContextSpecialization::ValueEffectControl
|
||||
JSNativeContextSpecialization::BuildPropertyAccess(
|
||||
Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect,
|
||||
Node* control, Handle<Name> name, ZoneVector<Node*>* if_exceptions,
|
||||
PropertyAccessInfo const& access_info, AccessMode access_mode,
|
||||
LanguageMode language_mode) {
|
||||
PropertyAccessInfo const& access_info, AccessMode access_mode) {
|
||||
switch (access_mode) {
|
||||
case AccessMode::kLoad:
|
||||
return BuildPropertyLoad(receiver, context, frame_state, effect, control,
|
||||
name, if_exceptions, access_info, language_mode);
|
||||
name, if_exceptions, access_info);
|
||||
case AccessMode::kStore:
|
||||
case AccessMode::kStoreInLiteral:
|
||||
return BuildPropertyStore(receiver, value, context, frame_state, effect,
|
||||
control, name, if_exceptions, access_info,
|
||||
access_mode, language_mode);
|
||||
access_mode);
|
||||
}
|
||||
UNREACHABLE();
|
||||
return ValueEffectControl();
|
||||
@ -1678,8 +1671,7 @@ JSNativeContextSpecialization::ValueEffectControl
|
||||
JSNativeContextSpecialization::BuildPropertyStore(
|
||||
Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect,
|
||||
Node* control, Handle<Name> name, ZoneVector<Node*>* if_exceptions,
|
||||
PropertyAccessInfo const& access_info, AccessMode access_mode,
|
||||
LanguageMode language_mode) {
|
||||
PropertyAccessInfo const& access_info, AccessMode access_mode) {
|
||||
// Determine actual holder and perform prototype chain checks.
|
||||
Handle<JSObject> holder;
|
||||
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
|
||||
@ -1945,7 +1937,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
|
||||
// Generate the actual property access.
|
||||
ValueEffectControl continuation = BuildPropertyAccess(
|
||||
receiver, value, context, frame_state_lazy, effect, control, cached_name,
|
||||
nullptr, access_info, AccessMode::kStoreInLiteral, LanguageMode::SLOPPY);
|
||||
nullptr, access_info, AccessMode::kStoreInLiteral);
|
||||
value = continuation.value();
|
||||
effect = continuation.effect();
|
||||
control = continuation.control();
|
||||
|
@ -75,22 +75,18 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
|
||||
Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
|
||||
MapHandles const& receiver_maps,
|
||||
AccessMode access_mode,
|
||||
LanguageMode language_mode,
|
||||
KeyedAccessStoreMode store_mode);
|
||||
template <typename KeyedICNexus>
|
||||
Reduction ReduceKeyedAccess(Node* node, Node* index, Node* value,
|
||||
KeyedICNexus const& nexus, AccessMode access_mode,
|
||||
LanguageMode language_mode,
|
||||
KeyedAccessStoreMode store_mode);
|
||||
Reduction ReduceNamedAccessFromNexus(Node* node, Node* value,
|
||||
FeedbackNexus const& nexus,
|
||||
Handle<Name> name,
|
||||
AccessMode access_mode,
|
||||
LanguageMode language_mode);
|
||||
AccessMode access_mode);
|
||||
Reduction ReduceNamedAccess(Node* node, Node* value,
|
||||
MapHandles const& receiver_maps,
|
||||
Handle<Name> name, AccessMode access_mode,
|
||||
LanguageMode language_mode,
|
||||
Node* index = nullptr);
|
||||
Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
|
||||
Handle<Name> name, AccessMode access_mode,
|
||||
@ -117,23 +113,26 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
|
||||
};
|
||||
|
||||
// Construct the appropriate subgraph for property access.
|
||||
ValueEffectControl BuildPropertyAccess(
|
||||
Node* receiver, Node* value, Node* context, Node* frame_state,
|
||||
Node* effect, Node* control, Handle<Name> name,
|
||||
ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info,
|
||||
AccessMode access_mode, LanguageMode language_mode);
|
||||
ValueEffectControl BuildPropertyAccess(Node* receiver, Node* value,
|
||||
Node* context, Node* frame_state,
|
||||
Node* effect, Node* control,
|
||||
Handle<Name> name,
|
||||
ZoneVector<Node*>* if_exceptions,
|
||||
PropertyAccessInfo const& access_info,
|
||||
AccessMode access_mode);
|
||||
ValueEffectControl BuildPropertyLoad(Node* receiver, Node* context,
|
||||
Node* frame_state, Node* effect,
|
||||
Node* control, Handle<Name> name,
|
||||
ZoneVector<Node*>* if_exceptions,
|
||||
PropertyAccessInfo const& access_info,
|
||||
LanguageMode language_mode);
|
||||
PropertyAccessInfo const& access_info);
|
||||
|
||||
ValueEffectControl BuildPropertyStore(
|
||||
Node* receiver, Node* value, Node* context, Node* frame_state,
|
||||
Node* effect, Node* control, Handle<Name> name,
|
||||
ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info,
|
||||
AccessMode access_mode, LanguageMode language_mode);
|
||||
ValueEffectControl BuildPropertyStore(Node* receiver, Node* value,
|
||||
Node* context, Node* frame_state,
|
||||
Node* effect, Node* control,
|
||||
Handle<Name> name,
|
||||
ZoneVector<Node*>* if_exceptions,
|
||||
PropertyAccessInfo const& access_info,
|
||||
AccessMode access_mode);
|
||||
|
||||
// Helpers for accessor inlining.
|
||||
Node* InlinePropertyGetterCall(Node* receiver, Node* context,
|
||||
|
@ -25,17 +25,21 @@ enum class FeedbackSlotKind {
|
||||
// There must be no such slots in the system.
|
||||
kInvalid,
|
||||
|
||||
// Sloppy kinds come first, for easy language mode testing.
|
||||
kStoreGlobalSloppy,
|
||||
kStoreNamedSloppy,
|
||||
kStoreKeyedSloppy,
|
||||
kLastSloppyKind = kStoreKeyedSloppy,
|
||||
|
||||
// Strict and language mode unaware kinds.
|
||||
kCall,
|
||||
kLoadProperty,
|
||||
kLoadGlobalNotInsideTypeof,
|
||||
kLoadGlobalInsideTypeof,
|
||||
kLoadKeyed,
|
||||
kStoreGlobalSloppy,
|
||||
kStoreGlobalStrict,
|
||||
kStoreNamedSloppy,
|
||||
kStoreNamedStrict,
|
||||
kStoreOwnNamed,
|
||||
kStoreKeyedSloppy,
|
||||
kStoreKeyedStrict,
|
||||
kBinaryOp,
|
||||
kCompareOp,
|
||||
@ -98,11 +102,13 @@ inline TypeofMode GetTypeofModeFromSlotKind(FeedbackSlotKind kind) {
|
||||
inline LanguageMode GetLanguageModeFromSlotKind(FeedbackSlotKind kind) {
|
||||
DCHECK(IsStoreICKind(kind) || IsStoreOwnICKind(kind) ||
|
||||
IsStoreGlobalICKind(kind) || IsKeyedStoreICKind(kind));
|
||||
return (kind == FeedbackSlotKind::kStoreNamedSloppy ||
|
||||
kind == FeedbackSlotKind::kStoreGlobalSloppy ||
|
||||
kind == FeedbackSlotKind::kStoreKeyedSloppy)
|
||||
? SLOPPY
|
||||
: STRICT;
|
||||
STATIC_ASSERT(FeedbackSlotKind::kStoreGlobalSloppy <=
|
||||
FeedbackSlotKind::kLastSloppyKind);
|
||||
STATIC_ASSERT(FeedbackSlotKind::kStoreKeyedSloppy <=
|
||||
FeedbackSlotKind::kLastSloppyKind);
|
||||
STATIC_ASSERT(FeedbackSlotKind::kStoreNamedSloppy <=
|
||||
FeedbackSlotKind::kLastSloppyKind);
|
||||
return (kind <= FeedbackSlotKind::kLastSloppyKind) ? SLOPPY : STRICT;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, FeedbackSlotKind kind);
|
||||
@ -452,6 +458,8 @@ class FeedbackMetadata : public FixedArray {
|
||||
bool HasTypeProfileSlot() const;
|
||||
|
||||
private:
|
||||
friend class AccessorAssembler;
|
||||
|
||||
static const int kFeedbackSlotKindBits = 5;
|
||||
STATIC_ASSERT(static_cast<int>(FeedbackSlotKind::kKindsNumber) <
|
||||
(1 << kFeedbackSlotKindBits));
|
||||
|
@ -638,7 +638,7 @@ void AccessorAssembler::JumpIfDataProperty(Node* details, Label* writable,
|
||||
|
||||
void AccessorAssembler::HandleStoreICHandlerCase(
|
||||
const StoreICParameters* p, Node* handler, Label* miss,
|
||||
LanguageMode language_mode, ElementSupport support_elements) {
|
||||
ElementSupport support_elements) {
|
||||
Label if_smi_handler(this), if_nonsmi_handler(this);
|
||||
Label if_proto_handler(this), if_element_handler(this), call_handler(this),
|
||||
store_global(this);
|
||||
@ -690,7 +690,7 @@ void AccessorAssembler::HandleStoreICHandlerCase(
|
||||
HandleStoreICSmiHandlerCase(handler_word, holder, p->value, nullptr, miss);
|
||||
|
||||
BIND(&if_proxy);
|
||||
HandleStoreToProxy(p, holder, miss, support_elements, language_mode);
|
||||
HandleStoreToProxy(p, holder, miss, support_elements);
|
||||
}
|
||||
|
||||
BIND(&if_nonsmi_handler);
|
||||
@ -705,14 +705,11 @@ void AccessorAssembler::HandleStoreICHandlerCase(
|
||||
|
||||
if (support_elements == kSupportElements) {
|
||||
BIND(&if_element_handler);
|
||||
{ HandleStoreICElementHandlerCase(p, handler, miss); }
|
||||
HandleStoreICElementHandlerCase(p, handler, miss);
|
||||
}
|
||||
|
||||
BIND(&if_proto_handler);
|
||||
{
|
||||
HandleStoreICProtoHandler(p, handler, miss, support_elements,
|
||||
language_mode);
|
||||
}
|
||||
HandleStoreICProtoHandler(p, handler, miss, support_elements);
|
||||
|
||||
// |handler| is a heap object. Must be code, call it.
|
||||
BIND(&call_handler);
|
||||
@ -801,7 +798,7 @@ void AccessorAssembler::HandleStoreICElementHandlerCase(
|
||||
|
||||
void AccessorAssembler::HandleStoreICProtoHandler(
|
||||
const StoreICParameters* p, Node* handler, Label* miss,
|
||||
ElementSupport support_elements, LanguageMode language_mode) {
|
||||
ElementSupport support_elements) {
|
||||
// IC dispatchers rely on these assumptions to be held.
|
||||
STATIC_ASSERT(FixedArray::kLengthOffset ==
|
||||
StoreHandler::kTransitionCellOffset);
|
||||
@ -866,7 +863,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
|
||||
BIND(&if_proxy);
|
||||
{
|
||||
Node* proxy = var_transition.value();
|
||||
HandleStoreToProxy(p, proxy, miss, support_elements, language_mode);
|
||||
HandleStoreToProxy(p, proxy, miss, support_elements);
|
||||
}
|
||||
|
||||
BIND(&if_transition);
|
||||
@ -967,13 +964,18 @@ void AccessorAssembler::HandleStoreICProtoHandler(
|
||||
|
||||
void AccessorAssembler::HandleStoreToProxy(const StoreICParameters* p,
|
||||
Node* proxy, Label* miss,
|
||||
ElementSupport support_elements,
|
||||
LanguageMode language_mode) {
|
||||
ElementSupport support_elements) {
|
||||
VARIABLE(var_index, MachineType::PointerRepresentation());
|
||||
VARIABLE(var_unique, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_language_mode, MachineRepresentation::kTaggedSigned,
|
||||
SmiConstant(STRICT));
|
||||
|
||||
Label if_index(this), if_unique_name(this),
|
||||
Label if_index(this), if_unique_name(this), language_mode_determined(this),
|
||||
to_name_failed(this, Label::kDeferred);
|
||||
BranchIfStrictMode(p->vector, p->slot, &language_mode_determined);
|
||||
var_language_mode.Bind(SmiConstant(SLOPPY));
|
||||
Goto(&language_mode_determined);
|
||||
BIND(&language_mode_determined);
|
||||
|
||||
if (support_elements == kSupportElements) {
|
||||
TryToName(p->name, &if_index, &var_index, &if_unique_name, &var_unique,
|
||||
@ -982,7 +984,7 @@ void AccessorAssembler::HandleStoreToProxy(const StoreICParameters* p,
|
||||
BIND(&if_unique_name);
|
||||
CallBuiltin(Builtins::kProxySetProperty, p->context, proxy,
|
||||
var_unique.value(), p->value, p->receiver,
|
||||
SmiConstant(language_mode));
|
||||
var_language_mode.value());
|
||||
Return(p->value);
|
||||
|
||||
// The index case is handled earlier by the runtime.
|
||||
@ -993,11 +995,11 @@ void AccessorAssembler::HandleStoreToProxy(const StoreICParameters* p,
|
||||
|
||||
BIND(&to_name_failed);
|
||||
TailCallRuntime(Runtime::kSetPropertyWithReceiver, p->context, proxy,
|
||||
p->name, p->value, p->receiver, SmiConstant(language_mode));
|
||||
p->name, p->value, p->receiver, var_language_mode.value());
|
||||
} else {
|
||||
Node* name = ToName(p->context, p->name);
|
||||
TailCallBuiltin(Builtins::kProxySetProperty, p->context, proxy, name,
|
||||
p->value, p->receiver, SmiConstant(language_mode));
|
||||
p->value, p->receiver, var_language_mode.value());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1575,6 +1577,38 @@ void AccessorAssembler::NameDictionaryNegativeLookup(Node* object, Node* name,
|
||||
BIND(&done);
|
||||
}
|
||||
|
||||
void AccessorAssembler::BranchIfStrictMode(Node* vector, Node* slot,
|
||||
Label* if_strict) {
|
||||
Node* sfi =
|
||||
LoadObjectField(vector, FeedbackVector::kSharedFunctionInfoOffset);
|
||||
Node* metadata =
|
||||
LoadObjectField(sfi, SharedFunctionInfo::kFeedbackMetadataOffset);
|
||||
Node* slot_int = SmiToWord32(slot);
|
||||
|
||||
// See VectorICComputer::index().
|
||||
const int kItemsPerWord = FeedbackMetadata::VectorICComputer::kItemsPerWord;
|
||||
Node* word_index = Int32Div(slot_int, Int32Constant(kItemsPerWord));
|
||||
Node* word_offset = Int32Mod(slot_int, Int32Constant(kItemsPerWord));
|
||||
Node* data = SmiToWord32(LoadFixedArrayElement(
|
||||
metadata, ChangeInt32ToIntPtr(word_index),
|
||||
FeedbackMetadata::kReservedIndexCount * kPointerSize, INTPTR_PARAMETERS));
|
||||
// See VectorICComputer::decode().
|
||||
const int kBitsPerItem = FeedbackMetadata::kFeedbackSlotKindBits;
|
||||
Node* shift = Int32Mul(word_offset, Int32Constant(kBitsPerItem));
|
||||
const int kMask = FeedbackMetadata::VectorICComputer::kMask;
|
||||
Node* kind = Word32And(Word32Shr(data, shift), Int32Constant(kMask));
|
||||
|
||||
STATIC_ASSERT(FeedbackSlotKind::kStoreGlobalSloppy <=
|
||||
FeedbackSlotKind::kLastSloppyKind);
|
||||
STATIC_ASSERT(FeedbackSlotKind::kStoreKeyedSloppy <=
|
||||
FeedbackSlotKind::kLastSloppyKind);
|
||||
STATIC_ASSERT(FeedbackSlotKind::kStoreNamedSloppy <=
|
||||
FeedbackSlotKind::kLastSloppyKind);
|
||||
GotoIfNot(Int32LessThanOrEqual(kind, Int32Constant(static_cast<int>(
|
||||
FeedbackSlotKind::kLastSloppyKind))),
|
||||
if_strict);
|
||||
}
|
||||
|
||||
void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map,
|
||||
Node* instance_type, Node* index,
|
||||
Label* slow) {
|
||||
@ -2306,8 +2340,7 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) {
|
||||
}
|
||||
}
|
||||
|
||||
void AccessorAssembler::StoreIC(const StoreICParameters* p,
|
||||
LanguageMode language_mode) {
|
||||
void AccessorAssembler::StoreIC(const StoreICParameters* p) {
|
||||
VARIABLE(var_handler, MachineRepresentation::kTagged);
|
||||
Label if_handler(this, &var_handler), try_polymorphic(this, Label::kDeferred),
|
||||
try_megamorphic(this, Label::kDeferred),
|
||||
@ -2323,7 +2356,7 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p,
|
||||
BIND(&if_handler);
|
||||
{
|
||||
Comment("StoreIC_if_handler");
|
||||
HandleStoreICHandlerCase(p, var_handler.value(), &miss, language_mode);
|
||||
HandleStoreICHandlerCase(p, var_handler.value(), &miss);
|
||||
}
|
||||
|
||||
BIND(&try_polymorphic);
|
||||
@ -2352,8 +2385,9 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p,
|
||||
GotoIfNot(
|
||||
WordEqual(feedback, LoadRoot(Heap::kuninitialized_symbolRootIndex)),
|
||||
&miss);
|
||||
TailCallStub(CodeFactory::StoreIC_Uninitialized(isolate(), language_mode),
|
||||
p->context, p->receiver, p->name, p->value, p->slot,
|
||||
Callable stub =
|
||||
Builtins::CallableFor(isolate(), Builtins::kStoreIC_Uninitialized);
|
||||
TailCallStub(stub, p->context, p->receiver, p->name, p->value, p->slot,
|
||||
p->vector);
|
||||
}
|
||||
BIND(&miss);
|
||||
@ -2363,8 +2397,7 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p,
|
||||
}
|
||||
}
|
||||
|
||||
void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p,
|
||||
LanguageMode language_mode) {
|
||||
void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) {
|
||||
Label miss(this, Label::kDeferred);
|
||||
{
|
||||
VARIABLE(var_handler, MachineRepresentation::kTagged);
|
||||
@ -2384,8 +2417,7 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p,
|
||||
BIND(&if_handler);
|
||||
{
|
||||
Comment("KeyedStoreIC_if_handler");
|
||||
HandleStoreICHandlerCase(p, var_handler.value(), &miss, language_mode,
|
||||
kSupportElements);
|
||||
HandleStoreICHandlerCase(p, var_handler.value(), &miss, kSupportElements);
|
||||
}
|
||||
|
||||
BIND(&try_polymorphic);
|
||||
@ -2407,7 +2439,7 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p,
|
||||
WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
|
||||
&try_polymorphic_name);
|
||||
TailCallStub(
|
||||
CodeFactory::KeyedStoreIC_Megamorphic(isolate(), language_mode),
|
||||
Builtins::CallableFor(isolate(), Builtins::kKeyedStoreIC_Megamorphic),
|
||||
p->context, p->receiver, p->name, p->value, p->slot, p->vector);
|
||||
}
|
||||
|
||||
@ -2603,7 +2635,7 @@ void AccessorAssembler::GenerateKeyedLoadIC_Megamorphic() {
|
||||
KeyedLoadICGeneric(&p);
|
||||
}
|
||||
|
||||
void AccessorAssembler::GenerateStoreIC(LanguageMode language_mode) {
|
||||
void AccessorAssembler::GenerateStoreIC() {
|
||||
typedef StoreWithVectorDescriptor Descriptor;
|
||||
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
@ -2614,10 +2646,10 @@ void AccessorAssembler::GenerateStoreIC(LanguageMode language_mode) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
|
||||
StoreICParameters p(context, receiver, name, value, slot, vector);
|
||||
StoreIC(&p, language_mode);
|
||||
StoreIC(&p);
|
||||
}
|
||||
|
||||
void AccessorAssembler::GenerateStoreICTrampoline(LanguageMode language_mode) {
|
||||
void AccessorAssembler::GenerateStoreICTrampoline() {
|
||||
typedef StoreDescriptor Descriptor;
|
||||
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
@ -2627,12 +2659,11 @@ void AccessorAssembler::GenerateStoreICTrampoline(LanguageMode language_mode) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* vector = LoadFeedbackVectorForStub();
|
||||
|
||||
Callable callable =
|
||||
CodeFactory::StoreICInOptimizedCode(isolate(), language_mode);
|
||||
Callable callable = Builtins::CallableFor(isolate(), Builtins::kStoreIC);
|
||||
TailCallStub(callable, context, receiver, name, value, slot, vector);
|
||||
}
|
||||
|
||||
void AccessorAssembler::GenerateKeyedStoreIC(LanguageMode language_mode) {
|
||||
void AccessorAssembler::GenerateKeyedStoreIC() {
|
||||
typedef StoreWithVectorDescriptor Descriptor;
|
||||
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
@ -2643,11 +2674,10 @@ void AccessorAssembler::GenerateKeyedStoreIC(LanguageMode language_mode) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
|
||||
StoreICParameters p(context, receiver, name, value, slot, vector);
|
||||
KeyedStoreIC(&p, language_mode);
|
||||
KeyedStoreIC(&p);
|
||||
}
|
||||
|
||||
void AccessorAssembler::GenerateKeyedStoreICTrampoline(
|
||||
LanguageMode language_mode) {
|
||||
void AccessorAssembler::GenerateKeyedStoreICTrampoline() {
|
||||
typedef StoreDescriptor Descriptor;
|
||||
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
@ -2657,8 +2687,7 @@ void AccessorAssembler::GenerateKeyedStoreICTrampoline(
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* vector = LoadFeedbackVectorForStub();
|
||||
|
||||
Callable callable =
|
||||
CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode);
|
||||
Callable callable = Builtins::CallableFor(isolate(), Builtins::kKeyedStoreIC);
|
||||
TailCallStub(callable, context, receiver, name, value, slot, vector);
|
||||
}
|
||||
|
||||
|
@ -31,16 +31,16 @@ class AccessorAssembler : public CodeStubAssembler {
|
||||
void GenerateKeyedLoadIC();
|
||||
void GenerateKeyedLoadICTrampoline();
|
||||
void GenerateKeyedLoadIC_Megamorphic();
|
||||
void GenerateStoreIC(LanguageMode language_mode);
|
||||
void GenerateStoreICTrampoline(LanguageMode language_mode);
|
||||
void GenerateStoreIC();
|
||||
void GenerateStoreICTrampoline();
|
||||
|
||||
void GenerateLoadICProtoArray(bool throw_reference_error_if_nonexistent);
|
||||
|
||||
void GenerateLoadGlobalIC(TypeofMode typeof_mode);
|
||||
void GenerateLoadGlobalICTrampoline(TypeofMode typeof_mode);
|
||||
|
||||
void GenerateKeyedStoreIC(LanguageMode language_mode);
|
||||
void GenerateKeyedStoreICTrampoline(LanguageMode language_mode);
|
||||
void GenerateKeyedStoreIC();
|
||||
void GenerateKeyedStoreICTrampoline();
|
||||
|
||||
void TryProbeStubCache(StubCache* stub_cache, Node* receiver, Node* name,
|
||||
Label* if_handler, Variable* var_handler,
|
||||
@ -93,10 +93,11 @@ class AccessorAssembler : public CodeStubAssembler {
|
||||
enum ElementSupport { kOnlyProperties, kSupportElements };
|
||||
void HandleStoreICHandlerCase(
|
||||
const StoreICParameters* p, Node* handler, Label* miss,
|
||||
LanguageMode language_mode,
|
||||
ElementSupport support_elements = kOnlyProperties);
|
||||
void JumpIfDataProperty(Node* details, Label* writable, Label* readonly);
|
||||
|
||||
void BranchIfStrictMode(Node* vector, Node* slot, Label* if_strict);
|
||||
|
||||
private:
|
||||
// Stub generation entry points.
|
||||
|
||||
@ -113,8 +114,8 @@ class AccessorAssembler : public CodeStubAssembler {
|
||||
void LoadGlobalIC(const LoadICParameters* p, TypeofMode typeof_mode);
|
||||
void KeyedLoadIC(const LoadICParameters* p);
|
||||
void KeyedLoadICGeneric(const LoadICParameters* p);
|
||||
void StoreIC(const StoreICParameters* p, LanguageMode language_mode);
|
||||
void KeyedStoreIC(const StoreICParameters* p, LanguageMode language_mode);
|
||||
void StoreIC(const StoreICParameters* p);
|
||||
void KeyedStoreIC(const StoreICParameters* p);
|
||||
|
||||
// IC dispatcher behavior.
|
||||
|
||||
@ -165,8 +166,7 @@ class AccessorAssembler : public CodeStubAssembler {
|
||||
Node* handler, Label* miss);
|
||||
|
||||
void HandleStoreICProtoHandler(const StoreICParameters* p, Node* handler,
|
||||
Label* miss, ElementSupport support_elements,
|
||||
LanguageMode language_mode);
|
||||
Label* miss, ElementSupport support_elements);
|
||||
// If |transition| is nullptr then the normal field store is generated or
|
||||
// transitioning store otherwise.
|
||||
void HandleStoreICSmiHandlerCase(Node* handler_word, Node* holder,
|
||||
@ -178,8 +178,7 @@ class AccessorAssembler : public CodeStubAssembler {
|
||||
Node* transition, Label* miss);
|
||||
|
||||
void HandleStoreToProxy(const StoreICParameters* p, Node* proxy, Label* miss,
|
||||
ElementSupport support_elements,
|
||||
LanguageMode language_mode);
|
||||
ElementSupport support_elements);
|
||||
|
||||
// KeyedLoadIC_Generic implementation.
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "src/code-factory.h"
|
||||
#include "src/code-stub-assembler.h"
|
||||
#include "src/contexts.h"
|
||||
#include "src/feedback-vector.h"
|
||||
#include "src/ic/accessor-assembler.h"
|
||||
#include "src/interface-descriptors.h"
|
||||
#include "src/isolate.h"
|
||||
@ -22,9 +23,9 @@ class KeyedStoreGenericAssembler : public AccessorAssembler {
|
||||
explicit KeyedStoreGenericAssembler(compiler::CodeAssemblerState* state)
|
||||
: AccessorAssembler(state) {}
|
||||
|
||||
void KeyedStoreGeneric(LanguageMode language_mode);
|
||||
void KeyedStoreGeneric();
|
||||
|
||||
void StoreIC_Uninitialized(LanguageMode language_mode);
|
||||
void StoreIC_Uninitialized();
|
||||
|
||||
private:
|
||||
enum UpdateLength {
|
||||
@ -41,7 +42,6 @@ class KeyedStoreGenericAssembler : public AccessorAssembler {
|
||||
|
||||
void EmitGenericPropertyStore(Node* receiver, Node* receiver_map,
|
||||
const StoreICParameters* p, Label* slow,
|
||||
LanguageMode language_mode,
|
||||
UseStubCache use_stub_cache = kUseStubCache);
|
||||
|
||||
void BranchIfPrototypesHaveNonFastElements(Node* receiver_map,
|
||||
@ -86,16 +86,15 @@ class KeyedStoreGenericAssembler : public AccessorAssembler {
|
||||
Node* value, Label* slow);
|
||||
};
|
||||
|
||||
void KeyedStoreGenericGenerator::Generate(compiler::CodeAssemblerState* state,
|
||||
LanguageMode language_mode) {
|
||||
void KeyedStoreGenericGenerator::Generate(compiler::CodeAssemblerState* state) {
|
||||
KeyedStoreGenericAssembler assembler(state);
|
||||
assembler.KeyedStoreGeneric(language_mode);
|
||||
assembler.KeyedStoreGeneric();
|
||||
}
|
||||
|
||||
void StoreICUninitializedGenerator::Generate(
|
||||
compiler::CodeAssemblerState* state, LanguageMode language_mode) {
|
||||
compiler::CodeAssemblerState* state) {
|
||||
KeyedStoreGenericAssembler assembler(state);
|
||||
assembler.StoreIC_Uninitialized(language_mode);
|
||||
assembler.StoreIC_Uninitialized();
|
||||
}
|
||||
|
||||
void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements(
|
||||
@ -746,7 +745,7 @@ void KeyedStoreGenericAssembler::OverwriteExistingFastProperty(
|
||||
|
||||
void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
|
||||
Node* receiver, Node* receiver_map, const StoreICParameters* p, Label* slow,
|
||||
LanguageMode language_mode, UseStubCache use_stub_cache) {
|
||||
UseStubCache use_stub_cache) {
|
||||
VARIABLE(var_accessor_pair, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_accessor_holder, MachineRepresentation::kTagged);
|
||||
Label stub_cache(this), fast_properties(this), dictionary_properties(this),
|
||||
@ -841,8 +840,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
|
||||
BIND(&found_handler);
|
||||
{
|
||||
Comment("KeyedStoreGeneric found transition handler");
|
||||
HandleStoreICHandlerCase(p, var_handler.value(), notfound,
|
||||
language_mode);
|
||||
HandleStoreICHandlerCase(p, var_handler.value(), notfound);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -916,27 +914,31 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
|
||||
|
||||
BIND(¬_callable);
|
||||
{
|
||||
if (language_mode == STRICT) {
|
||||
Label strict(this);
|
||||
BranchIfStrictMode(p->vector, p->slot, &strict);
|
||||
Return(p->value);
|
||||
|
||||
BIND(&strict);
|
||||
{
|
||||
Node* message = SmiConstant(MessageTemplate::kNoSetterInCallback);
|
||||
TailCallRuntime(Runtime::kThrowTypeError, p->context, message, p->name,
|
||||
var_accessor_holder.value());
|
||||
} else {
|
||||
DCHECK_EQ(SLOPPY, language_mode);
|
||||
Return(p->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&readonly);
|
||||
{
|
||||
if (language_mode == STRICT) {
|
||||
Label strict(this);
|
||||
BranchIfStrictMode(p->vector, p->slot, &strict);
|
||||
Return(p->value);
|
||||
|
||||
BIND(&strict);
|
||||
{
|
||||
Node* message = SmiConstant(MessageTemplate::kStrictReadOnlyProperty);
|
||||
Node* type = Typeof(p->receiver);
|
||||
TailCallRuntime(Runtime::kThrowTypeError, p->context, message, p->name,
|
||||
type, p->receiver);
|
||||
} else {
|
||||
DCHECK_EQ(SLOPPY, language_mode);
|
||||
Return(p->value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -950,8 +952,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
|
||||
BIND(&found_handler);
|
||||
{
|
||||
Comment("KeyedStoreGeneric found handler");
|
||||
HandleStoreICHandlerCase(p, var_handler.value(), &stub_cache_miss,
|
||||
language_mode);
|
||||
HandleStoreICHandlerCase(p, var_handler.value(), &stub_cache_miss);
|
||||
}
|
||||
BIND(&stub_cache_miss);
|
||||
{
|
||||
@ -962,7 +963,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
|
||||
}
|
||||
}
|
||||
|
||||
void KeyedStoreGenericAssembler::KeyedStoreGeneric(LanguageMode language_mode) {
|
||||
void KeyedStoreGenericAssembler::KeyedStoreGeneric() {
|
||||
typedef StoreWithVectorDescriptor Descriptor;
|
||||
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
@ -1000,19 +1001,25 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric(LanguageMode language_mode) {
|
||||
Comment("key is unique name");
|
||||
StoreICParameters p(context, receiver, var_unique.value(), value, slot,
|
||||
vector);
|
||||
EmitGenericPropertyStore(receiver, receiver_map, &p, &slow, language_mode);
|
||||
EmitGenericPropertyStore(receiver, receiver_map, &p, &slow);
|
||||
}
|
||||
|
||||
BIND(&slow);
|
||||
{
|
||||
Comment("KeyedStoreGeneric_slow");
|
||||
VARIABLE(var_language_mode, MachineRepresentation::kTaggedSigned,
|
||||
SmiConstant(STRICT));
|
||||
Label call_runtime(this);
|
||||
BranchIfStrictMode(vector, slot, &call_runtime);
|
||||
var_language_mode.Bind(SmiConstant(SLOPPY));
|
||||
Goto(&call_runtime);
|
||||
BIND(&call_runtime);
|
||||
TailCallRuntime(Runtime::kSetProperty, context, receiver, name, value,
|
||||
SmiConstant(language_mode));
|
||||
var_language_mode.value());
|
||||
}
|
||||
}
|
||||
|
||||
void KeyedStoreGenericAssembler::StoreIC_Uninitialized(
|
||||
LanguageMode language_mode) {
|
||||
void KeyedStoreGenericAssembler::StoreIC_Uninitialized() {
|
||||
typedef StoreWithVectorDescriptor Descriptor;
|
||||
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
@ -1022,14 +1029,13 @@ void KeyedStoreGenericAssembler::StoreIC_Uninitialized(
|
||||
Node* vector = Parameter(Descriptor::kVector);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
|
||||
Label miss(this), if_proxy(this, Label::kDeferred);
|
||||
Label miss(this);
|
||||
|
||||
GotoIf(TaggedIsSmi(receiver), &miss);
|
||||
Node* receiver_map = LoadMap(receiver);
|
||||
Node* instance_type = LoadMapInstanceType(receiver_map);
|
||||
GotoIf(Word32Equal(instance_type, Int32Constant(JS_PROXY_TYPE)), &if_proxy);
|
||||
// Receivers requiring non-standard element accesses (interceptors, access
|
||||
// checks, strings and string wrappers) are handled in the runtime.
|
||||
// checks, strings and string wrappers, proxies) are handled in the runtime.
|
||||
GotoIf(Int32LessThanOrEqual(instance_type,
|
||||
Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
|
||||
&miss);
|
||||
@ -1040,15 +1046,9 @@ void KeyedStoreGenericAssembler::StoreIC_Uninitialized(
|
||||
SKIP_WRITE_BARRIER, 0, SMI_PARAMETERS);
|
||||
|
||||
StoreICParameters p(context, receiver, name, value, slot, vector);
|
||||
EmitGenericPropertyStore(receiver, receiver_map, &p, &miss, language_mode,
|
||||
EmitGenericPropertyStore(receiver, receiver_map, &p, &miss,
|
||||
kDontUseStubCache);
|
||||
|
||||
BIND(&if_proxy);
|
||||
{
|
||||
CallBuiltin(Builtins::kProxySetProperty, context, receiver, name, value,
|
||||
receiver, SmiConstant(language_mode));
|
||||
Return(value);
|
||||
}
|
||||
BIND(&miss);
|
||||
{
|
||||
// Undo the optimistic state transition.
|
||||
|
@ -16,14 +16,12 @@ class CodeAssemblerState;
|
||||
|
||||
class KeyedStoreGenericGenerator {
|
||||
public:
|
||||
static void Generate(compiler::CodeAssemblerState* state,
|
||||
LanguageMode language_mode);
|
||||
static void Generate(compiler::CodeAssemblerState* state);
|
||||
};
|
||||
|
||||
class StoreICUninitializedGenerator {
|
||||
public:
|
||||
static void Generate(compiler::CodeAssemblerState* state,
|
||||
LanguageMode language_mode);
|
||||
static void Generate(compiler::CodeAssemblerState* state);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -829,20 +829,16 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CollectTypeProfile(int position) {
|
||||
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
|
||||
Register object, size_t name_index, int feedback_slot,
|
||||
LanguageMode language_mode) {
|
||||
#if DEBUG
|
||||
// Ensure that language mode is in sync with the IC slot kind if the function
|
||||
// literal is available (not a unit test case).
|
||||
// TODO(ishell): check only in debug mode.
|
||||
if (literal_) {
|
||||
FeedbackSlot slot = FeedbackVector::ToSlot(feedback_slot);
|
||||
CHECK_EQ(GetLanguageModeFromSlotKind(feedback_vector_spec()->GetKind(slot)),
|
||||
language_mode);
|
||||
}
|
||||
if (language_mode == SLOPPY) {
|
||||
OutputStaNamedPropertySloppy(object, name_index, feedback_slot);
|
||||
} else {
|
||||
DCHECK_EQ(language_mode, STRICT);
|
||||
OutputStaNamedPropertyStrict(object, name_index, feedback_slot);
|
||||
}
|
||||
#endif
|
||||
OutputStaNamedProperty(object, name_index, feedback_slot);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -856,14 +852,15 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
|
||||
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedOwnProperty(
|
||||
Register object, const AstRawString* name, int feedback_slot) {
|
||||
size_t name_index = GetConstantPoolEntry(name);
|
||||
#if DEBUG
|
||||
// Ensure that the store operation is in sync with the IC slot kind if
|
||||
// the function literal is available (not a unit test case).
|
||||
// TODO(ishell): check only in debug mode.
|
||||
if (literal_) {
|
||||
FeedbackSlot slot = FeedbackVector::ToSlot(feedback_slot);
|
||||
CHECK_EQ(FeedbackSlotKind::kStoreOwnNamed,
|
||||
feedback_vector_spec()->GetKind(slot));
|
||||
}
|
||||
#endif
|
||||
OutputStaNamedOwnProperty(object, name_index, feedback_slot);
|
||||
return *this;
|
||||
}
|
||||
@ -871,20 +868,16 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedOwnProperty(
|
||||
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
|
||||
Register object, Register key, int feedback_slot,
|
||||
LanguageMode language_mode) {
|
||||
#if DEBUG
|
||||
// Ensure that language mode is in sync with the IC slot kind if the function
|
||||
// literal is available (not a unit test case).
|
||||
// TODO(ishell): check only in debug mode.
|
||||
if (literal_) {
|
||||
FeedbackSlot slot = FeedbackVector::ToSlot(feedback_slot);
|
||||
CHECK_EQ(GetLanguageModeFromSlotKind(feedback_vector_spec()->GetKind(slot)),
|
||||
language_mode);
|
||||
}
|
||||
if (language_mode == SLOPPY) {
|
||||
OutputStaKeyedPropertySloppy(object, key, feedback_slot);
|
||||
} else {
|
||||
DCHECK_EQ(language_mode, STRICT);
|
||||
OutputStaKeyedPropertyStrict(object, key, feedback_slot);
|
||||
}
|
||||
#endif
|
||||
OutputStaKeyedProperty(object, key, feedback_slot);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -93,15 +93,11 @@ namespace interpreter {
|
||||
OperandType::kUImm) \
|
||||
\
|
||||
/* Propery stores (StoreIC) operations */ \
|
||||
V(StaNamedPropertySloppy, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
OperandType::kIdx, OperandType::kIdx) \
|
||||
V(StaNamedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
V(StaNamedProperty, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
OperandType::kIdx, OperandType::kIdx) \
|
||||
V(StaNamedOwnProperty, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
OperandType::kIdx, OperandType::kIdx) \
|
||||
V(StaKeyedPropertySloppy, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
OperandType::kReg, OperandType::kIdx) \
|
||||
V(StaKeyedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
V(StaKeyedProperty, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
OperandType::kReg, OperandType::kIdx) \
|
||||
V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg, \
|
||||
OperandType::kReg, OperandType::kFlag8, OperandType::kIdx) \
|
||||
|
@ -635,25 +635,13 @@ class InterpreterStoreNamedPropertyAssembler : public InterpreterAssembler {
|
||||
}
|
||||
};
|
||||
|
||||
// StaNamedPropertySloppy <object> <name_index> <slot>
|
||||
// StaNamedProperty <object> <name_index> <slot>
|
||||
//
|
||||
// Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and
|
||||
// Calls the StoreIC at FeedBackVector slot <slot> for <object> and
|
||||
// the name in constant pool entry <name_index> with the value in the
|
||||
// accumulator.
|
||||
IGNITION_HANDLER(StaNamedPropertySloppy,
|
||||
InterpreterStoreNamedPropertyAssembler) {
|
||||
Callable ic = CodeFactory::StoreICInOptimizedCode(isolate(), SLOPPY);
|
||||
StaNamedProperty(ic);
|
||||
}
|
||||
|
||||
// StaNamedPropertyStrict <object> <name_index> <slot>
|
||||
//
|
||||
// Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
|
||||
// the name in constant pool entry <name_index> with the value in the
|
||||
// accumulator.
|
||||
IGNITION_HANDLER(StaNamedPropertyStrict,
|
||||
InterpreterStoreNamedPropertyAssembler) {
|
||||
Callable ic = CodeFactory::StoreICInOptimizedCode(isolate(), STRICT);
|
||||
IGNITION_HANDLER(StaNamedProperty, InterpreterStoreNamedPropertyAssembler) {
|
||||
Callable ic = Builtins::CallableFor(isolate(), Builtins::kStoreIC);
|
||||
StaNamedProperty(ic);
|
||||
}
|
||||
|
||||
@ -667,48 +655,25 @@ IGNITION_HANDLER(StaNamedOwnProperty, InterpreterStoreNamedPropertyAssembler) {
|
||||
StaNamedProperty(ic);
|
||||
}
|
||||
|
||||
class InterpreterStoreKeyedPropertyAssembler : public InterpreterAssembler {
|
||||
public:
|
||||
InterpreterStoreKeyedPropertyAssembler(CodeAssemblerState* state,
|
||||
Bytecode bytecode,
|
||||
OperandScale operand_scale)
|
||||
: InterpreterAssembler(state, bytecode, operand_scale) {}
|
||||
|
||||
void StaKeyedProperty(Callable ic) {
|
||||
Node* code_target = HeapConstant(ic.code());
|
||||
Node* object_reg_index = BytecodeOperandReg(0);
|
||||
Node* object = LoadRegister(object_reg_index);
|
||||
Node* name_reg_index = BytecodeOperandReg(1);
|
||||
Node* name = LoadRegister(name_reg_index);
|
||||
Node* value = GetAccumulator();
|
||||
Node* raw_slot = BytecodeOperandIdx(2);
|
||||
Node* smi_slot = SmiTag(raw_slot);
|
||||
Node* feedback_vector = LoadFeedbackVector();
|
||||
Node* context = GetContext();
|
||||
CallStub(ic.descriptor(), code_target, context, object, name, value,
|
||||
smi_slot, feedback_vector);
|
||||
Dispatch();
|
||||
}
|
||||
};
|
||||
|
||||
// StaKeyedPropertySloppy <object> <key> <slot>
|
||||
// StaKeyedProperty <object> <key> <slot>
|
||||
//
|
||||
// Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object>
|
||||
// and the key <key> with the value in the accumulator.
|
||||
IGNITION_HANDLER(StaKeyedPropertySloppy,
|
||||
InterpreterStoreKeyedPropertyAssembler) {
|
||||
Callable ic = CodeFactory::KeyedStoreICInOptimizedCode(isolate(), SLOPPY);
|
||||
StaKeyedProperty(ic);
|
||||
}
|
||||
|
||||
// StaKeyedPropertyStrict <object> <key> <slot>
|
||||
//
|
||||
// Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
|
||||
// and the key <key> with the value in the accumulator.
|
||||
IGNITION_HANDLER(StaKeyedPropertyStrict,
|
||||
InterpreterStoreKeyedPropertyAssembler) {
|
||||
Callable ic = CodeFactory::KeyedStoreICInOptimizedCode(isolate(), STRICT);
|
||||
StaKeyedProperty(ic);
|
||||
// Calls the KeyedStoreIC at FeedbackVector slot <slot> for <object> and
|
||||
// the key <key> with the value in the accumulator.
|
||||
IGNITION_HANDLER(StaKeyedProperty, InterpreterAssembler) {
|
||||
Callable ic = Builtins::CallableFor(isolate(), Builtins::kKeyedStoreIC);
|
||||
Node* code_target = HeapConstant(ic.code());
|
||||
Node* object_reg_index = BytecodeOperandReg(0);
|
||||
Node* object = LoadRegister(object_reg_index);
|
||||
Node* name_reg_index = BytecodeOperandReg(1);
|
||||
Node* name = LoadRegister(name_reg_index);
|
||||
Node* value = GetAccumulator();
|
||||
Node* raw_slot = BytecodeOperandIdx(2);
|
||||
Node* smi_slot = SmiTag(raw_slot);
|
||||
Node* feedback_vector = LoadFeedbackVector();
|
||||
Node* context = GetContext();
|
||||
CallStub(ic.descriptor(), code_target, context, object, name, value, smi_slot,
|
||||
feedback_vector);
|
||||
Dispatch();
|
||||
}
|
||||
|
||||
// StaDataPropertyInLiteral <object> <name> <flags>
|
||||
|
@ -39,12 +39,12 @@ bytecodes: [
|
||||
B(LdaZero),
|
||||
B(Star), R(1),
|
||||
B(Ldar), R(0),
|
||||
/* 54 E> */ B(StaKeyedPropertySloppy), R(2), R(1), U8(2),
|
||||
/* 54 E> */ B(StaKeyedProperty), R(2), R(1), U8(2),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(1),
|
||||
B(Ldar), R(0),
|
||||
/* 59 E> */ B(AddSmi), I8(1), U8(0),
|
||||
B(StaKeyedPropertySloppy), R(2), R(1), U8(2),
|
||||
B(StaKeyedProperty), R(2), R(1), U8(2),
|
||||
B(Ldar), R(2),
|
||||
/* 65 S> */ B(Return),
|
||||
]
|
||||
@ -92,9 +92,9 @@ bytecodes: [
|
||||
B(LdaZero),
|
||||
B(Star), R(3),
|
||||
B(Ldar), R(0),
|
||||
/* 56 E> */ B(StaKeyedPropertySloppy), R(4), R(3), U8(1),
|
||||
/* 56 E> */ B(StaKeyedProperty), R(4), R(3), U8(1),
|
||||
B(Ldar), R(4),
|
||||
B(StaKeyedPropertySloppy), R(2), R(1), U8(8),
|
||||
B(StaKeyedProperty), R(2), R(1), U8(8),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Star), R(1),
|
||||
B(CreateArrayLiteral), U8(2), U8(4), U8(37),
|
||||
@ -103,9 +103,9 @@ bytecodes: [
|
||||
B(Star), R(3),
|
||||
B(Ldar), R(0),
|
||||
/* 68 E> */ B(AddSmi), I8(2), U8(3),
|
||||
B(StaKeyedPropertySloppy), R(4), R(3), U8(5),
|
||||
B(StaKeyedProperty), R(4), R(3), U8(5),
|
||||
B(Ldar), R(4),
|
||||
B(StaKeyedPropertySloppy), R(2), R(1), U8(8),
|
||||
B(StaKeyedProperty), R(2), R(1), U8(8),
|
||||
B(Ldar), R(2),
|
||||
/* 76 S> */ B(Return),
|
||||
]
|
||||
|
@ -123,7 +123,7 @@ bytecodes: [
|
||||
/* 128 S> */ B(Ldar), R(this),
|
||||
B(ThrowSuperNotCalledIfHole),
|
||||
B(LdaSmi), I8(2),
|
||||
/* 136 E> */ B(StaNamedPropertyStrict), R(2), U8(0), U8(2),
|
||||
/* 136 E> */ B(StaNamedProperty), R(2), U8(0), U8(2),
|
||||
B(Ldar), R(this),
|
||||
B(ThrowSuperNotCalledIfHole),
|
||||
/* 141 S> */ B(Return),
|
||||
@ -164,7 +164,7 @@ bytecodes: [
|
||||
/* 126 S> */ B(Ldar), R(this),
|
||||
B(ThrowSuperNotCalledIfHole),
|
||||
B(LdaSmi), I8(2),
|
||||
/* 134 E> */ B(StaNamedPropertyStrict), R(2), U8(0), U8(2),
|
||||
/* 134 E> */ B(StaNamedProperty), R(2), U8(0), U8(2),
|
||||
B(Ldar), R(this),
|
||||
B(ThrowSuperNotCalledIfHole),
|
||||
/* 139 S> */ B(Return),
|
||||
|
@ -60,7 +60,7 @@ bytecodes: [
|
||||
B(Mov), R(1), R(0),
|
||||
/* 54 S> */ B(LdaNamedProperty), R(1), U8(1), U8(1),
|
||||
B(MulSmi), I8(2), U8(3),
|
||||
/* 61 E> */ B(StaNamedPropertySloppy), R(1), U8(1), U8(4),
|
||||
/* 61 E> */ B(StaNamedProperty), R(1), U8(1), U8(4),
|
||||
B(LdaUndefined),
|
||||
/* 67 S> */ B(Return),
|
||||
]
|
||||
@ -86,7 +86,7 @@ bytecodes: [
|
||||
B(Star), R(2),
|
||||
B(LdaKeyedProperty), R(1), U8(1),
|
||||
B(BitwiseXorSmi), I8(2), U8(3),
|
||||
/* 57 E> */ B(StaKeyedPropertySloppy), R(1), R(2), U8(4),
|
||||
/* 57 E> */ B(StaKeyedProperty), R(1), R(2), U8(4),
|
||||
B(LdaUndefined),
|
||||
/* 63 S> */ B(Return),
|
||||
]
|
||||
|
@ -106,7 +106,7 @@ bytecodes: [
|
||||
B(ToNumber), R(2), U8(5),
|
||||
B(Ldar), R(2),
|
||||
B(Inc), U8(5),
|
||||
/* 66 E> */ B(StaNamedPropertySloppy), R(1), U8(1), U8(3),
|
||||
/* 66 E> */ B(StaNamedProperty), R(1), U8(1), U8(3),
|
||||
B(Ldar), R(2),
|
||||
/* 69 S> */ B(Return),
|
||||
]
|
||||
@ -130,7 +130,7 @@ bytecodes: [
|
||||
B(Mov), R(1), R(0),
|
||||
/* 54 S> */ B(LdaNamedProperty), R(1), U8(1), U8(1),
|
||||
B(Dec), U8(5),
|
||||
/* 65 E> */ B(StaNamedPropertySloppy), R(1), U8(1), U8(3),
|
||||
/* 65 E> */ B(StaNamedProperty), R(1), U8(1), U8(3),
|
||||
/* 69 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
@ -158,7 +158,7 @@ bytecodes: [
|
||||
B(ToNumber), R(4), U8(5),
|
||||
B(Ldar), R(4),
|
||||
B(Dec), U8(5),
|
||||
/* 86 E> */ B(StaKeyedPropertySloppy), R(2), R(0), U8(3),
|
||||
/* 86 E> */ B(StaKeyedProperty), R(2), R(0), U8(3),
|
||||
B(Ldar), R(4),
|
||||
/* 89 S> */ B(Return),
|
||||
]
|
||||
@ -185,7 +185,7 @@ bytecodes: [
|
||||
/* 72 S> */ B(Ldar), R(0),
|
||||
/* 83 E> */ B(LdaKeyedProperty), R(2), U8(1),
|
||||
B(Inc), U8(5),
|
||||
/* 87 E> */ B(StaKeyedPropertySloppy), R(2), R(0), U8(3),
|
||||
/* 87 E> */ B(StaKeyedProperty), R(2), R(0), U8(3),
|
||||
/* 89 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
@ -269,7 +269,7 @@ bytecodes: [
|
||||
B(Inc), U8(1),
|
||||
B(Star), R(0),
|
||||
B(LdaSmi), I8(2),
|
||||
/* 79 E> */ B(StaKeyedPropertySloppy), R(1), R(3), U8(2),
|
||||
/* 79 E> */ B(StaKeyedProperty), R(1), R(3), U8(2),
|
||||
/* 83 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
|
@ -984,7 +984,7 @@ bytecodes: [
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(4),
|
||||
B(Ldar), R(5),
|
||||
B(StaNamedPropertySloppy), R(1), U8(6), U8(14),
|
||||
B(StaNamedProperty), R(1), U8(6), U8(14),
|
||||
/* 53 E> */ B(StackCheck),
|
||||
/* 87 S> */ B(LdaNamedProperty), R(1), U8(6), U8(16),
|
||||
B(Star), R(14),
|
||||
|
@ -167,7 +167,7 @@ bytecodes: [
|
||||
B(JumpIfUndefined), U8(41),
|
||||
B(Star), R(6),
|
||||
B(Ldar), R(6),
|
||||
/* 67 E> */ B(StaNamedPropertySloppy), R(0), U8(2), U8(10),
|
||||
/* 67 E> */ B(StaNamedProperty), R(0), U8(2), U8(10),
|
||||
/* 62 E> */ B(StackCheck),
|
||||
/* 100 S> */ B(LdaNamedProperty), R(0), U8(2), U8(4),
|
||||
B(Star), R(6),
|
||||
@ -223,7 +223,7 @@ bytecodes: [
|
||||
B(LdaZero),
|
||||
B(Star), R(8),
|
||||
B(Ldar), R(6),
|
||||
/* 64 E> */ B(StaKeyedPropertySloppy), R(0), R(8), U8(6),
|
||||
/* 64 E> */ B(StaKeyedProperty), R(0), R(8), U8(6),
|
||||
/* 59 E> */ B(StackCheck),
|
||||
/* 83 S> */ B(LdaSmi), I8(3),
|
||||
/* 91 E> */ B(LdaKeyedProperty), R(0), U8(4),
|
||||
|
@ -476,7 +476,7 @@ bytecodes: [
|
||||
B(LdaSmi), I8(2),
|
||||
B(Star), R(3),
|
||||
B(Ldar), R(4),
|
||||
B(StaNamedPropertySloppy), R(0), U8(6), U8(14),
|
||||
B(StaNamedProperty), R(0), U8(6), U8(14),
|
||||
/* 62 E> */ B(StackCheck),
|
||||
/* 96 S> */ B(LdaNamedProperty), R(0), U8(6), U8(16),
|
||||
B(Star), R(8),
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,7 +42,8 @@ MODES = ["release", "debug", "optdebug"]
|
||||
# Modes that get built/run when you don't specify any.
|
||||
DEFAULT_MODES = ["release", "debug"]
|
||||
# Build targets that can be manually specified.
|
||||
TARGETS = ["d8", "cctest", "unittests", "v8_fuzzers", "mkgrokdump"]
|
||||
TARGETS = ["d8", "cctest", "unittests", "v8_fuzzers", "mkgrokdump",
|
||||
"generate-bytecode-expectations"]
|
||||
# Build targets that get built when you don't specify any (and specified tests
|
||||
# don't imply any other targets).
|
||||
DEFAULT_TARGETS = ["d8"]
|
||||
|
Loading…
Reference in New Issue
Block a user