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/asmjs/asm-js.h" | 7 #include "src/asmjs/asm-js.h" |
8 #include "src/assembler-inl.h" | 8 #include "src/assembler-inl.h" |
9 #include "src/base/atomic-utils.h" | 9 #include "src/base/atomic-utils.h" |
| 10 #include "src/base/utils/random-number-generator.h" |
10 #include "src/code-stubs.h" | 11 #include "src/code-stubs.h" |
11 #include "src/compiler/wasm-compiler.h" | 12 #include "src/compiler/wasm-compiler.h" |
12 #include "src/debug/interface-types.h" | 13 #include "src/debug/interface-types.h" |
13 #include "src/frames-inl.h" | 14 #include "src/frames-inl.h" |
14 #include "src/objects.h" | 15 #include "src/objects.h" |
15 #include "src/property-descriptor.h" | 16 #include "src/property-descriptor.h" |
16 #include "src/simulator.h" | 17 #include "src/simulator.h" |
17 #include "src/snapshot/snapshot.h" | 18 #include "src/snapshot/snapshot.h" |
18 #include "src/trap-handler/trap-handler.h" | 19 #include "src/trap-handler/trap-handler.h" |
19 #include "src/v8.h" | 20 #include "src/v8.h" |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 | 292 |
292 // A helper for compiling an entire module. | 293 // A helper for compiling an entire module. |
293 class CompilationHelper { | 294 class CompilationHelper { |
294 public: | 295 public: |
295 // The compilation helper takes ownership of the {WasmModule}. | 296 // The compilation helper takes ownership of the {WasmModule}. |
296 // In {CompileToModuleObject}, it will transfer ownership to the generated | 297 // In {CompileToModuleObject}, it will transfer ownership to the generated |
297 // {WasmModuleWrapper}. If this method is not called, ownership may be | 298 // {WasmModuleWrapper}. If this method is not called, ownership may be |
298 // reclaimed by explicitely releasing the {module_} field. | 299 // reclaimed by explicitely releasing the {module_} field. |
299 CompilationHelper(Isolate* isolate, std::unique_ptr<WasmModule> module, | 300 CompilationHelper(Isolate* isolate, std::unique_ptr<WasmModule> module, |
300 bool is_sync) | 301 bool is_sync) |
301 : isolate_(isolate), module_(std::move(module)), is_sync_(is_sync) {} | 302 : isolate_(isolate), |
| 303 module_(std::move(module)), |
| 304 is_sync_(is_sync), |
| 305 executed_units_( |
| 306 isolate->random_number_generator(), |
| 307 (isolate->heap()->memory_allocator()->code_range()->valid() |
| 308 ? isolate->heap()->memory_allocator()->code_range()->size() |
| 309 : isolate->heap()->code_space()->Capacity()) / |
| 310 2), |
| 311 num_background_tasks_(Min( |
| 312 static_cast<size_t>(FLAG_wasm_num_compilation_tasks), |
| 313 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())), |
| 314 stopped_compilation_tasks_(num_background_tasks_) {} |
| 315 |
| 316 bool GetNextUncompiledFunctionId(size_t* index) { |
| 317 DCHECK_NOT_NULL(index); |
| 318 // - 1 because AtomicIncrement returns the value after the atomic increment. |
| 319 *index = next_unit_.Increment(1) - 1; |
| 320 return *index < compilation_units_.size(); |
| 321 } |
302 | 322 |
303 // The actual runnable task that performs compilations in the background. | 323 // The actual runnable task that performs compilations in the background. |
304 class CompilationTask : public CancelableTask { | 324 class CompilationTask : public CancelableTask { |
305 public: | 325 public: |
306 CompilationHelper* helper_; | 326 CompilationHelper* helper_; |
307 explicit CompilationTask(CompilationHelper* helper) | 327 explicit CompilationTask(CompilationHelper* helper) |
308 : CancelableTask(helper->isolate_), helper_(helper) {} | 328 : CancelableTask(helper->isolate_, &helper->background_task_manager_), |
| 329 helper_(helper) {} |
309 | 330 |
310 void RunInternal() override { | 331 void RunInternal() override { |
311 while (helper_->FetchAndExecuteCompilationUnit()) { | 332 size_t index = 0; |
| 333 while (helper_->executed_units_.CanAcceptWork() && |
| 334 helper_->GetNextUncompiledFunctionId(&index)) { |
| 335 helper_->CompileAndSchedule(index); |
312 } | 336 } |
313 helper_->module_->pending_tasks.get()->Signal(); | 337 helper_->OnBackgroundTaskStopped(); |
314 } | 338 } |
315 }; | 339 }; |
316 | 340 |
| 341 void OnBackgroundTaskStopped() { |
| 342 base::LockGuard<base::Mutex> guard(&tasks_mutex_); |
| 343 ++stopped_compilation_tasks_; |
| 344 DCHECK_LE(stopped_compilation_tasks_, num_background_tasks_); |
| 345 } |
| 346 |
| 347 void CompileAndSchedule(size_t index) { |
| 348 DisallowHeapAllocation no_allocation; |
| 349 DisallowHandleAllocation no_handles; |
| 350 DisallowHandleDereference no_deref; |
| 351 DisallowCodeDependencyChange no_dependency_change; |
| 352 DCHECK_LT(index, compilation_units_.size()); |
| 353 |
| 354 std::unique_ptr<compiler::WasmCompilationUnit> unit = |
| 355 std::move(compilation_units_.at(index)); |
| 356 unit->ExecuteCompilation(); |
| 357 { |
| 358 base::LockGuard<base::Mutex> guard(&result_mutex_); |
| 359 executed_units_.Schedule(std::move(unit)); |
| 360 } |
| 361 } |
| 362 |
| 363 class CodeGenerationSchedule { |
| 364 public: |
| 365 explicit CodeGenerationSchedule( |
| 366 base::RandomNumberGenerator* random_number_generator, |
| 367 size_t max_memory = 0); |
| 368 |
| 369 void Schedule(std::unique_ptr<compiler::WasmCompilationUnit>&& item); |
| 370 |
| 371 bool IsEmpty() const { return schedule_.empty(); } |
| 372 |
| 373 std::unique_ptr<compiler::WasmCompilationUnit> GetNext(); |
| 374 |
| 375 bool CanAcceptWork() const; |
| 376 |
| 377 void EnableThrottling() { throttle_ = true; } |
| 378 |
| 379 private: |
| 380 size_t GetRandomIndexInSchedule(); |
| 381 |
| 382 base::RandomNumberGenerator* random_number_generator_ = nullptr; |
| 383 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> schedule_; |
| 384 const size_t max_memory_; |
| 385 bool throttle_ = false; |
| 386 base::AtomicNumber<size_t> allocated_memory_{0}; |
| 387 }; |
| 388 |
317 Isolate* isolate_; | 389 Isolate* isolate_; |
318 std::unique_ptr<WasmModule> module_; | 390 std::unique_ptr<WasmModule> module_; |
319 bool is_sync_; | 391 bool is_sync_; |
320 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> | 392 std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> |
321 compilation_units_; | 393 compilation_units_; |
322 std::queue<std::unique_ptr<compiler::WasmCompilationUnit>> executed_units_; | 394 CodeGenerationSchedule executed_units_; |
323 base::Mutex result_mutex_; | 395 base::Mutex result_mutex_; |
324 base::AtomicNumber<size_t> next_unit_; | 396 base::AtomicNumber<size_t> next_unit_; |
325 size_t num_background_tasks_ = 0; | 397 const size_t num_background_tasks_ = 0; |
| 398 CancelableTaskManager background_task_manager_; |
326 | 399 |
327 // Run by each compilation task and by the main thread. | 400 // Run by each compilation task and by the main thread. |
328 bool FetchAndExecuteCompilationUnit() { | 401 bool FetchAndExecuteCompilationUnit() { |
329 DisallowHeapAllocation no_allocation; | 402 DisallowHeapAllocation no_allocation; |
330 DisallowHandleAllocation no_handles; | 403 DisallowHandleAllocation no_handles; |
331 DisallowHandleDereference no_deref; | 404 DisallowHandleDereference no_deref; |
332 DisallowCodeDependencyChange no_dependency_change; | 405 DisallowCodeDependencyChange no_dependency_change; |
333 | 406 |
334 // - 1 because AtomicIncrement returns the value after the atomic increment. | 407 // - 1 because AtomicIncrement returns the value after the atomic increment. |
335 size_t index = next_unit_.Increment(1) - 1; | 408 size_t index = next_unit_.Increment(1) - 1; |
336 if (index >= compilation_units_.size()) { | 409 if (index >= compilation_units_.size()) { |
337 return false; | 410 return false; |
338 } | 411 } |
339 | 412 |
340 std::unique_ptr<compiler::WasmCompilationUnit> unit = | 413 std::unique_ptr<compiler::WasmCompilationUnit> unit = |
341 std::move(compilation_units_.at(index)); | 414 std::move(compilation_units_.at(index)); |
342 unit->ExecuteCompilation(); | 415 unit->ExecuteCompilation(); |
343 base::LockGuard<base::Mutex> guard(&result_mutex_); | 416 base::LockGuard<base::Mutex> guard(&result_mutex_); |
344 executed_units_.push(std::move(unit)); | 417 executed_units_.Schedule(std::move(unit)); |
345 return true; | 418 return true; |
346 } | 419 } |
347 | 420 |
348 size_t InitializeParallelCompilation( | 421 size_t InitializeParallelCompilation( |
349 const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env) { | 422 const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env) { |
350 uint32_t start = module_env.module_env.module->num_imported_functions + | 423 uint32_t start = module_env.module_env.module->num_imported_functions + |
351 FLAG_skip_compiling_wasm_funcs; | 424 FLAG_skip_compiling_wasm_funcs; |
352 uint32_t num_funcs = static_cast<uint32_t>(functions.size()); | 425 uint32_t num_funcs = static_cast<uint32_t>(functions.size()); |
353 uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start; | 426 uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start; |
354 compilation_units_.reserve(funcs_to_compile); | 427 compilation_units_.reserve(funcs_to_compile); |
355 for (uint32_t i = start; i < num_funcs; ++i) { | 428 for (uint32_t i = start; i < num_funcs; ++i) { |
356 const WasmFunction* func = &functions[i]; | 429 const WasmFunction* func = &functions[i]; |
357 constexpr bool is_sync = true; | 430 constexpr bool is_sync = true; |
358 compilation_units_.push_back( | 431 compilation_units_.push_back( |
359 std::unique_ptr<compiler::WasmCompilationUnit>( | 432 std::unique_ptr<compiler::WasmCompilationUnit>( |
360 new compiler::WasmCompilationUnit(isolate_, &module_env, func, | 433 new compiler::WasmCompilationUnit(isolate_, &module_env, func, |
361 !is_sync))); | 434 !is_sync))); |
362 } | 435 } |
363 return funcs_to_compile; | 436 return funcs_to_compile; |
364 } | 437 } |
365 | 438 |
366 void InitializeHandles() { | 439 void RestartCompilationTasks() { |
367 for (auto& unit : compilation_units_) { | 440 base::LockGuard<base::Mutex> guard(&tasks_mutex_); |
368 unit->InitializeHandles(); | 441 for (; stopped_compilation_tasks_ > 0; --stopped_compilation_tasks_) { |
| 442 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 443 new CompilationTask(this), v8::Platform::kShortRunningTask); |
369 } | 444 } |
370 } | 445 } |
371 | 446 |
372 uint32_t* StartCompilationTasks() { | |
373 num_background_tasks_ = | |
374 Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), | |
375 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()); | |
376 uint32_t* task_ids = new uint32_t[num_background_tasks_]; | |
377 for (size_t i = 0; i < num_background_tasks_; ++i) { | |
378 CompilationTask* task = new CompilationTask(this); | |
379 task_ids[i] = task->id(); | |
380 V8::GetCurrentPlatform()->CallOnBackgroundThread( | |
381 task, v8::Platform::kShortRunningTask); | |
382 } | |
383 return task_ids; | |
384 } | |
385 | |
386 void WaitForCompilationTasks(uint32_t* task_ids) { | 447 void WaitForCompilationTasks(uint32_t* task_ids) { |
387 for (size_t i = 0; i < num_background_tasks_; ++i) { | 448 for (size_t i = 0; i < num_background_tasks_; ++i) { |
388 // If the task has not started yet, then we abort it. Otherwise we wait | 449 // If the task has not started yet, then we abort it. Otherwise we wait |
389 // for it to finish. | 450 // for it to finish. |
390 if (isolate_->cancelable_task_manager()->TryAbort(task_ids[i]) != | 451 if (isolate_->cancelable_task_manager()->TryAbort(task_ids[i]) != |
391 CancelableTaskManager::kTaskAborted) { | 452 CancelableTaskManager::kTaskAborted) { |
392 module_->pending_tasks.get()->Wait(); | 453 module_->pending_tasks.get()->Wait(); |
393 } | 454 } |
394 } | 455 } |
395 } | 456 } |
396 | 457 |
397 void FinishCompilationUnits(std::vector<Handle<Code>>& results, | 458 size_t FinishCompilationUnits(std::vector<Handle<Code>>& results, |
398 ErrorThrower* thrower) { | 459 ErrorThrower* thrower) { |
| 460 size_t finished = 0; |
399 while (true) { | 461 while (true) { |
400 int func_index = -1; | 462 int func_index = -1; |
401 Handle<Code> result = FinishCompilationUnit(thrower, &func_index); | 463 Handle<Code> result = FinishCompilationUnit(thrower, &func_index); |
402 if (func_index < 0) break; | 464 if (func_index < 0) break; |
403 results[func_index] = result; | 465 results[func_index] = result; |
| 466 ++finished; |
404 } | 467 } |
| 468 RestartCompilationTasks(); |
| 469 return finished; |
405 } | 470 } |
406 | 471 |
407 Handle<Code> FinishCompilationUnit(ErrorThrower* thrower, int* func_index) { | 472 Handle<Code> FinishCompilationUnit(ErrorThrower* thrower, int* func_index) { |
408 std::unique_ptr<compiler::WasmCompilationUnit> unit; | 473 std::unique_ptr<compiler::WasmCompilationUnit> unit; |
409 { | 474 { |
410 base::LockGuard<base::Mutex> guard(&result_mutex_); | 475 base::LockGuard<base::Mutex> guard(&result_mutex_); |
411 if (executed_units_.empty()) return Handle<Code>::null(); | 476 if (executed_units_.IsEmpty()) return Handle<Code>::null(); |
412 unit = std::move(executed_units_.front()); | 477 unit = executed_units_.GetNext(); |
413 executed_units_.pop(); | |
414 } | 478 } |
415 *func_index = unit->func_index(); | 479 *func_index = unit->func_index(); |
416 Handle<Code> result = unit->FinishCompilation(thrower); | 480 Handle<Code> result = unit->FinishCompilation(thrower); |
417 return result; | 481 return result; |
418 } | 482 } |
419 | 483 |
420 void CompileInParallel(ModuleBytesEnv* module_env, | 484 void CompileInParallel(ModuleBytesEnv* module_env, |
421 std::vector<Handle<Code>>& results, | 485 std::vector<Handle<Code>>& results, |
422 ErrorThrower* thrower) { | 486 ErrorThrower* thrower) { |
423 const WasmModule* module = module_env->module_env.module; | 487 const WasmModule* module = module_env->module_env.module; |
(...skipping 15 matching lines...) Expand all Loading... |
439 // main thread waits for all {CompilationTask} instances to finish. | 503 // main thread waits for all {CompilationTask} instances to finish. |
440 // 5) The main thread finishes the compilation. | 504 // 5) The main thread finishes the compilation. |
441 | 505 |
442 // Turn on the {CanonicalHandleScope} so that the background threads can | 506 // Turn on the {CanonicalHandleScope} so that the background threads can |
443 // use the node cache. | 507 // use the node cache. |
444 CanonicalHandleScope canonical(isolate_); | 508 CanonicalHandleScope canonical(isolate_); |
445 | 509 |
446 // 1) The main thread allocates a compilation unit for each wasm function | 510 // 1) The main thread allocates a compilation unit for each wasm function |
447 // and stores them in the vector {compilation_units}. | 511 // and stores them in the vector {compilation_units}. |
448 InitializeParallelCompilation(module->functions, *module_env); | 512 InitializeParallelCompilation(module->functions, *module_env); |
449 InitializeHandles(); | |
450 | 513 |
451 // Objects for the synchronization with the background threads. | 514 executed_units_.EnableThrottling(); |
452 base::AtomicNumber<size_t> next_unit( | |
453 static_cast<size_t>(FLAG_skip_compiling_wasm_funcs)); | |
454 | 515 |
455 // 2) The main thread spawns {CompilationTask} instances which run on | 516 // 2) The main thread spawns {CompilationTask} instances which run on |
456 // the background threads. | 517 // the background threads. |
457 std::unique_ptr<uint32_t[]> task_ids(StartCompilationTasks()); | 518 RestartCompilationTasks(); |
458 | 519 |
459 // 3.a) The background threads and the main thread pick one compilation | 520 size_t finished_functions = 0; |
460 // unit at a time and execute the parallel phase of the compilation | 521 while (finished_functions < compilation_units_.size()) { |
461 // unit. After finishing the execution of the parallel phase, the | 522 // 3.a) The background threads and the main thread pick one compilation |
462 // result is enqueued in {executed_units}. | 523 // unit at a time and execute the parallel phase of the compilation |
463 while (FetchAndExecuteCompilationUnit()) { | 524 // unit. After finishing the execution of the parallel phase, the |
| 525 // result is enqueued in {executed_units}. |
| 526 size_t index = 0; |
| 527 if (GetNextUncompiledFunctionId(&index)) { |
| 528 CompileAndSchedule(index); |
| 529 } |
464 // 3.b) If {executed_units} contains a compilation unit, the main thread | 530 // 3.b) If {executed_units} contains a compilation unit, the main thread |
465 // dequeues it and finishes the compilation unit. Compilation units | 531 // dequeues it and finishes the compilation unit. Compilation units |
466 // are finished concurrently to the background threads to save | 532 // are finished concurrently to the background threads to save |
467 // memory. | 533 // memory. |
468 FinishCompilationUnits(results, thrower); | 534 finished_functions += FinishCompilationUnits(results, thrower); |
469 } | 535 } |
470 // 4) After the parallel phase of all compilation units has started, the | 536 // 4) After the parallel phase of all compilation units has started, the |
471 // main thread waits for all {CompilationTask} instances to finish. | 537 // main thread waits for all {CompilationTask} instances to finish - |
472 WaitForCompilationTasks(task_ids.get()); | 538 // which happens once they all realize there's no next work item to |
473 // Finish the compilation of the remaining compilation units. | 539 // process. |
474 FinishCompilationUnits(results, thrower); | 540 background_task_manager_.CancelAndWait(); |
475 } | 541 } |
476 | 542 |
477 void CompileSequentially(ModuleBytesEnv* module_env, | 543 void CompileSequentially(ModuleBytesEnv* module_env, |
478 std::vector<Handle<Code>>& results, | 544 std::vector<Handle<Code>>& results, |
479 ErrorThrower* thrower) { | 545 ErrorThrower* thrower) { |
480 DCHECK(!thrower->error()); | 546 DCHECK(!thrower->error()); |
481 | 547 |
482 const WasmModule* module = module_env->module_env.module; | 548 const WasmModule* module = module_env->module_env.module; |
483 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; | 549 for (uint32_t i = FLAG_skip_compiling_wasm_funcs; |
484 i < module->functions.size(); ++i) { | 550 i < module->functions.size(); ++i) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 wasm_code, exp.index); | 732 wasm_code, exp.index); |
667 int export_index = | 733 int export_index = |
668 static_cast<int>(module->functions.size() + func_index); | 734 static_cast<int>(module->functions.size() + func_index); |
669 code_table->set(export_index, *wrapper_code); | 735 code_table->set(export_index, *wrapper_code); |
670 RecordStats(isolate_, *wrapper_code, is_sync_); | 736 RecordStats(isolate_, *wrapper_code, is_sync_); |
671 func_index++; | 737 func_index++; |
672 } | 738 } |
673 | 739 |
674 return WasmModuleObject::New(isolate_, compiled_module); | 740 return WasmModuleObject::New(isolate_, compiled_module); |
675 } | 741 } |
| 742 size_t stopped_compilation_tasks_ = 0; |
| 743 base::Mutex tasks_mutex_; |
676 }; | 744 }; |
677 | 745 |
| 746 CompilationHelper::CodeGenerationSchedule::CodeGenerationSchedule( |
| 747 base::RandomNumberGenerator* random_number_generator, size_t max_memory) |
| 748 : random_number_generator_(random_number_generator), |
| 749 max_memory_(max_memory) { |
| 750 DCHECK_NOT_NULL(random_number_generator_); |
| 751 DCHECK_GT(max_memory_, 0); |
| 752 } |
| 753 |
| 754 void CompilationHelper::CodeGenerationSchedule::Schedule( |
| 755 std::unique_ptr<compiler::WasmCompilationUnit>&& item) { |
| 756 size_t cost = item->memory_cost(); |
| 757 schedule_.push_back(std::move(item)); |
| 758 allocated_memory_.Increment(cost); |
| 759 } |
| 760 |
| 761 bool CompilationHelper::CodeGenerationSchedule::CanAcceptWork() const { |
| 762 return (!throttle_ || allocated_memory_.Value() <= max_memory_); |
| 763 } |
| 764 |
| 765 std::unique_ptr<compiler::WasmCompilationUnit> |
| 766 CompilationHelper::CodeGenerationSchedule::GetNext() { |
| 767 DCHECK(!IsEmpty()); |
| 768 size_t index = GetRandomIndexInSchedule(); |
| 769 auto ret = std::move(schedule_[index]); |
| 770 std::swap(schedule_[schedule_.size() - 1], schedule_[index]); |
| 771 schedule_.pop_back(); |
| 772 allocated_memory_.Decrement(ret->memory_cost()); |
| 773 return ret; |
| 774 } |
| 775 |
| 776 size_t CompilationHelper::CodeGenerationSchedule::GetRandomIndexInSchedule() { |
| 777 double factor = random_number_generator_->NextDouble(); |
| 778 size_t index = (size_t)(factor * schedule_.size()); |
| 779 DCHECK_GE(index, 0); |
| 780 DCHECK_LT(index, schedule_.size()); |
| 781 return index; |
| 782 } |
| 783 |
678 static void MemoryInstanceFinalizer(Isolate* isolate, | 784 static void MemoryInstanceFinalizer(Isolate* isolate, |
679 WasmInstanceObject* instance) { | 785 WasmInstanceObject* instance) { |
680 DisallowHeapAllocation no_gc; | 786 DisallowHeapAllocation no_gc; |
681 // If the memory object is destroyed, nothing needs to be done here. | 787 // If the memory object is destroyed, nothing needs to be done here. |
682 if (!instance->has_memory_object()) return; | 788 if (!instance->has_memory_object()) return; |
683 Handle<WasmInstanceWrapper> instance_wrapper = | 789 Handle<WasmInstanceWrapper> instance_wrapper = |
684 handle(instance->instance_wrapper()); | 790 handle(instance->instance_wrapper()); |
685 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); | 791 DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper)); |
686 DCHECK(instance_wrapper->has_instance()); | 792 DCHECK(instance_wrapper->has_instance()); |
687 bool has_prev = instance_wrapper->has_previous(); | 793 bool has_prev = instance_wrapper->has_previous(); |
(...skipping 1950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2638 std::unique_ptr<WasmInstance> temp_instance_ = nullptr; | 2744 std::unique_ptr<WasmInstance> temp_instance_ = nullptr; |
2639 size_t outstanding_units_ = 0; | 2745 size_t outstanding_units_ = 0; |
2640 size_t num_background_tasks_ = 0; | 2746 size_t num_background_tasks_ = 0; |
2641 | 2747 |
2642 void ReopenHandlesInDeferredScope() { | 2748 void ReopenHandlesInDeferredScope() { |
2643 DeferredHandleScope deferred(isolate_); | 2749 DeferredHandleScope deferred(isolate_); |
2644 function_tables_ = handle(*function_tables_, isolate_); | 2750 function_tables_ = handle(*function_tables_, isolate_); |
2645 signature_tables_ = handle(*signature_tables_, isolate_); | 2751 signature_tables_ = handle(*signature_tables_, isolate_); |
2646 code_table_ = handle(*code_table_, isolate_); | 2752 code_table_ = handle(*code_table_, isolate_); |
2647 temp_instance_->ReopenHandles(isolate_); | 2753 temp_instance_->ReopenHandles(isolate_); |
2648 helper_->InitializeHandles(); | 2754 for (auto& unit : helper_->compilation_units_) { |
| 2755 unit->ReopenCentryStub(); |
| 2756 } |
2649 deferred_handles_.push_back(deferred.Detach()); | 2757 deferred_handles_.push_back(deferred.Detach()); |
2650 } | 2758 } |
2651 | 2759 |
2652 void AsyncCompileFailed(ErrorThrower& thrower) { | 2760 void AsyncCompileFailed(ErrorThrower& thrower) { |
2653 RejectPromise(isolate_, context_, thrower, module_promise_); | 2761 RejectPromise(isolate_, context_, thrower, module_promise_); |
2654 // The AsyncCompileJob is finished, we resolved the promise, we do not need | 2762 // The AsyncCompileJob is finished, we resolved the promise, we do not need |
2655 // the data anymore. We can delete the AsyncCompileJob object. | 2763 // the data anymore. We can delete the AsyncCompileJob object. |
2656 if (!FLAG_verify_predictable) delete this; | 2764 if (!FLAG_verify_predictable) delete this; |
2657 } | 2765 } |
2658 | 2766 |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3198 { | 3306 { |
3199 wasm::WasmName name = Vector<const char>::cast( | 3307 wasm::WasmName name = Vector<const char>::cast( |
3200 compiled_module->GetRawFunctionName(func_index)); | 3308 compiled_module->GetRawFunctionName(func_index)); |
3201 // Copy to std::string, because the underlying string object might move on | 3309 // Copy to std::string, because the underlying string object might move on |
3202 // the heap. | 3310 // the heap. |
3203 func_name.assign(name.start(), static_cast<size_t>(name.length())); | 3311 func_name.assign(name.start(), static_cast<size_t>(name.length())); |
3204 } | 3312 } |
3205 ErrorThrower thrower(isolate, "WasmLazyCompile"); | 3313 ErrorThrower thrower(isolate, "WasmLazyCompile"); |
3206 compiler::WasmCompilationUnit unit(isolate, &module_env, body, | 3314 compiler::WasmCompilationUnit unit(isolate, &module_env, body, |
3207 CStrVector(func_name.c_str()), func_index); | 3315 CStrVector(func_name.c_str()), func_index); |
3208 unit.InitializeHandles(); | |
3209 unit.ExecuteCompilation(); | 3316 unit.ExecuteCompilation(); |
3210 Handle<Code> code = unit.FinishCompilation(&thrower); | 3317 Handle<Code> code = unit.FinishCompilation(&thrower); |
3211 | 3318 |
3212 // If there is a pending error, something really went wrong. The module was | 3319 // If there is a pending error, something really went wrong. The module was |
3213 // verified before starting execution with lazy compilation. | 3320 // verified before starting execution with lazy compilation. |
3214 // This might be OOM, but then we cannot continue execution anyway. | 3321 // This might be OOM, but then we cannot continue execution anyway. |
3215 CHECK(!thrower.error()); | 3322 CHECK(!thrower.error()); |
3216 | 3323 |
3217 Handle<FixedArray> deopt_data = isolate->factory()->NewFixedArray(2, TENURED); | 3324 Handle<FixedArray> deopt_data = isolate->factory()->NewFixedArray(2, TENURED); |
3218 Handle<WeakCell> weak_instance = isolate->factory()->NewWeakCell(instance); | 3325 Handle<WeakCell> weak_instance = isolate->factory()->NewWeakCell(instance); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3338 callee_compiled->instruction_start()); | 3445 callee_compiled->instruction_start()); |
3339 } | 3446 } |
3340 DCHECK_EQ(non_compiled_functions.size(), idx); | 3447 DCHECK_EQ(non_compiled_functions.size(), idx); |
3341 } | 3448 } |
3342 | 3449 |
3343 Code* ret = | 3450 Code* ret = |
3344 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); | 3451 Code::cast(compiled_module->code_table()->get(func_to_return_idx)); |
3345 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); | 3452 DCHECK_EQ(Code::WASM_FUNCTION, ret->kind()); |
3346 return handle(ret, isolate); | 3453 return handle(ret, isolate); |
3347 } | 3454 } |
OLD | NEW |