OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "src/compiler/js-type-feedback-lowering.h" |
| 6 |
| 7 #include "src/compiler/access-builder.h" |
| 8 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/node-properties.h" |
| 10 |
| 11 namespace v8 { |
| 12 namespace internal { |
| 13 namespace compiler { |
| 14 |
| 15 JSTypeFeedbackLowering::JSTypeFeedbackLowering(Editor* editor, Flags flags, |
| 16 JSGraph* jsgraph) |
| 17 : AdvancedReducer(editor), |
| 18 flags_(flags), |
| 19 jsgraph_(jsgraph), |
| 20 simplified_(graph()->zone()) {} |
| 21 |
| 22 |
| 23 Reduction JSTypeFeedbackLowering::Reduce(Node* node) { |
| 24 switch (node->opcode()) { |
| 25 case IrOpcode::kJSLoadNamed: |
| 26 return ReduceJSLoadNamed(node); |
| 27 default: |
| 28 break; |
| 29 } |
| 30 return NoChange(); |
| 31 } |
| 32 |
| 33 |
| 34 Reduction JSTypeFeedbackLowering::ReduceJSLoadNamed(Node* node) { |
| 35 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); |
| 36 Node* receiver = NodeProperties::GetValueInput(node, 0); |
| 37 Type* receiver_type = NodeProperties::GetBounds(receiver).upper; |
| 38 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 39 Node* effect = NodeProperties::GetEffectInput(node); |
| 40 Node* control = NodeProperties::GetControlInput(node); |
| 41 // We need to make optimistic assumptions to continue. |
| 42 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
| 43 LoadNamedParameters const& p = LoadNamedParametersOf(node->op()); |
| 44 Handle<TypeFeedbackVector> vector; |
| 45 if (!p.feedback().vector().ToHandle(&vector)) return NoChange(); |
| 46 if (p.name().handle().is_identical_to(factory()->length_string())) { |
| 47 LoadICNexus nexus(vector, p.feedback().slot()); |
| 48 MapHandleList maps; |
| 49 if (nexus.ExtractMaps(&maps) > 0) { |
| 50 for (Handle<Map> map : maps) { |
| 51 if (map->instance_type() >= FIRST_NONSTRING_TYPE) return NoChange(); |
| 52 } |
| 53 // Optimistic optimization for "length" property of strings. |
| 54 if (receiver_type->Maybe(Type::TaggedSigned())) { |
| 55 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver); |
| 56 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 57 check, control); |
| 58 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 59 Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, |
| 60 effect, if_true); |
| 61 // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| 62 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
| 63 control = graph()->NewNode(common()->IfFalse(), branch); |
| 64 } |
| 65 Node* receiver_map = effect = |
| 66 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| 67 receiver, effect, control); |
| 68 Node* receiver_instance_type = effect = graph()->NewNode( |
| 69 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), |
| 70 receiver_map, effect, control); |
| 71 Node* check = |
| 72 graph()->NewNode(machine()->Uint32LessThan(), receiver_instance_type, |
| 73 jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE)); |
| 74 Node* branch = |
| 75 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 76 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 77 Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, |
| 78 effect, if_false); |
| 79 // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| 80 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
| 81 control = graph()->NewNode(common()->IfTrue(), branch); |
| 82 Node* value = effect = |
| 83 graph()->NewNode(simplified()->LoadField( |
| 84 AccessBuilder::ForStringLength(graph()->zone())), |
| 85 receiver, effect, control); |
| 86 ReplaceWithValue(node, value, effect, control); |
| 87 return Replace(value); |
| 88 } |
| 89 } |
| 90 return NoChange(); |
| 91 } |
| 92 |
| 93 |
| 94 Factory* JSTypeFeedbackLowering::factory() const { |
| 95 return isolate()->factory(); |
| 96 } |
| 97 |
| 98 |
| 99 CommonOperatorBuilder* JSTypeFeedbackLowering::common() const { |
| 100 return jsgraph()->common(); |
| 101 } |
| 102 |
| 103 |
| 104 Graph* JSTypeFeedbackLowering::graph() const { return jsgraph()->graph(); } |
| 105 |
| 106 |
| 107 Isolate* JSTypeFeedbackLowering::isolate() const { |
| 108 return jsgraph()->isolate(); |
| 109 } |
| 110 |
| 111 |
| 112 MachineOperatorBuilder* JSTypeFeedbackLowering::machine() const { |
| 113 return jsgraph()->machine(); |
| 114 } |
| 115 |
| 116 } // namespace compiler |
| 117 } // namespace internal |
| 118 } // namespace v8 |
OLD | NEW |