@@ -1403,11 +1403,26 @@ class CodeSerializationCluster : public SerializationCluster {
1403
1403
objects_.Add (code);
1404
1404
}
1405
1405
1406
- if (!(s->kind () == Snapshot::kFullAOT && FLAG_use_bare_instructions)) {
1406
+ if (s->kind () == Snapshot::kFullAOT && FLAG_use_bare_instructions) {
1407
+ if (FLAG_retain_function_objects) {
1408
+ ObjectPoolPtr pool = code->ptr ()->object_pool_ ;
1409
+ if ((pool != ObjectPool::null ()) && s->InCurrentLoadingUnit (code)) {
1410
+ const intptr_t length = pool->ptr ()->length_ ;
1411
+ uint8_t * entry_bits = pool->ptr ()->entry_bits ();
1412
+ for (intptr_t i = 0 ; i < length; i++) {
1413
+ auto entry_type = ObjectPool::TypeBits::decode (entry_bits[i]);
1414
+ if (entry_type == ObjectPool::EntryType::kTaggedObject ) {
1415
+ s->Push (pool->ptr ()->data ()[i].raw_obj_ );
1416
+ }
1417
+ }
1418
+ }
1419
+ }
1420
+ } else {
1407
1421
if (s->InCurrentLoadingUnit (code->ptr ()->object_pool_ )) {
1408
1422
s->Push (code->ptr ()->object_pool_ );
1409
1423
}
1410
1424
}
1425
+
1411
1426
s->Push (code->ptr ()->owner_ );
1412
1427
s->Push (code->ptr ()->exception_handlers_ );
1413
1428
s->Push (code->ptr ()->pc_descriptors_ );
@@ -1519,21 +1534,6 @@ class CodeSerializationCluster : public SerializationCluster {
1519
1534
}
1520
1535
1521
1536
void WriteAlloc (Serializer* s) {
1522
- Sort (&objects_);
1523
- auto loading_units = s->loading_units ();
1524
- if ((loading_units != nullptr ) &&
1525
- (s->current_loading_unit_id () == LoadingUnit::kRootId )) {
1526
- for (intptr_t i = LoadingUnit::kRootId + 1 ; i < loading_units->length ();
1527
- i++) {
1528
- auto unit_objects = loading_units->At (i)->deferred_objects ();
1529
- Sort (unit_objects);
1530
- for (intptr_t j = 0 ; j < unit_objects->length (); j++) {
1531
- deferred_objects_.Add (unit_objects->At (j)->raw ());
1532
- }
1533
- }
1534
- }
1535
- s->PrepareInstructions (&objects_);
1536
-
1537
1537
s->WriteCid (kCodeCid );
1538
1538
const intptr_t count = objects_.length ();
1539
1539
s->WriteUnsigned (count);
@@ -1679,7 +1679,8 @@ class CodeSerializationCluster : public SerializationCluster {
1679
1679
s->Write <int32_t >(code->ptr ()->state_bits_ );
1680
1680
}
1681
1681
1682
- GrowableArray<CodePtr>* discovered_objects () { return &objects_; }
1682
+ GrowableArray<CodePtr>* objects () { return &objects_; }
1683
+ GrowableArray<CodePtr>* deferred_objects () { return &deferred_objects_; }
1683
1684
1684
1685
// Some code objects would have their owners dropped from the snapshot,
1685
1686
// which makes it is impossible to recover program structure when
@@ -1843,12 +1844,17 @@ class ObjectPoolSerializationCluster : public SerializationCluster {
1843
1844
ObjectPoolPtr pool = ObjectPool::RawCast (object);
1844
1845
objects_.Add (pool);
1845
1846
1846
- const intptr_t length = pool->ptr ()->length_ ;
1847
- uint8_t * entry_bits = pool->ptr ()->entry_bits ();
1848
- for (intptr_t i = 0 ; i < length; i++) {
1849
- auto entry_type = ObjectPool::TypeBits::decode (entry_bits[i]);
1850
- if (entry_type == ObjectPool::EntryType::kTaggedObject ) {
1851
- s->Push (pool->ptr ()->data ()[i].raw_obj_ );
1847
+ if (s->kind () == Snapshot::kFullAOT && FLAG_use_bare_instructions &&
1848
+ FLAG_retain_function_objects) {
1849
+ // Treat pool as weak.
1850
+ } else {
1851
+ const intptr_t length = pool->ptr ()->length_ ;
1852
+ uint8_t * entry_bits = pool->ptr ()->entry_bits ();
1853
+ for (intptr_t i = 0 ; i < length; i++) {
1854
+ auto entry_type = ObjectPool::TypeBits::decode (entry_bits[i]);
1855
+ if (entry_type == ObjectPool::EntryType::kTaggedObject ) {
1856
+ s->Push (pool->ptr ()->data ()[i].raw_obj_ );
1857
+ }
1852
1858
}
1853
1859
}
1854
1860
}
@@ -1867,6 +1873,9 @@ class ObjectPoolSerializationCluster : public SerializationCluster {
1867
1873
}
1868
1874
1869
1875
void WriteFill (Serializer* s) {
1876
+ bool weak = s->kind () == Snapshot::kFullAOT && FLAG_use_bare_instructions &&
1877
+ FLAG_retain_function_objects;
1878
+
1870
1879
const intptr_t count = objects_.length ();
1871
1880
for (intptr_t i = 0 ; i < count; i++) {
1872
1881
ObjectPoolPtr pool = objects_[i];
@@ -1887,7 +1896,12 @@ class ObjectPoolSerializationCluster : public SerializationCluster {
1887
1896
s->WriteElementRef (StubCode::CallBootstrapNative ().raw (), j);
1888
1897
break ;
1889
1898
}
1890
- s->WriteElementRef (entry.raw_obj_ , j);
1899
+ if (weak && !s->HasRef (entry.raw_obj_ )) {
1900
+ // Any value will do, but null has the shortest id.
1901
+ s->WriteElementRef (Object::null (), j);
1902
+ } else {
1903
+ s->WriteElementRef (entry.raw_obj_ , j);
1904
+ }
1891
1905
break ;
1892
1906
}
1893
1907
case ObjectPool::EntryType::kImmediate : {
@@ -5269,19 +5283,26 @@ class UnitSerializationRoots : public SerializationRoots {
5269
5283
const Object* deferred_object = (*unit_->deferred_objects ())[i];
5270
5284
ASSERT (deferred_object->IsCode ());
5271
5285
CodePtr code = static_cast <CodePtr>(deferred_object->raw ());
5272
- if (!FLAG_use_bare_instructions) {
5286
+ if (FLAG_use_bare_instructions) {
5287
+ if (FLAG_retain_function_objects) {
5288
+ ObjectPoolPtr pool = code->ptr ()->object_pool_ ;
5289
+ if (pool != ObjectPool::null ()) {
5290
+ const intptr_t length = pool->ptr ()->length_ ;
5291
+ uint8_t * entry_bits = pool->ptr ()->entry_bits ();
5292
+ for (intptr_t i = 0 ; i < length; i++) {
5293
+ auto entry_type = ObjectPool::TypeBits::decode (entry_bits[i]);
5294
+ if (entry_type == ObjectPool::EntryType::kTaggedObject ) {
5295
+ s->Push (pool->ptr ()->data ()[i].raw_obj_ );
5296
+ }
5297
+ }
5298
+ }
5299
+ }
5300
+ } else {
5273
5301
s->Push (code->ptr ()->object_pool_ );
5274
5302
}
5275
5303
s->Push (code->ptr ()->compressed_stackmaps_ );
5276
5304
s->Push (code->ptr ()->code_source_map_ );
5277
5305
}
5278
- {
5279
- GrowableArray<CodePtr> raw_codes (num_deferred_objects);
5280
- for (intptr_t i = 0 ; i < num_deferred_objects; i++) {
5281
- raw_codes.Add ((*unit_->deferred_objects ())[i]->raw ());
5282
- }
5283
- s->PrepareInstructions (&raw_codes);
5284
- }
5285
5306
}
5286
5307
5287
5308
void WriteRoots (Serializer* s) {
@@ -5307,6 +5328,27 @@ class UnitSerializationRoots : public SerializationRoots {
5307
5328
s->WriteRootRef (code->ptr ()->compressed_stackmaps_ , " deferred-code" );
5308
5329
s->WriteRootRef (code->ptr ()->code_source_map_ , " deferred-code" );
5309
5330
}
5331
+
5332
+ if (FLAG_use_bare_instructions && FLAG_retain_function_objects) {
5333
+ ObjectPoolPtr pool =
5334
+ s->isolate_group ()->object_store ()->global_object_pool ();
5335
+ const intptr_t length = pool->ptr ()->length_ ;
5336
+ uint8_t * entry_bits = pool->ptr ()->entry_bits ();
5337
+ intptr_t last_write = 0 ;
5338
+ for (intptr_t i = 0 ; i < length; i++) {
5339
+ auto entry_type = ObjectPool::TypeBits::decode (entry_bits[i]);
5340
+ if (entry_type == ObjectPool::EntryType::kTaggedObject ) {
5341
+ if (s->IsWritten (pool->ptr ()->data ()[i].raw_obj_ )) {
5342
+ intptr_t skip = i - last_write;
5343
+ s->WriteUnsigned (skip);
5344
+ s->WriteRootRef (pool->ptr ()->data ()[i].raw_obj_ ,
5345
+ " deferred-literal" );
5346
+ last_write = i;
5347
+ }
5348
+ }
5349
+ }
5350
+ s->WriteUnsigned (length - last_write);
5351
+ }
5310
5352
#endif
5311
5353
}
5312
5354
@@ -5351,6 +5393,20 @@ class UnitDeserializationRoots : public DeserializationRoots {
5351
5393
static_cast <CodeSourceMapPtr>(d->ReadRef ());
5352
5394
}
5353
5395
5396
+ if (FLAG_use_bare_instructions && FLAG_retain_function_objects) {
5397
+ ObjectPoolPtr pool =
5398
+ d->isolate_group ()->object_store ()->global_object_pool ();
5399
+ const intptr_t length = pool->ptr ()->length_ ;
5400
+ uint8_t * entry_bits = pool->ptr ()->entry_bits ();
5401
+ for (intptr_t i = d->ReadUnsigned (); i < length; i += d->ReadUnsigned ()) {
5402
+ auto entry_type = ObjectPool::TypeBits::decode (entry_bits[i]);
5403
+ ASSERT (entry_type == ObjectPool::EntryType::kTaggedObject );
5404
+ // The existing entry will usually be null, but it might also be an
5405
+ // equivalent object that was duplicated in another loading unit.
5406
+ pool->ptr ()->data ()[i].raw_obj_ = d->ReadRef ();
5407
+ }
5408
+ }
5409
+
5354
5410
// Reinitialize the dispatch table by rereading the table's serialization
5355
5411
// in the root snapshot.
5356
5412
IsolateGroup* group = d->thread ()->isolate ()->group ();
@@ -5776,11 +5832,58 @@ bool Serializer::InCurrentLoadingUnit(ObjectPtr obj, bool record) {
5776
5832
}
5777
5833
5778
5834
#if !defined(DART_PRECOMPILED_RUNTIME)
5779
- void Serializer::PrepareInstructions (GrowableArray<CodePtr>* code_objects) {
5835
+ void Serializer::PrepareInstructions () {
5836
+ if (!Snapshot::IncludesCode (kind ())) return ;
5837
+
5838
+ CodeSerializationCluster* cluster =
5839
+ static_cast <CodeSerializationCluster*>(clusters_by_cid_[kCodeCid ]);
5840
+
5841
+ // Code objects that have identical/duplicate instructions must be adjacent in
5842
+ // the order that Code objects are written because the encoding of the
5843
+ // reference from the Code to the Instructions assumes monotonically
5844
+ // increasing offsets as part of a delta encoding. Also the code order table
5845
+ // that allows for mapping return addresses back to Code objects depends on
5846
+ // this sorting.
5847
+ if (cluster != nullptr ) {
5848
+ CodeSerializationCluster::Sort (cluster->objects ());
5849
+ }
5850
+ if ((loading_units_ != nullptr ) &&
5851
+ (current_loading_unit_id_ == LoadingUnit::kRootId )) {
5852
+ for (intptr_t i = LoadingUnit::kRootId + 1 ; i < loading_units_->length ();
5853
+ i++) {
5854
+ auto unit_objects = loading_units_->At (i)->deferred_objects ();
5855
+ CodeSerializationCluster::Sort (unit_objects);
5856
+ for (intptr_t j = 0 ; j < unit_objects->length (); j++) {
5857
+ cluster->deferred_objects ()->Add (unit_objects->At (j)->raw ());
5858
+ }
5859
+ }
5860
+ }
5861
+
5780
5862
#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
5781
5863
if ((kind () == Snapshot::kFullAOT ) && FLAG_use_bare_instructions) {
5864
+ // Group the code objects whose instructions are not being deferred in this
5865
+ // snapshot unit in the order they will be written: first the code objects
5866
+ // encountered for this first time in this unit being written by the
5867
+ // CodeSerializationCluster, then code object previously deferred whose
5868
+ // instructions are now written by UnitSerializationRoots. This order needs
5869
+ // to be known to finalize bare-instructions-mode's PC-relative calls.
5870
+ GrowableArray<CodePtr> code_objects;
5871
+ if (cluster != nullptr ) {
5872
+ auto in = cluster->objects ();
5873
+ for (intptr_t i = 0 ; i < in->length (); i++) {
5874
+ code_objects.Add (in->At (i));
5875
+ }
5876
+ }
5877
+ if (loading_units_ != nullptr ) {
5878
+ auto in =
5879
+ loading_units_->At (current_loading_unit_id_)->deferred_objects ();
5880
+ for (intptr_t i = 0 ; i < in->length (); i++) {
5881
+ code_objects.Add (in->At (i)->raw ());
5882
+ }
5883
+ }
5884
+
5782
5885
GrowableArray<ImageWriterCommand> writer_commands;
5783
- RelocateCodeObjects (vm_, code_objects, &writer_commands);
5886
+ RelocateCodeObjects (vm_, & code_objects, &writer_commands);
5784
5887
image_writer_->PrepareForSerialization (&writer_commands);
5785
5888
}
5786
5889
#endif // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
@@ -6030,6 +6133,8 @@ ZoneGrowableArray<Object*>* Serializer::Serialize(SerializationRoots* roots) {
6030
6133
}
6031
6134
#endif
6032
6135
6136
+ PrepareInstructions ();
6137
+
6033
6138
intptr_t num_objects = num_base_objects_ + num_written_objects_;
6034
6139
#if defined(ARCH_IS_64_BIT)
6035
6140
if (!Utils::IsInt (32 , num_objects)) {
@@ -6147,8 +6252,7 @@ void Serializer::WriteDispatchTable(const Array& entries) {
6147
6252
ASSERT (code_cluster != nullptr );
6148
6253
// Reference IDs in a cluster are allocated sequentially, so we can use the
6149
6254
// first code object's reference ID to calculate the cluster index.
6150
- const intptr_t first_code_id =
6151
- RefId (code_cluster->discovered_objects ()->At (0 ));
6255
+ const intptr_t first_code_id = RefId (code_cluster->objects ()->At (0 ));
6152
6256
// The first object in the code cluster must have its reference ID allocated.
6153
6257
ASSERT (IsAllocatedReference (first_code_id));
6154
6258
0 commit comments