| Index: src/compiler/node-properties.cc
|
| diff --git a/src/compiler/node-properties.cc b/src/compiler/node-properties.cc
|
| index 2e1e1bde8e83ef491ea1a7320b2b7e2429b237b7..e559844cbfa932d63480a3228733fd3846761067 100644
|
| --- a/src/compiler/node-properties.cc
|
| +++ b/src/compiler/node-properties.cc
|
| @@ -7,7 +7,9 @@
|
| #include "src/compiler/graph.h"
|
| #include "src/compiler/js-operator.h"
|
| #include "src/compiler/linkage.h"
|
| +#include "src/compiler/node-matchers.h"
|
| #include "src/compiler/operator-properties.h"
|
| +#include "src/compiler/simplified-operator.h"
|
| #include "src/compiler/verifier.h"
|
| #include "src/handles-inl.h"
|
| #include "src/objects-inl.h"
|
| @@ -328,6 +330,90 @@ bool NodeProperties::IsSame(Node* a, Node* b) {
|
| }
|
|
|
| // static
|
| +bool NodeProperties::InferReceiverMaps(Node* receiver, Node* effect,
|
| + ZoneHandleSet<Map>* maps_return) {
|
| + HeapObjectMatcher m(receiver);
|
| + if (m.HasValue()) {
|
| + Handle<Map> receiver_map(m.Value()->map());
|
| + if (receiver_map->is_stable()) {
|
| + *maps_return = ZoneHandleSet<Map>(receiver_map);
|
| + return true;
|
| + }
|
| + }
|
| + while (true) {
|
| + switch (effect->opcode()) {
|
| + case IrOpcode::kCheckMaps: {
|
| + Node* const object = GetValueInput(effect, 0);
|
| + if (IsSame(receiver, object)) {
|
| + *maps_return = CheckMapsParametersOf(effect->op()).maps();
|
| + return true;
|
| + }
|
| + break;
|
| + }
|
| + case IrOpcode::kJSCreate: {
|
| + if (IsSame(receiver, effect)) {
|
| + HeapObjectMatcher mtarget(GetValueInput(effect, 0));
|
| + HeapObjectMatcher mnewtarget(GetValueInput(effect, 1));
|
| + if (mtarget.HasValue() && mnewtarget.HasValue()) {
|
| + Handle<JSFunction> original_constructor =
|
| + Handle<JSFunction>::cast(mnewtarget.Value());
|
| + if (original_constructor->has_initial_map()) {
|
| + Handle<Map> initial_map(original_constructor->initial_map());
|
| + if (initial_map->constructor_or_backpointer() ==
|
| + *mtarget.Value()) {
|
| + *maps_return = ZoneHandleSet<Map>(initial_map);
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| + // We reached the allocation of the {receiver}.
|
| + return false;
|
| + }
|
| + break;
|
| + }
|
| + case IrOpcode::kStoreField: {
|
| + // We only care about StoreField of maps.
|
| + Node* const object = GetValueInput(effect, 0);
|
| + FieldAccess const& access = FieldAccessOf(effect->op());
|
| + if (access.base_is_tagged == kTaggedBase &&
|
| + access.offset == HeapObject::kMapOffset) {
|
| + if (IsSame(receiver, object)) {
|
| + Node* const value = GetValueInput(effect, 1);
|
| + HeapObjectMatcher m(value);
|
| + if (m.HasValue()) {
|
| + *maps_return = ZoneHandleSet<Map>(Handle<Map>::cast(m.Value()));
|
| + return true;
|
| + }
|
| + }
|
| + // Without alias analysis we cannot tell whether this
|
| + // StoreField[map] affects {receiver} or not.
|
| + return false;
|
| + }
|
| + break;
|
| + }
|
| + case IrOpcode::kJSStoreMessage:
|
| + case IrOpcode::kJSStoreModule:
|
| + case IrOpcode::kStoreElement:
|
| + case IrOpcode::kStoreTypedElement: {
|
| + // These never change the map of objects.
|
| + break;
|
| + }
|
| + default: {
|
| + DCHECK_EQ(1, effect->op()->EffectOutputCount());
|
| + if (effect->op()->EffectInputCount() != 1 ||
|
| + !effect->op()->HasProperty(Operator::kNoWrite)) {
|
| + // Didn't find any appropriate CheckMaps node.
|
| + return false;
|
| + }
|
| + break;
|
| + }
|
| + }
|
| + DCHECK_EQ(1, effect->op()->EffectInputCount());
|
| + effect = NodeProperties::GetEffectInput(effect);
|
| + }
|
| +}
|
| +
|
| +// static
|
| MaybeHandle<Context> NodeProperties::GetSpecializationContext(
|
| Node* node, MaybeHandle<Context> context) {
|
| switch (node->opcode()) {
|
|
|