OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 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-type-feedback.h" | 5 #include "src/compiler/js-type-feedback.h" |
6 | 6 |
7 #include "src/property-details.h" | 7 #include "src/property-details.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/ast.h" | 10 #include "src/ast.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 } | 41 } |
42 | 42 |
43 | 43 |
44 void JSTypeFeedbackTable::Record(Node* node, FeedbackVectorICSlot slot) { | 44 void JSTypeFeedbackTable::Record(Node* node, FeedbackVectorICSlot slot) { |
45 feedback_vector_ic_slot_map_.insert(std::make_pair(node->id(), slot)); | 45 feedback_vector_ic_slot_map_.insert(std::make_pair(node->id(), slot)); |
46 } | 46 } |
47 | 47 |
48 | 48 |
49 Reduction JSTypeFeedbackSpecializer::Reduce(Node* node) { | 49 Reduction JSTypeFeedbackSpecializer::Reduce(Node* node) { |
50 switch (node->opcode()) { | 50 switch (node->opcode()) { |
51 case IrOpcode::kJSLoadProperty: { | 51 case IrOpcode::kJSLoadProperty: |
52 HeapObjectMatcher<Name> match(node->InputAt(1)); | |
53 if (match.HasValue() && match.Value().handle()->IsName()) { | |
54 // LoadProperty(o, "constant") => LoadNamed["constant"](o). | |
55 Unique<Name> name = match.Value(); | |
56 const VectorSlotPair& feedback = | |
57 LoadPropertyParametersOf(node->op()).feedback(); | |
58 node->set_op(jsgraph()->javascript()->LoadNamed(name, feedback, | |
59 NOT_CONTEXTUAL, KEYED)); | |
60 node->RemoveInput(1); | |
61 return ReduceJSLoadNamed(node); | |
62 } | |
63 return ReduceJSLoadProperty(node); | 52 return ReduceJSLoadProperty(node); |
64 } | |
65 case IrOpcode::kJSLoadNamed: | 53 case IrOpcode::kJSLoadNamed: |
66 return ReduceJSLoadNamed(node); | 54 return ReduceJSLoadNamed(node); |
67 case IrOpcode::kJSStoreNamed: | 55 case IrOpcode::kJSStoreNamed: |
68 return ReduceJSStoreNamed(node); | 56 return ReduceJSStoreNamed(node); |
69 case IrOpcode::kJSStoreProperty: { | 57 case IrOpcode::kJSStoreProperty: |
70 HeapObjectMatcher<Name> match(node->InputAt(1)); | |
71 if (match.HasValue() && match.Value().handle()->IsName()) { | |
72 // StoreProperty(o, "constant", v) => StoreNamed["constant"](o, v). | |
73 Unique<Name> name = match.Value(); | |
74 LanguageMode language_mode = OpParameter<LanguageMode>(node); | |
75 node->set_op( | |
76 jsgraph()->javascript()->StoreNamed(language_mode, name, KEYED)); | |
77 node->RemoveInput(1); | |
78 return ReduceJSStoreNamed(node); | |
79 } | |
80 return ReduceJSStoreProperty(node); | 58 return ReduceJSStoreProperty(node); |
81 } | |
82 default: | 59 default: |
83 break; | 60 break; |
84 } | 61 } |
85 return NoChange(); | 62 return NoChange(); |
86 } | 63 } |
87 | 64 |
88 | 65 |
89 static void AddFieldAccessTypes(FieldAccess* access, | 66 static void AddFieldAccessTypes(FieldAccess* access, |
90 PropertyDetails property_details) { | 67 PropertyDetails property_details) { |
91 if (property_details.representation().IsSmi()) { | 68 if (property_details.representation().IsSmi()) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); | 157 const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); |
181 Handle<Name> name = p.name().handle(); | 158 Handle<Name> name = p.name().handle(); |
182 SmallMapList maps; | 159 SmallMapList maps; |
183 | 160 |
184 FeedbackVectorICSlot slot = js_type_feedback_->FindFeedbackVectorICSlot(node); | 161 FeedbackVectorICSlot slot = js_type_feedback_->FindFeedbackVectorICSlot(node); |
185 if (slot.IsInvalid() || | 162 if (slot.IsInvalid() || |
186 oracle()->LoadInlineCacheState(slot) == UNINITIALIZED) { | 163 oracle()->LoadInlineCacheState(slot) == UNINITIALIZED) { |
187 // No type feedback ids or the load is uninitialized. | 164 // No type feedback ids or the load is uninitialized. |
188 return NoChange(); | 165 return NoChange(); |
189 } | 166 } |
190 if (p.load_ic() == NAMED) { | 167 oracle()->PropertyReceiverTypes(slot, name, &maps); |
191 oracle()->PropertyReceiverTypes(slot, name, &maps); | |
192 } else { | |
193 // The load named was originally a load property. | |
194 bool is_string; // Unused. | |
195 IcCheckType key_type; // Unused. | |
196 oracle()->KeyedPropertyReceiverTypes(slot, &maps, &is_string, &key_type); | |
197 } | |
198 | 168 |
199 Node* effect = NodeProperties::GetEffectInput(node); | 169 Node* effect = NodeProperties::GetEffectInput(node); |
200 | 170 |
201 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism | 171 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism |
202 if (!ENABLE_FAST_PROPERTY_LOADS) return NoChange(); | 172 if (!ENABLE_FAST_PROPERTY_LOADS) return NoChange(); |
203 | 173 |
204 Handle<Map> map = maps.first(); | 174 Handle<Map> map = maps.first(); |
205 FieldAccess field_access; | 175 FieldAccess field_access; |
206 if (!GetInObjectFieldAccess(LOAD, map, name, &field_access)) { | 176 if (!GetInObjectFieldAccess(LOAD, map, name, &field_access)) { |
207 return NoChange(); | 177 return NoChange(); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 | 276 |
307 const StoreNamedParameters& p = StoreNamedParametersOf(node->op()); | 277 const StoreNamedParameters& p = StoreNamedParametersOf(node->op()); |
308 Handle<Name> name = p.name().handle(); | 278 Handle<Name> name = p.name().handle(); |
309 SmallMapList maps; | 279 SmallMapList maps; |
310 TypeFeedbackId id = js_type_feedback_->FindTypeFeedbackId(node); | 280 TypeFeedbackId id = js_type_feedback_->FindTypeFeedbackId(node); |
311 if (id.IsNone() || oracle()->StoreIsUninitialized(id) == UNINITIALIZED) { | 281 if (id.IsNone() || oracle()->StoreIsUninitialized(id) == UNINITIALIZED) { |
312 // No type feedback ids or the store is uninitialized. | 282 // No type feedback ids or the store is uninitialized. |
313 // TODO(titzer): no feedback from vector ICs from stores. | 283 // TODO(titzer): no feedback from vector ICs from stores. |
314 return NoChange(); | 284 return NoChange(); |
315 } else { | 285 } else { |
316 if (p.store_ic() == NAMED) { | 286 oracle()->PropertyReceiverTypes(id, name, &maps); |
317 oracle()->PropertyReceiverTypes(id, name, &maps); | |
318 } else { | |
319 // The named store was originally a store property. | |
320 bool is_string; // Unused. | |
321 IcCheckType key_type; // Unused. | |
322 oracle()->KeyedPropertyReceiverTypes(id, &maps, &is_string, &key_type); | |
323 } | |
324 } | 287 } |
325 | 288 |
326 Node* receiver = node->InputAt(0); | 289 Node* receiver = node->InputAt(0); |
327 Node* effect = NodeProperties::GetEffectInput(node); | 290 Node* effect = NodeProperties::GetEffectInput(node); |
328 | 291 |
329 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism | 292 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism |
330 | 293 |
331 if (!ENABLE_FAST_PROPERTY_STORES) return NoChange(); | 294 if (!ENABLE_FAST_PROPERTY_STORES) return NoChange(); |
332 | 295 |
333 Handle<Map> map = maps.first(); | 296 Handle<Map> map = maps.first(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 BailoutId id = OpParameter<FrameStateCallInfo>(node).bailout_id(); | 365 BailoutId id = OpParameter<FrameStateCallInfo>(node).bailout_id(); |
403 if (id != BailoutId::None()) return frame_state; | 366 if (id != BailoutId::None()) return frame_state; |
404 } | 367 } |
405 } | 368 } |
406 return nullptr; | 369 return nullptr; |
407 } | 370 } |
408 | 371 |
409 } // namespace compiler | 372 } // namespace compiler |
410 } // namespace internal | 373 } // namespace internal |
411 } // namespace v8 | 374 } // namespace v8 |
OLD | NEW |