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/macro-assembler.h" | 5 #include "src/macro-assembler.h" |
6 #include "src/objects.h" | 6 #include "src/objects.h" |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/simulator.h" | 9 #include "src/simulator.h" |
10 | 10 |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 } | 484 } |
485 } | 485 } |
486 | 486 |
487 //------------------------------------------------------------------------- | 487 //------------------------------------------------------------------------- |
488 // Compile all functions in the module. | 488 // Compile all functions in the module. |
489 //------------------------------------------------------------------------- | 489 //------------------------------------------------------------------------- |
490 { | 490 { |
491 isolate->counters()->wasm_functions_per_module()->AddSample( | 491 isolate->counters()->wasm_functions_per_module()->AddSample( |
492 static_cast<int>(functions.size())); | 492 static_cast<int>(functions.size())); |
493 | 493 |
| 494 std::vector<compiler::WasmCompilationUnit*> compilation_units( |
| 495 functions.size()); |
| 496 if (FLAG_wasm_parallel_compilation) { |
| 497 // Create a placeholder code object for all functions. |
| 498 // TODO(ahaas): Maybe we could skip this for external functions. |
| 499 for (uint32_t i = 0; i < functions.size(); i++) { |
| 500 linker.GetFunctionCode(i); |
| 501 } |
| 502 |
| 503 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); |
| 504 i++) { |
| 505 if (!functions[i].external) { |
| 506 compilation_units[i] = compiler::CreateWasmCompilationUnit( |
| 507 &thrower, isolate, &module_env, &functions[i]); |
| 508 } |
| 509 } |
| 510 |
| 511 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); |
| 512 i++) { |
| 513 if (!functions[i].external) { |
| 514 compiler::ExecuteCompilation(compilation_units[i]); |
| 515 } |
| 516 } |
| 517 } |
| 518 |
494 // First pass: compile each function and initialize the code table. | 519 // First pass: compile each function and initialize the code table. |
495 index = FLAG_skip_compiling_wasm_funcs; | 520 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); |
496 while (index < functions.size()) { | 521 i++) { |
497 const WasmFunction& func = functions[index]; | 522 const WasmFunction& func = functions[i]; |
498 if (thrower.error()) break; | 523 if (thrower.error()) break; |
499 DCHECK_EQ(index, func.func_index); | 524 DCHECK_EQ(i, func.func_index); |
500 | 525 |
501 WasmName str = GetName(func.name_offset, func.name_length); | 526 WasmName str = GetName(func.name_offset, func.name_length); |
502 WasmName str_null = {nullptr, 0}; | 527 WasmName str_null = {nullptr, 0}; |
503 Handle<String> name = factory->InternalizeUtf8String(str); | 528 Handle<String> name = factory->InternalizeUtf8String(str); |
504 Handle<Code> code = Handle<Code>::null(); | 529 Handle<Code> code = Handle<Code>::null(); |
505 Handle<JSFunction> function = Handle<JSFunction>::null(); | 530 Handle<JSFunction> function = Handle<JSFunction>::null(); |
506 if (func.external) { | 531 if (func.external) { |
507 // Lookup external function in FFI object. | 532 // Lookup external function in FFI object. |
508 MaybeHandle<JSFunction> function = | 533 MaybeHandle<JSFunction> function = |
509 LookupFunction(thrower, factory, ffi, index, str, str_null); | 534 LookupFunction(thrower, factory, ffi, i, str, str_null); |
510 if (function.is_null()) return MaybeHandle<JSObject>(); | 535 if (function.is_null()) return MaybeHandle<JSObject>(); |
511 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, | 536 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, |
512 function.ToHandleChecked(), | 537 function.ToHandleChecked(), |
513 func.sig, str, str_null); | 538 func.sig, str, str_null); |
514 } else { | 539 } else { |
515 // Compile the function. | 540 if (FLAG_wasm_parallel_compilation) { |
516 code = | 541 code = compiler::FinishCompilation(compilation_units[i]); |
517 compiler::CompileWasmFunction(thrower, isolate, &module_env, func); | 542 } else { |
| 543 // Compile the function. |
| 544 code = compiler::CompileWasmFunction(&thrower, isolate, &module_env, |
| 545 &func); |
| 546 } |
518 if (code.is_null()) { | 547 if (code.is_null()) { |
519 thrower.Error("Compilation of #%d:%.*s failed.", index, str.length(), | 548 thrower.Error("Compilation of #%d:%.*s failed.", i, str.length(), |
520 str.start()); | 549 str.start()); |
521 return MaybeHandle<JSObject>(); | 550 return MaybeHandle<JSObject>(); |
522 } | 551 } |
523 if (func.exported) { | 552 if (func.exported) { |
524 function = compiler::CompileJSToWasmWrapper( | 553 function = compiler::CompileJSToWasmWrapper( |
525 isolate, &module_env, name, code, instance.js_object, index); | 554 isolate, &module_env, name, code, instance.js_object, i); |
526 } | 555 } |
527 } | 556 } |
528 if (!code.is_null()) { | 557 if (!code.is_null()) { |
529 // Install the code into the linker table. | 558 // Install the code into the linker table. |
530 linker.Finish(index, code); | 559 linker.Finish(i, code); |
531 code_table->set(index, *code); | 560 code_table->set(i, *code); |
532 } | 561 } |
533 if (func.exported) { | 562 if (func.exported) { |
534 // Exported functions are installed as read-only properties on the | 563 // Exported functions are installed as read-only properties on the |
535 // module. | 564 // module. |
536 JSObject::AddProperty(instance.js_object, name, function, READ_ONLY); | 565 JSObject::AddProperty(instance.js_object, name, function, READ_ONLY); |
537 } | 566 } |
538 index++; | |
539 } | 567 } |
540 | 568 |
541 // Second pass: patch all direct call sites. | 569 // Second pass: patch all direct call sites. |
542 linker.Link(instance.function_table, this->function_table); | 570 linker.Link(instance.function_table, this->function_table); |
543 instance.js_object->SetInternalField(kWasmModuleFunctionTable, | 571 instance.js_object->SetInternalField(kWasmModuleFunctionTable, |
544 Smi::FromInt(0)); | 572 Smi::FromInt(0)); |
545 | 573 |
546 //------------------------------------------------------------------------- | 574 //------------------------------------------------------------------------- |
547 // Create and populate the exports object. | 575 // Create and populate the exports object. |
548 //------------------------------------------------------------------------- | 576 //------------------------------------------------------------------------- |
549 if (export_table.size() > 0 || mem_export) { | 577 if (export_table.size() > 0 || mem_export) { |
550 index = 0; | |
551 // Create the "exports" object. | 578 // Create the "exports" object. |
552 Handle<JSFunction> object_function = Handle<JSFunction>( | 579 Handle<JSFunction> object_function = Handle<JSFunction>( |
553 isolate->native_context()->object_function(), isolate); | 580 isolate->native_context()->object_function(), isolate); |
554 Handle<JSObject> exports_object = | 581 Handle<JSObject> exports_object = |
555 factory->NewJSObject(object_function, TENURED); | 582 factory->NewJSObject(object_function, TENURED); |
556 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); | 583 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); |
557 JSObject::AddProperty(instance.js_object, exports_name, exports_object, | 584 JSObject::AddProperty(instance.js_object, exports_name, exports_object, |
558 READ_ONLY); | 585 READ_ONLY); |
559 | 586 |
560 // Compile wrappers and add them to the exports object. | 587 // Compile wrappers and add them to the exports object. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 | 702 |
676 // Compile all functions. | 703 // Compile all functions. |
677 Handle<Code> main_code = Handle<Code>::null(); // record last code. | 704 Handle<Code> main_code = Handle<Code>::null(); // record last code. |
678 uint32_t index = 0; | 705 uint32_t index = 0; |
679 int main_index = 0; | 706 int main_index = 0; |
680 for (const WasmFunction& func : module->functions) { | 707 for (const WasmFunction& func : module->functions) { |
681 DCHECK_EQ(index, func.func_index); | 708 DCHECK_EQ(index, func.func_index); |
682 if (!func.external) { | 709 if (!func.external) { |
683 // Compile the function and install it in the code table. | 710 // Compile the function and install it in the code table. |
684 Handle<Code> code = | 711 Handle<Code> code = |
685 compiler::CompileWasmFunction(thrower, isolate, &module_env, func); | 712 compiler::CompileWasmFunction(&thrower, isolate, &module_env, &func); |
686 if (!code.is_null()) { | 713 if (!code.is_null()) { |
687 if (func.exported) { | 714 if (func.exported) { |
688 main_code = code; | 715 main_code = code; |
689 main_index = index; | 716 main_index = index; |
690 } | 717 } |
691 linker.Finish(index, code); | 718 linker.Finish(index, code); |
692 } | 719 } |
693 if (thrower.error()) return -1; | 720 if (thrower.error()) return -1; |
694 } | 721 } |
695 index++; | 722 index++; |
(...skipping 28 matching lines...) Expand all Loading... |
724 } | 751 } |
725 if (result->IsHeapNumber()) { | 752 if (result->IsHeapNumber()) { |
726 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); | 753 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); |
727 } | 754 } |
728 thrower.Error("WASM.compileRun() failed: Return value should be number"); | 755 thrower.Error("WASM.compileRun() failed: Return value should be number"); |
729 return -1; | 756 return -1; |
730 } | 757 } |
731 } // namespace wasm | 758 } // namespace wasm |
732 } // namespace internal | 759 } // namespace internal |
733 } // namespace v8 | 760 } // namespace v8 |
OLD | NEW |