Commit 9b18fbe8 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

Revert "[turbofan] Introduce FindOrderedHashMapEntryForReceiverKey operator."

This reverts commit 877de376.

Reason for revert: Looks like this doesn't really move the needle (only w/ high iteration count). So let's not do the extra complexity unless there's a good reason to do so.

Original change's description:
> [turbofan] Introduce FindOrderedHashMapEntryForReceiverKey operator.
> 
> This optimizes Map#get and Map#has for the case where the key is known
> to be a JSReceiver. This generalizes the existing logic for the
> FindOrderedHashMapEntryForSigned32Key operator to also deal with
> receivers. This gives a nice 33% boost on the map-set-lookup-es6 test
> of the six-speed benchmark suite.
> 
> Drive-by-fix: Rename the FindOrderedHashMapEntryForInt32Key operator to
> FindOrderedHashMapEntryForSigned32Key to match the naming of the types.
> 
> R=​jarin@chromium.org
> 
> Bug: v8:5267, v8:7001
> Change-Id: Ifab8414f26adee7ec833d8cb94ae0ac49f2c3d35
> Reviewed-on: https://chromium-review.googlesource.com/738180
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#48938}

TBR=jarin@chromium.org,bmeurer@chromium.org

Change-Id: Icaf9e22cb3412a97342c4e4cdc422d4aaa2d0ef9
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:5267, v8:7001
Reviewed-on: https://chromium-review.googlesource.com/738052Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48941}
parent 43095278
...@@ -862,11 +862,8 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, ...@@ -862,11 +862,8 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kFindOrderedHashMapEntry: case IrOpcode::kFindOrderedHashMapEntry:
result = LowerFindOrderedHashMapEntry(node); result = LowerFindOrderedHashMapEntry(node);
break; break;
case IrOpcode::kFindOrderedHashMapEntryForReceiverKey: case IrOpcode::kFindOrderedHashMapEntryForInt32Key:
result = LowerFindOrderedHashMapEntryForReceiverKey(node); result = LowerFindOrderedHashMapEntryForInt32Key(node);
break;
case IrOpcode::kFindOrderedHashMapEntryForSigned32Key:
result = LowerFindOrderedHashMapEntryForSigned32Key(node);
break; break;
case IrOpcode::kTransitionAndStoreNumberElement: case IrOpcode::kTransitionAndStoreNumberElement:
LowerTransitionAndStoreNumberElement(node); LowerTransitionAndStoreNumberElement(node);
...@@ -3961,9 +3958,44 @@ Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node) { ...@@ -3961,9 +3958,44 @@ Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node) {
return Just(done.PhiAt(0)); return Just(done.PhiAt(0));
} }
template <typename Predicate> Node* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) {
Node* EffectControlLinearizer::BuildFindOrderedHashMapEntry( Node* table = NodeProperties::GetValueInput(node, 0);
Node* table, Node* hash, Predicate const& predicate) { Node* key = NodeProperties::GetValueInput(node, 1);
{
Callable const callable =
Builtins::CallableFor(isolate(), Builtins::kFindOrderedHashMapEntry);
Operator::Properties const properties = node->op()->properties();
CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), callable.descriptor(), 0, flags,
properties);
return __ Call(desc, __ HeapConstant(callable.code()), table, key,
__ NoContextConstant());
}
}
Node* EffectControlLinearizer::ComputeIntegerHash(Node* value) {
// See v8::internal::ComputeIntegerHash()
value = __ Int32Add(__ Word32Xor(value, __ Int32Constant(0xffffffff)),
__ Word32Shl(value, __ Int32Constant(15)));
value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(12)));
value = __ Int32Add(value, __ Word32Shl(value, __ Int32Constant(2)));
value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(4)));
value = __ Int32Mul(value, __ Int32Constant(2057));
value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(16)));
value = __ Word32And(value, __ Int32Constant(0x3fffffff));
return value;
}
Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForInt32Key(
Node* node) {
Node* table = NodeProperties::GetValueInput(node, 0);
Node* key = NodeProperties::GetValueInput(node, 1);
// Compute the integer hash code.
Node* hash = ChangeUint32ToUintPtr(ComputeIntegerHash(key));
Node* number_of_buckets = ChangeSmiToIntPtr(__ LoadField( Node* number_of_buckets = ChangeSmiToIntPtr(__ LoadField(
AccessBuilder::ForOrderedHashTableBaseNumberOfBuckets(), table)); AccessBuilder::ForOrderedHashTableBaseNumberOfBuckets(), table));
hash = __ WordAnd(hash, __ IntSub(number_of_buckets, __ IntPtrConstant(1))); hash = __ WordAnd(hash, __ IntSub(number_of_buckets, __ IntPtrConstant(1)));
...@@ -3994,7 +4026,20 @@ Node* EffectControlLinearizer::BuildFindOrderedHashMapEntry( ...@@ -3994,7 +4026,20 @@ Node* EffectControlLinearizer::BuildFindOrderedHashMapEntry(
auto if_match = __ MakeLabel(); auto if_match = __ MakeLabel();
auto if_notmatch = __ MakeLabel(); auto if_notmatch = __ MakeLabel();
predicate(candidate_key, &if_match, &if_notmatch); auto if_notsmi = __ MakeDeferredLabel();
__ GotoIfNot(ObjectIsSmi(candidate_key), &if_notsmi);
__ Branch(__ Word32Equal(ChangeSmiToInt32(candidate_key), key), &if_match,
&if_notmatch);
__ Bind(&if_notsmi);
__ GotoIfNot(
__ WordEqual(__ LoadField(AccessBuilder::ForMap(), candidate_key),
__ HeapNumberMapConstant()),
&if_notmatch);
__ Branch(__ Float64Equal(__ LoadField(AccessBuilder::ForHeapNumberValue(),
candidate_key),
__ ChangeInt32ToFloat64(key)),
&if_match, &if_notmatch);
__ Bind(&if_match); __ Bind(&if_match);
{ {
...@@ -4019,138 +4064,6 @@ Node* EffectControlLinearizer::BuildFindOrderedHashMapEntry( ...@@ -4019,138 +4064,6 @@ Node* EffectControlLinearizer::BuildFindOrderedHashMapEntry(
return done.PhiAt(0); return done.PhiAt(0);
} }
Node* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) {
Node* table = NodeProperties::GetValueInput(node, 0);
Node* key = NodeProperties::GetValueInput(node, 1);
{
Callable const callable =
Builtins::CallableFor(isolate(), Builtins::kFindOrderedHashMapEntry);
Operator::Properties const properties = node->op()->properties();
CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), graph()->zone(), callable.descriptor(), 0, flags,
properties);
return __ Call(desc, __ HeapConstant(callable.code()), table, key,
__ NoContextConstant());
}
}
Node* EffectControlLinearizer::GetExistingHashForReceiver(Node* receiver) {
auto done = __ MakeLabel(MachineType::PointerRepresentation());
auto if_smi = __ MakeLabel();
auto if_fixed_array = __ MakeLabel();
auto if_property_array = __ MakeLabel();
auto if_property_dictionary = __ MakeLabel();
// Dispatch depending on the {receiver}s "properties or hash" field.
Node* properties_or_hash =
__ LoadField(AccessBuilder::ForJSObjectPropertiesOrHash(), receiver);
__ GotoIf(ObjectIsSmi(properties_or_hash), &if_smi);
Node* properties_map =
__ LoadField(AccessBuilder::ForMap(), properties_or_hash);
Node* properties_instance_type =
__ LoadField(AccessBuilder::ForMapInstanceType(), properties_map);
__ GotoIf(__ Word32Equal(properties_instance_type,
__ Int32Constant(PROPERTY_ARRAY_TYPE)),
&if_property_array);
__ Branch(__ Word32Equal(properties_instance_type,
__ Int32Constant(HASH_TABLE_TYPE)),
&if_property_dictionary, &if_fixed_array);
__ Bind(&if_smi);
{
Node* hash = ChangeSmiToIntPtr(properties_or_hash);
__ Goto(&done, hash);
}
__ Bind(&if_fixed_array);
{
Node* hash = __ Int32Constant(PropertyArray::kNoHashSentinel);
__ Goto(&done, hash);
}
__ Bind(&if_property_array);
{
Node* length_and_hash = ChangeSmiToIntPtr(__ LoadField(
AccessBuilder::ForPropertyArrayLengthAndHash(), properties_or_hash));
Node* hash = __ WordShr(
length_and_hash, __ IntPtrConstant(PropertyArray::HashField::kShift));
__ Goto(&done, hash);
}
__ Bind(&if_property_dictionary);
{
Node* hash = ChangeSmiToIntPtr(__ LoadField(
AccessBuilder::ForDictionaryObjectHashIndex(), properties_or_hash));
__ Goto(&done, hash);
}
__ Bind(&done);
return done.PhiAt(0);
}
Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForReceiverKey(
Node* node) {
Node* table = NodeProperties::GetValueInput(node, 0);
Node* key = NodeProperties::GetValueInput(node, 1);
// Compute the hash code for the {key}.
Node* hash = GetExistingHashForReceiver(key);
// Search for the entry with the given {key}.
return BuildFindOrderedHashMapEntry(
table, hash,
[=](Node* candidate_key, GraphAssemblerLabel<0>* if_match,
GraphAssemblerLabel<0>* if_notmatch) {
__ Branch(__ WordEqual(candidate_key, key), if_match, if_notmatch);
});
}
Node* EffectControlLinearizer::ComputeIntegerHash(Node* value) {
// See v8::internal::ComputeIntegerHash()
value = __ Int32Add(__ Word32Xor(value, __ Int32Constant(0xffffffff)),
__ Word32Shl(value, __ Int32Constant(15)));
value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(12)));
value = __ Int32Add(value, __ Word32Shl(value, __ Int32Constant(2)));
value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(4)));
value = __ Int32Mul(value, __ Int32Constant(2057));
value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(16)));
value = __ Word32And(value, __ Int32Constant(0x3fffffff));
return value;
}
Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForSigned32Key(
Node* node) {
Node* table = NodeProperties::GetValueInput(node, 0);
Node* key = NodeProperties::GetValueInput(node, 1);
// Compute the integer hash code for the {key}.
Node* hash = ChangeUint32ToUintPtr(ComputeIntegerHash(key));
// Search for the entry with the given {key}.
return BuildFindOrderedHashMapEntry(
table, hash,
[=](Node* candidate_key, GraphAssemblerLabel<0>* if_match,
GraphAssemblerLabel<0>* if_notmatch) {
auto if_notsmi = __ MakeDeferredLabel();
__ GotoIfNot(ObjectIsSmi(candidate_key), &if_notsmi);
__ Branch(__ Word32Equal(ChangeSmiToInt32(candidate_key), key),
if_match, if_notmatch);
__ Bind(&if_notsmi);
__ GotoIfNot(
__ WordEqual(__ LoadField(AccessBuilder::ForMap(), candidate_key),
__ HeapNumberMapConstant()),
if_notmatch);
__ Branch(
__ Float64Equal(__ LoadField(AccessBuilder::ForHeapNumberValue(),
candidate_key),
__ ChangeInt32ToFloat64(key)),
if_match, if_notmatch);
});
}
#undef __ #undef __
Factory* EffectControlLinearizer::factory() const { Factory* EffectControlLinearizer::factory() const {
......
...@@ -134,8 +134,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer { ...@@ -134,8 +134,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
void LowerStoreTypedElement(Node* node); void LowerStoreTypedElement(Node* node);
void LowerStoreSignedSmallElement(Node* node); void LowerStoreSignedSmallElement(Node* node);
Node* LowerFindOrderedHashMapEntry(Node* node); Node* LowerFindOrderedHashMapEntry(Node* node);
Node* LowerFindOrderedHashMapEntryForReceiverKey(Node* node); Node* LowerFindOrderedHashMapEntryForInt32Key(Node* node);
Node* LowerFindOrderedHashMapEntryForSigned32Key(Node* node);
void LowerTransitionAndStoreElement(Node* node); void LowerTransitionAndStoreElement(Node* node);
void LowerTransitionAndStoreNumberElement(Node* node); void LowerTransitionAndStoreNumberElement(Node* node);
void LowerTransitionAndStoreNonNumberElement(Node* node); void LowerTransitionAndStoreNonNumberElement(Node* node);
...@@ -154,11 +153,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer { ...@@ -154,11 +153,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* value, Node* value,
Node* frame_state); Node* frame_state);
Node* BuildFloat64RoundDown(Node* value); Node* BuildFloat64RoundDown(Node* value);
template <typename Predicate>
Node* BuildFindOrderedHashMapEntry(Node* table, Node* hash,
Predicate const& predicate);
Node* ComputeIntegerHash(Node* value); Node* ComputeIntegerHash(Node* value);
Node* GetExistingHashForReceiver(Node* receiver);
Node* LowerStringComparison(Callable const& callable, Node* node); Node* LowerStringComparison(Callable const& callable, Node* node);
Node* IsElementsKindGreaterThan(Node* kind, ElementsKind reference_kind); Node* IsElementsKindGreaterThan(Node* kind, ElementsKind reference_kind);
......
...@@ -34,7 +34,6 @@ namespace compiler { ...@@ -34,7 +34,6 @@ namespace compiler {
#define PURE_ASSEMBLER_MACH_BINOP_LIST(V) \ #define PURE_ASSEMBLER_MACH_BINOP_LIST(V) \
V(WordShl) \ V(WordShl) \
V(WordSar) \ V(WordSar) \
V(WordShr) \
V(WordAnd) \ V(WordAnd) \
V(Word32Or) \ V(Word32Or) \
V(Word32And) \ V(Word32And) \
......
...@@ -378,8 +378,7 @@ ...@@ -378,8 +378,7 @@
V(MaybeGrowFastElements) \ V(MaybeGrowFastElements) \
V(TransitionElementsKind) \ V(TransitionElementsKind) \
V(FindOrderedHashMapEntry) \ V(FindOrderedHashMapEntry) \
V(FindOrderedHashMapEntryForReceiverKey) \ V(FindOrderedHashMapEntryForInt32Key) \
V(FindOrderedHashMapEntryForSigned32Key) \
V(RuntimeAbort) V(RuntimeAbort)
#define SIMPLIFIED_OP_LIST(V) \ #define SIMPLIFIED_OP_LIST(V) \
......
...@@ -2962,21 +2962,13 @@ class RepresentationSelector { ...@@ -2962,21 +2962,13 @@ class RepresentationSelector {
case IrOpcode::kFindOrderedHashMapEntry: { case IrOpcode::kFindOrderedHashMapEntry: {
Type* const key_type = TypeOf(node->InputAt(1)); Type* const key_type = TypeOf(node->InputAt(1));
if (key_type->Is(Type::Receiver())) { if (key_type->Is(Type::Signed32OrMinusZero())) {
VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TaggedPointer(),
MachineRepresentation::kWord32);
if (lower()) {
NodeProperties::ChangeOp(
node, lowering->simplified()
->FindOrderedHashMapEntryForReceiverKey());
}
} else if (key_type->Is(Type::Signed32OrMinusZero())) {
VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(), VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32); MachineRepresentation::kWord32);
if (lower()) { if (lower()) {
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, lowering->simplified() node,
->FindOrderedHashMapEntryForSigned32Key()); lowering->simplified()->FindOrderedHashMapEntryForInt32Key());
} }
} else { } else {
VisitBinop(node, UseInfo::AnyTagged(), VisitBinop(node, UseInfo::AnyTagged(),
......
...@@ -722,23 +722,14 @@ struct SimplifiedOperatorGlobalCache final { ...@@ -722,23 +722,14 @@ struct SimplifiedOperatorGlobalCache final {
}; };
FindOrderedHashMapEntryOperator kFindOrderedHashMapEntry; FindOrderedHashMapEntryOperator kFindOrderedHashMapEntry;
struct FindOrderedHashMapEntryForReceiverKeyOperator final : public Operator { struct FindOrderedHashMapEntryForInt32KeyOperator final : public Operator {
FindOrderedHashMapEntryForReceiverKeyOperator() FindOrderedHashMapEntryForInt32KeyOperator()
: Operator(IrOpcode::kFindOrderedHashMapEntryForReceiverKey, : Operator(IrOpcode::kFindOrderedHashMapEntryForInt32Key,
Operator::kEliminatable, Operator::kEliminatable,
"FindOrderedHashMapEntryForReceiverKey", 2, 1, 1, 1, 1, 0) {} "FindOrderedHashMapEntryForInt32Key", 2, 1, 1, 1, 1, 0) {}
}; };
FindOrderedHashMapEntryForReceiverKeyOperator FindOrderedHashMapEntryForInt32KeyOperator
kFindOrderedHashMapEntryForReceiverKey; kFindOrderedHashMapEntryForInt32Key;
struct FindOrderedHashMapEntryForSigned32KeyOperator final : public Operator {
FindOrderedHashMapEntryForSigned32KeyOperator()
: Operator(IrOpcode::kFindOrderedHashMapEntryForSigned32Key,
Operator::kEliminatable,
"FindOrderedHashMapEntryForSigned32Key", 2, 1, 1, 1, 1, 0) {}
};
FindOrderedHashMapEntryForSigned32KeyOperator
kFindOrderedHashMapEntryForSigned32Key;
struct ArgumentsFrameOperator final : public Operator { struct ArgumentsFrameOperator final : public Operator {
ArgumentsFrameOperator() ArgumentsFrameOperator()
...@@ -917,8 +908,7 @@ CHECKED_OP_LIST(GET_FROM_CACHE) ...@@ -917,8 +908,7 @@ CHECKED_OP_LIST(GET_FROM_CACHE)
GET_FROM_CACHE(ArrayBufferWasNeutered) GET_FROM_CACHE(ArrayBufferWasNeutered)
GET_FROM_CACHE(ArgumentsFrame) GET_FROM_CACHE(ArgumentsFrame)
GET_FROM_CACHE(FindOrderedHashMapEntry) GET_FROM_CACHE(FindOrderedHashMapEntry)
GET_FROM_CACHE(FindOrderedHashMapEntryForReceiverKey) GET_FROM_CACHE(FindOrderedHashMapEntryForInt32Key)
GET_FROM_CACHE(FindOrderedHashMapEntryForSigned32Key)
GET_FROM_CACHE(LoadFieldByIndex) GET_FROM_CACHE(LoadFieldByIndex)
#undef GET_FROM_CACHE #undef GET_FROM_CACHE
......
...@@ -408,8 +408,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final ...@@ -408,8 +408,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* StringToUpperCaseIntl(); const Operator* StringToUpperCaseIntl();
const Operator* FindOrderedHashMapEntry(); const Operator* FindOrderedHashMapEntry();
const Operator* FindOrderedHashMapEntryForReceiverKey(); const Operator* FindOrderedHashMapEntryForInt32Key();
const Operator* FindOrderedHashMapEntryForSigned32Key();
const Operator* SpeculativeToNumber(NumberOperationHint hint); const Operator* SpeculativeToNumber(NumberOperationHint hint);
......
...@@ -2085,11 +2085,7 @@ Type* Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) { ...@@ -2085,11 +2085,7 @@ Type* Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
return Type::Range(-1.0, FixedArray::kMaxLength, zone()); return Type::Range(-1.0, FixedArray::kMaxLength, zone());
} }
Type* Typer::Visitor::TypeFindOrderedHashMapEntryForReceiverKey(Node* node) { Type* Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
return Type::Range(-1.0, FixedArray::kMaxLength, zone());
}
Type* Typer::Visitor::TypeFindOrderedHashMapEntryForSigned32Key(Node* node) {
return Type::Range(-1.0, FixedArray::kMaxLength, zone()); return Type::Range(-1.0, FixedArray::kMaxLength, zone());
} }
......
...@@ -1053,14 +1053,9 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -1053,14 +1053,9 @@ void Verifier::Visitor::Check(Node* node) {
CheckValueInputIs(node, 0, Type::Any()); CheckValueInputIs(node, 0, Type::Any());
CheckTypeIs(node, Type::SignedSmall()); CheckTypeIs(node, Type::SignedSmall());
break; break;
case IrOpcode::kFindOrderedHashMapEntryForReceiverKey: case IrOpcode::kFindOrderedHashMapEntryForInt32Key:
CheckValueInputIs(node, 0, Type::Any()); CheckValueInputIs(node, 0, Type::Any());
CheckValueInputIs(node, 1, Type::Receiver()); CheckValueInputIs(node, 1, Type::Signed32());
CheckTypeIs(node, Type::SignedSmall());
break;
case IrOpcode::kFindOrderedHashMapEntryForSigned32Key:
CheckValueInputIs(node, 0, Type::Any());
CheckValueInputIs(node, 1, Type::Signed32OrMinusZero());
CheckTypeIs(node, Type::SignedSmall()); CheckTypeIs(node, Type::SignedSmall());
break; break;
case IrOpcode::kArgumentsLength: case IrOpcode::kArgumentsLength:
......
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