1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_BIN_ISOLATE_DATA_H_
6#define RUNTIME_BIN_ISOLATE_DATA_H_
7
8#include <memory>
9#include <utility>
10
11#include "include/dart_api.h"
12#include "platform/assert.h"
13#include "platform/globals.h"
14#include "platform/growable_array.h"
15#include "platform/utils.h"
16
17namespace dart {
18
19// Forward declaration.
20template <typename T>
21class MallocGrowableArray;
22
23} // namespace dart
24
25namespace dart {
26namespace bin {
27
28// Forward declaration.
29class AppSnapshot;
30class EventHandler;
31class Loader;
32
33// Data associated with every isolate group in the standalone VM
34// embedding. This is used to free external resources for each isolate
35// group when the isolate group shuts down.
36class IsolateGroupData {
37 public:
38 IsolateGroupData(const char* url,
39 const char* packages_file,
40 AppSnapshot* app_snapshot,
41 bool isolate_run_app_snapshot);
42 ~IsolateGroupData();
43
44 char* script_url;
45
46 const std::shared_ptr<uint8_t>& kernel_buffer() const {
47 return kernel_buffer_;
48 }
49
50 intptr_t kernel_buffer_size() const { return kernel_buffer_size_; }
51
52 // Associate the given kernel buffer with this IsolateGroupData without
53 // giving it ownership of the buffer.
54 void SetKernelBufferUnowned(uint8_t* buffer, intptr_t size) {
55 ASSERT(kernel_buffer_.get() == NULL);
56 kernel_buffer_ = std::shared_ptr<uint8_t>(buffer, FreeUnownedKernelBuffer);
57 kernel_buffer_size_ = size;
58 }
59
60 // Associate the given kernel buffer with this IsolateGroupData and give it
61 // ownership of the buffer. This IsolateGroupData is the first one to own the
62 // buffer.
63 void SetKernelBufferNewlyOwned(uint8_t* buffer, intptr_t size) {
64 ASSERT(kernel_buffer_.get() == NULL);
65 kernel_buffer_ = std::shared_ptr<uint8_t>(buffer, free);
66 kernel_buffer_size_ = size;
67 }
68
69 // Associate the given kernel buffer with this IsolateGroupData and give it
70 // ownership of the buffer. The buffer is already owned by another
71 // IsolateGroupData.
72 void SetKernelBufferAlreadyOwned(std::shared_ptr<uint8_t> buffer,
73 intptr_t size) {
74 ASSERT(kernel_buffer_.get() == NULL);
75 kernel_buffer_ = std::move(buffer);
76 kernel_buffer_size_ = size;
77 }
78
79 const char* resolved_packages_config() const {
80 return resolved_packages_config_;
81 }
82
83 void set_resolved_packages_config(const char* packages_config) {
84 if (resolved_packages_config_ != NULL) {
85 free(resolved_packages_config_);
86 resolved_packages_config_ = NULL;
87 }
88 resolved_packages_config_ = Utils::StrDup(packages_config);
89 }
90
91 bool RunFromAppSnapshot() const {
92 // If the main isolate is using an app snapshot the [app_snapshot_] pointer
93 // will be still nullptr (see main.cc:CreateIsolateGroupAndSetupHelper)
94 //
95 // Because of thus we have an additional boolean signaling whether the
96 // isolate was started from an app snapshot.
97 return app_snapshot_ != nullptr || isolate_run_app_snapshot_;
98 }
99
100 void AddLoadingUnit(AppSnapshot* loading_unit) {
101 loading_units_.Add(loading_unit);
102 }
103
104 private:
105 friend class IsolateData; // For packages_file_
106
107 std::unique_ptr<AppSnapshot> app_snapshot_;
108 MallocGrowableArray<AppSnapshot*> loading_units_;
109 char* resolved_packages_config_;
110 std::shared_ptr<uint8_t> kernel_buffer_;
111 intptr_t kernel_buffer_size_;
112 char* packages_file_ = nullptr;
113 bool isolate_run_app_snapshot_;
114
115 static void FreeUnownedKernelBuffer(uint8_t*) {}
116
117 DISALLOW_COPY_AND_ASSIGN(IsolateGroupData);
118};
119
120// Data associated with every isolate in the standalone VM
121// embedding. This is used to free external resources for each isolate
122// when the isolate shuts down.
123class IsolateData {
124 public:
125 explicit IsolateData(IsolateGroupData* isolate_group_data);
126 ~IsolateData();
127
128 IsolateGroupData* isolate_group_data() const { return isolate_group_data_; }
129
130 void UpdatePackagesFile(const char* packages_file) {
131 if (packages_file != nullptr) {
132 free(packages_file_);
133 packages_file_ = nullptr;
134 }
135 packages_file_ = Utils::StrDup(packages_file);
136 }
137
138 // While loading a loader is associated with the isolate.
139 bool HasLoader() const { return loader_ != NULL; }
140 Loader* loader() const {
141 ASSERT(loader_ != NULL);
142 return loader_;
143 }
144 void set_loader(Loader* loader) {
145 ASSERT((loader_ == NULL) || (loader == NULL));
146 loader_ = loader;
147 }
148
149 const char* packages_file() const { return packages_file_; }
150
151 private:
152 IsolateGroupData* isolate_group_data_;
153 Loader* loader_;
154 char* packages_file_;
155
156 DISALLOW_COPY_AND_ASSIGN(IsolateData);
157};
158
159} // namespace bin
160} // namespace dart
161
162#endif // RUNTIME_BIN_ISOLATE_DATA_H_
163