diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc index 7d05a736ae..3e8b0badd9 100644 --- a/src/compiler/pipeline.cc +++ b/src/compiler/pipeline.cc @@ -83,30 +83,15 @@ class PipelineData : public ZoneObject { outer_zone_(info_->zone()), zone_pool_(zone_pool), pipeline_statistics_(pipeline_statistics), - compilation_failed_(false), - code_(Handle::null()), - profiler_data_(nullptr), graph_zone_scope_(zone_pool_), graph_zone_(graph_zone_scope_.zone()), - graph_(nullptr), - loop_assignment_(nullptr), - simplified_(nullptr), - machine_(nullptr), - common_(nullptr), - javascript_(nullptr), - jsgraph_(nullptr), - schedule_(nullptr), instruction_zone_scope_(zone_pool_), instruction_zone_(instruction_zone_scope_.zone()), - sequence_(nullptr), - frame_(nullptr), register_allocation_zone_scope_(zone_pool_), - register_allocation_zone_(register_allocation_zone_scope_.zone()), - register_allocation_data_(nullptr) { + register_allocation_zone_(register_allocation_zone_scope_.zone()) { PhaseScope scope(pipeline_statistics, "init pipeline data"); graph_ = new (graph_zone_) Graph(graph_zone_); - source_positions_ = new (graph_zone_->New(sizeof(SourcePositionTable))) - SourcePositionTable(graph_); + source_positions_ = new (graph_zone_) SourcePositionTable(graph_); simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_); machine_ = new (graph_zone_) MachineOperatorBuilder( graph_zone_, MachineType::PointerRepresentation(), @@ -117,65 +102,47 @@ class PipelineData : public ZoneObject { JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_); } + // For WASM compile entry point. + PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, + SourcePositionTable* source_positions) + : isolate_(info->isolate()), + info_(info), + zone_pool_(zone_pool), + graph_zone_scope_(zone_pool_), + graph_(graph), + source_positions_(source_positions), + instruction_zone_scope_(zone_pool_), + instruction_zone_(instruction_zone_scope_.zone()), + register_allocation_zone_scope_(zone_pool_), + register_allocation_zone_(register_allocation_zone_scope_.zone()) {} + // For machine graph testing entry point. PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph, Schedule* schedule) : isolate_(info->isolate()), info_(info), - outer_zone_(nullptr), zone_pool_(zone_pool), - pipeline_statistics_(nullptr), - compilation_failed_(false), - code_(Handle::null()), - profiler_data_(nullptr), graph_zone_scope_(zone_pool_), - graph_zone_(nullptr), graph_(graph), - source_positions_(new (info->zone()->New(sizeof(SourcePositionTable))) - SourcePositionTable(graph_)), - loop_assignment_(nullptr), - simplified_(nullptr), - machine_(nullptr), - common_(nullptr), - javascript_(nullptr), - jsgraph_(nullptr), + source_positions_(new (info->zone()) SourcePositionTable(graph_)), schedule_(schedule), instruction_zone_scope_(zone_pool_), instruction_zone_(instruction_zone_scope_.zone()), - sequence_(nullptr), - frame_(nullptr), register_allocation_zone_scope_(zone_pool_), - register_allocation_zone_(register_allocation_zone_scope_.zone()), - register_allocation_data_(nullptr) {} + register_allocation_zone_(register_allocation_zone_scope_.zone()) {} // For register allocation testing entry point. PipelineData(ZonePool* zone_pool, CompilationInfo* info, InstructionSequence* sequence) : isolate_(info->isolate()), info_(info), - outer_zone_(nullptr), zone_pool_(zone_pool), - pipeline_statistics_(nullptr), - compilation_failed_(false), - code_(Handle::null()), - profiler_data_(nullptr), graph_zone_scope_(zone_pool_), - graph_zone_(nullptr), - graph_(nullptr), - loop_assignment_(nullptr), - simplified_(nullptr), - machine_(nullptr), - common_(nullptr), - javascript_(nullptr), - jsgraph_(nullptr), - schedule_(nullptr), instruction_zone_scope_(zone_pool_), instruction_zone_(sequence->zone()), sequence_(sequence), - frame_(nullptr), register_allocation_zone_scope_(zone_pool_), - register_allocation_zone_(register_allocation_zone_scope_.zone()), - register_allocation_data_(nullptr) {} + register_allocation_zone_(register_allocation_zone_scope_.zone()) {} void Destroy() { DeleteRegisterAllocationZone(); @@ -208,7 +175,10 @@ class PipelineData : public ZoneObject { Zone* graph_zone() const { return graph_zone_; } Graph* graph() const { return graph_; } - SourcePositionTable* source_positions() const { return source_positions_; } + SourcePositionTable* source_positions() const { + DCHECK_NOT_NULL(source_positions_); + return source_positions_; + } MachineOperatorBuilder* machine() const { return machine_; } CommonOperatorBuilder* common() const { return common_; } JSOperatorBuilder* javascript() const { return javascript_; } @@ -315,28 +285,28 @@ class PipelineData : public ZoneObject { private: Isolate* isolate_; CompilationInfo* info_; - Zone* outer_zone_; + Zone* outer_zone_ = nullptr; ZonePool* const zone_pool_; - PipelineStatistics* pipeline_statistics_; - bool compilation_failed_; + PipelineStatistics* pipeline_statistics_ = nullptr; + bool compilation_failed_ = false; Handle code_; - BasicBlockProfiler::Data* profiler_data_; + BasicBlockProfiler::Data* profiler_data_ = nullptr; std::ostringstream source_position_output_; // All objects in the following group of fields are allocated in graph_zone_. // They are all set to nullptr when the graph_zone_ is destroyed. ZonePool::Scope graph_zone_scope_; - Zone* graph_zone_; - Graph* graph_; - SourcePositionTable* source_positions_; - LoopAssignmentAnalysis* loop_assignment_; + Zone* graph_zone_ = nullptr; + Graph* graph_ = nullptr; + SourcePositionTable* source_positions_ = nullptr; + LoopAssignmentAnalysis* loop_assignment_ = nullptr; TypeHintAnalysis* type_hint_analysis_ = nullptr; - SimplifiedOperatorBuilder* simplified_; - MachineOperatorBuilder* machine_; - CommonOperatorBuilder* common_; - JSOperatorBuilder* javascript_; - JSGraph* jsgraph_; - Schedule* schedule_; + SimplifiedOperatorBuilder* simplified_ = nullptr; + MachineOperatorBuilder* machine_ = nullptr; + CommonOperatorBuilder* common_ = nullptr; + JSOperatorBuilder* javascript_ = nullptr; + JSGraph* jsgraph_ = nullptr; + Schedule* schedule_ = nullptr; // All objects in the following group of fields are allocated in // instruction_zone_. They are all set to nullptr when the instruction_zone_ @@ -344,15 +314,15 @@ class PipelineData : public ZoneObject { // destroyed. ZonePool::Scope instruction_zone_scope_; Zone* instruction_zone_; - InstructionSequence* sequence_; - Frame* frame_; + InstructionSequence* sequence_ = nullptr; + Frame* frame_ = nullptr; // All objects in the following group of fields are allocated in // register_allocation_zone_. They are all set to nullptr when the zone is // destroyed. ZonePool::Scope register_allocation_zone_scope_; Zone* register_allocation_zone_; - RegisterAllocationData* register_allocation_data_; + RegisterAllocationData* register_allocation_data_ = nullptr; int CalculateFixedFrameSize(CallDescriptor* descriptor) { if (descriptor->IsJSFunctionCall()) { @@ -1324,7 +1294,6 @@ Handle Pipeline::GenerateCode() { Linkage::ComputeIncoming(data.instruction_zone(), info())); } - Handle Pipeline::GenerateCodeForCodeStub(Isolate* isolate, CallDescriptor* call_descriptor, Graph* graph, Schedule* schedule, @@ -1393,9 +1362,11 @@ Handle Pipeline::GenerateCodeForTesting(CompilationInfo* info, return pipeline.ScheduleAndGenerateCode(call_descriptor); } -void Pipeline::InitializeWasmCompilation(Zone* pipeline_zone, - ZonePool* zone_pool, Graph* graph) { - data_ = new (pipeline_zone) PipelineData(zone_pool, info(), graph, nullptr); +void Pipeline::InitializeWasmCompilation( + Zone* pipeline_zone, ZonePool* zone_pool, Graph* graph, + SourcePositionTable* source_positions) { + data_ = new (pipeline_zone) + PipelineData(zone_pool, info(), graph, source_positions); RunPrintAndVerify("Machine", true); } diff --git a/src/compiler/pipeline.h b/src/compiler/pipeline.h index 391fef87af..911f283f5e 100644 --- a/src/compiler/pipeline.h +++ b/src/compiler/pipeline.h @@ -25,6 +25,7 @@ class InstructionSequence; class Linkage; class PipelineData; class Schedule; +class SourcePositionTable; class ZonePool; class Pipeline { @@ -64,7 +65,8 @@ class Pipeline { static OptimizedCompileJob* NewCompilationJob(CompilationInfo* info); void InitializeWasmCompilation(Zone* pipeline_zone, ZonePool* zone_pool, - Graph* graph); + Graph* graph, + SourcePositionTable* source_positions); bool ExecuteWasmCompilation(CallDescriptor* descriptor); Handle FinalizeWasmCompilation(CallDescriptor* descriptor); diff --git a/src/compiler/source-position.cc b/src/compiler/source-position.cc index 48361ecac7..80f180076d 100644 --- a/src/compiler/source-position.cc +++ b/src/compiler/source-position.cc @@ -16,7 +16,8 @@ class SourcePositionTable::Decorator final : public GraphDecorator { : source_positions_(source_positions) {} void Decorate(Node* node) final { - source_positions_->table_.Set(node, source_positions_->current_position_); + source_positions_->SetSourcePosition(node, + source_positions_->current_position_); } private: @@ -49,6 +50,10 @@ SourcePosition SourcePositionTable::GetSourcePosition(Node* node) const { return table_.Get(node); } +void SourcePositionTable::SetSourcePosition(Node* node, + SourcePosition position) { + table_.Set(node, position); +} void SourcePositionTable::Print(std::ostream& os) const { os << "{"; diff --git a/src/compiler/source-position.h b/src/compiler/source-position.h index 1f5196d193..912f18829f 100644 --- a/src/compiler/source-position.h +++ b/src/compiler/source-position.h @@ -38,8 +38,7 @@ inline bool operator!=(const SourcePosition& lhs, const SourcePosition& rhs) { return !(lhs == rhs); } - -class SourcePositionTable final { +class SourcePositionTable final : public ZoneObject { public: class Scope final { public: @@ -71,6 +70,7 @@ class SourcePositionTable final { void RemoveDecorator(); SourcePosition GetSourcePosition(Node* node) const; + void SetSourcePosition(Node* node, SourcePosition position); void Print(std::ostream& os) const; diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc index 82b5b151b0..86ed71c586 100644 --- a/src/compiler/wasm-compiler.cc +++ b/src/compiler/wasm-compiler.cc @@ -245,8 +245,9 @@ class WasmTrapHelper : public ZoneObject { } }; -WasmGraphBuilder::WasmGraphBuilder(Zone* zone, JSGraph* jsgraph, - wasm::FunctionSig* function_signature) +WasmGraphBuilder::WasmGraphBuilder( + Zone* zone, JSGraph* jsgraph, wasm::FunctionSig* function_signature, + compiler::SourcePositionTable* source_position_table) : zone_(zone), jsgraph_(jsgraph), module_(nullptr), @@ -258,7 +259,8 @@ WasmGraphBuilder::WasmGraphBuilder(Zone* zone, JSGraph* jsgraph, cur_buffer_(def_buffer_), cur_bufsize_(kDefaultBufferSize), trap_(new (zone) WasmTrapHelper(this)), - function_signature_(function_signature) { + function_signature_(function_signature), + source_position_table_(source_position_table) { DCHECK_NOT_NULL(jsgraph_); } @@ -2664,6 +2666,12 @@ void WasmGraphBuilder::Int64LoweringForTesting() { } } +void WasmGraphBuilder::SetSourcePosition(Node* node, int position) { + compiler::SourcePosition pos(position); + if (source_position_table_) + source_position_table_->SetSourcePosition(node, pos); +} + static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, CompilationInfo* info, const char* message, uint32_t index, @@ -2756,7 +2764,7 @@ Handle CompileJSToWasmWrapper( CompilationInfo info(func_name, isolate, &zone, flags); Handle code = - Pipeline::GenerateCodeForTesting(&info, incoming, &graph, nullptr); + Pipeline::GenerateCodeForTesting(&info, incoming, &graph); #ifdef ENABLE_DISASSEMBLER if (FLAG_print_opt_code && !code.is_null()) { OFStream os(stdout); @@ -2847,11 +2855,10 @@ Handle CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module, return code; } -JSGraph* BuildGraphForWasmFunction(Zone* zone, wasm::ErrorThrower& thrower, - Isolate* isolate, - wasm::ModuleEnv*& module_env, - const wasm::WasmFunction& function, - double* decode_ms) { +std::pair BuildGraphForWasmFunction( + Zone* zone, wasm::ErrorThrower& thrower, Isolate* isolate, + wasm::ModuleEnv*& module_env, const wasm::WasmFunction& function, + double* decode_ms) { base::ElapsedTimer decode_timer; if (FLAG_trace_wasm_decode_time) { decode_timer.Start(); @@ -2864,7 +2871,9 @@ JSGraph* BuildGraphForWasmFunction(Zone* zone, wasm::ErrorThrower& thrower, InstructionSelector::SupportedMachineOperatorFlags()); JSGraph* jsgraph = new (zone) JSGraph(isolate, graph, common, nullptr, nullptr, machine); - WasmGraphBuilder builder(zone, jsgraph, function.sig); + SourcePositionTable* source_position_table = + new (zone) SourcePositionTable(graph); + WasmGraphBuilder builder(zone, jsgraph, function.sig, source_position_table); wasm::FunctionBody body = { module_env, function.sig, module_env->module->module_start, module_env->module->module_start + function.code_start_offset, @@ -2889,7 +2898,7 @@ JSGraph* BuildGraphForWasmFunction(Zone* zone, wasm::ErrorThrower& thrower, SNPrintF(buffer, "Compiling WASM function #%d:%.*s failed:", function.func_index, name.length, name.name); thrower.Failed(buffer.start(), result); - return nullptr; + return std::make_pair(nullptr, nullptr); } int index = static_cast(function.func_index); if (index >= FLAG_trace_wasm_ast_start && index < FLAG_trace_wasm_ast_end) { @@ -2898,7 +2907,7 @@ JSGraph* BuildGraphForWasmFunction(Zone* zone, wasm::ErrorThrower& thrower, if (FLAG_trace_wasm_decode_time) { *decode_ms = decode_timer.Elapsed().InMillisecondsF(); } - return jsgraph; + return std::make_pair(jsgraph, source_position_table); } // Helper function to compile a single function. @@ -2917,9 +2926,11 @@ Handle CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, compiler::ZonePool zone_pool(isolate->allocator()); compiler::ZonePool::Scope graph_zone_scope(&zone_pool); double decode_ms = 0; - JSGraph* jsgraph = + std::pair graph_result = BuildGraphForWasmFunction(graph_zone_scope.zone(), thrower, isolate, module_env, function, &decode_ms); + JSGraph* jsgraph = graph_result.first; + SourcePositionTable* source_positions = graph_result.second; if (jsgraph == nullptr) { return Handle::null(); @@ -2958,7 +2969,7 @@ Handle CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, compiler::ZonePool::Scope pipeline_zone_scope(&zone_pool); Pipeline pipeline(&info); pipeline.InitializeWasmCompilation(pipeline_zone_scope.zone(), &zone_pool, - jsgraph->graph()); + jsgraph->graph(), source_positions); Handle code; if (pipeline.ExecuteWasmCompilation(descriptor)) { code = pipeline.FinalizeWasmCompilation(descriptor); diff --git a/src/compiler/wasm-compiler.h b/src/compiler/wasm-compiler.h index 91774c0816..a27571f22b 100644 --- a/src/compiler/wasm-compiler.h +++ b/src/compiler/wasm-compiler.h @@ -19,6 +19,7 @@ class Node; class JSGraph; class Graph; class Operator; +class SourcePositionTable; } namespace wasm { @@ -56,7 +57,9 @@ Handle CompileJSToWasmWrapper( class WasmTrapHelper; class WasmGraphBuilder { public: - WasmGraphBuilder(Zone* z, JSGraph* g, wasm::FunctionSig* function_signature); + WasmGraphBuilder( + Zone* z, JSGraph* g, wasm::FunctionSig* function_signature, + compiler::SourcePositionTable* source_position_table = nullptr); Node** Buffer(size_t count) { if (count > cur_bufsize_) { @@ -140,6 +143,8 @@ class WasmGraphBuilder { void Int64LoweringForTesting(); + void SetSourcePosition(Node* node, int position); + private: static const int kDefaultBufferSize = 16; friend class WasmTrapHelper; @@ -160,6 +165,8 @@ class WasmGraphBuilder { wasm::FunctionSig* function_signature_; SetOncePointer allocate_heap_number_operator_; + compiler::SourcePositionTable* source_position_table_ = nullptr; + // Internal helper methods. JSGraph* jsgraph() { return jsgraph_; } Graph* graph(); diff --git a/src/wasm/ast-decoder.cc b/src/wasm/ast-decoder.cc index d63037aef7..62026517a7 100644 --- a/src/wasm/ast-decoder.cc +++ b/src/wasm/ast-decoder.cc @@ -718,6 +718,7 @@ class SR_WasmDecoder : public WasmDecoder { break; } case kExprUnreachable: { + // TODO(clemensh): add source position for unreachable BUILD0(Unreachable); ssa_env_->Kill(SsaEnv::kControlEnd); Leaf(kAstEnd, nullptr); @@ -1235,6 +1236,7 @@ class SR_WasmDecoder : public WasmDecoder { buffer[i] = p->tree->children[i - 1]->node; } p->tree->node = builder_->CallDirect(operand.index, buffer); + AddSourcePosition(p); } break; } @@ -1253,6 +1255,7 @@ class SR_WasmDecoder : public WasmDecoder { buffer[i] = p->tree->children[i]->node; } p->tree->node = builder_->CallIndirect(operand.index, buffer); + AddSourcePosition(p); } break; } @@ -1270,6 +1273,7 @@ class SR_WasmDecoder : public WasmDecoder { buffer[i] = p->tree->children[i - 1]->node; } p->tree->node = builder_->CallImport(operand.index, buffer); + AddSourcePosition(p); } break; } @@ -1631,6 +1635,17 @@ class SR_WasmDecoder : public WasmDecoder { } return assigned; } + + void AddSourcePosition(Production* p) { + DCHECK_NOT_NULL(p->tree->node); + AddSourcePosition(p->tree->node, p->pc()); + } + + void AddSourcePosition(TFNode* node, const byte* pc) { + int offset = static_cast(pc - start_); + DCHECK_EQ(pc - start_, offset); // overflows cannot happen + builder_->SetSourcePosition(node, offset); + } }; bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, diff --git a/test/cctest/wasm/test-run-wasm.cc b/test/cctest/wasm/test-run-wasm.cc index a682576c21..36a211e83f 100644 --- a/test/cctest/wasm/test-run-wasm.cc +++ b/test/cctest/wasm/test-run-wasm.cc @@ -1727,14 +1727,14 @@ static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) { if (sig->parameter_count() == 1) { byte code[] = {WASM_NO_LOCALS, static_cast(opcode), kExprGetLocal, 0}; - TestBuildingGraph(&zone, &jsgraph, nullptr, sig, code, + TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code, code + arraysize(code)); } else { CHECK_EQ(2, sig->parameter_count()); byte code[] = {WASM_NO_LOCALS, static_cast(opcode), kExprGetLocal, 0, kExprGetLocal, 1}; - TestBuildingGraph(&zone, &jsgraph, nullptr, sig, code, + TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code, code + arraysize(code)); } } diff --git a/test/cctest/wasm/wasm-run-utils.h b/test/cctest/wasm/wasm-run-utils.h index ea3e8ba2d4..9c371bd032 100644 --- a/test/cctest/wasm/wasm-run-utils.h +++ b/test/cctest/wasm/wasm-run-utils.h @@ -17,6 +17,7 @@ #include "src/compiler/node.h" #include "src/compiler/pipeline.h" #include "src/compiler/wasm-compiler.h" +#include "src/compiler/zone-pool.h" #include "src/wasm/ast-decoder.h" #include "src/wasm/wasm-js.h" @@ -242,9 +243,10 @@ class TestingModule : public ModuleEnv { }; inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module, - FunctionSig* sig, const byte* start, - const byte* end) { - compiler::WasmGraphBuilder builder(zone, jsgraph, sig); + FunctionSig* sig, + SourcePositionTable* source_position_table, + const byte* start, const byte* end) { + compiler::WasmGraphBuilder builder(zone, jsgraph, sig, source_position_table); TreeResult result = BuildTFGraph(zone->allocator(), &builder, module, sig, start, end); if (result.failed()) { @@ -418,7 +420,8 @@ class WasmFunctionCompiler : public HandleAndZoneScope, sig(sig), descriptor_(nullptr), testing_module_(module), - debug_name_(debug_name) { + debug_name_(debug_name), + source_position_table_(this->graph()) { if (module) { // Get a new function from the testing module. function_ = nullptr; @@ -444,6 +447,7 @@ class WasmFunctionCompiler : public HandleAndZoneScope, WasmFunction* function_; int function_index_; LocalDeclEncoder local_decls; + SourcePositionTable source_position_table_; Isolate* isolate() { return main_isolate(); } Graph* graph() const { return main_graph_; } @@ -460,7 +464,8 @@ class WasmFunctionCompiler : public HandleAndZoneScope, void Build(const byte* start, const byte* end) { // Build the TurboFan graph. local_decls.Prepend(&start, &end); - TestBuildingGraph(main_zone(), &jsgraph, testing_module_, sig, start, end); + TestBuildingGraph(main_zone(), &jsgraph, testing_module_, sig, + &source_position_table_, start, end); delete[] start; } @@ -479,16 +484,26 @@ class WasmFunctionCompiler : public HandleAndZoneScope, } CompilationInfo info(debug_name_, this->isolate(), this->zone(), Code::ComputeFlags(Code::WASM_FUNCTION)); - Handle result = - Pipeline::GenerateCodeForTesting(&info, desc, this->graph()); + compiler::ZonePool zone_pool(this->isolate()->allocator()); + compiler::ZonePool::Scope pipeline_zone_scope(&zone_pool); + Pipeline pipeline(&info); + pipeline.InitializeWasmCompilation(this->zone(), &zone_pool, this->graph(), + &source_position_table_); + Handle code; + if (pipeline.ExecuteWasmCompilation(desc)) { + code = pipeline.FinalizeWasmCompilation(desc); + } else { + code = Handle::null(); + } + pipeline_zone_scope.Destroy(); #ifdef ENABLE_DISASSEMBLER - if (!result.is_null() && FLAG_print_opt_code) { + if (!code.is_null() && FLAG_print_opt_code) { OFStream os(stdout); - result->Disassemble("wasm code", os); + code->Disassemble("wasm code", os); } #endif - return result; + return code; } uint32_t CompileAndAdd(uint16_t sig_index = 0) {