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/base/atomic-utils.h" | 7 #include "src/base/atomic-utils.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 | 9 |
10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 if (instance->has_globals_buffer()) { | 297 if (instance->has_globals_buffer()) { |
298 old_address = | 298 old_address = |
299 static_cast<Address>(instance->get_globals_buffer()->backing_store()); | 299 static_cast<Address>(instance->get_globals_buffer()->backing_store()); |
300 } | 300 } |
301 return old_address; | 301 return old_address; |
302 } | 302 } |
303 | 303 |
304 void InitializeParallelCompilation( | 304 void InitializeParallelCompilation( |
305 Isolate* isolate, const std::vector<WasmFunction>& functions, | 305 Isolate* isolate, const std::vector<WasmFunction>& functions, |
306 std::vector<compiler::WasmCompilationUnit*>& compilation_units, | 306 std::vector<compiler::WasmCompilationUnit*>& compilation_units, |
307 ModuleEnv& module_env, ErrorThrower* thrower) { | 307 ModuleBytesEnv& module_env, ErrorThrower* thrower) { |
308 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) { | 308 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); ++i) { |
309 const WasmFunction* func = &functions[i]; | 309 const WasmFunction* func = &functions[i]; |
310 compilation_units[i] = | 310 compilation_units[i] = |
311 func->imported ? nullptr : new compiler::WasmCompilationUnit( | 311 func->imported ? nullptr : new compiler::WasmCompilationUnit( |
312 thrower, isolate, &module_env, func, i); | 312 thrower, isolate, &module_env, func, i); |
313 } | 313 } |
314 } | 314 } |
315 | 315 |
316 uint32_t* StartCompilationTasks( | 316 uint32_t* StartCompilationTasks( |
317 Isolate* isolate, | 317 Isolate* isolate, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 } | 361 } |
362 unit = executed_units.front(); | 362 unit = executed_units.front(); |
363 executed_units.pop(); | 363 executed_units.pop(); |
364 } | 364 } |
365 int j = unit->index(); | 365 int j = unit->index(); |
366 results[j] = unit->FinishCompilation(); | 366 results[j] = unit->FinishCompilation(); |
367 delete unit; | 367 delete unit; |
368 } | 368 } |
369 } | 369 } |
370 | 370 |
371 void CompileInParallel(Isolate* isolate, const WasmModule* module, | 371 void CompileInParallel(Isolate* isolate, ModuleBytesEnv* module_env, |
372 std::vector<Handle<Code>>& functions, | 372 std::vector<Handle<Code>>& functions, |
373 ErrorThrower* thrower, ModuleEnv* module_env) { | 373 ErrorThrower* thrower) { |
| 374 const WasmModule* module = module_env->module; |
374 // Data structures for the parallel compilation. | 375 // Data structures for the parallel compilation. |
375 std::vector<compiler::WasmCompilationUnit*> compilation_units( | 376 std::vector<compiler::WasmCompilationUnit*> compilation_units( |
376 module->functions.size()); | 377 module->functions.size()); |
377 std::queue<compiler::WasmCompilationUnit*> executed_units; | 378 std::queue<compiler::WasmCompilationUnit*> executed_units; |
378 | 379 |
379 //----------------------------------------------------------------------- | 380 //----------------------------------------------------------------------- |
380 // For parallel compilation: | 381 // For parallel compilation: |
381 // 1) The main thread allocates a compilation unit for each wasm function | 382 // 1) The main thread allocates a compilation unit for each wasm function |
382 // and stores them in the vector {compilation_units}. | 383 // and stores them in the vector {compilation_units}. |
383 // 2) The main thread spawns {WasmCompilationTask} instances which run on | 384 // 2) The main thread spawns {WasmCompilationTask} instances which run on |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 // memory. | 426 // memory. |
426 FinishCompilationUnits(executed_units, functions, result_mutex); | 427 FinishCompilationUnits(executed_units, functions, result_mutex); |
427 } | 428 } |
428 // 4) After the parallel phase of all compilation units has started, the | 429 // 4) After the parallel phase of all compilation units has started, the |
429 // main thread waits for all {WasmCompilationTask} instances to finish. | 430 // main thread waits for all {WasmCompilationTask} instances to finish. |
430 WaitForCompilationTasks(isolate, task_ids.get(), module->pending_tasks.get()); | 431 WaitForCompilationTasks(isolate, task_ids.get(), module->pending_tasks.get()); |
431 // Finish the compilation of the remaining compilation units. | 432 // Finish the compilation of the remaining compilation units. |
432 FinishCompilationUnits(executed_units, functions, result_mutex); | 433 FinishCompilationUnits(executed_units, functions, result_mutex); |
433 } | 434 } |
434 | 435 |
435 void CompileSequentially(Isolate* isolate, const WasmModule* module, | 436 void CompileSequentially(Isolate* isolate, ModuleBytesEnv* module_env, |
436 std::vector<Handle<Code>>& functions, | 437 std::vector<Handle<Code>>& functions, |
437 ErrorThrower* thrower, ModuleEnv* module_env) { | 438 ErrorThrower* thrower) { |
438 DCHECK(!thrower->error()); | 439 DCHECK(!thrower->error()); |
439 | 440 |
| 441 const WasmModule* module = module_env->module; |
440 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; | 442 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; |
441 i < module->functions.size(); ++i) { | 443 i < module->functions.size(); ++i) { |
442 const WasmFunction& func = module->functions[i]; | 444 const WasmFunction& func = module->functions[i]; |
443 if (func.imported) continue; // Imports are compiled at instantiation time. | 445 if (func.imported) continue; // Imports are compiled at instantiation time. |
444 | 446 |
445 WasmName str = module->GetName(func.name_offset, func.name_length); | |
446 Handle<Code> code = Handle<Code>::null(); | 447 Handle<Code> code = Handle<Code>::null(); |
447 // Compile the function. | 448 // Compile the function. |
448 code = compiler::WasmCompilationUnit::CompileWasmFunction( | 449 code = compiler::WasmCompilationUnit::CompileWasmFunction( |
449 thrower, isolate, module_env, &func); | 450 thrower, isolate, module_env, &func); |
450 if (code.is_null()) { | 451 if (code.is_null()) { |
| 452 WasmName str = module_env->GetName(&func); |
451 thrower->CompileError("Compilation of #%d:%.*s failed.", i, str.length(), | 453 thrower->CompileError("Compilation of #%d:%.*s failed.", i, str.length(), |
452 str.start()); | 454 str.start()); |
453 break; | 455 break; |
454 } | 456 } |
455 // Install the code into the linker table. | 457 // Install the code into the linker table. |
456 functions[i] = code; | 458 functions[i] = code; |
457 } | 459 } |
458 } | 460 } |
459 | 461 |
460 void PatchDirectCalls(Handle<FixedArray> old_functions, | 462 void PatchDirectCalls(Handle<FixedArray> old_functions, |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 } | 775 } |
774 | 776 |
775 std::ostream& wasm::operator<<(std::ostream& os, const WasmFunction& function) { | 777 std::ostream& wasm::operator<<(std::ostream& os, const WasmFunction& function) { |
776 os << "WASM function with signature " << *function.sig; | 778 os << "WASM function with signature " << *function.sig; |
777 | 779 |
778 os << " code bytes: " | 780 os << " code bytes: " |
779 << (function.code_end_offset - function.code_start_offset); | 781 << (function.code_end_offset - function.code_start_offset); |
780 return os; | 782 return os; |
781 } | 783 } |
782 | 784 |
783 std::ostream& wasm::operator<<(std::ostream& os, const WasmFunctionName& pair) { | 785 std::ostream& wasm::operator<<(std::ostream& os, const WasmFunctionName& name) { |
784 os << "#" << pair.function_->func_index << ":"; | 786 os << "#" << name.function_->func_index; |
785 if (pair.function_->name_offset > 0) { | 787 if (name.function_->name_offset > 0) { |
786 if (pair.module_) { | 788 if (name.name_.start()) { |
787 WasmName name = pair.module_->GetName(pair.function_->name_offset, | 789 os << ":"; |
788 pair.function_->name_length); | 790 os.write(name.name_.start(), name.name_.length()); |
789 os.write(name.start(), name.length()); | |
790 } else { | |
791 os << "+" << pair.function_->func_index; | |
792 } | 791 } |
793 } else { | 792 } else { |
794 os << "?"; | 793 os << "?"; |
795 } | 794 } |
796 return os; | 795 return os; |
797 } | 796 } |
798 | 797 |
799 WasmInstanceObject* wasm::GetOwningWasmInstance(Code* code) { | 798 WasmInstanceObject* wasm::GetOwningWasmInstance(Code* code) { |
800 DCHECK(code->kind() == Code::WASM_FUNCTION); | 799 DCHECK(code->kind() == Code::WASM_FUNCTION); |
801 DisallowHeapAllocation no_gc; | 800 DisallowHeapAllocation no_gc; |
802 FixedArray* deopt_data = code->deoptimization_data(); | 801 FixedArray* deopt_data = code->deoptimization_data(); |
803 DCHECK_NOT_NULL(deopt_data); | 802 DCHECK_NOT_NULL(deopt_data); |
804 DCHECK(deopt_data->length() == 2); | 803 DCHECK(deopt_data->length() == 2); |
805 Object* weak_link = deopt_data->get(0); | 804 Object* weak_link = deopt_data->get(0); |
806 if (!weak_link->IsWeakCell()) return nullptr; | 805 if (!weak_link->IsWeakCell()) return nullptr; |
807 WeakCell* cell = WeakCell::cast(weak_link); | 806 WeakCell* cell = WeakCell::cast(weak_link); |
808 if (!cell->value()) return nullptr; | 807 if (!cell->value()) return nullptr; |
809 return WasmInstanceObject::cast(cell->value()); | 808 return WasmInstanceObject::cast(cell->value()); |
810 } | 809 } |
811 | 810 |
812 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, | 811 int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, |
813 int func_index) { | 812 int func_index) { |
814 return GetFunctionOffsetAndLength(compiled_module, func_index).first; | 813 return GetFunctionOffsetAndLength(compiled_module, func_index).first; |
815 } | 814 } |
816 | 815 |
817 WasmModule::WasmModule(Zone* owned, const byte* module_start) | 816 WasmModule::WasmModule(Zone* owned) |
818 : owned_zone(owned), | 817 : owned_zone(owned), pending_tasks(new base::Semaphore(0)) {} |
819 module_start(module_start), | |
820 pending_tasks(new base::Semaphore(0)) {} | |
821 | 818 |
822 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( | 819 MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( |
823 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper, | 820 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper, |
824 ErrorThrower* thrower) const { | 821 ErrorThrower* thrower, const ModuleWireBytes& wire_bytes) const { |
825 Factory* factory = isolate->factory(); | 822 Factory* factory = isolate->factory(); |
826 | 823 |
827 MaybeHandle<WasmCompiledModule> nothing; | 824 MaybeHandle<WasmCompiledModule> nothing; |
828 | 825 |
829 WasmInstance temp_instance(this); | 826 WasmInstance temp_instance(this); |
830 temp_instance.context = isolate->native_context(); | 827 temp_instance.context = isolate->native_context(); |
831 temp_instance.mem_size = WasmModule::kPageSize * this->min_mem_pages; | 828 temp_instance.mem_size = WasmModule::kPageSize * min_mem_pages; |
832 temp_instance.mem_start = nullptr; | 829 temp_instance.mem_start = nullptr; |
833 temp_instance.globals_start = nullptr; | 830 temp_instance.globals_start = nullptr; |
834 | 831 |
835 // Initialize the indirect tables with placeholders. | 832 // Initialize the indirect tables with placeholders. |
836 int function_table_count = static_cast<int>(this->function_tables.size()); | 833 int function_table_count = static_cast<int>(function_tables.size()); |
837 Handle<FixedArray> function_tables = | 834 Handle<FixedArray> function_tables = |
838 factory->NewFixedArray(function_table_count); | 835 factory->NewFixedArray(function_table_count); |
839 for (int i = 0; i < function_table_count; ++i) { | 836 for (int i = 0; i < function_table_count; ++i) { |
840 temp_instance.function_tables[i] = factory->NewFixedArray(0); | 837 temp_instance.function_tables[i] = factory->NewFixedArray(0); |
841 function_tables->set(i, *temp_instance.function_tables[i]); | 838 function_tables->set(i, *temp_instance.function_tables[i]); |
842 } | 839 } |
843 | 840 |
844 HistogramTimerScope wasm_compile_module_time_scope( | 841 HistogramTimerScope wasm_compile_module_time_scope( |
845 isolate->counters()->wasm_compile_module_time()); | 842 isolate->counters()->wasm_compile_module_time()); |
846 | 843 |
847 ModuleEnv module_env; | 844 ModuleBytesEnv module_env(this, &temp_instance, wire_bytes); |
848 module_env.module = this; | |
849 module_env.instance = &temp_instance; | |
850 module_env.origin = origin; | |
851 | 845 |
852 // The {code_table} array contains import wrappers and functions (which | 846 // The {code_table} array contains import wrappers and functions (which |
853 // are both included in {functions.size()}, and export wrappers. | 847 // are both included in {functions.size()}, and export wrappers. |
854 int code_table_size = | 848 int code_table_size = |
855 static_cast<int>(functions.size() + num_exported_functions); | 849 static_cast<int>(functions.size() + num_exported_functions); |
856 Handle<FixedArray> code_table = | 850 Handle<FixedArray> code_table = |
857 factory->NewFixedArray(static_cast<int>(code_table_size), TENURED); | 851 factory->NewFixedArray(static_cast<int>(code_table_size), TENURED); |
858 | 852 |
859 // Initialize the code table with placeholders. | 853 // Initialize the code table with placeholders. |
860 for (uint32_t i = 0; i < functions.size(); ++i) { | 854 for (uint32_t i = 0; i < functions.size(); ++i) { |
861 Code::Kind kind = Code::WASM_FUNCTION; | 855 Code::Kind kind = Code::WASM_FUNCTION; |
862 if (i < num_imported_functions) kind = Code::WASM_TO_JS_FUNCTION; | 856 if (i < num_imported_functions) kind = Code::WASM_TO_JS_FUNCTION; |
863 Handle<Code> placeholder = CreatePlaceholder(factory, i, kind); | 857 Handle<Code> placeholder = CreatePlaceholder(factory, i, kind); |
864 code_table->set(static_cast<int>(i), *placeholder); | 858 code_table->set(static_cast<int>(i), *placeholder); |
865 temp_instance.function_code[i] = placeholder; | 859 temp_instance.function_code[i] = placeholder; |
866 } | 860 } |
867 | 861 |
868 isolate->counters()->wasm_functions_per_module()->AddSample( | 862 isolate->counters()->wasm_functions_per_module()->AddSample( |
869 static_cast<int>(functions.size())); | 863 static_cast<int>(functions.size())); |
870 if (!FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks != 0) { | 864 if (!FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks != 0) { |
871 // Avoid a race condition by collecting results into a second vector. | 865 // Avoid a race condition by collecting results into a second vector. |
872 std::vector<Handle<Code>> results; | 866 std::vector<Handle<Code>> results; |
873 results.reserve(temp_instance.function_code.size()); | 867 results.reserve(temp_instance.function_code.size()); |
874 for (size_t i = 0; i < temp_instance.function_code.size(); ++i) { | 868 for (size_t i = 0; i < temp_instance.function_code.size(); ++i) { |
875 results.push_back(temp_instance.function_code[i]); | 869 results.push_back(temp_instance.function_code[i]); |
876 } | 870 } |
877 CompileInParallel(isolate, this, results, thrower, &module_env); | 871 CompileInParallel(isolate, &module_env, results, thrower); |
878 | 872 |
879 for (size_t i = 0; i < results.size(); ++i) { | 873 for (size_t i = 0; i < results.size(); ++i) { |
880 temp_instance.function_code[i] = results[i]; | 874 temp_instance.function_code[i] = results[i]; |
881 } | 875 } |
882 } else { | 876 } else { |
883 CompileSequentially(isolate, this, temp_instance.function_code, thrower, | 877 CompileSequentially(isolate, &module_env, temp_instance.function_code, |
884 &module_env); | 878 thrower); |
885 } | 879 } |
886 if (thrower->error()) return nothing; | 880 if (thrower->error()) return nothing; |
887 | 881 |
888 // At this point, compilation has completed. Update the code table. | 882 // At this point, compilation has completed. Update the code table. |
889 for (size_t i = FLAG_skip_compiling_wasm_funcs; | 883 for (size_t i = FLAG_skip_compiling_wasm_funcs; |
890 i < temp_instance.function_code.size(); ++i) { | 884 i < temp_instance.function_code.size(); ++i) { |
891 Code* code = *temp_instance.function_code[i]; | 885 Code* code = *temp_instance.function_code[i]; |
892 code_table->set(static_cast<int>(i), code); | 886 code_table->set(static_cast<int>(i), code); |
893 } | 887 } |
894 | 888 |
(...skipping 22 matching lines...) Expand all Loading... |
917 ret->set_function_tables(function_tables); | 911 ret->set_function_tables(function_tables); |
918 ret->set_empty_function_tables(function_tables); | 912 ret->set_empty_function_tables(function_tables); |
919 } | 913 } |
920 | 914 |
921 // Compile JS->WASM wrappers for exported functions. | 915 // Compile JS->WASM wrappers for exported functions. |
922 int func_index = 0; | 916 int func_index = 0; |
923 for (auto exp : export_table) { | 917 for (auto exp : export_table) { |
924 if (exp.kind != kExternalFunction) continue; | 918 if (exp.kind != kExternalFunction) continue; |
925 Handle<Code> wasm_code = | 919 Handle<Code> wasm_code = |
926 code_table->GetValueChecked<Code>(isolate, exp.index); | 920 code_table->GetValueChecked<Code>(isolate, exp.index); |
927 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( | 921 Handle<Code> wrapper_code = |
928 isolate, &module_env, wasm_code, exp.index); | 922 compiler::CompileJSToWasmWrapper(isolate, this, wasm_code, exp.index); |
929 int export_index = static_cast<int>(functions.size() + func_index); | 923 int export_index = static_cast<int>(functions.size() + func_index); |
930 code_table->set(export_index, *wrapper_code); | 924 code_table->set(export_index, *wrapper_code); |
931 func_index++; | 925 func_index++; |
932 } | 926 } |
933 | 927 |
934 { | 928 { |
935 // TODO(wasm): only save the sections necessary to deserialize a | 929 // TODO(wasm): only save the sections necessary to deserialize a |
936 // {WasmModule}. E.g. function bodies could be omitted. | 930 // {WasmModule}. E.g. function bodies could be omitted. |
937 size_t module_bytes_len = module_end - module_start; | |
938 DCHECK_LE(module_bytes_len, static_cast<size_t>(kMaxInt)); | |
939 Vector<const uint8_t> module_bytes_vec(module_start, | |
940 static_cast<int>(module_bytes_len)); | |
941 Handle<String> module_bytes_string = | 931 Handle<String> module_bytes_string = |
942 factory->NewStringFromOneByte(module_bytes_vec, TENURED) | 932 factory->NewStringFromOneByte(wire_bytes.module_bytes, TENURED) |
943 .ToHandleChecked(); | 933 .ToHandleChecked(); |
944 DCHECK(module_bytes_string->IsSeqOneByteString()); | 934 DCHECK(module_bytes_string->IsSeqOneByteString()); |
945 ret->set_module_bytes(Handle<SeqOneByteString>::cast(module_bytes_string)); | 935 ret->set_module_bytes(Handle<SeqOneByteString>::cast(module_bytes_string)); |
946 } | 936 } |
947 | 937 |
948 return ret; | 938 return ret; |
949 } | 939 } |
950 | 940 |
951 static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate, | 941 static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate, |
952 Handle<Object> target) { | 942 Handle<Object> target) { |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 GlobalHandles::MakeWeak(global_handle.location(), | 1293 GlobalHandles::MakeWeak(global_handle.location(), |
1304 global_handle.location(), &InstanceFinalizer, | 1294 global_handle.location(), &InstanceFinalizer, |
1305 v8::WeakCallbackType::kFinalizer); | 1295 v8::WeakCallbackType::kFinalizer); |
1306 } | 1296 } |
1307 } | 1297 } |
1308 //-------------------------------------------------------------------------- | 1298 //-------------------------------------------------------------------------- |
1309 // Run the start function if one was specified. | 1299 // Run the start function if one was specified. |
1310 //-------------------------------------------------------------------------- | 1300 //-------------------------------------------------------------------------- |
1311 if (module_->start_function_index >= 0) { | 1301 if (module_->start_function_index >= 0) { |
1312 HandleScope scope(isolate_); | 1302 HandleScope scope(isolate_); |
1313 ModuleEnv module_env; | |
1314 module_env.module = module_; | |
1315 module_env.instance = nullptr; | |
1316 module_env.origin = module_->origin; | |
1317 int start_index = module_->start_function_index; | 1303 int start_index = module_->start_function_index; |
1318 Handle<Code> startup_code = | 1304 Handle<Code> startup_code = |
1319 code_table->GetValueChecked<Code>(isolate_, start_index); | 1305 code_table->GetValueChecked<Code>(isolate_, start_index); |
1320 FunctionSig* sig = module_->functions[start_index].sig; | 1306 FunctionSig* sig = module_->functions[start_index].sig; |
1321 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( | 1307 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( |
1322 isolate_, &module_env, startup_code, start_index); | 1308 isolate_, module_, startup_code, start_index); |
1323 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( | 1309 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( |
1324 isolate_, instance, factory->InternalizeUtf8String("start"), | 1310 isolate_, instance, factory->InternalizeUtf8String("start"), |
1325 wrapper_code, static_cast<int>(sig->parameter_count()), start_index); | 1311 wrapper_code, static_cast<int>(sig->parameter_count()), start_index); |
1326 RecordStats(isolate_, *startup_code); | 1312 RecordStats(isolate_, *startup_code); |
1327 // Call the JS function. | 1313 // Call the JS function. |
1328 Handle<Object> undefined = factory->undefined_value(); | 1314 Handle<Object> undefined = factory->undefined_value(); |
1329 MaybeHandle<Object> retval = | 1315 MaybeHandle<Object> retval = |
1330 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); | 1316 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); |
1331 | 1317 |
1332 if (retval.is_null()) { | 1318 if (retval.is_null()) { |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1887 // No JSFunction entry yet exists for this function. Create one. | 1873 // No JSFunction entry yet exists for this function. Create one. |
1888 // TODO(titzer): We compile JS->WASM wrappers for functions are | 1874 // TODO(titzer): We compile JS->WASM wrappers for functions are |
1889 // not exported but are in an exported table. This should be done | 1875 // not exported but are in an exported table. This should be done |
1890 // at module compile time and cached instead. | 1876 // at module compile time and cached instead. |
1891 WasmInstance temp_instance(module_); | 1877 WasmInstance temp_instance(module_); |
1892 temp_instance.context = isolate_->native_context(); | 1878 temp_instance.context = isolate_->native_context(); |
1893 temp_instance.mem_size = 0; | 1879 temp_instance.mem_size = 0; |
1894 temp_instance.mem_start = nullptr; | 1880 temp_instance.mem_start = nullptr; |
1895 temp_instance.globals_start = nullptr; | 1881 temp_instance.globals_start = nullptr; |
1896 | 1882 |
1897 ModuleEnv module_env; | |
1898 module_env.module = module_; | |
1899 module_env.instance = &temp_instance; | |
1900 module_env.origin = module_->origin; | |
1901 | |
1902 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( | 1883 Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper( |
1903 isolate_, &module_env, wasm_code, func_index); | 1884 isolate_, module_, wasm_code, func_index); |
1904 Handle<WasmExportedFunction> js_function = | 1885 Handle<WasmExportedFunction> js_function = |
1905 WasmExportedFunction::New( | 1886 WasmExportedFunction::New( |
1906 isolate_, instance, isolate_->factory()->empty_string(), | 1887 isolate_, instance, isolate_->factory()->empty_string(), |
1907 wrapper_code, | 1888 wrapper_code, |
1908 static_cast<int>(function->sig->parameter_count()), | 1889 static_cast<int>(function->sig->parameter_count()), |
1909 func_index); | 1890 func_index); |
1910 js_wrappers_[func_index] = js_function; | 1891 js_wrappers_[func_index] = js_function; |
1911 } | 1892 } |
1912 table_instance.js_wrappers->set(table_index, | 1893 table_instance.js_wrappers->set(table_index, |
1913 *js_wrappers_[func_index]); | 1894 *js_wrappers_[func_index]); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1979 return compiled_module->has_asm_js_offset_table(); | 1960 return compiled_module->has_asm_js_offset_table(); |
1980 } | 1961 } |
1981 | 1962 |
1982 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { | 1963 Handle<Script> wasm::GetScript(Handle<JSObject> instance) { |
1983 WasmCompiledModule* compiled_module = | 1964 WasmCompiledModule* compiled_module = |
1984 WasmInstanceObject::cast(*instance)->get_compiled_module(); | 1965 WasmInstanceObject::cast(*instance)->get_compiled_module(); |
1985 DCHECK(compiled_module->has_script()); | 1966 DCHECK(compiled_module->has_script()); |
1986 return compiled_module->script(); | 1967 return compiled_module->script(); |
1987 } | 1968 } |
1988 | 1969 |
| 1970 // TODO(clemensh): Make this a non-static method of WasmCompiledModule. |
1989 std::pair<std::string, std::vector<std::tuple<uint32_t, int, int>>> | 1971 std::pair<std::string, std::vector<std::tuple<uint32_t, int, int>>> |
1990 wasm::DisassembleFunction(Handle<WasmCompiledModule> compiled_module, | 1972 wasm::DisassembleFunction(Handle<WasmCompiledModule> compiled_module, |
1991 int func_index) { | 1973 int func_index) { |
| 1974 DisallowHeapAllocation no_gc; |
| 1975 |
1992 if (func_index < 0 || | 1976 if (func_index < 0 || |
1993 static_cast<uint32_t>(func_index) >= | 1977 static_cast<uint32_t>(func_index) >= |
1994 compiled_module->module()->functions.size()) | 1978 compiled_module->module()->functions.size()) |
1995 return {}; | 1979 return {}; |
1996 | 1980 |
| 1981 SeqOneByteString* module_bytes_str = compiled_module->ptr_to_module_bytes(); |
| 1982 Vector<const byte> module_bytes(module_bytes_str->GetChars(), |
| 1983 module_bytes_str->length()); |
| 1984 |
1997 std::ostringstream disassembly_os; | 1985 std::ostringstream disassembly_os; |
1998 std::vector<std::tuple<uint32_t, int, int>> offset_table; | 1986 std::vector<std::tuple<uint32_t, int, int>> offset_table; |
1999 | 1987 |
2000 PrintWasmText(compiled_module->module(), static_cast<uint32_t>(func_index), | 1988 PrintWasmText(compiled_module->module(), module_bytes, |
2001 disassembly_os, &offset_table); | 1989 static_cast<uint32_t>(func_index), disassembly_os, |
| 1990 &offset_table); |
2002 | 1991 |
2003 return {disassembly_os.str(), std::move(offset_table)}; | 1992 return {disassembly_os.str(), std::move(offset_table)}; |
2004 } | 1993 } |
2005 | 1994 |
2006 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> object) { | 1995 Handle<WasmDebugInfo> wasm::GetDebugInfo(Handle<JSObject> object) { |
2007 auto instance = Handle<WasmInstanceObject>::cast(object); | 1996 auto instance = Handle<WasmInstanceObject>::cast(object); |
2008 if (instance->has_debug_info()) { | 1997 if (instance->has_debug_info()) { |
2009 Handle<WasmDebugInfo> info(instance->get_debug_info(), | 1998 Handle<WasmDebugInfo> info(instance->get_debug_info(), |
2010 instance->GetIsolate()); | 1999 instance->GetIsolate()); |
2011 return info; | 2000 return info; |
(...skipping 17 matching lines...) Expand all Loading... |
2029 return nothing; | 2018 return nothing; |
2030 } | 2019 } |
2031 | 2020 |
2032 // The {module_wrapper} will take ownership of the {WasmModule} object, | 2021 // The {module_wrapper} will take ownership of the {WasmModule} object, |
2033 // and it will be destroyed when the GC reclaims the wrapper object. | 2022 // and it will be destroyed when the GC reclaims the wrapper object. |
2034 Handle<WasmModuleWrapper> module_wrapper = | 2023 Handle<WasmModuleWrapper> module_wrapper = |
2035 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val)); | 2024 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val)); |
2036 | 2025 |
2037 // Compile the functions of the module, producing a compiled module. | 2026 // Compile the functions of the module, producing a compiled module. |
2038 MaybeHandle<WasmCompiledModule> maybe_compiled_module = | 2027 MaybeHandle<WasmCompiledModule> maybe_compiled_module = |
2039 result.val->CompileFunctions(isolate, module_wrapper, thrower); | 2028 result.val->CompileFunctions(isolate, module_wrapper, thrower, |
| 2029 ModuleWireBytes(start, end)); |
2040 | 2030 |
2041 if (maybe_compiled_module.is_null()) return nothing; | 2031 if (maybe_compiled_module.is_null()) return nothing; |
2042 | 2032 |
2043 Handle<WasmCompiledModule> compiled_module = | 2033 Handle<WasmCompiledModule> compiled_module = |
2044 maybe_compiled_module.ToHandleChecked(); | 2034 maybe_compiled_module.ToHandleChecked(); |
2045 | 2035 |
2046 DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null()); | 2036 DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null()); |
2047 DCHECK(!compiled_module->has_script()); | 2037 DCHECK(!compiled_module->has_script()); |
2048 DCHECK(!compiled_module->has_asm_js_offset_table()); | 2038 DCHECK(!compiled_module->has_asm_js_offset_table()); |
2049 if (origin == kAsmJsOrigin) { | 2039 if (origin == kAsmJsOrigin) { |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2361 MaybeHandle<String> WasmCompiledModule::GetFunctionName( | 2351 MaybeHandle<String> WasmCompiledModule::GetFunctionName( |
2362 Handle<WasmCompiledModule> compiled_module, uint32_t func_index) { | 2352 Handle<WasmCompiledModule> compiled_module, uint32_t func_index) { |
2363 DCHECK_LT(func_index, compiled_module->module()->functions.size()); | 2353 DCHECK_LT(func_index, compiled_module->module()->functions.size()); |
2364 WasmFunction& function = compiled_module->module()->functions[func_index]; | 2354 WasmFunction& function = compiled_module->module()->functions[func_index]; |
2365 Isolate* isolate = compiled_module->GetIsolate(); | 2355 Isolate* isolate = compiled_module->GetIsolate(); |
2366 MaybeHandle<String> string = ExtractStringFromModuleBytes( | 2356 MaybeHandle<String> string = ExtractStringFromModuleBytes( |
2367 isolate, compiled_module, function.name_offset, function.name_length); | 2357 isolate, compiled_module, function.name_offset, function.name_length); |
2368 if (!string.is_null()) return string.ToHandleChecked(); | 2358 if (!string.is_null()) return string.ToHandleChecked(); |
2369 return {}; | 2359 return {}; |
2370 } | 2360 } |
OLD | NEW |