Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(333)

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 184523002: Allocation sinking for contexts. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: support Redefinitions in alias computation Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 5417 matching lines...) Expand 10 before | Expand all | Expand 10 after
5428 return (kind_ == other->kind_) && 5428 return (kind_ == other->kind_) &&
5429 (representation_ == other->representation_) && 5429 (representation_ == other->representation_) &&
5430 (instance_ == other->instance_) && 5430 (instance_ == other->instance_) &&
5431 SameField(other); 5431 SameField(other);
5432 } 5432 }
5433 5433
5434 // Create a zone allocated copy of this place and assign given id to it. 5434 // Create a zone allocated copy of this place and assign given id to it.
5435 static Place* Wrap(Isolate* isolate, const Place& place, intptr_t id); 5435 static Place* Wrap(Isolate* isolate, const Place& place, intptr_t id);
5436 5436
5437 static bool IsAllocation(Definition* defn) { 5437 static bool IsAllocation(Definition* defn) {
5438 // TODO(vegorov): add CreateContext to this list.
5439 return (defn != NULL) && 5438 return (defn != NULL) &&
5440 (defn->IsAllocateObject() || 5439 (defn->IsAllocateObject() ||
5441 defn->IsCreateArray() || 5440 defn->IsCreateArray() ||
5441 defn->IsAllocateUninitializedContext() ||
5442 (defn->IsStaticCall() && 5442 (defn->IsStaticCall() &&
5443 defn->AsStaticCall()->IsRecognizedFactory())); 5443 defn->AsStaticCall()->IsRecognizedFactory()));
5444 } 5444 }
5445 5445
5446 private: 5446 private:
5447 Place(Kind kind, Definition* instance, intptr_t selector) 5447 Place(Kind kind, Definition* instance, intptr_t selector)
5448 : kind_(kind), 5448 : kind_(kind),
5449 representation_(kNoRepresentation), 5449 representation_(kNoRepresentation),
5450 instance_(instance), 5450 instance_(instance),
5451 raw_selector_(selector), 5451 raw_selector_(selector),
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
5892 // Can add more objects into aliasing_worklist_. 5892 // Can add more objects into aliasing_worklist_.
5893 bool AnyUseCreatesAlias(Definition* defn) { 5893 bool AnyUseCreatesAlias(Definition* defn) {
5894 for (Value* use = defn->input_use_list(); 5894 for (Value* use = defn->input_use_list();
5895 use != NULL; 5895 use != NULL;
5896 use = use->next_use()) { 5896 use = use->next_use()) {
5897 Instruction* instr = use->instruction(); 5897 Instruction* instr = use->instruction();
5898 if (instr->IsPushArgument() || 5898 if (instr->IsPushArgument() ||
5899 (instr->IsStoreIndexed() 5899 (instr->IsStoreIndexed()
5900 && (use->use_index() == StoreIndexedInstr::kValuePos)) || 5900 && (use->use_index() == StoreIndexedInstr::kValuePos)) ||
5901 instr->IsStoreStaticField() || 5901 instr->IsStoreStaticField() ||
5902 instr->IsPhi() || 5902 instr->IsPhi()) {
5903 instr->IsAssertAssignable() ||
5904 instr->IsRedefinition()) {
5905 return true; 5903 return true;
5904 } else if (instr->IsAssertAssignable() ||
5905 instr->IsRedefinition()) {
5906 return AnyUseCreatesAlias(instr->AsDefinition());
5906 } else if ((instr->IsStoreInstanceField() 5907 } else if ((instr->IsStoreInstanceField()
5907 && (use->use_index() != StoreInstanceFieldInstr::kInstancePos))) { 5908 && (use->use_index() != StoreInstanceFieldInstr::kInstancePos))) {
5908 ASSERT(use->use_index() == StoreInstanceFieldInstr::kValuePos); 5909 ASSERT(use->use_index() == StoreInstanceFieldInstr::kValuePos);
5909 // If we store this value into an object that is not aliased itself 5910 // If we store this value into an object that is not aliased itself
5910 // and we never load again then the store does not create an alias. 5911 // and we never load again then the store does not create an alias.
5911 StoreInstanceFieldInstr* store = instr->AsStoreInstanceField(); 5912 StoreInstanceFieldInstr* store = instr->AsStoreInstanceField();
5912 Definition* instance = store->instance()->definition(); 5913 Definition* instance = store->instance()->definition();
5913 if (instance->IsAllocateObject() && !instance->Identity().IsAliased()) { 5914 if (Place::IsAllocation(instance) &&
5915 !instance->Identity().IsAliased()) {
5914 bool is_load, is_store; 5916 bool is_load, is_store;
5915 Place store_place(instr, &is_load, &is_store); 5917 Place store_place(instr, &is_load, &is_store);
5916 5918
5917 if (!HasLoadsFromPlace(instance, &store_place)) { 5919 if (!HasLoadsFromPlace(instance, &store_place)) {
Vyacheslav Egorov (Google) 2014/11/03 13:37:48 HasLoadsFromPlace has to account for redifinitions
5918 // No loads found that match this store. If it is yet unknown if 5920 // No loads found that match this store. If it is yet unknown if
5919 // the object is not aliased then optimistically assume this but 5921 // the object is not aliased then optimistically assume this but
5920 // add it to the worklist to check its uses transitively. 5922 // add it to the worklist to check its uses transitively.
5921 if (instance->Identity().IsUnknown()) { 5923 if (instance->Identity().IsUnknown()) {
5922 instance->SetIdentity(AliasIdentity::NotAliased()); 5924 instance->SetIdentity(AliasIdentity::NotAliased());
5923 aliasing_worklist_.Add(instance); 5925 aliasing_worklist_.Add(instance);
5924 } 5926 }
5925 continue; 5927 continue;
5926 } 5928 }
5927 } 5929 }
5928 5930
5929 return true; 5931 return true;
5930 } 5932 }
5931 } 5933 }
5932 return false; 5934 return false;
5933 } 5935 }
5934 5936
5935 // Mark any value stored into the given object as potentially aliased. 5937 // Mark any value stored into the given object as potentially aliased.
5936 void MarkStoredValuesEscaping(Definition* defn) { 5938 void MarkStoredValuesEscaping(Definition* defn) {
5937 if (!defn->IsAllocateObject()) { 5939 if (!Place::IsAllocation(defn)) {
5938 return; 5940 return;
5939 } 5941 }
5940 5942
5941 // Find all stores into this object. 5943 // Find all stores into this object.
5942 for (Value* use = defn->input_use_list(); 5944 for (Value* use = defn->input_use_list();
5943 use != NULL; 5945 use != NULL;
5944 use = use->next_use()) { 5946 use = use->next_use()) {
5945 if ((use->use_index() == StoreInstanceFieldInstr::kInstancePos) && 5947 if ((use->use_index() == StoreInstanceFieldInstr::kInstancePos) &&
5946 use->instruction()->IsStoreInstanceField()) { 5948 use->instruction()->IsStoreInstanceField()) {
5947 StoreInstanceFieldInstr* store = 5949 StoreInstanceFieldInstr* store =
(...skipping 3432 matching lines...) Expand 10 before | Expand all | Expand 10 after
9380 } 9382 }
9381 9383
9382 return false; 9384 return false;
9383 } 9385 }
9384 9386
9385 9387
9386 // Right now we are attempting to sink allocation only into 9388 // Right now we are attempting to sink allocation only into
9387 // deoptimization exit. So candidate should only be used in StoreInstanceField 9389 // deoptimization exit. So candidate should only be used in StoreInstanceField
9388 // instructions that write into fields of the allocated object. 9390 // instructions that write into fields of the allocated object.
9389 // We do not support materialization of the object that has type arguments. 9391 // We do not support materialization of the object that has type arguments.
9390 static bool IsAllocationSinkingCandidate(AllocateObjectInstr* alloc, 9392 static bool IsAllocationSinkingCandidate(Definition* alloc,
9391 SafeUseCheck check_type) { 9393 SafeUseCheck check_type) {
9392 for (Value* use = alloc->input_use_list(); 9394 for (Value* use = alloc->input_use_list();
9393 use != NULL; 9395 use != NULL;
9394 use = use->next_use()) { 9396 use = use->next_use()) {
9395 if (!IsSafeUse(use, check_type)) { 9397 if (!IsSafeUse(use, check_type)) {
9396 if (FLAG_trace_optimization) { 9398 if (FLAG_trace_optimization) {
9397 OS::Print("use of %s at %s is unsafe for allocation sinking\n", 9399 OS::Print("use of %s at %s is unsafe for allocation sinking\n",
9398 alloc->ToCString(), 9400 alloc->ToCString(),
9399 use->instruction()->ToCString()); 9401 use->instruction()->ToCString());
9400 } 9402 }
(...skipping 12 matching lines...) Expand all
9413 if (store != NULL) { 9415 if (store != NULL) {
9414 return store->instance()->definition(); 9416 return store->instance()->definition();
9415 } 9417 }
9416 9418
9417 return NULL; 9419 return NULL;
9418 } 9420 }
9419 9421
9420 9422
9421 // Remove the given allocation from the graph. It is not observable. 9423 // Remove the given allocation from the graph. It is not observable.
9422 // If deoptimization occurs the object will be materialized. 9424 // If deoptimization occurs the object will be materialized.
9423 void AllocationSinking::EliminateAllocation(AllocateObjectInstr* alloc) { 9425 void AllocationSinking::EliminateAllocation(Definition* alloc) {
9424 ASSERT(IsAllocationSinkingCandidate(alloc, kStrictCheck)); 9426 ASSERT(IsAllocationSinkingCandidate(alloc, kStrictCheck));
9425 9427
9426 if (FLAG_trace_optimization) { 9428 if (FLAG_trace_optimization) {
9427 OS::Print("removing allocation from the graph: v%" Pd "\n", 9429 OS::Print("removing allocation from the graph: v%" Pd "\n",
9428 alloc->ssa_temp_index()); 9430 alloc->ssa_temp_index());
9429 } 9431 }
9430 9432
9431 // As an allocation sinking candidate it is only used in stores to its own 9433 // As an allocation sinking candidate it is only used in stores to its own
9432 // fields. Remove these stores. 9434 // fields. Remove these stores.
9433 for (Value* use = alloc->input_use_list(); 9435 for (Value* use = alloc->input_use_list();
(...skipping 25 matching lines...) Expand all
9459 // Find allocation instructions that can be potentially eliminated and 9461 // Find allocation instructions that can be potentially eliminated and
9460 // rematerialized at deoptimization exits if needed. See IsSafeUse 9462 // rematerialized at deoptimization exits if needed. See IsSafeUse
9461 // for the description of algorithm used below. 9463 // for the description of algorithm used below.
9462 void AllocationSinking::CollectCandidates() { 9464 void AllocationSinking::CollectCandidates() {
9463 // Optimistically collect all potential candidates. 9465 // Optimistically collect all potential candidates.
9464 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator(); 9466 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
9465 !block_it.Done(); 9467 !block_it.Done();
9466 block_it.Advance()) { 9468 block_it.Advance()) {
9467 BlockEntryInstr* block = block_it.Current(); 9469 BlockEntryInstr* block = block_it.Current();
9468 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 9470 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
9469 AllocateObjectInstr* alloc = it.Current()->AsAllocateObject(); 9471 { AllocateObjectInstr* alloc = it.Current()->AsAllocateObject();
9470 if ((alloc != NULL) && 9472 if ((alloc != NULL) &&
9471 IsAllocationSinkingCandidate(alloc, kOptimisticCheck)) { 9473 IsAllocationSinkingCandidate(alloc, kOptimisticCheck)) {
9472 alloc->SetIdentity(AliasIdentity::AllocationSinkingCandidate()); 9474 alloc->SetIdentity(AliasIdentity::AllocationSinkingCandidate());
9473 candidates_.Add(alloc); 9475 candidates_.Add(alloc);
9476 }
9477 }
9478 { AllocateUninitializedContextInstr* alloc =
9479 it.Current()->AsAllocateUninitializedContext();
9480 if ((alloc != NULL) &&
9481 IsAllocationSinkingCandidate(alloc, kOptimisticCheck)) {
9482 alloc->SetIdentity(AliasIdentity::AllocationSinkingCandidate());
9483 candidates_.Add(alloc);
9484 }
9474 } 9485 }
9475 } 9486 }
9476 } 9487 }
9477 9488
9478 // Transitively unmark all candidates that are not strictly valid. 9489 // Transitively unmark all candidates that are not strictly valid.
9479 bool changed; 9490 bool changed;
9480 do { 9491 do {
9481 changed = false; 9492 changed = false;
9482 for (intptr_t i = 0; i < candidates_.length(); i++) { 9493 for (intptr_t i = 0; i < candidates_.length(); i++) {
9483 AllocateObjectInstr* alloc = candidates_[i]; 9494 Definition* alloc = candidates_[i];
9484 if (alloc->Identity().IsAllocationSinkingCandidate()) { 9495 if (alloc->Identity().IsAllocationSinkingCandidate()) {
9485 if (!IsAllocationSinkingCandidate(alloc, kStrictCheck)) { 9496 if (!IsAllocationSinkingCandidate(alloc, kStrictCheck)) {
9486 alloc->SetIdentity(AliasIdentity::Unknown()); 9497 alloc->SetIdentity(AliasIdentity::Unknown());
9487 changed = true; 9498 changed = true;
9488 } 9499 }
9489 } 9500 }
9490 } 9501 }
9491 } while (changed); 9502 } while (changed);
9492 9503
9493 // Shrink the list of candidates removing all unmarked ones. 9504 // Shrink the list of candidates removing all unmarked ones.
9494 intptr_t j = 0; 9505 intptr_t j = 0;
9495 for (intptr_t i = 0; i < candidates_.length(); i++) { 9506 for (intptr_t i = 0; i < candidates_.length(); i++) {
9496 AllocateObjectInstr* alloc = candidates_[i]; 9507 Definition* alloc = candidates_[i];
9497 if (alloc->Identity().IsAllocationSinkingCandidate()) { 9508 if (alloc->Identity().IsAllocationSinkingCandidate()) {
9498 if (FLAG_trace_optimization) { 9509 if (FLAG_trace_optimization) {
9499 OS::Print("discovered allocation sinking candidate: v%" Pd "\n", 9510 OS::Print("discovered allocation sinking candidate: v%" Pd "\n",
9500 alloc->ssa_temp_index()); 9511 alloc->ssa_temp_index());
9501 } 9512 }
9502 9513
9503 if (j != i) { 9514 if (j != i) {
9504 candidates_[j] = alloc; 9515 candidates_[j] = alloc;
9505 } 9516 }
9506 j++; 9517 j++;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
9568 // the load forwarding because they flow into phis that load forwarding 9579 // the load forwarding because they flow into phis that load forwarding
9569 // inserts. Discover such allocations and remove them from the list 9580 // inserts. Discover such allocations and remove them from the list
9570 // of allocation sinking candidates undoing all changes that we did 9581 // of allocation sinking candidates undoing all changes that we did
9571 // in preparation for sinking these allocations. 9582 // in preparation for sinking these allocations.
9572 void AllocationSinking::DiscoverFailedCandidates() { 9583 void AllocationSinking::DiscoverFailedCandidates() {
9573 // Transitively unmark all candidates that are not strictly valid. 9584 // Transitively unmark all candidates that are not strictly valid.
9574 bool changed; 9585 bool changed;
9575 do { 9586 do {
9576 changed = false; 9587 changed = false;
9577 for (intptr_t i = 0; i < candidates_.length(); i++) { 9588 for (intptr_t i = 0; i < candidates_.length(); i++) {
9578 AllocateObjectInstr* alloc = candidates_[i]; 9589 Definition* alloc = candidates_[i];
9579 if (alloc->Identity().IsAllocationSinkingCandidate()) { 9590 if (alloc->Identity().IsAllocationSinkingCandidate()) {
9580 if (!IsAllocationSinkingCandidate(alloc, kStrictCheck)) { 9591 if (!IsAllocationSinkingCandidate(alloc, kStrictCheck)) {
9581 alloc->SetIdentity(AliasIdentity::Unknown()); 9592 alloc->SetIdentity(AliasIdentity::Unknown());
9582 changed = true; 9593 changed = true;
9583 } 9594 }
9584 } 9595 }
9585 } 9596 }
9586 } while (changed); 9597 } while (changed);
9587 9598
9588 // Remove all failed candidates from the candidates list. 9599 // Remove all failed candidates from the candidates list.
9589 intptr_t j = 0; 9600 intptr_t j = 0;
9590 for (intptr_t i = 0; i < candidates_.length(); i++) { 9601 for (intptr_t i = 0; i < candidates_.length(); i++) {
9591 AllocateObjectInstr* alloc = candidates_[i]; 9602 Definition* alloc = candidates_[i];
9592 if (!alloc->Identity().IsAllocationSinkingCandidate()) { 9603 if (!alloc->Identity().IsAllocationSinkingCandidate()) {
9593 if (FLAG_trace_optimization) { 9604 if (FLAG_trace_optimization) {
9594 OS::Print("allocation v%" Pd " can't be eliminated\n", 9605 OS::Print("allocation v%" Pd " can't be eliminated\n",
9595 alloc->ssa_temp_index()); 9606 alloc->ssa_temp_index());
9596 } 9607 }
9597 9608
9598 #ifdef DEBUG 9609 #ifdef DEBUG
9599 for (Value* use = alloc->env_use_list(); 9610 for (Value* use = alloc->env_use_list();
9600 use != NULL; 9611 use != NULL;
9601 use = use->next_use()) { 9612 use = use->next_use()) {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
9765 } 9776 }
9766 9777
9767 return NULL; 9778 return NULL;
9768 } 9779 }
9769 9780
9770 9781
9771 // Insert MaterializeObject instruction for the given allocation before 9782 // Insert MaterializeObject instruction for the given allocation before
9772 // the given instruction that can deoptimize. 9783 // the given instruction that can deoptimize.
9773 void AllocationSinking::CreateMaterializationAt( 9784 void AllocationSinking::CreateMaterializationAt(
9774 Instruction* exit, 9785 Instruction* exit,
9775 AllocateObjectInstr* alloc, 9786 Definition* alloc,
9776 const Class& cls,
9777 const ZoneGrowableArray<const Object*>& slots) { 9787 const ZoneGrowableArray<const Object*>& slots) {
9778 ZoneGrowableArray<Value*>* values = 9788 ZoneGrowableArray<Value*>* values =
9779 new(I) ZoneGrowableArray<Value*>(slots.length()); 9789 new(I) ZoneGrowableArray<Value*>(slots.length());
9780 9790
9781 // All loads should be inserted before the first materialization so that 9791 // All loads should be inserted before the first materialization so that
9782 // IR follows the following pattern: loads, materializations, deoptimizing 9792 // IR follows the following pattern: loads, materializations, deoptimizing
9783 // instruction. 9793 // instruction.
9784 Instruction* load_point = FirstMaterializationAt(exit); 9794 Instruction* load_point = FirstMaterializationAt(exit);
9785 9795
9786 // Insert load instruction for every field. 9796 // Insert load instruction for every field.
9787 for (intptr_t i = 0; i < slots.length(); i++) { 9797 for (intptr_t i = 0; i < slots.length(); i++) {
9788 LoadFieldInstr* load = slots[i]->IsField() 9798 LoadFieldInstr* load = slots[i]->IsField()
9789 ? new(I) LoadFieldInstr( 9799 ? new(I) LoadFieldInstr(
9790 new(I) Value(alloc), 9800 new(I) Value(alloc),
9791 &Field::Cast(*slots[i]), 9801 &Field::Cast(*slots[i]),
9792 AbstractType::ZoneHandle(I), 9802 AbstractType::ZoneHandle(I),
9793 alloc->token_pos()) 9803 alloc->token_pos())
9794 : new(I) LoadFieldInstr( 9804 : new(I) LoadFieldInstr(
9795 new(I) Value(alloc), 9805 new(I) Value(alloc),
9796 Smi::Cast(*slots[i]).Value(), 9806 Smi::Cast(*slots[i]).Value(),
9797 AbstractType::ZoneHandle(I), 9807 AbstractType::ZoneHandle(I),
9798 alloc->token_pos()); 9808 alloc->token_pos());
9799 flow_graph_->InsertBefore( 9809 flow_graph_->InsertBefore(
9800 load_point, load, NULL, FlowGraph::kValue); 9810 load_point, load, NULL, FlowGraph::kValue);
9801 values->Add(new(I) Value(load)); 9811 values->Add(new(I) Value(load));
9802 } 9812 }
9803 9813
9804 MaterializeObjectInstr* mat = 9814 MaterializeObjectInstr* mat = NULL;
9805 new(I) MaterializeObjectInstr(alloc, cls, slots, values); 9815 if (alloc->IsAllocateObject()) {
9816 mat = new(I) MaterializeObjectInstr(
9817 alloc->AsAllocateObject(), slots, values);
9818 } else {
9819 ASSERT(alloc->IsAllocateUninitializedContext());
9820 mat = new(I) MaterializeObjectInstr(
9821 alloc->AsAllocateUninitializedContext(), slots, values);
9822 }
9823
9806 flow_graph_->InsertBefore(exit, mat, NULL, FlowGraph::kValue); 9824 flow_graph_->InsertBefore(exit, mat, NULL, FlowGraph::kValue);
9807 9825
9808 // Replace all mentions of this allocation with a newly inserted 9826 // Replace all mentions of this allocation with a newly inserted
9809 // MaterializeObject instruction. 9827 // MaterializeObject instruction.
9810 // We must preserve the identity: all mentions are replaced by the same 9828 // We must preserve the identity: all mentions are replaced by the same
9811 // materialization. 9829 // materialization.
9812 for (Environment::DeepIterator env_it(exit->env()); 9830 for (Environment::DeepIterator env_it(exit->env());
9813 !env_it.Done(); 9831 !env_it.Done();
9814 env_it.Advance()) { 9832 env_it.Advance()) {
9815 Value* use = env_it.CurrentValue(); 9833 Value* use = env_it.CurrentValue();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
9888 // We are not removing allocations from the worklist not to waste space on 9906 // We are not removing allocations from the worklist not to waste space on
9889 // the side maintaining BitVector of already processed allocations: worklist 9907 // the side maintaining BitVector of already processed allocations: worklist
9890 // is expected to be very small thus linear search in it is just as effecient 9908 // is expected to be very small thus linear search in it is just as effecient
9891 // as a bitvector. 9909 // as a bitvector.
9892 for (intptr_t i = 0; i < worklist_.length(); i++) { 9910 for (intptr_t i = 0; i < worklist_.length(); i++) {
9893 Collect(worklist_[i]); 9911 Collect(worklist_[i]);
9894 } 9912 }
9895 } 9913 }
9896 9914
9897 9915
9898 void AllocationSinking::InsertMaterializations(AllocateObjectInstr* alloc) { 9916 void AllocationSinking::InsertMaterializations(Definition* alloc) {
9899 // Collect all fields that are written for this instance. 9917 // Collect all fields that are written for this instance.
9900 ZoneGrowableArray<const Object*>* slots = 9918 ZoneGrowableArray<const Object*>* slots =
9901 new(I) ZoneGrowableArray<const Object*>(5); 9919 new(I) ZoneGrowableArray<const Object*>(5);
9902 9920
9903 for (Value* use = alloc->input_use_list(); 9921 for (Value* use = alloc->input_use_list();
9904 use != NULL; 9922 use != NULL;
9905 use = use->next_use()) { 9923 use = use->next_use()) {
9906 StoreInstanceFieldInstr* store = use->instruction()->AsStoreInstanceField(); 9924 StoreInstanceFieldInstr* store = use->instruction()->AsStoreInstanceField();
9907 if ((store != NULL) && (store->instance()->definition() == alloc)) { 9925 if ((store != NULL) && (store->instance()->definition() == alloc)) {
9908 if (!store->field().IsNull()) { 9926 if (!store->field().IsNull()) {
9909 AddSlot(slots, store->field()); 9927 AddSlot(slots, store->field());
9910 } else { 9928 } else {
9911 AddSlot(slots, Smi::ZoneHandle(I, Smi::New(store->offset_in_bytes()))); 9929 AddSlot(slots, Smi::ZoneHandle(I, Smi::New(store->offset_in_bytes())));
9912 } 9930 }
9913 } 9931 }
9914 } 9932 }
9915 9933
9916 if (alloc->ArgumentCount() > 0) { 9934 if (alloc->ArgumentCount() > 0) {
9917 ASSERT(alloc->ArgumentCount() == 1); 9935 AllocateObjectInstr* alloc_object = alloc->AsAllocateObject();
9918 intptr_t type_args_offset = alloc->cls().type_arguments_field_offset(); 9936 ASSERT(alloc_object->ArgumentCount() == 1);
9937 intptr_t type_args_offset =
9938 alloc_object->cls().type_arguments_field_offset();
9919 AddSlot(slots, Smi::ZoneHandle(I, Smi::New(type_args_offset))); 9939 AddSlot(slots, Smi::ZoneHandle(I, Smi::New(type_args_offset)));
9920 } 9940 }
9921 9941
9922 // Collect all instructions that mention this object in the environment. 9942 // Collect all instructions that mention this object in the environment.
9923 exits_collector_.CollectTransitively(alloc); 9943 exits_collector_.CollectTransitively(alloc);
9924 9944
9925 // Insert materializations at environment uses. 9945 // Insert materializations at environment uses.
9926 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 9946 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
9927 CreateMaterializationAt( 9947 CreateMaterializationAt(
9928 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); 9948 exits_collector_.exits()[i], alloc, *slots);
9929 } 9949 }
9930 } 9950 }
9931 9951
9932 9952
9933 } // namespace dart 9953 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698