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

Unified Diff: src/compiler/escape-analysis-reducer.cc

Issue 2692753004: [turbofan] escape analysis supports arguments object and rest elements (Closed)
Patch Set: handle the case where Deoptimizer::function_ is a Smi Created 3 years, 10 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/escape-analysis-reducer.h ('k') | src/compiler/graph-assembler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/escape-analysis-reducer.cc
diff --git a/src/compiler/escape-analysis-reducer.cc b/src/compiler/escape-analysis-reducer.cc
index c05092e06ea95f71ef958c121990df06254834e6..59ad39bd4218c0ac492dbc93e74da2e078a65f5a 100644
--- a/src/compiler/escape-analysis-reducer.cc
+++ b/src/compiler/escape-analysis-reducer.cc
@@ -6,6 +6,8 @@
#include "src/compiler/all-nodes.h"
#include "src/compiler/js-graph.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/compiler/type-cache.h"
#include "src/counters.h"
namespace v8 {
@@ -84,6 +86,9 @@ Reduction EscapeAnalysisReducer::ReduceNode(Node* node) {
}
return NoChange();
}
+ case IrOpcode::kNewUnmappedArgumentsElements:
+ arguments_elements_.insert(node);
+ break;
default:
// TODO(sigurds): Change this to GetFrameStateInputCount once
// it is working. For now we use EffectInputCount > 0 to determine
@@ -380,6 +385,98 @@ void EscapeAnalysisReducer::VerifyReplacement() const {
#endif // DEBUG
}
+void EscapeAnalysisReducer::Finalize() {
+ for (Node* node : arguments_elements_) {
+ DCHECK(node->opcode() == IrOpcode::kNewUnmappedArgumentsElements);
+
+ Node* arguments_frame = NodeProperties::GetValueInput(node, 0);
+ if (arguments_frame->opcode() != IrOpcode::kArgumentsFrame) continue;
+ Node* arguments_length = NodeProperties::GetValueInput(node, 1);
+ if (arguments_length->opcode() != IrOpcode::kArgumentsLength) continue;
+
+ bool escaping_use = false;
+ ZoneVector<Node*> loads(zone());
+ for (Edge edge : node->use_edges()) {
+ Node* use = edge.from();
+ if (!NodeProperties::IsValueEdge(edge)) continue;
+ if (use->use_edges().empty()) {
+ // A node without uses is dead, so we don't have to care about it.
+ continue;
+ }
+ switch (use->opcode()) {
+ case IrOpcode::kStateValues:
+ case IrOpcode::kTypedStateValues:
+ case IrOpcode::kObjectState:
+ case IrOpcode::kTypedObjectState:
+ break;
+ case IrOpcode::kLoadElement:
+ loads.push_back(use);
+ break;
+ case IrOpcode::kLoadField:
+ if (FieldAccessOf(use->op()).offset == FixedArray::kLengthOffset) {
+ loads.push_back(use);
+ } else {
+ escaping_use = true;
+ }
+ break;
+ default:
+ // If the arguments elements node node is used by an unhandled node,
+ // then we cannot remove this allocation.
+ escaping_use = true;
+ break;
+ }
+ if (escaping_use) break;
+ }
+ if (!escaping_use) {
+ Node* arguments_elements_state = jsgraph()->graph()->NewNode(
+ jsgraph()->common()->ArgumentsElementsState(
+ IsRestLengthOf(arguments_length->op())));
+ NodeProperties::SetType(arguments_elements_state, Type::OtherInternal());
+ ReplaceWithValue(node, arguments_elements_state);
+
+ ElementAccess stack_access;
+ stack_access.base_is_tagged = BaseTaggedness::kUntaggedBase;
+ // Reduce base address by {kPointerSize} such that (length - index)
+ // resolves to the right position.
+ stack_access.header_size =
+ CommonFrameConstants::kFixedFrameSizeAboveFp - kPointerSize;
+ stack_access.type = Type::NonInternal();
+ stack_access.machine_type = MachineType::AnyTagged();
+ stack_access.write_barrier_kind = WriteBarrierKind::kNoWriteBarrier;
+ const Operator* load_stack_op =
+ jsgraph()->simplified()->LoadElement(stack_access);
+
+ for (Node* load : loads) {
+ switch (load->opcode()) {
+ case IrOpcode::kLoadElement: {
+ Node* index = NodeProperties::GetValueInput(load, 1);
+ // {offset} is a reverted index starting from 1. The base address is
+ // adapted to allow offsets starting from 1.
+ Node* offset = jsgraph()->graph()->NewNode(
+ jsgraph()->simplified()->NumberSubtract(), arguments_length,
+ index);
+ NodeProperties::SetType(offset,
+ TypeCache::Get().kArgumentsLengthType);
+ NodeProperties::ReplaceValueInput(load, arguments_frame, 0);
+ NodeProperties::ReplaceValueInput(load, offset, 1);
+ NodeProperties::ChangeOp(load, load_stack_op);
+ break;
+ }
+ case IrOpcode::kLoadField: {
+ DCHECK_EQ(FieldAccessOf(load->op()).offset,
+ FixedArray::kLengthOffset);
+ Node* length = NodeProperties::GetValueInput(node, 1);
+ ReplaceWithValue(load, length);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+ }
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
« no previous file with comments | « src/compiler/escape-analysis-reducer.h ('k') | src/compiler/graph-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698