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

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2627613002: [wasm] Refactor call site patching (Closed)
Patch Set: Only instantiate Decoder once 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 | « no previous file | 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"
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 WasmName str = module_env->GetName(&func); 438 WasmName str = module_env->GetName(&func);
439 thrower->CompileError("Compilation of #%d:%.*s failed.", i, str.length(), 439 thrower->CompileError("Compilation of #%d:%.*s failed.", i, str.length(),
440 str.start()); 440 str.start());
441 break; 441 break;
442 } 442 }
443 // Install the code into the linker table. 443 // Install the code into the linker table.
444 functions[i] = code; 444 functions[i] = code;
445 } 445 }
446 } 446 }
447 447
448 void PatchDirectCalls(Handle<FixedArray> old_functions, 448 int ExtractDirectCallIndex(wasm::Decoder& decoder, const byte* pc) {
449 Handle<FixedArray> new_functions, int start) { 449 DCHECK_EQ(static_cast<int>(kExprCallFunction), static_cast<int>(*pc));
450 DCHECK_EQ(new_functions->length(), old_functions->length()); 450 decoder.Reset(pc + 1, pc + 6);
451 uint32_t call_idx = decoder.consume_u32v("call index");
452 DCHECK(decoder.ok());
453 DCHECK_GE(kMaxInt, call_idx);
454 return static_cast<int>(call_idx);
455 }
451 456
457 void PatchDirectCalls(Handle<FixedArray> new_functions,
458 Handle<WasmCompiledModule> compiled_module,
459 WasmModule* module, int start) {
452 DisallowHeapAllocation no_gc; 460 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; 461 AllowDeferredHandleDereference embedding_raw_address;
460 for (int i = start; i < new_functions->length(); ++i) { 462 SeqOneByteString* module_bytes = compiled_module->module_bytes();
463 std::vector<WasmFunction>* wasm_functions =
464 &compiled_module->module()->functions;
465 DCHECK_EQ(wasm_functions->size() +
466 compiled_module->module()->num_exported_functions,
467 new_functions->length());
468 DCHECK_EQ(start, compiled_module->module()->num_imported_functions);
469
470 // Allocate decoder outside of the loop and reuse it to decode all function
471 // indexes.
472 wasm::Decoder decoder(nullptr, nullptr);
473 int num_wasm_functions = static_cast<int>(wasm_functions->size());
474 for (int i = start; i < num_wasm_functions; ++i) {
titzer 2017/01/11 18:34:04 Can you add a comment here about what we are doing
Clemens Hammacher 2017/01/12 09:03:12 Done.
461 Code* wasm_function = Code::cast(new_functions->get(i)); 475 Code* wasm_function = Code::cast(new_functions->get(i));
462 for (RelocIterator it(wasm_function, mode_mask); !it.done(); it.next()) { 476 DCHECK(wasm_function->kind() == Code::WASM_FUNCTION);
463 Code* old_code = 477 SourcePositionTableIterator source_pos_iterator(
464 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); 478 wasm_function->source_position_table());
465 if (old_code->kind() == Code::WASM_TO_JS_FUNCTION || 479 const byte* func_bytes =
466 old_code->kind() == Code::WASM_FUNCTION) { 480 module_bytes->GetChars() +
467 auto found = old_to_new_code.find(old_code); 481 compiled_module->module()->functions[i].code_start_offset;
468 DCHECK(found != old_to_new_code.end()); 482 for (RelocIterator it(wasm_function, RelocInfo::kCodeTargetMask);
469 Code* new_code = found->second; 483 !it.done(); it.next()) {
470 if (new_code != old_code) { 484 Code::Kind kind =
471 it.rinfo()->set_target_address(new_code->instruction_start(), 485 Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind();
472 UPDATE_WRITE_BARRIER, 486 if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION)
473 SKIP_ICACHE_FLUSH); 487 continue;
474 } 488 size_t offset_l = it.rinfo()->pc() - wasm_function->instruction_start();
475 } 489 DCHECK_GE(kMaxInt, offset_l);
490 int offset = static_cast<int>(offset_l);
491 DCHECK(!source_pos_iterator.done());
492 int byte_pos;
493 do {
494 byte_pos = source_pos_iterator.source_position().ScriptOffset();
495 source_pos_iterator.Advance();
496 } while (!source_pos_iterator.done() &&
497 source_pos_iterator.code_offset() <= offset);
498 int called_func_index =
499 ExtractDirectCallIndex(decoder, func_bytes + byte_pos);
500 Code* new_code = Code::cast(new_functions->get(called_func_index));
501 it.rinfo()->set_target_address(new_code->instruction_start(),
502 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
476 } 503 }
477 } 504 }
505 int func_index = num_wasm_functions;
506 for (auto exp : module->export_table) {
507 if (exp.kind != kExternalFunction) continue;
508 Code* export_wrapper = Code::cast(new_functions->get(func_index));
509 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind());
510 // There must be exactly one call to WASM_FUNCTION or WASM_TO_JS_FUNCTION.
511 int num_wasm_calls = 0;
512 for (RelocIterator it(export_wrapper, RelocInfo::kCodeTargetMask);
513 !it.done(); it.next()) {
514 Code::Kind kind =
515 Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind();
516 if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION)
517 continue;
518 ++num_wasm_calls;
519 Code* new_code = Code::cast(new_functions->get(exp.index));
520 DCHECK_EQ(kind, new_code->kind());
521 it.rinfo()->set_target_address(new_code->instruction_start(),
522 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
523 }
524 DCHECK_EQ(1, num_wasm_calls);
525 func_index++;
526 }
527 DCHECK_EQ(new_functions->length(), func_index);
478 } 528 }
479 529
480 static void ResetCompiledModule(Isolate* isolate, WasmInstanceObject* owner, 530 static void ResetCompiledModule(Isolate* isolate, WasmInstanceObject* owner,
481 WasmCompiledModule* compiled_module) { 531 WasmCompiledModule* compiled_module) {
482 TRACE("Resetting %d\n", compiled_module->instance_id()); 532 TRACE("Resetting %d\n", compiled_module->instance_id());
483 Object* undefined = *isolate->factory()->undefined_value(); 533 Object* undefined = *isolate->factory()->undefined_value();
484 uint32_t old_mem_size = compiled_module->mem_size(); 534 uint32_t old_mem_size = compiled_module->mem_size();
485 uint32_t default_mem_size = compiled_module->default_mem_size(); 535 uint32_t default_mem_size = compiled_module->default_mem_size();
486 Object* mem_start = compiled_module->maybe_ptr_to_memory(); 536 Object* mem_start = compiled_module->maybe_ptr_to_memory();
487 Address old_mem_address = nullptr; 537 Address old_mem_address = nullptr;
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 instance->memory_object()->AddInstance(isolate_, instance); 1348 instance->memory_object()->AddInstance(isolate_, instance);
1299 } 1349 }
1300 1350
1301 //-------------------------------------------------------------------------- 1351 //--------------------------------------------------------------------------
1302 // Set up the indirect function tables for the new instance. 1352 // Set up the indirect function tables for the new instance.
1303 //-------------------------------------------------------------------------- 1353 //--------------------------------------------------------------------------
1304 if (function_table_count > 0) InitializeTables(code_table, instance); 1354 if (function_table_count > 0) InitializeTables(code_table, instance);
1305 1355
1306 if (num_imported_functions > 0 || !owner.is_null()) { 1356 if (num_imported_functions > 0 || !owner.is_null()) {
1307 // If the code was cloned, or new imports were compiled, patch. 1357 // If the code was cloned, or new imports were compiled, patch.
1308 PatchDirectCalls(old_code_table, code_table, num_imported_functions); 1358 PatchDirectCalls(code_table, compiled_module_, module_,
1359 num_imported_functions);
1309 } 1360 }
1310 1361
1311 FlushICache(isolate_, code_table); 1362 FlushICache(isolate_, code_table);
1312 1363
1313 //-------------------------------------------------------------------------- 1364 //--------------------------------------------------------------------------
1314 // Unpack and notify signal handler of protected instructions. 1365 // Unpack and notify signal handler of protected instructions.
1315 //-------------------------------------------------------------------------- 1366 //--------------------------------------------------------------------------
1316 { 1367 {
1317 for (int i = 0; i < code_table->length(); ++i) { 1368 for (int i = 0; i < code_table->length(); ++i) {
1318 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i); 1369 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i);
(...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after
2457 2508
2458 JSObject::AddProperty(entry, name_string, export_name.ToHandleChecked(), 2509 JSObject::AddProperty(entry, name_string, export_name.ToHandleChecked(),
2459 NONE); 2510 NONE);
2460 JSObject::AddProperty(entry, kind_string, export_kind, NONE); 2511 JSObject::AddProperty(entry, kind_string, export_kind, NONE);
2461 2512
2462 storage->set(index, *entry); 2513 storage->set(index, *entry);
2463 } 2514 }
2464 2515
2465 return array_object; 2516 return array_object;
2466 } 2517 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698