1 // Copyright 2022 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_MAGLEV_MAGLEV_CONCURRENT_DISPATCHER_H_ 6 #define V8_MAGLEV_MAGLEV_CONCURRENT_DISPATCHER_H_ 7 8 #ifdef V8_ENABLE_MAGLEV 9 10 #include <memory> 11 12 #include "src/codegen/compiler.h" // For OptimizedCompilationJob. 13 #include "src/utils/locked-queue.h" 14 15 namespace v8 { 16 namespace internal { 17 18 class Isolate; 19 20 namespace maglev { 21 22 class MaglevCompilationInfo; 23 24 // TODO(v8:7700): While basic infrastructure now exists, there are many TODOs 25 // that should still be addressed soon: 26 // - Full tracing support through --trace-opt. 27 // - Concurrent codegen. 28 // - Concurrent Code object creation (optional?). 29 // - Test support for concurrency (see %FinalizeOptimization). 30 31 // Exports needed functionality without exposing implementation details. 32 class ExportedMaglevCompilationInfo final { 33 public: ExportedMaglevCompilationInfo(MaglevCompilationInfo * info)34 explicit ExportedMaglevCompilationInfo(MaglevCompilationInfo* info) 35 : info_(info) {} 36 37 Zone* zone() const; 38 void set_canonical_handles( 39 std::unique_ptr<CanonicalHandlesMap>&& canonical_handles); 40 41 private: 42 MaglevCompilationInfo* const info_; 43 }; 44 45 // The job is a single actual compilation task. 46 class MaglevCompilationJob final : public OptimizedCompilationJob { 47 public: 48 static std::unique_ptr<MaglevCompilationJob> New(Isolate* isolate, 49 Handle<JSFunction> function); 50 virtual ~MaglevCompilationJob(); 51 52 Status PrepareJobImpl(Isolate* isolate) override; 53 Status ExecuteJobImpl(RuntimeCallStats* stats, 54 LocalIsolate* local_isolate) override; 55 Status FinalizeJobImpl(Isolate* isolate) override; 56 57 Handle<JSFunction> function() const; 58 59 private: 60 explicit MaglevCompilationJob(std::unique_ptr<MaglevCompilationInfo>&& info); 61 info()62 MaglevCompilationInfo* info() const { return info_.get(); } 63 64 const std::unique_ptr<MaglevCompilationInfo> info_; 65 }; 66 67 // The public API for Maglev concurrent compilation. 68 // Keep this as minimal as possible. 69 class MaglevConcurrentDispatcher final { 70 class JobTask; 71 72 // TODO(jgruber): There's no reason to use locking queues here, we only use 73 // them for simplicity - consider replacing with lock-free data structures. 74 using QueueT = LockedQueue<std::unique_ptr<MaglevCompilationJob>>; 75 76 public: 77 explicit MaglevConcurrentDispatcher(Isolate* isolate); 78 ~MaglevConcurrentDispatcher(); 79 80 // Called from the main thread. 81 void EnqueueJob(std::unique_ptr<MaglevCompilationJob>&& job); 82 83 // Called from the main thread. 84 void FinalizeFinishedJobs(); 85 is_enabled()86 bool is_enabled() const { return static_cast<bool>(job_handle_); } 87 88 private: 89 Isolate* const isolate_; 90 std::unique_ptr<JobHandle> job_handle_; 91 QueueT incoming_queue_; 92 QueueT outgoing_queue_; 93 }; 94 95 } // namespace maglev 96 } // namespace internal 97 } // namespace v8 98 99 #endif // V8_ENABLE_MAGLEV 100 101 #endif // V8_MAGLEV_MAGLEV_CONCURRENT_DISPATCHER_H_ 102