Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1408)

Unified Diff: src/wasm/wasm-module.cc

Issue 2627613002: [wasm] Refactor call site patching (Closed)
Patch Set: Fix minor bug on arm64 Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/wasm/leb-helper.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/wasm/wasm-module.cc
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc
index b162704cdeb27356541d91ebd55e43d998aaf490..84e99e8e627c447619841d0a02b483320d766388 100644
--- a/src/wasm/wasm-module.cc
+++ b/src/wasm/wasm-module.cc
@@ -17,6 +17,7 @@
#include "src/v8.h"
#include "src/wasm/function-body-decoder.h"
+#include "src/wasm/leb-helper.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-limits.h"
@@ -445,36 +446,80 @@ void CompileSequentially(Isolate* isolate, ModuleBytesEnv* module_env,
}
}
-void PatchDirectCalls(Handle<FixedArray> old_functions,
- Handle<FixedArray> new_functions, int start) {
- DCHECK_EQ(new_functions->length(), old_functions->length());
+int ExtractDirectCallIndex(const byte* pc) {
titzer 2017/01/11 18:02:48 Can you use a decoder for this? That way we don't
Clemens Hammacher 2017/01/11 18:28:43 Done. FYI: I have to write it as wasm::Decoder, b
+ DCHECK_EQ(static_cast<int>(kExprCallFunction), static_cast<int>(*pc));
+ uint32_t call_idx = LEBHelper::read_u32v(pc + 1);
+ DCHECK_GE(kMaxInt, call_idx);
+ return static_cast<int>(call_idx);
+}
+void PatchDirectCalls(Handle<FixedArray> new_functions,
+ Handle<WasmCompiledModule> compiled_module,
+ WasmModule* module, int start) {
DisallowHeapAllocation no_gc;
- std::map<Code*, Code*> old_to_new_code;
- for (int i = 0; i < new_functions->length(); ++i) {
- old_to_new_code.insert(std::make_pair(Code::cast(old_functions->get(i)),
- Code::cast(new_functions->get(i))));
- }
- int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
AllowDeferredHandleDereference embedding_raw_address;
- for (int i = start; i < new_functions->length(); ++i) {
+ SeqOneByteString* module_bytes = compiled_module->module_bytes();
+ std::vector<WasmFunction>* wasm_functions =
+ &compiled_module->module()->functions;
+ DCHECK_EQ(wasm_functions->size() +
+ compiled_module->module()->num_exported_functions,
+ new_functions->length());
+ DCHECK_EQ(start, compiled_module->module()->num_imported_functions);
+
+ int num_wasm_functions = static_cast<int>(wasm_functions->size());
+ for (int i = start; i < num_wasm_functions; ++i) {
Code* wasm_function = Code::cast(new_functions->get(i));
- for (RelocIterator it(wasm_function, mode_mask); !it.done(); it.next()) {
- Code* old_code =
- Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
- if (old_code->kind() == Code::WASM_TO_JS_FUNCTION ||
- old_code->kind() == Code::WASM_FUNCTION) {
- auto found = old_to_new_code.find(old_code);
- DCHECK(found != old_to_new_code.end());
- Code* new_code = found->second;
- if (new_code != old_code) {
- it.rinfo()->set_target_address(new_code->instruction_start(),
- UPDATE_WRITE_BARRIER,
- SKIP_ICACHE_FLUSH);
- }
- }
+ DCHECK(wasm_function->kind() == Code::WASM_FUNCTION);
+ SourcePositionTableIterator source_pos_iterator(
+ wasm_function->source_position_table());
+ const byte* func_bytes =
+ module_bytes->GetChars() +
+ compiled_module->module()->functions[i].code_start_offset;
+ for (RelocIterator it(wasm_function, RelocInfo::kCodeTargetMask);
+ !it.done(); it.next()) {
+ Code::Kind kind =
+ Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind();
+ if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION)
+ continue;
+ size_t offset_l = it.rinfo()->pc() - wasm_function->instruction_start();
+ DCHECK_GE(kMaxInt, offset_l);
+ int offset = static_cast<int>(offset_l);
+ DCHECK(!source_pos_iterator.done());
+ int byte_pos;
+ do {
+ byte_pos = source_pos_iterator.source_position().ScriptOffset();
+ source_pos_iterator.Advance();
+ } while (!source_pos_iterator.done() &&
+ source_pos_iterator.code_offset() <= offset);
+ int called_func_index = ExtractDirectCallIndex(func_bytes + byte_pos);
+ Code* new_code = Code::cast(new_functions->get(called_func_index));
+ it.rinfo()->set_target_address(new_code->instruction_start(),
+ UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
}
}
+ int func_index = num_wasm_functions;
+ for (auto exp : module->export_table) {
+ if (exp.kind != kExternalFunction) continue;
+ Code* export_wrapper = Code::cast(new_functions->get(func_index));
+ DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind());
+ // There must be exactly one call to WASM_FUNCTION or WASM_TO_JS_FUNCTION.
+ int num_wasm_calls = 0;
+ for (RelocIterator it(export_wrapper, RelocInfo::kCodeTargetMask);
+ !it.done(); it.next()) {
+ Code::Kind kind =
+ Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind();
+ if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION)
+ continue;
+ ++num_wasm_calls;
+ Code* new_code = Code::cast(new_functions->get(exp.index));
+ DCHECK_EQ(kind, new_code->kind());
+ it.rinfo()->set_target_address(new_code->instruction_start(),
+ UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
+ }
+ DCHECK_EQ(1, num_wasm_calls);
+ func_index++;
+ }
+ DCHECK_EQ(new_functions->length(), func_index);
}
static void ResetCompiledModule(Isolate* isolate, WasmInstanceObject* owner,
@@ -1299,7 +1344,8 @@ class WasmInstanceBuilder {
if (num_imported_functions > 0 || !owner.is_null()) {
// If the code was cloned, or new imports were compiled, patch.
- PatchDirectCalls(old_code_table, code_table, num_imported_functions);
+ PatchDirectCalls(code_table, compiled_module_, module_,
+ num_imported_functions);
}
FlushICache(isolate_, code_table);
« no previous file with comments | « src/wasm/leb-helper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698