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 |