| Index: src/compiler/escape-analysis.cc
|
| diff --git a/src/compiler/escape-analysis.cc b/src/compiler/escape-analysis.cc
|
| index 822ba1b3c367e599aef901fc1377f7cd18e53f38..0a9c5aa00436c00c55aabf1918c7b12c26ae347a 100644
|
| --- a/src/compiler/escape-analysis.cc
|
| +++ b/src/compiler/escape-analysis.cc
|
| @@ -40,7 +40,6 @@ const Alias EscapeStatusAnalysis::kNotReachable =
|
| const Alias EscapeStatusAnalysis::kUntrackable =
|
| std::numeric_limits<Alias>::max() - 1;
|
|
|
| -
|
| class VirtualObject : public ZoneObject {
|
| public:
|
| enum Status {
|
| @@ -142,10 +141,8 @@ class VirtualObject : public ZoneObject {
|
| DISALLOW_COPY_AND_ASSIGN(VirtualObject);
|
| };
|
|
|
| -
|
| DEFINE_OPERATORS_FOR_FLAGS(VirtualObject::StatusFlags)
|
|
|
| -
|
| bool VirtualObject::UpdateFrom(const VirtualObject& other) {
|
| bool changed = status_ != other.status_;
|
| status_ = other.status_;
|
| @@ -163,11 +160,20 @@ bool VirtualObject::UpdateFrom(const VirtualObject& other) {
|
| return changed;
|
| }
|
|
|
| -
|
| class VirtualState : public ZoneObject {
|
| public:
|
| - VirtualState(NodeId owner, Zone* zone, size_t size);
|
| - VirtualState(NodeId owner, const VirtualState& states);
|
| + VirtualState(Node* owner, Zone* zone, size_t size)
|
| + : info_(size, nullptr, zone), owner_(owner) {}
|
| +
|
| + VirtualState(Node* owner, const VirtualState& state)
|
| + : info_(state.info_.size(), nullptr, state.info_.get_allocator().zone()),
|
| + owner_(owner) {
|
| + for (size_t i = 0; i < info_.size(); ++i) {
|
| + if (state.info_[i]) {
|
| + info_[i] = state.info_[i];
|
| + }
|
| + }
|
| + }
|
|
|
| VirtualObject* VirtualObjectFromAlias(size_t alias);
|
| VirtualObject* GetOrCreateTrackedVirtualObject(Alias alias, NodeId id,
|
| @@ -179,7 +185,7 @@ class VirtualState : public ZoneObject {
|
| bool MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
|
| CommonOperatorBuilder* common, Node* control, int arity);
|
| size_t size() const { return info_.size(); }
|
| - NodeId owner() const { return owner_; }
|
| + Node* owner() const { return owner_; }
|
| VirtualObject* Copy(VirtualObject* obj, Alias alias);
|
| void SetCopyRequired() {
|
| for (VirtualObject* obj : info_) {
|
| @@ -189,12 +195,11 @@ class VirtualState : public ZoneObject {
|
|
|
| private:
|
| ZoneVector<VirtualObject*> info_;
|
| - NodeId owner_;
|
| + Node* owner_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(VirtualState);
|
| };
|
|
|
| -
|
| class MergeCache : public ZoneObject {
|
| public:
|
| explicit MergeCache(Zone* zone)
|
| @@ -224,7 +229,6 @@ class MergeCache : public ZoneObject {
|
| DISALLOW_COPY_AND_ASSIGN(MergeCache);
|
| };
|
|
|
| -
|
| size_t MergeCache::LoadVirtualObjectsFromStatesFor(Alias alias) {
|
| objects_.clear();
|
| DCHECK_GT(states_.size(), 0u);
|
| @@ -238,7 +242,6 @@ size_t MergeCache::LoadVirtualObjectsFromStatesFor(Alias alias) {
|
| return min;
|
| }
|
|
|
| -
|
| void MergeCache::LoadVirtualObjectsForFieldsFrom(
|
| VirtualState* state, const ZoneVector<Alias>& aliases) {
|
| objects_.clear();
|
| @@ -252,7 +255,6 @@ void MergeCache::LoadVirtualObjectsForFieldsFrom(
|
| }
|
| }
|
|
|
| -
|
| Node* MergeCache::GetFields(size_t pos) {
|
| fields_.clear();
|
| Node* rep = pos >= objects_.front()->field_count()
|
| @@ -271,22 +273,6 @@ Node* MergeCache::GetFields(size_t pos) {
|
| return rep;
|
| }
|
|
|
| -
|
| -VirtualState::VirtualState(NodeId owner, Zone* zone, size_t size)
|
| - : info_(size, nullptr, zone), owner_(owner) {}
|
| -
|
| -
|
| -VirtualState::VirtualState(NodeId owner, const VirtualState& state)
|
| - : info_(state.info_.size(), nullptr, state.info_.get_allocator().zone()),
|
| - owner_(owner) {
|
| - for (size_t i = 0; i < info_.size(); ++i) {
|
| - if (state.info_[i]) {
|
| - info_[i] = state.info_[i];
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| VirtualObject* VirtualState::Copy(VirtualObject* obj, Alias alias) {
|
| if (obj->owner() == this) return obj;
|
| VirtualObject* new_obj =
|
| @@ -298,12 +284,10 @@ VirtualObject* VirtualState::Copy(VirtualObject* obj, Alias alias) {
|
| return new_obj;
|
| }
|
|
|
| -
|
| VirtualObject* VirtualState::VirtualObjectFromAlias(size_t alias) {
|
| return info_[alias];
|
| }
|
|
|
| -
|
| VirtualObject* VirtualState::GetOrCreateTrackedVirtualObject(
|
| Alias alias, NodeId id, size_t field_number, bool initialized, Zone* zone,
|
| bool force_copy) {
|
| @@ -317,12 +301,10 @@ VirtualObject* VirtualState::GetOrCreateTrackedVirtualObject(
|
| return obj;
|
| }
|
|
|
| -
|
| void VirtualState::SetVirtualObject(Alias alias, VirtualObject* obj) {
|
| info_[alias] = obj;
|
| }
|
|
|
| -
|
| bool VirtualState::UpdateFrom(VirtualState* from, Zone* zone) {
|
| if (from == this) return false;
|
| bool changed = false;
|
| @@ -346,7 +328,6 @@ bool VirtualState::UpdateFrom(VirtualState* from, Zone* zone) {
|
| return false;
|
| }
|
|
|
| -
|
| namespace {
|
|
|
| bool IsEquivalentPhi(Node* node1, Node* node2) {
|
| @@ -365,7 +346,6 @@ bool IsEquivalentPhi(Node* node1, Node* node2) {
|
| return true;
|
| }
|
|
|
| -
|
| bool IsEquivalentPhi(Node* phi, ZoneVector<Node*>& inputs) {
|
| if (phi->opcode() != IrOpcode::kPhi) return false;
|
| if (phi->op()->ValueInputCount() != inputs.size()) {
|
| @@ -382,7 +362,6 @@ bool IsEquivalentPhi(Node* phi, ZoneVector<Node*>& inputs) {
|
|
|
| } // namespace
|
|
|
| -
|
| Node* EscapeAnalysis::GetReplacementIfSame(ZoneVector<VirtualObject*>& objs) {
|
| Node* rep = GetReplacement(objs.front()->id());
|
| for (VirtualObject* obj : objs) {
|
| @@ -393,7 +372,6 @@ Node* EscapeAnalysis::GetReplacementIfSame(ZoneVector<VirtualObject*>& objs) {
|
| return rep;
|
| }
|
|
|
| -
|
| bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
|
| CommonOperatorBuilder* common, Node* control,
|
| int arity) {
|
| @@ -487,7 +465,6 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
|
| return changed;
|
| }
|
|
|
| -
|
| EscapeStatusAnalysis::EscapeStatusAnalysis(EscapeAnalysis* object_analysis,
|
| Graph* graph, Zone* zone)
|
| : stack_(zone),
|
| @@ -499,42 +476,46 @@ EscapeStatusAnalysis::EscapeStatusAnalysis(EscapeAnalysis* object_analysis,
|
| status_stack_(zone),
|
| aliases_(zone) {}
|
|
|
| -
|
| EscapeStatusAnalysis::~EscapeStatusAnalysis() {}
|
|
|
| -
|
| bool EscapeStatusAnalysis::HasEntry(Node* node) {
|
| return status_[node->id()] & (kTracked | kEscaped);
|
| }
|
|
|
| -
|
| bool EscapeStatusAnalysis::IsVirtual(Node* node) {
|
| return IsVirtual(node->id());
|
| }
|
|
|
| -
|
| bool EscapeStatusAnalysis::IsVirtual(NodeId id) {
|
| return (status_[id] & kTracked) && !(status_[id] & kEscaped);
|
| }
|
|
|
| -
|
| bool EscapeStatusAnalysis::IsEscaped(Node* node) {
|
| return status_[node->id()] & kEscaped;
|
| }
|
|
|
| -
|
| bool EscapeStatusAnalysis::IsAllocation(Node* node) {
|
| return node->opcode() == IrOpcode::kAllocate ||
|
| node->opcode() == IrOpcode::kFinishRegion;
|
| }
|
|
|
| -
|
| bool EscapeStatusAnalysis::SetEscaped(Node* node) {
|
| bool changed = !(status_[node->id()] & kEscaped);
|
| status_[node->id()] |= kEscaped | kTracked;
|
| return changed;
|
| }
|
|
|
| +bool EscapeStatusAnalysis::IsInQueue(NodeId id) {
|
| + return status_[id] & kInQueue;
|
| +}
|
| +
|
| +void EscapeStatusAnalysis::SetInQueue(NodeId id, bool on_stack) {
|
| + if (on_stack) {
|
| + status_[id] |= kInQueue;
|
| + } else {
|
| + status_[id] &= ~kInQueue;
|
| + }
|
| +}
|
|
|
| void EscapeStatusAnalysis::ResizeStatusVector() {
|
| if (status_.size() <= graph()->NodeCount()) {
|
| @@ -542,10 +523,8 @@ void EscapeStatusAnalysis::ResizeStatusVector() {
|
| }
|
| }
|
|
|
| -
|
| size_t EscapeStatusAnalysis::GetStatusVectorSize() { return status_.size(); }
|
|
|
| -
|
| void EscapeStatusAnalysis::RunStatusAnalysis() {
|
| ResizeStatusVector();
|
| while (!status_stack_.empty()) {
|
| @@ -557,7 +536,6 @@ void EscapeStatusAnalysis::RunStatusAnalysis() {
|
| }
|
| }
|
|
|
| -
|
| void EscapeStatusAnalysis::EnqueueForStatusAnalysis(Node* node) {
|
| DCHECK_NOT_NULL(node);
|
| if (!(status_[node->id()] & kOnStack)) {
|
| @@ -566,7 +544,6 @@ void EscapeStatusAnalysis::EnqueueForStatusAnalysis(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeStatusAnalysis::RevisitInputs(Node* node) {
|
| for (Edge edge : node->input_edges()) {
|
| Node* input = edge.to();
|
| @@ -577,7 +554,6 @@ void EscapeStatusAnalysis::RevisitInputs(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeStatusAnalysis::RevisitUses(Node* node) {
|
| for (Edge edge : node->use_edges()) {
|
| Node* use = edge.from();
|
| @@ -588,7 +564,6 @@ void EscapeStatusAnalysis::RevisitUses(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeStatusAnalysis::Process(Node* node) {
|
| switch (node->opcode()) {
|
| case IrOpcode::kAllocate:
|
| @@ -629,7 +604,6 @@ void EscapeStatusAnalysis::Process(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| bool EscapeStatusAnalysis::IsAllocationPhi(Node* node) {
|
| for (Edge edge : node->input_edges()) {
|
| Node* input = edge.to();
|
| @@ -640,7 +614,6 @@ bool EscapeStatusAnalysis::IsAllocationPhi(Node* node) {
|
| return true;
|
| }
|
|
|
| -
|
| void EscapeStatusAnalysis::ProcessStoreField(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kStoreField);
|
| Node* to = NodeProperties::GetValueInput(node, 0);
|
| @@ -653,7 +626,6 @@ void EscapeStatusAnalysis::ProcessStoreField(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeStatusAnalysis::ProcessStoreElement(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kStoreElement);
|
| Node* to = NodeProperties::GetValueInput(node, 0);
|
| @@ -666,7 +638,6 @@ void EscapeStatusAnalysis::ProcessStoreElement(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeStatusAnalysis::ProcessAllocate(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kAllocate);
|
| if (!HasEntry(node)) {
|
| @@ -691,7 +662,6 @@ void EscapeStatusAnalysis::ProcessAllocate(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| bool EscapeStatusAnalysis::CheckUsesForEscape(Node* uses, Node* rep,
|
| bool phi_escaping) {
|
| for (Edge edge : uses->use_edges()) {
|
| @@ -762,7 +732,6 @@ bool EscapeStatusAnalysis::CheckUsesForEscape(Node* uses, Node* rep,
|
| return false;
|
| }
|
|
|
| -
|
| void EscapeStatusAnalysis::ProcessFinishRegion(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kFinishRegion);
|
| if (!HasEntry(node)) {
|
| @@ -774,7 +743,6 @@ void EscapeStatusAnalysis::ProcessFinishRegion(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeStatusAnalysis::DebugPrint() {
|
| for (NodeId id = 0; id < status_.size(); id++) {
|
| if (status_[id] & kTracked) {
|
| @@ -784,7 +752,6 @@ void EscapeStatusAnalysis::DebugPrint() {
|
| }
|
| }
|
|
|
| -
|
| EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common,
|
| Zone* zone)
|
| : status_analysis_(this, graph, zone),
|
| @@ -793,10 +760,8 @@ EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common,
|
| replacements_(zone),
|
| cache_(new (zone) MergeCache(zone)) {}
|
|
|
| -
|
| EscapeAnalysis::~EscapeAnalysis() {}
|
|
|
| -
|
| void EscapeAnalysis::Run() {
|
| replacements_.resize(graph()->NodeCount());
|
| status_analysis_.AssignAliases();
|
| @@ -806,7 +771,6 @@ void EscapeAnalysis::Run() {
|
| status_analysis_.RunStatusAnalysis();
|
| }
|
|
|
| -
|
| void EscapeStatusAnalysis::AssignAliases() {
|
| stack_.reserve(graph()->NodeCount() * 0.2);
|
| ResizeStatusVector();
|
| @@ -867,7 +831,6 @@ void EscapeStatusAnalysis::AssignAliases() {
|
| TRACE("\n");
|
| }
|
|
|
| -
|
| bool EscapeStatusAnalysis::IsNotReachable(Node* node) {
|
| if (node->id() >= aliases_.size()) {
|
| return false;
|
| @@ -875,14 +838,15 @@ bool EscapeStatusAnalysis::IsNotReachable(Node* node) {
|
| return aliases_[node->id()] == kNotReachable;
|
| }
|
|
|
| -
|
| void EscapeAnalysis::RunObjectAnalysis() {
|
| virtual_states_.resize(graph()->NodeCount());
|
| - stack().push_back(graph()->start());
|
| + ZoneDeque<Node*> queue(zone());
|
| + queue.push_back(graph()->start());
|
| ZoneVector<Node*> danglers(zone());
|
| - while (!stack().empty()) {
|
| - Node* node = stack().back();
|
| - stack().pop_back();
|
| + while (!queue.empty()) {
|
| + Node* node = queue.back();
|
| + queue.pop_back();
|
| + status_analysis_.SetInQueue(node->id(), false);
|
| if (Process(node)) {
|
| for (Edge edge : node->use_edges()) {
|
| Node* use = edge.from();
|
| @@ -890,16 +854,29 @@ void EscapeAnalysis::RunObjectAnalysis() {
|
| continue;
|
| }
|
| if (NodeProperties::IsEffectEdge(edge)) {
|
| - if ((use->opcode() != IrOpcode::kLoadField &&
|
| - use->opcode() != IrOpcode::kLoadElement) ||
|
| - !IsDanglingEffectNode(use)) {
|
| - stack().push_back(use);
|
| + // Iteration order: depth first, but delay phis.
|
| + // We need DFS do avoid some duplication of VirtualStates and
|
| + // VirtualObjects, and we want to delay phis to improve performance.
|
| + if (use->opcode() == IrOpcode::kEffectPhi) {
|
| + if (!status_analysis_.IsInQueue(use->id())) {
|
| + queue.push_front(use);
|
| + }
|
| + } else if ((use->opcode() != IrOpcode::kLoadField &&
|
| + use->opcode() != IrOpcode::kLoadElement) ||
|
| + !IsDanglingEffectNode(use)) {
|
| + if (!status_analysis_.IsInQueue(use->id())) {
|
| + status_analysis_.SetInQueue(use->id(), true);
|
| + queue.push_back(use);
|
| + }
|
| } else {
|
| danglers.push_back(use);
|
| }
|
| }
|
| }
|
| - stack().insert(stack().end(), danglers.begin(), danglers.end());
|
| + // Danglers need to be processed immediately, even if they are
|
| + // on the stack. Since they do not have effect outputs,
|
| + // we don't have to track whether they are on the stack.
|
| + queue.insert(queue.end(), danglers.begin(), danglers.end());
|
| danglers.clear();
|
| }
|
| }
|
| @@ -910,7 +887,6 @@ void EscapeAnalysis::RunObjectAnalysis() {
|
| #endif
|
| }
|
|
|
| -
|
| bool EscapeStatusAnalysis::IsDanglingEffectNode(Node* node) {
|
| if (status_[node->id()] & kDanglingComputed) {
|
| return status_[node->id()] & kDangling;
|
| @@ -937,7 +913,6 @@ bool EscapeStatusAnalysis::IsDanglingEffectNode(Node* node) {
|
| return true;
|
| }
|
|
|
| -
|
| bool EscapeStatusAnalysis::IsEffectBranchPoint(Node* node) {
|
| if (status_[node->id()] & kBranchPointComputed) {
|
| return status_[node->id()] & kBranchPoint;
|
| @@ -962,7 +937,6 @@ bool EscapeStatusAnalysis::IsEffectBranchPoint(Node* node) {
|
| return false;
|
| }
|
|
|
| -
|
| bool EscapeAnalysis::Process(Node* node) {
|
| switch (node->opcode()) {
|
| case IrOpcode::kAllocate:
|
| @@ -1002,7 +976,6 @@ bool EscapeAnalysis::Process(Node* node) {
|
| return true;
|
| }
|
|
|
| -
|
| void EscapeAnalysis::ProcessAllocationUsers(Node* node) {
|
| for (Edge edge : node->input_edges()) {
|
| Node* input = edge.to();
|
| @@ -1036,11 +1009,10 @@ void EscapeAnalysis::ProcessAllocationUsers(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| VirtualState* EscapeAnalysis::CopyForModificationAt(VirtualState* state,
|
| Node* node) {
|
| - if (state->owner() != node->id()) {
|
| - VirtualState* new_state = new (zone()) VirtualState(node->id(), *state);
|
| + if (state->owner() != node) {
|
| + VirtualState* new_state = new (zone()) VirtualState(node, *state);
|
| virtual_states_[node->id()] = new_state;
|
| TRACE("Copying virtual state %p to new state %p at node %s#%d\n",
|
| static_cast<void*>(state), static_cast<void*>(new_state),
|
| @@ -1050,7 +1022,6 @@ VirtualState* EscapeAnalysis::CopyForModificationAt(VirtualState* state,
|
| return state;
|
| }
|
|
|
| -
|
| VirtualObject* EscapeAnalysis::CopyForModificationAt(VirtualObject* obj,
|
| VirtualState* state,
|
| Node* node) {
|
| @@ -1061,7 +1032,6 @@ VirtualObject* EscapeAnalysis::CopyForModificationAt(VirtualObject* obj,
|
| return obj;
|
| }
|
|
|
| -
|
| void EscapeAnalysis::ForwardVirtualState(Node* node) {
|
| DCHECK_EQ(node->op()->EffectInputCount(), 1);
|
| #ifdef DEBUG
|
| @@ -1078,7 +1048,7 @@ void EscapeAnalysis::ForwardVirtualState(Node* node) {
|
| if (effect->opcode() == IrOpcode::kEffectPhi &&
|
| virtual_states_[effect->id()] == nullptr) {
|
| VirtualState* state =
|
| - new (zone()) VirtualState(effect->id(), zone(), AliasCount());
|
| + new (zone()) VirtualState(effect, zone(), AliasCount());
|
| virtual_states_[effect->id()] = state;
|
| TRACE("Effect Phi #%d got new virtual state %p.\n", effect->id(),
|
| static_cast<void*>(virtual_states_[effect->id()]));
|
| @@ -1103,21 +1073,19 @@ void EscapeAnalysis::ForwardVirtualState(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeAnalysis::ProcessStart(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kStart);
|
| virtual_states_[node->id()] =
|
| - new (zone()) VirtualState(node->id(), zone(), AliasCount());
|
| + new (zone()) VirtualState(node, zone(), AliasCount());
|
| }
|
|
|
| -
|
| bool EscapeAnalysis::ProcessEffectPhi(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kEffectPhi);
|
| bool changed = false;
|
|
|
| VirtualState* mergeState = virtual_states_[node->id()];
|
| if (!mergeState) {
|
| - mergeState = new (zone()) VirtualState(node->id(), zone(), AliasCount());
|
| + mergeState = new (zone()) VirtualState(node, zone(), AliasCount());
|
| virtual_states_[node->id()] = mergeState;
|
| changed = true;
|
| TRACE("Effect Phi #%d got new virtual state %p.\n", node->id(),
|
| @@ -1135,8 +1103,7 @@ bool EscapeAnalysis::ProcessEffectPhi(Node* node) {
|
| if (state) {
|
| cache_->states().push_back(state);
|
| if (state == mergeState) {
|
| - mergeState =
|
| - new (zone()) VirtualState(node->id(), zone(), AliasCount());
|
| + mergeState = new (zone()) VirtualState(node, zone(), AliasCount());
|
| virtual_states_[node->id()] = mergeState;
|
| changed = true;
|
| }
|
| @@ -1163,7 +1130,6 @@ bool EscapeAnalysis::ProcessEffectPhi(Node* node) {
|
| return changed;
|
| }
|
|
|
| -
|
| void EscapeAnalysis::ProcessAllocation(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kAllocate);
|
| ForwardVirtualState(node);
|
| @@ -1175,7 +1141,9 @@ void EscapeAnalysis::ProcessAllocation(Node* node) {
|
| return;
|
| }
|
|
|
| - state = CopyForModificationAt(state, node);
|
| + if (state->owner()->opcode() == IrOpcode::kEffectPhi) {
|
| + state = CopyForModificationAt(state, node);
|
| + }
|
|
|
| NumberMatcher size(node->InputAt(0));
|
| DCHECK(node->InputAt(0)->opcode() != IrOpcode::kInt32Constant &&
|
| @@ -1183,16 +1151,15 @@ void EscapeAnalysis::ProcessAllocation(Node* node) {
|
| node->InputAt(0)->opcode() != IrOpcode::kFloat32Constant &&
|
| node->InputAt(0)->opcode() != IrOpcode::kFloat64Constant);
|
| if (size.HasValue()) {
|
| - state->SetVirtualObject(
|
| - alias, new (zone()) VirtualObject(node->id(), state, zone(),
|
| - size.Value() / kPointerSize, false));
|
| + VirtualObject* obj = new (zone()) VirtualObject(
|
| + node->id(), state, zone(), size.Value() / kPointerSize, false);
|
| + state->SetVirtualObject(alias, obj);
|
| } else {
|
| state->SetVirtualObject(
|
| alias, new (zone()) VirtualObject(node->id(), state, zone()));
|
| }
|
| }
|
|
|
| -
|
| void EscapeAnalysis::ProcessFinishRegion(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kFinishRegion);
|
| ForwardVirtualState(node);
|
| @@ -1205,25 +1172,21 @@ void EscapeAnalysis::ProcessFinishRegion(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| Node* EscapeAnalysis::replacement(NodeId id) {
|
| if (id >= replacements_.size()) return nullptr;
|
| return replacements_[id];
|
| }
|
|
|
| -
|
| Node* EscapeAnalysis::replacement(Node* node) {
|
| return replacement(node->id());
|
| }
|
|
|
| -
|
| bool EscapeAnalysis::SetReplacement(Node* node, Node* rep) {
|
| bool changed = replacements_[node->id()] != rep;
|
| replacements_[node->id()] = rep;
|
| return changed;
|
| }
|
|
|
| -
|
| bool EscapeAnalysis::UpdateReplacement(VirtualState* state, Node* node,
|
| Node* rep) {
|
| if (SetReplacement(node, rep)) {
|
| @@ -1238,7 +1201,6 @@ bool EscapeAnalysis::UpdateReplacement(VirtualState* state, Node* node,
|
| return false;
|
| }
|
|
|
| -
|
| Node* EscapeAnalysis::ResolveReplacement(Node* node) {
|
| while (replacement(node)) {
|
| node = replacement(node);
|
| @@ -1246,12 +1208,10 @@ Node* EscapeAnalysis::ResolveReplacement(Node* node) {
|
| return node;
|
| }
|
|
|
| -
|
| Node* EscapeAnalysis::GetReplacement(Node* node) {
|
| return GetReplacement(node->id());
|
| }
|
|
|
| -
|
| Node* EscapeAnalysis::GetReplacement(NodeId id) {
|
| Node* node = nullptr;
|
| while (replacement(id)) {
|
| @@ -1261,7 +1221,6 @@ Node* EscapeAnalysis::GetReplacement(NodeId id) {
|
| return node;
|
| }
|
|
|
| -
|
| bool EscapeAnalysis::IsVirtual(Node* node) {
|
| if (node->id() >= status_analysis_.GetStatusVectorSize()) {
|
| return false;
|
| @@ -1269,7 +1228,6 @@ bool EscapeAnalysis::IsVirtual(Node* node) {
|
| return status_analysis_.IsVirtual(node);
|
| }
|
|
|
| -
|
| bool EscapeAnalysis::IsEscaped(Node* node) {
|
| if (node->id() >= status_analysis_.GetStatusVectorSize()) {
|
| return false;
|
| @@ -1277,12 +1235,10 @@ bool EscapeAnalysis::IsEscaped(Node* node) {
|
| return status_analysis_.IsEscaped(node);
|
| }
|
|
|
| -
|
| bool EscapeAnalysis::SetEscaped(Node* node) {
|
| return status_analysis_.SetEscaped(node);
|
| }
|
|
|
| -
|
| VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) {
|
| if (VirtualState* states = virtual_states_[at->id()]) {
|
| return states->VirtualObjectFromAlias(GetAlias(id));
|
| @@ -1290,13 +1246,11 @@ VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) {
|
| return nullptr;
|
| }
|
|
|
| -
|
| VirtualObject* EscapeAnalysis::ResolveVirtualObject(VirtualState* state,
|
| Node* node) {
|
| return GetVirtualObject(state, ResolveReplacement(node));
|
| }
|
|
|
| -
|
| bool EscapeAnalysis::CompareVirtualObjects(Node* left, Node* right) {
|
| DCHECK(IsVirtual(left) && IsVirtual(right));
|
| left = ResolveReplacement(left);
|
| @@ -1307,13 +1261,11 @@ bool EscapeAnalysis::CompareVirtualObjects(Node* left, Node* right) {
|
| return false;
|
| }
|
|
|
| -
|
| int EscapeAnalysis::OffsetFromAccess(Node* node) {
|
| DCHECK(OpParameter<FieldAccess>(node).offset % kPointerSize == 0);
|
| return OpParameter<FieldAccess>(node).offset / kPointerSize;
|
| }
|
|
|
| -
|
| void EscapeAnalysis::ProcessLoadFromPhi(int offset, Node* from, Node* node,
|
| VirtualState* state) {
|
| TRACE("Load #%d from phi #%d", node->id(), from->id());
|
| @@ -1350,7 +1302,6 @@ void EscapeAnalysis::ProcessLoadFromPhi(int offset, Node* from, Node* node,
|
| }
|
| }
|
|
|
| -
|
| void EscapeAnalysis::ProcessLoadField(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kLoadField);
|
| ForwardVirtualState(node);
|
| @@ -1378,7 +1329,6 @@ void EscapeAnalysis::ProcessLoadField(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeAnalysis::ProcessLoadElement(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kLoadElement);
|
| ForwardVirtualState(node);
|
| @@ -1428,7 +1378,6 @@ void EscapeAnalysis::ProcessLoadElement(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeAnalysis::ProcessStoreField(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kStoreField);
|
| ForwardVirtualState(node);
|
| @@ -1446,7 +1395,6 @@ void EscapeAnalysis::ProcessStoreField(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeAnalysis::ProcessStoreElement(Node* node) {
|
| DCHECK_EQ(node->opcode(), IrOpcode::kStoreElement);
|
| ForwardVirtualState(node);
|
| @@ -1493,7 +1441,6 @@ void EscapeAnalysis::ProcessStoreElement(Node* node) {
|
| }
|
| }
|
|
|
| -
|
| Node* EscapeAnalysis::GetOrCreateObjectState(Node* effect, Node* node) {
|
| if ((node->opcode() == IrOpcode::kFinishRegion ||
|
| node->opcode() == IrOpcode::kAllocate) &&
|
| @@ -1536,7 +1483,6 @@ Node* EscapeAnalysis::GetOrCreateObjectState(Node* effect, Node* node) {
|
| return nullptr;
|
| }
|
|
|
| -
|
| void EscapeAnalysis::DebugPrintObject(VirtualObject* object, Alias alias) {
|
| PrintF(" Alias @%d: Object #%d with %zu fields\n", alias, object->id(),
|
| object->field_count());
|
| @@ -1547,7 +1493,6 @@ void EscapeAnalysis::DebugPrintObject(VirtualObject* object, Alias alias) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeAnalysis::DebugPrintState(VirtualState* state) {
|
| PrintF("Dumping virtual state %p\n", static_cast<void*>(state));
|
| for (Alias alias = 0; alias < AliasCount(); ++alias) {
|
| @@ -1557,7 +1502,6 @@ void EscapeAnalysis::DebugPrintState(VirtualState* state) {
|
| }
|
| }
|
|
|
| -
|
| void EscapeAnalysis::DebugPrint() {
|
| ZoneVector<VirtualState*> object_states(zone());
|
| for (NodeId id = 0; id < virtual_states_.size(); id++) {
|
| @@ -1573,7 +1517,6 @@ void EscapeAnalysis::DebugPrint() {
|
| }
|
| }
|
|
|
| -
|
| VirtualObject* EscapeAnalysis::GetVirtualObject(VirtualState* state,
|
| Node* node) {
|
| if (node->id() >= status_analysis_.GetAliasMap().size()) return nullptr;
|
| @@ -1582,7 +1525,6 @@ VirtualObject* EscapeAnalysis::GetVirtualObject(VirtualState* state,
|
| return state->VirtualObjectFromAlias(alias);
|
| }
|
|
|
| -
|
| bool EscapeAnalysis::ExistsVirtualAllocate() {
|
| for (size_t id = 0; id < status_analysis_.GetAliasMap().size(); ++id) {
|
| Alias alias = GetAlias(static_cast<NodeId>(id));
|
|
|