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 | |
10 | namespace dart { |
11 | |
12 | // Forward declarations. |
13 | class Isolate; |
14 | class 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, ) \ |
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 | |
275 | class 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. |
341 | class 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 | |