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/escape-analysis.h" | 5 #include "src/compiler/escape-analysis.h" |
6 | 6 |
7 #include "src/base/flags.h" | 7 #include "src/base/flags.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/common-operator.h" | 10 #include "src/compiler/common-operator.h" |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 } else { | 383 } else { |
384 GetFields(cache->objects(), cache->fields(), i); | 384 GetFields(cache->objects(), cache->fields(), i); |
385 if (cache->fields().size() == cache->objects().size()) { | 385 if (cache->fields().size() == cache->objects().size()) { |
386 Node* rep = mergeObject->GetField(i); | 386 Node* rep = mergeObject->GetField(i); |
387 if (!rep || !mergeObject->IsCreatedPhi(i)) { | 387 if (!rep || !mergeObject->IsCreatedPhi(i)) { |
388 cache->fields().push_back(control); | 388 cache->fields().push_back(control); |
389 Node* phi = | 389 Node* phi = |
390 graph->NewNode(common->Phi(MachineRepresentation::kTagged, 2), | 390 graph->NewNode(common->Phi(MachineRepresentation::kTagged, 2), |
391 static_cast<int>(cache->fields().size()), | 391 static_cast<int>(cache->fields().size()), |
392 &cache->fields().front()); | 392 &cache->fields().front()); |
393 if (mergeObject->SetField(i, phi, true)) { | 393 mergeObject->SetField(i, phi, true); |
394 if (FLAG_trace_turbo_escape) { | 394 if (FLAG_trace_turbo_escape) { |
395 PrintF(" Creating Phi #%d as merge of", phi->id()); | 395 PrintF(" Creating Phi #%d as merge of", phi->id()); |
396 for (size_t i = 0; i + 1 < cache->fields().size(); i++) { | 396 for (size_t i = 0; i + 1 < cache->fields().size(); i++) { |
397 PrintF(" #%d (%s)", cache->fields()[i]->id(), | 397 PrintF(" #%d (%s)", cache->fields()[i]->id(), |
398 cache->fields()[i]->op()->mnemonic()); | 398 cache->fields()[i]->op()->mnemonic()); |
399 } | |
400 PrintF("\n"); | |
401 } | 399 } |
402 changed = true; | 400 PrintF("\n"); |
403 } | 401 } |
| 402 changed = true; |
404 } else { | 403 } else { |
405 DCHECK(rep->opcode() == IrOpcode::kPhi); | 404 DCHECK(rep->opcode() == IrOpcode::kPhi); |
406 for (size_t n = 0; n < cache->fields().size(); ++n) { | 405 for (size_t n = 0; n < cache->fields().size(); ++n) { |
407 Node* old = | 406 Node* old = |
408 NodeProperties::GetValueInput(rep, static_cast<int>(n)); | 407 NodeProperties::GetValueInput(rep, static_cast<int>(n)); |
409 if (old != cache->fields()[n]) { | 408 if (old != cache->fields()[n]) { |
410 changed = true; | 409 changed = true; |
411 NodeProperties::ReplaceValueInput(rep, cache->fields()[n], | 410 NodeProperties::ReplaceValueInput(rep, cache->fields()[n], |
412 static_cast<int>(n)); | 411 static_cast<int>(n)); |
413 } | 412 } |
(...skipping 23 matching lines...) Expand all Loading... |
437 | 436 |
438 | 437 |
439 // ------------------------------EscapeStatusAnalysis--------------------------- | 438 // ------------------------------EscapeStatusAnalysis--------------------------- |
440 | 439 |
441 | 440 |
442 EscapeStatusAnalysis::EscapeStatusAnalysis(EscapeAnalysis* object_analysis, | 441 EscapeStatusAnalysis::EscapeStatusAnalysis(EscapeAnalysis* object_analysis, |
443 Graph* graph, Zone* zone) | 442 Graph* graph, Zone* zone) |
444 : object_analysis_(object_analysis), | 443 : object_analysis_(object_analysis), |
445 graph_(graph), | 444 graph_(graph), |
446 zone_(zone), | 445 zone_(zone), |
447 info_(zone), | 446 info_(graph->NodeCount(), kUnknown, zone), |
448 queue_(zone) { | 447 queue_(zone) {} |
449 info_.resize(graph->NodeCount()); | |
450 } | |
451 | 448 |
452 | 449 |
453 EscapeStatusAnalysis::~EscapeStatusAnalysis() {} | 450 EscapeStatusAnalysis::~EscapeStatusAnalysis() {} |
454 | 451 |
455 | 452 |
456 bool EscapeStatusAnalysis::HasEntry(Node* node) { | 453 bool EscapeStatusAnalysis::HasEntry(Node* node) { |
457 return info_[node->id()] != kUnknown; | 454 return info_[node->id()] != kUnknown; |
458 } | 455 } |
459 | 456 |
460 | 457 |
461 bool EscapeStatusAnalysis::IsVirtual(Node* node) { | 458 bool EscapeStatusAnalysis::IsVirtual(Node* node) { |
462 if (node->id() >= info_.size()) { | |
463 return false; | |
464 } | |
465 return info_[node->id()] == kVirtual; | 459 return info_[node->id()] == kVirtual; |
466 } | 460 } |
467 | 461 |
468 | 462 |
469 bool EscapeStatusAnalysis::IsEscaped(Node* node) { | 463 bool EscapeStatusAnalysis::IsEscaped(Node* node) { |
470 return info_[node->id()] == kEscaped; | 464 return info_[node->id()] == kEscaped; |
471 } | 465 } |
472 | 466 |
473 | 467 |
474 bool EscapeStatusAnalysis::IsAllocation(Node* node) { | 468 bool EscapeStatusAnalysis::IsAllocation(Node* node) { |
475 return node->opcode() == IrOpcode::kAllocate || | 469 return node->opcode() == IrOpcode::kAllocate || |
476 node->opcode() == IrOpcode::kFinishRegion; | 470 node->opcode() == IrOpcode::kFinishRegion; |
477 } | 471 } |
478 | 472 |
479 | 473 |
480 bool EscapeStatusAnalysis::SetEscaped(Node* node) { | 474 bool EscapeStatusAnalysis::SetEscaped(Node* node) { |
481 bool changed = info_[node->id()] != kEscaped; | 475 bool changed = info_[node->id()] != kEscaped; |
482 info_[node->id()] = kEscaped; | 476 info_[node->id()] = kEscaped; |
483 return changed; | 477 return changed; |
484 } | 478 } |
485 | 479 |
486 | 480 |
| 481 void EscapeStatusAnalysis::Resize() { |
| 482 info_.resize(graph()->NodeCount(), kUnknown); |
| 483 } |
| 484 |
| 485 |
| 486 size_t EscapeStatusAnalysis::size() { return info_.size(); } |
| 487 |
| 488 |
487 void EscapeStatusAnalysis::Run() { | 489 void EscapeStatusAnalysis::Run() { |
488 info_.resize(graph()->NodeCount()); | 490 Resize(); |
489 ZoneVector<bool> visited(zone()); | 491 ZoneVector<bool> visited(zone()); |
490 visited.resize(graph()->NodeCount()); | 492 visited.resize(graph()->NodeCount()); |
491 queue_.push_back(graph()->end()); | 493 queue_.push_back(graph()->end()); |
492 while (!queue_.empty()) { | 494 while (!queue_.empty()) { |
493 Node* node = queue_.front(); | 495 Node* node = queue_.front(); |
494 queue_.pop_front(); | 496 queue_.pop_front(); |
495 Process(node); | 497 Process(node); |
496 if (!visited[node->id()]) { | 498 if (!visited[node->id()]) { |
497 RevisitInputs(node); | 499 RevisitInputs(node); |
498 } | 500 } |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
960 changed = mergeState->MergeFrom(&cache_, zone(), graph(), common(), | 962 changed = mergeState->MergeFrom(&cache_, zone(), graph(), common(), |
961 NodeProperties::GetControlInput(node)) || | 963 NodeProperties::GetControlInput(node)) || |
962 changed; | 964 changed; |
963 | 965 |
964 if (FLAG_trace_turbo_escape) { | 966 if (FLAG_trace_turbo_escape) { |
965 PrintF("Merge %s the node.\n", changed ? "changed" : "did not change"); | 967 PrintF("Merge %s the node.\n", changed ? "changed" : "did not change"); |
966 } | 968 } |
967 | 969 |
968 if (changed) { | 970 if (changed) { |
969 mergeState->LastChangedAt(node); | 971 mergeState->LastChangedAt(node); |
| 972 escape_status_.Resize(); |
970 } | 973 } |
971 return changed; | 974 return changed; |
972 } | 975 } |
973 | 976 |
974 | 977 |
975 void EscapeAnalysis::ProcessAllocation(Node* node) { | 978 void EscapeAnalysis::ProcessAllocation(Node* node) { |
976 DCHECK_EQ(node->opcode(), IrOpcode::kAllocate); | 979 DCHECK_EQ(node->opcode(), IrOpcode::kAllocate); |
977 ForwardVirtualState(node); | 980 ForwardVirtualState(node); |
978 | 981 |
979 // Check if we have already processed this node. | 982 // Check if we have already processed this node. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 Node* node = nullptr; | 1068 Node* node = nullptr; |
1066 while (replacement(id)) { | 1069 while (replacement(id)) { |
1067 node = replacement(id); | 1070 node = replacement(id); |
1068 id = node->id(); | 1071 id = node->id(); |
1069 } | 1072 } |
1070 return node; | 1073 return node; |
1071 } | 1074 } |
1072 | 1075 |
1073 | 1076 |
1074 bool EscapeAnalysis::IsVirtual(Node* node) { | 1077 bool EscapeAnalysis::IsVirtual(Node* node) { |
| 1078 if (node->id() >= escape_status_.size()) { |
| 1079 return false; |
| 1080 } |
1075 return escape_status_.IsVirtual(node); | 1081 return escape_status_.IsVirtual(node); |
1076 } | 1082 } |
1077 | 1083 |
1078 | 1084 |
1079 bool EscapeAnalysis::IsEscaped(Node* node) { | 1085 bool EscapeAnalysis::IsEscaped(Node* node) { |
| 1086 if (node->id() >= escape_status_.size()) { |
| 1087 return false; |
| 1088 } |
1080 return escape_status_.IsEscaped(node); | 1089 return escape_status_.IsEscaped(node); |
1081 } | 1090 } |
1082 | 1091 |
1083 | 1092 |
1084 bool EscapeAnalysis::SetEscaped(Node* node) { | 1093 bool EscapeAnalysis::SetEscaped(Node* node) { |
1085 return escape_status_.SetEscaped(node); | 1094 return escape_status_.SetEscaped(node); |
1086 } | 1095 } |
1087 | 1096 |
1088 | 1097 |
1089 VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) { | 1098 VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 GetVirtualObjects(state, inputs, cache_.objects()); | 1135 GetVirtualObjects(state, inputs, cache_.objects()); |
1127 if (cache_.objects().size() == inputs.size()) { | 1136 if (cache_.objects().size() == inputs.size()) { |
1128 GetFields(cache_.objects(), cache_.fields(), offset); | 1137 GetFields(cache_.objects(), cache_.fields(), offset); |
1129 if (cache_.fields().size() == cache_.objects().size()) { | 1138 if (cache_.fields().size() == cache_.objects().size()) { |
1130 Node* rep = replacement(node); | 1139 Node* rep = replacement(node); |
1131 if (!rep || !IsEquivalentPhi(rep, cache_.fields())) { | 1140 if (!rep || !IsEquivalentPhi(rep, cache_.fields())) { |
1132 cache_.fields().push_back(NodeProperties::GetControlInput(from)); | 1141 cache_.fields().push_back(NodeProperties::GetControlInput(from)); |
1133 Node* phi = graph()->NewNode( | 1142 Node* phi = graph()->NewNode( |
1134 common()->Phi(MachineRepresentation::kTagged, 2), | 1143 common()->Phi(MachineRepresentation::kTagged, 2), |
1135 static_cast<int>(cache_.fields().size()), &cache_.fields().front()); | 1144 static_cast<int>(cache_.fields().size()), &cache_.fields().front()); |
| 1145 escape_status_.Resize(); |
1136 SetReplacement(node, phi); | 1146 SetReplacement(node, phi); |
1137 state->LastChangedAt(node); | 1147 state->LastChangedAt(node); |
1138 if (FLAG_trace_turbo_escape) { | 1148 if (FLAG_trace_turbo_escape) { |
1139 PrintF(" got phi created.\n"); | 1149 PrintF(" got phi created.\n"); |
1140 } | 1150 } |
1141 } else if (FLAG_trace_turbo_escape) { | 1151 } else if (FLAG_trace_turbo_escape) { |
1142 PrintF(" has already phi #%d.\n", rep->id()); | 1152 PrintF(" has already phi #%d.\n", rep->id()); |
1143 } | 1153 } |
1144 } else if (FLAG_trace_turbo_escape) { | 1154 } else if (FLAG_trace_turbo_escape) { |
1145 PrintF(" has incomplete field info.\n"); | 1155 PrintF(" has incomplete field info.\n"); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 } | 1315 } |
1306 } | 1316 } |
1307 for (size_t n = 0; n < object_states.size(); n++) { | 1317 for (size_t n = 0; n < object_states.size(); n++) { |
1308 DebugPrintState(object_states[n]); | 1318 DebugPrintState(object_states[n]); |
1309 } | 1319 } |
1310 } | 1320 } |
1311 | 1321 |
1312 } // namespace compiler | 1322 } // namespace compiler |
1313 } // namespace internal | 1323 } // namespace internal |
1314 } // namespace v8 | 1324 } // namespace v8 |
OLD | NEW |