Commit 7c4cc5ed authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

Revert "[nci] Prepare JSForInPrepare and JSForInNext for feedback input"

This reverts commit 16cd5995.

Reason for revert: Can't be landed without also implementing generic lowering, see https://ci.chromium.org/p/v8/builders/ci/V8%20Linux64%20-%20fyi/18261.

Original change's description:
> [nci] Prepare JSForInPrepare and JSForInNext for feedback input
>
> These two operators are still missing feedback collection in generic
> lowering (reminder: all operations that collect FB in the interpreter
> must also collect FB in generic lowering).
>
> This CL prepares for that by adding the feedback vector as an input,
> and additionally adds node wrappers to improve useability.
>
> The actual collection logic will be added in a following CL.
>
> Bug: v8:8888
> Change-Id: I04627eedb2dc237dc4e417091c44d2a95bd98f5f
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2454712
> Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#70372}

TBR=jgruber@chromium.org,leszeks@chromium.org,tebbi@chromium.org

Change-Id: Ibff2bf44eb04bebd982b019b4539275db75c611a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:8888
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2454078Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70376}
parent 4cb4a229
...@@ -284,7 +284,7 @@ class BytecodeGraphBuilder { ...@@ -284,7 +284,7 @@ class BytecodeGraphBuilder {
uint32_t depth); uint32_t depth);
// Helper function to create for-in mode from the recorded type feedback. // Helper function to create for-in mode from the recorded type feedback.
ForInMode GetForInMode(FeedbackSlot slot); ForInMode GetForInMode(int operand_index);
// Helper function to compute call frequency from the recorded type // Helper function to compute call frequency from the recorded type
// feedback. Returns unknown if invocation count is unknown. Returns 0 if // feedback. Returns unknown if invocation count is unknown. Returns 0 if
...@@ -2932,7 +2932,8 @@ void BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) { ...@@ -2932,7 +2932,8 @@ void BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) {
} }
// Helper function to create for-in mode from the recorded type feedback. // Helper function to create for-in mode from the recorded type feedback.
ForInMode BytecodeGraphBuilder::GetForInMode(FeedbackSlot slot) { ForInMode BytecodeGraphBuilder::GetForInMode(int operand_index) {
FeedbackSlot slot = bytecode_iterator().GetSlotOperand(operand_index);
FeedbackSource source(feedback_vector(), slot); FeedbackSource source(feedback_vector(), slot);
switch (broker()->GetFeedbackForForIn(source)) { switch (broker()->GetFeedbackForForIn(source)) {
case ForInHint::kNone: case ForInHint::kNone:
...@@ -3589,9 +3590,7 @@ void BytecodeGraphBuilder::VisitForInPrepare() { ...@@ -3589,9 +3590,7 @@ void BytecodeGraphBuilder::VisitForInPrepare() {
TryBuildSimplifiedForInPrepare(enumerator, slot); TryBuildSimplifiedForInPrepare(enumerator, slot);
if (lowering.IsExit()) return; if (lowering.IsExit()) return;
DCHECK(!lowering.Changed()); DCHECK(!lowering.Changed());
FeedbackSource feedback = CreateFeedbackSource(slot); Node* node = NewNode(javascript()->ForInPrepare(GetForInMode(1)), enumerator);
Node* node = NewNode(javascript()->ForInPrepare(GetForInMode(slot), feedback),
enumerator, feedback_vector_node());
environment()->BindRegistersToProjections( environment()->BindRegistersToProjections(
bytecode_iterator().GetRegisterOperand(0), node); bytecode_iterator().GetRegisterOperand(0), node);
} }
...@@ -3620,7 +3619,7 @@ void BytecodeGraphBuilder::VisitForInNext() { ...@@ -3620,7 +3619,7 @@ void BytecodeGraphBuilder::VisitForInNext() {
Node* cache_array = environment()->LookupRegister( Node* cache_array = environment()->LookupRegister(
interpreter::Register(catch_reg_pair_index + 1)); interpreter::Register(catch_reg_pair_index + 1));
// We need to rename the {index} here, as in case of OSR we lose the // We need to rename the {index} here, as in case of OSR we loose the
// information that the {index} is always a valid unsigned Smi value. // information that the {index} is always a valid unsigned Smi value.
index = NewNode(common()->TypeGuard(Type::UnsignedSmall()), index); index = NewNode(common()->TypeGuard(Type::UnsignedSmall()), index);
...@@ -3630,10 +3629,8 @@ void BytecodeGraphBuilder::VisitForInNext() { ...@@ -3630,10 +3629,8 @@ void BytecodeGraphBuilder::VisitForInNext() {
if (lowering.IsExit()) return; if (lowering.IsExit()) return;
DCHECK(!lowering.Changed()); DCHECK(!lowering.Changed());
FeedbackSource feedback = CreateFeedbackSource(slot); Node* node = NewNode(javascript()->ForInNext(GetForInMode(3)), receiver,
Node* node = cache_array, cache_type, index);
NewNode(javascript()->ForInNext(GetForInMode(slot), feedback), receiver,
cache_array, cache_type, index, feedback_vector_node());
environment()->BindAccumulator(node, Environment::kAttachFrameState); environment()->BindAccumulator(node, Environment::kAttachFrameState);
} }
......
...@@ -2901,10 +2901,10 @@ Reduction JSCallReducer::ReduceObjectPrototypeHasOwnProperty(Node* node) { ...@@ -2901,10 +2901,10 @@ Reduction JSCallReducer::ReduceObjectPrototypeHasOwnProperty(Node* node) {
// Object.prototype.hasOwnProperty does an implicit ToObject anyway, and // Object.prototype.hasOwnProperty does an implicit ToObject anyway, and
// these operations are not observable. // these operations are not observable.
if (name->opcode() == IrOpcode::kJSForInNext) { if (name->opcode() == IrOpcode::kJSForInNext) {
JSForInNextNode n(name); ForInMode const mode = ForInModeOf(name->op());
if (n.Parameters().mode() != ForInMode::kGeneric) { if (mode != ForInMode::kGeneric) {
Node* object = n.receiver(); Node* object = NodeProperties::GetValueInput(name, 0);
Node* cache_type = n.cache_type(); Node* cache_type = NodeProperties::GetValueInput(name, 2);
if (object->opcode() == IrOpcode::kJSToObject) { if (object->opcode() == IrOpcode::kJSToObject) {
object = NodeProperties::GetValueInput(object, 0); object = NodeProperties::GetValueInput(object, 0);
} }
......
...@@ -2008,17 +2008,18 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadPropertyWithEnumeratedKey( ...@@ -2008,17 +2008,18 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadPropertyWithEnumeratedKey(
DCHECK_EQ(IrOpcode::kJSLoadProperty, node->opcode()); DCHECK_EQ(IrOpcode::kJSLoadProperty, node->opcode());
Node* receiver = NodeProperties::GetValueInput(node, 0); Node* receiver = NodeProperties::GetValueInput(node, 0);
JSForInNextNode name(NodeProperties::GetValueInput(node, 1)); Node* name = NodeProperties::GetValueInput(node, 1);
DCHECK_EQ(IrOpcode::kJSForInNext, name->opcode());
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
if (name.Parameters().mode() != ForInMode::kUseEnumCacheKeysAndIndices) { if (ForInModeOf(name->op()) != ForInMode::kUseEnumCacheKeysAndIndices) {
return NoChange(); return NoChange();
} }
Node* object = name.receiver(); Node* object = NodeProperties::GetValueInput(name, 0);
Node* cache_type = name.cache_type(); Node* enumerator = NodeProperties::GetValueInput(name, 2);
Node* index = name.index(); Node* key = NodeProperties::GetValueInput(name, 3);
if (object->opcode() == IrOpcode::kJSToObject) { if (object->opcode() == IrOpcode::kJSToObject) {
object = NodeProperties::GetValueInput(object, 0); object = NodeProperties::GetValueInput(object, 0);
} }
...@@ -2032,7 +2033,7 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadPropertyWithEnumeratedKey( ...@@ -2032,7 +2033,7 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadPropertyWithEnumeratedKey(
graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
receiver, effect, control); receiver, effect, control);
Node* check = graph()->NewNode(simplified()->ReferenceEqual(), receiver_map, Node* check = graph()->NewNode(simplified()->ReferenceEqual(), receiver_map,
cache_type); enumerator);
effect = effect =
graph()->NewNode(simplified()->CheckIf(DeoptimizeReason::kWrongMap), graph()->NewNode(simplified()->CheckIf(DeoptimizeReason::kWrongMap),
check, effect, control); check, effect, control);
...@@ -2040,7 +2041,7 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadPropertyWithEnumeratedKey( ...@@ -2040,7 +2041,7 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadPropertyWithEnumeratedKey(
// Load the enum cache indices from the {cache_type}. // Load the enum cache indices from the {cache_type}.
Node* descriptor_array = effect = graph()->NewNode( Node* descriptor_array = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForMapDescriptors()), cache_type, simplified()->LoadField(AccessBuilder::ForMapDescriptors()), enumerator,
effect, control); effect, control);
Node* enum_cache = effect = graph()->NewNode( Node* enum_cache = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForDescriptorArrayEnumCache()), simplified()->LoadField(AccessBuilder::ForDescriptorArrayEnumCache()),
...@@ -2059,10 +2060,10 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadPropertyWithEnumeratedKey( ...@@ -2059,10 +2060,10 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadPropertyWithEnumeratedKey(
control); control);
// Determine the key from the {enum_indices}. // Determine the key from the {enum_indices}.
Node* key = effect = graph()->NewNode( key = effect = graph()->NewNode(
simplified()->LoadElement( simplified()->LoadElement(
AccessBuilder::ForFixedArrayElement(PACKED_SMI_ELEMENTS)), AccessBuilder::ForFixedArrayElement(PACKED_SMI_ELEMENTS)),
enum_indices, index, effect, control); enum_indices, key, effect, control);
// Load the actual field value. // Load the actual field value.
Node* value = effect = graph()->NewNode(simplified()->LoadFieldByIndex(), Node* value = effect = graph()->NewNode(simplified()->LoadFieldByIndex(),
......
...@@ -640,9 +640,9 @@ size_t hash_value(GetIteratorParameters const& p) { ...@@ -640,9 +640,9 @@ size_t hash_value(GetIteratorParameters const& p) {
FeedbackSource::Hash()(p.callFeedback())); FeedbackSource::Hash()(p.callFeedback()));
} }
size_t hash_value(ForInMode const& mode) { return static_cast<uint8_t>(mode); } size_t hash_value(ForInMode mode) { return static_cast<uint8_t>(mode); }
std::ostream& operator<<(std::ostream& os, ForInMode const& mode) { std::ostream& operator<<(std::ostream& os, ForInMode mode) {
switch (mode) { switch (mode) {
case ForInMode::kUseEnumCacheKeysAndIndices: case ForInMode::kUseEnumCacheKeysAndIndices:
return os << "UseEnumCacheKeysAndIndices"; return os << "UseEnumCacheKeysAndIndices";
...@@ -654,26 +654,10 @@ std::ostream& operator<<(std::ostream& os, ForInMode const& mode) { ...@@ -654,26 +654,10 @@ std::ostream& operator<<(std::ostream& os, ForInMode const& mode) {
UNREACHABLE(); UNREACHABLE();
} }
bool operator==(ForInParameters const& lhs, ForInParameters const& rhs) { ForInMode ForInModeOf(Operator const* op) {
return lhs.feedback() == rhs.feedback() && lhs.mode() == rhs.mode();
}
bool operator!=(ForInParameters const& lhs, ForInParameters const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(ForInParameters const& p) {
return base::hash_combine(FeedbackSource::Hash()(p.feedback()), p.mode());
}
std::ostream& operator<<(std::ostream& os, ForInParameters const& p) {
return os << p.feedback() << ", " << p.mode();
}
ForInParameters const& ForInParametersOf(const Operator* op) {
DCHECK(op->opcode() == IrOpcode::kJSForInNext || DCHECK(op->opcode() == IrOpcode::kJSForInNext ||
op->opcode() == IrOpcode::kJSForInPrepare); op->opcode() == IrOpcode::kJSForInPrepare);
return OpParameter<ForInParameters>(op); return OpParameter<ForInMode>(op);
} }
#define CACHED_OP_LIST(V) \ #define CACHED_OP_LIST(V) \
...@@ -977,23 +961,21 @@ const Operator* JSOperatorBuilder::HasProperty(FeedbackSource const& feedback) { ...@@ -977,23 +961,21 @@ const Operator* JSOperatorBuilder::HasProperty(FeedbackSource const& feedback) {
access); // parameter access); // parameter
} }
const Operator* JSOperatorBuilder::ForInNext(ForInMode mode, const Operator* JSOperatorBuilder::ForInNext(ForInMode mode) {
const FeedbackSource& feedback) { return zone()->New<Operator1<ForInMode>>( // --
return zone()->New<Operator1<ForInParameters>>( // --
IrOpcode::kJSForInNext, Operator::kNoProperties, // opcode IrOpcode::kJSForInNext, Operator::kNoProperties, // opcode
"JSForInNext", // name "JSForInNext", // name
5, 1, 1, 1, 1, 2, // counts 4, 1, 1, 1, 1, 2, // counts
ForInParameters{feedback, mode}); // parameter mode); // parameter
} }
const Operator* JSOperatorBuilder::ForInPrepare( const Operator* JSOperatorBuilder::ForInPrepare(ForInMode mode) {
ForInMode mode, const FeedbackSource& feedback) { return zone()->New<Operator1<ForInMode>>( // --
return zone()->New<Operator1<ForInParameters>>( // --
IrOpcode::kJSForInPrepare, // opcode IrOpcode::kJSForInPrepare, // opcode
Operator::kNoWrite | Operator::kNoThrow, // flags Operator::kNoWrite | Operator::kNoThrow, // flags
"JSForInPrepare", // name "JSForInPrepare", // name
2, 1, 1, 3, 1, 1, // counts 1, 1, 1, 3, 1, 1, // counts
ForInParameters{feedback, mode}); // parameter mode); // parameter
} }
const Operator* JSOperatorBuilder::GeneratorStore(int register_count) { const Operator* JSOperatorBuilder::GeneratorStore(int register_count) {
......
...@@ -789,32 +789,18 @@ std::ostream& operator<<(std::ostream&, GetIteratorParameters const&); ...@@ -789,32 +789,18 @@ std::ostream& operator<<(std::ostream&, GetIteratorParameters const&);
const GetIteratorParameters& GetIteratorParametersOf(const Operator* op); const GetIteratorParameters& GetIteratorParametersOf(const Operator* op);
// Descriptor used by the JSForInPrepare and JSForInNext opcodes.
enum class ForInMode : uint8_t { enum class ForInMode : uint8_t {
kUseEnumCacheKeysAndIndices, kUseEnumCacheKeysAndIndices,
kUseEnumCacheKeys, kUseEnumCacheKeys,
kGeneric kGeneric
}; };
size_t hash_value(ForInMode const&);
std::ostream& operator<<(std::ostream&, ForInMode const&);
class ForInParameters final { size_t hash_value(ForInMode);
public:
ForInParameters(const FeedbackSource& feedback, ForInMode mode)
: feedback_(feedback), mode_(mode) {}
const FeedbackSource& feedback() const { return feedback_; }
ForInMode mode() const { return mode_; }
private: std::ostream& operator<<(std::ostream&, ForInMode);
const FeedbackSource feedback_;
const ForInMode mode_;
};
bool operator==(ForInParameters const&, ForInParameters const&); ForInMode ForInModeOf(Operator const* op) V8_WARN_UNUSED_RESULT;
bool operator!=(ForInParameters const&, ForInParameters const&);
size_t hash_value(ForInParameters const&);
std::ostream& operator<<(std::ostream&, ForInParameters const&);
const ForInParameters& ForInParametersOf(const Operator* op);
int RegisterCountOf(Operator const* op) V8_WARN_UNUSED_RESULT; int RegisterCountOf(Operator const* op) V8_WARN_UNUSED_RESULT;
...@@ -980,8 +966,8 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final ...@@ -980,8 +966,8 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* AsyncFunctionResolve(); const Operator* AsyncFunctionResolve();
const Operator* ForInEnumerate(); const Operator* ForInEnumerate();
const Operator* ForInNext(ForInMode mode, const FeedbackSource& feedback); const Operator* ForInNext(ForInMode);
const Operator* ForInPrepare(ForInMode mode, const FeedbackSource& feedback); const Operator* ForInPrepare(ForInMode);
const Operator* LoadMessage(); const Operator* LoadMessage();
const Operator* StoreMessage(); const Operator* StoreMessage();
...@@ -1560,43 +1546,6 @@ class JSCreateClosureNode final : public JSNodeWrapperBase { ...@@ -1560,43 +1546,6 @@ class JSCreateClosureNode final : public JSNodeWrapperBase {
FeedbackCellRef GetFeedbackCellRefChecked(JSHeapBroker* broker) const; FeedbackCellRef GetFeedbackCellRefChecked(JSHeapBroker* broker) const;
}; };
class JSForInPrepareNode final : public JSNodeWrapperBase {
public:
explicit constexpr JSForInPrepareNode(Node* node) : JSNodeWrapperBase(node) {
CONSTEXPR_DCHECK(node->opcode() == IrOpcode::kJSForInPrepare);
}
const ForInParameters& Parameters() const {
return ForInParametersOf(node()->op());
}
#define INPUTS(V) \
V(Enumerator, enumerator, 0, Object) \
V(FeedbackVector, feedback_vector, 1, HeapObject)
INPUTS(DEFINE_INPUT_ACCESSORS)
#undef INPUTS
};
class JSForInNextNode final : public JSNodeWrapperBase {
public:
explicit constexpr JSForInNextNode(Node* node) : JSNodeWrapperBase(node) {
CONSTEXPR_DCHECK(node->opcode() == IrOpcode::kJSForInNext);
}
const ForInParameters& Parameters() const {
return ForInParametersOf(node()->op());
}
#define INPUTS(V) \
V(Receiver, receiver, 0, Object) \
V(CacheArray, cache_array, 1, Object) \
V(CacheType, cache_type, 2, Object) \
V(Index, index, 3, Smi) \
V(FeedbackVector, feedback_vector, 4, HeapObject)
INPUTS(DEFINE_INPUT_ACCESSORS)
#undef INPUTS
};
#undef DEFINE_INPUT_ACCESSORS #undef DEFINE_INPUT_ACCESSORS
} // namespace compiler } // namespace compiler
......
...@@ -1912,22 +1912,23 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) { ...@@ -1912,22 +1912,23 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
} }
Reduction JSTypedLowering::ReduceJSForInNext(Node* node) { Reduction JSTypedLowering::ReduceJSForInNext(Node* node) {
JSForInNextNode n(node); DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode());
Node* receiver = n.receiver(); ForInMode const mode = ForInModeOf(node->op());
Node* cache_array = n.cache_array(); Node* receiver = NodeProperties::GetValueInput(node, 0);
Node* cache_type = n.cache_type(); Node* cache_array = NodeProperties::GetValueInput(node, 1);
Node* index = n.index(); Node* cache_type = NodeProperties::GetValueInput(node, 2);
Node* context = n.context(); Node* index = NodeProperties::GetValueInput(node, 3);
FrameState frame_state = n.frame_state(); Node* context = NodeProperties::GetContextInput(node);
Effect effect = n.effect(); Node* frame_state = NodeProperties::GetFrameStateInput(node);
Control control = n.control(); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
// Load the map of the {receiver}. // Load the map of the {receiver}.
Node* receiver_map = effect = Node* receiver_map = effect =
graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
receiver, effect, control); receiver, effect, control);
switch (n.Parameters().mode()) { switch (mode) {
case ForInMode::kUseEnumCacheKeys: case ForInMode::kUseEnumCacheKeys:
case ForInMode::kUseEnumCacheKeysAndIndices: { case ForInMode::kUseEnumCacheKeysAndIndices: {
// Ensure that the expected map still matches that of the {receiver}. // Ensure that the expected map still matches that of the {receiver}.
...@@ -2024,15 +2025,16 @@ Reduction JSTypedLowering::ReduceJSForInNext(Node* node) { ...@@ -2024,15 +2025,16 @@ Reduction JSTypedLowering::ReduceJSForInNext(Node* node) {
} }
Reduction JSTypedLowering::ReduceJSForInPrepare(Node* node) { Reduction JSTypedLowering::ReduceJSForInPrepare(Node* node) {
JSForInPrepareNode n(node); DCHECK_EQ(IrOpcode::kJSForInPrepare, node->opcode());
Node* enumerator = n.enumerator(); ForInMode const mode = ForInModeOf(node->op());
Effect effect = n.effect(); Node* enumerator = NodeProperties::GetValueInput(node, 0);
Control control = n.control(); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* cache_type = enumerator; Node* cache_type = enumerator;
Node* cache_array = nullptr; Node* cache_array = nullptr;
Node* cache_length = nullptr; Node* cache_length = nullptr;
switch (n.Parameters().mode()) { switch (mode) {
case ForInMode::kUseEnumCacheKeys: case ForInMode::kUseEnumCacheKeys:
case ForInMode::kUseEnumCacheKeysAndIndices: { case ForInMode::kUseEnumCacheKeysAndIndices: {
// Check that the {enumerator} is a Map. // Check that the {enumerator} is a Map.
......
...@@ -1095,8 +1095,6 @@ class V8_EXPORT_PRIVATE IrOpcode { ...@@ -1095,8 +1095,6 @@ class V8_EXPORT_PRIVATE IrOpcode {
case kJSCreateLiteralArray: case kJSCreateLiteralArray:
case kJSCreateLiteralObject: case kJSCreateLiteralObject:
case kJSCreateLiteralRegExp: case kJSCreateLiteralRegExp:
case kJSForInNext:
case kJSForInPrepare:
case kJSGetIterator: case kJSGetIterator:
case kJSGetTemplateObject: case kJSGetTemplateObject:
case kJSHasProperty: case kJSHasProperty:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment