Chromium Code Reviews| Index: src/compiler/wasm-compiler.cc |
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc |
| index 7270ddd24848854d9e42a020404ed04bdcca7ed4..7ac90362dd35b6ad0b7edaae380a7ee7ab673a5b 100644 |
| --- a/src/compiler/wasm-compiler.cc |
| +++ b/src/compiler/wasm-compiler.cc |
| @@ -1908,7 +1908,8 @@ Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, |
| 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); |
| @@ -3309,6 +3310,36 @@ Handle<Code> WasmCompilationUnit::FinishCompilation() { |
| return code; |
| } |
| +void Link(Isolate* isolate, std::vector<Handle<Code>>& functions) { |
|
ahaas
2016/06/02 13:48:27
What's the reason why you move the code for linkin
Mircea Trofin
2016/06/02 14:46:21
I didn't realize that was the separation. I though
|
| + // 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; |
| + for (Handle<Code> code : functions) { |
| + int mode_mask = RelocInfo::kWasmDirectCallMask; |
| + 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> code = functions[f_index]; |
| + worklist.push_back( |
| + std::make_pair(*it.rinfo(), code->instruction_start())); |
| + } |
| + 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 |