Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |