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

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

Issue 2623203003: [wasm] Patch the native context embedded in compiled code (Closed)
Patch Set: Set context in the WCM on instantiation 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 | test/mjsunit/regress/regress-673297.js » ('j') | 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 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 int offset = static_cast<int>(offset_l); 460 int offset = static_cast<int>(offset_l);
461 DCHECK(!iterator.done()); 461 DCHECK(!iterator.done());
462 int byte_pos; 462 int byte_pos;
463 do { 463 do {
464 byte_pos = iterator.source_position().ScriptOffset(); 464 byte_pos = iterator.source_position().ScriptOffset();
465 iterator.Advance(); 465 iterator.Advance();
466 } while (!iterator.done() && iterator.code_offset() <= offset); 466 } while (!iterator.done() && iterator.code_offset() <= offset);
467 return byte_pos; 467 return byte_pos;
468 } 468 }
469 469
470 void PatchDirectCalls(Handle<FixedArray> new_functions, 470 void PatchContext(RelocIterator& it, Context* context) {
471 Handle<WasmCompiledModule> compiled_module, 471 Object* old = it.rinfo()->target_object();
472 WasmModule* module, int start) { 472 // The only context we use is the native context.
473 DCHECK_IMPLIES(old->IsContext(), old->IsNativeContext());
474 if (!old->IsNativeContext()) return;
475 it.rinfo()->set_target_object(context, UPDATE_WRITE_BARRIER,
476 SKIP_ICACHE_FLUSH);
477 }
478
479 void PatchDirectCallsAndContext(Handle<FixedArray> new_functions,
480 Handle<WasmCompiledModule> compiled_module,
481 WasmModule* module, int start) {
473 DisallowHeapAllocation no_gc; 482 DisallowHeapAllocation no_gc;
474 AllowDeferredHandleDereference embedding_raw_address; 483 AllowDeferredHandleDereference embedding_raw_address;
475 SeqOneByteString* module_bytes = compiled_module->module_bytes(); 484 SeqOneByteString* module_bytes = compiled_module->module_bytes();
476 std::vector<WasmFunction>* wasm_functions = 485 std::vector<WasmFunction>* wasm_functions =
477 &compiled_module->module()->functions; 486 &compiled_module->module()->functions;
478 DCHECK_EQ(wasm_functions->size() + 487 DCHECK_EQ(wasm_functions->size() +
479 compiled_module->module()->num_exported_functions, 488 compiled_module->module()->num_exported_functions,
480 new_functions->length()); 489 new_functions->length());
481 DCHECK_EQ(start, compiled_module->module()->num_imported_functions); 490 DCHECK_EQ(start, compiled_module->module()->num_imported_functions);
491 Context* context = compiled_module->ptr_to_native_context();
492 int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
493 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
482 494
483 // Allocate decoder outside of the loop and reuse it to decode all function 495 // Allocate decoder outside of the loop and reuse it to decode all function
484 // indexes. 496 // indexes.
485 wasm::Decoder decoder(nullptr, nullptr); 497 wasm::Decoder decoder(nullptr, nullptr);
486 int num_wasm_functions = static_cast<int>(wasm_functions->size()); 498 int num_wasm_functions = static_cast<int>(wasm_functions->size());
487 int func_index = start; 499 int func_index = start;
488 // Patch all wasm functions. 500 // Patch all wasm functions.
489 for (; func_index < num_wasm_functions; ++func_index) { 501 for (; func_index < num_wasm_functions; ++func_index) {
490 Code* wasm_function = Code::cast(new_functions->get(func_index)); 502 Code* wasm_function = Code::cast(new_functions->get(func_index));
491 DCHECK(wasm_function->kind() == Code::WASM_FUNCTION); 503 DCHECK(wasm_function->kind() == Code::WASM_FUNCTION);
492 // Iterate simultaneously over the relocation information and the source 504 // Iterate simultaneously over the relocation information and the source
493 // position table. For each call in the reloc info, move the source position 505 // position table. For each call in the reloc info, move the source position
494 // iterator forward to that position to find the byte offset of the 506 // iterator forward to that position to find the byte offset of the
495 // respective call. Then extract the call index from the module wire bytes 507 // respective call. Then extract the call index from the module wire bytes
496 // to find the new compiled function. 508 // to find the new compiled function.
497 SourcePositionTableIterator source_pos_iterator( 509 SourcePositionTableIterator source_pos_iterator(
498 wasm_function->source_position_table()); 510 wasm_function->source_position_table());
499 const byte* func_bytes = 511 const byte* func_bytes =
500 module_bytes->GetChars() + 512 module_bytes->GetChars() +
501 compiled_module->module()->functions[func_index].code_start_offset; 513 compiled_module->module()->functions[func_index].code_start_offset;
502 for (RelocIterator it(wasm_function, RelocInfo::kCodeTargetMask); 514 for (RelocIterator it(wasm_function, mode_mask); !it.done(); it.next()) {
503 !it.done(); it.next()) { 515 if (RelocInfo::IsEmbeddedObject(it.rinfo()->rmode())) {
516 PatchContext(it, context);
517 continue;
518 }
519 DCHECK(RelocInfo::IsCodeTarget(it.rinfo()->rmode()));
504 Code::Kind kind = 520 Code::Kind kind =
505 Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind(); 521 Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind();
506 if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION) 522 if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION)
507 continue; 523 continue;
508 size_t offset = it.rinfo()->pc() - wasm_function->instruction_start(); 524 size_t offset = it.rinfo()->pc() - wasm_function->instruction_start();
509 int byte_pos = 525 int byte_pos =
510 AdvanceSourcePositionTableIterator(source_pos_iterator, offset); 526 AdvanceSourcePositionTableIterator(source_pos_iterator, offset);
511 int called_func_index = 527 int called_func_index =
512 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); 528 ExtractDirectCallIndex(decoder, func_bytes + byte_pos);
513 Code* new_code = Code::cast(new_functions->get(called_func_index)); 529 Code* new_code = Code::cast(new_functions->get(called_func_index));
514 it.rinfo()->set_target_address(new_code->instruction_start(), 530 it.rinfo()->set_target_address(new_code->instruction_start(),
515 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH); 531 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
516 } 532 }
517 } 533 }
518 // Patch all exported functions. 534 // Patch all exported functions.
519 for (auto exp : module->export_table) { 535 for (auto exp : module->export_table) {
520 if (exp.kind != kExternalFunction) continue; 536 if (exp.kind != kExternalFunction) continue;
521 Code* export_wrapper = Code::cast(new_functions->get(func_index)); 537 Code* export_wrapper = Code::cast(new_functions->get(func_index));
522 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind()); 538 DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind());
523 // There must be exactly one call to WASM_FUNCTION or WASM_TO_JS_FUNCTION. 539 // There must be exactly one call to WASM_FUNCTION or WASM_TO_JS_FUNCTION.
524 int num_wasm_calls = 0; 540 int num_wasm_calls = 0;
525 for (RelocIterator it(export_wrapper, RelocInfo::kCodeTargetMask); 541 for (RelocIterator it(export_wrapper, mode_mask); !it.done(); it.next()) {
526 !it.done(); it.next()) { 542 if (RelocInfo::IsEmbeddedObject(it.rinfo()->rmode())) {
543 PatchContext(it, context);
544 continue;
545 }
546 DCHECK(RelocInfo::IsCodeTarget(it.rinfo()->rmode()));
527 Code::Kind kind = 547 Code::Kind kind =
528 Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind(); 548 Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind();
529 if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION) 549 if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION)
530 continue; 550 continue;
531 ++num_wasm_calls; 551 ++num_wasm_calls;
532 Code* new_code = Code::cast(new_functions->get(exp.index)); 552 Code* new_code = Code::cast(new_functions->get(exp.index));
533 DCHECK_EQ(kind, new_code->kind()); 553 DCHECK_EQ(kind, new_code->kind());
534 it.rinfo()->set_target_address(new_code->instruction_start(), 554 it.rinfo()->set_target_address(new_code->instruction_start(),
535 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH); 555 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
536 } 556 }
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 } 1250 }
1231 } 1251 }
1232 RecordStats(isolate_, code_table); 1252 RecordStats(isolate_, code_table);
1233 } else { 1253 } else {
1234 // There was no owner, so we can reuse the original. 1254 // There was no owner, so we can reuse the original.
1235 compiled_module_ = original; 1255 compiled_module_ = original;
1236 TRACE("Reusing existing instance %d\n", 1256 TRACE("Reusing existing instance %d\n",
1237 compiled_module_->instance_id()); 1257 compiled_module_->instance_id());
1238 } 1258 }
1239 compiled_module_->set_code_table(code_table); 1259 compiled_module_->set_code_table(code_table);
1260 compiled_module_->set_native_context(isolate_->native_context());
1240 } 1261 }
1241 module_ = compiled_module_->module(); 1262 module_ = compiled_module_->module();
1242 1263
1243 //-------------------------------------------------------------------------- 1264 //--------------------------------------------------------------------------
1244 // Allocate the instance object. 1265 // Allocate the instance object.
1245 //-------------------------------------------------------------------------- 1266 //--------------------------------------------------------------------------
1246 Handle<WasmInstanceObject> instance = 1267 Handle<WasmInstanceObject> instance =
1247 WasmInstanceObject::New(isolate_, compiled_module_); 1268 WasmInstanceObject::New(isolate_, compiled_module_);
1248 1269
1249 //-------------------------------------------------------------------------- 1270 //--------------------------------------------------------------------------
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 DCHECK(wasm::IsWasmInstance(*instance)); 1380 DCHECK(wasm::IsWasmInstance(*instance));
1360 if (instance->has_memory_object()) { 1381 if (instance->has_memory_object()) {
1361 instance->memory_object()->AddInstance(isolate_, instance); 1382 instance->memory_object()->AddInstance(isolate_, instance);
1362 } 1383 }
1363 1384
1364 //-------------------------------------------------------------------------- 1385 //--------------------------------------------------------------------------
1365 // Set up the indirect function tables for the new instance. 1386 // Set up the indirect function tables for the new instance.
1366 //-------------------------------------------------------------------------- 1387 //--------------------------------------------------------------------------
1367 if (function_table_count > 0) InitializeTables(code_table, instance); 1388 if (function_table_count > 0) InitializeTables(code_table, instance);
1368 1389
1369 if (num_imported_functions > 0 || !owner.is_null()) { 1390 // Patch new call sites and the context.
1370 // If the code was cloned, or new imports were compiled, patch. 1391 PatchDirectCallsAndContext(code_table, compiled_module_, module_,
1371 PatchDirectCalls(code_table, compiled_module_, module_, 1392 num_imported_functions);
1372 num_imported_functions);
1373 }
1374 1393
1375 FlushICache(isolate_, code_table); 1394 FlushICache(isolate_, code_table);
1376 1395
1377 //-------------------------------------------------------------------------- 1396 //--------------------------------------------------------------------------
1378 // Unpack and notify signal handler of protected instructions. 1397 // Unpack and notify signal handler of protected instructions.
1379 //-------------------------------------------------------------------------- 1398 //--------------------------------------------------------------------------
1380 { 1399 {
1381 for (int i = 0; i < code_table->length(); ++i) { 1400 for (int i = 0; i < code_table->length(); ++i) {
1382 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i); 1401 Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i);
1383 1402
(...skipping 1137 matching lines...) Expand 10 before | Expand all | Expand 10 after
2521 2540
2522 JSObject::AddProperty(entry, name_string, export_name.ToHandleChecked(), 2541 JSObject::AddProperty(entry, name_string, export_name.ToHandleChecked(),
2523 NONE); 2542 NONE);
2524 JSObject::AddProperty(entry, kind_string, export_kind, NONE); 2543 JSObject::AddProperty(entry, kind_string, export_kind, NONE);
2525 2544
2526 storage->set(index, *entry); 2545 storage->set(index, *entry);
2527 } 2546 }
2528 2547
2529 return array_object; 2548 return array_object;
2530 } 2549 }
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-673297.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698