[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:
Jakob Kummerow 2017-09-01 17:52:16 -07:00 committed by Commit Bot
parent 62fee3b64c
commit cfcdeab002
27 changed files with 770 additions and 885 deletions

View File

@ -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) \

View File

@ -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) {

View File

@ -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,

View File

@ -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));
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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,

View File

@ -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));

View File

@ -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);
}

View File

@ -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.

View File

@ -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(&not_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.

View File

@ -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

View File

@ -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;
}

View File

@ -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) \

View File

@ -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>

View File

@ -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),
]

View File

@ -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),

View File

@ -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),
]

View File

@ -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: [

View File

@ -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),

View File

@ -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),

View File

@ -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),

View File

@ -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"]