Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/assembler-inl.h" | 9 #include "src/assembler-inl.h" |
| 10 #include "src/base/platform/elapsed-timer.h" | 10 #include "src/base/platform/elapsed-timer.h" |
| (...skipping 3969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3980 if (FLAG_trace_wasm_decode_time) { | 3980 if (FLAG_trace_wasm_decode_time) { |
| 3981 decode_timer.Start(); | 3981 decode_timer.Start(); |
| 3982 } | 3982 } |
| 3983 // Create a TF graph during decoding. | 3983 // Create a TF graph during decoding. |
| 3984 | 3984 |
| 3985 Graph* graph = jsgraph_->graph(); | 3985 Graph* graph = jsgraph_->graph(); |
| 3986 CommonOperatorBuilder* common = jsgraph_->common(); | 3986 CommonOperatorBuilder* common = jsgraph_->common(); |
| 3987 MachineOperatorBuilder* machine = jsgraph_->machine(); | 3987 MachineOperatorBuilder* machine = jsgraph_->machine(); |
| 3988 SourcePositionTable* source_position_table = | 3988 SourcePositionTable* source_position_table = |
| 3989 new (jsgraph_->zone()) SourcePositionTable(graph); | 3989 new (jsgraph_->zone()) SourcePositionTable(graph); |
| 3990 WasmGraphBuilder builder(&module_env_->module_env, jsgraph_->zone(), jsgraph_, | 3990 WasmGraphBuilder builder(module_env_, jsgraph_->zone(), jsgraph_, |
| 3991 function_->sig, source_position_table); | 3991 func_body_.sig, source_position_table); |
| 3992 const byte* module_start = module_env_->wire_bytes.start(); | |
| 3993 wasm::FunctionBody body = {function_->sig, module_start, | |
| 3994 module_start + function_->code_start_offset, | |
| 3995 module_start + function_->code_end_offset}; | |
| 3996 graph_construction_result_ = | 3992 graph_construction_result_ = |
| 3997 wasm::BuildTFGraph(isolate_->allocator(), &builder, body); | 3993 wasm::BuildTFGraph(isolate_->allocator(), &builder, func_body_); |
| 3998 | 3994 |
| 3999 if (graph_construction_result_.failed()) { | 3995 if (graph_construction_result_.failed()) { |
| 4000 if (FLAG_trace_wasm_compiler) { | 3996 if (FLAG_trace_wasm_compiler) { |
| 4001 OFStream os(stdout); | 3997 OFStream os(stdout); |
| 4002 os << "Compilation failed: " << graph_construction_result_ << std::endl; | 3998 os << "Compilation failed: " << graph_construction_result_ << std::endl; |
| 4003 } | 3999 } |
| 4004 return nullptr; | 4000 return nullptr; |
| 4005 } | 4001 } |
| 4006 | 4002 |
| 4007 if (machine->Is32()) { | 4003 if (machine->Is32()) { |
| 4008 Int64Lowering(graph, machine, common, jsgraph_->zone(), function_->sig) | 4004 Int64Lowering(graph, machine, common, jsgraph_->zone(), func_body_.sig) |
| 4009 .LowerGraph(); | 4005 .LowerGraph(); |
| 4010 } | 4006 } |
| 4011 | 4007 |
| 4012 if (builder.has_simd() && !CpuFeatures::SupportsSimd128()) { | 4008 if (builder.has_simd() && !CpuFeatures::SupportsSimd128()) { |
| 4013 SimdScalarLowering(graph, machine, common, jsgraph_->zone(), function_->sig) | 4009 SimdScalarLowering(graph, machine, common, jsgraph_->zone(), func_body_.sig) |
| 4014 .LowerGraph(); | 4010 .LowerGraph(); |
| 4015 } | 4011 } |
| 4016 | 4012 |
| 4017 int index = static_cast<int>(function_->func_index); | 4013 if (func_index_ >= FLAG_trace_wasm_ast_start && |
| 4018 | 4014 func_index_ < FLAG_trace_wasm_ast_end) { |
| 4019 if (index >= FLAG_trace_wasm_ast_start && index < FLAG_trace_wasm_ast_end) { | 4015 PrintRawWasmCode(isolate_->allocator(), func_body_, module_env_->module); |
| 4020 OFStream os(stdout); | |
| 4021 PrintRawWasmCode(isolate_->allocator(), body, | |
| 4022 module_env_->module_env.module); | |
| 4023 } | 4016 } |
| 4024 if (index >= FLAG_trace_wasm_text_start && index < FLAG_trace_wasm_text_end) { | 4017 // TODO(clemens): Remove the trace_wasm_text_start flag. |
| 4025 OFStream os(stdout); | 4018 // if (func_index_ >= FLAG_trace_wasm_text_start && func_index_ < |
| 4026 PrintWasmText(module_env_->module_env.module, module_env_->wire_bytes, | 4019 // FLAG_trace_wasm_text_end) { |
| 4027 function_->func_index, os, nullptr); | 4020 // OFStream os(stdout); |
| 4028 } | 4021 // PrintWasmText(module_env_.module, module_env_->wire_bytes, |
| 4022 // function_->func_index, os, nullptr); | |
| 4023 //} | |
| 4029 if (FLAG_trace_wasm_decode_time) { | 4024 if (FLAG_trace_wasm_decode_time) { |
| 4030 *decode_ms = decode_timer.Elapsed().InMillisecondsF(); | 4025 *decode_ms = decode_timer.Elapsed().InMillisecondsF(); |
| 4031 } | 4026 } |
| 4032 return source_position_table; | 4027 return source_position_table; |
| 4033 } | 4028 } |
| 4034 | 4029 |
| 4035 char* WasmCompilationUnit::GetTaggedFunctionName( | 4030 WasmCompilationUnit::WasmCompilationUnit(Isolate* isolate, |
| 4036 const wasm::WasmFunction* function) { | 4031 wasm::ModuleBytesEnv* module_env, |
| 4037 snprintf(function_name_, sizeof(function_name_), "wasm#%d", | 4032 const wasm::WasmFunction* function) |
| 4038 function->func_index); | 4033 : WasmCompilationUnit( |
| 4039 return function_name_; | 4034 isolate, &module_env->module_env, |
| 4040 } | 4035 wasm::FunctionBody{ |
| 4036 function->sig, module_env->wire_bytes.start(), | |
| 4037 module_env->wire_bytes.start() + function->code_start_offset, | |
| 4038 module_env->wire_bytes.start() + function->code_end_offset}, | |
| 4039 module_env->wire_bytes.GetNameOrNull(function), | |
| 4040 function->func_index) {} | |
| 4041 | 4041 |
| 4042 WasmCompilationUnit::WasmCompilationUnit(wasm::ErrorThrower* thrower, | 4042 WasmCompilationUnit::WasmCompilationUnit(Isolate* isolate, |
| 4043 Isolate* isolate, | 4043 wasm::ModuleEnv* module_env, |
| 4044 wasm::ModuleBytesEnv* module_env, | 4044 wasm::FunctionBody body, |
| 4045 const wasm::WasmFunction* function, | 4045 wasm::WasmName name, int index) |
| 4046 uint32_t index) | 4046 : isolate_(isolate), |
| 4047 : thrower_(thrower), | |
| 4048 isolate_(isolate), | |
| 4049 module_env_(module_env), | 4047 module_env_(module_env), |
| 4050 function_(&module_env->module_env.module->functions[index]), | 4048 func_body_(body), |
| 4049 func_name_(name), | |
| 4051 graph_zone_(new Zone(isolate->allocator(), ZONE_NAME)), | 4050 graph_zone_(new Zone(isolate->allocator(), ZONE_NAME)), |
| 4052 jsgraph_(new (graph_zone()) JSGraph( | 4051 jsgraph_(new (graph_zone()) JSGraph( |
| 4053 isolate, new (graph_zone()) Graph(graph_zone()), | 4052 isolate, new (graph_zone()) Graph(graph_zone()), |
| 4054 new (graph_zone()) CommonOperatorBuilder(graph_zone()), nullptr, | 4053 new (graph_zone()) CommonOperatorBuilder(graph_zone()), nullptr, |
| 4055 nullptr, new (graph_zone()) MachineOperatorBuilder( | 4054 nullptr, |
| 4056 graph_zone(), MachineType::PointerRepresentation(), | 4055 new (graph_zone()) MachineOperatorBuilder( |
| 4057 InstructionSelector::SupportedMachineOperatorFlags(), | 4056 graph_zone(), MachineType::PointerRepresentation(), |
| 4058 InstructionSelector::AlignmentRequirements()))), | 4057 InstructionSelector::SupportedMachineOperatorFlags(), |
| 4058 InstructionSelector::AlignmentRequirements()))), | |
| 4059 compilation_zone_(isolate->allocator(), ZONE_NAME), | 4059 compilation_zone_(isolate->allocator(), ZONE_NAME), |
| 4060 info_(function->name_length != 0 | 4060 info_(name, isolate, &compilation_zone_, |
| 4061 ? module_env->wire_bytes.GetNameOrNull(function) | |
| 4062 : CStrVector(GetTaggedFunctionName(function)), | |
| 4063 isolate, &compilation_zone_, | |
| 4064 Code::ComputeFlags(Code::WASM_FUNCTION)), | 4061 Code::ComputeFlags(Code::WASM_FUNCTION)), |
| 4065 job_(), | 4062 func_index_(index), |
| 4066 index_(index), | |
| 4067 ok_(true), | |
| 4068 protected_instructions_(&compilation_zone_) { | 4063 protected_instructions_(&compilation_zone_) { |
| 4069 // Create and cache this node in the main thread. | 4064 // Create and cache this node in the main thread. |
| 4070 jsgraph_->CEntryStubConstant(1); | 4065 jsgraph_->CEntryStubConstant(1); |
| 4071 } | 4066 } |
| 4072 | 4067 |
| 4073 void WasmCompilationUnit::ExecuteCompilation() { | 4068 void WasmCompilationUnit::ExecuteCompilation() { |
| 4074 // TODO(ahaas): The counters are not thread-safe at the moment. | 4069 // TODO(ahaas): The counters are not thread-safe at the moment. |
| 4075 // HistogramTimerScope wasm_compile_function_time_scope( | 4070 // HistogramTimerScope wasm_compile_function_time_scope( |
| 4076 // isolate_->counters()->wasm_compile_function_time()); | 4071 // isolate_->counters()->wasm_compile_function_time()); |
| 4077 if (FLAG_trace_wasm_compiler) { | 4072 if (FLAG_trace_wasm_compiler) { |
| 4078 OFStream os(stdout); | 4073 if (func_name_.start() == nullptr) { |
|
ahaas
2017/02/28 18:33:35
Shouldn't this be a !=?
Clemens Hammacher
2017/03/02 11:52:13
Indeed. Fixed.
| |
| 4079 os << "Compiling WASM function " | 4074 PrintF("Compiling WASM function '%.*s'\n\n", func_name_.length(), |
| 4080 << wasm::WasmFunctionName( | 4075 func_name_.start()); |
| 4081 function_, module_env_->wire_bytes.GetNameOrNull(function_)) | 4076 } else { |
| 4082 << std::endl; | 4077 PrintF("Compiling WASM function <unnamed>\n\n"); |
| 4083 os << std::endl; | 4078 } |
| 4084 } | 4079 } |
| 4085 | 4080 |
| 4086 double decode_ms = 0; | 4081 double decode_ms = 0; |
| 4087 size_t node_count = 0; | 4082 size_t node_count = 0; |
| 4088 | 4083 |
| 4089 std::unique_ptr<Zone> graph_zone(graph_zone_.release()); | 4084 std::unique_ptr<Zone> graph_zone(graph_zone_.release()); |
| 4090 SourcePositionTable* source_positions = BuildGraphForWasmFunction(&decode_ms); | 4085 SourcePositionTable* source_positions = BuildGraphForWasmFunction(&decode_ms); |
| 4091 | 4086 |
| 4092 if (graph_construction_result_.failed()) { | 4087 if (graph_construction_result_.failed()) { |
| 4093 ok_ = false; | 4088 ok_ = false; |
| 4094 return; | 4089 return; |
| 4095 } | 4090 } |
| 4096 | 4091 |
| 4097 base::ElapsedTimer pipeline_timer; | 4092 base::ElapsedTimer pipeline_timer; |
| 4098 if (FLAG_trace_wasm_decode_time) { | 4093 if (FLAG_trace_wasm_decode_time) { |
| 4099 node_count = jsgraph_->graph()->NodeCount(); | 4094 node_count = jsgraph_->graph()->NodeCount(); |
| 4100 pipeline_timer.Start(); | 4095 pipeline_timer.Start(); |
| 4101 } | 4096 } |
| 4102 | 4097 |
| 4103 // Run the compiler pipeline to generate machine code. | 4098 // Run the compiler pipeline to generate machine code. |
| 4104 CallDescriptor* descriptor = wasm::ModuleEnv::GetWasmCallDescriptor( | 4099 CallDescriptor* descriptor = wasm::ModuleEnv::GetWasmCallDescriptor( |
| 4105 &compilation_zone_, function_->sig); | 4100 &compilation_zone_, func_body_.sig); |
| 4106 if (jsgraph_->machine()->Is32()) { | 4101 if (jsgraph_->machine()->Is32()) { |
| 4107 descriptor = module_env_->module_env.GetI32WasmCallDescriptor( | 4102 descriptor = |
| 4108 &compilation_zone_, descriptor); | 4103 module_env_->GetI32WasmCallDescriptor(&compilation_zone_, descriptor); |
| 4109 } | 4104 } |
| 4110 job_.reset(Pipeline::NewWasmCompilationJob( | 4105 job_.reset(Pipeline::NewWasmCompilationJob( |
| 4111 &info_, jsgraph_, descriptor, source_positions, &protected_instructions_, | 4106 &info_, jsgraph_, descriptor, source_positions, &protected_instructions_, |
| 4112 module_env_->module_env.module->origin != wasm::kWasmOrigin)); | 4107 module_env_->module->origin != wasm::kWasmOrigin)); |
| 4113 ok_ = job_->ExecuteJob() == CompilationJob::SUCCEEDED; | 4108 ok_ = job_->ExecuteJob() == CompilationJob::SUCCEEDED; |
| 4114 // TODO(bradnelson): Improve histogram handling of size_t. | 4109 // TODO(bradnelson): Improve histogram handling of size_t. |
| 4115 // TODO(ahaas): The counters are not thread-safe at the moment. | 4110 // TODO(ahaas): The counters are not thread-safe at the moment. |
| 4116 // isolate_->counters()->wasm_compile_function_peak_memory_bytes() | 4111 // isolate_->counters()->wasm_compile_function_peak_memory_bytes() |
| 4117 // ->AddSample( | 4112 // ->AddSample( |
| 4118 // static_cast<int>(jsgraph->graph()->zone()->allocation_size())); | 4113 // static_cast<int>(jsgraph->graph()->zone()->allocation_size())); |
| 4119 | 4114 |
| 4120 if (FLAG_trace_wasm_decode_time) { | 4115 if (FLAG_trace_wasm_decode_time) { |
| 4121 double pipeline_ms = pipeline_timer.Elapsed().InMillisecondsF(); | 4116 double pipeline_ms = pipeline_timer.Elapsed().InMillisecondsF(); |
| 4122 PrintF( | 4117 PrintF( |
| 4123 "wasm-compilation phase 1 ok: %u bytes, %0.3f ms decode, %zu nodes, " | 4118 "wasm-compilation phase 1 ok: %u bytes, %0.3f ms decode, %zu nodes, " |
| 4124 "%0.3f ms pipeline\n", | 4119 "%0.3f ms pipeline\n", |
| 4125 function_->code_end_offset - function_->code_start_offset, decode_ms, | 4120 static_cast<unsigned>(func_body_.end - func_body_.start), decode_ms, |
| 4126 node_count, pipeline_ms); | 4121 node_count, pipeline_ms); |
| 4127 } | 4122 } |
| 4128 } | 4123 } |
| 4129 | 4124 |
| 4130 Handle<Code> WasmCompilationUnit::FinishCompilation() { | 4125 Handle<Code> WasmCompilationUnit::FinishCompilation( |
| 4126 wasm::ErrorThrower* thrower) { | |
| 4131 if (!ok_) { | 4127 if (!ok_) { |
| 4132 if (graph_construction_result_.failed()) { | 4128 if (graph_construction_result_.failed()) { |
| 4133 // Add the function as another context for the exception | 4129 // Add the function as another context for the exception |
| 4134 ScopedVector<char> buffer(128); | 4130 ScopedVector<char> buffer(128); |
| 4135 wasm::WasmName name = module_env_->wire_bytes.GetName(function_); | 4131 if (func_name_.start() == nullptr) { |
| 4136 SNPrintF(buffer, "Compiling WASM function #%d:%.*s failed:", | 4132 SNPrintF(buffer, |
| 4137 function_->func_index, name.length(), name.start()); | 4133 "Compiling WASM function #%d:%.*s failed:", func_index_, |
| 4138 thrower_->CompileFailed(buffer.start(), graph_construction_result_); | 4134 func_name_.length(), func_name_.start()); |
| 4135 } else { | |
| 4136 SNPrintF(buffer, "Compiling WASM function #%d failed:", func_index_); | |
| 4137 } | |
| 4138 thrower->CompileFailed(buffer.start(), graph_construction_result_); | |
| 4139 } | 4139 } |
| 4140 | 4140 |
| 4141 return Handle<Code>::null(); | 4141 return Handle<Code>::null(); |
| 4142 } | 4142 } |
| 4143 base::ElapsedTimer codegen_timer; | 4143 base::ElapsedTimer codegen_timer; |
| 4144 if (FLAG_trace_wasm_decode_time) { | 4144 if (FLAG_trace_wasm_decode_time) { |
| 4145 codegen_timer.Start(); | 4145 codegen_timer.Start(); |
| 4146 } | 4146 } |
| 4147 if (job_->FinalizeJob() != CompilationJob::SUCCEEDED) { | 4147 if (job_->FinalizeJob() != CompilationJob::SUCCEEDED) { |
| 4148 return Handle<Code>::null(); | 4148 return Handle<Code>::null(); |
| 4149 } | 4149 } |
| 4150 Handle<Code> code = info_.code(); | 4150 Handle<Code> code = info_.code(); |
| 4151 DCHECK(!code.is_null()); | 4151 DCHECK(!code.is_null()); |
| 4152 | 4152 |
| 4153 if (isolate_->logger()->is_logging_code_events() || | 4153 if (isolate_->logger()->is_logging_code_events() || |
| 4154 isolate_->is_profiling()) { | 4154 isolate_->is_profiling()) { |
| 4155 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, isolate_, code, | 4155 RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, isolate_, code, |
| 4156 "WASM_function", function_->func_index, | 4156 "WASM_function", func_index_, |
| 4157 wasm::WasmName("module"), | 4157 wasm::WasmName("module"), func_name_); |
| 4158 module_env_->wire_bytes.GetName(function_)); | |
| 4159 } | 4158 } |
| 4160 | 4159 |
| 4161 if (FLAG_trace_wasm_decode_time) { | 4160 if (FLAG_trace_wasm_decode_time) { |
| 4162 double codegen_ms = codegen_timer.Elapsed().InMillisecondsF(); | 4161 double codegen_ms = codegen_timer.Elapsed().InMillisecondsF(); |
| 4163 PrintF("wasm-code-generation ok: %u bytes, %0.3f ms code generation\n", | 4162 PrintF("wasm-code-generation ok: %u bytes, %0.3f ms code generation\n", |
| 4164 function_->code_end_offset - function_->code_start_offset, | 4163 static_cast<unsigned>(func_body_.end - func_body_.start), |
| 4165 codegen_ms); | 4164 codegen_ms); |
| 4166 } | 4165 } |
| 4167 | 4166 |
| 4168 return code; | 4167 return code; |
| 4169 } | 4168 } |
| 4170 | 4169 |
| 4170 // static | |
| 4171 Handle<Code> WasmCompilationUnit::CompileWasmFunction( | |
| 4172 wasm::ErrorThrower* thrower, Isolate* isolate, | |
| 4173 wasm::ModuleBytesEnv* module_env, const wasm::WasmFunction* function) { | |
| 4174 WasmCompilationUnit unit(isolate, module_env, function); | |
| 4175 unit.ExecuteCompilation(); | |
| 4176 return unit.FinishCompilation(thrower); | |
| 4177 } | |
| 4178 | |
| 4171 } // namespace compiler | 4179 } // namespace compiler |
| 4172 } // namespace internal | 4180 } // namespace internal |
| 4173 } // namespace v8 | 4181 } // namespace v8 |
| OLD | NEW |