Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
message_snapshot.cc
Go to the documentation of this file.
1// Copyright (c) 2021, 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
6
7#include <memory>
8
9#include "platform/assert.h"
10#include "platform/unicode.h"
11#include "vm/class_finalizer.h"
12#include "vm/class_id.h"
13#include "vm/dart_api_message.h"
14#include "vm/dart_api_state.h"
15#include "vm/dart_entry.h"
16#include "vm/flags.h"
17#include "vm/growable_array.h"
18#include "vm/heap/heap.h"
19#include "vm/heap/weak_table.h"
20#include "vm/longjump.h"
21#include "vm/object.h"
23#include "vm/object_store.h"
24#include "vm/symbols.h"
26
27namespace dart {
28
38
39// Workaround for lack of designated initializers until we adopt c++20
41 public:
44 return instance;
45 }
46
47 static Dart_CObject* cobj_null() { return &getInstance().cobj_null_; }
49 return &getInstance().cobj_empty_array_;
50 }
51
52 private:
54 cobj_null_.type = Dart_CObject_kNull;
55 cobj_null_.value.as_int64 = 0;
56 cobj_empty_array_.type = Dart_CObject_kArray;
57 cobj_empty_array_.value.as_array = {0, nullptr};
58 }
59
60 Dart_CObject cobj_null_;
61 Dart_CObject cobj_empty_array_;
62
63 DISALLOW_COPY_AND_ASSIGN(PredefinedCObjects);
64};
65
66enum class MessagePhase {
67 kBeforeTypes = 0,
68 kTypes = 1,
71
72 kNumPhases = 4,
73};
74
75class MessageSerializer;
76class MessageDeserializer;
77class ApiMessageSerializer;
78class ApiMessageDeserializer;
79
81 public:
82 explicit MessageSerializationCluster(const char* name,
84 intptr_t cid,
85 bool is_canonical = false)
88
89 virtual void Trace(MessageSerializer* s, Object* object) = 0;
90 virtual void WriteNodes(MessageSerializer* s) = 0;
91 virtual void WriteEdges(MessageSerializer* s) {}
92
93 virtual void TraceApi(ApiMessageSerializer* s, Dart_CObject* object) {}
96
97 const char* name() const { return name_; }
98 MessagePhase phase() const { return phase_; }
99 intptr_t cid() const { return cid_; }
100 bool is_canonical() const { return is_canonical_; }
101
102 protected:
103 const char* const name_;
105 const intptr_t cid_;
106 const bool is_canonical_;
107
109};
110
112 public:
114 bool is_canonical = false)
115 : name_(name),
117 start_index_(0),
118 stop_index_(0) {}
120
121 virtual void ReadNodes(MessageDeserializer* d) = 0;
123 virtual ObjectPtr PostLoad(MessageDeserializer* d) { return nullptr; }
127
130
131 const char* name() const { return name_; }
132 bool is_canonical() const { return is_canonical_; }
133
134 protected:
137
138 const char* const name_;
139 const bool is_canonical_;
140 // The range of the ref array that belongs to this cluster.
141 intptr_t start_index_;
142 intptr_t stop_index_;
143
145};
146
148 public:
151
152 // Writes raw data to the stream (basic type).
153 // sizeof(T) must be in {1,2,4,8}.
154 template <typename T>
155 void Write(T value) {
157 }
158 void WriteUnsigned(intptr_t value) { stream_.WriteUnsigned(value); }
162 void WriteBytes(const void* addr, intptr_t len) {
163 stream_.WriteBytes(addr, len);
164 }
165 void WriteAscii(const String& str) {
166 intptr_t len = str.Length();
167 WriteUnsigned(len);
168 for (intptr_t i = 0; i < len; i++) {
169 int64_t c = str.CharAt(i);
170 ASSERT(c < 128);
171 Write<uint8_t>(c);
172 }
173 Write<uint8_t>(0);
174 }
175
177 bool is_canonical);
179
180 std::unique_ptr<Message> Finish(Dart_Port dest_port,
181 Message::Priority priority) {
183 finalizable_data_ = nullptr;
185 intptr_t size;
186 uint8_t* buffer = stream_.Steal(&size);
187 return Message::New(dest_port, buffer, size, finalizable_data, priority);
188 }
189
190 Zone* zone() const { return zone_; }
192 intptr_t next_ref_index() const { return next_ref_index_; }
193
194 protected:
195 Zone* const zone_;
202};
203
205 public:
208
209 bool MarkObjectId(ObjectPtr object, intptr_t id) {
212 if (object->IsImmediateOrOldObject()) {
214 } else {
216 }
217 return table->MarkValueExclusive(object, id);
218 }
219
220 void SetObjectId(ObjectPtr object, intptr_t id) {
223 if (object->IsImmediateOrOldObject()) {
225 } else {
227 }
228 table->SetValueExclusive(object, id);
229 }
230
231 intptr_t GetObjectId(ObjectPtr object) const {
232 const WeakTable* table;
233 if (object->IsImmediateOrOldObject()) {
235 } else {
237 }
238 return table->GetValueExclusive(object);
239 }
240
241 DART_NOINLINE void AddBaseObject(ObjectPtr base_object) {
242 AssignRef(base_object);
244 }
245 DART_NOINLINE void AssignRef(ObjectPtr object) {
248 }
249 void AssignRef(Object* object) { AssignRef(object->ptr()); }
250
251 void Push(ObjectPtr object);
252
253 void Trace(const Object& root, Object* object);
254
255 void IllegalObject(const Object& object, const char* message);
256
257 void AddBaseObjects();
258 void Serialize(const Object& root);
259
260 DART_NOINLINE void WriteRef(ObjectPtr object) {
261 intptr_t index = GetObjectId(object);
262 ASSERT(index != WeakTable::kNoValue);
263 WriteUnsigned(index);
264 }
265
266 Thread* thread() const {
267 return static_cast<Thread*>(StackResource::thread());
268 }
269 Isolate* isolate() const { return thread()->isolate(); }
271
272 bool HasRef(ObjectPtr object) const {
273 return GetObjectId(object) != WeakTable::kNoValue;
274 }
275
276 private:
277 WeakTable* forward_table_new_;
278 WeakTable* forward_table_old_;
280};
281
283 public:
284 explicit ApiMessageSerializer(Zone* zone);
286
287 bool MarkObjectId(Dart_CObject* object, intptr_t id) {
289 return forward_table_.MarkValueExclusive(
290 static_cast<ObjectPtr>(reinterpret_cast<uword>(object)), id);
291 }
292
293 void SetObjectId(Dart_CObject* object, intptr_t id) {
295 forward_table_.SetValueExclusive(
296 static_cast<ObjectPtr>(reinterpret_cast<uword>(object)), id);
297 }
298
299 intptr_t GetObjectId(Dart_CObject* object) const {
300 return forward_table_.GetValueExclusive(
301 static_cast<ObjectPtr>(reinterpret_cast<uword>(object)));
302 }
303
304 DART_NOINLINE void AddBaseObject(Dart_CObject* base_object) {
305 AssignRef(base_object);
307 }
308 DART_NOINLINE intptr_t AssignRef(Dart_CObject* object) {
310 return next_ref_index_++;
311 }
313 intptr_t id = GetObjectId(nue);
315 SetObjectId(old, id);
317 }
318
319 void Push(Dart_CObject* object);
320
321 bool Trace(Dart_CObject* object);
322
323 void AddBaseObjects();
324 bool Serialize(Dart_CObject* root);
325
326 void WriteRef(Dart_CObject* object) {
327 intptr_t index = GetObjectId(object);
328 ASSERT(index != WeakTable::kNoValue);
329 WriteUnsigned(index);
330 }
331
332 bool Fail(const char* message) {
333 exception_message_ = message;
334 return false;
335 }
336
337 private:
338 WeakTable forward_table_;
340 const char* exception_message_;
341};
342
344 public:
347
348 // Reads raw data (for basic types).
349 // sizeof(T) must be in {1,2,4,8}.
350 template <typename T>
351 T Read() {
352 return ReadStream::Raw<sizeof(T), T>::Read(&stream_);
353 }
354 intptr_t ReadUnsigned() { return stream_.ReadUnsigned(); }
356 void ReadBytes(void* addr, intptr_t len) { stream_.ReadBytes(addr, len); }
357 const char* ReadAscii() {
358 intptr_t len = ReadUnsigned();
359 const char* result = reinterpret_cast<const char*>(CurrentBufferAddress());
360 Advance(len + 1);
361 return result;
362 }
363
364 const uint8_t* CurrentBufferAddress() const {
366 }
367
368 void Advance(intptr_t value) { stream_.Advance(value); }
369
371
372 Zone* zone() const { return zone_; }
373 intptr_t next_index() const { return next_ref_index_; }
375
376 protected:
381};
382
384 public:
387 thread_(thread),
388 refs_(Array::Handle(thread->zone())) {}
390
391 DART_NOINLINE void AddBaseObject(ObjectPtr base_object) {
392 AssignRef(base_object);
393 }
394 void AssignRef(ObjectPtr object) {
395 refs_.untag()->set_element(next_ref_index_, object);
397 }
398
399 ObjectPtr Ref(intptr_t index) const {
400 ASSERT(index > 0);
401 ASSERT(index <= next_ref_index_);
402 return refs_.At(index);
403 }
404 void UpdateRef(intptr_t index, const Object& new_object) {
405 ASSERT(index > 0);
406 ASSERT(index <= next_ref_index_);
407 refs_.SetAt(index, new_object);
408 }
409
411
412 void AddBaseObjects();
414
415 Thread* thread() const { return thread_; }
416 IsolateGroup* isolate_group() const { return thread_->isolate_group(); }
417 ArrayPtr refs() const { return refs_.ptr(); }
418
419 private:
420 Thread* const thread_;
421 Array& refs_;
422};
423
425 public:
429
430 void AddBaseObject(Dart_CObject* base_object) { AssignRef(base_object); }
431 void AssignRef(Dart_CObject* object) {
432 refs_[next_ref_index_] = object;
434 }
435
441
442 Dart_CObject* Ref(intptr_t index) const {
443 ASSERT(index > 0);
444 ASSERT(index <= next_ref_index_);
445 return refs_[index];
446 }
447
449
450 void AddBaseObjects();
452
453 private:
454 Dart_CObject** refs_;
455};
456
458 start_index_ = d->next_index();
459 this->ReadNodes(d);
460 stop_index_ = d->next_index();
461}
462
465 start_index_ = d->next_index();
466 this->ReadNodesApi(d);
467 stop_index_ = d->next_index();
468}
469
476 Code& code = Code::Handle(d->zone());
477 for (intptr_t id = start_index_; id < stop_index_; id++) {
478 type ^= d->Ref(id);
479
481 type.InitializeTypeTestingStubNonAtomic(code);
482
483 type ^= ClassFinalizer::FinalizeType(type, finalization);
484 d->UpdateRef(id, type);
485 }
486 return nullptr;
487}
488
492 Array& maps = Array::Handle(d->zone(), d->refs());
494 /*with_type_argument=*/false);
496}
497
499 public:
503 kClassCid),
504 objects_() {}
506
507 void Trace(MessageSerializer* s, Object* object) {
508 Class* cls = static_cast<Class*>(object);
509 objects_.Add(cls);
510 }
511
513 const intptr_t count = objects_.length();
514 s->WriteUnsigned(count);
515 Library& lib = Library::Handle(s->zone());
516 String& str = String::Handle(s->zone());
517 for (intptr_t i = 0; i < count; i++) {
518 Class* cls = objects_[i];
519 s->AssignRef(cls);
520 intptr_t cid = cls->id();
521 if (cid < kNumPredefinedCids) {
522 ASSERT(cid != 0);
523 s->WriteUnsigned(cid);
524 } else {
525 s->WriteUnsigned(0);
526 lib = cls->library();
527 str = lib.url();
528 s->WriteAscii(str);
529 str = cls->Name();
530 s->WriteAscii(str);
531 }
532 }
533 }
534
535 private:
536 GrowableArray<Class*> objects_;
537};
538
541 public:
545
547 auto* class_table = d->isolate_group()->class_table();
548 String& uri = String::Handle(d->zone());
549 Library& lib = Library::Handle(d->zone());
550 String& name = String::Handle(d->zone());
551 Class& cls = Class::Handle(d->zone());
552 intptr_t count = d->ReadUnsigned();
553 for (intptr_t i = 0; i < count; i++) {
554 intptr_t cid = d->ReadUnsigned();
555 if (cid != 0) {
556 cls = class_table->At(cid);
557 } else {
558 uri = String::New(d->ReadAscii()); // Library URI.
559 name = String::New(d->ReadAscii()); // Class name.
560 lib = Library::LookupLibrary(d->thread(), uri);
561 if (UNLIKELY(lib.IsNull())) {
562 FATAL("Not found: %s %s\n", uri.ToCString(), name.ToCString());
563 }
564 if (name.Equals(Symbols::TopLevel())) {
565 cls = lib.toplevel_class();
566 } else {
567 cls = lib.LookupClass(name);
568 }
569 if (UNLIKELY(cls.IsNull())) {
570 FATAL("Not found: %s %s\n", uri.ToCString(), name.ToCString());
571 }
572 cls.EnsureIsFinalized(d->thread());
573 }
574 d->AssignRef(cls.ptr());
575 }
576 }
577
579 intptr_t count = d->ReadUnsigned();
580 for (intptr_t i = 0; i < count; i++) {
581 intptr_t cid = d->ReadUnsigned();
582 if (cid == 0) {
583 d->ReadAscii(); // Library URI.
584 d->ReadAscii(); // Class name.
585 }
586 d->AssignRef(nullptr);
587 }
588 }
589};
590
593 public:
595 : MessageSerializationCluster("TypeArguments",
597 kTypeArgumentsCid,
598 is_canonical) {}
600
601 void Trace(MessageSerializer* s, Object* object) {
602 TypeArguments* type_args = static_cast<TypeArguments*>(object);
603 objects_.Add(type_args);
604
605 s->Push(type_args->untag()->instantiations());
606 intptr_t length = Smi::Value(type_args->untag()->length());
607 for (intptr_t i = 0; i < length; i++) {
608 s->Push(type_args->untag()->element(i));
609 }
610 }
611
613 const intptr_t count = objects_.length();
614 s->WriteUnsigned(count);
615 for (intptr_t i = 0; i < count; i++) {
616 TypeArguments* type_args = objects_[i];
617 s->AssignRef(type_args);
618 intptr_t length = Smi::Value(type_args->untag()->length());
619 s->WriteUnsigned(length);
620 }
621 }
622
624 const intptr_t count = objects_.length();
625 for (intptr_t i = 0; i < count; i++) {
626 TypeArguments* type_args = objects_[i];
627 intptr_t hash = Smi::Value(type_args->untag()->hash());
628 s->Write<int32_t>(hash);
629 const intptr_t nullability =
630 Smi::Value(type_args->untag()->nullability());
631 s->WriteUnsigned(nullability);
632
633 intptr_t length = Smi::Value(type_args->untag()->length());
634 s->WriteUnsigned(length);
635 for (intptr_t j = 0; j < length; j++) {
636 s->WriteRef(type_args->untag()->element(j));
637 }
638 }
639 }
640
641 private:
643};
644
647 public:
651
653 const intptr_t count = d->ReadUnsigned();
654 for (intptr_t i = 0; i < count; i++) {
655 intptr_t length = d->ReadUnsigned();
656 d->AssignRef(TypeArguments::New(length));
657 }
658 }
659
661 for (intptr_t id = start_index_; id < stop_index_; id++) {
662 TypeArgumentsPtr type_args = static_cast<TypeArgumentsPtr>(d->Ref(id));
663
664 type_args->untag()->hash_ = Smi::New(d->Read<int32_t>());
665 type_args->untag()->nullability_ = Smi::New(d->ReadUnsigned());
666
667 intptr_t length = d->ReadUnsigned();
668 for (intptr_t j = 0; j < length; j++) {
669 type_args->untag()->types()[j] =
670 static_cast<AbstractTypePtr>(d->ReadRef());
671 }
672 }
673 }
674
676 if (is_canonical()) {
677 TypeArguments& type_args = TypeArguments::Handle(d->zone());
678 for (intptr_t id = start_index_; id < stop_index_; id++) {
679 type_args ^= d->Ref(id);
680 type_args ^= type_args.Canonicalize(d->thread());
681 d->UpdateRef(id, type_args);
682 }
683 }
684 return nullptr;
685 }
686
688 intptr_t count = d->ReadUnsigned();
689 for (intptr_t i = 0; i < count; i++) {
690 d->ReadUnsigned(); // Length.
691 d->AssignRef(nullptr);
692 }
693 }
694
696 for (intptr_t id = start_index_; id < stop_index_; id++) {
697 d->Read<int32_t>(); // Hash.
698 d->ReadUnsigned(); // Nullability.
699 intptr_t length = d->ReadUnsigned();
700 for (intptr_t j = 0; j < length; j++) {
701 d->ReadRef(); // Element.
702 }
703 }
704 }
705};
706
708 public:
715
716 void Trace(MessageSerializer* s, Object* object) {
717 Type* type = static_cast<Type*>(object);
718
719 if (!type->IsTypeClassAllowedBySpawnUri()) {
720 s->IllegalObject(*object, "is a Type");
721 }
722
723 objects_.Add(type);
724
725 s->Push(type->type_class());
726 s->Push(type->arguments());
727 }
728
730 const intptr_t count = objects_.length();
731 s->WriteUnsigned(count);
732 for (intptr_t i = 0; i < count; i++) {
733 Type* type = objects_[i];
734 s->AssignRef(type);
735 }
736 }
737
739 const intptr_t count = objects_.length();
740 for (intptr_t i = 0; i < count; i++) {
741 Type* type = objects_[i];
742 s->WriteRef(type->type_class());
743 s->WriteRef(type->arguments());
744 s->Write<uint8_t>(static_cast<uint8_t>(type->nullability()));
745 }
746 }
747
748 private:
749 GrowableArray<Type*> objects_;
750};
751
753 public:
757
759 const intptr_t count = d->ReadUnsigned();
760 for (intptr_t i = 0; i < count; i++) {
761 d->AssignRef(Type::New());
762 }
763 }
764
766 Class& cls = Class::Handle(d->zone());
767 Type& type = Type::Handle(d->zone());
768 TypeArguments& type_args = TypeArguments::Handle(d->zone());
769 for (intptr_t id = start_index_; id < stop_index_; id++) {
770 type ^= d->Ref(id);
771 cls ^= d->ReadRef();
772 type.set_type_class(cls);
773 type_args ^= d->ReadRef();
774 type.set_arguments(type_args);
775 type.untag()->set_hash(Smi::New(0));
776 type.set_nullability(static_cast<Nullability>(d->Read<uint8_t>()));
777 type.SetIsFinalized();
778 }
779 }
780
782
784 intptr_t count = d->ReadUnsigned();
785 for (intptr_t i = 0; i < count; i++) {
786 d->AssignRef(nullptr);
787 }
788 }
789
791 for (intptr_t id = start_index_; id < stop_index_; id++) {
792 d->ReadRef(); // Class.
793 d->ReadRef(); // Type arguments.
794 d->Read<uint8_t>(); // Nullability.
795 }
796 }
797};
798
800 public:
804 kSmiCid,
805 true),
806 objects_(zone, 0) {}
808
809 void Trace(MessageSerializer* s, Object* object) {
810 Smi* smi = static_cast<Smi*>(object);
811 objects_.Add(smi);
812 }
813
815 const intptr_t count = objects_.length();
816 s->WriteUnsigned(count);
817 for (intptr_t i = 0; i < count; i++) {
818 Smi* smi = static_cast<Smi*>(objects_[i]);
819 s->AssignRef(smi);
820 s->Write<intptr_t>(smi->Value());
821 }
822 }
823
825 objects_.Add(reinterpret_cast<Smi*>(object));
826 }
827
829 intptr_t count = objects_.length();
830 s->WriteUnsigned(count);
831 for (intptr_t i = 0; i < count; i++) {
832 Dart_CObject* smi = reinterpret_cast<Dart_CObject*>(objects_[i]);
833 s->AssignRef(smi);
834 intptr_t value = smi->type == Dart_CObject_kInt32 ? smi->value.as_int32
835 : smi->value.as_int64;
836 s->Write<intptr_t>(value);
837 }
838 }
839
840 private:
841 GrowableArray<Smi*> objects_;
842};
843
845 public:
849
851 const intptr_t count = d->ReadUnsigned();
852 for (intptr_t i = 0; i < count; i++) {
853 d->AssignRef(Smi::New(d->Read<intptr_t>()));
854 }
855 }
856
858 intptr_t count = d->ReadUnsigned();
859 for (intptr_t i = 0; i < count; i++) {
860 intptr_t value = d->Read<intptr_t>();
861 Dart_CObject* smi;
862 if ((kMinInt32 <= value) && (value <= kMaxInt32)) {
863 smi = d->Allocate(Dart_CObject_kInt32);
864 smi->value.as_int32 = value;
865 } else {
866 smi = d->Allocate(Dart_CObject_kInt64);
867 smi->value.as_int64 = value;
868 }
869 d->AssignRef(smi);
870 }
871 }
872};
873
875 public:
879 kMintCid,
881 objects_(zone, 0) {}
883
884 void Trace(MessageSerializer* s, Object* object) {
885 Mint* mint = static_cast<Mint*>(object);
886 objects_.Add(mint);
887 }
888
890 const intptr_t count = objects_.length();
891 s->WriteUnsigned(count);
892 for (intptr_t i = 0; i < count; i++) {
893 Mint* mint = static_cast<Mint*>(objects_[i]);
894 s->AssignRef(mint);
895 s->Write<int64_t>(mint->value());
896 }
897 }
898
900 objects_.Add(reinterpret_cast<Mint*>(object));
901 }
902
904 intptr_t count = objects_.length();
905 s->WriteUnsigned(count);
906 for (intptr_t i = 0; i < count; i++) {
907 Dart_CObject* mint = reinterpret_cast<Dart_CObject*>(objects_[i]);
908 s->AssignRef(mint);
909 int64_t value = mint->type == Dart_CObject_kInt32 ? mint->value.as_int32
910 : mint->value.as_int64;
911 s->Write<int64_t>(value);
912 }
913 }
914
915 private:
916 GrowableArray<Mint*> objects_;
917};
918
920 public:
924
926 const intptr_t count = d->ReadUnsigned();
927 for (intptr_t i = 0; i < count; i++) {
928 int64_t value = d->Read<int64_t>();
929 d->AssignRef(is_canonical() ? Mint::NewCanonical(value)
930 : Mint::New(value));
931 }
932 }
933
935 intptr_t count = d->ReadUnsigned();
936 for (intptr_t i = 0; i < count; i++) {
937 int64_t value = d->Read<int64_t>();
938 Dart_CObject* mint;
939 if ((kMinInt32 <= value) && (value <= kMaxInt32)) {
940 mint = d->Allocate(Dart_CObject_kInt32);
941 mint->value.as_int32 = value;
942 } else {
943 mint = d->Allocate(Dart_CObject_kInt64);
944 mint->value.as_int64 = value;
945 }
946 d->AssignRef(mint);
947 }
948 }
949};
950
952 public:
956 kDoubleCid,
958 objects_(zone, 0) {}
959
961
962 void Trace(MessageSerializer* s, Object* object) {
963 Double* dbl = static_cast<Double*>(object);
964 objects_.Add(dbl);
965 }
966
968 const intptr_t count = objects_.length();
969 s->WriteUnsigned(count);
970 for (intptr_t i = 0; i < count; i++) {
971 Double* dbl = objects_[i];
972 s->AssignRef(dbl);
973 s->Write<double>(dbl->untag()->value_);
974 }
975 }
976
978 objects_.Add(reinterpret_cast<Double*>(object));
979 }
980
982 intptr_t count = objects_.length();
983 s->WriteUnsigned(count);
984 for (intptr_t i = 0; i < count; i++) {
985 Dart_CObject* dbl = reinterpret_cast<Dart_CObject*>(objects_[i]);
986 s->AssignRef(dbl);
987 s->Write<double>(dbl->value.as_double);
988 }
989 }
990
991 private:
992 GrowableArray<Double*> objects_;
993};
994
997 public:
1001
1003 const intptr_t count = d->ReadUnsigned();
1004 for (intptr_t i = 0; i < count; i++) {
1005 double value = d->Read<double>();
1007 : Double::New(value));
1008 }
1009 }
1010
1012 intptr_t count = d->ReadUnsigned();
1013 for (intptr_t i = 0; i < count; i++) {
1014 Dart_CObject* dbl = d->Allocate(Dart_CObject_kDouble);
1015 dbl->value.as_double = d->Read<double>();
1016 d->AssignRef(dbl);
1017 }
1018 }
1019};
1020
1023 public:
1025 : MessageSerializationCluster("GrowableObjectArray",
1027 kGrowableObjectArrayCid) {}
1029
1031 GrowableObjectArray* array = static_cast<GrowableObjectArray*>(object);
1032 objects_.Add(array);
1033
1034 // Compensation for bogus type prefix optimization.
1036 TypeArguments::Handle(s->zone(), array->untag()->type_arguments());
1037 if (!args.IsNull() && (args.Length() != 1)) {
1038 args = args.TruncatedTo(1);
1039 array->untag()->set_type_arguments(args.ptr());
1040 }
1041
1042 s->Push(array->untag()->type_arguments());
1043 for (intptr_t i = 0, n = array->Length(); i < n; i++) {
1044 s->Push(array->At(i));
1045 }
1046 }
1047
1049 const intptr_t count = objects_.length();
1050 s->WriteUnsigned(count);
1051 for (intptr_t i = 0; i < count; i++) {
1052 GrowableObjectArray* array = objects_[i];
1053 s->WriteUnsigned(array->Length());
1054 s->AssignRef(array);
1055 }
1056 }
1057
1059 const intptr_t count = objects_.length();
1060 for (intptr_t i = 0; i < count; i++) {
1061 GrowableObjectArray* array = objects_[i];
1062 s->WriteRef(array->untag()->type_arguments());
1063 for (intptr_t i = 0, n = array->Length(); i < n; i++) {
1064 s->WriteRef(array->At(i));
1065 }
1066 }
1067 }
1068
1069 private:
1071};
1072
1075 public:
1079
1081 const intptr_t count = d->ReadUnsigned();
1083 for (intptr_t i = 0; i < count; i++) {
1084 intptr_t length = d->ReadUnsigned();
1085 array = GrowableObjectArray::New(length); // Here length is capacity.
1086 array.SetLength(length);
1087 d->AssignRef(array.ptr());
1088 }
1089 }
1090
1093 for (intptr_t id = start_index_; id < stop_index_; id++) {
1094 array ^= d->Ref(id);
1095 array.untag()->set_type_arguments(
1096 static_cast<TypeArgumentsPtr>(d->ReadRef()));
1097 for (intptr_t i = 0, n = array.Length(); i < n; i++) {
1098 array.untag()->data()->untag()->set_element(i, d->ReadRef());
1099 }
1100 }
1101 }
1102
1104 ASSERT(!is_canonical());
1105 return nullptr;
1106 }
1107
1109 intptr_t count = d->ReadUnsigned();
1110 for (intptr_t i = 0; i < count; i++) {
1111 Dart_CObject* array = d->Allocate(Dart_CObject_kArray);
1112 intptr_t length = d->ReadUnsigned();
1113 array->value.as_array.length = length;
1114 if (length > 0) {
1115 array->value.as_array.values = d->zone()->Alloc<Dart_CObject*>(length);
1116 } else {
1117 ASSERT(length == 0);
1118 array->value.as_array.values = nullptr;
1119 }
1120 d->AssignRef(array);
1121 }
1122 }
1123
1125 for (intptr_t id = start_index_; id < stop_index_; id++) {
1126 Dart_CObject* array = d->Ref(id);
1127 intptr_t length = array->value.as_array.length;
1128 d->ReadRef(); // type_arguments
1129 for (intptr_t i = 0; i < length; i++) {
1130 array->value.as_array.values[i] = d->ReadRef();
1131 }
1132 }
1133 }
1134};
1135
1138 public:
1140 : MessageSerializationCluster("TypedData",
1142 cid),
1143 objects_(zone, 0) {}
1145
1147 TypedData* data = static_cast<TypedData*>(object);
1148 objects_.Add(data);
1149 }
1150
1153 intptr_t count = objects_.length();
1154 s->WriteUnsigned(count);
1155 for (intptr_t i = 0; i < count; i++) {
1156 TypedData* data = objects_[i];
1157 s->AssignRef(data);
1158 intptr_t length = data->Length();
1159 s->WriteUnsigned(length);
1160 NoSafepointScope no_safepoint;
1161 uint8_t* cdata = reinterpret_cast<uint8_t*>(data->untag()->data());
1162 s->WriteBytes(cdata, length * element_size);
1163 }
1164 }
1165
1167 objects_.Add(reinterpret_cast<TypedData*>(object));
1168 }
1169
1172 intptr_t count = objects_.length();
1173 s->WriteUnsigned(count);
1174 for (intptr_t i = 0; i < count; i++) {
1175 Dart_CObject* data = reinterpret_cast<Dart_CObject*>(objects_[i]);
1176 s->AssignRef(data);
1177 intptr_t length = data->value.as_external_typed_data.length;
1178 s->WriteUnsigned(length);
1179 const uint8_t* cdata = data->value.as_typed_data.values;
1180 s->WriteBytes(cdata, length * element_size);
1181 }
1182 }
1183
1184 private:
1186};
1187
1190 public:
1192 : MessageDeserializationCluster("TypedData"), cid_(cid) {}
1194
1197 intptr_t count = d->ReadUnsigned();
1198 TypedData& data = TypedData::Handle(d->zone());
1199 for (intptr_t i = 0; i < count; i++) {
1200 intptr_t length = d->ReadUnsigned();
1201 data = TypedData::New(cid_, length);
1202 d->AssignRef(data.ptr());
1203 const intptr_t length_in_bytes = length * element_size;
1204 NoSafepointScope no_safepoint;
1205 d->ReadBytes(data.untag()->data(), length_in_bytes);
1206 }
1207 }
1208
1211 switch (cid_) {
1212 case kTypedDataInt8ArrayCid:
1214 break;
1215 case kTypedDataUint8ArrayCid:
1217 break;
1218 case kTypedDataUint8ClampedArrayCid:
1220 break;
1221 case kTypedDataInt16ArrayCid:
1223 break;
1224 case kTypedDataUint16ArrayCid:
1226 break;
1227 case kTypedDataInt32ArrayCid:
1229 break;
1230 case kTypedDataUint32ArrayCid:
1232 break;
1233 case kTypedDataInt64ArrayCid:
1235 break;
1236 case kTypedDataUint64ArrayCid:
1238 break;
1239 case kTypedDataFloat32ArrayCid:
1241 break;
1242 case kTypedDataFloat64ArrayCid:
1244 break;
1245 case kTypedDataInt32x4ArrayCid:
1247 break;
1248 case kTypedDataFloat32x4ArrayCid:
1250 break;
1251 case kTypedDataFloat64x2ArrayCid:
1253 break;
1254 default:
1255 UNREACHABLE();
1256 }
1257
1259 intptr_t count = d->ReadUnsigned();
1260 for (intptr_t i = 0; i < count; i++) {
1262 intptr_t length = d->ReadUnsigned();
1264 data->value.as_typed_data.length = length;
1265 if (length == 0) {
1266 data->value.as_typed_data.values = nullptr;
1267 } else {
1268 data->value.as_typed_data.values = d->CurrentBufferAddress();
1269 d->Advance(length * element_size);
1270 }
1271 d->AssignRef(data);
1272 }
1273 }
1274
1275 private:
1276 const intptr_t cid_;
1277};
1278
1279// This function's name can appear in Observatory.
1280static void IsolateMessageTypedDataFinalizer(void* isolate_callback_data,
1281 void* buffer) {
1282 free(buffer);
1283}
1284
1287 public:
1289 intptr_t cid)
1290 : MessageSerializationCluster("ExternalTypedData",
1292 cid),
1293 objects_(zone, 0) {}
1295
1297 ExternalTypedData* data = static_cast<ExternalTypedData*>(object);
1298 objects_.Add(data);
1299 }
1300
1303
1304 intptr_t count = objects_.length();
1305 s->WriteUnsigned(count);
1306 for (intptr_t i = 0; i < count; i++) {
1307 ExternalTypedData* data = objects_[i];
1308 s->AssignRef(data);
1309 intptr_t length = Smi::Value(data->untag()->length_);
1310 s->WriteUnsigned(length);
1311
1312 intptr_t length_in_bytes = length * element_size;
1313 void* passed_data = malloc(length_in_bytes);
1314 memmove(passed_data, data->untag()->data_, length_in_bytes);
1315 s->finalizable_data()->Put(length_in_bytes,
1316 passed_data, // data
1317 passed_data, // peer,
1319 }
1320 }
1321
1323 objects_.Add(reinterpret_cast<ExternalTypedData*>(object));
1324 }
1325
1328
1329 intptr_t count = objects_.length();
1330 s->WriteUnsigned(count);
1331 for (intptr_t i = 0; i < count; i++) {
1332 Dart_CObject* data = reinterpret_cast<Dart_CObject*>(objects_[i]);
1333 s->AssignRef(data);
1334
1335 intptr_t length = data->value.as_external_typed_data.length;
1336 s->WriteUnsigned(length);
1337
1338 s->finalizable_data()->Put(length * element_size,
1339 data->value.as_external_typed_data.data,
1340 data->value.as_external_typed_data.peer,
1341 data->value.as_external_typed_data.callback);
1342 }
1343 }
1344
1345 private:
1347};
1348
1351 public:
1353 : MessageDeserializationCluster("ExternalTypedData"), cid_(cid) {}
1355
1358 intptr_t count = d->ReadUnsigned();
1360 for (intptr_t i = 0; i < count; i++) {
1361 intptr_t length = d->ReadUnsigned();
1362 FinalizableData finalizable_data = d->finalizable_data()->Take();
1364 cid_, reinterpret_cast<uint8_t*>(finalizable_data.data), length);
1365 intptr_t external_size = length * element_size;
1366 data.AddFinalizer(finalizable_data.peer, finalizable_data.callback,
1367 external_size);
1368 d->AssignRef(data.ptr());
1369 }
1370 }
1371
1374 switch (cid_) {
1375 case kExternalTypedDataInt8ArrayCid:
1377 break;
1378 case kExternalTypedDataUint8ArrayCid:
1380 break;
1381 case kExternalTypedDataUint8ClampedArrayCid:
1383 break;
1384 case kExternalTypedDataInt16ArrayCid:
1386 break;
1387 case kExternalTypedDataUint16ArrayCid:
1389 break;
1390 case kExternalTypedDataInt32ArrayCid:
1392 break;
1393 case kExternalTypedDataUint32ArrayCid:
1395 break;
1396 case kExternalTypedDataInt64ArrayCid:
1398 break;
1399 case kExternalTypedDataUint64ArrayCid:
1401 break;
1402 case kExternalTypedDataFloat32ArrayCid:
1404 break;
1405 case kExternalTypedDataFloat64ArrayCid:
1407 break;
1408 case kExternalTypedDataInt32x4ArrayCid:
1410 break;
1411 case kExternalTypedDataFloat32x4ArrayCid:
1413 break;
1414 case kExternalTypedDataFloat64x2ArrayCid:
1416 break;
1417 default:
1418 UNREACHABLE();
1419 }
1420
1421 intptr_t count = d->ReadUnsigned();
1422 for (intptr_t i = 0; i < count; i++) {
1424 intptr_t length = d->ReadUnsigned();
1425 FinalizableData finalizable_data = d->finalizable_data()->Get();
1426 data->value.as_typed_data.type = type;
1427 data->value.as_typed_data.length = length;
1428 data->value.as_typed_data.values =
1429 reinterpret_cast<uint8_t*>(finalizable_data.data);
1430 d->AssignRef(data);
1431 }
1432 }
1433
1434 private:
1435 const intptr_t cid_;
1436};
1437
1440 public:
1442 : MessageSerializationCluster("NativePointer",
1445 objects_(zone, 0) {}
1447
1449
1451
1453 objects_.Add(object);
1454 }
1455
1457 intptr_t count = objects_.length();
1458 s->WriteUnsigned(count);
1459 for (intptr_t i = 0; i < count; i++) {
1460 Dart_CObject* data = objects_[i];
1461 s->AssignRef(data);
1462
1463 s->finalizable_data()->Put(
1464 data->value.as_native_pointer.size,
1465 reinterpret_cast<void*>(data->value.as_native_pointer.ptr),
1466 reinterpret_cast<void*>(data->value.as_native_pointer.ptr),
1467 data->value.as_native_pointer.callback);
1468 }
1469 }
1470
1471 private:
1473};
1474
1477 public:
1481
1483 const intptr_t count = d->ReadUnsigned();
1484 for (intptr_t i = 0; i < count; i++) {
1485 FinalizableData finalizable_data = d->finalizable_data()->Take();
1486 intptr_t ptr = reinterpret_cast<intptr_t>(finalizable_data.data);
1487 d->AssignRef(Integer::New(ptr));
1488 }
1489 }
1490
1492
1493 private:
1494 const intptr_t cid_;
1495};
1496
1501
1504 public:
1506 : MessageSerializationCluster("TypedDataView",
1508 cid),
1509 objects_(zone, 0) {}
1511
1513 TypedDataView* view = static_cast<TypedDataView*>(object);
1514 objects_.Add(view);
1515
1516 s->Push(view->untag()->length());
1517 s->Push(view->untag()->typed_data());
1518 s->Push(view->untag()->offset_in_bytes());
1519 }
1520
1522 const intptr_t count = objects_.length();
1523 s->WriteUnsigned(count);
1525 for (intptr_t i = 0; i < count; i++) {
1526 TypedDataView* view = objects_[i];
1527 s->AssignRef(view);
1528 }
1529 }
1530
1532 const intptr_t count = objects_.length();
1533 for (intptr_t i = 0; i < count; i++) {
1534 TypedDataView* view = objects_[i];
1535 s->WriteRef(view->untag()->length());
1536 s->WriteRef(view->untag()->typed_data());
1537 s->WriteRef(view->untag()->offset_in_bytes());
1538 }
1539 }
1540
1543 objects_.Add(reinterpret_cast<TypedDataView*>(object));
1544 }
1545
1548
1549 intptr_t count = objects_.length();
1550 s->WriteUnsigned(count);
1552 for (intptr_t i = 0; i < count; i++) {
1553 Dart_CObject* data = reinterpret_cast<Dart_CObject*>(objects_[i]);
1554 s->AssignRef(data);
1555
1556 intptr_t length = data->value.as_external_typed_data.length;
1557 s->WriteUnsigned(length);
1558
1559 s->finalizable_data()->Put(length * element_size,
1560 data->value.as_external_typed_data.data,
1561 data->value.as_external_typed_data.peer,
1562 data->value.as_external_typed_data.callback);
1563 }
1564 }
1565
1566 private:
1568};
1569
1572 public:
1574 : MessageDeserializationCluster("TypedDataView"), cid_(cid) {}
1576
1578 const intptr_t count = d->ReadUnsigned();
1579 format_ = d->Read<TypedDataViewFormat>();
1580 if (format_ == kTypedDataViewFromC) {
1581 intptr_t view_cid = cid_;
1583 intptr_t backing_cid = cid_ - kTypedDataCidRemainderUnmodifiable +
1585 ASSERT(IsExternalTypedDataClassId(backing_cid));
1586 intptr_t element_size =
1589 TypedDataView& view = TypedDataView::Handle(d->zone());
1590 for (intptr_t i = 0; i < count; i++) {
1591 intptr_t length = d->ReadUnsigned();
1592 FinalizableData finalizable_data = d->finalizable_data()->Take();
1594 backing_cid, reinterpret_cast<uint8_t*>(finalizable_data.data),
1595 length);
1596 data.SetImmutable(); // Can pass by reference.
1597 intptr_t external_size = length * element_size;
1598 data.AddFinalizer(finalizable_data.peer, finalizable_data.callback,
1599 external_size);
1600 view = TypedDataView::New(view_cid, data, 0, length);
1601 d->AssignRef(data.ptr());
1602 }
1603 } else {
1604 for (intptr_t i = 0; i < count; i++) {
1605 d->AssignRef(TypedDataView::New(cid_));
1606 }
1607 }
1608 }
1609
1611 if (format_ == kTypedDataViewFromC) return;
1612 for (intptr_t id = start_index_; id < stop_index_; id++) {
1613 TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d->Ref(id));
1614 view->untag()->set_length(static_cast<SmiPtr>(d->ReadRef()));
1615 view->untag()->set_typed_data(
1616 static_cast<TypedDataBasePtr>(d->ReadRef()));
1617 view->untag()->set_offset_in_bytes(static_cast<SmiPtr>(d->ReadRef()));
1618 }
1619 }
1620
1622 if (format_ == kTypedDataViewFromC) return nullptr;
1623 for (intptr_t id = start_index_; id < stop_index_; id++) {
1624 TypedDataViewPtr view = static_cast<TypedDataViewPtr>(d->Ref(id));
1625 view->untag()->RecomputeDataField();
1626 }
1627 return nullptr;
1628 }
1629
1635
1637 intptr_t count = d->ReadUnsigned();
1638 format_ = d->Read<TypedDataViewFormat>();
1639 if (format_ == kTypedDataViewFromC) {
1641 switch (cid_) {
1642 case kUnmodifiableTypedDataInt8ArrayViewCid:
1644 break;
1645 case kUnmodifiableTypedDataUint8ArrayViewCid:
1647 break;
1648 case kUnmodifiableTypedDataUint8ClampedArrayViewCid:
1650 break;
1651 case kUnmodifiableTypedDataInt16ArrayViewCid:
1653 break;
1654 case kUnmodifiableTypedDataUint16ArrayViewCid:
1656 break;
1657 case kUnmodifiableTypedDataInt32ArrayViewCid:
1659 break;
1660 case kUnmodifiableTypedDataUint32ArrayViewCid:
1662 break;
1663 case kUnmodifiableTypedDataInt64ArrayViewCid:
1665 break;
1666 case kUnmodifiableTypedDataUint64ArrayViewCid:
1668 break;
1669 case kUnmodifiableTypedDataFloat32ArrayViewCid:
1671 break;
1672 case kUnmodifiableTypedDataFloat64ArrayViewCid:
1674 break;
1675 case kUnmodifiableTypedDataInt32x4ArrayViewCid:
1677 break;
1678 case kUnmodifiableTypedDataFloat32x4ArrayViewCid:
1680 break;
1681 case kUnmodifiableTypedDataFloat64x2ArrayViewCid:
1683 break;
1684 default:
1685 UNREACHABLE();
1686 }
1687
1690 intptr_t length = d->ReadUnsigned();
1691 FinalizableData finalizable_data = d->finalizable_data()->Get();
1692 data->value.as_typed_data.type = type;
1693 data->value.as_typed_data.length = length;
1694 data->value.as_typed_data.values =
1695 reinterpret_cast<uint8_t*>(finalizable_data.data);
1696 d->AssignRef(data);
1697 } else {
1698 for (intptr_t i = 0; i < count; i++) {
1699 Dart_CTypedDataView* view = d->zone()->Alloc<Dart_CTypedDataView>(1);
1700 d->AssignRef(view);
1701 }
1702 }
1703 }
1704
1706 if (format_ == kTypedDataViewFromC) return;
1707 for (intptr_t id = start_index_; id < stop_index_; id++) {
1708 Dart_CTypedDataView* view = static_cast<Dart_CTypedDataView*>(d->Ref(id));
1709 view->length = d->ReadRef();
1710 view->typed_data = d->ReadRef();
1711 view->offset_in_bytes = d->ReadRef();
1712 }
1713 }
1714
1716 if (format_ == kTypedDataViewFromC) return;
1718 switch (cid_) {
1719 case kTypedDataInt8ArrayViewCid:
1720 case kUnmodifiableTypedDataInt8ArrayViewCid:
1722 break;
1723 case kTypedDataUint8ArrayViewCid:
1724 case kUnmodifiableTypedDataUint8ArrayViewCid:
1726 break;
1727 case kTypedDataUint8ClampedArrayViewCid:
1728 case kUnmodifiableTypedDataUint8ClampedArrayViewCid:
1730 break;
1731 case kTypedDataInt16ArrayViewCid:
1732 case kUnmodifiableTypedDataInt16ArrayViewCid:
1734 break;
1735 case kTypedDataUint16ArrayViewCid:
1736 case kUnmodifiableTypedDataUint16ArrayViewCid:
1738 break;
1739 case kTypedDataInt32ArrayViewCid:
1740 case kUnmodifiableTypedDataInt32ArrayViewCid:
1742 break;
1743 case kTypedDataUint32ArrayViewCid:
1744 case kUnmodifiableTypedDataUint32ArrayViewCid:
1746 break;
1747 case kTypedDataInt64ArrayViewCid:
1748 case kUnmodifiableTypedDataInt64ArrayViewCid:
1750 break;
1751 case kTypedDataUint64ArrayViewCid:
1752 case kUnmodifiableTypedDataUint64ArrayViewCid:
1754 break;
1755 case kTypedDataFloat32ArrayViewCid:
1756 case kUnmodifiableTypedDataFloat32ArrayViewCid:
1758 break;
1759 case kTypedDataFloat64ArrayViewCid:
1760 case kUnmodifiableTypedDataFloat64ArrayViewCid:
1762 break;
1763 case kTypedDataInt32x4ArrayViewCid:
1764 case kUnmodifiableTypedDataInt32x4ArrayViewCid:
1766 break;
1767 case kTypedDataFloat32x4ArrayViewCid:
1768 case kUnmodifiableTypedDataFloat32x4ArrayViewCid:
1770 break;
1771 case kTypedDataFloat64x2ArrayViewCid:
1772 case kUnmodifiableTypedDataFloat64x2ArrayViewCid:
1774 break;
1775 default:
1776 UNREACHABLE();
1777 }
1778
1779 for (intptr_t id = start_index_; id < stop_index_; id++) {
1780 Dart_CTypedDataView* view = static_cast<Dart_CTypedDataView*>(d->Ref(id));
1781 if (view->typed_data->type == Dart_CObject_kTypedData) {
1783 view->value.as_typed_data.type = type;
1785 view->value.as_typed_data.values =
1788 } else {
1789 UNREACHABLE();
1790 }
1791 }
1792 }
1793
1794 private:
1795 const intptr_t cid_;
1796 TypedDataViewFormat format_;
1797};
1798
1801 public:
1803 : MessageSerializationCluster("TransferableTypedData",
1805 kTransferableTypedDataCid) {}
1807
1809 TransferableTypedData* transferable =
1810 static_cast<TransferableTypedData*>(object);
1811 objects_.Add(transferable);
1812
1813 void* peer = s->thread()->heap()->GetPeer(transferable->ptr());
1814 // Assume that object's Peer is only used to track transferability state.
1815 ASSERT(peer != nullptr);
1817 reinterpret_cast<TransferableTypedDataPeer*>(peer);
1818 if (tpeer->data() == nullptr) {
1819 s->IllegalObject(*object,
1820 "TransferableTypedData has been transferred already");
1821 }
1822 }
1823
1825 const intptr_t count = objects_.length();
1826 s->WriteUnsigned(count);
1827 for (intptr_t i = 0; i < count; i++) {
1828 TransferableTypedData* transferable = objects_[i];
1829 s->AssignRef(transferable);
1830
1831 void* peer = s->thread()->heap()->GetPeer(transferable->ptr());
1832 // Assume that object's Peer is only used to track transferability state.
1833 ASSERT(peer != nullptr);
1835 reinterpret_cast<TransferableTypedDataPeer*>(peer);
1836 intptr_t length = tpeer->length(); // In bytes.
1837 void* data = tpeer->data();
1838 ASSERT(data != nullptr);
1839 s->WriteUnsigned(length);
1840 s->finalizable_data()->Put(
1841 length, data, tpeer,
1842 // Finalizer does nothing - in case of failure to serialize,
1843 // [data] remains wrapped in sender's [TransferableTypedData].
1844 [](void* data, void* peer) {},
1845 // This is invoked on successful serialization of the message
1846 [](void* data, void* peer) {
1848 reinterpret_cast<TransferableTypedDataPeer*>(peer);
1850 ttpeer->ClearData();
1851 });
1852 }
1853 }
1854
1855 private:
1857};
1858
1861 public:
1865
1867 const intptr_t count = d->ReadUnsigned();
1868 for (intptr_t i = 0; i < count; i++) {
1869 intptr_t length = d->ReadUnsigned();
1870 const FinalizableData finalizable_data = d->finalizable_data()->Take();
1871 d->AssignRef(TransferableTypedData::New(
1872 reinterpret_cast<uint8_t*>(finalizable_data.data), length));
1873 }
1874 }
1875
1877 intptr_t count = d->ReadUnsigned();
1878 for (intptr_t i = 0; i < count; i++) {
1880 data->value.as_typed_data.length = d->ReadUnsigned();
1881 data->value.as_typed_data.type = Dart_TypedData_kUint8;
1882 FinalizableData finalizable_data = d->finalizable_data()->Get();
1883 data->value.as_typed_data.values =
1884 reinterpret_cast<const uint8_t*>(finalizable_data.data);
1885 d->AssignRef(data);
1886 }
1887 }
1888};
1889
1891 public:
1897
1898 void Trace(MessageSerializer* s, Object* object) { objects_.Add(object); }
1899
1901 const intptr_t count = objects_.length();
1902 s->WriteUnsigned(count);
1903 for (intptr_t i = 0; i < count; i++) {
1904 Object* vector = objects_[i];
1905 s->AssignRef(vector);
1908 s->WriteBytes(&(static_cast<Int32x4Ptr>(vector->ptr())->untag()->value_),
1909 sizeof(simd128_value_t));
1910 }
1911 }
1912
1913 private:
1914 GrowableArray<Object*> objects_;
1915};
1916
1919 public:
1921 : MessageDeserializationCluster("Simd128"), cid_(cid) {
1922 ASSERT(cid_ == kInt32x4Cid || cid_ == kFloat32x4Cid ||
1923 cid_ == kFloat64x2Cid);
1924#if defined(DEBUG)
1925 // If not for Int32x4, check that all the Int32x4-specific arguments used in
1926 // ReadNodes match those for the actual class.
1927 if (cid_ == kFloat32x4Cid) {
1928 AssertSameStructure<Int32x4, Float32x4>();
1929 } else if (cid_ == kFloat64x2Cid) {
1930 AssertSameStructure<Int32x4, Float64x2>();
1931 }
1932#endif
1933 }
1935
1936#if defined(DEBUG)
1937 template <typename Expected, typename Got>
1938 static void AssertSameStructure() {
1939 ASSERT_EQUAL(Got::InstanceSize(), Expected::InstanceSize());
1940 ASSERT_EQUAL(Got::ContainsCompressedPointers(),
1941 Expected::ContainsCompressedPointers());
1942 ASSERT_EQUAL(Object::from_offset<Got>(), Object::from_offset<Expected>());
1943 ASSERT_EQUAL(Object::to_offset<Got>(), Object::to_offset<Expected>());
1944 ASSERT_EQUAL(Got::value_offset(), Expected::value_offset());
1945 }
1946#endif
1947
1949 const intptr_t count = d->ReadUnsigned();
1950 for (intptr_t i = 0; i < count; i++) {
1951 ObjectPtr vector = Object::Allocate(
1953 Int32x4::ContainsCompressedPointers(), Object::from_offset<Int32x4>(),
1954 Object::to_offset<Int32x4>());
1955 d->AssignRef(vector);
1956 d->ReadBytes(&(static_cast<Int32x4Ptr>(vector)->untag()->value_),
1957 sizeof(simd128_value_t));
1958 }
1959 }
1960
1961 private:
1962 const intptr_t cid_;
1963};
1964
1966 public:
1968 : MessageSerializationCluster("SendPort",
1970 kSendPortCid),
1971 objects_(zone, 0) {}
1973
1975 SendPort* port = static_cast<SendPort*>(object);
1976 objects_.Add(port);
1977 }
1978
1980 const intptr_t count = objects_.length();
1981 s->WriteUnsigned(count);
1982 for (intptr_t i = 0; i < count; i++) {
1983 SendPort* port = objects_[i];
1984 s->AssignRef(port);
1985 s->Write<Dart_Port>(port->untag()->id_);
1986 s->Write<Dart_Port>(port->untag()->origin_id_);
1987 }
1988 }
1989
1991 objects_.Add(reinterpret_cast<SendPort*>(object));
1992 }
1993
1995 intptr_t count = objects_.length();
1996 s->WriteUnsigned(count);
1997 for (intptr_t i = 0; i < count; i++) {
1998 Dart_CObject* port = reinterpret_cast<Dart_CObject*>(objects_[i]);
1999 s->AssignRef(port);
2000 s->Write<Dart_Port>(port->value.as_send_port.id);
2001 s->Write<Dart_Port>(port->value.as_send_port.origin_id);
2002 }
2003 }
2004
2005 private:
2006 GrowableArray<SendPort*> objects_;
2007};
2008
2011 public:
2015
2017 const intptr_t count = d->ReadUnsigned();
2018 for (intptr_t i = 0; i < count; i++) {
2019 Dart_Port id = d->Read<Dart_Port>();
2020 Dart_Port origin_id = d->Read<Dart_Port>();
2021 d->AssignRef(SendPort::New(id, origin_id));
2022 }
2023 }
2024
2026 intptr_t count = d->ReadUnsigned();
2027 for (intptr_t i = 0; i < count; i++) {
2028 Dart_CObject* port = d->Allocate(Dart_CObject_kSendPort);
2029 port->value.as_send_port.id = d->Read<Dart_Port>();
2030 port->value.as_send_port.origin_id = d->Read<Dart_Port>();
2031 d->AssignRef(port);
2032 }
2033 }
2034};
2035
2038 public:
2040 : MessageSerializationCluster("Capability",
2042 kCapabilityCid),
2043 objects_(zone, 0) {}
2045
2047 Capability* cap = static_cast<Capability*>(object);
2048 objects_.Add(cap);
2049 }
2050
2052 const intptr_t count = objects_.length();
2053 s->WriteUnsigned(count);
2054 for (intptr_t i = 0; i < count; i++) {
2055 Capability* cap = objects_[i];
2056 s->AssignRef(cap);
2057 s->Write<uint64_t>(cap->untag()->id_);
2058 }
2059 }
2060
2062 objects_.Add(reinterpret_cast<Capability*>(object));
2063 }
2064
2066 intptr_t count = objects_.length();
2067 s->WriteUnsigned(count);
2068 for (intptr_t i = 0; i < count; i++) {
2069 Dart_CObject* cap = reinterpret_cast<Dart_CObject*>(objects_[i]);
2070 s->AssignRef(cap);
2071 s->Write<Dart_Port>(cap->value.as_capability.id);
2072 }
2073 }
2074
2075 private:
2077};
2078
2081 public:
2085
2087 const intptr_t count = d->ReadUnsigned();
2088 for (intptr_t i = 0; i < count; i++) {
2089 uint64_t id = d->Read<uint64_t>();
2090 d->AssignRef(Capability::New(id));
2091 }
2092 }
2093
2095 intptr_t count = d->ReadUnsigned();
2096 for (intptr_t i = 0; i < count; i++) {
2097 Dart_CObject* cap = d->Allocate(Dart_CObject_kCapability);
2098 cap->value.as_capability.id = d->Read<uint64_t>();
2099 d->AssignRef(cap);
2100 }
2101 }
2102};
2103
2105 public:
2115
2117 Map* map = static_cast<Map*>(object);
2118 objects_.Add(map);
2119
2120 // Compensation for bogus type prefix optimization.
2122 TypeArguments::Handle(s->zone(), map->untag()->type_arguments());
2123 if (!args.IsNull() && (args.Length() != 2)) {
2124 args = args.TruncatedTo(2);
2125 map->untag()->set_type_arguments(args.ptr());
2126 }
2127
2128 s->Push(map->untag()->type_arguments());
2129 s->Push(map->untag()->data());
2130 s->Push(map->untag()->used_data());
2131 }
2132
2134 const intptr_t count = objects_.length();
2135 s->WriteUnsigned(count);
2136 for (intptr_t i = 0; i < count; i++) {
2137 Map* map = objects_[i];
2138 s->AssignRef(map);
2139 }
2140 }
2141
2143 const intptr_t count = objects_.length();
2144 for (intptr_t i = 0; i < count; i++) {
2145 Map* map = objects_[i];
2146 s->WriteRef(map->untag()->type_arguments());
2147 s->WriteRef(map->untag()->data());
2148 s->WriteRef(map->untag()->used_data());
2149 }
2150 }
2151
2152 private:
2153 GrowableArray<Map*> objects_;
2154};
2155
2157 public:
2161
2163 const intptr_t count = d->ReadUnsigned();
2164 for (intptr_t i = 0; i < count; i++) {
2165 d->AssignRef(Map::NewUninitialized(cid_));
2166 }
2167 }
2168
2170 for (intptr_t id = start_index_; id < stop_index_; id++) {
2171 MapPtr map = static_cast<MapPtr>(d->Ref(id));
2172 map->untag()->set_hash_mask(Smi::New(0));
2173 map->untag()->set_type_arguments(
2174 static_cast<TypeArgumentsPtr>(d->ReadRef()));
2175 map->untag()->set_data(static_cast<ArrayPtr>(d->ReadRef()));
2176 map->untag()->set_used_data(static_cast<SmiPtr>(d->ReadRef()));
2177 map->untag()->set_deleted_keys(Smi::New(0));
2178 }
2179 }
2180
2182 if (!is_canonical()) {
2183 ASSERT(cid_ == kMapCid);
2184 return PostLoadLinkedHash(d);
2185 }
2186
2187 ASSERT(cid_ == kConstMapCid);
2189 d->isolate_group()->constant_canonicalization_mutex());
2190 Map& instance = Map::Handle(d->zone());
2191 for (intptr_t i = start_index_; i < stop_index_; i++) {
2192 instance ^= d->Ref(i);
2193 instance ^= instance.CanonicalizeLocked(d->thread());
2194 d->UpdateRef(i, instance);
2195 }
2196 return nullptr;
2197 }
2198
2199 private:
2200 const intptr_t cid_;
2201};
2202
2204 public:
2214
2216 Set* set = static_cast<Set*>(object);
2217 objects_.Add(set);
2218
2219 // Compensation for bogus type prefix optimization.
2221 TypeArguments::Handle(s->zone(), set->untag()->type_arguments());
2222 if (!args.IsNull() && (args.Length() != 1)) {
2223 args = args.TruncatedTo(1);
2224 set->untag()->set_type_arguments(args.ptr());
2225 }
2226
2227 s->Push(set->untag()->type_arguments());
2228 s->Push(set->untag()->data());
2229 s->Push(set->untag()->used_data());
2230 }
2231
2233 const intptr_t count = objects_.length();
2234 s->WriteUnsigned(count);
2235 for (intptr_t i = 0; i < count; i++) {
2236 Set* set = objects_[i];
2237 s->AssignRef(set);
2238 }
2239 }
2240
2242 const intptr_t count = objects_.length();
2243 for (intptr_t i = 0; i < count; i++) {
2244 Set* set = objects_[i];
2245 s->WriteRef(set->untag()->type_arguments());
2246 s->WriteRef(set->untag()->data());
2247 s->WriteRef(set->untag()->used_data());
2248 }
2249 }
2250
2251 private:
2252 GrowableArray<Set*> objects_;
2253};
2254
2256 public:
2260
2262 const intptr_t count = d->ReadUnsigned();
2263 for (intptr_t i = 0; i < count; i++) {
2264 d->AssignRef(Set::NewUninitialized(cid_));
2265 }
2266 }
2267
2269 for (intptr_t id = start_index_; id < stop_index_; id++) {
2270 SetPtr map = static_cast<SetPtr>(d->Ref(id));
2271 map->untag()->set_hash_mask(Smi::New(0));
2272 map->untag()->set_type_arguments(
2273 static_cast<TypeArgumentsPtr>(d->ReadRef()));
2274 map->untag()->set_data(static_cast<ArrayPtr>(d->ReadRef()));
2275 map->untag()->set_used_data(static_cast<SmiPtr>(d->ReadRef()));
2276 map->untag()->set_deleted_keys(Smi::New(0));
2277 }
2278 }
2279
2281 if (!is_canonical()) {
2282 ASSERT(cid_ == kSetCid);
2283 return PostLoadLinkedHash(d);
2284 }
2285
2286 ASSERT(cid_ == kConstSetCid);
2288 d->isolate_group()->constant_canonicalization_mutex());
2289 Set& instance = Set::Handle(d->zone());
2290 for (intptr_t i = start_index_; i < stop_index_; i++) {
2291 instance ^= d->Ref(i);
2292 instance ^= instance.CanonicalizeLocked(d->thread());
2293 d->UpdateRef(i, instance);
2294 }
2295 return nullptr;
2296 }
2297
2298 private:
2299 const intptr_t cid_;
2300};
2301
2303 public:
2313
2315 Array* array = static_cast<Array*>(object);
2316 objects_.Add(array);
2317
2318 // Compensation for bogus type prefix optimization.
2320 TypeArguments::Handle(s->zone(), array->untag()->type_arguments());
2321 if (!args.IsNull() && (args.Length() != 1)) {
2322 args = args.TruncatedTo(1);
2323 array->untag()->set_type_arguments(args.ptr());
2324 }
2325
2326 s->Push(array->untag()->type_arguments());
2327 intptr_t length = Smi::Value(array->untag()->length());
2328 for (intptr_t i = 0; i < length; i++) {
2329 s->Push(array->untag()->element(i));
2330 }
2331 }
2332
2334 const intptr_t count = objects_.length();
2335 s->WriteUnsigned(count);
2336 for (intptr_t i = 0; i < count; i++) {
2337 Array* array = objects_[i];
2338 s->AssignRef(array);
2339 intptr_t length = Smi::Value(array->untag()->length());
2340 s->WriteUnsigned(length);
2341 }
2342 }
2343
2345 const intptr_t count = objects_.length();
2346 for (intptr_t i = 0; i < count; i++) {
2347 Array* array = objects_[i];
2348 intptr_t length = array->Length();
2349 s->WriteRef(array->untag()->type_arguments());
2350 for (intptr_t j = 0; j < length; j++) {
2351 s->WriteRef(array->untag()->element(j));
2352 }
2353 }
2354 }
2355
2357 objects_.Add(reinterpret_cast<Array*>(object));
2358
2359 for (intptr_t i = 0, n = object->value.as_array.length; i < n; i++) {
2360 s->Push(object->value.as_array.values[i]);
2361 }
2362 }
2363
2365 intptr_t count = objects_.length();
2366 s->WriteUnsigned(count);
2367 for (intptr_t i = 0; i < count; i++) {
2368 Dart_CObject* array = reinterpret_cast<Dart_CObject*>(objects_[i]);
2369 s->AssignRef(array);
2370 s->WriteUnsigned(array->value.as_array.length);
2371 }
2372 }
2373
2375 intptr_t count = objects_.length();
2376 for (intptr_t i = 0; i < count; i++) {
2377 Dart_CObject* array = reinterpret_cast<Dart_CObject*>(objects_[i]);
2378 intptr_t length = array->value.as_array.length;
2379 s->WriteRef(PredefinedCObjects::cobj_null()); // TypeArguments
2380 for (intptr_t j = 0; j < length; j++) {
2381 s->WriteRef(array->value.as_array.values[j]);
2382 }
2383 }
2384 }
2385
2386 private:
2387 GrowableArray<Array*> objects_;
2388};
2389
2392 public:
2396
2398 const intptr_t count = d->ReadUnsigned();
2399 for (intptr_t i = 0; i < count; i++) {
2400 intptr_t length = d->ReadUnsigned();
2401 d->AssignRef(Array::NewUninitialized(cid_, length));
2402 }
2403 }
2404
2406 for (intptr_t id = start_index_; id < stop_index_; id++) {
2407 ArrayPtr array = static_cast<ArrayPtr>(d->Ref(id));
2408 intptr_t length = Smi::Value(array->untag()->length());
2409 array->untag()->set_type_arguments(
2410 static_cast<TypeArgumentsPtr>(d->ReadRef()));
2411 for (intptr_t j = 0; j < length; j++) {
2412 array->untag()->set_element(j, d->ReadRef());
2413 }
2414 }
2415 }
2416
2418 if (is_canonical()) {
2420 d->isolate_group()->constant_canonicalization_mutex());
2421 Instance& instance = Instance::Handle(d->zone());
2422 for (intptr_t i = start_index_; i < stop_index_; i++) {
2423 instance ^= d->Ref(i);
2424 instance = instance.CanonicalizeLocked(d->thread());
2425 d->UpdateRef(i, instance);
2426 }
2427 }
2428 return nullptr;
2429 }
2430
2432 intptr_t count = d->ReadUnsigned();
2433 for (intptr_t i = 0; i < count; i++) {
2434 Dart_CObject* array = d->Allocate(Dart_CObject_kArray);
2435 intptr_t length = d->ReadUnsigned();
2436 array->value.as_array.length = length;
2437 if (length == 0) {
2438 array->value.as_array.values = nullptr;
2439 } else {
2440 array->value.as_array.values = d->zone()->Alloc<Dart_CObject*>(length);
2441 }
2442 d->AssignRef(array);
2443 }
2444 }
2445
2447 for (intptr_t id = start_index_; id < stop_index_; id++) {
2448 Dart_CObject* array = d->Ref(id);
2449 intptr_t length = array->value.as_array.length;
2450 d->ReadRef(); // type_arguments
2451 for (intptr_t i = 0; i < length; i++) {
2452 array->value.as_array.values[i] = d->ReadRef();
2453 }
2454 }
2455 }
2456
2457 private:
2458 const intptr_t cid_;
2459};
2460
2463 public:
2465 bool is_canonical)
2466 : MessageSerializationCluster("OneByteString",
2468 kOneByteStringCid,
2469 is_canonical),
2470 objects_(zone, 0) {}
2472
2474 String* str = static_cast<String*>(object);
2475 objects_.Add(str);
2476 }
2477
2479 const intptr_t count = objects_.length();
2480 s->WriteUnsigned(count);
2481 for (intptr_t i = 0; i < count; i++) {
2482 String* str = objects_[i];
2483 s->AssignRef(str);
2484 intptr_t length = str->Length();
2485 s->WriteUnsigned(length);
2486 NoSafepointScope no_safepoint;
2487 s->WriteBytes(OneByteString::DataStart(*str), length * sizeof(uint8_t));
2488 }
2489 }
2490
2492 objects_.Add(reinterpret_cast<String*>(object));
2493 }
2494
2496 intptr_t count = objects_.length();
2497 s->WriteUnsigned(count);
2498 for (intptr_t i = 0; i < count; i++) {
2499 Dart_CObject* str = reinterpret_cast<Dart_CObject*>(objects_[i]);
2500 s->AssignRef(str);
2501
2502 const uint8_t* utf8_str =
2503 reinterpret_cast<const uint8_t*>(str->value.as_string);
2504 intptr_t utf8_len = strlen(str->value.as_string);
2506 intptr_t latin1_len = Utf8::CodeUnitCount(utf8_str, utf8_len, &type);
2507
2508 uint8_t* latin1_str = reinterpret_cast<uint8_t*>(
2509 dart::malloc(latin1_len * sizeof(uint8_t)));
2510 bool success =
2511 Utf8::DecodeToLatin1(utf8_str, utf8_len, latin1_str, latin1_len);
2512 ASSERT(success);
2513 s->WriteUnsigned(latin1_len);
2514 s->WriteBytes(latin1_str, latin1_len);
2515 ::free(latin1_str);
2516 }
2517 }
2518
2519 private:
2520 GrowableArray<String*> objects_;
2521};
2522
2525 public:
2529
2531 const intptr_t count = d->ReadUnsigned();
2532 for (intptr_t i = 0; i < count; i++) {
2533 intptr_t length = d->ReadUnsigned();
2534 const uint8_t* data = d->CurrentBufferAddress();
2535 d->Advance(length * sizeof(uint8_t));
2536 d->AssignRef(is_canonical()
2537 ? Symbols::FromLatin1(d->thread(), data, length)
2539 }
2540 }
2541
2543 intptr_t count = d->ReadUnsigned();
2544 for (intptr_t i = 0; i < count; i++) {
2545 Dart_CObject* str = d->Allocate(Dart_CObject_kString);
2546 intptr_t latin1_length = d->ReadUnsigned();
2547 const uint8_t* data = d->CurrentBufferAddress();
2548
2549 d->Advance(latin1_length * sizeof(uint8_t));
2550
2551 intptr_t utf8_len = 0;
2552 for (intptr_t i = 0; i < latin1_length; i++) {
2553 utf8_len += Utf8::Length(data[i]);
2554 }
2555 char* utf8_data = d->zone()->Alloc<char>(utf8_len + 1);
2556 str->value.as_string = utf8_data;
2557 for (intptr_t i = 0; i < latin1_length; i++) {
2558 utf8_data += Utf8::Encode(data[i], utf8_data);
2559 }
2560 *utf8_data = '\0';
2561
2562 d->AssignRef(str);
2563 }
2564 }
2565};
2566
2569 public:
2571 bool is_canonical)
2572 : MessageSerializationCluster("TwoByteString",
2574 kTwoByteStringCid,
2575 is_canonical),
2576 objects_(zone, 0) {}
2578
2580 String* str = static_cast<String*>(object);
2581 objects_.Add(str);
2582 }
2583
2585 const intptr_t count = objects_.length();
2586 s->WriteUnsigned(count);
2587 for (intptr_t i = 0; i < count; i++) {
2588 String* str = objects_[i];
2589 s->AssignRef(str);
2590 intptr_t length = str->Length();
2591 s->WriteUnsigned(length);
2592 NoSafepointScope no_safepoint;
2593 uint16_t* utf16 = TwoByteString::DataStart(*str);
2594 s->WriteBytes(reinterpret_cast<const uint8_t*>(utf16),
2595 length * sizeof(uint16_t));
2596 }
2597 }
2598
2600 objects_.Add(reinterpret_cast<String*>(object));
2601 }
2602
2604 intptr_t count = objects_.length();
2605 s->WriteUnsigned(count);
2606 for (intptr_t i = 0; i < count; i++) {
2607 Dart_CObject* str = reinterpret_cast<Dart_CObject*>(objects_[i]);
2608 s->AssignRef(str);
2609
2610 const uint8_t* utf8_str =
2611 reinterpret_cast<const uint8_t*>(str->value.as_string);
2612 intptr_t utf8_len = strlen(str->value.as_string);
2614 intptr_t utf16_len = Utf8::CodeUnitCount(utf8_str, utf8_len, &type);
2615
2616 uint16_t* utf16_str = reinterpret_cast<uint16_t*>(
2617 dart::malloc(utf16_len * sizeof(uint16_t)));
2618 bool success =
2619 Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, utf16_len);
2620 ASSERT(success);
2621 s->WriteUnsigned(utf16_len);
2622 s->WriteBytes(reinterpret_cast<const uint8_t*>(utf16_str),
2623 utf16_len * sizeof(uint16_t));
2624 ::free(utf16_str);
2625 }
2626 }
2627
2628 private:
2629 GrowableArray<String*> objects_;
2630};
2631
2634 public:
2638
2640 const intptr_t count = d->ReadUnsigned();
2641 for (intptr_t i = 0; i < count; i++) {
2642 intptr_t length = d->ReadUnsigned();
2643 const uint16_t* data =
2644 reinterpret_cast<const uint16_t*>(d->CurrentBufferAddress());
2645 d->Advance(length * sizeof(uint16_t));
2646 d->AssignRef(is_canonical()
2647 ? Symbols::FromUTF16(d->thread(), data, length)
2649 }
2650 }
2651
2653 intptr_t count = d->ReadUnsigned();
2654 for (intptr_t j = 0; j < count; j++) {
2655 // Read all the UTF-16 code units.
2656 intptr_t utf16_length = d->ReadUnsigned();
2657 const uint16_t* utf16 =
2658 reinterpret_cast<const uint16_t*>(d->CurrentBufferAddress());
2659 d->Advance(utf16_length * sizeof(uint16_t));
2660
2661 // Calculate the UTF-8 length and check if the string can be
2662 // UTF-8 encoded.
2663 intptr_t utf8_len = 0;
2664 bool valid = true;
2665 intptr_t i = 0;
2666 while (i < utf16_length && valid) {
2667 int32_t ch = Utf16::Next(utf16, &i, utf16_length);
2668 utf8_len += Utf8::Length(ch);
2669 valid = !Utf16::IsSurrogate(ch);
2670 }
2671 if (!valid) {
2672 d->AssignRef(d->Allocate(Dart_CObject_kUnsupported));
2673 } else {
2674 Dart_CObject* str = d->Allocate(Dart_CObject_kString);
2675 char* utf8 = d->zone()->Alloc<char>(utf8_len + 1);
2676 str->value.as_string = utf8;
2677 i = 0;
2678 while (i < utf16_length) {
2679 utf8 += Utf8::Encode(Utf16::Next(utf16, &i, utf16_length), utf8);
2680 }
2681 *utf8 = '\0';
2682 d->AssignRef(str);
2683 }
2684 }
2685 }
2686};
2687
2688static constexpr intptr_t kFirstReference = 1;
2689static constexpr intptr_t kUnallocatedReference = -1;
2690
2692 : StackResource(thread),
2693 zone_(zone),
2694 stream_(100),
2695 finalizable_data_(new MessageFinalizableData()),
2696 clusters_(zone, 0),
2697 num_base_objects_(0),
2698 num_written_objects_(0),
2699 next_ref_index_(kFirstReference) {}
2700
2704
2706 : BaseSerializer(thread, thread->zone()),
2707 forward_table_new_(),
2708 forward_table_old_(),
2709 stack_(thread->zone(), 0) {
2712}
2713
2718
2720 : BaseSerializer(nullptr, zone), forward_table_(), stack_(zone, 0) {}
2721
2723
2725 if (MarkObjectId(object, kUnallocatedReference)) {
2726 stack_.Add(&Object::ZoneHandle(zone_, object));
2728 }
2729}
2730
2732 if (MarkObjectId(object, kUnallocatedReference)) {
2733 stack_.Add(object);
2735 }
2736}
2737
2738void MessageSerializer::Trace(const Object& root, Object* object) {
2739 intptr_t cid;
2740 bool is_canonical;
2741 if (!object->ptr()->IsHeapObject()) {
2742 cid = kSmiCid;
2743 is_canonical = true;
2744 } else {
2745 cid = object->GetClassId();
2746 is_canonical = object->ptr()->untag()->IsCanonical();
2747 }
2748
2749 MessageSerializationCluster* cluster = nullptr;
2751 if ((c->cid() == cid) && (c->is_canonical() == is_canonical)) {
2752 cluster = c;
2753 break;
2754 }
2755 }
2756 if (cluster == nullptr) {
2757 if (cid >= kNumPredefinedCids || cid == kInstanceCid) {
2758 // Will stomp over forward_table_new/old WeakTables, which should be ok,
2759 // as they are not going to be used again here.
2760 const char* message = OS::SCreate(
2761 zone_, "is a regular instance reachable via %s",
2762 FindRetainingPath(zone_, isolate(), root, *object,
2764 IllegalObject(*object, message);
2765 }
2766
2767 const char* illegal_cid_string = nullptr;
2768 // Keep the list in sync with the one in lib/isolate.cc,
2769 // vm/object_graph_copy.cc
2770#define ILLEGAL(type) \
2771 case k##type##Cid: \
2772 illegal_cid_string = #type; \
2773 break;
2774
2775 switch (cid) {
2792
2793 // From "dart:ffi" we handle only Pointer/DynamicLibrary specially, since
2794 // those are the only non-abstract classes (so we avoid checking more cids
2795 // here that cannot happen in reality)
2798
2799#undef ILLEGAL
2800 }
2801
2802 if (illegal_cid_string != nullptr) {
2803 // Will stomp over forward_table_new/old WeakTables, which should be ok,
2804 // as they are not going to be used again here.
2805 const char* message = OS::SCreate(
2806 zone_, "is a %s reachable via %s", illegal_cid_string,
2807 FindRetainingPath(zone_, isolate(), root, *object,
2809 IllegalObject(*object, message);
2810 }
2811
2812 cluster = NewClusterForClass(cid, is_canonical);
2813 clusters_.Add(cluster);
2814 }
2815
2816 cluster->Trace(this, object);
2817}
2818
2820 const bool is_canonical = false;
2821 intptr_t cid;
2822 switch (object->type) {
2823 case Dart_CObject_kNull:
2825 return true;
2826 case Dart_CObject_kBool:
2827 ForwardRef(object, object->value.as_bool ? &cobj_true : &cobj_false);
2828 return true;
2830 cid = Smi::IsValid(object->value.as_int32) ? kSmiCid : kMintCid;
2831 break;
2833 cid = Smi::IsValid(object->value.as_int64) ? kSmiCid : kMintCid;
2834 break;
2836 cid = kDoubleCid;
2837 break;
2838 case Dart_CObject_kString: {
2839 RELEASE_ASSERT(object->value.as_string != nullptr);
2840 const uint8_t* utf8_str =
2841 reinterpret_cast<const uint8_t*>(object->value.as_string);
2842 intptr_t utf8_len = strlen(object->value.as_string);
2843 if (!Utf8::IsValid(utf8_str, utf8_len)) {
2844 return Fail("invalid utf8");
2845 }
2847 intptr_t len = Utf8::CodeUnitCount(utf8_str, utf8_len, &type);
2848 if (len > String::kMaxElements) {
2849 return Fail("invalid string length");
2850 }
2851 cid = type == Utf8::kLatin1 ? kOneByteStringCid : kTwoByteStringCid;
2852 break;
2853 }
2855 cid = kArrayCid;
2856 if (!Array::IsValidLength(object->value.as_array.length)) {
2857 return Fail("invalid array length");
2858 }
2859 break;
2861 switch (object->value.as_typed_data.type) {
2863 cid = kTypedDataInt8ArrayCid;
2864 break;
2866 cid = kTypedDataUint8ArrayCid;
2867 break;
2869 cid = kTypedDataUint8ClampedArrayCid;
2870 break;
2872 cid = kTypedDataInt16ArrayCid;
2873 break;
2875 cid = kTypedDataUint16ArrayCid;
2876 break;
2878 cid = kTypedDataInt32ArrayCid;
2879 break;
2881 cid = kTypedDataUint32ArrayCid;
2882 break;
2884 cid = kTypedDataInt64ArrayCid;
2885 break;
2887 cid = kTypedDataUint64ArrayCid;
2888 break;
2890 cid = kTypedDataFloat32ArrayCid;
2891 break;
2893 cid = kTypedDataFloat64ArrayCid;
2894 break;
2896 cid = kTypedDataInt32x4ArrayCid;
2897 break;
2899 cid = kTypedDataFloat32x4ArrayCid;
2900 break;
2902 cid = kTypedDataFloat64x2ArrayCid;
2903 break;
2904 default:
2905 return Fail("invalid TypedData type");
2906 }
2907 {
2908 intptr_t len = object->value.as_typed_data.length;
2909 if (len < 0 || len > TypedData::MaxElements(cid)) {
2910 return Fail("invalid typeddata length");
2911 }
2912 }
2913 break;
2915 switch (object->value.as_external_typed_data.type) {
2917 cid = kExternalTypedDataInt8ArrayCid;
2918 break;
2920 cid = kExternalTypedDataUint8ArrayCid;
2921 break;
2923 cid = kExternalTypedDataUint8ClampedArrayCid;
2924 break;
2926 cid = kExternalTypedDataInt16ArrayCid;
2927 break;
2929 cid = kExternalTypedDataUint16ArrayCid;
2930 break;
2932 cid = kExternalTypedDataInt32ArrayCid;
2933 break;
2935 cid = kExternalTypedDataUint32ArrayCid;
2936 break;
2938 cid = kExternalTypedDataInt64ArrayCid;
2939 break;
2941 cid = kExternalTypedDataUint64ArrayCid;
2942 break;
2944 cid = kExternalTypedDataFloat32ArrayCid;
2945 break;
2947 cid = kExternalTypedDataFloat64ArrayCid;
2948 break;
2950 cid = kExternalTypedDataInt32x4ArrayCid;
2951 break;
2953 cid = kExternalTypedDataFloat32x4ArrayCid;
2954 break;
2956 cid = kExternalTypedDataFloat64x2ArrayCid;
2957 break;
2958 default:
2959 return Fail("invalid TypedData type");
2960 }
2961 {
2962 intptr_t len = object->value.as_typed_data.length;
2963 if (len < 0 || len > ExternalTypedData::MaxElements(cid)) {
2964 return Fail("invalid typeddata length");
2965 }
2966 }
2967 break;
2969 switch (object->value.as_external_typed_data.type) {
2971 cid = kUnmodifiableTypedDataInt8ArrayViewCid;
2972 break;
2974 cid = kUnmodifiableTypedDataUint8ArrayViewCid;
2975 break;
2977 cid = kUnmodifiableTypedDataUint8ClampedArrayViewCid;
2978 break;
2980 cid = kUnmodifiableTypedDataInt16ArrayViewCid;
2981 break;
2983 cid = kUnmodifiableTypedDataUint16ArrayViewCid;
2984 break;
2986 cid = kUnmodifiableTypedDataInt32ArrayViewCid;
2987 break;
2989 cid = kUnmodifiableTypedDataUint32ArrayViewCid;
2990 break;
2992 cid = kUnmodifiableTypedDataInt64ArrayViewCid;
2993 break;
2995 cid = kUnmodifiableTypedDataUint64ArrayViewCid;
2996 break;
2998 cid = kUnmodifiableTypedDataFloat32ArrayViewCid;
2999 break;
3001 cid = kUnmodifiableTypedDataFloat64ArrayViewCid;
3002 break;
3004 cid = kUnmodifiableTypedDataInt32x4ArrayViewCid;
3005 break;
3007 cid = kUnmodifiableTypedDataFloat32x4ArrayViewCid;
3008 break;
3010 cid = kUnmodifiableTypedDataFloat64x2ArrayViewCid;
3011 break;
3012 default:
3013 return Fail("invalid TypedData type");
3014 }
3015 {
3016 intptr_t len = object->value.as_typed_data.length;
3017 if (len < 0 || len > TypedData::MaxElements(
3020 return Fail("invalid typeddata length");
3021 }
3022 }
3023 break;
3025 cid = kSendPortCid;
3026 break;
3028 cid = kCapabilityCid;
3029 break;
3032 break;
3033 default:
3034 return Fail("invalid Dart_CObject type");
3035 }
3036
3037 MessageSerializationCluster* cluster = nullptr;
3039 if (c->cid() == cid) {
3040 cluster = c;
3041 break;
3042 }
3043 }
3044 if (cluster == nullptr) {
3045 cluster = NewClusterForClass(cid, is_canonical);
3046 clusters_.Add(cluster);
3047 }
3048
3049 cluster->TraceApi(this, object);
3050 return true;
3051}
3052
3054 const char* message) {
3055 const Array& args = Array::Handle(zone(), Array::New(3));
3056 args.SetAt(0, object);
3059}
3060
3062 : zone_(zone),
3063 stream_(message->snapshot(), message->snapshot_length()),
3064 finalizable_data_(message->finalizable_data()),
3065 next_ref_index_(kFirstReference) {}
3066
3068
3070 intptr_t cid,
3071 bool is_canonical) {
3072 Zone* Z = zone_;
3077 }
3080 }
3081 if (IsTypedDataClassId(cid)) {
3083 }
3084
3085 switch (cid) {
3086 case kNativePointer:
3088 case kClassCid:
3089 return new (Z) ClassMessageSerializationCluster();
3090 case kTypeArgumentsCid:
3091 return new (Z) TypeArgumentsMessageSerializationCluster(is_canonical);
3092 case kTypeCid:
3093 return new (Z) TypeMessageSerializationCluster(is_canonical);
3094 case kSmiCid:
3095 return new (Z) SmiMessageSerializationCluster(Z);
3096 case kMintCid:
3097 return new (Z) MintMessageSerializationCluster(Z, is_canonical);
3098 case kDoubleCid:
3099 return new (Z) DoubleMessageSerializationCluster(Z, is_canonical);
3100 case kGrowableObjectArrayCid:
3102 case kSendPortCid:
3104 case kCapabilityCid:
3106 case kTransferableTypedDataCid:
3108 case kMapCid:
3109 case kConstMapCid:
3110 return new (Z) MapMessageSerializationCluster(Z, is_canonical, cid);
3111 case kSetCid:
3112 case kConstSetCid:
3113 return new (Z) SetMessageSerializationCluster(Z, is_canonical, cid);
3114 case kArrayCid:
3115 case kImmutableArrayCid:
3116 return new (Z) ArrayMessageSerializationCluster(Z, is_canonical, cid);
3117 case kOneByteStringCid:
3118 return new (Z) OneByteStringMessageSerializationCluster(Z, is_canonical);
3119 case kTwoByteStringCid:
3120 return new (Z) TwoByteStringMessageSerializationCluster(Z, is_canonical);
3121 case kInt32x4Cid:
3122 case kFloat32x4Cid:
3123 case kFloat64x2Cid:
3125 default:
3126 break;
3127 }
3128
3129 FATAL("No cluster defined for cid %" Pd, cid);
3130 return nullptr;
3131}
3132
3134 uint64_t cid_and_canonical = (static_cast<uint64_t>(cluster->cid()) << 1) |
3135 (cluster->is_canonical() ? 0x1 : 0x0);
3136 WriteUnsigned(cid_and_canonical);
3137}
3138
3140 const uint64_t cid_and_canonical = ReadUnsigned();
3141 const intptr_t cid = (cid_and_canonical >> 1) & kMaxUint32;
3142 const bool is_canonical = (cid_and_canonical & 0x1) == 0x1;
3143
3144 Zone* Z = zone_;
3148 ASSERT(!is_canonical);
3150 }
3152 ASSERT(!is_canonical);
3154 }
3155 if (IsTypedDataClassId(cid)) {
3156 ASSERT(!is_canonical);
3158 }
3159
3160 switch (cid) {
3161 case kNativePointer:
3162 ASSERT(!is_canonical);
3164 case kClassCid:
3165 ASSERT(!is_canonical);
3167 case kTypeArgumentsCid:
3168 return new (Z) TypeArgumentsMessageDeserializationCluster(is_canonical);
3169 case kTypeCid:
3170 return new (Z) TypeMessageDeserializationCluster(is_canonical);
3171 case kSmiCid:
3172 ASSERT(is_canonical);
3173 return new (Z) SmiMessageDeserializationCluster();
3174 case kMintCid:
3175 return new (Z) MintMessageDeserializationCluster(is_canonical);
3176 case kDoubleCid:
3177 return new (Z) DoubleMessageDeserializationCluster(is_canonical);
3178 case kGrowableObjectArrayCid:
3179 ASSERT(!is_canonical);
3181 case kSendPortCid:
3182 ASSERT(!is_canonical);
3184 case kCapabilityCid:
3185 ASSERT(!is_canonical);
3187 case kTransferableTypedDataCid:
3188 ASSERT(!is_canonical);
3190 case kMapCid:
3191 case kConstMapCid:
3192 return new (Z) MapMessageDeserializationCluster(is_canonical, cid);
3193 case kSetCid:
3194 case kConstSetCid:
3195 return new (Z) SetMessageDeserializationCluster(is_canonical, cid);
3196 case kArrayCid:
3197 case kImmutableArrayCid:
3198 return new (Z) ArrayMessageDeserializationCluster(is_canonical, cid);
3199 case kOneByteStringCid:
3200 return new (Z) OneByteStringMessageDeserializationCluster(is_canonical);
3201 case kTwoByteStringCid:
3202 return new (Z) TwoByteStringMessageDeserializationCluster(is_canonical);
3203 case kInt32x4Cid:
3204 case kFloat32x4Cid:
3205 case kFloat64x2Cid:
3206 ASSERT(!is_canonical);
3208 default:
3209 break;
3210 }
3211
3212 FATAL("No cluster defined for cid %" Pd, cid);
3213 return nullptr;
3214}
3215
3218 AddBaseObject(Object::sentinel().ptr());
3219 AddBaseObject(Object::transition_sentinel().ptr());
3220 AddBaseObject(Object::empty_array().ptr());
3221 AddBaseObject(Object::dynamic_type().ptr());
3222 AddBaseObject(Object::void_type().ptr());
3223 AddBaseObject(Object::empty_type_arguments().ptr());
3224 AddBaseObject(Bool::True().ptr());
3225 AddBaseObject(Bool::False().ptr());
3226}
3227
3230 AddBaseObject(Object::sentinel().ptr());
3231 AddBaseObject(Object::transition_sentinel().ptr());
3232 AddBaseObject(Object::empty_array().ptr());
3233 AddBaseObject(Object::dynamic_type().ptr());
3234 AddBaseObject(Object::void_type().ptr());
3235 AddBaseObject(Object::empty_type_arguments().ptr());
3236 AddBaseObject(Bool::True().ptr());
3237 AddBaseObject(Bool::False().ptr());
3238}
3239
3251
3263
3266
3267 Push(root.ptr());
3268
3269 while (stack_.length() > 0) {
3270 Trace(root, stack_.RemoveLast());
3271 }
3272
3273 intptr_t num_objects = num_base_objects_ + num_written_objects_;
3275 WriteUnsigned(num_objects);
3276
3277 for (intptr_t i = 0; i < static_cast<intptr_t>(MessagePhase::kNumPhases);
3278 i++) {
3279 intptr_t num_clusters = 0;
3280 for (MessageSerializationCluster* cluster : clusters_) {
3281 if (static_cast<intptr_t>(cluster->phase()) != i) continue;
3282 num_clusters++;
3283 }
3284 WriteUnsigned(num_clusters);
3285 for (MessageSerializationCluster* cluster : clusters_) {
3286 if (static_cast<intptr_t>(cluster->phase()) != i) continue;
3287 WriteCluster(cluster);
3288 cluster->WriteNodes(this);
3289 }
3290 for (MessageSerializationCluster* cluster : clusters_) {
3291 if (static_cast<intptr_t>(cluster->phase()) != i) continue;
3292 cluster->WriteEdges(this);
3293 }
3294 }
3295
3296 // We should have assigned a ref to every object we pushed.
3297 ASSERT((next_ref_index_ - 1) == num_objects);
3298
3299 WriteRef(root.ptr());
3300}
3301
3304
3305 Push(root);
3306
3307 // Strong references only.
3308 while (stack_.length() > 0) {
3309 if (!Trace(stack_.RemoveLast())) {
3310 return false;
3311 }
3312 }
3313
3314 intptr_t num_objects = num_base_objects_ + num_written_objects_;
3316 WriteUnsigned(num_objects);
3317
3318 for (intptr_t i = 0; i < static_cast<intptr_t>(MessagePhase::kNumPhases);
3319 i++) {
3320 intptr_t num_clusters = 0;
3321 for (MessageSerializationCluster* cluster : clusters_) {
3322 if (static_cast<intptr_t>(cluster->phase()) != i) continue;
3323 num_clusters++;
3324 }
3325 WriteUnsigned(num_clusters);
3326 for (MessageSerializationCluster* cluster : clusters_) {
3327 if (static_cast<intptr_t>(cluster->phase()) != i) continue;
3328 WriteCluster(cluster);
3329 cluster->WriteNodesApi(this);
3330 }
3331 for (MessageSerializationCluster* cluster : clusters_) {
3332 if (static_cast<intptr_t>(cluster->phase()) != i) continue;
3333 cluster->WriteEdgesApi(this);
3334 }
3335 }
3336
3337 // We should have assigned a ref to every object we pushed.
3338 ASSERT((next_ref_index_ - 1) == num_objects);
3339
3340 WriteRef(root);
3341 return true;
3342}
3343
3345 intptr_t num_base_objects = ReadUnsigned();
3346 intptr_t num_objects = ReadUnsigned();
3347
3348 refs_ = Array::New(num_objects + kFirstReference);
3349
3351
3352 // Writer and reader must agree on number of base objects.
3353 ASSERT_EQUAL(num_base_objects, (next_ref_index_ - kFirstReference));
3354
3356 for (intptr_t i = 0; i < static_cast<intptr_t>(MessagePhase::kNumPhases);
3357 i++) {
3358 intptr_t num_clusters = ReadUnsigned();
3360 zone()->Alloc<MessageDeserializationCluster*>(num_clusters);
3361 for (intptr_t i = 0; i < num_clusters; i++) {
3362 clusters[i] = ReadCluster();
3363 clusters[i]->ReadNodesWrapped(this);
3364 }
3365 for (intptr_t i = 0; i < num_clusters; i++) {
3366 clusters[i]->ReadEdges(this);
3367 }
3368 for (intptr_t i = 0; i < num_clusters; i++) {
3369 error = clusters[i]->PostLoad(this);
3370 if (error.IsError()) {
3371 return error.ptr(); // E.g., an UnwindError during rehashing.
3372 }
3373 }
3374 }
3375
3376 // We should have completely filled the ref array.
3378
3379 return ReadRef();
3380}
3381
3383 intptr_t num_base_objects = ReadUnsigned();
3384 intptr_t num_objects = ReadUnsigned();
3385
3386 refs_ = zone()->Alloc<Dart_CObject*>(num_objects + kFirstReference);
3387
3389
3390 // Writer and reader must agree on number of base objects.
3391 ASSERT_EQUAL(num_base_objects, (next_ref_index_ - kFirstReference));
3392
3393 for (intptr_t i = 0; i < static_cast<intptr_t>(MessagePhase::kNumPhases);
3394 i++) {
3395 intptr_t num_clusters = ReadUnsigned();
3397 zone()->Alloc<MessageDeserializationCluster*>(num_clusters);
3398 for (intptr_t i = 0; i < num_clusters; i++) {
3399 clusters[i] = ReadCluster();
3400 clusters[i]->ReadNodesWrappedApi(this);
3401 }
3402 for (intptr_t i = 0; i < num_clusters; i++) {
3403 clusters[i]->ReadEdgesApi(this);
3404 }
3405 for (intptr_t i = 0; i < num_clusters; i++) {
3406 clusters[i]->PostLoadApi(this);
3407 }
3408 }
3409
3410 // We should have completely filled the ref array.
3412
3413 return ReadRef();
3414}
3415
3416std::unique_ptr<Message> WriteMessage(bool same_group,
3417 const Object& obj,
3418 Dart_Port dest_port,
3419 Message::Priority priority) {
3421 return Message::New(dest_port, obj.ptr(), priority);
3422 } else if (same_group) {
3424 auto handle =
3426 handle->set_ptr(copy.ptr());
3427 return std::make_unique<Message>(dest_port, handle, priority);
3428 }
3429
3430 Thread* thread = Thread::Current();
3431 MessageSerializer serializer(thread);
3432 serializer.Serialize(obj);
3433 return serializer.Finish(dest_port, priority);
3434}
3435
3436std::unique_ptr<Message> WriteApiMessage(Zone* zone,
3437 Dart_CObject* obj,
3438 Dart_Port dest_port,
3439 Message::Priority priority) {
3440 ApiMessageSerializer serializer(zone);
3441 if (!serializer.Serialize(obj)) {
3442 return nullptr;
3443 }
3444 return serializer.Finish(dest_port, priority);
3445}
3446
3448 // msg_array = [
3449 // <message>,
3450 // <collection-lib-objects-to-rehash>,
3451 // <core-lib-objects-to-rehash>,
3452 // ]
3453 Zone* zone = thread->zone();
3454 Object& msg_obj = Object::Handle(zone);
3455 const auto& msg_array = Array::Handle(zone, Array::RawCast(handle->ptr()));
3456 ASSERT(msg_array.Length() == 3);
3457 msg_obj = msg_array.At(0);
3458 if (msg_array.At(1) != Object::null()) {
3459 const auto& objects_to_rehash = Object::Handle(zone, msg_array.At(1));
3460 auto& result = Object::Handle(zone);
3462 objects_to_rehash);
3463 if (result.ptr() != Object::null()) {
3464 msg_obj = result.ptr();
3465 }
3466 }
3467 if (msg_array.At(2) != Object::null()) {
3468 const auto& objects_to_rehash = Object::Handle(zone, msg_array.At(2));
3469 auto& result = Object::Handle(zone);
3470 result =
3471 DartLibraryCalls::RehashObjectsInDartCore(thread, objects_to_rehash);
3472 if (result.ptr() != Object::null()) {
3473 msg_obj = result.ptr();
3474 }
3475 }
3476 return msg_obj.ptr();
3477}
3478
3480 if (message->IsRaw()) {
3481 return message->raw_obj();
3482 } else if (message->IsFinalizerInvocationRequest()) {
3483 PersistentHandle* handle = message->persistent_handle();
3484 Object& msg_obj = Object::Handle(thread->zone(), handle->ptr());
3485 ASSERT(msg_obj.IsFinalizer() || msg_obj.IsNativeFinalizer());
3486 return msg_obj.ptr();
3487 } else if (message->IsPersistentHandle()) {
3488 return ReadObjectGraphCopyMessage(thread, message->persistent_handle());
3489 } else {
3490 RELEASE_ASSERT(message->IsSnapshot());
3491 LongJumpScope jump(thread);
3492 if (setjmp(*jump.Set()) == 0) {
3493 MessageDeserializer deserializer(thread, message);
3494 return deserializer.Deserialize();
3495 } else {
3496 return thread->StealStickyError();
3497 }
3498 }
3499}
3500
3502 if (message->IsRaw()) {
3505 return result;
3506 } else {
3507 RELEASE_ASSERT(message->IsSnapshot());
3508 ApiMessageDeserializer deserializer(zone, message);
3509 return deserializer.Deserialize();
3510 }
3511}
3512
3513} // namespace dart
int count
static uint32_t hash(const SkShaderBase::GradientInfo &v)
SI F table(const skcms_Curve *curve, F v)
static size_t element_size(Layout layout, SkSLType type)
#define UNREACHABLE()
Definition assert.h:248
#define ASSERT_EQUAL(expected, actual)
Definition assert.h:309
#define RELEASE_ASSERT(cond)
Definition assert.h:327
#define Z
ApiMessageDeserializer(Zone *zone, Message *message)
Dart_CObject * Allocate(Dart_CObject_Type type)
void AssignRef(Dart_CObject *object)
void AddBaseObject(Dart_CObject *base_object)
Dart_CObject * Ref(intptr_t index) const
void ForwardRef(Dart_CObject *old, Dart_CObject *nue)
void Push(Dart_CObject *object)
intptr_t GetObjectId(Dart_CObject *object) const
DART_NOINLINE intptr_t AssignRef(Dart_CObject *object)
bool Serialize(Dart_CObject *root)
void SetObjectId(Dart_CObject *object, intptr_t id)
void WriteRef(Dart_CObject *object)
bool Fail(const char *message)
DART_NOINLINE void AddBaseObject(Dart_CObject *base_object)
bool Trace(Dart_CObject *object)
bool MarkObjectId(Dart_CObject *object, intptr_t id)
static bool Convert(const ObjectPtr raw_obj, Dart_CObject *c_obj)
static bool CanConvert(const ObjectPtr raw_obj)
PersistentHandle * AllocatePersistentHandle()
void ReadEdgesApi(ApiMessageDeserializer *d)
ArrayMessageDeserializationCluster(bool is_canonical, intptr_t cid)
ObjectPtr PostLoad(MessageDeserializer *d)
void ReadNodesApi(ApiMessageDeserializer *d)
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
void WriteEdgesApi(ApiMessageSerializer *s)
void WriteNodesApi(ApiMessageSerializer *s)
ArrayMessageSerializationCluster(Zone *zone, bool is_canonical, intptr_t cid)
void Trace(MessageSerializer *s, Object *object)
ArrayPtr Slice(intptr_t start, intptr_t count, bool with_type_argument) const
Definition object.cc:24889
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
static constexpr bool IsValidLength(intptr_t len)
Definition object.h:10906
ObjectPtr At(intptr_t index) const
Definition object.h:10854
intptr_t Length() const
Definition object.h:10808
static ArrayPtr NewUninitialized(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10938
void SetAt(intptr_t index, const Object &value) const
Definition object.h:10858
void Advance(intptr_t value)
MessageDeserializationCluster * ReadCluster()
const uint8_t * CurrentBufferAddress() const
MessageFinalizableData * finalizable_data_
intptr_t next_index() const
BaseDeserializer(Zone *zone, Message *message)
void ReadBytes(void *addr, intptr_t len)
MessageFinalizableData * finalizable_data() const
BaseSerializer(Thread *thread, Zone *zone)
GrowableArray< MessageSerializationCluster * > clusters_
void WriteBytes(const void *addr, intptr_t len)
intptr_t next_ref_index() const
MessageSerializationCluster * NewClusterForClass(intptr_t cid, bool is_canonical)
MessageFinalizableData * finalizable_data_
void WriteCluster(MessageSerializationCluster *cluster)
std::unique_ptr< Message > Finish(Dart_Port dest_port, Message::Priority priority)
void WriteUnsigned(intptr_t value)
MallocWriteStream stream_
void WriteAscii(const String &str)
MessageFinalizableData * finalizable_data() const
void WriteWordWith32BitWrites(uword value)
void WriteBytes(const void *addr, intptr_t len)
Definition datastream.h:424
void WriteWordWith32BitWrites(uword value)
Definition datastream.h:389
void WriteUnsigned(T value)
Definition datastream.h:400
static const Bool & False()
Definition object.h:10778
static const Bool & True()
Definition object.h:10776
void Trace(MessageSerializer *s, Object *object)
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
static CapabilityPtr New(uint64_t id, Heap::Space space=Heap::kNew)
Definition object.cc:25852
static AbstractTypePtr FinalizeType(const AbstractType &type, FinalizationKind finalization=kCanonicalize)
void ReadNodesApi(ApiMessageDeserializer *d)
void Trace(MessageSerializer *s, Object *object)
LibraryPtr library() const
Definition object.h:1335
intptr_t id() const
Definition object.h:1235
StringPtr Name() const
Definition object.cc:3038
ErrorPtr EnsureIsFinalized(Thread *thread) const
Definition object.cc:4979
static ObjectPtr RehashObjectsInDartCollection(Thread *thread, const Object &array_or_growable_array)
static ObjectPtr RehashObjectsInDartCore(Thread *thread, const Object &array_or_growable_array)
void ReadNodesApi(ApiMessageDeserializer *d)
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
void WriteNodesApi(ApiMessageSerializer *s)
void Trace(MessageSerializer *s, Object *object)
DoubleMessageSerializationCluster(Zone *zone, bool is_canonical)
static DoublePtr New(double d, Heap::Space space=Heap::kNew)
Definition object.cc:23481
static DoublePtr NewCanonical(double d)
Definition object.cc:23497
static DART_NORETURN void ThrowByType(ExceptionType type, const Array &arguments)
ExternalTypedDataMessageSerializationCluster(Zone *zone, intptr_t cid)
void Trace(MessageSerializer *s, Object *object)
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
static ExternalTypedDataPtr New(intptr_t class_id, uint8_t *data, intptr_t len, Heap::Space space=Heap::kNew, bool perform_eager_msan_initialization_check=true)
Definition object.cc:25705
static intptr_t MaxElements(intptr_t class_id)
Definition object.h:11718
void EnsureFreedExternal(IsolateGroup *isolate_group)
static intptr_t value_offset()
Definition object.h:11171
static intptr_t value_offset()
Definition object.h:11240
void Trace(MessageSerializer *s, Object *object)
void SetLength(intptr_t value) const
Definition object.h:11050
static GrowableObjectArrayPtr New(Heap::Space space=Heap::kNew)
Definition object.h:11118
intptr_t Length() const
Definition object.h:11046
ObjectPtr At(intptr_t index) const
Definition object.h:11059
ArrayPtr data() const
Definition object.h:11056
@ kNew
Definition heap.h:38
static intptr_t InstanceSize()
Definition object.h:11205
static intptr_t value_offset()
Definition object.h:11209
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition object.cc:23063
static IsolateGroup * Current()
Definition isolate.h:534
ApiState * api_state() const
Definition isolate.h:693
void set_forward_table_old(WeakTable *table)
Definition isolate.cc:2516
void set_forward_table_new(WeakTable *table)
Definition isolate.cc:2512
WeakTable * forward_table_old()
Definition isolate.h:1414
WeakTable * forward_table_new()
Definition isolate.h:1411
ClassPtr toplevel_class() const
Definition object.h:5179
ClassPtr LookupClass(const String &name) const
Definition object.cc:14152
static LibraryPtr LookupLibrary(Thread *thread, const String &url)
Definition object.cc:14646
StringPtr url() const
Definition object.h:5068
jmp_buf * Set()
Definition longjump.cc:16
uint8_t * Steal(intptr_t *length)
Definition datastream.h:633
ObjectPtr PostLoad(MessageDeserializer *d)
void ReadEdges(MessageDeserializer *d)
MapMessageDeserializationCluster(bool is_canonical, intptr_t cid)
void ReadNodes(MessageDeserializer *d)
void WriteEdges(MessageSerializer *s)
void Trace(MessageSerializer *s, Object *object)
void WriteNodes(MessageSerializer *s)
MapMessageSerializationCluster(Zone *zone, bool is_canonical, intptr_t cid)
virtual void ReadNodesApi(ApiMessageDeserializer *d)
MessageDeserializationCluster(const char *name, bool is_canonical=false)
void ReadNodesWrappedApi(ApiMessageDeserializer *d)
virtual void ReadEdgesApi(ApiMessageDeserializer *d)
void ReadNodesWrapped(MessageDeserializer *d)
ObjectPtr PostLoadAbstractType(MessageDeserializer *d)
virtual void PostLoadApi(ApiMessageDeserializer *d)
DISALLOW_COPY_AND_ASSIGN(MessageDeserializationCluster)
ObjectPtr PostLoadLinkedHash(MessageDeserializer *d)
virtual ObjectPtr PostLoad(MessageDeserializer *d)
virtual void ReadEdges(MessageDeserializer *d)
virtual void ReadNodes(MessageDeserializer *d)=0
IsolateGroup * isolate_group() const
MessageDeserializer(Thread *thread, Message *message)
void AssignRef(ObjectPtr object)
DART_NOINLINE void AddBaseObject(ObjectPtr base_object)
ObjectPtr Ref(intptr_t index) const
void UpdateRef(intptr_t index, const Object &new_object)
virtual void WriteEdgesApi(ApiMessageSerializer *s)
virtual void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
DISALLOW_COPY_AND_ASSIGN(MessageSerializationCluster)
MessageSerializationCluster(const char *name, MessagePhase phase, intptr_t cid, bool is_canonical=false)
virtual void WriteEdges(MessageSerializer *s)
virtual void Trace(MessageSerializer *s, Object *object)=0
virtual void WriteNodes(MessageSerializer *s)=0
virtual void WriteNodesApi(ApiMessageSerializer *s)
bool HasRef(ObjectPtr object) const
intptr_t GetObjectId(ObjectPtr object) const
DART_NOINLINE void AddBaseObject(ObjectPtr base_object)
IsolateGroup * isolate_group() const
DART_NOINLINE void WriteRef(ObjectPtr object)
bool MarkObjectId(ObjectPtr object, intptr_t id)
MessageSerializer(Thread *thread)
DART_NOINLINE void AssignRef(ObjectPtr object)
void Push(ObjectPtr object)
void Serialize(const Object &root)
void AssignRef(Object *object)
void Trace(const Object &root, Object *object)
void SetObjectId(ObjectPtr object, intptr_t id)
void IllegalObject(const Object &object, const char *message)
static std::unique_ptr< Message > New(Args &&... args)
Definition message.h:72
void ReadNodes(MessageDeserializer *d)
void ReadNodesApi(ApiMessageDeserializer *d)
void WriteNodes(MessageSerializer *s)
void Trace(MessageSerializer *s, Object *object)
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
MintMessageSerializationCluster(Zone *zone, bool is_canonical)
void WriteNodesApi(ApiMessageSerializer *s)
static MintPtr NewCanonical(int64_t value)
Definition object.cc:23393
int64_t value() const
Definition object.h:10052
static MintPtr New(int64_t value, Heap::Space space=Heap::kNew)
Definition object.cc:23383
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
void Trace(MessageSerializer *s, Object *object)
static char * SCreate(Zone *zone, const char *format,...) PRINTF_ATTRIBUTE(2
UntaggedObject * untag() const
static ObjectPtr Allocate(intptr_t cls_id, intptr_t size, Heap::Space space, bool compressed, uword ptr_field_start_offset, uword ptr_field_end_offset)
Definition object.cc:2820
static ObjectPtr null()
Definition object.h:433
ObjectPtr ptr() const
Definition object.h:332
static constexpr bool ContainsCompressedPointers()
Definition object.h:329
bool IsNull() const
Definition object.h:363
static Object & Handle()
Definition object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition object.h:325
static Object & ZoneHandle()
Definition object.h:419
OneByteStringMessageSerializationCluster(Zone *zone, bool is_canonical)
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
void Trace(MessageSerializer *s, Object *object)
void set_ptr(ObjectPtr ref)
ObjectPtr ptr() const
static Dart_CObject * cobj_empty_array()
static Dart_CObject * cobj_null()
static PredefinedCObjects & getInstance()
uword ReadWordWith32BitReads()
Definition datastream.h:157
const uint8_t * AddressOfCurrentPosition() const
Definition datastream.h:140
void Advance(intptr_t value)
Definition datastream.h:142
void ReadBytes(void *addr, intptr_t len)
Definition datastream.h:90
void ReadNodesApi(ApiMessageDeserializer *d)
void WriteNodesApi(ApiMessageSerializer *s)
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
void Trace(MessageSerializer *s, Object *object)
static SendPortPtr New(Dart_Port id, Heap::Space space=Heap::kNew)
Definition object.cc:25891
ObjectPtr PostLoad(MessageDeserializer *d)
void ReadEdges(MessageDeserializer *d)
SetMessageDeserializationCluster(bool is_canonical, intptr_t cid)
void ReadNodes(MessageDeserializer *d)
void Trace(MessageSerializer *s, Object *object)
void WriteNodes(MessageSerializer *s)
SetMessageSerializationCluster(Zone *zone, bool is_canonical, intptr_t cid)
void WriteEdges(MessageSerializer *s)
void Trace(MessageSerializer *s, Object *object)
void ReadNodes(MessageDeserializer *d)
void ReadNodesApi(ApiMessageDeserializer *d)
void Trace(MessageSerializer *s, Object *object)
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
void WriteNodesApi(ApiMessageSerializer *s)
void WriteNodes(MessageSerializer *s)
static SmiPtr New(intptr_t value)
Definition object.h:9985
intptr_t Value() const
Definition object.h:9969
static bool IsValid(int64_t value)
Definition object.h:10005
ThreadState * thread() const
Definition allocation.h:33
static StringPtr FromLatin1(const uint8_t *latin1_array, intptr_t array_len, Heap::Space space=Heap::kNew)
Definition object.cc:23812
static constexpr intptr_t kMaxElements
Definition object.h:10152
intptr_t Length() const
Definition object.h:10189
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition object.cc:23777
uint16_t CharAt(intptr_t index) const
Definition object.h:10238
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition object.cc:24205
static StringPtr FromUTF16(const uint16_t *utf16_array, intptr_t array_len, Heap::Space space=Heap::kNew)
Definition object.cc:23818
static StringPtr FromUTF16(Thread *thread, const uint16_t *utf16_array, intptr_t len)
Definition symbols.cc:229
static StringPtr FromLatin1(Thread *thread, const uint8_t *latin1_array, intptr_t len)
Definition symbols.cc:223
Zone * zone() const
static Thread * Current()
Definition thread.h:361
DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError()
Definition thread.cc:243
Isolate * isolate() const
Definition thread.h:533
IsolateGroup * isolate_group() const
Definition thread.h:540
void Trace(MessageSerializer *s, Object *object)
FinalizablePersistentHandle * handle() const
Definition object.h:12497
static TransferableTypedDataPtr New(uint8_t *data, intptr_t len)
Definition object.cc:25914
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
void Trace(MessageSerializer *s, Object *object)
TwoByteStringMessageSerializationCluster(Zone *zone, bool is_canonical)
void Trace(MessageSerializer *s, Object *object)
intptr_t nullability() const
Definition object.cc:7359
TypeArgumentsPtr Canonicalize(Thread *thread) const
Definition object.cc:7761
static TypeArgumentsPtr New(intptr_t len, Heap::Space space=Heap::kOld)
Definition object.cc:7733
void ReadEdgesApi(ApiMessageDeserializer *d)
void ReadEdges(MessageDeserializer *d)
void ReadNodesApi(ApiMessageDeserializer *d)
ObjectPtr PostLoad(MessageDeserializer *d)
void ReadNodes(MessageDeserializer *d)
void Trace(MessageSerializer *s, Object *object)
void WriteNodes(MessageSerializer *s)
void WriteEdges(MessageSerializer *s)
static CodePtr DefaultCodeForType(const AbstractType &type, bool lazy_specialize=true)
static TypePtr New(const Class &clazz, const TypeArguments &arguments, Nullability nullability=Nullability::kLegacy, Heap::Space space=Heap::kOld)
Definition object.cc:22492
SmiPtr length() const
Definition object.h:11490
intptr_t ElementSizeInBytes() const
Definition object.h:11505
void ReadNodesApi(ApiMessageDeserializer *d)
TypedDataMessageSerializationCluster(Zone *zone, intptr_t cid)
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
void Trace(MessageSerializer *s, Object *object)
void WriteNodesApi(ApiMessageSerializer *s)
TypedDataViewMessageSerializationCluster(Zone *zone, intptr_t cid)
void Trace(MessageSerializer *s, Object *object)
void TraceApi(ApiMessageSerializer *s, Dart_CObject *object)
static TypedDataViewPtr New(intptr_t class_id, Heap::Space space=Heap::kNew)
Definition object.cc:25737
TypedDataBasePtr typed_data() const
Definition object.h:11794
SmiPtr offset_in_bytes() const
Definition object.h:11809
static intptr_t MaxElements(intptr_t class_id)
Definition object.h:11658
static TypedDataPtr New(intptr_t class_id, intptr_t len, Heap::Space space=Heap::kNew)
Definition object.cc:25666
static bool IsSurrogate(uint32_t ch)
Definition unicode.h:123
static int32_t Next(const uint16_t *characters, intptr_t *i, intptr_t len)
Definition unicode.h:137
static intptr_t Length(int32_t ch)
Definition unicode.cc:98
static intptr_t CodeUnitCount(const uint8_t *utf8_array, intptr_t array_len, Type *type)
Definition unicode.cc:46
static bool IsValid(const uint8_t *utf8_array, intptr_t array_len)
Definition unicode.cc:70
static bool DecodeToUTF16(const uint8_t *utf8_array, intptr_t array_len, uint16_t *dst, intptr_t len)
Definition unicode.cc:217
static bool DecodeToLatin1(const uint8_t *utf8_array, intptr_t array_len, uint8_t *dst, intptr_t len)
Definition unicode.cc:194
static intptr_t Encode(int32_t ch, char *dst)
Definition unicode.cc:110
static constexpr intptr_t kNoValue
Definition weak_table.h:18
bool MarkValueExclusive(ObjectPtr key, intptr_t val)
Definition weak_table.cc:78
void SetValueExclusive(ObjectPtr key, intptr_t val)
Definition weak_table.cc:33
intptr_t GetValueExclusive(ObjectPtr key) const
Definition weak_table.h:109
ElementType * Alloc(intptr_t length)
int64_t Dart_Port
Definition dart_api.h:1524
Dart_TypedData_Type
Definition dart_api.h:2603
@ Dart_TypedData_kFloat32x4
Definition dart_api.h:2617
@ Dart_TypedData_kInt32x4
Definition dart_api.h:2616
@ Dart_TypedData_kUint8
Definition dart_api.h:2606
@ Dart_TypedData_kUint32
Definition dart_api.h:2611
@ Dart_TypedData_kInt32
Definition dart_api.h:2610
@ Dart_TypedData_kUint16
Definition dart_api.h:2609
@ Dart_TypedData_kFloat64x2
Definition dart_api.h:2618
@ Dart_TypedData_kUint64
Definition dart_api.h:2613
@ Dart_TypedData_kFloat32
Definition dart_api.h:2614
@ Dart_TypedData_kInt16
Definition dart_api.h:2608
@ Dart_TypedData_kFloat64
Definition dart_api.h:2615
@ Dart_TypedData_kUint8Clamped
Definition dart_api.h:2607
@ Dart_TypedData_kInt8
Definition dart_api.h:2605
@ Dart_TypedData_kInt64
Definition dart_api.h:2612
Dart_CObject_Type
@ Dart_CObject_kInt64
@ Dart_CObject_kNativePointer
@ Dart_CObject_kDouble
@ Dart_CObject_kUnmodifiableExternalTypedData
@ Dart_CObject_kTypedData
@ Dart_CObject_kSendPort
@ Dart_CObject_kString
@ Dart_CObject_kArray
@ Dart_CObject_kUnsupported
@ Dart_CObject_kNull
@ Dart_CObject_kExternalTypedData
@ Dart_CObject_kInt32
@ Dart_CObject_kBool
@ Dart_CObject_kCapability
#define ASSERT(E)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
VkInstance instance
Definition main.cc:48
struct MyStruct s
#define FATAL(error)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
size_t length
Win32Message message
#define ILLEGAL(type)
Definition copy.py:1
bool IsTypedDataViewClassId(intptr_t index)
Definition class_id.h:439
bool IsTypedDataClassId(intptr_t index)
Definition class_id.h:433
@ kExternalBetweenIsolateGroups
ObjectPtr ReadMessage(Thread *thread, Message *message)
static Dart_CObject cobj_transition_sentinel
const int kTypedDataCidRemainderUnmodifiable
Definition class_id.h:264
Nullability
Definition object.h:1112
ObjectPtr ReadObjectGraphCopyMessage(Thread *thread, PersistentHandle *handle)
const char * FindRetainingPath(Zone *zone_, Isolate *isolate, const Object &from, const Object &to, TraversalRules traversal_rules)
constexpr int32_t kMinInt32
Definition globals.h:482
static Dart_CObject cobj_empty_type_arguments
void * malloc(size_t size)
Definition allocation.cc:19
static Dart_CObject cobj_true
const int kTypedDataCidRemainderInternal
Definition class_id.h:261
ObjectPtr CopyMutableObjectGraph(const Object &object)
bool IsUnmodifiableTypedDataViewClassId(intptr_t index)
Definition class_id.h:453
@ kNumPredefinedCids
Definition class_id.h:257
@ kNativePointer
Definition class_id.h:218
@ kByteDataViewCid
Definition class_id.h:244
@ kUnmodifiableByteDataViewCid
Definition class_id.h:245
constexpr uint32_t kMaxUint32
Definition globals.h:484
static constexpr intptr_t kUnallocatedReference
uintptr_t uword
Definition globals.h:501
static Dart_CObject cobj_false
const int kTypedDataCidRemainderExternal
Definition class_id.h:263
static Dart_CObject cobj_dynamic_type
Dart_CObject * ReadApiMessage(Zone *zone, Message *message)
static void IsolateMessageTypedDataFinalizer(void *isolate_callback_data, void *buffer)
const intptr_t cid
raw_obj untag() -> num_entries()) VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->untag() ->length())) VARIABLE_COMPRESSED_VISITOR(TypedData, TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *Smi::Value(raw_obj->untag() ->length())) VARIABLE_COMPRESSED_VISITOR(Record, RecordShape(raw_obj->untag() ->shape()).num_fields()) VARIABLE_NULL_VISITOR(CompressedStackMaps, CompressedStackMaps::PayloadSizeOf(raw_obj)) VARIABLE_NULL_VISITOR(OneByteString, Smi::Value(raw_obj->untag() ->length())) VARIABLE_NULL_VISITOR(TwoByteString, Smi::Value(raw_obj->untag() ->length())) intptr_t UntaggedField::VisitFieldPointers(FieldPtr raw_obj, ObjectPointerVisitor *visitor)
@ kTypedDataViewFromDart
static constexpr intptr_t kFirstReference
std::unique_ptr< Message > WriteMessage(bool same_group, const Object &obj, Dart_Port dest_port, Message::Priority priority)
constexpr int32_t kMaxInt32
Definition globals.h:483
std::unique_ptr< Message > WriteApiMessage(Zone *zone, Dart_CObject *obj, Dart_Port dest_port, Message::Priority priority)
static Dart_CObject cobj_void_type
static Dart_CObject cobj_sentinel
static int8_t data[kExtLength]
bool IsExternalTypedDataClassId(intptr_t index)
Definition class_id.h:447
#define UNLIKELY(cond)
Definition globals.h:261
#define Pd
Definition globals.h:408
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
#define T
union _Dart_CObject::@86 value
Dart_CObject_Type type
struct _Dart_CObject::@86::@88 as_capability
struct _Dart_CObject::@86::@90 as_typed_data
const char * as_string
struct _Dart_CObject::@86::@91 as_external_typed_data
struct _Dart_CObject::@86::@89 as_array
struct _Dart_CObject ** values
Dart_HandleFinalizer callback