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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/wasm/leb-helper.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <memory> 5 #include <memory>
6 6
7 #include "src/assembler-inl.h" 7 #include "src/assembler-inl.h"
8 #include "src/base/adapters.h" 8 #include "src/base/adapters.h"
9 #include "src/base/atomic-utils.h" 9 #include "src/base/atomic-utils.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
11 #include "src/compiler/wasm-compiler.h" 11 #include "src/compiler/wasm-compiler.h"
12 #include "src/debug/interface-types.h" 12 #include "src/debug/interface-types.h"
13 #include "src/objects.h" 13 #include "src/objects.h"
14 #include "src/property-descriptor.h" 14 #include "src/property-descriptor.h"
15 #include "src/simulator.h" 15 #include "src/simulator.h"
16 #include "src/snapshot/snapshot.h" 16 #include "src/snapshot/snapshot.h"
17 #include "src/v8.h" 17 #include "src/v8.h"
18 18
19 #include "src/wasm/function-body-decoder.h" 19 #include "src/wasm/function-body-decoder.h"
20 #include "src/wasm/leb-helper.h"
20 #include "src/wasm/module-decoder.h" 21 #include "src/wasm/module-decoder.h"
21 #include "src/wasm/wasm-js.h" 22 #include "src/wasm/wasm-js.h"
22 #include "src/wasm/wasm-limits.h" 23 #include "src/wasm/wasm-limits.h"
23 #include "src/wasm/wasm-module.h" 24 #include "src/wasm/wasm-module.h"
24 #include "src/wasm/wasm-objects.h" 25 #include "src/wasm/wasm-objects.h"
25 #include "src/wasm/wasm-result.h" 26 #include "src/wasm/wasm-result.h"
26 27
27 using namespace v8::internal; 28 using namespace v8::internal;
28 using namespace v8::internal::wasm; 29 using namespace v8::internal::wasm;
29 namespace base = v8::base; 30 namespace base = v8::base;
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 WasmName str = module_env->GetName(&func); 439 WasmName str = module_env->GetName(&func);
439 thrower->CompileError("Compilation of #%d:%.*s failed.", i, str.length(), 440 thrower->CompileError("Compilation of #%d:%.*s failed.", i, str.length(),
440 str.start()); 441 str.start());
441 break; 442 break;
442 } 443 }
443 // Install the code into the linker table. 444 // Install the code into the linker table.
444 functions[i] = code; 445 functions[i] = code;
445 } 446 }
446 } 447 }
447 448
448 void PatchDirectCalls(Handle<FixedArray> old_functions, 449 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
449 Handle<FixedArray> new_functions, int start) { 450 DCHECK_EQ(static_cast<int>(kExprCallFunction), static_cast<int>(*pc));
450 DCHECK_EQ(new_functions->length(), old_functions->length()); 451 uint32_t call_idx = LEBHelper::read_u32v(pc + 1);
452 DCHECK_GE(kMaxInt, call_idx);
453 return static_cast<int>(call_idx);
454 }
451 455
456 void PatchDirectCalls(Handle<FixedArray> new_functions,
457 Handle<WasmCompiledModule> compiled_module,
458 WasmModule* module, int start) {
452 DisallowHeapAllocation no_gc; 459 DisallowHeapAllocation no_gc;
453 std::map<Code*, Code*> old_to_new_code;
454 for (int i = 0; i < new_functions->length(); ++i) {
455 old_to_new_code.insert(std::make_pair(Code::cast(old_functions->get(i)),
456 Code::cast(new_functions->get(i))));
457 }
458 int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
459 AllowDeferredHandleDereference embedding_raw_address; 460 AllowDeferredHandleDereference embedding_raw_address;
460 for (int i = start; i < new_functions->length(); ++i) { 461 SeqOneByteString* module_bytes = compiled_module->module_bytes();
462 std::vector<WasmFunction>* wasm_functions =
463 &compiled_module->module()->functions;
464 DCHECK_EQ(wasm_functions->size() +
465 compiled_module->module()->num_exported_functions,
466 new_functions->length());
467 DCHECK_EQ(start, compiled_module->module()->num_imported_functions);
468
469 int num_wasm_functions = static_cast<int>(wasm_functions->size());
470 for (int i = start; i < num_wasm_functions; ++i) {
461 Code* wasm_function = Code::cast(new_functions->get(i)); 471 Code* wasm_function = Code::cast(new_functions->get(i));
462 for (RelocIterator it(wasm_function, mode_mask); !it.done(); it.next()) { 472 DCHECK(wasm_function->kind() == Code::WASM_FUNCTION);
463 Code* old_code = 473 SourcePositionTableIterator source_pos_iterator(
464 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); 474 wasm_function->source_position_table());
465 if (old_code->kind() == Code::WASM_TO_JS_FUNCTION || 475 const byte* func_bytes =
466 old_code->kind() == Code::WASM_FUNCTION) { 476 module_bytes->GetChars() +
467 auto found = old_to_new_code.find(old_code); 477 compiled_module->module()->functions[i].code_start_offset;
468 DCHECK(found != old_to_new_code.end()); 478 for (RelocIterator it(wasm_function, RelocInfo::kCodeTargetMask);
469 Code* new_code = found->second; 479 !it.done(); it.next()) {
470 if (new_code != old_code) { 480 Code::Kind kind =
471 it.rinfo()->set_target_address(new_code->instruction_start(), 481 Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind();
472 UPDATE_WRITE_BARRIER, 482 if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION)
473 SKIP_ICACHE_FLUSH); 483 continue;
474 } 484 size_t offset_l = it.rinfo()->pc() - wasm_function->instruction_start();
475 } 485 DCHECK_GE(kMaxInt, offset_l);
486 int offset = static_cast<int>(offset_l);
487 DCHECK(!source_pos_iterator.done());
488 int byte_pos;
489 do {
490 byte_pos = source_pos_iterator.source_position().ScriptOffset();
491 source_pos_iterator.Advance();
492 } while (!source_pos_iterator.done() &&
493 source_pos_iterator.code_offset() <= offset);
494 int called_func_index = ExtractDirectCallIndex(func_bytes + byte_pos);
495 Code* new_code = Code::cast(new_functions->get(called_func_index));
496 it.rinfo()->set_target_address(new_code->instruction_start(),
497 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
476 } 498 }
477 } 499 }
500 int func_index = num_wasm_functions;
501 for (auto exp : module->export_table) {
502 if (exp.kind != kExternalFunction) continue;
503 Code* export_wrapper = Code::cast(new_functions->get(func_index));
504 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind());
505 // There must be exactly one call to WASM_FUNCTION or WASM_TO_JS_FUNCTION.
506 int num_wasm_calls = 0;
507 for (RelocIterator it(export_wrapper, RelocInfo::kCodeTargetMask);
508 !it.done(); it.next()) {
509 Code::Kind kind =
510 Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind();
511 if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION)
512 continue;
513 ++num_wasm_calls;
514 Code* new_code = Code::cast(new_functions->get(exp.index));
515 DCHECK_EQ(kind, new_code->kind());
516 it.rinfo()->set_target_address(new_code->instruction_start(),
517 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
518 }
519 DCHECK_EQ(1, num_wasm_calls);
520 func_index++;
521 }
522 DCHECK_EQ(new_functions->length(), func_index);
478 } 523 }
479 524
480 static void ResetCompiledModule(Isolate* isolate, WasmInstanceObject* owner, 525 static void ResetCompiledModule(Isolate* isolate, WasmInstanceObject* owner,
481 WasmCompiledModule* compiled_module) { 526 WasmCompiledModule* compiled_module) {
482 TRACE("Resetting %d\n", compiled_module->instance_id()); 527 TRACE("Resetting %d\n", compiled_module->instance_id());
483 Object* undefined = *isolate->factory()->undefined_value(); 528 Object* undefined = *isolate->factory()->undefined_value();
484 uint32_t old_mem_size = compiled_module->mem_size(); 529 uint32_t old_mem_size = compiled_module->mem_size();
485 uint32_t default_mem_size = compiled_module->default_mem_size(); 530 uint32_t default_mem_size = compiled_module->default_mem_size();
486 Object* mem_start = compiled_module->maybe_ptr_to_memory(); 531 Object* mem_start = compiled_module->maybe_ptr_to_memory();
487 Address old_mem_address = nullptr; 532 Address old_mem_address = nullptr;
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 instance->memory_object()->AddInstance(isolate_, instance); 1337 instance->memory_object()->AddInstance(isolate_, instance);
1293 } 1338 }
1294 1339
1295 //-------------------------------------------------------------------------- 1340 //--------------------------------------------------------------------------
1296 // Set up the indirect function tables for the new instance. 1341 // Set up the indirect function tables for the new instance.
1297 //-------------------------------------------------------------------------- 1342 //--------------------------------------------------------------------------
1298 if (function_table_count > 0) InitializeTables(code_table, instance); 1343 if (function_table_count > 0) InitializeTables(code_table, instance);
1299 1344
1300 if (num_imported_functions > 0 || !owner.is_null()) { 1345 if (num_imported_functions > 0 || !owner.is_null()) {
1301 // If the code was cloned, or new imports were compiled, patch. 1346 // If the code was cloned, or new imports were compiled, patch.
1302 PatchDirectCalls(old_code_table, code_table, num_imported_functions); 1347 PatchDirectCalls(code_table, compiled_module_, module_,
1348 num_imported_functions);
1303 } 1349 }
1304 1350
1305 FlushICache(isolate_, code_table); 1351 FlushICache(isolate_, code_table);
1306 1352
1307 //-------------------------------------------------------------------------- 1353 //--------------------------------------------------------------------------
1308 // Unpack and notify signal handler of protected instructions. 1354 // Unpack and notify signal handler of protected instructions.
1309 //-------------------------------------------------------------------------- 1355 //--------------------------------------------------------------------------
1310 { 1356 {
1311 for (int i = 0; i < code_table->length(); ++i) { 1357 for (int i = 0; i < code_table->length(); ++i) {
1312 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i); 1358 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i);
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after
2298 CHECK(!compiled_module->has_weak_owning_instance()); 2344 CHECK(!compiled_module->has_weak_owning_instance());
2299 } 2345 }
2300 2346
2301 void testing::ValidateOrphanedInstance(Isolate* isolate, 2347 void testing::ValidateOrphanedInstance(Isolate* isolate,
2302 Handle<WasmInstanceObject> instance) { 2348 Handle<WasmInstanceObject> instance) {
2303 DisallowHeapAllocation no_gc; 2349 DisallowHeapAllocation no_gc;
2304 WasmCompiledModule* compiled_module = instance->compiled_module(); 2350 WasmCompiledModule* compiled_module = instance->compiled_module();
2305 CHECK(compiled_module->has_weak_wasm_module()); 2351 CHECK(compiled_module->has_weak_wasm_module());
2306 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared()); 2352 CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared());
2307 } 2353 }
OLDNEW
« 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