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 |