OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 "hydrogen-check-elimination.h" | 5 #include "hydrogen-check-elimination.h" |
6 #include "hydrogen-alias-analysis.h" | 6 #include "hydrogen-alias-analysis.h" |
7 #include "hydrogen-flow-engine.h" | 7 #include "hydrogen-flow-engine.h" |
8 | 8 |
9 #define GLOBAL 1 | 9 #define GLOBAL 1 |
10 | 10 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 } | 63 } |
64 case HValue::kCompareObjectEqAndBranch: { | 64 case HValue::kCompareObjectEqAndBranch: { |
65 ReduceCompareObjectEqAndBranch(HCompareObjectEqAndBranch::cast(instr)); | 65 ReduceCompareObjectEqAndBranch(HCompareObjectEqAndBranch::cast(instr)); |
66 break; | 66 break; |
67 } | 67 } |
68 case HValue::kTransitionElementsKind: { | 68 case HValue::kTransitionElementsKind: { |
69 ReduceTransitionElementsKind( | 69 ReduceTransitionElementsKind( |
70 HTransitionElementsKind::cast(instr)); | 70 HTransitionElementsKind::cast(instr)); |
71 break; | 71 break; |
72 } | 72 } |
73 case HValue::kCheckMapValue: { | |
74 ReduceCheckMapValue(HCheckMapValue::cast(instr)); | |
75 break; | |
76 } | |
77 case HValue::kCheckHeapObject: { | 73 case HValue::kCheckHeapObject: { |
78 ReduceCheckHeapObject(HCheckHeapObject::cast(instr)); | 74 ReduceCheckHeapObject(HCheckHeapObject::cast(instr)); |
79 break; | 75 break; |
80 } | 76 } |
81 default: { | 77 default: { |
82 // If the instruction changes maps uncontrollably, drop everything. | 78 // If the instruction changes maps uncontrollably, drop everything. |
83 if (instr->CheckChangesFlag(kElementsKind) || | 79 if (instr->CheckChangesFlag(kElementsKind) || |
84 instr->CheckChangesFlag(kMaps) || | 80 instr->CheckChangesFlag(kMaps) || |
85 instr->CheckChangesFlag(kOsrEntries)) { | 81 instr->CheckChangesFlag(kOsrEntries)) { |
86 Kill(); | 82 Kill(); |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 MapSet maps = FindMaps(object); | 350 MapSet maps = FindMaps(object); |
355 if (maps == NULL || maps->size() != 1) return; // Not a constant. | 351 if (maps == NULL || maps->size() != 1) return; // Not a constant. |
356 | 352 |
357 Unique<Map> map = maps->at(0); | 353 Unique<Map> map = maps->at(0); |
358 HConstant* constant = HConstant::CreateAndInsertBefore( | 354 HConstant* constant = HConstant::CreateAndInsertBefore( |
359 instr->block()->graph()->zone(), map, true, instr); | 355 instr->block()->graph()->zone(), map, true, instr); |
360 instr->DeleteAndReplaceWith(constant); | 356 instr->DeleteAndReplaceWith(constant); |
361 INC_STAT(loads_); | 357 INC_STAT(loads_); |
362 } | 358 } |
363 | 359 |
364 void ReduceCheckMapValue(HCheckMapValue* instr) { | |
365 if (!instr->map()->IsConstant()) return; // Nothing to learn. | |
366 | |
367 HValue* object = instr->value()->ActualValue(); | |
368 // Match a HCheckMapValue(object, HConstant(map)) | |
369 Unique<Map> map = MapConstant(instr->map()); | |
370 | |
371 HCheckTableEntry* entry = Find(object); | |
372 if (entry != NULL) { | |
373 if (entry->maps_->Contains(map)) { | |
374 if (entry->maps_->size() == 1) { | |
375 // Object is known to have exactly this map. | |
376 if (entry->check_ != NULL) { | |
377 instr->DeleteAndReplaceWith(entry->check_); | |
378 } else { | |
379 // Mark check as dead but leave it in the graph as a checkpoint for | |
380 // subsequent checks. | |
381 instr->SetFlag(HValue::kIsDead); | |
382 entry->check_ = instr; | |
383 } | |
384 INC_STAT(removed_); | |
385 } else { | |
386 // Only one map survives the check. | |
387 entry->maps_ = new(zone()) UniqueSet<Map>(map, zone()); | |
388 entry->check_ = instr; | |
389 } | |
390 } | |
391 } else { | |
392 // No prior information. | |
393 Insert(object, instr, map); | |
394 } | |
395 } | |
396 | |
397 void ReduceCheckHeapObject(HCheckHeapObject* instr) { | 360 void ReduceCheckHeapObject(HCheckHeapObject* instr) { |
398 if (FindMaps(instr->value()->ActualValue()) != NULL) { | 361 if (FindMaps(instr->value()->ActualValue()) != NULL) { |
399 // If the object has known maps, it's definitely a heap object. | 362 // If the object has known maps, it's definitely a heap object. |
400 instr->DeleteAndReplaceWith(instr->value()); | 363 instr->DeleteAndReplaceWith(instr->value()); |
401 INC_STAT(removed_cho_); | 364 INC_STAT(removed_cho_); |
402 } | 365 } |
403 } | 366 } |
404 | 367 |
405 void ReduceStoreNamedField(HStoreNamedField* instr) { | 368 void ReduceStoreNamedField(HStoreNamedField* instr) { |
406 HValue* object = instr->object()->ActualValue(); | 369 HValue* object = instr->object()->ActualValue(); |
407 if (instr->has_transition()) { | 370 if (instr->has_transition()) { |
408 // This store transitions the object to a new map. | 371 // This store transitions the object to a new map. |
409 Kill(object); | 372 Kill(object); |
410 Insert(object, NULL, MapConstant(instr->transition())); | 373 Insert(object, NULL, HConstant::cast(instr->transition())->MapValue()); |
411 } else if (instr->access().IsMap()) { | 374 } else if (instr->access().IsMap()) { |
412 // This is a store directly to the map field of the object. | 375 // This is a store directly to the map field of the object. |
413 Kill(object); | 376 Kill(object); |
414 if (!instr->value()->IsConstant()) return; | 377 if (!instr->value()->IsConstant()) return; |
415 Insert(object, NULL, MapConstant(instr->value())); | 378 Insert(object, NULL, HConstant::cast(instr->value())->MapValue()); |
416 } else { | 379 } else { |
417 // If the instruction changes maps, it should be handled above. | 380 // If the instruction changes maps, it should be handled above. |
418 CHECK(!instr->CheckChangesFlag(kMaps)); | 381 CHECK(!instr->CheckChangesFlag(kMaps)); |
419 } | 382 } |
420 } | 383 } |
421 | 384 |
422 void ReduceCompareMap(HCompareMap* instr) { | 385 void ReduceCompareMap(HCompareMap* instr) { |
423 MapSet maps = FindMaps(instr->value()->ActualValue()); | 386 MapSet maps = FindMaps(instr->value()->ActualValue()); |
424 if (maps == NULL) return; | 387 if (maps == NULL) return; |
425 | 388 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 void Insert(HValue* object, HInstruction* check, MapSet maps) { | 543 void Insert(HValue* object, HInstruction* check, MapSet maps) { |
581 HCheckTableEntry* entry = &entries_[cursor_++]; | 544 HCheckTableEntry* entry = &entries_[cursor_++]; |
582 entry->object_ = object; | 545 entry->object_ = object; |
583 entry->check_ = check; | 546 entry->check_ = check; |
584 entry->maps_ = maps; | 547 entry->maps_ = maps; |
585 // If the table becomes full, wrap around and overwrite older entries. | 548 // If the table becomes full, wrap around and overwrite older entries. |
586 if (cursor_ == kMaxTrackedObjects) cursor_ = 0; | 549 if (cursor_ == kMaxTrackedObjects) cursor_ = 0; |
587 if (size_ < kMaxTrackedObjects) size_++; | 550 if (size_ < kMaxTrackedObjects) size_++; |
588 } | 551 } |
589 | 552 |
590 Unique<Map> MapConstant(HValue* value) { | |
591 return Unique<Map>::cast(HConstant::cast(value)->GetUnique()); | |
592 } | |
593 | |
594 Zone* zone() const { return phase_->zone(); } | 553 Zone* zone() const { return phase_->zone(); } |
595 | 554 |
596 friend class HCheckMapsEffects; | 555 friend class HCheckMapsEffects; |
597 friend class HCheckEliminationPhase; | 556 friend class HCheckEliminationPhase; |
598 | 557 |
599 HCheckEliminationPhase* phase_; | 558 HCheckEliminationPhase* phase_; |
600 HCheckTableEntry entries_[kMaxTrackedObjects]; | 559 HCheckTableEntry entries_[kMaxTrackedObjects]; |
601 int16_t cursor_; // Must be <= kMaxTrackedObjects | 560 int16_t cursor_; // Must be <= kMaxTrackedObjects |
602 int16_t size_; // Must be <= kMaxTrackedObjects | 561 int16_t size_; // Must be <= kMaxTrackedObjects |
603 // TODO(titzer): STATIC_ASSERT kMaxTrackedObjects < max(cursor_) | 562 // TODO(titzer): STATIC_ASSERT kMaxTrackedObjects < max(cursor_) |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 PRINT_STAT(removed_cho); | 656 PRINT_STAT(removed_cho); |
698 PRINT_STAT(narrowed); | 657 PRINT_STAT(narrowed); |
699 PRINT_STAT(loads); | 658 PRINT_STAT(loads); |
700 PRINT_STAT(empty); | 659 PRINT_STAT(empty); |
701 PRINT_STAT(compares_true); | 660 PRINT_STAT(compares_true); |
702 PRINT_STAT(compares_false); | 661 PRINT_STAT(compares_false); |
703 PRINT_STAT(transitions); | 662 PRINT_STAT(transitions); |
704 } | 663 } |
705 | 664 |
706 } } // namespace v8::internal | 665 } } // namespace v8::internal |
OLD | NEW |