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#include "src/maglev/maglev-compilation-info.h"
6
7#include "src/compiler/compilation-dependencies.h"
8#include "src/compiler/js-heap-broker.h"
9#include "src/execution/isolate.h"
10#include "src/flags/flags.h"
11#include "src/handles/persistent-handles.h"
12#include "src/maglev/maglev-compilation-unit.h"
13#include "src/maglev/maglev-compiler.h"
14#include "src/maglev/maglev-concurrent-dispatcher.h"
15#include "src/maglev/maglev-graph-labeller.h"
16#include "src/objects/js-function-inl.h"
17#include "src/utils/identity-map.h"
18#include "src/utils/locked-queue-inl.h"
19
20namespace v8 {
21namespace internal {
22namespace maglev {
23
24namespace {
25
26constexpr char kMaglevZoneName[] = "maglev-compilation-job-zone";
27
28class V8_NODISCARD MaglevCompilationHandleScope final {
29 public:
30  MaglevCompilationHandleScope(Isolate* isolate,
31                               maglev::MaglevCompilationInfo* info)
32      : info_(info),
33        persistent_(isolate),
34        exported_info_(info),
35        canonical_(isolate, &exported_info_) {
36    info->ReopenHandlesInNewHandleScope(isolate);
37  }
38
39  ~MaglevCompilationHandleScope() {
40    info_->set_persistent_handles(persistent_.Detach());
41  }
42
43 private:
44  maglev::MaglevCompilationInfo* const info_;
45  PersistentHandlesScope persistent_;
46  ExportedMaglevCompilationInfo exported_info_;
47  CanonicalHandleScopeForMaglev canonical_;
48};
49
50}  // namespace
51
52MaglevCompilationInfo::MaglevCompilationInfo(Isolate* isolate,
53                                             Handle<JSFunction> function)
54    : zone_(isolate->allocator(), kMaglevZoneName),
55      isolate_(isolate),
56      broker_(new compiler::JSHeapBroker(
57          isolate, zone(), FLAG_trace_heap_broker, CodeKind::MAGLEV)),
58      shared_(function->shared(), isolate),
59      function_(function)
60#define V(Name) , Name##_(FLAG_##Name)
61          MAGLEV_COMPILATION_FLAG_LIST(V)
62#undef V
63{
64  DCHECK(FLAG_maglev);
65
66  MaglevCompilationHandleScope compilation(isolate, this);
67
68  compiler::CompilationDependencies* deps =
69      zone()->New<compiler::CompilationDependencies>(broker(), zone());
70  USE(deps);  // The deps register themselves in the heap broker.
71
72  // Heap broker initialization may already use IsPendingAllocation.
73  isolate->heap()->PublishPendingAllocations();
74
75  broker()->SetTargetNativeContextRef(
76      handle(function->native_context(), isolate));
77  broker()->InitializeAndStartSerializing();
78  broker()->StopSerializing();
79
80  // Serialization may have allocated.
81  isolate->heap()->PublishPendingAllocations();
82
83  toplevel_compilation_unit_ =
84      MaglevCompilationUnit::New(zone(), this, function);
85}
86
87MaglevCompilationInfo::~MaglevCompilationInfo() = default;
88
89void MaglevCompilationInfo::set_graph_labeller(
90    MaglevGraphLabeller* graph_labeller) {
91  graph_labeller_.reset(graph_labeller);
92}
93
94void MaglevCompilationInfo::ReopenHandlesInNewHandleScope(Isolate* isolate) {
95  DCHECK(!shared_.is_null());
96  shared_ = handle(*shared_, isolate);
97  DCHECK(!function_.is_null());
98  function_ = handle(*function_, isolate);
99}
100
101void MaglevCompilationInfo::set_persistent_handles(
102    std::unique_ptr<PersistentHandles>&& persistent_handles) {
103  DCHECK_NULL(ph_);
104  ph_ = std::move(persistent_handles);
105  DCHECK_NOT_NULL(ph_);
106}
107
108std::unique_ptr<PersistentHandles>
109MaglevCompilationInfo::DetachPersistentHandles() {
110  DCHECK_NOT_NULL(ph_);
111  return std::move(ph_);
112}
113
114void MaglevCompilationInfo::set_canonical_handles(
115    std::unique_ptr<CanonicalHandlesMap>&& canonical_handles) {
116  DCHECK_NULL(canonical_handles_);
117  canonical_handles_ = std::move(canonical_handles);
118  DCHECK_NOT_NULL(canonical_handles_);
119}
120
121std::unique_ptr<CanonicalHandlesMap>
122MaglevCompilationInfo::DetachCanonicalHandles() {
123  DCHECK_NOT_NULL(canonical_handles_);
124  return std::move(canonical_handles_);
125}
126
127}  // namespace maglev
128}  // namespace internal
129}  // namespace v8
130