OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/js-builtin-reducer.h" | 5 #include "src/compiler/js-builtin-reducer.h" |
6 | 6 |
7 #include "src/compilation-dependencies.h" | 7 #include "src/compilation-dependencies.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 } | 121 } |
122 | 122 |
123 MaybeHandle<Map> GetMapWitness(Node* node) { | 123 MaybeHandle<Map> GetMapWitness(Node* node) { |
124 Node* receiver = NodeProperties::GetValueInput(node, 1); | 124 Node* receiver = NodeProperties::GetValueInput(node, 1); |
125 Node* effect = NodeProperties::GetEffectInput(node); | 125 Node* effect = NodeProperties::GetEffectInput(node); |
126 // Check if the {node} is dominated by a CheckMaps with a single map | 126 // Check if the {node} is dominated by a CheckMaps with a single map |
127 // for the {receiver}, and if so use that map for the lowering below. | 127 // for the {receiver}, and if so use that map for the lowering below. |
128 for (Node* dominator = effect;;) { | 128 for (Node* dominator = effect;;) { |
129 if (dominator->opcode() == IrOpcode::kCheckMaps && | 129 if (dominator->opcode() == IrOpcode::kCheckMaps && |
130 IsSame(dominator->InputAt(0), receiver)) { | 130 IsSame(dominator->InputAt(0), receiver)) { |
131 if (dominator->op()->ValueInputCount() == 2) { | 131 ZoneHandleSet<Map> const& maps = |
132 HeapObjectMatcher m(dominator->InputAt(1)); | 132 CheckMapsParametersOf(dominator->op()).maps(); |
133 if (m.HasValue()) return Handle<Map>::cast(m.Value()); | 133 return (maps.size() == 1) ? MaybeHandle<Map>(maps[0]) |
134 } | 134 : MaybeHandle<Map>(); |
135 return MaybeHandle<Map>(); | |
136 } | 135 } |
137 if (dominator->op()->EffectInputCount() != 1) { | 136 if (dominator->op()->EffectInputCount() != 1) { |
138 // Didn't find any appropriate CheckMaps node. | 137 // Didn't find any appropriate CheckMaps node. |
139 return MaybeHandle<Map>(); | 138 return MaybeHandle<Map>(); |
140 } | 139 } |
141 dominator = NodeProperties::GetEffectInput(dominator); | 140 dominator = NodeProperties::GetEffectInput(dominator); |
142 } | 141 } |
143 } | 142 } |
144 | 143 |
145 // TODO(turbofan): This was copied from Crankshaft, might be too restrictive. | 144 // TODO(turbofan): This was copied from Crankshaft, might be too restrictive. |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 Node* etrue1 = efalse0; | 405 Node* etrue1 = efalse0; |
407 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | 406 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
408 { | 407 { |
409 // iterator.[[NextIndex]] < array.length, continue iterating | 408 // iterator.[[NextIndex]] < array.length, continue iterating |
410 vdone_true1 = jsgraph()->FalseConstant(); | 409 vdone_true1 = jsgraph()->FalseConstant(); |
411 if (kind == IterationKind::kKeys) { | 410 if (kind == IterationKind::kKeys) { |
412 vtrue1 = index; | 411 vtrue1 = index; |
413 } else { | 412 } else { |
414 // For value/entry iteration, first step is a mapcheck to ensure | 413 // For value/entry iteration, first step is a mapcheck to ensure |
415 // inlining is still valid. | 414 // inlining is still valid. |
| 415 Node* array_map = etrue1 = |
| 416 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| 417 array, etrue1, if_true1); |
416 Node* orig_map = etrue1 = | 418 Node* orig_map = etrue1 = |
417 graph()->NewNode(simplified()->LoadField( | 419 graph()->NewNode(simplified()->LoadField( |
418 AccessBuilder::ForJSArrayIteratorObjectMap()), | 420 AccessBuilder::ForJSArrayIteratorObjectMap()), |
419 iterator, etrue1, if_true1); | 421 iterator, etrue1, if_true1); |
420 etrue1 = graph()->NewNode(simplified()->CheckMaps(1), array, orig_map, | 422 Node* check_map = graph()->NewNode(simplified()->ReferenceEqual(), |
421 etrue1, if_true1); | 423 array_map, orig_map); |
| 424 etrue1 = graph()->NewNode(simplified()->CheckIf(), check_map, etrue1, |
| 425 if_true1); |
422 } | 426 } |
423 | 427 |
424 if (kind != IterationKind::kKeys) { | 428 if (kind != IterationKind::kKeys) { |
425 Node* elements = etrue1 = graph()->NewNode( | 429 Node* elements = etrue1 = graph()->NewNode( |
426 simplified()->LoadField(AccessBuilder::ForJSObjectElements()), | 430 simplified()->LoadField(AccessBuilder::ForJSObjectElements()), |
427 array, etrue1, if_true1); | 431 array, etrue1, if_true1); |
428 Node* value = etrue1 = graph()->NewNode( | 432 Node* value = etrue1 = graph()->NewNode( |
429 simplified()->LoadElement( | 433 simplified()->LoadElement( |
430 AccessBuilder::ForFixedArrayElement(elements_kind)), | 434 AccessBuilder::ForFixedArrayElement(elements_kind)), |
431 elements, index, etrue1, if_true1); | 435 elements, index, etrue1, if_true1); |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 return NoChange(); | 907 return NoChange(); |
904 } | 908 } |
905 | 909 |
906 namespace { | 910 namespace { |
907 | 911 |
908 bool HasInstanceTypeWitness(Node* receiver, Node* effect, | 912 bool HasInstanceTypeWitness(Node* receiver, Node* effect, |
909 InstanceType instance_type) { | 913 InstanceType instance_type) { |
910 for (Node* dominator = effect;;) { | 914 for (Node* dominator = effect;;) { |
911 if (dominator->opcode() == IrOpcode::kCheckMaps && | 915 if (dominator->opcode() == IrOpcode::kCheckMaps && |
912 IsSame(dominator->InputAt(0), receiver)) { | 916 IsSame(dominator->InputAt(0), receiver)) { |
| 917 ZoneHandleSet<Map> const& maps = |
| 918 CheckMapsParametersOf(dominator->op()).maps(); |
913 // Check if all maps have the given {instance_type}. | 919 // Check if all maps have the given {instance_type}. |
914 for (int i = 1; i < dominator->op()->ValueInputCount(); ++i) { | 920 for (size_t i = 0; i < maps.size(); ++i) { |
915 Node* const map = NodeProperties::GetValueInput(dominator, i); | 921 if (maps[i]->instance_type() != instance_type) return false; |
916 Type* const map_type = NodeProperties::GetType(map); | |
917 if (!map_type->IsHeapConstant()) return false; | |
918 Handle<Map> const map_value = | |
919 Handle<Map>::cast(map_type->AsHeapConstant()->Value()); | |
920 if (map_value->instance_type() != instance_type) return false; | |
921 } | 922 } |
922 return true; | 923 return true; |
923 } | 924 } |
924 switch (dominator->opcode()) { | 925 switch (dominator->opcode()) { |
925 case IrOpcode::kStoreField: { | 926 case IrOpcode::kStoreField: { |
926 FieldAccess const& access = FieldAccessOf(dominator->op()); | 927 FieldAccess const& access = FieldAccessOf(dominator->op()); |
927 if (access.base_is_tagged == kTaggedBase && | 928 if (access.base_is_tagged == kTaggedBase && |
928 access.offset == HeapObject::kMapOffset) { | 929 access.offset == HeapObject::kMapOffset) { |
929 return false; | 930 return false; |
930 } | 931 } |
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2055 return jsgraph()->simplified(); | 2056 return jsgraph()->simplified(); |
2056 } | 2057 } |
2057 | 2058 |
2058 JSOperatorBuilder* JSBuiltinReducer::javascript() const { | 2059 JSOperatorBuilder* JSBuiltinReducer::javascript() const { |
2059 return jsgraph()->javascript(); | 2060 return jsgraph()->javascript(); |
2060 } | 2061 } |
2061 | 2062 |
2062 } // namespace compiler | 2063 } // namespace compiler |
2063 } // namespace internal | 2064 } // namespace internal |
2064 } // namespace v8 | 2065 } // namespace v8 |
OLD | NEW |