| 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 |