| 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 "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 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 Isolate* isolate, std::vector<WasmFunction>& functions, | 497 Isolate* isolate, std::vector<WasmFunction>& functions, |
| 498 std::vector<compiler::WasmCompilationUnit*>& compilation_units, | 498 std::vector<compiler::WasmCompilationUnit*>& compilation_units, |
| 499 ModuleEnv& module_env, ErrorThrower& thrower) { | 499 ModuleEnv& module_env, ErrorThrower& thrower) { |
| 500 // Create a placeholder code object for all functions. | 500 // Create a placeholder code object for all functions. |
| 501 // TODO(ahaas): Maybe we could skip this for external functions. | 501 // TODO(ahaas): Maybe we could skip this for external functions. |
| 502 for (uint32_t i = 0; i < functions.size(); i++) { | 502 for (uint32_t i = 0; i < functions.size(); i++) { |
| 503 module_env.linker->GetFunctionCode(i); | 503 module_env.linker->GetFunctionCode(i); |
| 504 } | 504 } |
| 505 | 505 |
| 506 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); i++) { | 506 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); i++) { |
| 507 if (!functions[i].external) { | 507 compilation_units[i] = compiler::CreateWasmCompilationUnit( |
| 508 compilation_units[i] = compiler::CreateWasmCompilationUnit( | 508 &thrower, isolate, &module_env, &functions[i], i); |
| 509 &thrower, isolate, &module_env, &functions[i], i); | |
| 510 } else { | |
| 511 compilation_units[i] = nullptr; | |
| 512 } | |
| 513 } | 509 } |
| 514 } | 510 } |
| 515 | 511 |
| 516 uint32_t* StartCompilationTasks( | 512 uint32_t* StartCompilationTasks( |
| 517 Isolate* isolate, | 513 Isolate* isolate, |
| 518 std::vector<compiler::WasmCompilationUnit*>& compilation_units, | 514 std::vector<compiler::WasmCompilationUnit*>& compilation_units, |
| 519 std::queue<compiler::WasmCompilationUnit*>& executed_units, | 515 std::queue<compiler::WasmCompilationUnit*>& executed_units, |
| 520 const base::SmartPointer<base::Semaphore>& pending_tasks, | 516 const base::SmartPointer<base::Semaphore>& pending_tasks, |
| 521 base::Mutex& result_mutex, base::AtomicNumber<size_t>& next_unit) { | 517 base::Mutex& result_mutex, base::AtomicNumber<size_t>& next_unit) { |
| 522 const size_t num_tasks = | 518 const size_t num_tasks = |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 compiler::WasmCompilationUnit* unit = nullptr; | 553 compiler::WasmCompilationUnit* unit = nullptr; |
| 558 { | 554 { |
| 559 base::LockGuard<base::Mutex> guard(&result_mutex); | 555 base::LockGuard<base::Mutex> guard(&result_mutex); |
| 560 if (executed_units.empty()) { | 556 if (executed_units.empty()) { |
| 561 break; | 557 break; |
| 562 } | 558 } |
| 563 unit = executed_units.front(); | 559 unit = executed_units.front(); |
| 564 executed_units.pop(); | 560 executed_units.pop(); |
| 565 } | 561 } |
| 566 int j = compiler::GetIndexOfWasmCompilationUnit(unit); | 562 int j = compiler::GetIndexOfWasmCompilationUnit(unit); |
| 567 if (!module->functions[j].external) { | 563 results[j] = compiler::FinishCompilation(unit); |
| 568 results[j] = compiler::FinishCompilation(unit); | |
| 569 } | |
| 570 } | 564 } |
| 571 } | 565 } |
| 572 | 566 |
| 573 bool FinishCompilation(Isolate* isolate, WasmModule* module, | 567 bool FinishCompilation(Isolate* isolate, WasmModule* module, |
| 574 const Handle<JSReceiver> ffi, | 568 const Handle<JSReceiver> ffi, |
| 575 const std::vector<Handle<Code>>& results, | 569 const std::vector<Handle<Code>>& results, |
| 576 const WasmModuleInstance& instance, | 570 const WasmModuleInstance& instance, |
| 577 const Handle<FixedArray>& code_table, | 571 const Handle<FixedArray>& code_table, |
| 578 ErrorThrower& thrower, Factory* factory, | 572 ErrorThrower& thrower, Factory* factory, |
| 579 ModuleEnv& module_env, uint32_t& total_code_size, | 573 ModuleEnv& module_env, uint32_t& total_code_size, |
| 580 PropertyDescriptor& desc) { | 574 PropertyDescriptor& desc) { |
| 581 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; | 575 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; |
| 582 i < module->functions.size(); i++) { | 576 i < module->functions.size(); i++) { |
| 583 const WasmFunction& func = module->functions[i]; | 577 const WasmFunction& func = module->functions[i]; |
| 584 if (thrower.error()) break; | 578 if (thrower.error()) break; |
| 585 | 579 |
| 586 DCHECK_EQ(i, func.func_index); | 580 DCHECK_EQ(i, func.func_index); |
| 587 WasmName str = module->GetName(func.name_offset, func.name_length); | 581 WasmName str = module->GetName(func.name_offset, func.name_length); |
| 588 WasmName str_null = {nullptr, 0}; | |
| 589 Handle<Code> code = Handle<Code>::null(); | 582 Handle<Code> code = Handle<Code>::null(); |
| 590 Handle<JSFunction> function = Handle<JSFunction>::null(); | 583 Handle<JSFunction> function = Handle<JSFunction>::null(); |
| 591 Handle<String> function_name = Handle<String>::null(); | 584 Handle<String> function_name = Handle<String>::null(); |
| 592 if (func.external) { | 585 if (FLAG_wasm_num_compilation_tasks != 0) { |
| 593 // Lookup external function in FFI object. | 586 code = results[i]; |
| 594 MaybeHandle<JSFunction> function = | |
| 595 LookupFunction(thrower, factory, ffi, i, str, str_null); | |
| 596 if (function.is_null()) { | |
| 597 return false; | |
| 598 } | |
| 599 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, | |
| 600 function.ToHandleChecked(), | |
| 601 func.sig, str, str_null); | |
| 602 } else { | 587 } else { |
| 603 if (FLAG_wasm_num_compilation_tasks != 0) { | 588 // Compile the function. |
| 604 code = results[i]; | 589 code = |
| 605 } else { | 590 compiler::CompileWasmFunction(&thrower, isolate, &module_env, &func); |
| 606 // Compile the function. | 591 } |
| 607 code = compiler::CompileWasmFunction(&thrower, isolate, &module_env, | 592 if (code.is_null()) { |
| 608 &func); | 593 thrower.Error("Compilation of #%d:%.*s failed.", i, str.length(), |
| 609 } | 594 str.start()); |
| 610 if (code.is_null()) { | 595 return false; |
| 611 thrower.Error("Compilation of #%d:%.*s failed.", i, str.length(), | 596 } |
| 612 str.start()); | 597 if (func.exported) { |
| 613 return false; | 598 function_name = factory->InternalizeUtf8String(str); |
| 614 } | 599 function = compiler::CompileJSToWasmWrapper( |
| 615 if (func.exported) { | 600 isolate, &module_env, function_name, code, instance.js_object, i); |
| 616 function_name = factory->InternalizeUtf8String(str); | 601 record_code_size(total_code_size, function->code()); |
| 617 function = compiler::CompileJSToWasmWrapper( | |
| 618 isolate, &module_env, function_name, code, instance.js_object, i); | |
| 619 record_code_size(total_code_size, function->code()); | |
| 620 } | |
| 621 } | 602 } |
| 622 if (!code.is_null()) { | 603 if (!code.is_null()) { |
| 623 // Install the code into the linker table. | 604 // Install the code into the linker table. |
| 624 module_env.linker->Finish(i, code); | 605 module_env.linker->Finish(i, code); |
| 625 code_table->set(i, *code); | 606 code_table->set(i, *code); |
| 626 record_code_size(total_code_size, *code); | 607 record_code_size(total_code_size, *code); |
| 627 } | 608 } |
| 628 if (func.exported) { | 609 if (func.exported) { |
| 629 // Exported functions are installed as read-only properties on the | 610 // Exported functions are installed as read-only properties on the |
| 630 // module. | 611 // module. |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 module_env.instance = &instance; | 928 module_env.instance = &instance; |
| 948 module_env.linker = &linker; | 929 module_env.linker = &linker; |
| 949 module_env.origin = module->origin; | 930 module_env.origin = module->origin; |
| 950 | 931 |
| 951 // Compile all functions. | 932 // Compile all functions. |
| 952 Handle<Code> main_code = Handle<Code>::null(); // record last code. | 933 Handle<Code> main_code = Handle<Code>::null(); // record last code. |
| 953 uint32_t index = 0; | 934 uint32_t index = 0; |
| 954 int main_index = 0; | 935 int main_index = 0; |
| 955 for (const WasmFunction& func : module->functions) { | 936 for (const WasmFunction& func : module->functions) { |
| 956 DCHECK_EQ(index, func.func_index); | 937 DCHECK_EQ(index, func.func_index); |
| 957 if (!func.external) { | 938 // Compile the function and install it in the code table. |
| 958 // Compile the function and install it in the code table. | 939 Handle<Code> code = |
| 959 Handle<Code> code = | 940 compiler::CompileWasmFunction(&thrower, isolate, &module_env, &func); |
| 960 compiler::CompileWasmFunction(&thrower, isolate, &module_env, &func); | 941 if (!code.is_null()) { |
| 961 if (!code.is_null()) { | 942 if (func.exported) { |
| 962 if (func.exported) { | 943 main_code = code; |
| 963 main_code = code; | 944 main_index = index; |
| 964 main_index = index; | |
| 965 } | |
| 966 linker.Finish(index, code); | |
| 967 } | 945 } |
| 968 if (thrower.error()) return -1; | 946 linker.Finish(index, code); |
| 969 } | 947 } |
| 948 if (thrower.error()) return -1; |
| 970 index++; | 949 index++; |
| 971 } | 950 } |
| 972 | 951 |
| 973 if (main_code.is_null()) { | 952 if (main_code.is_null()) { |
| 974 thrower.Error("WASM.compileRun() failed: no main code found"); | 953 thrower.Error("WASM.compileRun() failed: no main code found"); |
| 975 return -1; | 954 return -1; |
| 976 } | 955 } |
| 977 | 956 |
| 978 linker.Link(instance.function_table, instance.module->function_table); | 957 linker.Link(instance.function_table, instance.module->function_table); |
| 979 | 958 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1009 wasm->GetInternalField(kWasmFunctionNamesArray), wasm->GetIsolate()); | 988 wasm->GetInternalField(kWasmFunctionNamesArray), wasm->GetIsolate()); |
| 1010 if (func_names_arr_obj->IsUndefined()) | 989 if (func_names_arr_obj->IsUndefined()) |
| 1011 return func_names_arr_obj; // Return undefined. | 990 return func_names_arr_obj; // Return undefined. |
| 1012 return GetWasmFunctionNameFromTable( | 991 return GetWasmFunctionNameFromTable( |
| 1013 Handle<ByteArray>::cast(func_names_arr_obj), func_index); | 992 Handle<ByteArray>::cast(func_names_arr_obj), func_index); |
| 1014 } | 993 } |
| 1015 | 994 |
| 1016 } // namespace wasm | 995 } // namespace wasm |
| 1017 } // namespace internal | 996 } // namespace internal |
| 1018 } // namespace v8 | 997 } // namespace v8 |
| OLD | NEW |