summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/memory-optimizer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/memory-optimizer.cc')
-rw-r--r--deps/v8/src/compiler/memory-optimizer.cc185
1 files changed, 80 insertions, 105 deletions
diff --git a/deps/v8/src/compiler/memory-optimizer.cc b/deps/v8/src/compiler/memory-optimizer.cc
index 66fcbb9362..7e9a522a70 100644
--- a/deps/v8/src/compiler/memory-optimizer.cc
+++ b/deps/v8/src/compiler/memory-optimizer.cc
@@ -20,7 +20,8 @@ MemoryOptimizer::MemoryOptimizer(JSGraph* jsgraph, Zone* zone)
empty_state_(AllocationState::Empty(zone)),
pending_(zone),
tokens_(zone),
- zone_(zone) {}
+ zone_(zone),
+ graph_assembler_(jsgraph, nullptr, nullptr, zone) {}
void MemoryOptimizer::Optimize() {
EnqueueUses(graph()->start(), empty_state());
@@ -91,7 +92,9 @@ void MemoryOptimizer::VisitNode(Node* node, AllocationState const* state) {
case IrOpcode::kDeoptimizeUnless:
case IrOpcode::kIfException:
case IrOpcode::kLoad:
+ case IrOpcode::kProtectedLoad:
case IrOpcode::kStore:
+ case IrOpcode::kProtectedStore:
case IrOpcode::kRetain:
case IrOpcode::kUnsafePointerAdd:
return VisitOtherEffect(node, state);
@@ -101,12 +104,17 @@ void MemoryOptimizer::VisitNode(Node* node, AllocationState const* state) {
DCHECK_EQ(0, node->op()->EffectOutputCount());
}
+#define __ gasm()->
+
void MemoryOptimizer::VisitAllocate(Node* node, AllocationState const* state) {
DCHECK_EQ(IrOpcode::kAllocate, node->opcode());
Node* value;
Node* size = node->InputAt(0);
Node* effect = node->InputAt(1);
Node* control = node->InputAt(2);
+
+ gasm()->Reset(effect, control);
+
PretenureFlag pretenure = PretenureFlagOf(node->op());
// Propagate tenuring from outer allocations to inner allocations, i.e.
@@ -141,11 +149,11 @@ void MemoryOptimizer::VisitAllocate(Node* node, AllocationState const* state) {
}
// Determine the top/limit addresses.
- Node* top_address = jsgraph()->ExternalConstant(
+ Node* top_address = __ ExternalConstant(
pretenure == NOT_TENURED
? ExternalReference::new_space_allocation_top_address(isolate())
: ExternalReference::old_space_allocation_top_address(isolate()));
- Node* limit_address = jsgraph()->ExternalConstant(
+ Node* limit_address = __ ExternalConstant(
pretenure == NOT_TENURED
? ExternalReference::new_space_allocation_limit_address(isolate())
: ExternalReference::old_space_allocation_limit_address(isolate()));
@@ -171,89 +179,69 @@ void MemoryOptimizer::VisitAllocate(Node* node, AllocationState const* state) {
// Update the allocation top with the new object allocation.
// TODO(bmeurer): Defer writing back top as much as possible.
- Node* top = graph()->NewNode(machine()->IntAdd(), state->top(),
- jsgraph()->IntPtrConstant(object_size));
- effect = graph()->NewNode(
- machine()->Store(StoreRepresentation(
- MachineType::PointerRepresentation(), kNoWriteBarrier)),
- top_address, jsgraph()->IntPtrConstant(0), top, effect, control);
+ Node* top = __ IntAdd(state->top(), __ IntPtrConstant(object_size));
+ __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
+ kNoWriteBarrier),
+ top_address, __ IntPtrConstant(0), top);
// Compute the effective inner allocated address.
- value = graph()->NewNode(
- machine()->BitcastWordToTagged(),
- graph()->NewNode(machine()->IntAdd(), state->top(),
- jsgraph()->IntPtrConstant(kHeapObjectTag)));
+ value = __ BitcastWordToTagged(
+ __ IntAdd(state->top(), __ IntPtrConstant(kHeapObjectTag)));
// Extend the allocation {group}.
group->Add(value);
state = AllocationState::Open(group, state_size, top, zone());
} else {
+ auto call_runtime = __ MakeDeferredLabel<1>();
+ auto done = __ MakeLabel<2>(MachineType::PointerRepresentation());
+
// Setup a mutable reservation size node; will be patched as we fold
// additional allocations into this new group.
- Node* size = graph()->NewNode(common()->Int32Constant(object_size));
+ Node* size = __ UniqueInt32Constant(object_size);
// Load allocation top and limit.
- Node* top = effect =
- graph()->NewNode(machine()->Load(MachineType::Pointer()), top_address,
- jsgraph()->IntPtrConstant(0), effect, control);
- Node* limit = effect = graph()->NewNode(
- machine()->Load(MachineType::Pointer()), limit_address,
- jsgraph()->IntPtrConstant(0), effect, control);
+ Node* top =
+ __ Load(MachineType::Pointer(), top_address, __ IntPtrConstant(0));
+ Node* limit =
+ __ Load(MachineType::Pointer(), limit_address, __ IntPtrConstant(0));
// Check if we need to collect garbage before we can start bump pointer
// allocation (always done for folded allocations).
- Node* check = graph()->NewNode(
- machine()->UintLessThan(),
- graph()->NewNode(
- machine()->IntAdd(), top,
- machine()->Is64()
- ? graph()->NewNode(machine()->ChangeInt32ToInt64(), size)
- : size),
+ Node* check = __ UintLessThan(
+ __ IntAdd(top,
+ machine()->Is64() ? __ ChangeInt32ToInt64(size) : size),
limit);
- Node* branch =
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
- Node* etrue = effect;
- Node* vtrue = top;
+ __ GotoUnless(check, &call_runtime);
+ __ Goto(&done, top);
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
- Node* efalse = effect;
- Node* vfalse;
+ __ Bind(&call_runtime);
{
- Node* target = pretenure == NOT_TENURED
- ? jsgraph()->AllocateInNewSpaceStubConstant()
- : jsgraph()->AllocateInOldSpaceStubConstant();
+ Node* target =
+ pretenure == NOT_TENURED ? __ AllocateInNewSpaceStubConstant()
+ : __
+ AllocateInOldSpaceStubConstant();
if (!allocate_operator_.is_set()) {
CallDescriptor* descriptor =
Linkage::GetAllocateCallDescriptor(graph()->zone());
allocate_operator_.set(common()->Call(descriptor));
}
- vfalse = efalse = graph()->NewNode(allocate_operator_.get(), target,
- size, efalse, if_false);
- vfalse = graph()->NewNode(machine()->IntSub(), vfalse,
- jsgraph()->IntPtrConstant(kHeapObjectTag));
+ Node* vfalse = __ Call(allocate_operator_.get(), target, size);
+ vfalse = __ IntSub(vfalse, __ IntPtrConstant(kHeapObjectTag));
+ __ Goto(&done, vfalse);
}
- control = graph()->NewNode(common()->Merge(2), if_true, if_false);
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
- value = graph()->NewNode(
- common()->Phi(MachineType::PointerRepresentation(), 2), vtrue, vfalse,
- control);
+ __ Bind(&done);
// Compute the new top and write it back.
- top = graph()->NewNode(machine()->IntAdd(), value,
- jsgraph()->IntPtrConstant(object_size));
- effect = graph()->NewNode(
- machine()->Store(StoreRepresentation(
- MachineType::PointerRepresentation(), kNoWriteBarrier)),
- top_address, jsgraph()->IntPtrConstant(0), top, effect, control);
+ top = __ IntAdd(done.PhiAt(0), __ IntPtrConstant(object_size));
+ __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
+ kNoWriteBarrier),
+ top_address, __ IntPtrConstant(0), top);
// Compute the initial object address.
- value = graph()->NewNode(
- machine()->BitcastWordToTagged(),
- graph()->NewNode(machine()->IntAdd(), value,
- jsgraph()->IntPtrConstant(kHeapObjectTag)));
+ value = __ BitcastWordToTagged(
+ __ IntAdd(done.PhiAt(0), __ IntPtrConstant(kHeapObjectTag)));
// Start a new allocation group.
AllocationGroup* group =
@@ -261,61 +249,42 @@ void MemoryOptimizer::VisitAllocate(Node* node, AllocationState const* state) {
state = AllocationState::Open(group, object_size, top, zone());
}
} else {
+ auto call_runtime = __ MakeDeferredLabel<1>();
+ auto done = __ MakeLabel<2>(MachineRepresentation::kTaggedPointer);
+
// Load allocation top and limit.
- Node* top = effect =
- graph()->NewNode(machine()->Load(MachineType::Pointer()), top_address,
- jsgraph()->IntPtrConstant(0), effect, control);
- Node* limit = effect =
- graph()->NewNode(machine()->Load(MachineType::Pointer()), limit_address,
- jsgraph()->IntPtrConstant(0), effect, control);
+ Node* top =
+ __ Load(MachineType::Pointer(), top_address, __ IntPtrConstant(0));
+ Node* limit =
+ __ Load(MachineType::Pointer(), limit_address, __ IntPtrConstant(0));
// Compute the new top.
- Node* new_top = graph()->NewNode(
- machine()->IntAdd(), top,
- machine()->Is64()
- ? graph()->NewNode(machine()->ChangeInt32ToInt64(), size)
- : size);
+ Node* new_top =
+ __ IntAdd(top, machine()->Is64() ? __ ChangeInt32ToInt64(size) : size);
// Check if we can do bump pointer allocation here.
- Node* check = graph()->NewNode(machine()->UintLessThan(), new_top, limit);
- Node* branch =
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
-
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
- Node* etrue = effect;
- Node* vtrue;
- {
- etrue = graph()->NewNode(
- machine()->Store(StoreRepresentation(
- MachineType::PointerRepresentation(), kNoWriteBarrier)),
- top_address, jsgraph()->IntPtrConstant(0), new_top, etrue, if_true);
- vtrue = graph()->NewNode(
- machine()->BitcastWordToTagged(),
- graph()->NewNode(machine()->IntAdd(), top,
- jsgraph()->IntPtrConstant(kHeapObjectTag)));
+ Node* check = __ UintLessThan(new_top, limit);
+ __ GotoUnless(check, &call_runtime);
+ __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
+ kNoWriteBarrier),
+ top_address, __ IntPtrConstant(0), new_top);
+ __ Goto(&done, __ BitcastWordToTagged(
+ __ IntAdd(top, __ IntPtrConstant(kHeapObjectTag))));
+
+ __ Bind(&call_runtime);
+ Node* target =
+ pretenure == NOT_TENURED ? __ AllocateInNewSpaceStubConstant()
+ : __
+ AllocateInOldSpaceStubConstant();
+ if (!allocate_operator_.is_set()) {
+ CallDescriptor* descriptor =
+ Linkage::GetAllocateCallDescriptor(graph()->zone());
+ allocate_operator_.set(common()->Call(descriptor));
}
+ __ Goto(&done, __ Call(allocate_operator_.get(), target, size));
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
- Node* efalse = effect;
- Node* vfalse;
- {
- Node* target = pretenure == NOT_TENURED
- ? jsgraph()->AllocateInNewSpaceStubConstant()
- : jsgraph()->AllocateInOldSpaceStubConstant();
- if (!allocate_operator_.is_set()) {
- CallDescriptor* descriptor =
- Linkage::GetAllocateCallDescriptor(graph()->zone());
- allocate_operator_.set(common()->Call(descriptor));
- }
- vfalse = efalse = graph()->NewNode(allocate_operator_.get(), target, size,
- efalse, if_false);
- }
-
- control = graph()->NewNode(common()->Merge(2), if_true, if_false);
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
- value = graph()->NewNode(
- common()->Phi(MachineRepresentation::kTaggedPointer, 2), vtrue, vfalse,
- control);
+ __ Bind(&done);
+ value = done.PhiAt(0);
// Create an unfoldable allocation group.
AllocationGroup* group =
@@ -323,6 +292,10 @@ void MemoryOptimizer::VisitAllocate(Node* node, AllocationState const* state) {
state = AllocationState::Closed(group, zone());
}
+ effect = __ ExtractCurrentEffect();
+ control = __ ExtractCurrentControl();
+ USE(control); // Floating control, dropped on the floor.
+
// Replace all effect uses of {node} with the {effect}, enqueue the
// effect uses for further processing, and replace all value uses of
// {node} with the {value}.
@@ -340,6 +313,8 @@ void MemoryOptimizer::VisitAllocate(Node* node, AllocationState const* state) {
node->Kill();
}
+#undef __
+
void MemoryOptimizer::VisitCall(Node* node, AllocationState const* state) {
DCHECK_EQ(IrOpcode::kCall, node->opcode());
// If the call can allocate, we start with a fresh state.