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_VM_OBJECT_STORE_H_
6#define RUNTIME_VM_OBJECT_STORE_H_
7
8#include "vm/object.h"
9
10namespace dart {
11
12// Forward declarations.
13class Isolate;
14class ObjectPointerVisitor;
15
16// A list of the bootstrap libraries including CamelName and name.
17//
18// These are listed in the order that they are compiled (see vm/bootstrap.cc).
19#define FOR_EACH_BOOTSTRAP_LIBRARY(M) \
20 M(Core, core) \
21 M(Async, async) \
22 M(Collection, collection) \
23 M(Convert, convert) \
24 M(Developer, developer) \
25 M(Ffi, ffi) \
26 M(Internal, _internal) \
27 M(Isolate, isolate) \
28 M(Math, math) \
29 M(Mirrors, mirrors) \
30 M(TypedData, typed_data) \
31 M(VMService, _vmservice) \
32 M(Wasm, wasm)
33
34// TODO(liama): Once NNBD is enabled, *_type will be deleted and all uses will
35// be replaced with *_type_non_nullable. Later, once we drop support for opted
36// out code, *_type_legacy will be deleted.
37//
38// R_ - needs getter only
39// RW - needs getter and setter
40// CW - needs lazy Core init getter and setter
41// FW - needs lazy Future init getter and setter
42#define OBJECT_STORE_FIELD_LIST(R_, RW, CW, FW) \
43 RW(Class, object_class) \
44 RW(Type, object_type) \
45 RW(Type, legacy_object_type) \
46 RW(Type, non_nullable_object_type) \
47 RW(Type, nullable_object_type) \
48 RW(Class, null_class) \
49 RW(Type, null_type) \
50 RW(Class, never_class) \
51 RW(Type, never_type) \
52 RW(Type, function_type) \
53 RW(Type, legacy_function_type) \
54 RW(Type, non_nullable_function_type) \
55 RW(Type, type_type) \
56 RW(Class, closure_class) \
57 RW(Type, number_type) \
58 RW(Type, legacy_number_type) \
59 RW(Type, non_nullable_number_type) \
60 RW(Type, int_type) \
61 RW(Type, legacy_int_type) \
62 RW(Type, non_nullable_int_type) \
63 RW(Type, nullable_int_type) \
64 RW(Class, integer_implementation_class) \
65 RW(Type, int64_type) \
66 RW(Class, smi_class) \
67 RW(Type, smi_type) \
68 RW(Type, legacy_smi_type) \
69 RW(Type, non_nullable_smi_type) \
70 RW(Class, mint_class) \
71 RW(Type, mint_type) \
72 RW(Type, legacy_mint_type) \
73 RW(Type, non_nullable_mint_type) \
74 RW(Class, double_class) \
75 RW(Type, double_type) \
76 RW(Type, legacy_double_type) \
77 RW(Type, non_nullable_double_type) \
78 RW(Type, nullable_double_type) \
79 RW(Type, float32x4_type) \
80 RW(Type, int32x4_type) \
81 RW(Type, float64x2_type) \
82 RW(Type, string_type) \
83 RW(Type, legacy_string_type) \
84 RW(Type, non_nullable_string_type) \
85 CW(Type, non_nullable_list_rare_type) /* maybe be null, lazily built */ \
86 CW(Type, non_nullable_map_rare_type) /* maybe be null, lazily built */ \
87 FW(Type, non_nullable_future_rare_type) /* maybe be null, lazily built */ \
88 FW(Type, non_nullable_future_never_type) /* maybe be null, lazily built */ \
89 FW(Type, nullable_future_null_type) /* maybe be null, lazily built */ \
90 RW(TypeArguments, type_argument_int) \
91 RW(TypeArguments, type_argument_legacy_int) \
92 RW(TypeArguments, type_argument_non_nullable_int) \
93 RW(TypeArguments, type_argument_double) \
94 RW(TypeArguments, type_argument_legacy_double) \
95 RW(TypeArguments, type_argument_non_nullable_double) \
96 RW(TypeArguments, type_argument_string) \
97 RW(TypeArguments, type_argument_legacy_string) \
98 RW(TypeArguments, type_argument_non_nullable_string) \
99 RW(TypeArguments, type_argument_string_dynamic) \
100 RW(TypeArguments, type_argument_legacy_string_dynamic) \
101 RW(TypeArguments, type_argument_non_nullable_string_dynamic) \
102 RW(TypeArguments, type_argument_string_string) \
103 RW(TypeArguments, type_argument_legacy_string_legacy_string) \
104 RW(TypeArguments, type_argument_non_nullable_string_non_nullable_string) \
105 RW(Class, compiletime_error_class) \
106 RW(Class, pragma_class) \
107 RW(Field, pragma_name) \
108 RW(Field, pragma_options) \
109 RW(Class, future_class) \
110 RW(Class, completer_class) \
111 RW(Class, symbol_class) \
112 RW(Class, one_byte_string_class) \
113 RW(Class, two_byte_string_class) \
114 RW(Class, external_one_byte_string_class) \
115 RW(Class, external_two_byte_string_class) \
116 RW(Type, bool_type) \
117 RW(Type, legacy_bool_type) \
118 RW(Type, non_nullable_bool_type) \
119 RW(Class, bool_class) \
120 RW(Class, array_class) \
121 RW(Type, array_type) \
122 RW(Type, legacy_array_type) \
123 RW(Type, non_nullable_array_type) \
124 RW(Class, immutable_array_class) \
125 RW(Class, growable_object_array_class) \
126 RW(Class, linked_hash_map_class) \
127 RW(Class, linked_hash_set_class) \
128 RW(Class, float32x4_class) \
129 RW(Class, int32x4_class) \
130 RW(Class, float64x2_class) \
131 RW(Class, error_class) \
132 RW(Class, weak_property_class) \
133 RW(Array, symbol_table) \
134 RW(Array, canonical_types) \
135 RW(Array, canonical_type_parameters) \
136 RW(Array, canonical_type_arguments) \
137 RW(Library, async_library) \
138 RW(Library, builtin_library) \
139 RW(Library, core_library) \
140 RW(Library, collection_library) \
141 RW(Library, convert_library) \
142 RW(Library, developer_library) \
143 RW(Library, ffi_library) \
144 RW(Library, _internal_library) \
145 RW(Library, isolate_library) \
146 RW(Library, math_library) \
147 RW(Library, mirrors_library) \
148 RW(Library, native_wrappers_library) \
149 RW(Library, profiler_library) \
150 RW(Library, root_library) \
151 RW(Library, typed_data_library) \
152 RW(Library, _vmservice_library) \
153 RW(Library, wasm_library) \
154 RW(GrowableObjectArray, libraries) \
155 RW(Array, libraries_map) \
156 RW(Array, loading_units) \
157 RW(GrowableObjectArray, closure_functions) \
158 RW(GrowableObjectArray, pending_classes) \
159 RW(Instance, stack_overflow) \
160 RW(Instance, out_of_memory) \
161 RW(Function, lookup_port_handler) \
162 RW(Function, handle_message_function) \
163 RW(Function, growable_list_factory) \
164 RW(Function, simple_instance_of_function) \
165 RW(Function, simple_instance_of_true_function) \
166 RW(Function, simple_instance_of_false_function) \
167 RW(Function, async_clear_thread_stack_trace) \
168 RW(Function, async_set_thread_stack_trace) \
169 RW(Function, async_star_move_next_helper) \
170 RW(Function, complete_on_async_return) \
171 RW(Class, async_star_stream_controller) \
172 RW(Array, bytecode_attributes) \
173 RW(GrowableObjectArray, llvm_constant_pool) \
174 RW(GrowableObjectArray, llvm_function_pool) \
175 RW(Array, llvm_constant_hash_table) \
176 RW(CompressedStackMaps, canonicalized_stack_map_entries) \
177 RW(ObjectPool, global_object_pool) \
178 RW(Array, unique_dynamic_targets) \
179 RW(GrowableObjectArray, megamorphic_cache_table) \
180 RW(Code, build_method_extractor_code) \
181 RW(Code, dispatch_table_null_error_stub) \
182 RW(Code, null_error_stub_with_fpu_regs_stub) \
183 RW(Code, null_error_stub_without_fpu_regs_stub) \
184 RW(Code, null_arg_error_stub_with_fpu_regs_stub) \
185 RW(Code, null_arg_error_stub_without_fpu_regs_stub) \
186 RW(Code, null_cast_error_stub_with_fpu_regs_stub) \
187 RW(Code, null_cast_error_stub_without_fpu_regs_stub) \
188 RW(Code, range_error_stub_with_fpu_regs_stub) \
189 RW(Code, range_error_stub_without_fpu_regs_stub) \
190 RW(Code, allocate_mint_with_fpu_regs_stub) \
191 RW(Code, allocate_mint_without_fpu_regs_stub) \
192 RW(Code, stack_overflow_stub_with_fpu_regs_stub) \
193 RW(Code, stack_overflow_stub_without_fpu_regs_stub) \
194 RW(Code, allocate_array_stub) \
195 RW(Code, allocate_context_stub) \
196 RW(Code, allocate_object_stub) \
197 RW(Code, allocate_object_parametrized_stub) \
198 RW(Code, allocate_unhandled_exception_stub) \
199 RW(Code, clone_context_stub) \
200 RW(Code, write_barrier_wrappers_stub) \
201 RW(Code, array_write_barrier_stub) \
202 RW(Code, throw_stub) \
203 RW(Code, re_throw_stub) \
204 RW(Code, assert_boolean_stub) \
205 RW(Code, instance_of_stub) \
206 RW(Code, init_static_field_stub) \
207 RW(Code, init_instance_field_stub) \
208 RW(Code, init_late_instance_field_stub) \
209 RW(Code, init_late_final_instance_field_stub) \
210 RW(Code, call_closure_no_such_method_stub) \
211 RW(Code, default_tts_stub) \
212 RW(Code, default_nullable_tts_stub) \
213 RW(Code, top_type_tts_stub) \
214 RW(Code, unreachable_tts_stub) \
215 RW(Code, slow_tts_stub) \
216 RW(Array, dispatch_table_code_entries) \
217 RW(GrowableObjectArray, code_order_tables) \
218 RW(Array, obfuscation_map) \
219 RW(Class, ffi_pointer_class) \
220 RW(Class, ffi_native_type_class) \
221 RW(Class, ffi_struct_class) \
222 RW(Object, ffi_as_function_internal) \
223 // Please remember the last entry must be referred in the 'to' function below.
224
225#define OBJECT_STORE_STUB_CODE_LIST(DO) \
226 DO(dispatch_table_null_error_stub, DispatchTableNullError) \
227 DO(null_error_stub_with_fpu_regs_stub, NullErrorSharedWithFPURegs) \
228 DO(null_error_stub_without_fpu_regs_stub, NullErrorSharedWithoutFPURegs) \
229 DO(null_arg_error_stub_with_fpu_regs_stub, NullArgErrorSharedWithFPURegs) \
230 DO(null_arg_error_stub_without_fpu_regs_stub, \
231 NullArgErrorSharedWithoutFPURegs) \
232 DO(null_cast_error_stub_with_fpu_regs_stub, NullCastErrorSharedWithFPURegs) \
233 DO(null_cast_error_stub_without_fpu_regs_stub, \
234 NullCastErrorSharedWithoutFPURegs) \
235 DO(range_error_stub_with_fpu_regs_stub, RangeErrorSharedWithFPURegs) \
236 DO(range_error_stub_without_fpu_regs_stub, RangeErrorSharedWithoutFPURegs) \
237 DO(allocate_mint_with_fpu_regs_stub, AllocateMintSharedWithFPURegs) \
238 DO(allocate_mint_without_fpu_regs_stub, AllocateMintSharedWithoutFPURegs) \
239 DO(stack_overflow_stub_with_fpu_regs_stub, StackOverflowSharedWithFPURegs) \
240 DO(stack_overflow_stub_without_fpu_regs_stub, \
241 StackOverflowSharedWithoutFPURegs) \
242 DO(allocate_array_stub, AllocateArray) \
243 DO(allocate_context_stub, AllocateContext) \
244 DO(allocate_object_stub, AllocateObject) \
245 DO(allocate_object_parametrized_stub, AllocateObjectParameterized) \
246 DO(allocate_unhandled_exception_stub, AllocateUnhandledException) \
247 DO(clone_context_stub, CloneContext) \
248 DO(call_closure_no_such_method_stub, CallClosureNoSuchMethod) \
249 DO(default_tts_stub, DefaultTypeTest) \
250 DO(default_nullable_tts_stub, DefaultNullableTypeTest) \
251 DO(top_type_tts_stub, TopTypeTypeTest) \
252 DO(unreachable_tts_stub, UnreachableTypeTest) \
253 DO(slow_tts_stub, SlowTypeTest) \
254 DO(write_barrier_wrappers_stub, WriteBarrierWrappers) \
255 DO(array_write_barrier_stub, ArrayWriteBarrier) \
256 DO(throw_stub, Throw) \
257 DO(re_throw_stub, ReThrow) \
258 DO(assert_boolean_stub, AssertBoolean) \
259 DO(init_static_field_stub, InitStaticField) \
260 DO(init_instance_field_stub, InitInstanceField) \
261 DO(init_late_instance_field_stub, InitLateInstanceField) \
262 DO(init_late_final_instance_field_stub, InitLateFinalInstanceField) \
263 DO(instance_of_stub, InstanceOf)
264
265#define ISOLATE_OBJECT_STORE_FIELD_LIST(R_, RW) \
266 RW(UnhandledException, preallocated_unhandled_exception) \
267 RW(StackTrace, preallocated_stack_trace) \
268 RW(Array, dart_args_1) \
269 RW(Array, dart_args_2) \
270 R_(GrowableObjectArray, resume_capabilities) \
271 R_(GrowableObjectArray, exit_listeners) \
272 R_(GrowableObjectArray, error_listeners)
273// Please remember the last entry must be referred in the 'to' function below.
274
275class IsolateObjectStore {
276 public:
277 explicit IsolateObjectStore(ObjectStore* object_store);
278 ~IsolateObjectStore();
279
280#define DECLARE_GETTER(Type, name) \
281 Type##Ptr name() const { return name##_; } \
282 static intptr_t name##_offset() { \
283 return OFFSET_OF(IsolateObjectStore, name##_); \
284 }
285
286#define DECLARE_GETTER_AND_SETTER(Type, name) \
287 DECLARE_GETTER(Type, name) \
288 void set_##name(const Type& value) { name##_ = value.raw(); }
289 ISOLATE_OBJECT_STORE_FIELD_LIST(DECLARE_GETTER, DECLARE_GETTER_AND_SETTER)
290#undef DECLARE_GETTER
291#undef DECLARE_GETTER_AND_SETTER
292
293 // Visit all object pointers.
294 void VisitObjectPointers(ObjectPointerVisitor* visitor);
295
296 // Called to initialize objects required by the vm but which invoke
297 // dart code. If an error occurs the error object is returned otherwise
298 // a null object is returned.
299 ErrorPtr PreallocateObjects();
300
301 void Init();
302 void PostLoad();
303
304 ObjectStore* object_store() const { return object_store_; }
305 void set_object_store(ObjectStore* object_store) {
306 ASSERT(object_store_ == nullptr);
307 object_store_ = object_store;
308 }
309
310 static intptr_t object_store_offset() {
311 return OFFSET_OF(IsolateObjectStore, object_store_);
312 }
313
314#ifndef PRODUCT
315 void PrintToJSONObject(JSONObject* jsobj);
316#endif
317
318 private:
319 // Finds a core library private method in Object.
320 FunctionPtr PrivateObjectLookup(const String& name);
321
322 ObjectPtr* from() {
323 return reinterpret_cast<ObjectPtr*>(&preallocated_unhandled_exception_);
324 }
325#define DECLARE_OBJECT_STORE_FIELD(type, name) type##Ptr name##_;
326 ISOLATE_OBJECT_STORE_FIELD_LIST(DECLARE_OBJECT_STORE_FIELD,
327 DECLARE_OBJECT_STORE_FIELD)
328#undef DECLARE_OBJECT_STORE_FIELD
329 ObjectPtr* to() { return reinterpret_cast<ObjectPtr*>(&error_listeners_); }
330
331 ObjectStore* object_store_;
332
333 friend class Serializer;
334 friend class Deserializer;
335
336 DISALLOW_COPY_AND_ASSIGN(IsolateObjectStore);
337};
338
339// The object store is a per isolate group instance which stores references to
340// objects used by the VM shared by all isolates in a group.
341class ObjectStore {
342 public:
343 enum BootstrapLibraryId {
344#define MAKE_ID(Name, _) k##Name,
345
346 FOR_EACH_BOOTSTRAP_LIBRARY(MAKE_ID)
347#undef MAKE_ID
348 };
349
350 ObjectStore();
351 ~ObjectStore();
352
353#define DECLARE_GETTER(Type, name) \
354 Type##Ptr name() const { return name##_; } \
355 static intptr_t name##_offset() { return OFFSET_OF(ObjectStore, name##_); }
356#define DECLARE_GETTER_AND_SETTER(Type, name) \
357 DECLARE_GETTER(Type, name) \
358 void set_##name(const Type& value) { name##_ = value.raw(); }
359#define DECLARE_LAZY_INIT_GETTER(Type, name, init) \
360 Type##Ptr name() { \
361 if (name##_ == Type::null()) { \
362 init(); \
363 } \
364 return name##_; \
365 } \
366 static intptr_t name##_offset() { return OFFSET_OF(ObjectStore, name##_); }
367#define DECLARE_LAZY_INIT_CORE_GETTER_AND_SETTER(Type, name) \
368 DECLARE_LAZY_INIT_GETTER(Type, name, LazyInitCoreTypes) \
369 void set_##name(const Type& value) { name##_ = value.raw(); }
370#define DECLARE_LAZY_INIT_FUTURE_GETTER_AND_SETTER(Type, name) \
371 DECLARE_LAZY_INIT_GETTER(Type, name, LazyInitFutureTypes) \
372 void set_##name(const Type& value) { name##_ = value.raw(); }
373 OBJECT_STORE_FIELD_LIST(DECLARE_GETTER,
374 DECLARE_GETTER_AND_SETTER,
375 DECLARE_LAZY_INIT_CORE_GETTER_AND_SETTER,
376 DECLARE_LAZY_INIT_FUTURE_GETTER_AND_SETTER)
377#undef DECLARE_GETTER
378#undef DECLARE_GETTER_AND_SETTER
379#undef DECLARE_LAZY_INIT_GETTER
380#undef DECLARE_LAZY_INIT_CORE_GETTER_AND_SETTER
381#undef DECLARE_LAZY_INIT_FUTURE_GETTER_AND_SETTER
382
383 LibraryPtr bootstrap_library(BootstrapLibraryId index) {
384 switch (index) {
385#define MAKE_CASE(CamelName, name) \
386 case k##CamelName: \
387 return name##_library_;
388
389 FOR_EACH_BOOTSTRAP_LIBRARY(MAKE_CASE)
390#undef MAKE_CASE
391
392 default:
393 UNREACHABLE();
394 return Library::null();
395 }
396 }
397
398 void set_bootstrap_library(BootstrapLibraryId index, const Library& value) {
399 switch (index) {
400#define MAKE_CASE(CamelName, name) \
401 case k##CamelName: \
402 name##_library_ = value.raw(); \
403 break;
404
405 FOR_EACH_BOOTSTRAP_LIBRARY(MAKE_CASE)
406#undef MAKE_CASE
407 default:
408 UNREACHABLE();
409 }
410 }
411
412 // Visit all object pointers.
413 void VisitObjectPointers(ObjectPointerVisitor* visitor);
414
415 // Called to initialize objects required by the vm but which invoke
416 // dart code. If an error occurs the error object is returned otherwise
417 // a null object is returned.
418 ErrorPtr PreallocateObjects();
419
420 void InitKnownObjects();
421
422 void InitStubs();
423
424#ifndef PRODUCT
425 void PrintToJSONObject(JSONObject* jsobj);
426#endif
427
428 private:
429 void LazyInitCoreTypes();
430 void LazyInitFutureTypes();
431
432 // Finds a core library private method in Object.
433 FunctionPtr PrivateObjectLookup(const String& name);
434
435 ObjectPtr* from() { return reinterpret_cast<ObjectPtr*>(&object_class_); }
436#define DECLARE_OBJECT_STORE_FIELD(type, name) type##Ptr name##_;
437 OBJECT_STORE_FIELD_LIST(DECLARE_OBJECT_STORE_FIELD,
438 DECLARE_OBJECT_STORE_FIELD,
439 DECLARE_OBJECT_STORE_FIELD,
440 DECLARE_OBJECT_STORE_FIELD)
441#undef DECLARE_OBJECT_STORE_FIELD
442 ObjectPtr* to() {
443 return reinterpret_cast<ObjectPtr*>(&ffi_as_function_internal_);
444 }
445 ObjectPtr* to_snapshot(Snapshot::Kind kind) {
446 switch (kind) {
447 case Snapshot::kFull:
448 return reinterpret_cast<ObjectPtr*>(&global_object_pool_);
449 case Snapshot::kFullJIT:
450 case Snapshot::kFullAOT:
451 return reinterpret_cast<ObjectPtr*>(&slow_tts_stub_);
452 case Snapshot::kMessage:
453 case Snapshot::kNone:
454 case Snapshot::kInvalid:
455 break;
456 }
457 UNREACHABLE();
458 return NULL;
459 }
460
461 friend class Serializer;
462 friend class Deserializer;
463 friend class ProgramVisitor;
464
465 DISALLOW_COPY_AND_ASSIGN(ObjectStore);
466};
467
468} // namespace dart
469
470#endif // RUNTIME_VM_OBJECT_STORE_H_
471