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 <functional> | 5 #include <functional> |
6 #include <memory> | 6 #include <memory> |
7 | 7 |
8 #include "src/asmjs/asm-js.h" | 8 #include "src/asmjs/asm-js.h" |
9 #include "src/assembler-inl.h" | 9 #include "src/assembler-inl.h" |
10 #include "src/base/atomic-utils.h" | 10 #include "src/base/atomic-utils.h" |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 // The compilation helper takes ownership of the {WasmModule}. | 326 // The compilation helper takes ownership of the {WasmModule}. |
327 // In {CompileToModuleObject}, it will transfer ownership to the generated | 327 // In {CompileToModuleObject}, it will transfer ownership to the generated |
328 // {WasmModuleWrapper}. If this method is not called, ownership may be | 328 // {WasmModuleWrapper}. If this method is not called, ownership may be |
329 // reclaimed by explicitely releasing the {module_} field. | 329 // reclaimed by explicitely releasing the {module_} field. |
330 CompilationHelper(Isolate* isolate, std::unique_ptr<WasmModule> module, | 330 CompilationHelper(Isolate* isolate, std::unique_ptr<WasmModule> module, |
331 bool is_sync) | 331 bool is_sync) |
332 : isolate_(isolate), | 332 : isolate_(isolate), |
333 module_(std::move(module)), | 333 module_(std::move(module)), |
334 counters_shared_(isolate->counters_shared()), | 334 counters_shared_(isolate->counters_shared()), |
335 is_sync_(is_sync), | 335 is_sync_(is_sync), |
336 executed_units_(isolate->random_number_generator()) { | 336 executed_units_(isolate->random_number_generator()) {} |
337 counters_ = counters_shared_.get(); | |
338 } | |
339 | 337 |
340 // The actual runnable task that performs compilations in the background. | 338 // The actual runnable task that performs compilations in the background. |
341 class CompilationTask : public CancelableTask { | 339 class CompilationTask : public CancelableTask { |
342 public: | 340 public: |
343 CompilationHelper* helper_; | 341 CompilationHelper* helper_; |
344 explicit CompilationTask(CompilationHelper* helper) | 342 explicit CompilationTask(CompilationHelper* helper) |
345 : CancelableTask(helper->isolate_), helper_(helper) {} | 343 : CancelableTask(helper->isolate_), helper_(helper) {} |
346 | 344 |
347 void RunInternal() override { | 345 void RunInternal() override { |
348 while (helper_->FetchAndExecuteCompilationUnit()) { | 346 while (helper_->FetchAndExecuteCompilationUnit()) { |
349 } | 347 } |
350 helper_->module_->pending_tasks.get()->Signal(); | 348 helper_->module_->pending_tasks.get()->Signal(); |
351 } | 349 } |
352 }; | 350 }; |
353 | 351 |
354 Isolate* isolate_; | 352 Isolate* isolate_; |
355 std::unique_ptr<WasmModule> module_; | 353 std::unique_ptr<WasmModule> module_; |
356 std::shared_ptr<Counters> counters_shared_; | 354 std::shared_ptr<Counters> counters_shared_; |
357 Counters* counters_; | |
358 bool is_sync_; | 355 bool is_sync_; |
359 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> | 356 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> |
360 compilation_units_; | 357 compilation_units_; |
361 CodeGenerationSchedule executed_units_; | 358 CodeGenerationSchedule executed_units_; |
362 base::Mutex result_mutex_; | 359 base::Mutex result_mutex_; |
363 base::AtomicNumber<size_t> next_unit_; | 360 base::AtomicNumber<size_t> next_unit_; |
364 size_t num_background_tasks_ = 0; | 361 size_t num_background_tasks_ = 0; |
365 // This flag should only be set while holding result_mutex_. | 362 // This flag should only be set while holding result_mutex_. |
366 bool finisher_is_running_ = false; | 363 bool finisher_is_running_ = false; |
367 | 364 |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 // (lazy) compilation time. | 681 // (lazy) compilation time. |
685 ValidateSequentially(&module_env, thrower); | 682 ValidateSequentially(&module_env, thrower); |
686 } | 683 } |
687 if (thrower->error()) return {}; | 684 if (thrower->error()) return {}; |
688 | 685 |
689 // At this point, compilation has completed. Update the code table. | 686 // At this point, compilation has completed. Update the code table. |
690 for (size_t i = FLAG_skip_compiling_wasm_funcs; | 687 for (size_t i = FLAG_skip_compiling_wasm_funcs; |
691 i < temp_instance->function_code.size(); ++i) { | 688 i < temp_instance->function_code.size(); ++i) { |
692 Code* code = *temp_instance->function_code[i]; | 689 Code* code = *temp_instance->function_code[i]; |
693 code_table->set(static_cast<int>(i), code); | 690 code_table->set(static_cast<int>(i), code); |
694 RecordStats(code, counters_); | 691 RecordStats(code, counters_shared_.get()); |
695 } | 692 } |
696 | 693 |
697 // Create heap objects for script, module bytes and asm.js offset table to | 694 // Create heap objects for script, module bytes and asm.js offset table to |
698 // be stored in the shared module data. | 695 // be stored in the shared module data. |
699 Handle<Script> script; | 696 Handle<Script> script; |
700 Handle<ByteArray> asm_js_offset_table; | 697 Handle<ByteArray> asm_js_offset_table; |
701 if (asm_js_script.is_null()) { | 698 if (asm_js_script.is_null()) { |
702 script = CreateWasmScript(isolate_, wire_bytes); | 699 script = CreateWasmScript(isolate_, wire_bytes); |
703 } else { | 700 } else { |
704 script = asm_js_script; | 701 script = asm_js_script; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 for (auto exp : module->export_table) { | 749 for (auto exp : module->export_table) { |
753 if (exp.kind != kExternalFunction) continue; | 750 if (exp.kind != kExternalFunction) continue; |
754 Handle<Code> wasm_code = EnsureExportedLazyDeoptData( | 751 Handle<Code> wasm_code = EnsureExportedLazyDeoptData( |
755 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index); | 752 isolate_, Handle<WasmInstanceObject>::null(), code_table, exp.index); |
756 Handle<Code> wrapper_code = | 753 Handle<Code> wrapper_code = |
757 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(isolate_, module, | 754 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(isolate_, module, |
758 wasm_code, exp.index); | 755 wasm_code, exp.index); |
759 int export_index = | 756 int export_index = |
760 static_cast<int>(module->functions.size() + func_index); | 757 static_cast<int>(module->functions.size() + func_index); |
761 code_table->set(export_index, *wrapper_code); | 758 code_table->set(export_index, *wrapper_code); |
762 RecordStats(*wrapper_code, counters_); | 759 RecordStats(*wrapper_code, counters_shared_.get()); |
763 func_index++; | 760 func_index++; |
764 } | 761 } |
765 | 762 |
766 return WasmModuleObject::New(isolate_, compiled_module); | 763 return WasmModuleObject::New(isolate_, compiled_module); |
767 } | 764 } |
768 }; | 765 }; |
769 | 766 |
770 static void MemoryInstanceFinalizer(Isolate* isolate, | 767 static void MemoryInstanceFinalizer(Isolate* isolate, |
771 WasmInstanceObject* instance) { | 768 WasmInstanceObject* instance) { |
772 DisallowHeapAllocation no_gc; | 769 DisallowHeapAllocation no_gc; |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1150 MaybeHandle<JSReceiver> ffi, | 1147 MaybeHandle<JSReceiver> ffi, |
1151 MaybeHandle<JSArrayBuffer> memory) | 1148 MaybeHandle<JSArrayBuffer> memory) |
1152 : isolate_(isolate), | 1149 : isolate_(isolate), |
1153 module_(module_object->compiled_module()->module()), | 1150 module_(module_object->compiled_module()->module()), |
1154 counters_shared_(isolate->counters_shared()), | 1151 counters_shared_(isolate->counters_shared()), |
1155 thrower_(thrower), | 1152 thrower_(thrower), |
1156 module_object_(module_object), | 1153 module_object_(module_object), |
1157 ffi_(ffi.is_null() ? Handle<JSReceiver>::null() | 1154 ffi_(ffi.is_null() ? Handle<JSReceiver>::null() |
1158 : ffi.ToHandleChecked()), | 1155 : ffi.ToHandleChecked()), |
1159 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null() | 1156 memory_(memory.is_null() ? Handle<JSArrayBuffer>::null() |
1160 : memory.ToHandleChecked()) { | 1157 : memory.ToHandleChecked()) {} |
1161 counters_ = counters_shared_.get(); | |
1162 } | |
1163 | 1158 |
1164 // Build an instance, in all of its glory. | 1159 // Build an instance, in all of its glory. |
1165 MaybeHandle<WasmInstanceObject> Build() { | 1160 MaybeHandle<WasmInstanceObject> Build() { |
1166 // Check that an imports argument was provided, if the module requires it. | 1161 // Check that an imports argument was provided, if the module requires it. |
1167 // No point in continuing otherwise. | 1162 // No point in continuing otherwise. |
1168 if (!module_->import_table.empty() && ffi_.is_null()) { | 1163 if (!module_->import_table.empty() && ffi_.is_null()) { |
1169 thrower_->TypeError( | 1164 thrower_->TypeError( |
1170 "Imports argument must be present and must be an object"); | 1165 "Imports argument must be present and must be an object"); |
1171 return {}; | 1166 return {}; |
1172 } | 1167 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1242 case Code::JS_TO_WASM_FUNCTION: | 1237 case Code::JS_TO_WASM_FUNCTION: |
1243 case Code::WASM_FUNCTION: { | 1238 case Code::WASM_FUNCTION: { |
1244 Handle<Code> code = factory->CopyCode(orig_code); | 1239 Handle<Code> code = factory->CopyCode(orig_code); |
1245 code_table->set(i, *code); | 1240 code_table->set(i, *code); |
1246 break; | 1241 break; |
1247 } | 1242 } |
1248 default: | 1243 default: |
1249 UNREACHABLE(); | 1244 UNREACHABLE(); |
1250 } | 1245 } |
1251 } | 1246 } |
1252 RecordStats(code_table, counters_); | 1247 RecordStats(code_table, counters_shared_.get()); |
1253 } else { | 1248 } else { |
1254 // There was no owner, so we can reuse the original. | 1249 // There was no owner, so we can reuse the original. |
1255 compiled_module_ = original; | 1250 compiled_module_ = original; |
1256 old_code_table = | 1251 old_code_table = |
1257 factory->CopyFixedArray(compiled_module_->code_table()); | 1252 factory->CopyFixedArray(compiled_module_->code_table()); |
1258 code_table = compiled_module_->code_table(); | 1253 code_table = compiled_module_->code_table(); |
1259 TRACE("Reusing existing instance %d\n", | 1254 TRACE("Reusing existing instance %d\n", |
1260 compiled_module_->instance_id()); | 1255 compiled_module_->instance_id()); |
1261 } | 1256 } |
1262 compiled_module_->set_native_context(isolate_->native_context()); | 1257 compiled_module_->set_native_context(isolate_->native_context()); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1525 int start_index = module_->start_function_index; | 1520 int start_index = module_->start_function_index; |
1526 Handle<Code> startup_code = EnsureExportedLazyDeoptData( | 1521 Handle<Code> startup_code = EnsureExportedLazyDeoptData( |
1527 isolate_, instance, code_table, start_index); | 1522 isolate_, instance, code_table, start_index); |
1528 FunctionSig* sig = module_->functions[start_index].sig; | 1523 FunctionSig* sig = module_->functions[start_index].sig; |
1529 Handle<Code> wrapper_code = | 1524 Handle<Code> wrapper_code = |
1530 js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( | 1525 js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper( |
1531 isolate_, module_, startup_code, start_index); | 1526 isolate_, module_, startup_code, start_index); |
1532 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( | 1527 Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New( |
1533 isolate_, instance, MaybeHandle<String>(), start_index, | 1528 isolate_, instance, MaybeHandle<String>(), start_index, |
1534 static_cast<int>(sig->parameter_count()), wrapper_code); | 1529 static_cast<int>(sig->parameter_count()), wrapper_code); |
1535 RecordStats(*startup_code, counters_); | 1530 RecordStats(*startup_code, counters_shared_.get()); |
1536 // Call the JS function. | 1531 // Call the JS function. |
1537 Handle<Object> undefined = factory->undefined_value(); | 1532 Handle<Object> undefined = factory->undefined_value(); |
1538 MaybeHandle<Object> retval = | 1533 MaybeHandle<Object> retval = |
1539 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); | 1534 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); |
1540 | 1535 |
1541 if (retval.is_null()) { | 1536 if (retval.is_null()) { |
1542 DCHECK(isolate_->has_pending_exception()); | 1537 DCHECK(isolate_->has_pending_exception()); |
1543 isolate_->OptionalRescheduleException(false); | 1538 isolate_->OptionalRescheduleException(false); |
1544 // It's unfortunate that the new instance is already linked in the | 1539 // It's unfortunate that the new instance is already linked in the |
1545 // chain. However, we need to set up everything before executing the | 1540 // chain. However, we need to set up everything before executing the |
(...skipping 14 matching lines...) Expand all Loading... |
1560 struct TableInstance { | 1555 struct TableInstance { |
1561 Handle<WasmTableObject> table_object; // WebAssembly.Table instance | 1556 Handle<WasmTableObject> table_object; // WebAssembly.Table instance |
1562 Handle<FixedArray> js_wrappers; // JSFunctions exported | 1557 Handle<FixedArray> js_wrappers; // JSFunctions exported |
1563 Handle<FixedArray> function_table; // internal code array | 1558 Handle<FixedArray> function_table; // internal code array |
1564 Handle<FixedArray> signature_table; // internal sig array | 1559 Handle<FixedArray> signature_table; // internal sig array |
1565 }; | 1560 }; |
1566 | 1561 |
1567 Isolate* isolate_; | 1562 Isolate* isolate_; |
1568 WasmModule* const module_; | 1563 WasmModule* const module_; |
1569 std::shared_ptr<Counters> counters_shared_; | 1564 std::shared_ptr<Counters> counters_shared_; |
1570 Counters* counters_; | |
1571 ErrorThrower* thrower_; | 1565 ErrorThrower* thrower_; |
1572 Handle<WasmModuleObject> module_object_; | 1566 Handle<WasmModuleObject> module_object_; |
1573 Handle<JSReceiver> ffi_; // TODO(titzer): Use MaybeHandle | 1567 Handle<JSReceiver> ffi_; // TODO(titzer): Use MaybeHandle |
1574 Handle<JSArrayBuffer> memory_; // TODO(titzer): Use MaybeHandle | 1568 Handle<JSArrayBuffer> memory_; // TODO(titzer): Use MaybeHandle |
1575 Handle<JSArrayBuffer> globals_; | 1569 Handle<JSArrayBuffer> globals_; |
1576 Handle<WasmCompiledModule> compiled_module_; | 1570 Handle<WasmCompiledModule> compiled_module_; |
1577 std::vector<TableInstance> table_instances_; | 1571 std::vector<TableInstance> table_instances_; |
1578 std::vector<Handle<JSFunction>> js_wrappers_; | 1572 std::vector<Handle<JSFunction>> js_wrappers_; |
1579 JSToWasmWrapperCache js_to_wasm_cache_; | 1573 JSToWasmWrapperCache js_to_wasm_cache_; |
1580 | 1574 |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1770 isolate_, index, module_->functions[import.index].sig, | 1764 isolate_, index, module_->functions[import.index].sig, |
1771 Handle<JSReceiver>::cast(value), module_name, import_name, | 1765 Handle<JSReceiver>::cast(value), module_name, import_name, |
1772 module_->get_origin()); | 1766 module_->get_origin()); |
1773 if (import_wrapper.is_null()) { | 1767 if (import_wrapper.is_null()) { |
1774 ReportLinkError( | 1768 ReportLinkError( |
1775 "imported function does not match the expected type", index, | 1769 "imported function does not match the expected type", index, |
1776 module_name, import_name); | 1770 module_name, import_name); |
1777 return -1; | 1771 return -1; |
1778 } | 1772 } |
1779 code_table->set(num_imported_functions, *import_wrapper); | 1773 code_table->set(num_imported_functions, *import_wrapper); |
1780 RecordStats(*import_wrapper, counters_); | 1774 RecordStats(*import_wrapper, counters_shared_.get()); |
1781 num_imported_functions++; | 1775 num_imported_functions++; |
1782 break; | 1776 break; |
1783 } | 1777 } |
1784 case kExternalTable: { | 1778 case kExternalTable: { |
1785 if (!WasmJs::IsWasmTableObject(isolate_, value)) { | 1779 if (!WasmJs::IsWasmTableObject(isolate_, value)) { |
1786 ReportLinkError("table import requires a WebAssembly.Table", index, | 1780 ReportLinkError("table import requires a WebAssembly.Table", index, |
1787 module_name, import_name); | 1781 module_name, import_name); |
1788 return -1; | 1782 return -1; |
1789 } | 1783 } |
1790 WasmIndirectFunctionTable& table = | 1784 WasmIndirectFunctionTable& table = |
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2747 Handle<JSPromise> promise) | 2741 Handle<JSPromise> promise) |
2748 : isolate_(isolate), | 2742 : isolate_(isolate), |
2749 counters_shared_(isolate->counters_shared()), | 2743 counters_shared_(isolate->counters_shared()), |
2750 bytes_copy_(std::move(bytes_copy)), | 2744 bytes_copy_(std::move(bytes_copy)), |
2751 wire_bytes_(bytes_copy_.get(), bytes_copy_.get() + length) { | 2745 wire_bytes_(bytes_copy_.get(), bytes_copy_.get() + length) { |
2752 // The handles for the context and promise must be deferred. | 2746 // The handles for the context and promise must be deferred. |
2753 DeferredHandleScope deferred(isolate); | 2747 DeferredHandleScope deferred(isolate); |
2754 context_ = Handle<Context>(*context); | 2748 context_ = Handle<Context>(*context); |
2755 module_promise_ = Handle<JSPromise>(*promise); | 2749 module_promise_ = Handle<JSPromise>(*promise); |
2756 deferred_handles_.push_back(deferred.Detach()); | 2750 deferred_handles_.push_back(deferred.Detach()); |
2757 counters_ = counters_shared_.get(); | |
2758 } | 2751 } |
2759 | 2752 |
2760 void Start() { | 2753 void Start() { |
2761 DoAsync<DecodeModule>(); // -- | 2754 DoAsync<DecodeModule>(); // -- |
2762 } | 2755 } |
2763 | 2756 |
2764 ~AsyncCompileJob() { | 2757 ~AsyncCompileJob() { |
2765 for (auto d : deferred_handles_) delete d; | 2758 for (auto d : deferred_handles_) delete d; |
2766 } | 2759 } |
2767 | 2760 |
2768 private: | 2761 private: |
2769 Isolate* isolate_; | 2762 Isolate* isolate_; |
2770 std::shared_ptr<Counters> counters_shared_; | 2763 std::shared_ptr<Counters> counters_shared_; |
2771 Counters* counters_; | |
2772 std::unique_ptr<byte[]> bytes_copy_; | 2764 std::unique_ptr<byte[]> bytes_copy_; |
2773 ModuleWireBytes wire_bytes_; | 2765 ModuleWireBytes wire_bytes_; |
2774 Handle<Context> context_; | 2766 Handle<Context> context_; |
2775 Handle<JSPromise> module_promise_; | 2767 Handle<JSPromise> module_promise_; |
2776 std::unique_ptr<CompilationHelper> helper_; | 2768 std::unique_ptr<CompilationHelper> helper_; |
2777 std::unique_ptr<ModuleBytesEnv> module_bytes_env_; | 2769 std::unique_ptr<ModuleBytesEnv> module_bytes_env_; |
2778 | 2770 |
2779 bool failed_ = false; | 2771 bool failed_ = false; |
2780 std::vector<DeferredHandles*> deferred_handles_; | 2772 std::vector<DeferredHandles*> deferred_handles_; |
2781 Handle<WasmModuleObject> module_object_; | 2773 Handle<WasmModuleObject> module_object_; |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3126 // Step 5b (sync): Finish heap-allocated data structures. | 3118 // Step 5b (sync): Finish heap-allocated data structures. |
3127 //========================================================================== | 3119 //========================================================================== |
3128 class FinishCompile : public SyncCompileTask { | 3120 class FinishCompile : public SyncCompileTask { |
3129 void RunImpl() override { | 3121 void RunImpl() override { |
3130 TRACE_COMPILE("(5b) Finish compile...\n"); | 3122 TRACE_COMPILE("(5b) Finish compile...\n"); |
3131 HandleScope scope(job_->isolate_); | 3123 HandleScope scope(job_->isolate_); |
3132 // At this point, compilation has completed. Update the code table. | 3124 // At this point, compilation has completed. Update the code table. |
3133 for (size_t i = FLAG_skip_compiling_wasm_funcs; | 3125 for (size_t i = FLAG_skip_compiling_wasm_funcs; |
3134 i < job_->temp_instance_->function_code.size(); ++i) { | 3126 i < job_->temp_instance_->function_code.size(); ++i) { |
3135 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i))); | 3127 Code* code = Code::cast(job_->code_table_->get(static_cast<int>(i))); |
3136 RecordStats(code, job_->counters_); | 3128 RecordStats(code, job_->counters_shared_.get()); |
3137 } | 3129 } |
3138 | 3130 |
3139 // Create heap objects for script and module bytes to be stored in the | 3131 // Create heap objects for script and module bytes to be stored in the |
3140 // shared module data. Asm.js is not compiled asynchronously. | 3132 // shared module data. Asm.js is not compiled asynchronously. |
3141 Handle<Script> script = | 3133 Handle<Script> script = |
3142 CreateWasmScript(job_->isolate_, job_->wire_bytes_); | 3134 CreateWasmScript(job_->isolate_, job_->wire_bytes_); |
3143 Handle<ByteArray> asm_js_offset_table; | 3135 Handle<ByteArray> asm_js_offset_table; |
3144 // TODO(wasm): Improve efficiency of storing module wire bytes. | 3136 // TODO(wasm): Improve efficiency of storing module wire bytes. |
3145 // 1. Only store relevant sections, not function bodies | 3137 // 1. Only store relevant sections, not function bodies |
3146 // 2. Don't make a second copy of the bytes here; reuse the copy made | 3138 // 2. Don't make a second copy of the bytes here; reuse the copy made |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3203 for (auto exp : module->export_table) { | 3195 for (auto exp : module->export_table) { |
3204 if (exp.kind != kExternalFunction) continue; | 3196 if (exp.kind != kExternalFunction) continue; |
3205 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)), | 3197 Handle<Code> wasm_code(Code::cast(job_->code_table_->get(exp.index)), |
3206 job_->isolate_); | 3198 job_->isolate_); |
3207 Handle<Code> wrapper_code = | 3199 Handle<Code> wrapper_code = |
3208 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper( | 3200 js_to_wasm_cache.CloneOrCompileJSToWasmWrapper( |
3209 job_->isolate_, module, wasm_code, exp.index); | 3201 job_->isolate_, module, wasm_code, exp.index); |
3210 int export_index = | 3202 int export_index = |
3211 static_cast<int>(module->functions.size() + func_index); | 3203 static_cast<int>(module->functions.size() + func_index); |
3212 job_->code_table_->set(export_index, *wrapper_code); | 3204 job_->code_table_->set(export_index, *wrapper_code); |
3213 RecordStats(*wrapper_code, job_->counters_); | 3205 RecordStats(*wrapper_code, job_->counters_shared_.get()); |
3214 func_index++; | 3206 func_index++; |
3215 } | 3207 } |
3216 | 3208 |
3217 job_->DoSync<FinishModule>(); | 3209 job_->DoSync<FinishModule>(); |
3218 } | 3210 } |
3219 }; | 3211 }; |
3220 | 3212 |
3221 //========================================================================== | 3213 //========================================================================== |
3222 // Step 7 (sync): Finish the module and resolve the promise. | 3214 // Step 7 (sync): Finish the module and resolve the promise. |
3223 //========================================================================== | 3215 //========================================================================== |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3425 } | 3417 } |
3426 | 3418 |
3427 Handle<Code> LazyCompilationOrchestrator::CompileLazy( | 3419 Handle<Code> LazyCompilationOrchestrator::CompileLazy( |
3428 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, | 3420 Isolate* isolate, Handle<WasmInstanceObject> instance, Handle<Code> caller, |
3429 int call_offset, int exported_func_index, bool patch_caller) { | 3421 int call_offset, int exported_func_index, bool patch_caller) { |
3430 struct NonCompiledFunction { | 3422 struct NonCompiledFunction { |
3431 int offset; | 3423 int offset; |
3432 int func_index; | 3424 int func_index; |
3433 }; | 3425 }; |
3434 std::shared_ptr<Counters> counters_shared = isolate->counters_shared(); | 3426 std::shared_ptr<Counters> counters_shared = isolate->counters_shared(); |
3435 Counters* counters = counters_shared.get(); | |
3436 std::vector<NonCompiledFunction> non_compiled_functions; | 3427 std::vector<NonCompiledFunction> non_compiled_functions; |
3437 int func_to_return_idx = exported_func_index; | 3428 int func_to_return_idx = exported_func_index; |
3438 wasm::Decoder decoder(nullptr, nullptr); | 3429 wasm::Decoder decoder(nullptr, nullptr); |
3439 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION; | 3430 bool is_js_to_wasm = caller->kind() == Code::JS_TO_WASM_FUNCTION; |
3440 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), | 3431 Handle<WasmCompiledModule> compiled_module(instance->compiled_module(), |
3441 isolate); | 3432 isolate); |
3442 | 3433 |
3443 if (is_js_to_wasm) { | 3434 if (is_js_to_wasm) { |
3444 non_compiled_functions.push_back({0, exported_func_index}); | 3435 non_compiled_functions.push_back({0, exported_func_index}); |
3445 } else if (patch_caller) { | 3436 } else if (patch_caller) { |
(...skipping 24 matching lines...) Expand all Loading... |
3470 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); | 3461 ExtractDirectCallIndex(decoder, func_bytes + byte_pos); |
3471 non_compiled_functions.push_back({offset, called_func_index}); | 3462 non_compiled_functions.push_back({offset, called_func_index}); |
3472 // Call offset one instruction after the call. Remember the last called | 3463 // Call offset one instruction after the call. Remember the last called |
3473 // function before that offset. | 3464 // function before that offset. |
3474 if (offset < call_offset) func_to_return_idx = called_func_index; | 3465 if (offset < call_offset) func_to_return_idx = called_func_index; |
3475 } | 3466 } |
3476 } | 3467 } |
3477 | 3468 |
3478 // TODO(clemensh): compile all functions in non_compiled_functions in | 3469 // TODO(clemensh): compile all functions in non_compiled_functions in |
3479 // background, wait for func_to_return_idx. | 3470 // background, wait for func_to_return_idx. |
3480 CompileFunction(isolate, instance, func_to_return_idx, counters); | 3471 CompileFunction(isolate, instance, func_to_return_idx, counters_shared.get()); |
3481 | 3472 |
3482 if (is_js_to_wasm || patch_caller) { | 3473 if (is_js_to_wasm || patch_caller) { |
3483 DisallowHeapAllocation no_gc; | 3474 DisallowHeapAllocation no_gc; |
3484 // Now patch the code object with all functions which are now compiled. | 3475 // Now patch the code object with all functions which are now compiled. |
3485 int idx = 0; | 3476 int idx = 0; |
3486 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done(); | 3477 for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done(); |
3487 it.next()) { | 3478 it.next()) { |
3488 Code* callee = | 3479 Code* callee = |
3489 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); | 3480 Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); |
3490 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue; | 3481 if (callee->builtin_index() != Builtins::kWasmCompileLazy) continue; |
(...skipping 22 matching lines...) Expand all Loading... |
3513 callee_compiled->instruction_start()); | 3504 callee_compiled->instruction_start()); |
3514 } | 3505 } |
3515 DCHECK_EQ(non_compiled_functions.size(), idx); | 3506 DCHECK_EQ(non_compiled_functions.size(), idx); |
3516 } | 3507 } |
3517 | 3508 |
3518 Code* ret = | 3509 Code* ret = |
3519 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); | 3510 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); |
3520 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); | 3511 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); |
3521 return handle(ret, isolate); | 3512 return handle(ret, isolate); |
3522 } | 3513 } |
OLD | NEW |