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 "src/isolate-inl.h" | 7 #include "src/isolate-inl.h" |
8 | 8 |
9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
10 | 10 |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "src/compiler/machine-operator.h" | 22 #include "src/compiler/machine-operator.h" |
23 #include "src/compiler/node-matchers.h" | 23 #include "src/compiler/node-matchers.h" |
24 #include "src/compiler/pipeline.h" | 24 #include "src/compiler/pipeline.h" |
25 #include "src/compiler/simplified-lowering.h" | 25 #include "src/compiler/simplified-lowering.h" |
26 #include "src/compiler/simplified-operator.h" | 26 #include "src/compiler/simplified-operator.h" |
27 #include "src/compiler/source-position.h" | 27 #include "src/compiler/source-position.h" |
28 #include "src/compiler/typer.h" | 28 #include "src/compiler/typer.h" |
29 | 29 |
30 #include "src/code-factory.h" | 30 #include "src/code-factory.h" |
31 #include "src/code-stubs.h" | 31 #include "src/code-stubs.h" |
| 32 #include "src/factory.h" |
| 33 #include "src/log-inl.h" |
| 34 #include "src/profiler/cpu-profiler.h" |
32 | 35 |
33 #include "src/wasm/ast-decoder.h" | 36 #include "src/wasm/ast-decoder.h" |
34 #include "src/wasm/wasm-module.h" | 37 #include "src/wasm/wasm-module.h" |
35 #include "src/wasm/wasm-opcodes.h" | 38 #include "src/wasm/wasm-opcodes.h" |
36 | 39 |
37 // TODO(titzer): pull WASM_64 up to a common header. | 40 // TODO(titzer): pull WASM_64 up to a common header. |
38 #if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64 | 41 #if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64 |
39 #define WASM_64 1 | 42 #define WASM_64 1 |
40 #else | 43 #else |
41 #define WASM_64 0 | 44 #define WASM_64 0 |
(...skipping 1813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1855 | 1858 |
1856 Node* WasmGraphBuilder::String(const char* string) { | 1859 Node* WasmGraphBuilder::String(const char* string) { |
1857 return jsgraph()->Constant( | 1860 return jsgraph()->Constant( |
1858 jsgraph()->isolate()->factory()->NewStringFromAsciiChecked(string)); | 1861 jsgraph()->isolate()->factory()->NewStringFromAsciiChecked(string)); |
1859 } | 1862 } |
1860 | 1863 |
1861 | 1864 |
1862 Graph* WasmGraphBuilder::graph() { return jsgraph()->graph(); } | 1865 Graph* WasmGraphBuilder::graph() { return jsgraph()->graph(); } |
1863 | 1866 |
1864 | 1867 |
| 1868 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, |
| 1869 CompilationInfo* info, |
| 1870 const char* message, uint32_t index, |
| 1871 const char* func_name) { |
| 1872 Isolate* isolate = info->isolate(); |
| 1873 if (isolate->logger()->is_logging_code_events() || |
| 1874 isolate->cpu_profiler()->is_profiling()) { |
| 1875 ScopedVector<char> buffer(128); |
| 1876 SNPrintF(buffer, "%s#%d:%s", message, index, func_name); |
| 1877 Handle<String> name_str = |
| 1878 isolate->factory()->NewStringFromAsciiChecked(buffer.start()); |
| 1879 Handle<String> script_str = |
| 1880 isolate->factory()->NewStringFromAsciiChecked("(WASM)"); |
| 1881 Handle<Code> code = info->code(); |
| 1882 Handle<SharedFunctionInfo> shared = |
| 1883 isolate->factory()->NewSharedFunctionInfo(name_str, code, false); |
| 1884 PROFILE(isolate, |
| 1885 CodeCreateEvent(tag, *code, *shared, info, *script_str, 0, 0)); |
| 1886 } |
| 1887 } |
| 1888 |
| 1889 |
1865 Handle<JSFunction> CompileJSToWasmWrapper( | 1890 Handle<JSFunction> CompileJSToWasmWrapper( |
1866 Isolate* isolate, wasm::ModuleEnv* module, Handle<String> name, | 1891 Isolate* isolate, wasm::ModuleEnv* module, Handle<String> name, |
1867 Handle<Code> wasm_code, Handle<JSObject> module_object, uint32_t index) { | 1892 Handle<Code> wasm_code, Handle<JSObject> module_object, uint32_t index) { |
1868 wasm::WasmFunction* func = &module->module->functions->at(index); | 1893 wasm::WasmFunction* func = &module->module->functions->at(index); |
1869 | 1894 |
1870 //---------------------------------------------------------------------------- | 1895 //---------------------------------------------------------------------------- |
1871 // Create the JSFunction object. | 1896 // Create the JSFunction object. |
1872 //---------------------------------------------------------------------------- | 1897 //---------------------------------------------------------------------------- |
1873 Handle<SharedFunctionInfo> shared = | 1898 Handle<SharedFunctionInfo> shared = |
1874 isolate->factory()->NewSharedFunctionInfo(name, wasm_code, false); | 1899 isolate->factory()->NewSharedFunctionInfo(name, wasm_code, false); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1926 // Schedule and compile to machine code. | 1951 // Schedule and compile to machine code. |
1927 int params = static_cast<int>( | 1952 int params = static_cast<int>( |
1928 module->GetFunctionSignature(index)->parameter_count()); | 1953 module->GetFunctionSignature(index)->parameter_count()); |
1929 CallDescriptor* incoming = Linkage::GetJSCallDescriptor( | 1954 CallDescriptor* incoming = Linkage::GetJSCallDescriptor( |
1930 &zone, false, params + 1, CallDescriptor::kNoFlags); | 1955 &zone, false, params + 1, CallDescriptor::kNoFlags); |
1931 // TODO(titzer): this is technically a WASM wrapper, not a wasm function. | 1956 // TODO(titzer): this is technically a WASM wrapper, not a wasm function. |
1932 Code::Flags flags = Code::ComputeFlags(Code::WASM_FUNCTION); | 1957 Code::Flags flags = Code::ComputeFlags(Code::WASM_FUNCTION); |
1933 CompilationInfo info("js-to-wasm", isolate, &zone, flags); | 1958 CompilationInfo info("js-to-wasm", isolate, &zone, flags); |
1934 Handle<Code> code = | 1959 Handle<Code> code = |
1935 Pipeline::GenerateCodeForTesting(&info, incoming, &graph, nullptr); | 1960 Pipeline::GenerateCodeForTesting(&info, incoming, &graph, nullptr); |
1936 | 1961 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, "js-to-wasm", index, |
1937 #ifdef ENABLE_DISASSEMBLER | 1962 module->module->GetName(func->name_offset)); |
1938 // Disassemble the wrapper code for debugging. | |
1939 if (!code.is_null() && FLAG_print_opt_code) { | |
1940 Vector<char> buffer; | |
1941 const char* name = ""; | |
1942 if (func->name_offset > 0) { | |
1943 const byte* ptr = module->module->module_start + func->name_offset; | |
1944 name = reinterpret_cast<const char*>(ptr); | |
1945 } | |
1946 SNPrintF(buffer, "JS->WASM function wrapper #%d:%s", index, name); | |
1947 OFStream os(stdout); | |
1948 code->Disassemble(buffer.start(), os); | |
1949 } | |
1950 #endif | |
1951 // Set the JSFunction's machine code. | 1963 // Set the JSFunction's machine code. |
1952 function->set_code(*code); | 1964 function->set_code(*code); |
1953 } | 1965 } |
1954 return function; | 1966 return function; |
1955 } | 1967 } |
1956 | 1968 |
1957 | 1969 |
1958 Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module, | 1970 Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module, |
1959 Handle<JSFunction> function, | 1971 Handle<JSFunction> function, |
1960 uint32_t index) { | 1972 uint32_t index) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2001 os << AsRPO(graph); | 2013 os << AsRPO(graph); |
2002 } | 2014 } |
2003 | 2015 |
2004 // Schedule and compile to machine code. | 2016 // Schedule and compile to machine code. |
2005 CallDescriptor* incoming = module->GetWasmCallDescriptor(&zone, func->sig); | 2017 CallDescriptor* incoming = module->GetWasmCallDescriptor(&zone, func->sig); |
2006 // TODO(titzer): this is technically a WASM wrapper, not a wasm function. | 2018 // TODO(titzer): this is technically a WASM wrapper, not a wasm function. |
2007 Code::Flags flags = Code::ComputeFlags(Code::WASM_FUNCTION); | 2019 Code::Flags flags = Code::ComputeFlags(Code::WASM_FUNCTION); |
2008 CompilationInfo info("wasm-to-js", isolate, &zone, flags); | 2020 CompilationInfo info("wasm-to-js", isolate, &zone, flags); |
2009 code = Pipeline::GenerateCodeForTesting(&info, incoming, &graph, nullptr); | 2021 code = Pipeline::GenerateCodeForTesting(&info, incoming, &graph, nullptr); |
2010 | 2022 |
2011 #ifdef ENABLE_DISASSEMBLER | 2023 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, "wasm-to-js", index, |
2012 // Disassemble the wrapper code for debugging. | 2024 module->module->GetName(func->name_offset)); |
2013 if (!code.is_null() && FLAG_print_opt_code) { | |
2014 Vector<char> buffer; | |
2015 const char* name = ""; | |
2016 if (func->name_offset > 0) { | |
2017 const byte* ptr = module->module->module_start + func->name_offset; | |
2018 name = reinterpret_cast<const char*>(ptr); | |
2019 } | |
2020 SNPrintF(buffer, "WASM->JS function wrapper #%d:%s", index, name); | |
2021 OFStream os(stdout); | |
2022 code->Disassemble(buffer.start(), os); | |
2023 } | |
2024 #endif | |
2025 } | 2025 } |
2026 return code; | 2026 return code; |
2027 } | 2027 } |
2028 | 2028 |
2029 | 2029 |
2030 // Helper function to compile a single function. | 2030 // Helper function to compile a single function. |
2031 Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, | 2031 Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, |
2032 wasm::ModuleEnv* module_env, | 2032 wasm::ModuleEnv* module_env, |
2033 const wasm::WasmFunction& function, | 2033 const wasm::WasmFunction& function, |
2034 int index) { | 2034 int index) { |
(...skipping 30 matching lines...) Expand all Loading... |
2065 module_env->module->module_start, // -- | 2065 module_env->module->module_start, // -- |
2066 module_env->module->module_start + function.code_start_offset, // -- | 2066 module_env->module->module_start + function.code_start_offset, // -- |
2067 module_env->module->module_start + function.code_end_offset); // -- | 2067 module_env->module->module_start + function.code_end_offset); // -- |
2068 | 2068 |
2069 if (result.failed()) { | 2069 if (result.failed()) { |
2070 if (FLAG_trace_wasm_compiler) { | 2070 if (FLAG_trace_wasm_compiler) { |
2071 OFStream os(stdout); | 2071 OFStream os(stdout); |
2072 os << "Compilation failed: " << result << std::endl; | 2072 os << "Compilation failed: " << result << std::endl; |
2073 } | 2073 } |
2074 // Add the function as another context for the exception | 2074 // Add the function as another context for the exception |
2075 Vector<char> buffer; | 2075 ScopedVector<char> buffer(128); |
2076 SNPrintF(buffer, "Compiling WASM function #%d:%s failed:", index, | 2076 SNPrintF(buffer, "Compiling WASM function #%d:%s failed:", index, |
2077 module_env->module->GetName(function.name_offset)); | 2077 module_env->module->GetName(function.name_offset)); |
2078 thrower.Failed(buffer.start(), result); | 2078 thrower.Failed(buffer.start(), result); |
2079 return Handle<Code>::null(); | 2079 return Handle<Code>::null(); |
2080 } | 2080 } |
2081 | 2081 |
2082 // Run the compiler pipeline to generate machine code. | 2082 // Run the compiler pipeline to generate machine code. |
2083 CallDescriptor* descriptor = const_cast<CallDescriptor*>( | 2083 CallDescriptor* descriptor = const_cast<CallDescriptor*>( |
2084 module_env->GetWasmCallDescriptor(&zone, function.sig)); | 2084 module_env->GetWasmCallDescriptor(&zone, function.sig)); |
2085 Code::Flags flags = Code::ComputeFlags(Code::WASM_FUNCTION); | 2085 Code::Flags flags = Code::ComputeFlags(Code::WASM_FUNCTION); |
2086 CompilationInfo info("wasm", isolate, &zone, flags); | 2086 // add flags here if a meaningful name is helpful for debugging. |
| 2087 bool debugging = |
| 2088 FLAG_print_opt_code || FLAG_trace_turbo || FLAG_trace_turbo_graph; |
| 2089 const char* func_name = "wasm"; |
| 2090 Vector<char> buffer; |
| 2091 if (debugging) { |
| 2092 buffer = Vector<char>::New(128); |
| 2093 SNPrintF(buffer, "WASM_function_#%d:%s", index, |
| 2094 module_env->module->GetName(function.name_offset)); |
| 2095 func_name = buffer.start(); |
| 2096 } |
| 2097 CompilationInfo info(func_name, isolate, &zone, flags); |
2087 Handle<Code> code = | 2098 Handle<Code> code = |
2088 Pipeline::GenerateCodeForTesting(&info, descriptor, &graph); | 2099 Pipeline::GenerateCodeForTesting(&info, descriptor, &graph); |
| 2100 if (debugging) { |
| 2101 buffer.Dispose(); |
| 2102 } |
| 2103 if (!code.is_null()) { |
| 2104 RecordFunctionCompilation( |
| 2105 Logger::FUNCTION_TAG, &info, "WASM_function", index, |
| 2106 module_env->module->GetName(function.name_offset)); |
| 2107 } |
2089 | 2108 |
2090 #ifdef ENABLE_DISASSEMBLER | |
2091 // Disassemble the code for debugging. | |
2092 if (!code.is_null() && FLAG_print_opt_code) { | |
2093 Vector<char> buffer; | |
2094 const char* name = ""; | |
2095 if (function.name_offset > 0) { | |
2096 const byte* ptr = module_env->module->module_start + function.name_offset; | |
2097 name = reinterpret_cast<const char*>(ptr); | |
2098 } | |
2099 SNPrintF(buffer, "WASM function #%d:%s", index, name); | |
2100 OFStream os(stdout); | |
2101 code->Disassemble(buffer.start(), os); | |
2102 } | |
2103 #endif | |
2104 return code; | 2109 return code; |
2105 } | 2110 } |
2106 | 2111 |
2107 | 2112 |
2108 } // namespace compiler | 2113 } // namespace compiler |
2109 } // namespace internal | 2114 } // namespace internal |
2110 } // namespace v8 | 2115 } // namespace v8 |
OLD | NEW |