summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/effect-control-linearizer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/effect-control-linearizer.cc')
-rw-r--r--deps/v8/src/compiler/effect-control-linearizer.cc202
1 files changed, 41 insertions, 161 deletions
diff --git a/deps/v8/src/compiler/effect-control-linearizer.cc b/deps/v8/src/compiler/effect-control-linearizer.cc
index 51e23d89d3..21696969ec 100644
--- a/deps/v8/src/compiler/effect-control-linearizer.cc
+++ b/deps/v8/src/compiler/effect-control-linearizer.cc
@@ -184,8 +184,6 @@ class EffectControlLinearizer {
void LowerCheckEqualsInternalizedString(Node* node, Node* frame_state);
void LowerCheckEqualsSymbol(Node* node, Node* frame_state);
Node* LowerTypeOf(Node* node);
- void LowerTierUpCheck(Node* node);
- void LowerUpdateInterruptBudget(Node* node);
Node* LowerToBoolean(Node* node);
Node* LowerPlainPrimitiveToNumber(Node* node);
Node* LowerPlainPrimitiveToWord32(Node* node);
@@ -342,6 +340,7 @@ class EffectControlLinearizer {
Zone* temp_zone_;
MaintainSchedule maintain_schedule_;
RegionObservability region_observability_ = RegionObservability::kObservable;
+ bool inside_region_ = false;
SourcePositionTable* source_positions_;
NodeOriginTable* node_origins_;
JSHeapBroker* broker_;
@@ -625,7 +624,7 @@ void EffectControlLinearizer::Run() {
continue;
}
- gasm()->Reset(block);
+ gasm()->Reset();
BasicBlock::iterator instr = block->begin();
BasicBlock::iterator end_instr = block->end();
@@ -764,8 +763,6 @@ void EffectControlLinearizer::Run() {
ProcessNode(node, &frame_state);
}
- block = gasm()->FinalizeCurrentBlock(block);
-
switch (block->control()) {
case BasicBlock::kGoto:
case BasicBlock::kNone:
@@ -864,6 +861,7 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state) {
if (node->opcode() == IrOpcode::kFinishRegion) {
// Reset the current region observability.
region_observability_ = RegionObservability::kObservable;
+ inside_region_ = false;
// Update the value uses to the value input of the finish node and
// the effect uses to the effect input.
return RemoveRenameNode(node);
@@ -874,6 +872,7 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state) {
// StoreField and other operators).
DCHECK_NE(RegionObservability::kNotObservable, region_observability_);
region_observability_ = RegionObservabilityOf(node->op());
+ inside_region_ = true;
// Update the value uses to the value input of the finish node and
// the effect uses to the effect input.
return RemoveRenameNode(node);
@@ -891,6 +890,14 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state) {
return;
}
+ if (node->opcode() == IrOpcode::kStoreField) {
+ // Mark stores outside a region as non-initializing and non-transitioning.
+ if (!inside_region_) {
+ const FieldAccess access = FieldAccessOf(node->op());
+ NodeProperties::ChangeOp(node, simplified()->StoreField(access, false));
+ }
+ }
+
// The IfSuccess nodes should always start a basic block (and basic block
// start nodes are not handled in the ProcessNode method).
DCHECK_NE(IrOpcode::kIfSuccess, node->opcode());
@@ -1160,12 +1167,6 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kTypeOf:
result = LowerTypeOf(node);
break;
- case IrOpcode::kTierUpCheck:
- LowerTierUpCheck(node);
- break;
- case IrOpcode::kUpdateInterruptBudget:
- LowerUpdateInterruptBudget(node);
- break;
case IrOpcode::kNewDoubleElements:
result = LowerNewDoubleElements(node);
break;
@@ -3588,85 +3589,6 @@ Node* EffectControlLinearizer::LowerTypeOf(Node* node) {
__ NoContextConstant());
}
-void EffectControlLinearizer::LowerTierUpCheck(Node* node) {
- TierUpCheckNode n(node);
- TNode<FeedbackVector> vector = n.feedback_vector();
-
- Node* optimization_state =
- __ LoadField(AccessBuilder::ForFeedbackVectorFlags(), vector);
-
- // TODO(jgruber): The branch introduces a sequence of spills before the
- // branch (and restores at `fallthrough`) that are completely unnecessary
- // since the IfFalse continuation ends in a tail call. Investigate how to
- // avoid these and fix it.
-
- auto fallthrough = __ MakeLabel();
- auto has_optimized_code_or_marker = __ MakeDeferredLabel();
- __ BranchWithHint(
- __ Word32Equal(
- __ Word32And(optimization_state,
- __ Uint32Constant(
- FeedbackVector::
- kHasNoTopTierCodeOrCompileOptimizedMarkerMask)),
- __ Int32Constant(0)),
- &fallthrough, &has_optimized_code_or_marker, BranchHint::kTrue);
-
- __ Bind(&has_optimized_code_or_marker);
-
- // The optimization marker field contains a non-trivial value, and some
- // action has to be taken. For example, perhaps tier-up has been requested
- // and we need to kick off a compilation job; or optimized code is available
- // and should be tail-called.
- //
- // Currently we delegate these tasks to the InterpreterEntryTrampoline.
- // TODO(jgruber,v8:8888): Consider a dedicated builtin instead.
-
- TNode<HeapObject> code =
- __ HeapConstant(BUILTIN_CODE(isolate(), InterpreterEntryTrampoline));
-
- JSTrampolineDescriptor descriptor;
- CallDescriptor::Flags flags = CallDescriptor::kFixedTargetRegister |
- CallDescriptor::kIsTailCallForTierUp;
- auto call_descriptor = Linkage::GetStubCallDescriptor(
- graph()->zone(), descriptor, descriptor.GetStackParameterCount(), flags,
- Operator::kNoProperties);
- Node* nodes[] = {code, n.target(), n.new_target(), n.input_count(),
- n.context(), __ effect(), __ control()};
-
-#ifdef DEBUG
- static constexpr int kCodeContextEffectControl = 4;
- DCHECK_EQ(arraysize(nodes),
- descriptor.GetParameterCount() + kCodeContextEffectControl);
-#endif // DEBUG
-
- __ TailCall(call_descriptor, arraysize(nodes), nodes);
-
- __ Bind(&fallthrough);
-}
-
-void EffectControlLinearizer::LowerUpdateInterruptBudget(Node* node) {
- UpdateInterruptBudgetNode n(node);
- TNode<FeedbackCell> feedback_cell = n.feedback_cell();
- TNode<Int32T> budget = __ LoadField<Int32T>(
- AccessBuilder::ForFeedbackCellInterruptBudget(), feedback_cell);
- Node* new_budget = __ Int32Add(budget, __ Int32Constant(n.delta()));
- __ StoreField(AccessBuilder::ForFeedbackCellInterruptBudget(), feedback_cell,
- new_budget);
- if (n.delta() < 0) {
- auto next = __ MakeLabel();
- auto if_budget_exhausted = __ MakeDeferredLabel();
- __ Branch(__ Int32LessThan(new_budget, __ Int32Constant(0)),
- &if_budget_exhausted, &next);
-
- __ Bind(&if_budget_exhausted);
- CallBuiltin(Builtin::kBytecodeBudgetInterruptFromCode,
- node->op()->properties(), feedback_cell);
- __ Goto(&next);
-
- __ Bind(&next);
- }
-}
-
Node* EffectControlLinearizer::LowerToBoolean(Node* node) {
Node* obj = node->InputAt(0);
Callable const callable =
@@ -3683,10 +3605,8 @@ Node* EffectControlLinearizer::LowerArgumentsLength(Node* node) {
Node* arguments_length = ChangeIntPtrToSmi(
__ Load(MachineType::Pointer(), __ LoadFramePointer(),
__ IntPtrConstant(StandardFrameConstants::kArgCOffset)));
- if (kJSArgcIncludesReceiver) {
- arguments_length =
- __ SmiSub(arguments_length, __ SmiConstant(kJSArgcReceiverSlots));
- }
+ arguments_length =
+ __ SmiSub(arguments_length, __ SmiConstant(kJSArgcReceiverSlots));
return arguments_length;
}
@@ -3700,10 +3620,8 @@ Node* EffectControlLinearizer::LowerRestLength(Node* node) {
Node* arguments_length = ChangeIntPtrToSmi(
__ Load(MachineType::Pointer(), frame,
__ IntPtrConstant(StandardFrameConstants::kArgCOffset)));
- if (kJSArgcIncludesReceiver) {
- arguments_length =
- __ SmiSub(arguments_length, __ SmiConstant(kJSArgcReceiverSlots));
- }
+ arguments_length =
+ __ SmiSub(arguments_length, __ SmiConstant(kJSArgcReceiverSlots));
Node* rest_length =
__ SmiSub(arguments_length, __ SmiConstant(formal_parameter_count));
__ GotoIf(__ SmiLessThan(rest_length, __ SmiConstant(0)), &done,
@@ -4972,36 +4890,6 @@ void EffectControlLinearizer::LowerStoreMessage(Node* node) {
__ StoreField(AccessBuilder::ForExternalIntPtr(), offset, object_pattern);
}
-namespace {
-MachineType MachineTypeFor(CTypeInfo::Type type) {
- switch (type) {
- case CTypeInfo::Type::kVoid:
- return MachineType::AnyTagged();
- case CTypeInfo::Type::kBool:
- return MachineType::Bool();
- case CTypeInfo::Type::kInt32:
- return MachineType::Int32();
- case CTypeInfo::Type::kUint32:
- return MachineType::Uint32();
- case CTypeInfo::Type::kInt64:
- return MachineType::Int64();
- case CTypeInfo::Type::kAny:
- static_assert(sizeof(AnyCType) == 8,
- "CTypeInfo::Type::kAny is assumed to be of size 64 bits.");
- return MachineType::Int64();
- case CTypeInfo::Type::kUint64:
- return MachineType::Uint64();
- case CTypeInfo::Type::kFloat32:
- return MachineType::Float32();
- case CTypeInfo::Type::kFloat64:
- return MachineType::Float64();
- case CTypeInfo::Type::kV8Value:
- case CTypeInfo::Type::kApiObject:
- return MachineType::AnyTagged();
- }
-}
-} // namespace
-
Node* EffectControlLinearizer::AdaptFastCallTypedArrayArgument(
Node* node, ElementsKind expected_elements_kind,
GraphAssemblerLabel<0>* bailout) {
@@ -5320,15 +5208,14 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) {
value_input_count);
Node* stack_slot = nullptr;
+ int kAlign = alignof(v8::FastApiCallbackOptions);
+ int kSize = sizeof(v8::FastApiCallbackOptions);
+ // If this check fails, you've probably added new fields to
+ // v8::FastApiCallbackOptions, which means you'll need to write code
+ // that initializes and reads from them too.
+ CHECK_EQ(kSize, sizeof(uintptr_t) * 2);
+ stack_slot = __ StackSlot(kSize, kAlign);
if (c_signature->HasOptions()) {
- int kAlign = alignof(v8::FastApiCallbackOptions);
- int kSize = sizeof(v8::FastApiCallbackOptions);
- // If this check fails, you've probably added new fields to
- // v8::FastApiCallbackOptions, which means you'll need to write code
- // that initializes and reads from them too.
- CHECK_EQ(kSize, sizeof(uintptr_t) * 2);
- stack_slot = __ StackSlot(kSize, kAlign);
-
__ Store(
StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
stack_slot,
@@ -5339,17 +5226,29 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) {
stack_slot,
static_cast<int>(offsetof(v8::FastApiCallbackOptions, data)),
n.SlowCallArgument(FastApiCallNode::kSlowCallDataArgumentIndex));
+ } else {
+ __ Store(
+ StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
+ stack_slot,
+ 0, // fallback = false
+ __ Int32Constant(0));
+ __ Store(StoreRepresentation(MachineType::PointerRepresentation(),
+ kNoWriteBarrier),
+ stack_slot,
+ 0, // no data
+ n.SlowCallArgument(FastApiCallNode::kSlowCallDataArgumentIndex));
}
MachineSignature::Builder builder(
graph()->zone(), 1, c_arg_count + (c_signature->HasOptions() ? 1 : 0));
- MachineType return_type = MachineTypeFor(c_signature->ReturnInfo().GetType());
+ MachineType return_type =
+ MachineType::TypeForCType(c_signature->ReturnInfo());
builder.AddReturn(return_type);
for (int i = 0; i < c_arg_count; ++i) {
CTypeInfo type = c_signature->ArgumentInfo(i);
MachineType machine_type =
type.GetSequenceType() == CTypeInfo::SequenceType::kScalar
- ? MachineTypeFor(type.GetType())
+ ? MachineType::TypeForCType(type)
: MachineType::AnyTagged();
builder.AddParam(machine_type);
}
@@ -5487,10 +5386,8 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) {
Node* is_zero = __ Word32Equal(load, __ Int32Constant(0));
__ Branch(is_zero, &if_success, &if_error);
} else {
- // If c_call_result is nullptr, we didn't execute the fast path, so
- // we need to follow the slow path.
- Node* is_zero = __ WordEqual(c_call_result, __ IntPtrConstant(0));
- __ Branch(is_zero, &if_error, &if_success);
+ Node* true_constant = __ TrueConstant();
+ __ Branch(true_constant, &if_success, &if_error);
}
__ Bind(&if_success);
@@ -6818,7 +6715,7 @@ Node* EffectControlLinearizer::BuildAllocateBigInt(Node* bitfield,
DCHECK(machine()->Is64());
DCHECK_EQ(bitfield == nullptr, digit == nullptr);
static constexpr auto zero_bitfield =
- BigInt::SignBits::update(BigInt::LengthBits::encode(0), 0);
+ BigInt::SignBits::update(BigInt::LengthBits::encode(0), false);
Node* map = __ HeapConstant(factory()->bigint_map());
@@ -6846,30 +6743,13 @@ void LinearizeEffectControl(JSGraph* graph, Schedule* schedule, Zone* temp_zone,
SourcePositionTable* source_positions,
NodeOriginTable* node_origins,
JSHeapBroker* broker) {
- JSGraphAssembler graph_assembler_(graph, temp_zone, base::nullopt, nullptr);
+ JSGraphAssembler graph_assembler_(graph, temp_zone);
EffectControlLinearizer linearizer(graph, schedule, &graph_assembler_,
temp_zone, source_positions, node_origins,
MaintainSchedule::kDiscard, broker);
linearizer.Run();
}
-void LowerToMachineSchedule(JSGraph* js_graph, Schedule* schedule,
- Zone* temp_zone,
- SourcePositionTable* source_positions,
- NodeOriginTable* node_origins,
- JSHeapBroker* broker) {
- JSGraphAssembler graph_assembler(js_graph, temp_zone, base::nullopt,
- schedule);
- EffectControlLinearizer linearizer(js_graph, schedule, &graph_assembler,
- temp_zone, source_positions, node_origins,
- MaintainSchedule::kMaintain, broker);
- MemoryLowering memory_lowering(js_graph, temp_zone, &graph_assembler);
- SelectLowering select_lowering(&graph_assembler, js_graph->graph());
- graph_assembler.AddInlineReducer(&memory_lowering);
- graph_assembler.AddInlineReducer(&select_lowering);
- linearizer.Run();
-}
-
} // namespace compiler
} // namespace internal
} // namespace v8