diff options
Diffstat (limited to 'deps/v8/src/compiler/code-assembler.cc')
-rw-r--r-- | deps/v8/src/compiler/code-assembler.cc | 201 |
1 files changed, 186 insertions, 15 deletions
diff --git a/deps/v8/src/compiler/code-assembler.cc b/deps/v8/src/compiler/code-assembler.cc index 1ace7dae5e..1bde4c6a4c 100644 --- a/deps/v8/src/compiler/code-assembler.cc +++ b/deps/v8/src/compiler/code-assembler.cc @@ -31,6 +31,11 @@ #define REPEAT_1_TO_7(V, T) REPEAT_1_TO_6(V, T) V(T, T, T, T, T, T, T) #define REPEAT_1_TO_8(V, T) REPEAT_1_TO_7(V, T) V(T, T, T, T, T, T, T, T) #define REPEAT_1_TO_9(V, T) REPEAT_1_TO_8(V, T) V(T, T, T, T, T, T, T, T, T) +#define REPEAT_1_TO_10(V, T) REPEAT_1_TO_9(V, T) V(T, T, T, T, T, T, T, T, T, T) +#define REPEAT_1_TO_11(V, T) \ + REPEAT_1_TO_10(V, T) V(T, T, T, T, T, T, T, T, T, T, T) +#define REPEAT_1_TO_12(V, T) \ + REPEAT_1_TO_11(V, T) V(T, T, T, T, T, T, T, T, T, T, T, T) namespace v8 { namespace internal { @@ -79,6 +84,21 @@ int CodeAssemblerState::parameter_count() const { CodeAssembler::~CodeAssembler() {} +#if DEBUG +void CodeAssemblerState::PrintCurrentBlock(std::ostream& os) { + raw_assembler_->PrintCurrentBlock(os); +} +#endif + +void CodeAssemblerState::SetInitialDebugInformation(const char* msg, + const char* file, + int line) { +#if DEBUG + AssemblerDebugInfo debug_info = {msg, file, line}; + raw_assembler_->SetInitialDebugInformation(debug_info); +#endif // DEBUG +} + class BreakOnNodeDecorator final : public GraphDecorator { public: explicit BreakOnNodeDecorator(NodeId node_id) : node_id_(node_id) {} @@ -160,6 +180,19 @@ bool CodeAssembler::IsFloat64RoundTruncateSupported() const { return raw_assembler()->machine()->Float64RoundTruncate().IsSupported(); } +bool CodeAssembler::IsInt32AbsWithOverflowSupported() const { + return raw_assembler()->machine()->Int32AbsWithOverflow().IsSupported(); +} + +bool CodeAssembler::IsInt64AbsWithOverflowSupported() const { + return raw_assembler()->machine()->Int64AbsWithOverflow().IsSupported(); +} + +bool CodeAssembler::IsIntPtrAbsWithOverflowSupported() const { + return Is64() ? IsInt64AbsWithOverflowSupported() + : IsInt32AbsWithOverflowSupported(); +} + Node* CodeAssembler::Int32Constant(int32_t value) { return raw_assembler()->Int32Constant(value); } @@ -277,6 +310,14 @@ void CodeAssembler::PopAndReturn(Node* pop, Node* value) { return raw_assembler()->PopAndReturn(pop, value); } +void CodeAssembler::ReturnIf(Node* condition, Node* value) { + Label if_return(this), if_continue(this); + Branch(condition, &if_return, &if_continue); + Bind(&if_return); + Return(value); + Bind(&if_continue); +} + void CodeAssembler::DebugBreak() { raw_assembler()->DebugBreak(); } void CodeAssembler::Unreachable() { @@ -306,6 +347,12 @@ void CodeAssembler::Comment(const char* format, ...) { void CodeAssembler::Bind(Label* label) { return label->Bind(); } +#if DEBUG +void CodeAssembler::Bind(Label* label, AssemblerDebugInfo debug_info) { + return label->Bind(debug_info); +} +#endif // DEBUG + Node* CodeAssembler::LoadFramePointer() { return raw_assembler()->LoadFramePointer(); } @@ -391,6 +438,13 @@ Node* CodeAssembler::ChangeInt32ToIntPtr(Node* value) { return value; } +Node* CodeAssembler::ChangeFloat64ToUintPtr(Node* value) { + if (raw_assembler()->machine()->Is64()) { + return raw_assembler()->ChangeFloat64ToUint64(value); + } + return raw_assembler()->ChangeFloat64ToUint32(value); +} + Node* CodeAssembler::RoundIntPtrToFloat64(Node* value) { if (raw_assembler()->machine()->Is64()) { return raw_assembler()->RoundInt64ToFloat64(value); @@ -462,6 +516,26 @@ Node* CodeAssembler::AtomicStore(MachineRepresentation rep, Node* base, return raw_assembler()->AtomicStore(rep, base, offset, value); } +#define ATOMIC_FUNCTION(name) \ + Node* CodeAssembler::Atomic##name(MachineType type, Node* base, \ + Node* offset, Node* value) { \ + return raw_assembler()->Atomic##name(type, base, offset, value); \ + } +ATOMIC_FUNCTION(Exchange); +ATOMIC_FUNCTION(Add); +ATOMIC_FUNCTION(Sub); +ATOMIC_FUNCTION(And); +ATOMIC_FUNCTION(Or); +ATOMIC_FUNCTION(Xor); +#undef ATOMIC_FUNCTION + +Node* CodeAssembler::AtomicCompareExchange(MachineType type, Node* base, + Node* offset, Node* old_value, + Node* new_value) { + return raw_assembler()->AtomicCompareExchange(type, base, offset, old_value, + new_value); +} + Node* CodeAssembler::StoreRoot(Heap::RootListIndex root_index, Node* value) { DCHECK(Heap::RootCanBeWrittenAfterInitialization(root_index)); Node* roots_array_start = @@ -520,7 +594,7 @@ Node* CodeAssembler::CallRuntime(Runtime::FunctionId function, Node* context, return return_value; } -// Instantiate CallRuntime() with up to 6 arguments. +// Instantiate CallRuntime() for argument counts used by CSA-generated code #define INSTANTIATE(...) \ template V8_EXPORT_PRIVATE Node* CodeAssembler::CallRuntime( \ Runtime::FunctionId, __VA_ARGS__); @@ -546,7 +620,7 @@ Node* CodeAssembler::TailCallRuntime(Runtime::FunctionId function, return raw_assembler()->TailCallN(desc, arraysize(nodes), nodes); } -// Instantiate TailCallRuntime() with up to 6 arguments. +// Instantiate TailCallRuntime() for argument counts used by CSA-generated code #define INSTANTIATE(...) \ template V8_EXPORT_PRIVATE Node* CodeAssembler::TailCallRuntime( \ Runtime::FunctionId, __VA_ARGS__); @@ -561,11 +635,11 @@ Node* CodeAssembler::CallStubR(const CallInterfaceDescriptor& descriptor, return CallStubN(descriptor, result_size, arraysize(nodes), nodes); } -// Instantiate CallStubR() with up to 6 arguments. +// Instantiate CallStubR() for argument counts used by CSA-generated code. #define INSTANTIATE(...) \ template V8_EXPORT_PRIVATE Node* CodeAssembler::CallStubR( \ const CallInterfaceDescriptor& descriptor, size_t, Node*, __VA_ARGS__); -REPEAT_1_TO_7(INSTANTIATE, Node*) +REPEAT_1_TO_8(INSTANTIATE, Node*) #undef INSTANTIATE Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor, @@ -600,15 +674,15 @@ Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor, MachineType::AnyTagged(), result_size); Node* nodes[] = {target, args..., context}; - + CHECK_EQ(descriptor.GetParameterCount() + 2, arraysize(nodes)); return raw_assembler()->TailCallN(desc, arraysize(nodes), nodes); } -// Instantiate TailCallStub() with up to 6 arguments. +// Instantiate TailCallStub() for argument counts used by CSA-generated code #define INSTANTIATE(...) \ template V8_EXPORT_PRIVATE Node* CodeAssembler::TailCallStub( \ const CallInterfaceDescriptor& descriptor, Node*, __VA_ARGS__); -REPEAT_1_TO_7(INSTANTIATE, Node*) +REPEAT_1_TO_12(INSTANTIATE, Node*) #undef INSTANTIATE template <class... TArgs> @@ -619,10 +693,12 @@ Node* CodeAssembler::TailCallBytecodeDispatch( isolate(), zone(), descriptor, descriptor.GetStackParameterCount()); Node* nodes[] = {target, args...}; + CHECK_EQ(descriptor.GetParameterCount() + 1, arraysize(nodes)); return raw_assembler()->TailCallN(desc, arraysize(nodes), nodes); } -// Instantiate TailCallBytecodeDispatch() with 4 arguments. +// Instantiate TailCallBytecodeDispatch() for argument counts used by +// CSA-generated code template V8_EXPORT_PRIVATE Node* CodeAssembler::TailCallBytecodeDispatch( const CallInterfaceDescriptor& descriptor, Node* target, Node*, Node*, Node*, Node*); @@ -690,6 +766,17 @@ void CodeAssembler::Switch(Node* index, Label* default_label, labels, case_count); } +bool CodeAssembler::UnalignedLoadSupported(const MachineType& machineType, + uint8_t alignment) const { + return raw_assembler()->machine()->UnalignedLoadSupported(machineType, + alignment); +} +bool CodeAssembler::UnalignedStoreSupported(const MachineType& machineType, + uint8_t alignment) const { + return raw_assembler()->machine()->UnalignedStoreSupported(machineType, + alignment); +} + // RawMachineAssembler delegate helpers: Isolate* CodeAssembler::isolate() const { return raw_assembler()->isolate(); } @@ -707,7 +794,23 @@ RawMachineAssembler* CodeAssembler::raw_assembler() const { // properly be verified. class CodeAssemblerVariable::Impl : public ZoneObject { public: - explicit Impl(MachineRepresentation rep) : value_(nullptr), rep_(rep) {} + explicit Impl(MachineRepresentation rep) + : +#if DEBUG + debug_info_(AssemblerDebugInfo(nullptr, nullptr, -1)), +#endif + value_(nullptr), + rep_(rep) { + } + +#if DEBUG + AssemblerDebugInfo debug_info() const { return debug_info_; } + void set_debug_info(AssemblerDebugInfo debug_info) { + debug_info_ = debug_info; + } + + AssemblerDebugInfo debug_info_; +#endif // DEBUG Node* value_; MachineRepresentation rep_; }; @@ -725,6 +828,25 @@ CodeAssemblerVariable::CodeAssemblerVariable(CodeAssembler* assembler, Bind(initial_value); } +#if DEBUG +CodeAssemblerVariable::CodeAssemblerVariable(CodeAssembler* assembler, + AssemblerDebugInfo debug_info, + MachineRepresentation rep) + : impl_(new (assembler->zone()) Impl(rep)), state_(assembler->state()) { + impl_->set_debug_info(debug_info); + state_->variables_.insert(impl_); +} + +CodeAssemblerVariable::CodeAssemblerVariable(CodeAssembler* assembler, + AssemblerDebugInfo debug_info, + MachineRepresentation rep, + Node* initial_value) + : CodeAssemblerVariable(assembler, debug_info, rep) { + impl_->set_debug_info(debug_info); + Bind(initial_value); +} +#endif // DEBUG + CodeAssemblerVariable::~CodeAssemblerVariable() { state_->variables_.erase(impl_); } @@ -732,7 +854,18 @@ CodeAssemblerVariable::~CodeAssemblerVariable() { void CodeAssemblerVariable::Bind(Node* value) { impl_->value_ = value; } Node* CodeAssemblerVariable::value() const { - DCHECK_NOT_NULL(impl_->value_); +#if DEBUG + if (!IsBound()) { + std::stringstream str; + str << "#Use of unbound variable:" + << "#\n Variable: " << *this; + if (state_) { + str << "#\n Current Block: "; + state_->PrintCurrentBlock(str); + } + FATAL(str.str().c_str()); + } +#endif // DEBUG return impl_->value_; } @@ -740,9 +873,24 @@ MachineRepresentation CodeAssemblerVariable::rep() const { return impl_->rep_; } bool CodeAssemblerVariable::IsBound() const { return impl_->value_ != nullptr; } +std::ostream& operator<<(std::ostream& os, + const CodeAssemblerVariable::Impl& impl) { +#if DEBUG + AssemblerDebugInfo info = impl.debug_info(); + if (info.name) os << "V" << info; +#endif // DEBUG + return os; +} + +std::ostream& operator<<(std::ostream& os, + const CodeAssemblerVariable& variable) { + os << *variable.impl_; + return os; +} + CodeAssemblerLabel::CodeAssemblerLabel(CodeAssembler* assembler, size_t vars_count, - CodeAssemblerVariable** vars, + CodeAssemblerVariable* const* vars, CodeAssemblerLabel::Type type) : bound_(false), merge_count_(0), @@ -761,7 +909,7 @@ CodeAssemblerLabel::~CodeAssemblerLabel() { label_->~RawMachineLabel(); } void CodeAssemblerLabel::MergeVariables() { ++merge_count_; - for (auto var : state_->variables_) { + for (CodeAssemblerVariable::Impl* var : state_->variables_) { size_t count = 0; Node* node = var->value_; if (node != nullptr) { @@ -796,19 +944,42 @@ void CodeAssemblerLabel::MergeVariables() { // the variable after the label bind (it's not possible to add phis to // the bound label after the fact, just make sure to list the variable // in the label's constructor's list of merged variables). - DCHECK(find_if(i->second.begin(), i->second.end(), - [node](Node* e) -> bool { return node != e; }) == - i->second.end()); +#if DEBUG + if (find_if(i->second.begin(), i->second.end(), + [node](Node* e) -> bool { return node != e; }) != + i->second.end()) { + std::stringstream str; + str << "Unmerged variable found when jumping to block. \n" + << "# Variable: " << *var; + if (bound_) { + str << "\n# Target block: " << *label_->block(); + } + str << "\n# Current Block: "; + state_->PrintCurrentBlock(str); + FATAL(str.str().c_str()); + } +#endif // DEBUG } } } } } +#if DEBUG +void CodeAssemblerLabel::Bind(AssemblerDebugInfo debug_info) { + DCHECK(!bound_); + state_->raw_assembler_->Bind(label_, debug_info); + UpdateVariablesAfterBind(); +} +#endif // DEBUG + void CodeAssemblerLabel::Bind() { DCHECK(!bound_); state_->raw_assembler_->Bind(label_); + UpdateVariablesAfterBind(); +} +void CodeAssemblerLabel::UpdateVariablesAfterBind() { // Make sure that all variables that have changed along any path up to this // point are marked as merge variables. for (auto var : state_->variables_) { |