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

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

Issue 2864583004: Only turn on UMA WASM metric when synchronous. (Closed)
Patch Set: Again, merge updated master. Created 3 years, 7 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/module-decoder.cc ('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/asmjs/asm-js.h" 7 #include "src/asmjs/asm-js.h"
8 #include "src/assembler-inl.h" 8 #include "src/assembler-inl.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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 base::OS::Free(memory, 65 base::OS::Free(memory,
66 RoundUp(kWasmMaxHeapOffset, base::OS::CommitPageSize())); 66 RoundUp(kWasmMaxHeapOffset, base::OS::CommitPageSize()));
67 67
68 data.GetIsolate()->AdjustAmountOfExternalAllocatedMemory( 68 data.GetIsolate()->AdjustAmountOfExternalAllocatedMemory(
69 -buffer->byte_length()->Number()); 69 -buffer->byte_length()->Number());
70 } 70 }
71 71
72 GlobalHandles::Destroy(reinterpret_cast<Object**>(p)); 72 GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
73 } 73 }
74 74
75 static void RecordStats(Isolate* isolate, Code* code) { 75 static void RecordStats(Isolate* isolate, Code* code, bool is_sync) {
76 isolate->counters()->wasm_generated_code_size()->Increment(code->body_size()); 76 if (is_sync) {
77 isolate->counters()->wasm_reloc_size()->Increment( 77 // TODO(karlschimpf): Make this work when asynchronous.
78 code->relocation_info()->length()); 78 // https://bugs.chromium.org/p/v8/issues/detail?id=6361
79 } 79 isolate->counters()->wasm_generated_code_size()->Increment(
80 80 code->body_size());
81 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions) { 81 isolate->counters()->wasm_reloc_size()->Increment(
82 DisallowHeapAllocation no_gc; 82 code->relocation_info()->length());
83 for (int i = 0; i < functions->length(); ++i) {
84 RecordStats(isolate, Code::cast(functions->get(i)));
85 } 83 }
86 } 84 }
87 85
86 static void RecordStats(Isolate* isolate, Handle<FixedArray> functions,
87 bool is_sync) {
88 DisallowHeapAllocation no_gc;
89 for (int i = 0; i < functions->length(); ++i) {
90 RecordStats(isolate, Code::cast(functions->get(i)), is_sync);
91 }
92 }
93
88 void* TryAllocateBackingStore(Isolate* isolate, size_t size, 94 void* TryAllocateBackingStore(Isolate* isolate, size_t size,
89 bool enable_guard_regions, bool& is_external) { 95 bool enable_guard_regions, bool& is_external) {
90 is_external = false; 96 is_external = false;
91 // TODO(eholk): Right now enable_guard_regions has no effect on 32-bit 97 // TODO(eholk): Right now enable_guard_regions has no effect on 32-bit
92 // systems. It may be safer to fail instead, given that other code might do 98 // systems. It may be safer to fail instead, given that other code might do
93 // things that would be unsafe if they expected guard pages where there 99 // things that would be unsafe if they expected guard pages where there
94 // weren't any. 100 // weren't any.
95 if (enable_guard_regions && kGuardRegionsSupported) { 101 if (enable_guard_regions && kGuardRegionsSupported) {
96 // TODO(eholk): On Windows we want to make sure we don't commit the guard 102 // TODO(eholk): On Windows we want to make sure we don't commit the guard
97 // pages yet. 103 // pages yet.
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 (FLAG_asm_wasm_lazy_compilation && module->is_asm_js()); 303 (FLAG_asm_wasm_lazy_compilation && module->is_asm_js());
298 } 304 }
299 305
300 // A helper for compiling an entire module. 306 // A helper for compiling an entire module.
301 class CompilationHelper { 307 class CompilationHelper {
302 public: 308 public:
303 // The compilation helper takes ownership of the {WasmModule}. 309 // The compilation helper takes ownership of the {WasmModule}.
304 // In {CompileToModuleObject}, it will transfer ownership to the generated 310 // In {CompileToModuleObject}, it will transfer ownership to the generated
305 // {WasmModuleWrapper}. If this method is not called, ownership may be 311 // {WasmModuleWrapper}. If this method is not called, ownership may be
306 // reclaimed by explicitely releasing the {module_} field. 312 // reclaimed by explicitely releasing the {module_} field.
307 CompilationHelper(Isolate* isolate, std::unique_ptr<WasmModule> module) 313 CompilationHelper(Isolate* isolate, std::unique_ptr<WasmModule> module,
308 : isolate_(isolate), module_(std::move(module)) {} 314 bool is_sync)
315 : isolate_(isolate), module_(std::move(module)), is_sync_(is_sync) {}
309 316
310 // The actual runnable task that performs compilations in the background. 317 // The actual runnable task that performs compilations in the background.
311 class CompilationTask : public CancelableTask { 318 class CompilationTask : public CancelableTask {
312 public: 319 public:
313 CompilationHelper* helper_; 320 CompilationHelper* helper_;
314 explicit CompilationTask(CompilationHelper* helper) 321 explicit CompilationTask(CompilationHelper* helper)
315 : CancelableTask(helper->isolate_), helper_(helper) {} 322 : CancelableTask(helper->isolate_), helper_(helper) {}
316 323
317 void RunInternal() override { 324 void RunInternal() override {
318 while (helper_->FetchAndExecuteCompilationUnit()) { 325 while (helper_->FetchAndExecuteCompilationUnit()) {
319 } 326 }
320 helper_->module_->pending_tasks.get()->Signal(); 327 helper_->module_->pending_tasks.get()->Signal();
321 } 328 }
322 }; 329 };
323 330
324 Isolate* isolate_; 331 Isolate* isolate_;
325 std::unique_ptr<WasmModule> module_; 332 std::unique_ptr<WasmModule> module_;
333 bool is_sync_;
326 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> 334 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>>
327 compilation_units_; 335 compilation_units_;
328 std::queue<std::unique_ptr<compiler::WasmCompilationUnit>> executed_units_; 336 std::queue<std::unique_ptr<compiler::WasmCompilationUnit>> executed_units_;
329 base::Mutex result_mutex_; 337 base::Mutex result_mutex_;
330 base::AtomicNumber<size_t> next_unit_; 338 base::AtomicNumber<size_t> next_unit_;
331 size_t num_background_tasks_ = 0; 339 size_t num_background_tasks_ = 0;
332 340
333 // Run by each compilation task and by the main thread. 341 // Run by each compilation task and by the main thread.
334 bool FetchAndExecuteCompilationUnit() { 342 bool FetchAndExecuteCompilationUnit() {
335 DisallowHeapAllocation no_allocation; 343 DisallowHeapAllocation no_allocation;
(...skipping 17 matching lines...) Expand all
353 361
354 size_t InitializeParallelCompilation( 362 size_t InitializeParallelCompilation(
355 const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env) { 363 const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env) {
356 uint32_t start = module_env.module_env.module->num_imported_functions + 364 uint32_t start = module_env.module_env.module->num_imported_functions +
357 FLAG_skip_compiling_wasm_funcs; 365 FLAG_skip_compiling_wasm_funcs;
358 uint32_t num_funcs = static_cast<uint32_t>(functions.size()); 366 uint32_t num_funcs = static_cast<uint32_t>(functions.size());
359 uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start; 367 uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start;
360 compilation_units_.reserve(funcs_to_compile); 368 compilation_units_.reserve(funcs_to_compile);
361 for (uint32_t i = start; i < num_funcs; ++i) { 369 for (uint32_t i = start; i < num_funcs; ++i) {
362 const WasmFunction* func = &functions[i]; 370 const WasmFunction* func = &functions[i];
371 constexpr bool is_sync = true;
363 compilation_units_.push_back( 372 compilation_units_.push_back(
364 std::unique_ptr<compiler::WasmCompilationUnit>( 373 std::unique_ptr<compiler::WasmCompilationUnit>(
365 new compiler::WasmCompilationUnit(isolate_, &module_env, func))); 374 new compiler::WasmCompilationUnit(isolate_, &module_env, func,
375 !is_sync)));
366 } 376 }
367 return funcs_to_compile; 377 return funcs_to_compile;
368 } 378 }
369 379
370 void InitializeHandles() { 380 void InitializeHandles() {
371 for (auto& unit : compilation_units_) { 381 for (auto& unit : compilation_units_) {
372 unit->InitializeHandles(); 382 unit->InitializeHandles();
373 } 383 }
374 } 384 }
375 385
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 factory->NewFixedArray(function_table_count, TENURED); 531 factory->NewFixedArray(function_table_count, TENURED);
522 Handle<FixedArray> signature_tables = 532 Handle<FixedArray> signature_tables =
523 factory->NewFixedArray(function_table_count, TENURED); 533 factory->NewFixedArray(function_table_count, TENURED);
524 for (int i = 0; i < function_table_count; ++i) { 534 for (int i = 0; i < function_table_count; ++i) {
525 temp_instance.function_tables[i] = factory->NewFixedArray(1, TENURED); 535 temp_instance.function_tables[i] = factory->NewFixedArray(1, TENURED);
526 temp_instance.signature_tables[i] = factory->NewFixedArray(1, TENURED); 536 temp_instance.signature_tables[i] = factory->NewFixedArray(1, TENURED);
527 function_tables->set(i, *temp_instance.function_tables[i]); 537 function_tables->set(i, *temp_instance.function_tables[i]);
528 signature_tables->set(i, *temp_instance.signature_tables[i]); 538 signature_tables->set(i, *temp_instance.signature_tables[i]);
529 } 539 }
530 540
531 HistogramTimerScope wasm_compile_module_time_scope( 541 if (is_sync_) {
532 module_->is_wasm() 542 // TODO(karlschimpf): Make this work when asynchronous.
533 ? isolate_->counters()->wasm_compile_wasm_module_time() 543 // https://bugs.chromium.org/p/v8/issues/detail?id=6361
534 : isolate_->counters()->wasm_compile_asm_module_time()); 544 HistogramTimerScope wasm_compile_module_time_scope(
545 module_->is_wasm()
546 ? isolate_->counters()->wasm_compile_wasm_module_time()
547 : isolate_->counters()->wasm_compile_asm_module_time());
548 return CompileToModuleObjectInternal(
549 thrower, wire_bytes, asm_js_script, asm_js_offset_table_bytes,
550 factory, &temp_instance, &function_tables, &signature_tables);
551 }
552 return CompileToModuleObjectInternal(
553 thrower, wire_bytes, asm_js_script, asm_js_offset_table_bytes, factory,
554 &temp_instance, &function_tables, &signature_tables);
555 }
535 556
536 ModuleBytesEnv module_env(module_.get(), &temp_instance, wire_bytes); 557 private:
558 MaybeHandle<WasmModuleObject> CompileToModuleObjectInternal(
559 ErrorThrower* thrower, const ModuleWireBytes& wire_bytes,
560 Handle<Script> asm_js_script,
561 Vector<const byte> asm_js_offset_table_bytes, Factory* factory,
562 WasmInstance* temp_instance, Handle<FixedArray>* function_tables,
563 Handle<FixedArray>* signature_tables) {
564 ModuleBytesEnv module_env(module_.get(), temp_instance, wire_bytes);
537 565
538 // The {code_table} array contains import wrappers and functions (which 566 // The {code_table} array contains import wrappers and functions (which
539 // are both included in {functions.size()}, and export wrappers. 567 // are both included in {functions.size()}, and export wrappers.
540 int code_table_size = static_cast<int>(module_->functions.size() + 568 int code_table_size = static_cast<int>(module_->functions.size() +
541 module_->num_exported_functions); 569 module_->num_exported_functions);
542 Handle<FixedArray> code_table = 570 Handle<FixedArray> code_table =
543 factory->NewFixedArray(static_cast<int>(code_table_size), TENURED); 571 factory->NewFixedArray(static_cast<int>(code_table_size), TENURED);
544 572
545 // Check whether lazy compilation is enabled for this module. 573 // Check whether lazy compilation is enabled for this module.
546 bool lazy_compile = compile_lazy(module_.get()); 574 bool lazy_compile = compile_lazy(module_.get());
547 575
548 // If lazy compile: Initialize the code table with the lazy compile builtin. 576 // If lazy compile: Initialize the code table with the lazy compile builtin.
549 // Otherwise: Initialize with the illegal builtin. All call sites will be 577 // Otherwise: Initialize with the illegal builtin. All call sites will be
550 // patched at instantiation. 578 // patched at instantiation.
551 Handle<Code> init_builtin = lazy_compile 579 Handle<Code> init_builtin = lazy_compile
552 ? isolate_->builtins()->WasmCompileLazy() 580 ? isolate_->builtins()->WasmCompileLazy()
553 : isolate_->builtins()->Illegal(); 581 : isolate_->builtins()->Illegal();
554 for (int i = 0, e = static_cast<int>(module_->functions.size()); i < e; 582 for (int i = 0, e = static_cast<int>(module_->functions.size()); i < e;
555 ++i) { 583 ++i) {
556 code_table->set(i, *init_builtin); 584 code_table->set(i, *init_builtin);
557 temp_instance.function_code[i] = init_builtin; 585 temp_instance->function_code[i] = init_builtin;
558 } 586 }
559 587
560 (module_->is_wasm() ? isolate_->counters()->wasm_functions_per_wasm_module() 588 if (is_sync_)
561 : isolate_->counters()->wasm_functions_per_asm_module()) 589 // TODO(karlschimpf): Make this work when asynchronous.
562 ->AddSample(static_cast<int>(module_->functions.size())); 590 // https://bugs.chromium.org/p/v8/issues/detail?id=6361
591 (module_->is_wasm()
592 ? isolate_->counters()->wasm_functions_per_wasm_module()
593 : isolate_->counters()->wasm_functions_per_asm_module())
594 ->AddSample(static_cast<int>(module_->functions.size()));
563 595
564 if (!lazy_compile) { 596 if (!lazy_compile) {
565 size_t funcs_to_compile = 597 size_t funcs_to_compile =
566 module_->functions.size() - module_->num_imported_functions; 598 module_->functions.size() - module_->num_imported_functions;
567 if (!FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks != 0 && 599 if (!FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks != 0 &&
568 funcs_to_compile > 1) { 600 funcs_to_compile > 1) {
569 // Avoid a race condition by collecting results into a second vector. 601 // Avoid a race condition by collecting results into a second vector.
570 std::vector<Handle<Code>> results(temp_instance.function_code); 602 std::vector<Handle<Code>> results(temp_instance->function_code);
571 CompileInParallel(&module_env, results, thrower); 603 CompileInParallel(&module_env, results, thrower);
572 temp_instance.function_code.swap(results); 604 temp_instance->function_code.swap(results);
573 } else { 605 } else {
574 CompileSequentially(&module_env, temp_instance.function_code, thrower); 606 CompileSequentially(&module_env, temp_instance->function_code, thrower);
575 } 607 }
576 if (thrower->error()) return {}; 608 if (thrower->error()) return {};
577 } 609 }
578 610
579 // At this point, compilation has completed. Update the code table. 611 // At this point, compilation has completed. Update the code table.
580 for (size_t i = FLAG_skip_compiling_wasm_funcs; 612 for (size_t i = FLAG_skip_compiling_wasm_funcs;
581 i < temp_instance.function_code.size(); ++i) { 613 i < temp_instance->function_code.size(); ++i) {
582 Code* code = *temp_instance.function_code[i]; 614 Code* code = *temp_instance->function_code[i];
583 code_table->set(static_cast<int>(i), code); 615 code_table->set(static_cast<int>(i), code);
584 RecordStats(isolate_, code); 616 RecordStats(isolate_, code, is_sync_);
585 } 617 }
586 618
587 // Create heap objects for script, module bytes and asm.js offset table to 619 // Create heap objects for script, module bytes and asm.js offset table to
588 // be stored in the shared module data. 620 // be stored in the shared module data.
589 Handle<Script> script; 621 Handle<Script> script;
590 Handle<ByteArray> asm_js_offset_table; 622 Handle<ByteArray> asm_js_offset_table;
591 if (asm_js_script.is_null()) { 623 if (asm_js_script.is_null()) {
592 script = CreateWasmScript(isolate_, wire_bytes); 624 script = CreateWasmScript(isolate_, wire_bytes);
593 } else { 625 } else {
594 script = asm_js_script; 626 script = asm_js_script;
(...skipping 25 matching lines...) Expand all
620 Handle<WasmSharedModuleData> shared = WasmSharedModuleData::New( 652 Handle<WasmSharedModuleData> shared = WasmSharedModuleData::New(
621 isolate_, module_wrapper, Handle<SeqOneByteString>::cast(module_bytes), 653 isolate_, module_wrapper, Handle<SeqOneByteString>::cast(module_bytes),
622 script, asm_js_offset_table); 654 script, asm_js_offset_table);
623 if (lazy_compile) WasmSharedModuleData::PrepareForLazyCompilation(shared); 655 if (lazy_compile) WasmSharedModuleData::PrepareForLazyCompilation(shared);
624 656
625 // Create the compiled module object, and populate with compiled functions 657 // Create the compiled module object, and populate with compiled functions
626 // and information needed at instantiation time. This object needs to be 658 // and information needed at instantiation time. This object needs to be
627 // serializable. Instantiation may occur off a deserialized version of this 659 // serializable. Instantiation may occur off a deserialized version of this
628 // object. 660 // object.
629 Handle<WasmCompiledModule> compiled_module = WasmCompiledModule::New( 661 Handle<WasmCompiledModule> compiled_module = WasmCompiledModule::New(
630 isolate_, shared, code_table, function_tables, signature_tables); 662 isolate_, shared, code_table, *function_tables, *signature_tables);
631 663
632 // If we created a wasm script, finish it now and make it public to the 664 // If we created a wasm script, finish it now and make it public to the
633 // debugger. 665 // debugger.
634 if (asm_js_script.is_null()) { 666 if (asm_js_script.is_null()) {
635 script->set_wasm_compiled_module(*compiled_module); 667 script->set_wasm_compiled_module(*compiled_module);
636 isolate_->debug()->OnAfterCompile(script); 668 isolate_->debug()->OnAfterCompile(script);
637 } 669 }
638 670
639 // Compile JS->WASM wrappers for exported functions. 671 // Compile JS->WASM wrappers for exported functions.
640 JSToWasmWrapperCache js_to_wasm_cache; 672 JSToWasmWrapperCache js_to_wasm_cache;
641 int func_index = 0; 673 int func_index = 0;
642 for (auto exp : module->export_table) { 674 for (auto exp : module->export_table) {
643 if (exp.kind != kExternalFunction) continue; 675 if (exp.kind != kExternalFunction) continue;
644 Handle<Code> wasm_code = EnsureExportedLazyDeoptData( 676 Handle<Code> wasm_code = EnsureExportedLazyDeoptData(
645 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index); 677 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index);
646 Handle<Code> wrapper_code = 678 Handle<Code> wrapper_code =
647 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(isolate_, module, 679 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(isolate_, module,
648 wasm_code, exp.index); 680 wasm_code, exp.index);
649 int export_index = 681 int export_index =
650 static_cast<int>(module->functions.size() + func_index); 682 static_cast<int>(module->functions.size() + func_index);
651 code_table->set(export_index, *wrapper_code); 683 code_table->set(export_index, *wrapper_code);
652 RecordStats(isolate_, *wrapper_code); 684 RecordStats(isolate_, *wrapper_code, is_sync_);
653 func_index++; 685 func_index++;
654 } 686 }
655 687
656 return WasmModuleObject::New(isolate_, compiled_module); 688 return WasmModuleObject::New(isolate_, compiled_module);
657 } 689 }
658 }; 690 };
659 691
660 static void MemoryInstanceFinalizer(Isolate* isolate, 692 static void MemoryInstanceFinalizer(Isolate* isolate,
661 WasmInstanceObject* instance) { 693 WasmInstanceObject* instance) {
662 DisallowHeapAllocation no_gc; 694 DisallowHeapAllocation no_gc;
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 case Code::JS_TO_WASM_FUNCTION: 1164 case Code::JS_TO_WASM_FUNCTION:
1133 case Code::WASM_FUNCTION: { 1165 case Code::WASM_FUNCTION: {
1134 Handle<Code> code = factory->CopyCode(orig_code); 1166 Handle<Code> code = factory->CopyCode(orig_code);
1135 code_table->set(i, *code); 1167 code_table->set(i, *code);
1136 break; 1168 break;
1137 } 1169 }
1138 default: 1170 default:
1139 UNREACHABLE(); 1171 UNREACHABLE();
1140 } 1172 }
1141 } 1173 }
1142 RecordStats(isolate_, code_table); 1174 RecordStats(isolate_, code_table, is_sync_);
1143 } else { 1175 } else {
1144 // There was no owner, so we can reuse the original. 1176 // There was no owner, so we can reuse the original.
1145 compiled_module_ = original; 1177 compiled_module_ = original;
1146 old_code_table = 1178 old_code_table =
1147 factory->CopyFixedArray(compiled_module_->code_table()); 1179 factory->CopyFixedArray(compiled_module_->code_table());
1148 code_table = compiled_module_->code_table(); 1180 code_table = compiled_module_->code_table();
1149 TRACE("Reusing existing instance %d\n", 1181 TRACE("Reusing existing instance %d\n",
1150 compiled_module_->instance_id()); 1182 compiled_module_->instance_id());
1151 } 1183 }
1152 compiled_module_->set_native_context(isolate_->native_context()); 1184 compiled_module_->set_native_context(isolate_->native_context());
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 int start_index = module_->start_function_index; 1441 int start_index = module_->start_function_index;
1410 Handle<Code> startup_code = EnsureExportedLazyDeoptData( 1442 Handle<Code> startup_code = EnsureExportedLazyDeoptData(
1411 isolate_, instance, code_table, start_index); 1443 isolate_, instance, code_table, start_index);
1412 FunctionSig* sig = module_->functions[start_index].sig; 1444 FunctionSig* sig = module_->functions[start_index].sig;
1413 Handle<Code> wrapper_code = 1445 Handle<Code> wrapper_code =
1414 js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( 1446 js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper(
1415 isolate_, module_, startup_code, start_index); 1447 isolate_, module_, startup_code, start_index);
1416 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( 1448 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New(
1417 isolate_, instance, MaybeHandle<String>(), start_index, 1449 isolate_, instance, MaybeHandle<String>(), start_index,
1418 static_cast<int>(sig->parameter_count()), wrapper_code); 1450 static_cast<int>(sig->parameter_count()), wrapper_code);
1419 RecordStats(isolate_, *startup_code); 1451 RecordStats(isolate_, *startup_code, is_sync_);
1420 // Call the JS function. 1452 // Call the JS function.
1421 Handle<Object> undefined = factory->undefined_value(); 1453 Handle<Object> undefined = factory->undefined_value();
1422 MaybeHandle<Object> retval = 1454 MaybeHandle<Object> retval =
1423 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); 1455 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr);
1424 1456
1425 if (retval.is_null()) { 1457 if (retval.is_null()) {
1426 DCHECK(isolate_->has_pending_exception()); 1458 DCHECK(isolate_->has_pending_exception());
1427 isolate_->OptionalRescheduleException(false); 1459 isolate_->OptionalRescheduleException(false);
1428 // It's unfortunate that the new instance is already linked in the 1460 // It's unfortunate that the new instance is already linked in the
1429 // chain. However, we need to set up everything before executing the 1461 // chain. However, we need to set up everything before executing the
(...skipping 13 matching lines...) Expand all
1443 // Represents the initialized state of a table. 1475 // Represents the initialized state of a table.
1444 struct TableInstance { 1476 struct TableInstance {
1445 Handle<WasmTableObject> table_object; // WebAssembly.Table instance 1477 Handle<WasmTableObject> table_object; // WebAssembly.Table instance
1446 Handle<FixedArray> js_wrappers; // JSFunctions exported 1478 Handle<FixedArray> js_wrappers; // JSFunctions exported
1447 Handle<FixedArray> function_table; // internal code array 1479 Handle<FixedArray> function_table; // internal code array
1448 Handle<FixedArray> signature_table; // internal sig array 1480 Handle<FixedArray> signature_table; // internal sig array
1449 }; 1481 };
1450 1482
1451 Isolate* isolate_; 1483 Isolate* isolate_;
1452 WasmModule* const module_; 1484 WasmModule* const module_;
1485 constexpr static bool is_sync_ = true;
1453 ErrorThrower* thrower_; 1486 ErrorThrower* thrower_;
1454 Handle<WasmModuleObject> module_object_; 1487 Handle<WasmModuleObject> module_object_;
1455 Handle<JSReceiver> ffi_; // TODO(titzer): Use MaybeHandle 1488 Handle<JSReceiver> ffi_; // TODO(titzer): Use MaybeHandle
1456 Handle<JSArrayBuffer> memory_; // TODO(titzer): Use MaybeHandle 1489 Handle<JSArrayBuffer> memory_; // TODO(titzer): Use MaybeHandle
1457 Handle<JSArrayBuffer> globals_; 1490 Handle<JSArrayBuffer> globals_;
1458 Handle<WasmCompiledModule> compiled_module_; 1491 Handle<WasmCompiledModule> compiled_module_;
1459 std::vector<TableInstance> table_instances_; 1492 std::vector<TableInstance> table_instances_;
1460 std::vector<Handle<JSFunction>> js_wrappers_; 1493 std::vector<Handle<JSFunction>> js_wrappers_;
1461 JSToWasmWrapperCache js_to_wasm_cache_; 1494 JSToWasmWrapperCache js_to_wasm_cache_;
1462 1495
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1614 isolate_, index, module_->functions[import.index].sig, 1647 isolate_, index, module_->functions[import.index].sig,
1615 Handle<JSReceiver>::cast(value), module_name, import_name, 1648 Handle<JSReceiver>::cast(value), module_name, import_name,
1616 module_->get_origin()); 1649 module_->get_origin());
1617 if (import_wrapper.is_null()) { 1650 if (import_wrapper.is_null()) {
1618 ReportLinkError( 1651 ReportLinkError(
1619 "imported function does not match the expected type", index, 1652 "imported function does not match the expected type", index,
1620 module_name, import_name); 1653 module_name, import_name);
1621 return -1; 1654 return -1;
1622 } 1655 }
1623 code_table->set(num_imported_functions, *import_wrapper); 1656 code_table->set(num_imported_functions, *import_wrapper);
1624 RecordStats(isolate_, *import_wrapper); 1657 RecordStats(isolate_, *import_wrapper, is_sync_);
1625 num_imported_functions++; 1658 num_imported_functions++;
1626 break; 1659 break;
1627 } 1660 }
1628 case kExternalTable: { 1661 case kExternalTable: {
1629 if (!WasmJs::IsWasmTableObject(isolate_, value)) { 1662 if (!WasmJs::IsWasmTableObject(isolate_, value)) {
1630 ReportLinkError("table import requires a WebAssembly.Table", index, 1663 ReportLinkError("table import requires a WebAssembly.Table", index,
1631 module_name, import_name); 1664 module_name, import_name);
1632 return -1; 1665 return -1;
1633 } 1666 }
1634 WasmIndirectFunctionTable& table = 1667 WasmIndirectFunctionTable& table =
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after
2485 2518
2486 ModuleResult result = DecodeWasmModule(isolate, bytes.start(), bytes.end(), 2519 ModuleResult result = DecodeWasmModule(isolate, bytes.start(), bytes.end(),
2487 false, kAsmJsOrigin); 2520 false, kAsmJsOrigin);
2488 if (result.failed()) { 2521 if (result.failed()) {
2489 thrower->CompileFailed("Wasm decoding failed", result); 2522 thrower->CompileFailed("Wasm decoding failed", result);
2490 return {}; 2523 return {};
2491 } 2524 }
2492 2525
2493 // Transfer ownership to the {WasmModuleWrapper} generated in 2526 // Transfer ownership to the {WasmModuleWrapper} generated in
2494 // {CompileToModuleObject}. 2527 // {CompileToModuleObject}.
2495 CompilationHelper helper(isolate, std::move(result.val)); 2528 constexpr bool is_sync = true;
2529 CompilationHelper helper(isolate, std::move(result.val), is_sync);
2496 return helper.CompileToModuleObject(thrower, bytes, asm_js_script, 2530 return helper.CompileToModuleObject(thrower, bytes, asm_js_script,
2497 asm_js_offset_table_bytes); 2531 asm_js_offset_table_bytes);
2498 } 2532 }
2499 2533
2500 MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate, 2534 MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate,
2501 ErrorThrower* thrower, 2535 ErrorThrower* thrower,
2502 const ModuleWireBytes& bytes) { 2536 const ModuleWireBytes& bytes) {
2503 if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) { 2537 if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) {
2504 thrower->CompileError("Wasm code generation disallowed in this context"); 2538 thrower->CompileError("Wasm code generation disallowed in this context");
2505 return {}; 2539 return {};
2506 } 2540 }
2507 2541
2508 ModuleResult result = 2542 ModuleResult result =
2509 DecodeWasmModule(isolate, bytes.start(), bytes.end(), false, kWasmOrigin); 2543 DecodeWasmModule(isolate, bytes.start(), bytes.end(), false, kWasmOrigin);
2510 if (result.failed()) { 2544 if (result.failed()) {
2511 thrower->CompileFailed("Wasm decoding failed", result); 2545 thrower->CompileFailed("Wasm decoding failed", result);
2512 return {}; 2546 return {};
2513 } 2547 }
2514 2548
2515 // Transfer ownership to the {WasmModuleWrapper} generated in 2549 // Transfer ownership to the {WasmModuleWrapper} generated in
2516 // {CompileToModuleObject}. 2550 // {CompileToModuleObject}.
2517 CompilationHelper helper(isolate, std::move(result.val)); 2551 constexpr bool is_sync = true;
2552 CompilationHelper helper(isolate, std::move(result.val), is_sync);
2518 return helper.CompileToModuleObject(thrower, bytes, Handle<Script>(), 2553 return helper.CompileToModuleObject(thrower, bytes, Handle<Script>(),
2519 Vector<const byte>()); 2554 Vector<const byte>());
2520 } 2555 }
2521 2556
2522 MaybeHandle<WasmInstanceObject> wasm::SyncInstantiate( 2557 MaybeHandle<WasmInstanceObject> wasm::SyncInstantiate(
2523 Isolate* isolate, ErrorThrower* thrower, 2558 Isolate* isolate, ErrorThrower* thrower,
2524 Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports, 2559 Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
2525 MaybeHandle<JSArrayBuffer> memory) { 2560 MaybeHandle<JSArrayBuffer> memory) {
2526 InstantiationHelper helper(isolate, thrower, module_object, imports, memory); 2561 InstantiationHelper helper(isolate, thrower, module_object, imports, memory);
2527 return helper.Build(); 2562 return helper.Build();
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2691 // Step 1: (async) Decode the module. 2726 // Step 1: (async) Decode the module.
2692 //========================================================================== 2727 //==========================================================================
2693 class DecodeModule : public CompileTask<ASYNC> { 2728 class DecodeModule : public CompileTask<ASYNC> {
2694 void Run() override { 2729 void Run() override {
2695 ModuleResult result; 2730 ModuleResult result;
2696 { 2731 {
2697 DisallowHandleAllocation no_handle; 2732 DisallowHandleAllocation no_handle;
2698 DisallowHeapAllocation no_allocation; 2733 DisallowHeapAllocation no_allocation;
2699 // Decode the module bytes. 2734 // Decode the module bytes.
2700 TRACE_COMPILE("(1) Decoding module...\n"); 2735 TRACE_COMPILE("(1) Decoding module...\n");
2736 constexpr bool is_sync = true;
2701 result = DecodeWasmModule(job_->isolate_, job_->wire_bytes_.start(), 2737 result = DecodeWasmModule(job_->isolate_, job_->wire_bytes_.start(),
2702 job_->wire_bytes_.end(), false, kWasmOrigin); 2738 job_->wire_bytes_.end(), false, kWasmOrigin,
2739 !is_sync);
2703 } 2740 }
2704 if (result.failed()) { 2741 if (result.failed()) {
2705 // Decoding failure; reject the promise and clean up. 2742 // Decoding failure; reject the promise and clean up.
2706 job_->DoSync<DecodeFail>(std::move(result)); 2743 job_->DoSync<DecodeFail>(std::move(result));
2707 } else { 2744 } else {
2708 // Decode passed. 2745 // Decode passed.
2709 job_->DoSync<PrepareAndStartCompile>(std::move(result.val)); 2746 job_->DoSync<PrepareAndStartCompile>(std::move(result.val));
2710 } 2747 }
2711 } 2748 }
2712 }; 2749 };
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2785 job_->code_table_->set(static_cast<int>(i), *illegal_builtin); 2822 job_->code_table_->set(static_cast<int>(i), *illegal_builtin);
2786 job_->temp_instance_->function_code[i] = illegal_builtin; 2823 job_->temp_instance_->function_code[i] = illegal_builtin;
2787 } 2824 }
2788 2825
2789 job_->isolate_->counters()->wasm_functions_per_wasm_module()->AddSample( 2826 job_->isolate_->counters()->wasm_functions_per_wasm_module()->AddSample(
2790 static_cast<int>(module_->functions.size())); 2827 static_cast<int>(module_->functions.size()));
2791 2828
2792 // Transfer ownership of the {WasmModule} to the {CompilationHelper}, but 2829 // Transfer ownership of the {WasmModule} to the {CompilationHelper}, but
2793 // keep a pointer. 2830 // keep a pointer.
2794 WasmModule* module = module_.get(); 2831 WasmModule* module = module_.get();
2832 constexpr bool is_sync = true;
2795 job_->helper_.reset( 2833 job_->helper_.reset(
2796 new CompilationHelper(job_->isolate_, std::move(module_))); 2834 new CompilationHelper(job_->isolate_, std::move(module_), !is_sync));
2797 2835
2798 DCHECK_LE(module->num_imported_functions, module->functions.size()); 2836 DCHECK_LE(module->num_imported_functions, module->functions.size());
2799 size_t num_functions = 2837 size_t num_functions =
2800 module->functions.size() - module->num_imported_functions; 2838 module->functions.size() - module->num_imported_functions;
2801 if (num_functions == 0) { 2839 if (num_functions == 0) {
2802 job_->ReopenHandlesInDeferredScope(); 2840 job_->ReopenHandlesInDeferredScope();
2803 // Degenerate case of an empty module. 2841 // Degenerate case of an empty module.
2804 job_->DoSync<FinishCompile>(); 2842 job_->DoSync<FinishCompile>();
2805 return; 2843 return;
2806 } 2844 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
2927 }; 2965 };
2928 2966
2929 //========================================================================== 2967 //==========================================================================
2930 // Step 5b (sync): Finish heap-allocated data structures. 2968 // Step 5b (sync): Finish heap-allocated data structures.
2931 //========================================================================== 2969 //==========================================================================
2932 class FinishCompile : public SyncCompileTask { 2970 class FinishCompile : public SyncCompileTask {
2933 void RunImpl() override { 2971 void RunImpl() override {
2934 TRACE_COMPILE("(5b) Finish compile...\n"); 2972 TRACE_COMPILE("(5b) Finish compile...\n");
2935 HandleScope scope(job_->isolate_); 2973 HandleScope scope(job_->isolate_);
2936 // At this point, compilation has completed. Update the code table. 2974 // At this point, compilation has completed. Update the code table.
2975 constexpr bool is_sync = true;
2937 for (size_t i = FLAG_skip_compiling_wasm_funcs; 2976 for (size_t i = FLAG_skip_compiling_wasm_funcs;
2938 i < job_->temp_instance_->function_code.size(); ++i) { 2977 i < job_->temp_instance_->function_code.size(); ++i) {
2939 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i))); 2978 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i)));
2940 RecordStats(job_->isolate_, code); 2979 RecordStats(job_->isolate_, code, !is_sync);
2941 } 2980 }
2942 2981
2943 // Create heap objects for script and module bytes to be stored in the 2982 // Create heap objects for script and module bytes to be stored in the
2944 // shared module data. Asm.js is not compiled asynchronously. 2983 // shared module data. Asm.js is not compiled asynchronously.
2945 Handle<Script> script = 2984 Handle<Script> script =
2946 CreateWasmScript(job_->isolate_, job_->wire_bytes_); 2985 CreateWasmScript(job_->isolate_, job_->wire_bytes_);
2947 Handle<ByteArray> asm_js_offset_table; 2986 Handle<ByteArray> asm_js_offset_table;
2948 // TODO(wasm): Improve efficiency of storing module wire bytes. 2987 // TODO(wasm): Improve efficiency of storing module wire bytes.
2949 // 1. Only store relevant sections, not function bodies 2988 // 1. Only store relevant sections, not function bodies
2950 // 2. Don't make a second copy of the bytes here; reuse the copy made 2989 // 2. Don't make a second copy of the bytes here; reuse the copy made
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2996 //========================================================================== 3035 //==========================================================================
2997 // Step 6 (sync): Compile JS->WASM wrappers. 3036 // Step 6 (sync): Compile JS->WASM wrappers.
2998 //========================================================================== 3037 //==========================================================================
2999 class CompileWrappers : public SyncCompileTask { 3038 class CompileWrappers : public SyncCompileTask {
3000 void RunImpl() override { 3039 void RunImpl() override {
3001 TRACE_COMPILE("(6) Compile wrappers...\n"); 3040 TRACE_COMPILE("(6) Compile wrappers...\n");
3002 // Compile JS->WASM wrappers for exported functions. 3041 // Compile JS->WASM wrappers for exported functions.
3003 HandleScope scope(job_->isolate_); 3042 HandleScope scope(job_->isolate_);
3004 JSToWasmWrapperCache js_to_wasm_cache; 3043 JSToWasmWrapperCache js_to_wasm_cache;
3005 int func_index = 0; 3044 int func_index = 0;
3045 constexpr bool is_sync = true;
3006 WasmModule* module = job_->compiled_module_->module(); 3046 WasmModule* module = job_->compiled_module_->module();
3007 for (auto exp : module->export_table) { 3047 for (auto exp : module->export_table) {
3008 if (exp.kind != kExternalFunction) continue; 3048 if (exp.kind != kExternalFunction) continue;
3009 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)), 3049 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)),
3010 job_->isolate_); 3050 job_->isolate_);
3011 Handle<Code> wrapper_code = 3051 Handle<Code> wrapper_code =
3012 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper( 3052 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(
3013 job_->isolate_, module, wasm_code, exp.index); 3053 job_->isolate_, module, wasm_code, exp.index);
3014 int export_index = 3054 int export_index =
3015 static_cast<int>(module->functions.size() + func_index); 3055 static_cast<int>(module->functions.size() + func_index);
3016 job_->code_table_->set(export_index, *wrapper_code); 3056 job_->code_table_->set(export_index, *wrapper_code);
3017 RecordStats(job_->isolate_, *wrapper_code); 3057 RecordStats(job_->isolate_, *wrapper_code, !is_sync);
3018 func_index++; 3058 func_index++;
3019 } 3059 }
3020 3060
3021 job_->DoSync<FinishModule>(); 3061 job_->DoSync<FinishModule>();
3022 } 3062 }
3023 }; 3063 };
3024 3064
3025 //========================================================================== 3065 //==========================================================================
3026 // Step 7 (sync): Finish the module and resolve the promise. 3066 // Step 7 (sync): Finish the module and resolve the promise.
3027 //========================================================================== 3067 //==========================================================================
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
3314 callee_compiled->instruction_start()); 3354 callee_compiled->instruction_start());
3315 } 3355 }
3316 DCHECK_EQ(non_compiled_functions.size(), idx); 3356 DCHECK_EQ(non_compiled_functions.size(), idx);
3317 } 3357 }
3318 3358
3319 Code* ret = 3359 Code* ret =
3320 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); 3360 Code::cast(compiled_module->code_table()->get(func_to_return_idx));
3321 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); 3361 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind());
3322 return handle(ret, isolate); 3362 return handle(ret, isolate);
3323 } 3363 }
OLDNEW
« no previous file with comments | « src/wasm/module-decoder.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698