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 15namespace v8 { 16namespace internal { 17 18class Isolate; 19 20namespace maglev { 21 22class 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. 32class ExportedMaglevCompilationInfo final { 33 public: 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. 46class 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 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. 69class 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 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