Skip to content

Commit f792cc1

Browse files
rmacnak-googleCommit Queue
authored and
Commit Queue
committed
[vm] Also set immutability bit when deserializing.
Currently the immutable bit is a of function of the class. If we start having some instances of a class be immutable and others not, we will need separate clusters like we do for the canonical bit. TEST=vm/dart/snapshot_immutable_bit_test Bug: #55136 Cq-Include-Trybots: luci.dart.try:vm-appjit-linux-debug-x64-try Change-Id: I073f28cabca8293b766aa7c0b224934a62bf9cb4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/356280 Reviewed-by: Daco Harkes <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent d918ac1 commit f792cc1

File tree

2 files changed

+64
-16
lines changed

2 files changed

+64
-16
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import "dart:isolate";
6+
7+
@pragma("vm:deeply-immutable")
8+
final class Box {
9+
final int contents;
10+
const Box(this.contents);
11+
}
12+
13+
main() {
14+
var immutable = Box(42);
15+
var port = new RawReceivePort();
16+
port.handler = (msg) {
17+
if (!identical(msg, immutable)) {
18+
throw "Not treated as immutable";
19+
}
20+
port.close();
21+
};
22+
port.sendPort.send(immutable);
23+
}

runtime/vm/app_snapshot.cc

+41-16
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ class SerializationCluster : public ZoneAllocated {
167167
: name_(name),
168168
cid_(cid),
169169
target_instance_size_(target_instance_size),
170-
is_canonical_(is_canonical) {
170+
is_canonical_(is_canonical),
171+
is_immutable_(Object::ShouldHaveImmutabilityBitSet(cid)) {
171172
ASSERT(target_instance_size == kSizeVaries || target_instance_size >= 0);
172173
}
173174
virtual ~SerializationCluster() {}
@@ -189,6 +190,7 @@ class SerializationCluster : public ZoneAllocated {
189190
const char* name() const { return name_; }
190191
intptr_t cid() const { return cid_; }
191192
bool is_canonical() const { return is_canonical_; }
193+
bool is_immutable() const { return is_immutable_; }
192194
intptr_t size() const { return size_; }
193195
intptr_t num_objects() const { return num_objects_; }
194196

@@ -206,16 +208,20 @@ class SerializationCluster : public ZoneAllocated {
206208
const intptr_t cid_;
207209
const intptr_t target_instance_size_;
208210
const bool is_canonical_;
211+
const bool is_immutable_;
209212
intptr_t size_ = 0;
210213
intptr_t num_objects_ = 0;
211214
intptr_t target_memory_size_ = 0;
212215
};
213216

214217
class DeserializationCluster : public ZoneAllocated {
215218
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)
217222
: name_(name),
218223
is_canonical_(is_canonical),
224+
is_immutable_(is_immutable),
219225
start_index_(-1),
220226
stop_index_(-1) {}
221227
virtual ~DeserializationCluster() {}
@@ -245,6 +251,7 @@ class DeserializationCluster : public ZoneAllocated {
245251

246252
const char* const name_;
247253
const bool is_canonical_;
254+
const bool is_immutable_;
248255
// The range of the ref array that belongs to this cluster.
249256
intptr_t start_index_;
250257
intptr_t stop_index_;
@@ -678,7 +685,15 @@ class Deserializer : public ThreadStackResource {
678685
static void InitializeHeader(ObjectPtr raw,
679686
intptr_t cid,
680687
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);
682697

683698
// Reads raw data (for basic types).
684699
// sizeof(T) must be in {1,2,4,8}.
@@ -869,7 +884,8 @@ ObjectPtr Deserializer::Allocate(intptr_t size) {
869884
void Deserializer::InitializeHeader(ObjectPtr raw,
870885
intptr_t class_id,
871886
intptr_t size,
872-
bool is_canonical) {
887+
bool is_canonical,
888+
bool is_immutable) {
873889
ASSERT(Utils::IsAligned(size, kObjectAlignment));
874890
uword tags = 0;
875891
tags = UntaggedObject::ClassIdTag::update(class_id, tags);
@@ -879,7 +895,7 @@ void Deserializer::InitializeHeader(ObjectPtr raw,
879895
tags = UntaggedObject::NotMarkedBit::update(true, tags);
880896
tags = UntaggedObject::OldAndNotRememberedBit::update(true, tags);
881897
tags = UntaggedObject::NewBit::update(false, tags);
882-
// TODO(https://dartbug.com/55136): Initialize the ImmutableBit.
898+
tags = UntaggedObject::ImmutableBit::update(is_immutable, tags);
883899
raw->untag()->tags_ = tags;
884900
}
885901

@@ -888,9 +904,10 @@ void SerializationCluster::WriteAndMeasureAlloc(Serializer* serializer) {
888904
intptr_t start_size = serializer->bytes_written();
889905
intptr_t start_data = serializer->GetDataSize();
890906
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);
894911
WriteAlloc(serializer);
895912
intptr_t stop_size = serializer->bytes_written();
896913
intptr_t stop_data = serializer->GetDataSize();
@@ -4575,9 +4592,12 @@ class AbstractInstanceDeserializationCluster : public DeserializationCluster {
45754592
class InstanceDeserializationCluster
45764593
: public AbstractInstanceDeserializationCluster {
45774594
public:
4578-
explicit InstanceDeserializationCluster(intptr_t cid, bool is_canonical)
4595+
explicit InstanceDeserializationCluster(intptr_t cid,
4596+
bool is_canonical,
4597+
bool is_immutable)
45794598
: AbstractInstanceDeserializationCluster("Instance", is_canonical),
4580-
cid_(cid) {}
4599+
cid_(cid),
4600+
is_immutable_(is_immutable) {}
45814601
~InstanceDeserializationCluster() {}
45824602

45834603
void ReadAlloc(Deserializer* d) {
@@ -4598,6 +4618,7 @@ class InstanceDeserializationCluster
45984618

45994619
const intptr_t cid = cid_;
46004620
const bool mark_canonical = primary && is_canonical();
4621+
const bool is_immutable = is_immutable_;
46014622
intptr_t next_field_offset = next_field_offset_in_words_
46024623
<< kCompressedWordSizeLog2;
46034624
intptr_t instance_size = Object::RoundedAllocationSize(
@@ -4607,7 +4628,7 @@ class InstanceDeserializationCluster
46074628
for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
46084629
InstancePtr instance = static_cast<InstancePtr>(d.Ref(id));
46094630
Deserializer::InitializeHeader(instance, cid, instance_size,
4610-
mark_canonical);
4631+
mark_canonical, is_immutable);
46114632
intptr_t offset = Instance::NextFieldOffset();
46124633
while (offset < next_field_offset) {
46134634
if (unboxed_fields_bitmap.Get(offset / kCompressedWordSize)) {
@@ -4634,6 +4655,7 @@ class InstanceDeserializationCluster
46344655

46354656
private:
46364657
const intptr_t cid_;
4658+
const bool is_immutable_;
46374659
intptr_t next_field_offset_in_words_;
46384660
intptr_t instance_size_in_words_;
46394661
};
@@ -8837,12 +8859,14 @@ Deserializer::~Deserializer() {
88378859
}
88388860

88398861
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);
88438866
Zone* Z = zone_;
88448867
if (cid >= kNumPredefinedCids || cid == kInstanceCid) {
8845-
return new (Z) InstanceDeserializationCluster(cid, is_canonical);
8868+
return new (Z)
8869+
InstanceDeserializationCluster(cid, is_canonical, is_immutable);
88468870
}
88478871
if (IsTypedDataViewClassId(cid)) {
88488872
ASSERT(!is_canonical);
@@ -9019,7 +9043,8 @@ DeserializationCluster* Deserializer::ReadCluster() {
90199043
#define CASE_FFI_CID(name) case kFfi##name##Cid:
90209044
CLASS_LIST_FFI_TYPE_MARKER(CASE_FFI_CID)
90219045
#undef CASE_FFI_CID
9022-
return new (Z) InstanceDeserializationCluster(cid, is_canonical);
9046+
return new (Z)
9047+
InstanceDeserializationCluster(cid, is_canonical, is_immutable);
90239048
case kDeltaEncodedTypedDataCid:
90249049
return new (Z) DeltaEncodedTypedDataDeserializationCluster();
90259050
default:

0 commit comments

Comments
 (0)