1// Copyright (c) 2019, 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#include "vm/compiler/runtime_api.h"
6
7#include "vm/object.h"
8
9#if !defined(DART_PRECOMPILED_RUNTIME)
10#include "vm/compiler/runtime_offsets_list.h"
11#include "vm/dart_api_state.h"
12#include "vm/dart_entry.h"
13#include "vm/longjump.h"
14#include "vm/native_arguments.h"
15#include "vm/native_entry.h"
16#include "vm/object_store.h"
17#include "vm/runtime_entry.h"
18#include "vm/symbols.h"
19#include "vm/timeline.h"
20#endif // !defined(DART_PRECOMPILED_RUNTIME)
21
22namespace dart {
23namespace compiler {
24namespace target {
25
26#include "vm/compiler/runtime_offsets_extracted.h"
27
28bool IsSmi(int64_t v) {
29 return Utils::IsInt(kSmiBits + 1, v);
30}
31
32bool WillAllocateNewOrRememberedContext(intptr_t num_context_variables) {
33 if (!dart::Context::IsValidLength(num_context_variables)) return false;
34 return dart::Heap::IsAllocatableInNewSpace(
35 dart::Context::InstanceSize(num_context_variables));
36}
37
38bool WillAllocateNewOrRememberedArray(intptr_t length) {
39 if (!dart::Array::IsValidLength(length)) return false;
40 return !dart::Array::UseCardMarkingForAllocation(length);
41}
42
43} // namespace target
44} // namespace compiler
45} // namespace dart
46
47#if !defined(DART_PRECOMPILED_RUNTIME)
48
49namespace dart {
50namespace compiler {
51
52bool IsSameObject(const Object& a, const Object& b) {
53 if (a.IsMint() && b.IsMint()) {
54 return Mint::Cast(a).value() == Mint::Cast(b).value();
55 } else if (a.IsDouble() && b.IsDouble()) {
56 return Double::Cast(a).value() == Double::Cast(b).value();
57 }
58 return a.raw() == b.raw();
59}
60
61bool IsEqualType(const AbstractType& a, const AbstractType& b) {
62 return a.Equals(b);
63}
64
65bool IsDoubleType(const AbstractType& type) {
66 return type.IsDoubleType();
67}
68
69bool IsBoolType(const AbstractType& type) {
70 return type.IsBoolType();
71}
72
73bool IsIntType(const AbstractType& type) {
74 return type.IsIntType();
75}
76
77bool IsSmiType(const AbstractType& type) {
78 return type.IsSmiType();
79}
80
81bool IsNotTemporaryScopedHandle(const Object& obj) {
82 return obj.IsNotTemporaryScopedHandle();
83}
84
85#define DO(clazz) \
86 bool Is##clazz##Handle(const Object& obj) { return obj.Is##clazz(); }
87CLASS_LIST_FOR_HANDLES(DO)
88#undef DO
89
90bool IsInOldSpace(const Object& obj) {
91 return obj.IsSmi() || obj.IsOld();
92}
93
94intptr_t ObjectHash(const Object& obj) {
95 if (obj.IsNull()) {
96 return 2011;
97 }
98 if (obj.IsString() || obj.IsNumber()) {
99 return Instance::Cast(obj).CanonicalizeHash();
100 }
101 if (obj.IsCode()) {
102 // Instructions don't move during compaction.
103 return Code::Cast(obj).PayloadStart();
104 }
105 if (obj.IsFunction()) {
106 return Function::Cast(obj).Hash();
107 }
108 if (obj.IsField()) {
109 return dart::String::HashRawSymbol(Field::Cast(obj).name());
110 }
111 // Unlikely.
112 return obj.GetClassId();
113}
114
115void SetToNull(Object* obj) {
116 *obj = Object::null();
117}
118
119Object& NewZoneHandle(Zone* zone) {
120 return Object::ZoneHandle(zone, Object::null());
121}
122
123Object& NewZoneHandle(Zone* zone, const Object& obj) {
124 return Object::ZoneHandle(zone, obj.raw());
125}
126
127const Object& NullObject() {
128 return Object::null_object();
129}
130
131const Object& SentinelObject() {
132 return Object::sentinel();
133}
134
135const Bool& TrueObject() {
136 return dart::Bool::True();
137}
138
139const Bool& FalseObject() {
140 return dart::Bool::False();
141}
142
143const Object& EmptyTypeArguments() {
144 return Object::empty_type_arguments();
145}
146
147const Type& DynamicType() {
148 return dart::Type::dynamic_type();
149}
150
151const Type& ObjectType() {
152 return Type::Handle(dart::Type::ObjectType());
153}
154
155const Type& VoidType() {
156 return dart::Type::void_type();
157}
158
159const Type& IntType() {
160 return Type::Handle(dart::Type::IntType());
161}
162
163const Class& GrowableObjectArrayClass() {
164 auto object_store = Isolate::Current()->object_store();
165 return Class::Handle(object_store->growable_object_array_class());
166}
167
168const Class& MintClass() {
169 auto object_store = Isolate::Current()->object_store();
170 return Class::Handle(object_store->mint_class());
171}
172
173const Class& DoubleClass() {
174 auto object_store = Isolate::Current()->object_store();
175 return Class::Handle(object_store->double_class());
176}
177
178const Array& OneArgArgumentsDescriptor() {
179 return Array::ZoneHandle(
180 ArgumentsDescriptor::NewBoxed(/*type_args_len=*/0, /*num_arguments=*/1));
181}
182
183bool IsOriginalObject(const Object& object) {
184 if (object.IsICData()) {
185 return ICData::Cast(object).IsOriginal();
186 } else if (object.IsField()) {
187 return Field::Cast(object).IsOriginal();
188 }
189 return true;
190}
191
192const String& AllocateString(const char* buffer) {
193 return String::ZoneHandle(String::New(buffer, dart::Heap::kOld));
194}
195
196bool HasIntegerValue(const dart::Object& object, int64_t* value) {
197 if (object.IsInteger()) {
198 *value = Integer::Cast(object).AsInt64Value();
199 return true;
200 }
201 return false;
202}
203
204int32_t CreateJitCookie() {
205 return static_cast<int32_t>(Isolate::Current()->random()->NextUInt32());
206}
207
208word TypedDataElementSizeInBytes(classid_t cid) {
209 return dart::TypedData::ElementSizeInBytes(cid);
210}
211
212word TypedDataMaxNewSpaceElements(classid_t cid) {
213 return (dart::Heap::kNewAllocatableSize - target::TypedData::InstanceSize()) /
214 TypedDataElementSizeInBytes(cid);
215}
216
217const Field& LookupMathRandomStateFieldOffset() {
218 const auto& math_lib = dart::Library::Handle(dart::Library::MathLibrary());
219 ASSERT(!math_lib.IsNull());
220 const auto& random_class = dart::Class::Handle(
221 math_lib.LookupClassAllowPrivate(dart::Symbols::_Random()));
222 ASSERT(!random_class.IsNull());
223 const auto& state_field = dart::Field::ZoneHandle(
224 random_class.LookupInstanceFieldAllowPrivate(dart::Symbols::_state()));
225 return state_field;
226}
227
228const Field& LookupConvertUtf8DecoderScanFlagsField() {
229 const auto& convert_lib =
230 dart::Library::Handle(dart::Library::ConvertLibrary());
231 ASSERT(!convert_lib.IsNull());
232 const auto& _utf8decoder_class = dart::Class::Handle(
233 convert_lib.LookupClassAllowPrivate(dart::Symbols::_Utf8Decoder()));
234 ASSERT(!_utf8decoder_class.IsNull());
235 const auto& scan_flags_field = dart::Field::ZoneHandle(
236 _utf8decoder_class.LookupInstanceFieldAllowPrivate(
237 dart::Symbols::_scanFlags()));
238 return scan_flags_field;
239}
240
241word LookupFieldOffsetInBytes(const Field& field) {
242 return field.TargetOffset();
243}
244
245#if defined(TARGET_ARCH_IA32)
246uword SymbolsPredefinedAddress() {
247 return reinterpret_cast<uword>(dart::Symbols::PredefinedAddress());
248}
249#endif
250
251const Code& StubCodeAllocateArray() {
252 return dart::StubCode::AllocateArray();
253}
254
255const Code& StubCodeSubtype2TestCache() {
256 return dart::StubCode::Subtype2TestCache();
257}
258
259const Code& StubCodeSubtype6TestCache() {
260 return dart::StubCode::Subtype6TestCache();
261}
262
263#define DEFINE_ALIAS(name) \
264 const RuntimeEntry& k##name##RuntimeEntry(dart::k##name##RuntimeEntry);
265RUNTIME_ENTRY_LIST(DEFINE_ALIAS)
266#undef DEFINE_ALIAS
267
268#define DEFINE_ALIAS(type, name, ...) \
269 const RuntimeEntry& k##name##RuntimeEntry(dart::k##name##RuntimeEntry);
270LEAF_RUNTIME_ENTRY_LIST(DEFINE_ALIAS)
271#undef DEFINE_ALIAS
272
273void BailoutWithBranchOffsetError() {
274 Thread::Current()->long_jump_base()->Jump(1, Object::branch_offset_error());
275}
276
277word RuntimeEntry::OffsetFromThread() const {
278 return target::Thread::OffsetFromThread(runtime_entry_);
279}
280
281namespace target {
282
283const word kOldPageSize = dart::kOldPageSize;
284const word kOldPageSizeInWords = dart::kOldPageSize / kWordSize;
285const word kOldPageMask = dart::kOldPageMask;
286
287static word TranslateOffsetInWordsToHost(word offset) {
288 RELEASE_ASSERT((offset % kWordSize) == 0);
289 return (offset / kWordSize) * dart::kWordSize;
290}
291
292bool SizeFitsInSizeTag(uword instance_size) {
293 return dart::ObjectLayout::SizeTag::SizeFits(
294 TranslateOffsetInWordsToHost(instance_size));
295}
296
297uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size) {
298 return dart::ObjectLayout::SizeTag::encode(
299 TranslateOffsetInWordsToHost(instance_size)) |
300 dart::ObjectLayout::ClassIdTag::encode(cid) |
301 dart::ObjectLayout::NewBit::encode(true);
302}
303
304word Object::tags_offset() {
305 return 0;
306}
307
308const word ObjectLayout::kCardRememberedBit =
309 dart::ObjectLayout::kCardRememberedBit;
310
311const word ObjectLayout::kOldAndNotRememberedBit =
312 dart::ObjectLayout::kOldAndNotRememberedBit;
313
314const word ObjectLayout::kOldAndNotMarkedBit =
315 dart::ObjectLayout::kOldAndNotMarkedBit;
316
317const word ObjectLayout::kSizeTagPos = dart::ObjectLayout::kSizeTagPos;
318
319const word ObjectLayout::kSizeTagSize = dart::ObjectLayout::kSizeTagSize;
320
321const word ObjectLayout::kClassIdTagPos = dart::ObjectLayout::kClassIdTagPos;
322
323const word ObjectLayout::kClassIdTagSize = dart::ObjectLayout::kClassIdTagSize;
324
325const word ObjectLayout::kSizeTagMaxSizeTag =
326 dart::ObjectLayout::SizeTag::kMaxSizeTagInUnitsOfAlignment *
327 ObjectAlignment::kObjectAlignment;
328
329const word ObjectLayout::kTagBitsSizeTagPos =
330 dart::ObjectLayout::TagBits::kSizeTagPos;
331
332const word AbstractTypeLayout::kTypeStateFinalizedInstantiated =
333 dart::AbstractTypeLayout::kFinalizedInstantiated;
334
335const word ObjectLayout::kBarrierOverlapShift =
336 dart::ObjectLayout::kBarrierOverlapShift;
337
338bool IsTypedDataClassId(intptr_t cid) {
339 return dart::IsTypedDataClassId(cid);
340}
341
342const word Class::kNoTypeArguments = dart::Class::kNoTypeArguments;
343
344classid_t Class::GetId(const dart::Class& handle) {
345 return handle.id();
346}
347
348static word TranslateOffsetInWords(word offset) {
349 RELEASE_ASSERT((offset % dart::kWordSize) == 0);
350 return (offset / dart::kWordSize) * kWordSize;
351}
352
353static uword GetInstanceSizeImpl(const dart::Class& handle) {
354 switch (handle.id()) {
355 case kMintCid:
356 return Mint::InstanceSize();
357 case kDoubleCid:
358 return Double::InstanceSize();
359 case kInt32x4Cid:
360 return Int32x4::InstanceSize();
361 case kFloat32x4Cid:
362 return Float32x4::InstanceSize();
363 case kFloat64x2Cid:
364 return Float64x2::InstanceSize();
365 case kObjectCid:
366 return Object::InstanceSize();
367 case kInstanceCid:
368 return Instance::InstanceSize();
369 case kGrowableObjectArrayCid:
370 return GrowableObjectArray::InstanceSize();
371 case kClosureCid:
372 return Closure::InstanceSize();
373 case kTypedDataBaseCid:
374 return TypedDataBase::InstanceSize();
375 case kLinkedHashMapCid:
376 return LinkedHashMap::InstanceSize();
377 case kUnhandledExceptionCid:
378 return UnhandledException::InstanceSize();
379 case kByteBufferCid:
380 case kByteDataViewCid:
381 case kFfiPointerCid:
382 case kFfiDynamicLibraryCid:
383#define HANDLE_CASE(clazz) case kFfi##clazz##Cid:
384 CLASS_LIST_FFI_TYPE_MARKER(HANDLE_CASE)
385#undef HANDLE_CASE
386#define HANDLE_CASE(clazz) \
387 case kTypedData##clazz##Cid: \
388 case kTypedData##clazz##ViewCid: \
389 case kExternalTypedData##clazz##Cid:
390 CLASS_LIST_TYPED_DATA(HANDLE_CASE)
391#undef HANDLE_CASE
392 return handle.target_instance_size();
393 default:
394 if (handle.id() >= kNumPredefinedCids) {
395 return handle.target_instance_size();
396 }
397 }
398 FATAL3("Unsupported class for size translation: %s (id=%" Pd
399 ", kNumPredefinedCids=%" Pd ")\n",
400 handle.ToCString(), handle.id(), kNumPredefinedCids);
401 return -1;
402}
403
404uword Class::GetInstanceSize(const dart::Class& handle) {
405 return Utils::RoundUp(GetInstanceSizeImpl(handle),
406 ObjectAlignment::kObjectAlignment);
407}
408
409intptr_t Class::NumTypeArguments(const dart::Class& klass) {
410 return klass.NumTypeArguments();
411}
412
413bool Class::HasTypeArgumentsField(const dart::Class& klass) {
414 return klass.host_type_arguments_field_offset() !=
415 dart::Class::kNoTypeArguments;
416}
417
418intptr_t Class::TypeArgumentsFieldOffset(const dart::Class& klass) {
419 return klass.target_type_arguments_field_offset();
420}
421
422bool Class::TraceAllocation(const dart::Class& klass) {
423 return klass.TraceAllocation(dart::Isolate::Current());
424}
425
426word Instance::first_field_offset() {
427 return TranslateOffsetInWords(dart::Instance::NextFieldOffset());
428}
429
430word Instance::DataOffsetFor(intptr_t cid) {
431 if (dart::IsExternalTypedDataClassId(cid) ||
432 dart::IsExternalStringClassId(cid)) {
433 // Elements start at offset 0 of the external data.
434 return 0;
435 }
436 if (dart::IsTypedDataClassId(cid)) {
437 return TypedData::data_offset();
438 }
439 switch (cid) {
440 case kArrayCid:
441 case kImmutableArrayCid:
442 return Array::data_offset();
443 case kOneByteStringCid:
444 return OneByteString::data_offset();
445 case kTwoByteStringCid:
446 return TwoByteString::data_offset();
447 default:
448 UNIMPLEMENTED();
449 return Array::data_offset();
450 }
451}
452
453word Instance::ElementSizeFor(intptr_t cid) {
454 if (dart::IsExternalTypedDataClassId(cid) || dart::IsTypedDataClassId(cid) ||
455 dart::IsTypedDataViewClassId(cid)) {
456 return dart::TypedDataBase::ElementSizeInBytes(cid);
457 }
458 switch (cid) {
459 case kArrayCid:
460 case kImmutableArrayCid:
461 return kWordSize;
462 case kOneByteStringCid:
463 return dart::OneByteString::kBytesPerElement;
464 case kTwoByteStringCid:
465 return dart::TwoByteString::kBytesPerElement;
466 case kExternalOneByteStringCid:
467 return dart::ExternalOneByteString::kBytesPerElement;
468 case kExternalTwoByteStringCid:
469 return dart::ExternalTwoByteString::kBytesPerElement;
470 default:
471 UNIMPLEMENTED();
472 return 0;
473 }
474}
475
476word ICData::CodeIndexFor(word num_args) {
477 return dart::ICData::CodeIndexFor(num_args);
478}
479
480word ICData::CountIndexFor(word num_args) {
481 return dart::ICData::CountIndexFor(num_args);
482}
483
484word ICData::TargetIndexFor(word num_args) {
485 return dart::ICData::TargetIndexFor(num_args);
486}
487
488word ICData::ExactnessIndexFor(word num_args) {
489 return dart::ICData::ExactnessIndexFor(num_args);
490}
491
492word ICData::TestEntryLengthFor(word num_args, bool exactness_check) {
493 return dart::ICData::TestEntryLengthFor(num_args, exactness_check);
494}
495
496word ICData::EntryPointIndexFor(word num_args) {
497 return dart::ICData::EntryPointIndexFor(num_args);
498}
499
500const word MegamorphicCache::kSpreadFactor =
501 dart::MegamorphicCache::kSpreadFactor;
502
503word Context::InstanceSize(word n) {
504 return TranslateOffsetInWords(dart::Context::InstanceSize(n));
505}
506
507word Context::variable_offset(word n) {
508 return TranslateOffsetInWords(dart::Context::variable_offset(n));
509}
510
511#define DEFINE_CONSTANT(Class, Name) const word Class::Name = Class##_##Name;
512
513#if defined(TARGET_ARCH_IA32)
514
515#define DEFINE_FIELD(clazz, name) \
516 word clazz::name() { return clazz##_##name; }
517
518#define DEFINE_ARRAY(clazz, name) \
519 word clazz::name(intptr_t index) { \
520 return clazz##_elements_start_offset + index * clazz##_element_size; \
521 }
522
523#define DEFINE_SIZEOF(clazz, name, what) \
524 word clazz::name() { return clazz##_##name; }
525
526#define DEFINE_RANGE(Class, Getter, Type, First, Last, Filter) \
527 word Class::Getter(Type index) { \
528 return Class##_##Getter[static_cast<intptr_t>(index) - \
529 static_cast<intptr_t>(First)]; \
530 }
531
532JIT_OFFSETS_LIST(DEFINE_FIELD,
533 DEFINE_ARRAY,
534 DEFINE_SIZEOF,
535 DEFINE_RANGE,
536 DEFINE_CONSTANT)
537
538COMMON_OFFSETS_LIST(DEFINE_FIELD,
539 DEFINE_ARRAY,
540 DEFINE_SIZEOF,
541 DEFINE_RANGE,
542 DEFINE_CONSTANT)
543
544#else
545
546#define DEFINE_JIT_FIELD(clazz, name) \
547 word clazz::name() { \
548 if (FLAG_precompiled_mode) { \
549 FATAL1("Use JIT-only field %s in precompiled mode", #clazz "::" #name); \
550 } \
551 return clazz##_##name; \
552 }
553
554#define DEFINE_JIT_ARRAY(clazz, name) \
555 word clazz::name(intptr_t index) { \
556 if (FLAG_precompiled_mode) { \
557 FATAL1("Use of JIT-only array %s in precompiled mode", \
558 #clazz "::" #name); \
559 } \
560 return clazz##_elements_start_offset + index * clazz##_element_size; \
561 }
562
563#define DEFINE_JIT_SIZEOF(clazz, name, what) \
564 word clazz::name() { \
565 if (FLAG_precompiled_mode) { \
566 FATAL1("Use of JIT-only sizeof %s in precompiled mode", \
567 #clazz "::" #name); \
568 } \
569 return clazz##_##name; \
570 }
571
572#define DEFINE_JIT_RANGE(Class, Getter, Type, First, Last, Filter) \
573 word Class::Getter(Type index) { \
574 if (FLAG_precompiled_mode) { \
575 FATAL1("Use of JIT-only range %s in precompiled mode", \
576 #Class "::" #Getter); \
577 } \
578 return Class##_##Getter[static_cast<intptr_t>(index) - \
579 static_cast<intptr_t>(First)]; \
580 }
581
582JIT_OFFSETS_LIST(DEFINE_JIT_FIELD,
583 DEFINE_JIT_ARRAY,
584 DEFINE_JIT_SIZEOF,
585 DEFINE_JIT_RANGE,
586 DEFINE_CONSTANT)
587
588#undef DEFINE_JIT_FIELD
589#undef DEFINE_JIT_ARRAY
590#undef DEFINE_JIT_SIZEOF
591#undef DEFINE_JIT_RANGE
592
593#define DEFINE_FIELD(clazz, name) \
594 word clazz::name() { \
595 return FLAG_precompiled_mode ? AOT_##clazz##_##name : clazz##_##name; \
596 }
597
598#define DEFINE_ARRAY(clazz, name) \
599 word clazz::name(intptr_t index) { \
600 if (FLAG_precompiled_mode) { \
601 return AOT_##clazz##_elements_start_offset + \
602 index * AOT_##clazz##_element_size; \
603 } else { \
604 return clazz##_elements_start_offset + index * clazz##_element_size; \
605 } \
606 }
607
608#define DEFINE_SIZEOF(clazz, name, what) \
609 word clazz::name() { \
610 return FLAG_precompiled_mode ? AOT_##clazz##_##name : clazz##_##name; \
611 }
612
613#define DEFINE_RANGE(Class, Getter, Type, First, Last, Filter) \
614 word Class::Getter(Type index) { \
615 if (FLAG_precompiled_mode) { \
616 return AOT_##Class##_##Getter[static_cast<intptr_t>(index) - \
617 static_cast<intptr_t>(First)]; \
618 } else { \
619 return Class##_##Getter[static_cast<intptr_t>(index) - \
620 static_cast<intptr_t>(First)]; \
621 } \
622 }
623
624COMMON_OFFSETS_LIST(DEFINE_FIELD,
625 DEFINE_ARRAY,
626 DEFINE_SIZEOF,
627 DEFINE_RANGE,
628 DEFINE_CONSTANT)
629
630#endif
631
632#undef DEFINE_FIELD
633#undef DEFINE_ARRAY
634#undef DEFINE_SIZEOF
635#undef DEFINE_RANGE
636#undef DEFINE_CONSTANT
637
638const word StoreBufferBlock::kSize = dart::StoreBufferBlock::kSize;
639
640const word MarkingStackBlock::kSize = dart::MarkingStackBlock::kSize;
641
642word InstructionsSection::HeaderSize() {
643 return Utils::RoundUp(InstructionsSection::UnalignedHeaderSize(),
644 target::kWordSize);
645}
646
647word Instructions::HeaderSize() {
648 return Utils::RoundUp(Instructions::UnalignedHeaderSize(), target::kWordSize);
649}
650
651word Thread::stack_overflow_shared_stub_entry_point_offset(bool fpu_regs) {
652 return fpu_regs ? stack_overflow_shared_with_fpu_regs_entry_point_offset()
653 : stack_overflow_shared_without_fpu_regs_entry_point_offset();
654}
655
656uword Thread::safepoint_state_unacquired() {
657 return dart::Thread::safepoint_state_unacquired();
658}
659
660uword Thread::safepoint_state_acquired() {
661 return dart::Thread::safepoint_state_acquired();
662}
663
664intptr_t Thread::safepoint_state_inside_bit() {
665 COMPILE_ASSERT(dart::Thread::AtSafepointField::bitsize() == 1);
666 return dart::Thread::AtSafepointField::shift();
667}
668
669uword Thread::generated_execution_state() {
670 return dart::Thread::ExecutionState::kThreadInGenerated;
671}
672
673uword Thread::native_execution_state() {
674 return dart::Thread::ExecutionState::kThreadInNative;
675}
676
677uword Thread::vm_execution_state() {
678 return dart::Thread::ExecutionState::kThreadInVM;
679}
680
681uword Thread::vm_tag_compiled_id() {
682 return dart::VMTag::kDartCompiledTagId;
683}
684
685uword Thread::exit_through_runtime_call() {
686 return dart::Thread::kExitThroughRuntimeCall;
687}
688
689uword Thread::exit_through_ffi() {
690 return dart::Thread::kExitThroughFfi;
691}
692
693word Thread::OffsetFromThread(const dart::Object& object) {
694 auto host_offset = dart::Thread::OffsetFromThread(object);
695 return object_null_offset() +
696 TranslateOffsetInWords(host_offset -
697 dart::Thread::object_null_offset());
698}
699
700intptr_t Thread::OffsetFromThread(const dart::RuntimeEntry* runtime_entry) {
701 auto host_offset = dart::Thread::OffsetFromThread(runtime_entry);
702 return AllocateArray_entry_point_offset() +
703 TranslateOffsetInWords(
704 host_offset - dart::Thread::AllocateArray_entry_point_offset());
705}
706
707bool CanLoadFromThread(const dart::Object& object,
708 intptr_t* offset /* = nullptr */) {
709 if (dart::Thread::CanLoadFromThread(object)) {
710 if (offset != nullptr) {
711 *offset = Thread::OffsetFromThread(object);
712 }
713 return true;
714 }
715 return false;
716}
717
718static_assert(
719 kSmiBits <= dart::kSmiBits,
720 "Expected that size of Smi on HOST is at least as large as on target.");
721
722bool IsSmi(const dart::Object& a) {
723 return a.IsSmi() && IsSmi(dart::Smi::Cast(a).Value());
724}
725
726word ToRawSmi(const dart::Object& a) {
727 RELEASE_ASSERT(IsSmi(a));
728 return static_cast<word>(static_cast<intptr_t>(a.raw()));
729}
730
731word ToRawSmi(intptr_t value) {
732 return dart::Smi::RawValue(value);
733}
734
735word SmiValue(const dart::Object& a) {
736 RELEASE_ASSERT(IsSmi(a));
737 return static_cast<word>(dart::Smi::Cast(a).Value());
738}
739
740#if defined(TARGET_ARCH_IA32)
741uword Code::EntryPointOf(const dart::Code& code) {
742 static_assert(kHostWordSize == kWordSize,
743 "Can't embed raw pointers to runtime objects when host and "
744 "target word sizes are different");
745 return code.EntryPoint();
746}
747
748bool CanEmbedAsRawPointerInGeneratedCode(const dart::Object& obj) {
749 return obj.IsSmi() || obj.InVMIsolateHeap();
750}
751
752word ToRawPointer(const dart::Object& a) {
753 static_assert(kHostWordSize == kWordSize,
754 "Can't embed raw pointers to runtime objects when host and "
755 "target word sizes are different");
756 return static_cast<word>(a.raw());
757}
758#endif // defined(TARGET_ARCH_IA32)
759
760word RegExp::function_offset(classid_t cid, bool sticky) {
761 return TranslateOffsetInWords(dart::RegExp::function_offset(cid, sticky));
762}
763
764const word Symbols::kNumberOfOneCharCodeSymbols =
765 dart::Symbols::kNumberOfOneCharCodeSymbols;
766const word Symbols::kNullCharCodeSymbolOffset =
767 dart::Symbols::kNullCharCodeSymbolOffset;
768
769const word String::kHashBits = dart::String::kHashBits;
770
771const int8_t Nullability::kNullable =
772 static_cast<int8_t>(dart::Nullability::kNullable);
773const int8_t Nullability::kNonNullable =
774 static_cast<int8_t>(dart::Nullability::kNonNullable);
775const int8_t Nullability::kLegacy =
776 static_cast<int8_t>(dart::Nullability::kLegacy);
777
778bool Heap::IsAllocatableInNewSpace(intptr_t instance_size) {
779 return dart::Heap::IsAllocatableInNewSpace(instance_size);
780}
781
782word Field::OffsetOf(const dart::Field& field) {
783 return field.TargetOffset();
784}
785
786word FieldTable::OffsetOf(const dart::Field& field) {
787 return TranslateOffsetInWords(
788 dart::FieldTable::FieldOffsetFor(field.field_id()));
789}
790
791word FreeListElement::FakeInstance::InstanceSize() {
792 return 0;
793}
794
795word ForwardingCorpse::FakeInstance::InstanceSize() {
796 return 0;
797}
798
799word Instance::NextFieldOffset() {
800 return TranslateOffsetInWords(dart::Instance::NextFieldOffset());
801}
802
803word Pointer::NextFieldOffset() {
804 return TranslateOffsetInWords(dart::Pointer::NextFieldOffset());
805}
806
807word WeakSerializationReference::NextFieldOffset() {
808 return -kWordSize;
809}
810
811word ObjectPool::NextFieldOffset() {
812 return -kWordSize;
813}
814
815word Class::NextFieldOffset() {
816 return -kWordSize;
817}
818
819word Function::NextFieldOffset() {
820 return -kWordSize;
821}
822
823word ICData::NextFieldOffset() {
824 return -kWordSize;
825}
826
827word MegamorphicCache::NextFieldOffset() {
828 return -kWordSize;
829}
830
831word SingleTargetCache::NextFieldOffset() {
832 return -kWordSize;
833}
834
835word Array::NextFieldOffset() {
836 return -kWordSize;
837}
838
839word GrowableObjectArray::NextFieldOffset() {
840 return -kWordSize;
841}
842
843word TypedDataBase::NextFieldOffset() {
844 return -kWordSize;
845}
846
847word TypedData::NextFieldOffset() {
848 return -kWordSize;
849}
850
851word ExternalTypedData::NextFieldOffset() {
852 return -kWordSize;
853}
854
855word TypedDataView::NextFieldOffset() {
856 return -kWordSize;
857}
858
859word LinkedHashMap::NextFieldOffset() {
860 return -kWordSize;
861}
862
863word Type::NextFieldOffset() {
864 return -kWordSize;
865}
866
867word TypeRef::NextFieldOffset() {
868 return -kWordSize;
869}
870
871word Double::NextFieldOffset() {
872 return -kWordSize;
873}
874
875word Mint::NextFieldOffset() {
876 return -kWordSize;
877}
878
879word String::NextFieldOffset() {
880 return -kWordSize;
881}
882
883word OneByteString::NextFieldOffset() {
884 return -kWordSize;
885}
886
887word TwoByteString::NextFieldOffset() {
888 return -kWordSize;
889}
890
891word ExternalOneByteString::NextFieldOffset() {
892 return -kWordSize;
893}
894
895word ExternalTwoByteString::NextFieldOffset() {
896 return -kWordSize;
897}
898
899word Int32x4::NextFieldOffset() {
900 return -kWordSize;
901}
902
903word Float32x4::NextFieldOffset() {
904 return -kWordSize;
905}
906
907word Float64x2::NextFieldOffset() {
908 return -kWordSize;
909}
910
911word DynamicLibrary::NextFieldOffset() {
912 return -kWordSize;
913}
914
915word PatchClass::NextFieldOffset() {
916 return -kWordSize;
917}
918
919word SignatureData::NextFieldOffset() {
920 return -kWordSize;
921}
922
923word RedirectionData::NextFieldOffset() {
924 return -kWordSize;
925}
926
927word FfiTrampolineData::NextFieldOffset() {
928 return -kWordSize;
929}
930
931word Script::NextFieldOffset() {
932 return -kWordSize;
933}
934
935word Library::NextFieldOffset() {
936 return -kWordSize;
937}
938
939word Namespace::NextFieldOffset() {
940 return -kWordSize;
941}
942
943word KernelProgramInfo::NextFieldOffset() {
944 return -kWordSize;
945}
946
947word Bytecode::NextFieldOffset() {
948 return -kWordSize;
949}
950
951word PcDescriptors::NextFieldOffset() {
952 return -kWordSize;
953}
954
955word CodeSourceMap::NextFieldOffset() {
956 return -kWordSize;
957}
958
959word CompressedStackMaps::NextFieldOffset() {
960 return -kWordSize;
961}
962
963word LocalVarDescriptors::NextFieldOffset() {
964 return -kWordSize;
965}
966
967word ExceptionHandlers::NextFieldOffset() {
968 return -kWordSize;
969}
970
971word ContextScope::NextFieldOffset() {
972 return -kWordSize;
973}
974
975word ParameterTypeCheck::NextFieldOffset() {
976 return -kWordSize;
977}
978
979word UnlinkedCall::NextFieldOffset() {
980 return -kWordSize;
981}
982
983word ApiError::NextFieldOffset() {
984 return -kWordSize;
985}
986
987word LanguageError::NextFieldOffset() {
988 return -kWordSize;
989}
990
991word UnhandledException::NextFieldOffset() {
992 return -kWordSize;
993}
994
995word UnwindError::NextFieldOffset() {
996 return -kWordSize;
997}
998
999word Bool::NextFieldOffset() {
1000 return -kWordSize;
1001}
1002
1003word TypeParameter::NextFieldOffset() {
1004 return -kWordSize;
1005}
1006
1007word LibraryPrefix::NextFieldOffset() {
1008 return -kWordSize;
1009}
1010
1011word Capability::NextFieldOffset() {
1012 return -kWordSize;
1013}
1014
1015word ReceivePort::NextFieldOffset() {
1016 return -kWordSize;
1017}
1018
1019word SendPort::NextFieldOffset() {
1020 return -kWordSize;
1021}
1022
1023word TransferableTypedData::NextFieldOffset() {
1024 return -kWordSize;
1025}
1026
1027word StackTrace::NextFieldOffset() {
1028 return -kWordSize;
1029}
1030
1031word Integer::NextFieldOffset() {
1032 return -kWordSize;
1033}
1034
1035word Smi::NextFieldOffset() {
1036 return -kWordSize;
1037}
1038
1039word WeakProperty::NextFieldOffset() {
1040 return -kWordSize;
1041}
1042
1043word MirrorReference::NextFieldOffset() {
1044 return -kWordSize;
1045}
1046
1047word Number::NextFieldOffset() {
1048 return -kWordSize;
1049}
1050
1051word MonomorphicSmiableCall::NextFieldOffset() {
1052 return -kWordSize;
1053}
1054
1055word InstructionsSection::NextFieldOffset() {
1056 return -kWordSize;
1057}
1058
1059word Instructions::NextFieldOffset() {
1060 return -kWordSize;
1061}
1062
1063word Code::NextFieldOffset() {
1064 return -kWordSize;
1065}
1066
1067word SubtypeTestCache::NextFieldOffset() {
1068 return -kWordSize;
1069}
1070
1071word LoadingUnit::NextFieldOffset() {
1072 return -kWordSize;
1073}
1074
1075word Context::NextFieldOffset() {
1076 return -kWordSize;
1077}
1078
1079word Closure::NextFieldOffset() {
1080 return -kWordSize;
1081}
1082
1083word ClosureData::NextFieldOffset() {
1084 return -kWordSize;
1085}
1086
1087word RegExp::NextFieldOffset() {
1088 return -kWordSize;
1089}
1090
1091word UserTag::NextFieldOffset() {
1092 return -kWordSize;
1093}
1094
1095word FutureOr::NextFieldOffset() {
1096 return -kWordSize;
1097}
1098
1099word Field::NextFieldOffset() {
1100 return -kWordSize;
1101}
1102
1103word TypeArguments::NextFieldOffset() {
1104 return -kWordSize;
1105}
1106
1107word FreeListElement::FakeInstance::NextFieldOffset() {
1108 return -kWordSize;
1109}
1110
1111word ForwardingCorpse::FakeInstance::NextFieldOffset() {
1112 return -kWordSize;
1113}
1114
1115} // namespace target
1116} // namespace compiler
1117} // namespace dart
1118
1119#else
1120
1121namespace dart {
1122namespace compiler {
1123namespace target {
1124
1125const word Array::kMaxElements = Array_kMaxElements;
1126
1127} // namespace target
1128} // namespace compiler
1129} // namespace dart
1130
1131#endif // !defined(DART_PRECOMPILED_RUNTIME)
1132