| 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/elapsed-timer.h" | 9 #include "src/base/platform/elapsed-timer.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| (...skipping 1856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1867 CallDescriptor* desc = | 1867 CallDescriptor* desc = |
| 1868 Linkage::GetSimplifiedCDescriptor(jsgraph()->zone(), sig); | 1868 Linkage::GetSimplifiedCDescriptor(jsgraph()->zone(), sig); |
| 1869 | 1869 |
| 1870 const Operator* op = jsgraph()->common()->Call(desc); | 1870 const Operator* op = jsgraph()->common()->Call(desc); |
| 1871 Node* call = graph()->NewNode(op, static_cast<int>(count), args); | 1871 Node* call = graph()->NewNode(op, static_cast<int>(count), args); |
| 1872 *effect_ = call; | 1872 *effect_ = call; |
| 1873 return call; | 1873 return call; |
| 1874 } | 1874 } |
| 1875 | 1875 |
| 1876 Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args, | 1876 Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args, |
| 1877 wasm::WasmCodePosition position) { | 1877 wasm::WasmCodePosition position, |
| 1878 bool internal) { |
| 1878 const size_t params = sig->parameter_count(); | 1879 const size_t params = sig->parameter_count(); |
| 1879 const size_t extra = 2; // effect and control inputs. | 1880 const size_t extra = 2; // effect and control inputs. |
| 1880 const size_t count = 1 + params + extra; | 1881 const size_t count = 1 + params + extra; |
| 1881 | 1882 |
| 1882 // Reallocate the buffer to make space for extra inputs. | 1883 // Reallocate the buffer to make space for extra inputs. |
| 1883 args = Realloc(args, 1 + params, count); | 1884 args = Realloc(args, 1 + params, count); |
| 1884 | 1885 |
| 1885 // Add effect and control inputs. | 1886 // Add effect and control inputs. |
| 1886 args[params + 1] = *effect_; | 1887 args[params + 1] = *effect_; |
| 1887 args[params + 2] = *control_; | 1888 args[params + 2] = *control_; |
| 1888 | 1889 |
| 1889 CallDescriptor* descriptor = | 1890 CallDescriptor* descriptor = |
| 1890 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); | 1891 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig, internal); |
| 1891 const Operator* op = jsgraph()->common()->Call(descriptor); | 1892 const Operator* op = jsgraph()->common()->Call(descriptor); |
| 1892 Node* call = graph()->NewNode(op, static_cast<int>(count), args); | 1893 Node* call = graph()->NewNode(op, static_cast<int>(count), args); |
| 1893 SetSourcePosition(call, position); | 1894 SetSourcePosition(call, position); |
| 1894 | 1895 |
| 1895 *effect_ = call; | 1896 *effect_ = call; |
| 1896 return call; | 1897 return call; |
| 1897 } | 1898 } |
| 1898 | 1899 |
| 1899 Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, | 1900 Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, |
| 1900 wasm::WasmCodePosition position) { | 1901 wasm::WasmCodePosition position) { |
| 1901 DCHECK_NULL(args[0]); | 1902 DCHECK_NULL(args[0]); |
| 1902 | 1903 |
| 1903 // Add code object as constant. | 1904 args[0] = |
| 1904 args[0] = HeapConstant(module_->GetCodeOrPlaceholder(index)); | 1905 jsgraph()->RelocatableInt32Constant(index, RelocInfo::WASM_DIRECT_CALL); |
| 1905 wasm::FunctionSig* sig = module_->GetFunctionSignature(index); | 1906 wasm::FunctionSig* sig = module_->GetFunctionSignature(index); |
| 1906 | 1907 |
| 1907 return BuildWasmCall(sig, args, position); | 1908 return BuildWasmCall(sig, args, position, true); |
| 1908 } | 1909 } |
| 1909 | 1910 |
| 1910 Node* WasmGraphBuilder::CallImport(uint32_t index, Node** args, | 1911 Node* WasmGraphBuilder::CallImport(uint32_t index, Node** args, |
| 1911 wasm::WasmCodePosition position) { | 1912 wasm::WasmCodePosition position) { |
| 1912 DCHECK_NULL(args[0]); | 1913 DCHECK_NULL(args[0]); |
| 1913 | 1914 |
| 1914 // Add code object as constant. | 1915 args[0] = |
| 1915 args[0] = HeapConstant(module_->GetImportCode(index)); | 1916 jsgraph()->RelocatableInt32Constant(index, RelocInfo::WASM_IMPORT_CALL); |
| 1916 wasm::FunctionSig* sig = module_->GetImportSignature(index); | 1917 wasm::FunctionSig* sig = module_->GetImportSignature(index); |
| 1917 | 1918 return BuildWasmCall(sig, args, position, true); |
| 1918 return BuildWasmCall(sig, args, position); | |
| 1919 } | 1919 } |
| 1920 | 1920 |
| 1921 Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args, | 1921 Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args, |
| 1922 wasm::WasmCodePosition position) { | 1922 wasm::WasmCodePosition position) { |
| 1923 DCHECK_NOT_NULL(args[0]); | 1923 DCHECK_NOT_NULL(args[0]); |
| 1924 DCHECK(module_ && module_->instance); | 1924 DCHECK(module_ && module_->instance); |
| 1925 | 1925 |
| 1926 MachineOperatorBuilder* machine = jsgraph()->machine(); | 1926 MachineOperatorBuilder* machine = jsgraph()->machine(); |
| 1927 | 1927 |
| 1928 // Compute the code object by loading it from the function table. | 1928 // Compute the code object by loading it from the function table. |
| (...skipping 1366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3295 double compile_ms = compile_timer.Elapsed().InMillisecondsF(); | 3295 double compile_ms = compile_timer.Elapsed().InMillisecondsF(); |
| 3296 PrintF("wasm-code-generation ok: %d bytes, %0.3f ms code generation\n", | 3296 PrintF("wasm-code-generation ok: %d bytes, %0.3f ms code generation\n", |
| 3297 static_cast<int>(function_->code_end_offset - | 3297 static_cast<int>(function_->code_end_offset - |
| 3298 function_->code_start_offset), | 3298 function_->code_start_offset), |
| 3299 compile_ms); | 3299 compile_ms); |
| 3300 } | 3300 } |
| 3301 | 3301 |
| 3302 return code; | 3302 return code; |
| 3303 } | 3303 } |
| 3304 | 3304 |
| 3305 void Link(Isolate* isolate, std::vector<Handle<Code>>& unlinked_functions, |
| 3306 const std::vector<Handle<Code>>& functions_to_link, int mode_mask) { |
| 3307 // On architectures supporting constant pools, if a function A calls another |
| 3308 // function B in a number of places, then the same slot in the constant pool |
| 3309 // would be used for the call to B. We can't update eagerly the location, |
| 3310 // because that would mean that the next time we look at the location to find |
| 3311 // the index of the function being called, we'd find the actual address |
| 3312 // instead. So we keep a worklist. To keep the code simple, we maintain the |
| 3313 // worklist even on architectures that do not support constant pools. |
| 3314 |
| 3315 std::vector<std::pair<RelocInfo, Address>> worklist; |
| 3316 { |
| 3317 DisallowHeapAllocation no_gc_scope; |
| 3318 RelocInfoWriter writer; |
| 3319 for (Handle<Code> code : unlinked_functions) { |
| 3320 AllowDeferredHandleDereference embedding_raw_address; |
| 3321 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { |
| 3322 size_t f_index = it.rinfo()->wasm_function_index(); |
| 3323 Handle<Code> to_link = functions_to_link[f_index]; |
| 3324 worklist.push_back( |
| 3325 std::make_pair(*it.rinfo(), to_link->instruction_start())); |
| 3326 writer.Reposition(it.mode_pos(), it.rinfo()->pc()); |
| 3327 writer.WriteModeNoAdvance(RelocInfo::CODE_TARGET); |
| 3328 } |
| 3329 for (auto pair : worklist) { |
| 3330 pair.first.set_target_address(pair.second, SKIP_WRITE_BARRIER, |
| 3331 SKIP_ICACHE_FLUSH); |
| 3332 } |
| 3333 if (!worklist.empty()) { |
| 3334 worklist.clear(); |
| 3335 Assembler::FlushICache(isolate, code->instruction_start(), |
| 3336 code->instruction_size()); |
| 3337 } |
| 3338 } |
| 3339 } |
| 3340 } |
| 3341 |
| 3305 } // namespace compiler | 3342 } // namespace compiler |
| 3306 } // namespace internal | 3343 } // namespace internal |
| 3307 } // namespace v8 | 3344 } // namespace v8 |
| OLD | NEW |