From 78b1585f1d148b2bbbc27f870efbe4e2787bbffb Mon Sep 17 00:00:00 2001 From: danno Date: Thu, 19 May 2016 02:46:34 -0700 Subject: [PATCH] [turbofan] Add DebugBreak machine operator and support Review-Url: https://codereview.chromium.org/1995543003 Cr-Commit-Position: refs/heads/master@{#36355} --- src/code-stub-assembler.cc | 12 ++++++++++++ src/code-stub-assembler.h | 2 ++ src/compiler/arm/code-generator-arm.cc | 3 +++ src/compiler/arm64/code-generator-arm64.cc | 3 +++ src/compiler/code-assembler.cc | 2 ++ src/compiler/code-assembler.h | 2 ++ src/compiler/ia32/code-generator-ia32.cc | 3 +++ src/compiler/instruction-codes.h | 1 + src/compiler/instruction-scheduler.cc | 1 + src/compiler/instruction-selector.cc | 7 +++++++ src/compiler/instruction-selector.h | 1 + src/compiler/machine-operator.cc | 10 ++++++++++ src/compiler/machine-operator.h | 2 ++ src/compiler/mips/code-generator-mips.cc | 3 +++ src/compiler/mips64/code-generator-mips64.cc | 3 +++ src/compiler/opcodes.h | 1 + src/compiler/raw-machine-assembler.cc | 1 + src/compiler/raw-machine-assembler.h | 1 + src/compiler/typer.cc | 2 ++ src/compiler/verifier.cc | 4 ++++ src/compiler/x64/code-generator-x64.cc | 3 +++ 21 files changed, 67 insertions(+) diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc index e0963145ff..0cca9e7f3b 100644 --- a/src/code-stub-assembler.cc +++ b/src/code-stub-assembler.cc @@ -22,6 +22,18 @@ CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, const char* name) : compiler::CodeAssembler(isolate, zone, parameter_count, flags, name) {} +void CodeStubAssembler::Assert(Node* condition) { +#if defined(DEBUG) + Label ok(this); + Label not_ok(this); + Branch(condition, &ok, ¬_ok); + Bind(¬_ok); + DebugBreak(); + Goto(&ok); + Bind(&ok); +#endif +} + Node* CodeStubAssembler::BooleanMapConstant() { return HeapConstant(isolate()->factory()->boolean_map()); } diff --git a/src/code-stub-assembler.h b/src/code-stub-assembler.h index 19b798216f..c24d3785d8 100644 --- a/src/code-stub-assembler.h +++ b/src/code-stub-assembler.h @@ -75,6 +75,8 @@ class CodeStubAssembler : public compiler::CodeAssembler { compiler::Node* InnerAllocate(compiler::Node* previous, compiler::Node* offset); + void Assert(compiler::Node* condition); + // Check a value for smi-ness compiler::Node* WordIsSmi(compiler::Node* a); // Check that the value is a positive smi. diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc index 2c9415e68d..c8d109c43f 100644 --- a/src/compiler/arm/code-generator-arm.cc +++ b/src/compiler/arm/code-generator-arm.cc @@ -584,6 +584,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( AssembleArchTableSwitch(instr); DCHECK_EQ(LeaveCC, i.OutputSBit()); break; + case kArchDebugBreak: + __ stop("kArchDebugBreak"); + break; case kArchNop: case kArchThrowTerminator: // don't emit code for nops. diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc index 0f9fb7ce7d..9b65ccb5e3 100644 --- a/src/compiler/arm64/code-generator-arm64.cc +++ b/src/compiler/arm64/code-generator-arm64.cc @@ -711,6 +711,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArchLookupSwitch: AssembleArchLookupSwitch(instr); break; + case kArchDebugBreak: + __ Debug("kArchDebugBreak", 0, BREAK); + break; case kArchNop: case kArchThrowTerminator: // don't emit code for nops. diff --git a/src/compiler/code-assembler.cc b/src/compiler/code-assembler.cc index 0a90b9e925..334f5c4280 100644 --- a/src/compiler/code-assembler.cc +++ b/src/compiler/code-assembler.cc @@ -131,6 +131,8 @@ void CodeAssembler::Return(Node* value) { return raw_assembler_->Return(value); } +void CodeAssembler::DebugBreak() { raw_assembler_->DebugBreak(); } + void CodeAssembler::Bind(CodeAssembler::Label* label) { return label->Bind(); } Node* CodeAssembler::LoadFramePointer() { diff --git a/src/compiler/code-assembler.h b/src/compiler/code-assembler.h index d32093496b..787d16b449 100644 --- a/src/compiler/code-assembler.h +++ b/src/compiler/code-assembler.h @@ -203,6 +203,8 @@ class CodeAssembler { Node* Parameter(int value); void Return(Node* value); + void DebugBreak(); + void Bind(Label* label); void Goto(Label* label); void GotoIf(Node* condition, Label* true_label); diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc index a9083e1351..c3964e7f4d 100644 --- a/src/compiler/ia32/code-generator-ia32.cc +++ b/src/compiler/ia32/code-generator-ia32.cc @@ -539,6 +539,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArchTableSwitch: AssembleArchTableSwitch(instr); break; + case kArchDebugBreak: + __ int3(); + break; case kArchNop: case kArchThrowTerminator: // don't emit code for nops. diff --git a/src/compiler/instruction-codes.h b/src/compiler/instruction-codes.h index 57868c6507..697604f911 100644 --- a/src/compiler/instruction-codes.h +++ b/src/compiler/instruction-codes.h @@ -56,6 +56,7 @@ enum class RecordWriteMode { kValueIsMap, kValueIsPointer, kValueIsAny }; V(ArchLookupSwitch) \ V(ArchTableSwitch) \ V(ArchNop) \ + V(ArchDebugBreak) \ V(ArchThrowTerminator) \ V(ArchDeoptimize) \ V(ArchRet) \ diff --git a/src/compiler/instruction-scheduler.cc b/src/compiler/instruction-scheduler.cc index b3e4bbcee8..f2f8f4f4bd 100644 --- a/src/compiler/instruction-scheduler.cc +++ b/src/compiler/instruction-scheduler.cc @@ -222,6 +222,7 @@ int InstructionScheduler::GetInstructionFlags(const Instruction* instr) const { case kArchParentFramePointer: case kArchTruncateDoubleToI: case kArchStackSlot: + case kArchDebugBreak: return kNoOpcodeFlags; case kArchStackPointer: diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index 88cc2e536c..92223e87a0 100644 --- a/src/compiler/instruction-selector.cc +++ b/src/compiler/instruction-selector.cc @@ -900,6 +900,9 @@ void InstructionSelector::VisitNode(Node* node) { case IrOpcode::kStateValues: case IrOpcode::kObjectState: return; + case IrOpcode::kDebugBreak: + VisitDebugBreak(); + return; case IrOpcode::kLoad: { LoadRepresentation type = LoadRepresentationOf(node->op()); MarkAsRepresentation(type.representation(), node); @@ -1785,6 +1788,10 @@ void InstructionSelector::VisitThrow(Node* value) { Emit(kArchThrowTerminator, g.NoOutput()); } +void InstructionSelector::VisitDebugBreak() { + OperandGenerator g(this); + Emit(kArchDebugBreak, g.NoOutput()); +} FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( Node* state) { diff --git a/src/compiler/instruction-selector.h b/src/compiler/instruction-selector.h index 335099f35b..edc0eec021 100644 --- a/src/compiler/instruction-selector.h +++ b/src/compiler/instruction-selector.h @@ -263,6 +263,7 @@ class InstructionSelector final { void VisitDeoptimize(DeoptimizeKind kind, Node* value); void VisitReturn(Node* ret); void VisitThrow(Node* value); + void VisitDebugBreak(); void EmitPrepareArguments(ZoneVector* arguments, const CallDescriptor* descriptor, Node* node); diff --git a/src/compiler/machine-operator.cc b/src/compiler/machine-operator.cc index 0d229c7abe..cd9f7c0cc8 100644 --- a/src/compiler/machine-operator.cc +++ b/src/compiler/machine-operator.cc @@ -526,6 +526,13 @@ struct MachineOperatorGlobalCache { AtomicStore##Type##Operator kAtomicStore##Type; ATOMIC_REPRESENTATION_LIST(ATOMIC_STORE) #undef STORE + + struct DebugBreakOperator : public Operator { + DebugBreakOperator() + : Operator(IrOpcode::kDebugBreak, Operator::kNoThrow, "DebugBreak", 0, + 0, 0, 0, 0, 0) {} + }; + DebugBreakOperator kDebugBreak; }; @@ -604,6 +611,9 @@ const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) { return nullptr; } +const Operator* MachineOperatorBuilder::DebugBreak() { + return &cache_.kDebugBreak; +} const Operator* MachineOperatorBuilder::CheckedLoad( CheckedLoadRepresentation rep) { diff --git a/src/compiler/machine-operator.h b/src/compiler/machine-operator.h index 814f6c9bed..ed2a758b08 100644 --- a/src/compiler/machine-operator.h +++ b/src/compiler/machine-operator.h @@ -128,6 +128,8 @@ class MachineOperatorBuilder final : public ZoneObject { MachineRepresentation word = MachineType::PointerRepresentation(), Flags supportedOperators = kNoFlags); + const Operator* DebugBreak(); + const Operator* Word32And(); const Operator* Word32Or(); const Operator* Word32Xor(); diff --git a/src/compiler/mips/code-generator-mips.cc b/src/compiler/mips/code-generator-mips.cc index c437d5e895..ffc0258ba0 100644 --- a/src/compiler/mips/code-generator-mips.cc +++ b/src/compiler/mips/code-generator-mips.cc @@ -652,6 +652,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArchTableSwitch: AssembleArchTableSwitch(instr); break; + case kArchDebugBreak: + __ stop("kArchDebugBreak"); + break; case kArchNop: case kArchThrowTerminator: // don't emit code for nops. diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc index a7d2301410..b122cbf955 100644 --- a/src/compiler/mips64/code-generator-mips64.cc +++ b/src/compiler/mips64/code-generator-mips64.cc @@ -661,6 +661,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArchTableSwitch: AssembleArchTableSwitch(instr); break; + case kArchDebugBreak: + __ stop("kArchDebugBreak"); + break; case kArchNop: case kArchThrowTerminator: // don't emit code for nops. diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h index ce5087c7c2..4225be3671 100644 --- a/src/compiler/opcodes.h +++ b/src/compiler/opcodes.h @@ -242,6 +242,7 @@ #define MACHINE_OP_LIST(V) \ MACHINE_COMPARE_BINOP_LIST(V) \ + V(DebugBreak) \ V(Load) \ V(Store) \ V(StackSlot) \ diff --git a/src/compiler/raw-machine-assembler.cc b/src/compiler/raw-machine-assembler.cc index 9407da6ae3..0d4643b8e6 100644 --- a/src/compiler/raw-machine-assembler.cc +++ b/src/compiler/raw-machine-assembler.cc @@ -135,6 +135,7 @@ void RawMachineAssembler::Return(Node* v1, Node* v2, Node* v3) { current_block_ = nullptr; } +void RawMachineAssembler::DebugBreak() { AddNode(machine()->DebugBreak()); } Node* RawMachineAssembler::CallN(CallDescriptor* desc, Node* function, Node** args) { diff --git a/src/compiler/raw-machine-assembler.h b/src/compiler/raw-machine-assembler.h index 69ddd5065f..f12ad871da 100644 --- a/src/compiler/raw-machine-assembler.h +++ b/src/compiler/raw-machine-assembler.h @@ -697,6 +697,7 @@ class RawMachineAssembler { void Return(Node* v1, Node* v2, Node* v3); void Bind(RawMachineLabel* label); void Deoptimize(Node* state); + void DebugBreak(); // Variables. Node* Phi(MachineRepresentation rep, Node* n1, Node* n2) { diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index d98d2fe1a8..7eba280d0a 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -2008,6 +2008,8 @@ Type* Typer::Visitor::TypeObjectIsUndetectable(Node* node) { // Machine operators. +Type* Typer::Visitor::TypeDebugBreak(Node* node) { return Type::None(); } + Type* Typer::Visitor::TypeLoad(Node* node) { return Type::Any(); } Type* Typer::Visitor::TypeStackSlot(Node* node) { return Type::Any(); } diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc index 0e34285221..345347d0a1 100644 --- a/src/compiler/verifier.cc +++ b/src/compiler/verifier.cc @@ -641,6 +641,10 @@ void Verifier::Visitor::Check(Node* node) { CheckNotTyped(node); break; + case IrOpcode::kDebugBreak: + CheckNotTyped(node); + break; + // Simplified operators // ------------------------------- case IrOpcode::kBooleanNot: diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc index a90a584cde..a4ece5d557 100644 --- a/src/compiler/x64/code-generator-x64.cc +++ b/src/compiler/x64/code-generator-x64.cc @@ -763,6 +763,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArchTableSwitch: AssembleArchTableSwitch(instr); break; + case kArchDebugBreak: + __ int3(); + break; case kArchNop: case kArchThrowTerminator: // don't emit code for nops.