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

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

Issue 2003383002: [wasm] Separate reloc info stats from code size stats. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 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 | « 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 "src/base/atomic-utils.h" 5 #include "src/base/atomic-utils.h"
6 #include "src/macro-assembler.h" 6 #include "src/macro-assembler.h"
7 #include "src/objects.h" 7 #include "src/objects.h"
8 #include "src/property-descriptor.h" 8 #include "src/property-descriptor.h"
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 } 444 }
445 445
446 Isolate* isolate_; 446 Isolate* isolate_;
447 std::vector<compiler::WasmCompilationUnit*>* compilation_units_; 447 std::vector<compiler::WasmCompilationUnit*>* compilation_units_;
448 std::queue<compiler::WasmCompilationUnit*>* executed_units_; 448 std::queue<compiler::WasmCompilationUnit*>* executed_units_;
449 base::Semaphore* on_finished_; 449 base::Semaphore* on_finished_;
450 base::Mutex* result_mutex_; 450 base::Mutex* result_mutex_;
451 base::AtomicNumber<size_t>* next_unit_; 451 base::AtomicNumber<size_t>* next_unit_;
452 }; 452 };
453 453
454 void record_code_size(uint32_t& total_code_size, Code* code) { 454 // Records statistics on the code generated by compiling WASM functions.
455 if (FLAG_print_wasm_code_size) { 455 struct CodeStats {
456 total_code_size += code->body_size() + code->relocation_info()->length(); 456 size_t code_size;
457 size_t reloc_size;
458
459 inline CodeStats() : code_size(0), reloc_size(0) {}
460
461 inline void Record(Code* code) {
462 if (FLAG_print_wasm_code_size) {
463 code_size += code->body_size();
464 reloc_size += code->relocation_info()->length();
465 }
457 } 466 }
458 } 467
468 inline void Report() {
469 if (FLAG_print_wasm_code_size) {
470 PrintF("Total generated wasm code: %zu bytes\n", code_size);
471 PrintF("Total generated wasm reloc: %zu bytes\n", reloc_size);
472 }
473 }
474 };
459 475
460 bool CompileWrappersToImportedFunctions(Isolate* isolate, WasmModule* module, 476 bool CompileWrappersToImportedFunctions(Isolate* isolate, WasmModule* module,
461 const Handle<JSReceiver> ffi, 477 const Handle<JSReceiver> ffi,
462 WasmModuleInstance* instance, 478 WasmModuleInstance* instance,
463 ErrorThrower* thrower, Factory* factory, 479 ErrorThrower* thrower, Factory* factory,
464 ModuleEnv* module_env, 480 ModuleEnv* module_env,
465 uint32_t& total_code_size) { 481 CodeStats& code_stats) {
466 uint32_t index = 0; 482 uint32_t index = 0;
467 if (module->import_table.size() > 0) { 483 if (module->import_table.size() > 0) {
468 instance->import_code.reserve(module->import_table.size()); 484 instance->import_code.reserve(module->import_table.size());
469 for (const WasmImport& import : module->import_table) { 485 for (const WasmImport& import : module->import_table) {
470 WasmName module_name = module->GetNameOrNull(import.module_name_offset, 486 WasmName module_name = module->GetNameOrNull(import.module_name_offset,
471 import.module_name_length); 487 import.module_name_length);
472 WasmName function_name = module->GetNameOrNull( 488 WasmName function_name = module->GetNameOrNull(
473 import.function_name_offset, import.function_name_length); 489 import.function_name_offset, import.function_name_length);
474 MaybeHandle<JSFunction> function = LookupFunction( 490 MaybeHandle<JSFunction> function = LookupFunction(
475 *thrower, factory, ffi, index, module_name, function_name); 491 *thrower, factory, ffi, index, module_name, function_name);
476 if (function.is_null()) return false; 492 if (function.is_null()) return false;
477 493
478 Handle<Code> code = compiler::CompileWasmToJSWrapper( 494 Handle<Code> code = compiler::CompileWasmToJSWrapper(
479 isolate, module_env, function.ToHandleChecked(), import.sig, 495 isolate, module_env, function.ToHandleChecked(), import.sig,
480 module_name, function_name); 496 module_name, function_name);
481 instance->import_code.push_back(code); 497 instance->import_code.push_back(code);
482 record_code_size(total_code_size, *code); 498 code_stats.Record(*code);
483 index++; 499 index++;
484 } 500 }
485 } 501 }
486 return true; 502 return true;
487 } 503 }
488 504
489 void InitializeParallelCompilation( 505 void InitializeParallelCompilation(
490 Isolate* isolate, std::vector<WasmFunction>& functions, 506 Isolate* isolate, std::vector<WasmFunction>& functions,
491 std::vector<compiler::WasmCompilationUnit*>& compilation_units, 507 std::vector<compiler::WasmCompilationUnit*>& compilation_units,
492 ModuleEnv& module_env, ErrorThrower& thrower) { 508 ModuleEnv& module_env, ErrorThrower& thrower) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 delete unit; 573 delete unit;
558 } 574 }
559 } 575 }
560 576
561 bool FinishCompilation(Isolate* isolate, WasmModule* module, 577 bool FinishCompilation(Isolate* isolate, WasmModule* module,
562 const Handle<JSReceiver> ffi, 578 const Handle<JSReceiver> ffi,
563 const std::vector<Handle<Code>>& results, 579 const std::vector<Handle<Code>>& results,
564 const WasmModuleInstance& instance, 580 const WasmModuleInstance& instance,
565 const Handle<FixedArray>& code_table, 581 const Handle<FixedArray>& code_table,
566 ErrorThrower& thrower, Factory* factory, 582 ErrorThrower& thrower, Factory* factory,
567 ModuleEnv& module_env, uint32_t& total_code_size, 583 ModuleEnv& module_env, CodeStats& code_stats,
568 PropertyDescriptor& desc) { 584 PropertyDescriptor& desc) {
569 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; 585 for (uint32_t i = FLAG_skip_compiling_wasm_funcs;
570 i < module->functions.size(); i++) { 586 i < module->functions.size(); i++) {
571 const WasmFunction& func = module->functions[i]; 587 const WasmFunction& func = module->functions[i];
572 if (thrower.error()) break; 588 if (thrower.error()) break;
573 589
574 DCHECK_EQ(i, func.func_index); 590 DCHECK_EQ(i, func.func_index);
575 WasmName str = module->GetName(func.name_offset, func.name_length); 591 WasmName str = module->GetName(func.name_offset, func.name_length);
576 Handle<Code> code = Handle<Code>::null(); 592 Handle<Code> code = Handle<Code>::null();
577 Handle<JSFunction> function = Handle<JSFunction>::null(); 593 Handle<JSFunction> function = Handle<JSFunction>::null();
578 Handle<String> function_name = Handle<String>::null(); 594 Handle<String> function_name = Handle<String>::null();
579 if (FLAG_wasm_num_compilation_tasks != 0) { 595 if (FLAG_wasm_num_compilation_tasks != 0) {
580 code = results[i]; 596 code = results[i];
581 } else { 597 } else {
582 // Compile the function. 598 // Compile the function.
583 code = compiler::WasmCompilationUnit::CompileWasmFunction( 599 code = compiler::WasmCompilationUnit::CompileWasmFunction(
584 &thrower, isolate, &module_env, &func); 600 &thrower, isolate, &module_env, &func);
585 } 601 }
586 if (code.is_null()) { 602 if (code.is_null()) {
587 thrower.Error("Compilation of #%d:%.*s failed.", i, str.length(), 603 thrower.Error("Compilation of #%d:%.*s failed.", i, str.length(),
588 str.start()); 604 str.start());
589 return false; 605 return false;
590 } 606 }
591 if (func.exported) { 607 if (func.exported) {
592 function_name = factory->InternalizeUtf8String(str); 608 function_name = factory->InternalizeUtf8String(str);
593 function = compiler::CompileJSToWasmWrapper( 609 function = compiler::CompileJSToWasmWrapper(
594 isolate, &module_env, function_name, code, instance.js_object, i); 610 isolate, &module_env, function_name, code, instance.js_object, i);
595 record_code_size(total_code_size, function->code()); 611 code_stats.Record(function->code());
596 } 612 }
597 if (!code.is_null()) { 613 if (!code.is_null()) {
598 // Install the code into the linker table. 614 // Install the code into the linker table.
599 module_env.linker->Finish(i, code); 615 module_env.linker->Finish(i, code);
600 code_table->set(i, *code); 616 code_table->set(i, *code);
601 record_code_size(total_code_size, *code); 617 code_stats.Record(*code);
602 } 618 }
603 if (func.exported) { 619 if (func.exported) {
604 // Exported functions are installed as read-only properties on the 620 // Exported functions are installed as read-only properties on the
605 // module. 621 // module.
606 desc.set_value(function); 622 desc.set_value(function);
607 Maybe<bool> status = JSReceiver::DefineOwnProperty( 623 Maybe<bool> status = JSReceiver::DefineOwnProperty(
608 isolate, instance.js_object, function_name, &desc, 624 isolate, instance.js_object, function_name, &desc,
609 Object::THROW_ON_ERROR); 625 Object::THROW_ON_ERROR);
610 if (!status.IsJust()) 626 if (!status.IsJust())
611 thrower.Error("export of %.*s failed.", str.length(), str.start()); 627 thrower.Error("export of %.*s failed.", str.length(), str.start());
(...skipping 15 matching lines...) Expand all
627 isolate->counters()->wasm_instantiate_module_time()); 643 isolate->counters()->wasm_instantiate_module_time());
628 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); 644 ErrorThrower thrower(isolate, "WasmModule::Instantiate()");
629 Factory* factory = isolate->factory(); 645 Factory* factory = isolate->factory();
630 646
631 PropertyDescriptor desc; 647 PropertyDescriptor desc;
632 desc.set_writable(false); 648 desc.set_writable(false);
633 649
634 // If FLAG_print_wasm_code_size is set, this aggregates the sum of all code 650 // If FLAG_print_wasm_code_size is set, this aggregates the sum of all code
635 // objects created for this module. 651 // objects created for this module.
636 // TODO(titzer): switch this to TRACE_EVENT 652 // TODO(titzer): switch this to TRACE_EVENT
637 uint32_t total_code_size = 0; 653 CodeStats code_stats;
638 654
639 //------------------------------------------------------------------------- 655 //-------------------------------------------------------------------------
640 // Allocate the instance and its JS counterpart. 656 // Allocate the instance and its JS counterpart.
641 //------------------------------------------------------------------------- 657 //-------------------------------------------------------------------------
642 Handle<Map> map = factory->NewMap( 658 Handle<Map> map = factory->NewMap(
643 JS_OBJECT_TYPE, 659 JS_OBJECT_TYPE,
644 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 660 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
645 WasmModuleInstance instance(this); 661 WasmModuleInstance instance(this);
646 instance.context = isolate->native_context(); 662 instance.context = isolate->native_context();
647 instance.js_object = factory->NewJSObjectFromMap(map, TENURED); 663 instance.js_object = factory->NewJSObjectFromMap(map, TENURED);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 module_env.module = this; 703 module_env.module = this;
688 module_env.instance = &instance; 704 module_env.instance = &instance;
689 module_env.linker = &linker; 705 module_env.linker = &linker;
690 module_env.origin = origin; 706 module_env.origin = origin;
691 707
692 //------------------------------------------------------------------------- 708 //-------------------------------------------------------------------------
693 // Compile wrappers to imported functions. 709 // Compile wrappers to imported functions.
694 //------------------------------------------------------------------------- 710 //-------------------------------------------------------------------------
695 if (!CompileWrappersToImportedFunctions(isolate, this, ffi, &instance, 711 if (!CompileWrappersToImportedFunctions(isolate, this, ffi, &instance,
696 &thrower, factory, &module_env, 712 &thrower, factory, &module_env,
697 total_code_size)) { 713 code_stats)) {
698 return MaybeHandle<JSObject>(); 714 return MaybeHandle<JSObject>();
699 } 715 }
700 //------------------------------------------------------------------------- 716 //-------------------------------------------------------------------------
701 // Compile all functions in the module. 717 // Compile all functions in the module.
702 //------------------------------------------------------------------------- 718 //-------------------------------------------------------------------------
703 { 719 {
704 isolate->counters()->wasm_functions_per_module()->AddSample( 720 isolate->counters()->wasm_functions_per_module()->AddSample(
705 static_cast<int>(functions.size())); 721 static_cast<int>(functions.size()));
706 722
707 // Data structures for the parallel compilation. 723 // Data structures for the parallel compilation.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 FinishCompilationUnits(this, executed_units, results, result_mutex); 778 FinishCompilationUnits(this, executed_units, results, result_mutex);
763 } 779 }
764 // 4) After the parallel phase of all compilation units has started, the 780 // 4) After the parallel phase of all compilation units has started, the
765 // main thread waits for all {WasmCompilationTask} instances to finish. 781 // main thread waits for all {WasmCompilationTask} instances to finish.
766 WaitForCompilationTasks(isolate, task_ids.get(), pending_tasks); 782 WaitForCompilationTasks(isolate, task_ids.get(), pending_tasks);
767 // Finish the compilation of the remaining compilation units. 783 // Finish the compilation of the remaining compilation units.
768 FinishCompilationUnits(this, executed_units, results, result_mutex); 784 FinishCompilationUnits(this, executed_units, results, result_mutex);
769 } 785 }
770 // 5) The main thread finishes the compilation. 786 // 5) The main thread finishes the compilation.
771 if (!FinishCompilation(isolate, this, ffi, results, instance, code_table, 787 if (!FinishCompilation(isolate, this, ffi, results, instance, code_table,
772 thrower, factory, module_env, total_code_size, 788 thrower, factory, module_env, code_stats, desc)) {
773 desc)) {
774 instance.js_object = Handle<JSObject>::null(); 789 instance.js_object = Handle<JSObject>::null();
775 } 790 }
776 791
777 // Patch all direct call sites. 792 // Patch all direct call sites.
778 linker.Link(instance.function_table, this->function_table); 793 linker.Link(instance.function_table, this->function_table);
779 instance.js_object->SetInternalField(kWasmModuleFunctionTable, 794 instance.js_object->SetInternalField(kWasmModuleFunctionTable,
780 Smi::FromInt(0)); 795 Smi::FromInt(0));
781 796
782 //------------------------------------------------------------------------- 797 //-------------------------------------------------------------------------
783 // Create and populate the exports object. 798 // Create and populate the exports object.
(...skipping 10 matching lines...) Expand all
794 809
795 // Compile wrappers and add them to the exports object. 810 // Compile wrappers and add them to the exports object.
796 for (const WasmExport& exp : export_table) { 811 for (const WasmExport& exp : export_table) {
797 if (thrower.error()) break; 812 if (thrower.error()) break;
798 WasmName str = GetName(exp.name_offset, exp.name_length); 813 WasmName str = GetName(exp.name_offset, exp.name_length);
799 Handle<String> name = factory->InternalizeUtf8String(str); 814 Handle<String> name = factory->InternalizeUtf8String(str);
800 Handle<Code> code = linker.GetFunctionCode(exp.func_index); 815 Handle<Code> code = linker.GetFunctionCode(exp.func_index);
801 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper( 816 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper(
802 isolate, &module_env, name, code, instance.js_object, 817 isolate, &module_env, name, code, instance.js_object,
803 exp.func_index); 818 exp.func_index);
804 record_code_size(total_code_size, function->code()); 819 code_stats.Record(function->code());
805 desc.set_value(function); 820 desc.set_value(function);
806 Maybe<bool> status = JSReceiver::DefineOwnProperty( 821 Maybe<bool> status = JSReceiver::DefineOwnProperty(
807 isolate, exports_object, name, &desc, Object::THROW_ON_ERROR); 822 isolate, exports_object, name, &desc, Object::THROW_ON_ERROR);
808 if (!status.IsJust()) 823 if (!status.IsJust())
809 thrower.Error("export of %.*s failed.", str.length(), str.start()); 824 thrower.Error("export of %.*s failed.", str.length(), str.start());
810 } 825 }
811 826
812 if (mem_export) { 827 if (mem_export) {
813 // Export the memory as a named property. 828 // Export the memory as a named property.
814 Handle<String> name = factory->InternalizeUtf8String("memory"); 829 Handle<String> name = factory->InternalizeUtf8String("memory");
815 JSObject::AddProperty(exports_object, name, instance.mem_buffer, 830 JSObject::AddProperty(exports_object, name, instance.mem_buffer,
816 READ_ONLY); 831 READ_ONLY);
817 } 832 }
818 } 833 }
819 } 834 }
820 835
821 //------------------------------------------------------------------------- 836 //-------------------------------------------------------------------------
822 // Attach an array with function names and an array with offsets into that 837 // Attach an array with function names and an array with offsets into that
823 // first array. 838 // first array.
824 //------------------------------------------------------------------------- 839 //-------------------------------------------------------------------------
825 { 840 {
826 Handle<Object> arr = BuildFunctionNamesTable(isolate, module_env.module); 841 Handle<Object> arr = BuildFunctionNamesTable(isolate, module_env.module);
827 instance.js_object->SetInternalField(kWasmFunctionNamesArray, *arr); 842 instance.js_object->SetInternalField(kWasmFunctionNamesArray, *arr);
828 } 843 }
829 844
830 if (FLAG_print_wasm_code_size) 845 code_stats.Report();
831 printf("Total generated wasm code: %u bytes\n", total_code_size);
832 846
833 // Run the start function if one was specified. 847 // Run the start function if one was specified.
834 if (this->start_function_index >= 0) { 848 if (this->start_function_index >= 0) {
835 HandleScope scope(isolate); 849 HandleScope scope(isolate);
836 uint32_t index = static_cast<uint32_t>(this->start_function_index); 850 uint32_t index = static_cast<uint32_t>(this->start_function_index);
837 Handle<String> name = isolate->factory()->NewStringFromStaticChars("start"); 851 Handle<String> name = isolate->factory()->NewStringFromStaticChars("start");
838 Handle<Code> code = linker.GetFunctionCode(index); 852 Handle<Code> code = linker.GetFunctionCode(index);
839 Handle<JSFunction> jsfunc = compiler::CompileJSToWasmWrapper( 853 Handle<JSFunction> jsfunc = compiler::CompileJSToWasmWrapper(
840 isolate, &module_env, name, code, instance.js_object, index); 854 isolate, &module_env, name, code, instance.js_object, index);
841 855
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 uint32_t func_index) { 994 uint32_t func_index) {
981 Object* func_names_arr_obj = wasm->GetInternalField(kWasmFunctionNamesArray); 995 Object* func_names_arr_obj = wasm->GetInternalField(kWasmFunctionNamesArray);
982 if (func_names_arr_obj->IsUndefined()) return Handle<String>::null(); 996 if (func_names_arr_obj->IsUndefined()) return Handle<String>::null();
983 return GetWasmFunctionNameFromTable( 997 return GetWasmFunctionNameFromTable(
984 handle(ByteArray::cast(func_names_arr_obj)), func_index); 998 handle(ByteArray::cast(func_names_arr_obj)), func_index);
985 } 999 }
986 1000
987 } // namespace wasm 1001 } // namespace wasm
988 } // namespace internal 1002 } // namespace internal
989 } // namespace v8 1003 } // namespace v8
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