| Index: src/compiler/wasm-compiler.cc
|
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
|
| index 1d547113d270d6536bf719d10750dd6e8467b4f5..2db46c38fd0fe207282ca6fe859c17ad27438b76 100644
|
| --- a/src/compiler/wasm-compiler.cc
|
| +++ b/src/compiler/wasm-compiler.cc
|
| @@ -1874,7 +1874,8 @@ Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) {
|
| }
|
|
|
| Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args,
|
| - wasm::WasmCodePosition position) {
|
| + wasm::WasmCodePosition position,
|
| + bool internal) {
|
| const size_t params = sig->parameter_count();
|
| const size_t extra = 2; // effect and control inputs.
|
| const size_t count = 1 + params + extra;
|
| @@ -1887,7 +1888,7 @@ Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args,
|
| args[params + 2] = *control_;
|
|
|
| CallDescriptor* descriptor =
|
| - wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig);
|
| + wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig, internal);
|
| const Operator* op = jsgraph()->common()->Call(descriptor);
|
| Node* call = graph()->NewNode(op, static_cast<int>(count), args);
|
| SetSourcePosition(call, position);
|
| @@ -1900,22 +1901,21 @@ Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args,
|
| wasm::WasmCodePosition position) {
|
| DCHECK_NULL(args[0]);
|
|
|
| - // Add code object as constant.
|
| - args[0] = HeapConstant(module_->GetCodeOrPlaceholder(index));
|
| + args[0] =
|
| + jsgraph()->RelocatableInt32Constant(index, RelocInfo::WASM_DIRECT_CALL);
|
| wasm::FunctionSig* sig = module_->GetFunctionSignature(index);
|
|
|
| - return BuildWasmCall(sig, args, position);
|
| + return BuildWasmCall(sig, args, position, true);
|
| }
|
|
|
| Node* WasmGraphBuilder::CallImport(uint32_t index, Node** args,
|
| wasm::WasmCodePosition position) {
|
| DCHECK_NULL(args[0]);
|
|
|
| - // Add code object as constant.
|
| - args[0] = HeapConstant(module_->GetImportCode(index));
|
| + args[0] =
|
| + jsgraph()->RelocatableInt32Constant(index, RelocInfo::WASM_IMPORT_CALL);
|
| wasm::FunctionSig* sig = module_->GetImportSignature(index);
|
| -
|
| - return BuildWasmCall(sig, args, position);
|
| + return BuildWasmCall(sig, args, position, true);
|
| }
|
|
|
| Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args,
|
| @@ -3302,6 +3302,43 @@ Handle<Code> WasmCompilationUnit::FinishCompilation() {
|
| return code;
|
| }
|
|
|
| +void Link(Isolate* isolate, std::vector<Handle<Code>>& unlinked_functions,
|
| + const std::vector<Handle<Code>>& functions_to_link, int mode_mask) {
|
| + // On architectures supporting constant pools, if a function A calls another
|
| + // function B in a number of places, then the same slot in the constant pool
|
| + // would be used for the call to B. We can't update eagerly the location,
|
| + // because that would mean that the next time we look at the location to find
|
| + // the index of the function being called, we'd find the actual address
|
| + // instead. So we keep a worklist. To keep the code simple, we maintain the
|
| + // worklist even on architectures that do not support constant pools.
|
| +
|
| + std::vector<std::pair<RelocInfo, Address>> worklist;
|
| + {
|
| + DisallowHeapAllocation no_gc_scope;
|
| + RelocInfoWriter writer;
|
| + for (Handle<Code> code : unlinked_functions) {
|
| + AllowDeferredHandleDereference embedding_raw_address;
|
| + for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
|
| + size_t f_index = it.rinfo()->wasm_function_index();
|
| + Handle<Code> to_link = functions_to_link[f_index];
|
| + worklist.push_back(
|
| + std::make_pair(*it.rinfo(), to_link->instruction_start()));
|
| + writer.Reposition(it.mode_pos(), it.rinfo()->pc());
|
| + writer.WriteModeNoAdvance(RelocInfo::CODE_TARGET);
|
| + }
|
| + for (auto pair : worklist) {
|
| + pair.first.set_target_address(pair.second, SKIP_WRITE_BARRIER,
|
| + SKIP_ICACHE_FLUSH);
|
| + }
|
| + if (!worklist.empty()) {
|
| + worklist.clear();
|
| + Assembler::FlushICache(isolate, code->instruction_start(),
|
| + code->instruction_size());
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|