@@ -141,7 +141,7 @@ struct GlobalTypeOptimization : public Pass {
141
141
// still need to be descriptors for their own subtypes and supertypes to be
142
142
// valid. We will keep them descriptors by having them describe trivial new
143
143
// placeholder types.
144
- InsertOrderedMap <HeapType, Index > descriptorsOfPlaceholders;
144
+ std::vector <HeapType> descriptorsOfPlaceholders;
145
145
146
146
void run (Module* module ) override {
147
147
if (!module ->features .hasGC ()) {
@@ -473,8 +473,7 @@ struct GlobalTypeOptimization : public Pass {
473
473
auto desc = type.getDescribedType ();
474
474
assert (desc);
475
475
if (haveUnneededDescriptors.count (*desc)) {
476
- descriptorsOfPlaceholders.insert (
477
- {type, descriptorsOfPlaceholders.size ()});
476
+ descriptorsOfPlaceholders.push_back (type);
478
477
}
479
478
}
480
479
}
@@ -498,20 +497,30 @@ struct GlobalTypeOptimization : public Pass {
498
497
void updateTypes (Module& wasm) {
499
498
class TypeRewriter : public GlobalTypeRewriter {
500
499
GlobalTypeOptimization& parent;
500
+ InsertOrderedMap<HeapType, Index> placeholderIndices;
501
501
InsertOrderedMap<HeapType, Index>::iterator placeholderIt;
502
502
503
503
public:
504
504
TypeRewriter (Module& wasm, GlobalTypeOptimization& parent)
505
505
: GlobalTypeRewriter(wasm), parent(parent),
506
- placeholderIt (parent.descriptorsOfPlaceholders .begin()) {}
506
+ placeholderIt (placeholderIndices .begin()) {}
507
507
508
508
std::vector<HeapType> getSortedTypes (PredecessorGraph preds) override {
509
509
auto types = GlobalTypeRewriter::getSortedTypes (std::move (preds));
510
+ // Some of the descriptors of placeholders may not end up being used at
511
+ // all, so we will not rebuild them. Record the used types that need
512
+ // placeholder describees and assign them placeholder indices.
513
+ std::unordered_set<HeapType> typeSet (types.begin (), types.end ());
514
+ for (auto desc : parent.descriptorsOfPlaceholders ) {
515
+ if (typeSet.count (desc)) {
516
+ placeholderIndices.insert ({desc, placeholderIndices.size ()});
517
+ }
518
+ }
519
+ placeholderIt = placeholderIndices.begin ();
510
520
// Prefix the types with placeholders to be overwritten with the
511
521
// placeholder describees.
512
522
HeapType placeholder = Struct{};
513
- types.insert (
514
- types.begin (), parent.descriptorsOfPlaceholders .size (), placeholder);
523
+ types.insert (types.begin (), placeholderIndices.size (), placeholder);
515
524
return types;
516
525
}
517
526
@@ -577,19 +586,20 @@ struct GlobalTypeOptimization : public Pass {
577
586
578
587
// Until we've created all the placeholders, create a placeholder
579
588
// describee type for the next descriptor that needs one.
580
- if (placeholderIt != parent. descriptorsOfPlaceholders .end ()) {
589
+ if (placeholderIt != placeholderIndices .end ()) {
581
590
auto descriptor = placeholderIt->first ;
582
591
typeBuilder[i].descriptor (getTempHeapType (descriptor));
583
592
typeBuilder[i].setShared (descriptor.getShared ());
593
+
584
594
++placeholderIt;
585
595
return ;
586
596
}
587
597
588
598
// Remove an unneeded describee or describe a placeholder type.
589
599
if (auto described = oldType.getDescribedType ()) {
590
600
if (parent.haveUnneededDescriptors .count (*described)) {
591
- if (auto it = parent. descriptorsOfPlaceholders .find (oldType);
592
- it != parent. descriptorsOfPlaceholders .end ()) {
601
+ if (auto it = placeholderIndices .find (oldType);
602
+ it != placeholderIndices .end ()) {
593
603
typeBuilder[i].describes (typeBuilder[it->second ]);
594
604
} else {
595
605
typeBuilder[i].describes (std::nullopt );
0 commit comments