@@ -167,7 +167,8 @@ class SerializationCluster : public ZoneAllocated {
167
167
: name_(name),
168
168
cid_(cid),
169
169
target_instance_size_(target_instance_size),
170
- is_canonical_(is_canonical) {
170
+ is_canonical_(is_canonical),
171
+ is_immutable_(Object::ShouldHaveImmutabilityBitSet(cid)) {
171
172
ASSERT (target_instance_size == kSizeVaries || target_instance_size >= 0 );
172
173
}
173
174
virtual ~SerializationCluster () {}
@@ -189,6 +190,7 @@ class SerializationCluster : public ZoneAllocated {
189
190
const char * name () const { return name_; }
190
191
intptr_t cid () const { return cid_; }
191
192
bool is_canonical () const { return is_canonical_; }
193
+ bool is_immutable () const { return is_immutable_; }
192
194
intptr_t size () const { return size_; }
193
195
intptr_t num_objects () const { return num_objects_; }
194
196
@@ -206,16 +208,20 @@ class SerializationCluster : public ZoneAllocated {
206
208
const intptr_t cid_;
207
209
const intptr_t target_instance_size_;
208
210
const bool is_canonical_;
211
+ const bool is_immutable_;
209
212
intptr_t size_ = 0 ;
210
213
intptr_t num_objects_ = 0 ;
211
214
intptr_t target_memory_size_ = 0 ;
212
215
};
213
216
214
217
class DeserializationCluster : public ZoneAllocated {
215
218
public:
216
- explicit DeserializationCluster (const char * name, bool is_canonical = false )
219
+ explicit DeserializationCluster (const char * name,
220
+ bool is_canonical = false ,
221
+ bool is_immutable = false )
217
222
: name_(name),
218
223
is_canonical_(is_canonical),
224
+ is_immutable_(is_immutable),
219
225
start_index_(-1 ),
220
226
stop_index_(-1 ) {}
221
227
virtual ~DeserializationCluster () {}
@@ -245,6 +251,7 @@ class DeserializationCluster : public ZoneAllocated {
245
251
246
252
const char * const name_;
247
253
const bool is_canonical_;
254
+ const bool is_immutable_;
248
255
// The range of the ref array that belongs to this cluster.
249
256
intptr_t start_index_;
250
257
intptr_t stop_index_;
@@ -678,7 +685,15 @@ class Deserializer : public ThreadStackResource {
678
685
static void InitializeHeader (ObjectPtr raw,
679
686
intptr_t cid,
680
687
intptr_t size,
681
- bool is_canonical = false );
688
+ bool is_canonical = false ) {
689
+ InitializeHeader (raw, cid, size, is_canonical,
690
+ ShouldHaveImmutabilityBitSetCid (cid));
691
+ }
692
+ static void InitializeHeader (ObjectPtr raw,
693
+ intptr_t cid,
694
+ intptr_t size,
695
+ bool is_canonical,
696
+ bool is_immutable);
682
697
683
698
// Reads raw data (for basic types).
684
699
// sizeof(T) must be in {1,2,4,8}.
@@ -869,7 +884,8 @@ ObjectPtr Deserializer::Allocate(intptr_t size) {
869
884
void Deserializer::InitializeHeader (ObjectPtr raw,
870
885
intptr_t class_id,
871
886
intptr_t size,
872
- bool is_canonical) {
887
+ bool is_canonical,
888
+ bool is_immutable) {
873
889
ASSERT (Utils::IsAligned (size, kObjectAlignment ));
874
890
uword tags = 0 ;
875
891
tags = UntaggedObject::ClassIdTag::update (class_id, tags);
@@ -879,7 +895,7 @@ void Deserializer::InitializeHeader(ObjectPtr raw,
879
895
tags = UntaggedObject::NotMarkedBit::update (true , tags);
880
896
tags = UntaggedObject::OldAndNotRememberedBit::update (true , tags);
881
897
tags = UntaggedObject::NewBit::update (false , tags);
882
- // TODO(https://dartbug.com/55136): Initialize the ImmutableBit.
898
+ tags = UntaggedObject:: ImmutableBit::update (is_immutable, tags);
883
899
raw->untag ()->tags_ = tags;
884
900
}
885
901
@@ -888,9 +904,10 @@ void SerializationCluster::WriteAndMeasureAlloc(Serializer* serializer) {
888
904
intptr_t start_size = serializer->bytes_written ();
889
905
intptr_t start_data = serializer->GetDataSize ();
890
906
intptr_t start_objects = serializer->next_ref_index ();
891
- uint64_t cid_and_canonical =
892
- (static_cast <uint64_t >(cid_) << 1 ) | (is_canonical () ? 0x1 : 0x0 );
893
- serializer->Write <uint64_t >(cid_and_canonical);
907
+ uint32_t tags = UntaggedObject::ClassIdTag::encode (cid_) |
908
+ UntaggedObject::CanonicalBit::encode (is_canonical ()) |
909
+ UntaggedObject::ImmutableBit::encode (is_immutable ());
910
+ serializer->Write <uint32_t >(tags);
894
911
WriteAlloc (serializer);
895
912
intptr_t stop_size = serializer->bytes_written ();
896
913
intptr_t stop_data = serializer->GetDataSize ();
@@ -4575,9 +4592,12 @@ class AbstractInstanceDeserializationCluster : public DeserializationCluster {
4575
4592
class InstanceDeserializationCluster
4576
4593
: public AbstractInstanceDeserializationCluster {
4577
4594
public:
4578
- explicit InstanceDeserializationCluster (intptr_t cid, bool is_canonical)
4595
+ explicit InstanceDeserializationCluster (intptr_t cid,
4596
+ bool is_canonical,
4597
+ bool is_immutable)
4579
4598
: AbstractInstanceDeserializationCluster(" Instance" , is_canonical),
4580
- cid_(cid) {}
4599
+ cid_(cid),
4600
+ is_immutable_(is_immutable) {}
4581
4601
~InstanceDeserializationCluster () {}
4582
4602
4583
4603
void ReadAlloc (Deserializer* d) {
@@ -4598,6 +4618,7 @@ class InstanceDeserializationCluster
4598
4618
4599
4619
const intptr_t cid = cid_;
4600
4620
const bool mark_canonical = primary && is_canonical ();
4621
+ const bool is_immutable = is_immutable_;
4601
4622
intptr_t next_field_offset = next_field_offset_in_words_
4602
4623
<< kCompressedWordSizeLog2 ;
4603
4624
intptr_t instance_size = Object::RoundedAllocationSize (
@@ -4607,7 +4628,7 @@ class InstanceDeserializationCluster
4607
4628
for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
4608
4629
InstancePtr instance = static_cast <InstancePtr>(d.Ref (id));
4609
4630
Deserializer::InitializeHeader (instance, cid, instance_size,
4610
- mark_canonical);
4631
+ mark_canonical, is_immutable );
4611
4632
intptr_t offset = Instance::NextFieldOffset ();
4612
4633
while (offset < next_field_offset) {
4613
4634
if (unboxed_fields_bitmap.Get (offset / kCompressedWordSize )) {
@@ -4634,6 +4655,7 @@ class InstanceDeserializationCluster
4634
4655
4635
4656
private:
4636
4657
const intptr_t cid_;
4658
+ const bool is_immutable_;
4637
4659
intptr_t next_field_offset_in_words_;
4638
4660
intptr_t instance_size_in_words_;
4639
4661
};
@@ -8837,12 +8859,14 @@ Deserializer::~Deserializer() {
8837
8859
}
8838
8860
8839
8861
DeserializationCluster* Deserializer::ReadCluster () {
8840
- const uint64_t cid_and_canonical = Read<uint64_t >();
8841
- const intptr_t cid = (cid_and_canonical >> 1 ) & kMaxUint32 ;
8842
- const bool is_canonical = (cid_and_canonical & 0x1 ) == 0x1 ;
8862
+ const uint32_t tags = Read<uint32_t >();
8863
+ const intptr_t cid = UntaggedObject::ClassIdTag::decode (tags);
8864
+ const bool is_canonical = UntaggedObject::CanonicalBit::decode (tags);
8865
+ const bool is_immutable = UntaggedObject::ImmutableBit::decode (tags);
8843
8866
Zone* Z = zone_;
8844
8867
if (cid >= kNumPredefinedCids || cid == kInstanceCid ) {
8845
- return new (Z) InstanceDeserializationCluster (cid, is_canonical);
8868
+ return new (Z)
8869
+ InstanceDeserializationCluster (cid, is_canonical, is_immutable);
8846
8870
}
8847
8871
if (IsTypedDataViewClassId (cid)) {
8848
8872
ASSERT (!is_canonical);
@@ -9019,7 +9043,8 @@ DeserializationCluster* Deserializer::ReadCluster() {
9019
9043
#define CASE_FFI_CID (name ) case kFfi ##name##Cid:
9020
9044
CLASS_LIST_FFI_TYPE_MARKER (CASE_FFI_CID)
9021
9045
#undef CASE_FFI_CID
9022
- return new (Z) InstanceDeserializationCluster (cid, is_canonical);
9046
+ return new (Z)
9047
+ InstanceDeserializationCluster (cid, is_canonical, is_immutable);
9023
9048
case kDeltaEncodedTypedDataCid :
9024
9049
return new (Z) DeltaEncodedTypedDataDeserializationCluster ();
9025
9050
default :
0 commit comments