| 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 |