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_COMPILATION_INFO_H_
6#define V8_MAGLEV_MAGLEV_COMPILATION_INFO_H_
7
8#include <memory>
9
10#include "src/handles/handles.h"
11#include "src/handles/maybe-handles.h"
12
13namespace v8 {
14namespace internal {
15
16class Isolate;
17class PersistentHandles;
18class SharedFunctionInfo;
19class Zone;
20
21namespace compiler {
22class JSHeapBroker;
23}
24
25namespace maglev {
26
27class Graph;
28class MaglevCompilationUnit;
29class MaglevGraphLabeller;
30
31#define MAGLEV_COMPILATION_FLAG_LIST(V) \
32  V(code_comments)                      \
33  V(maglev)                             \
34  V(print_maglev_code)                  \
35  V(print_maglev_graph)                 \
36  V(trace_maglev_regalloc)
37
38class MaglevCompilationInfo final {
39 public:
40  static std::unique_ptr<MaglevCompilationInfo> New(
41      Isolate* isolate, Handle<JSFunction> function) {
42    // Doesn't use make_unique due to the private ctor.
43    return std::unique_ptr<MaglevCompilationInfo>(
44        new MaglevCompilationInfo(isolate, function));
45  }
46  ~MaglevCompilationInfo();
47
48  Isolate* isolate() const { return isolate_; }
49  Zone* zone() { return &zone_; }
50  compiler::JSHeapBroker* broker() const { return broker_.get(); }
51  MaglevCompilationUnit* toplevel_compilation_unit() const {
52    return toplevel_compilation_unit_;
53  }
54  Handle<JSFunction> function() const { return function_; }
55
56  bool has_graph_labeller() const { return !!graph_labeller_; }
57  void set_graph_labeller(MaglevGraphLabeller* graph_labeller);
58  MaglevGraphLabeller* graph_labeller() const {
59    DCHECK(has_graph_labeller());
60    return graph_labeller_.get();
61  }
62
63  void set_graph(Graph* graph) { graph_ = graph; }
64  Graph* graph() const { return graph_; }
65
66  // Flag accessors (for thread-safe access to global flags).
67  // TODO(v8:7700): Consider caching these.
68#define V(Name) \
69  bool Name() const { return Name##_; }
70  MAGLEV_COMPILATION_FLAG_LIST(V)
71#undef V
72
73  // Must be called from within a MaglevCompilationHandleScope. Transfers owned
74  // handles (e.g. shared_, function_) to the new scope.
75  void ReopenHandlesInNewHandleScope(Isolate* isolate);
76
77  // Persistent and canonical handles are passed back and forth between the
78  // Isolate, this info, and the LocalIsolate.
79  void set_persistent_handles(
80      std::unique_ptr<PersistentHandles>&& persistent_handles);
81  std::unique_ptr<PersistentHandles> DetachPersistentHandles();
82  void set_canonical_handles(
83      std::unique_ptr<CanonicalHandlesMap>&& canonical_handles);
84  std::unique_ptr<CanonicalHandlesMap> DetachCanonicalHandles();
85
86 private:
87  MaglevCompilationInfo(Isolate* isolate, Handle<JSFunction> function);
88
89  Zone zone_;
90  Isolate* const isolate_;
91  const std::unique_ptr<compiler::JSHeapBroker> broker_;
92  // Must be initialized late since it requires an initialized heap broker.
93  MaglevCompilationUnit* toplevel_compilation_unit_ = nullptr;
94
95  Handle<SharedFunctionInfo> shared_;
96  Handle<JSFunction> function_;
97
98  std::unique_ptr<MaglevGraphLabeller> graph_labeller_;
99
100  // Produced off-thread during ExecuteJobImpl.
101  Graph* graph_ = nullptr;
102
103#define V(Name) const bool Name##_;
104  MAGLEV_COMPILATION_FLAG_LIST(V)
105#undef V
106
107  // 1) PersistentHandles created via PersistentHandlesScope inside of
108  //    CompilationHandleScope.
109  // 2) Owned by MaglevCompilationInfo.
110  // 3) Owned by the broker's LocalHeap when entering the LocalHeapScope.
111  // 4) Back to MaglevCompilationInfo when exiting the LocalHeapScope.
112  //
113  // TODO(jgruber,v8:7700): Update this comment:
114  //
115  // In normal execution it gets destroyed when PipelineData gets destroyed.
116  // There is a special case in GenerateCodeForTesting where the JSHeapBroker
117  // will not be retired in that same method. In this case, we need to re-attach
118  // the PersistentHandles container to the JSHeapBroker.
119  std::unique_ptr<PersistentHandles> ph_;
120
121  // Canonical handles follow the same path as described by the persistent
122  // handles above. The only difference is that is created in the
123  // CanonicalHandleScope(i.e step 1) is different).
124  std::unique_ptr<CanonicalHandlesMap> canonical_handles_;
125};
126
127}  // namespace maglev
128}  // namespace internal
129}  // namespace v8
130
131#endif  // V8_MAGLEV_MAGLEV_COMPILATION_INFO_H_
132