@@ -354,13 +354,10 @@ class ObjcCategoryMerger {
354
354
ConcatInputSection *catListIsec;
355
355
ConcatInputSection *catBodyIsec;
356
356
uint32_t offCatListIsec = 0 ;
357
- uint32_t inputIndex = 0 ;
358
357
359
358
bool wasMerged = false ;
360
359
};
361
360
362
- typedef std::vector<InfoInputCategory> CategoryGroup;
363
-
364
361
// To write new (merged) categories or classes, we will try make limited
365
362
// assumptions about the alignment and the sections the various class/category
366
363
// info are stored in and . So we'll just reuse the same sections and
@@ -432,14 +429,15 @@ class ObjcCategoryMerger {
432
429
433
430
private:
434
431
void collectAndValidateCategoriesData ();
435
- void mergeCategoriesIntoSingleCategory (CategoryGroup &categories);
432
+ void
433
+ mergeCategoriesIntoSingleCategory (std::vector<InfoInputCategory> &categories);
436
434
437
435
void eraseISec (ConcatInputSection *isec);
438
436
void removeRefsToErasedIsecs ();
439
437
void eraseMergedCategories ();
440
438
441
439
void generateCatListForNonErasedCategories (
442
- std::map <ConcatInputSection *, std::set<uint64_t >>
440
+ MapVector <ConcatInputSection *, std::set<uint64_t >>
443
441
catListToErasedOffsets);
444
442
void collectSectionWriteInfoFromIsec (const InputSection *isec,
445
443
InfoWriteSection &catWriteInfo);
@@ -492,8 +490,8 @@ class ObjcCategoryMerger {
492
490
493
491
InfoCategoryWriter infoCategoryWriter;
494
492
std::vector<ConcatInputSection *> &allInputSections;
495
- // Info for all input categories, grouped by base class
496
- std::vector<CategoryGroup> categoryGroups ;
493
+ // Map of base class Symbol to list of InfoInputCategory's for it
494
+ MapVector< const Symbol *, std::vector<InfoInputCategory>> categoryMap ;
497
495
// Set for tracking InputSection erased via eraseISec
498
496
DenseSet<InputSection *> erasedIsecs;
499
497
@@ -1063,12 +1061,6 @@ void ObjcCategoryMerger::createSymbolReference(Defined *refFrom,
1063
1061
}
1064
1062
1065
1063
void ObjcCategoryMerger::collectAndValidateCategoriesData () {
1066
- // Make category merging deterministic by using a counter for found categories
1067
- uint32_t inputCategoryIndex = 0 ;
1068
- // Map of base class Symbol to list of InfoInputCategory's for it. We use this
1069
- // for fast lookup of categories to their base class. Later this info will be
1070
- // moved into 'categoryGroups' member.
1071
- DenseMap<const Symbol *, std::vector<InfoInputCategory>> categoryMap;
1072
1064
for (InputSection *sec : allInputSections) {
1073
1065
if (sec->getName () != section_names::objcCatList)
1074
1066
continue ;
@@ -1098,25 +1090,12 @@ void ObjcCategoryMerger::collectAndValidateCategoriesData() {
1098
1090
tryGetSymbolAtIsecOffset (catBodyIsec, catLayout.klassOffset );
1099
1091
assert (classSym && " Category does not have a valid base class" );
1100
1092
1101
- InfoInputCategory catInputInfo{catListCisec, catBodyIsec, off,
1102
- inputCategoryIndex++};
1093
+ InfoInputCategory catInputInfo{catListCisec, catBodyIsec, off};
1103
1094
categoryMap[classSym].push_back (catInputInfo);
1104
1095
1105
1096
collectCategoryWriterInfoFromCategory (catInputInfo);
1106
1097
}
1107
1098
}
1108
-
1109
- // Move categoryMap into categoryGroups and sort by the first category's
1110
- // inputIndex. This way we can be sure that category merging will be
1111
- // deterministic across linker runs.
1112
- categoryGroups.reserve (categoryMap.size ());
1113
- for (auto &mapEntry : categoryMap)
1114
- categoryGroups.push_back (mapEntry.second );
1115
-
1116
- std::sort (categoryGroups.begin (), categoryGroups.end (),
1117
- [](const CategoryGroup &a, const CategoryGroup &b) {
1118
- return a[0 ].inputIndex < b[0 ].inputIndex ;
1119
- });
1120
1099
}
1121
1100
1122
1101
// In the input we have multiple __objc_catlist InputSection, each of which may
@@ -1125,7 +1104,7 @@ void ObjcCategoryMerger::collectAndValidateCategoriesData() {
1125
1104
// (not erased). For these not erased categories, we generate new __objc_catlist
1126
1105
// entries since the parent __objc_catlist entry will be erased
1127
1106
void ObjcCategoryMerger::generateCatListForNonErasedCategories (
1128
- const std::map <ConcatInputSection *, std::set<uint64_t >>
1107
+ const MapVector <ConcatInputSection *, std::set<uint64_t >>
1129
1108
catListToErasedOffsets) {
1130
1109
1131
1110
// Go through all offsets of all __objc_catlist's that we process and if there
@@ -1192,10 +1171,10 @@ void ObjcCategoryMerger::eraseISec(ConcatInputSection *isec) {
1192
1171
// them.
1193
1172
void ObjcCategoryMerger::eraseMergedCategories () {
1194
1173
// Map of InputSection to a set of offsets of the categories that were merged
1195
- std::map <ConcatInputSection *, std::set<uint64_t >> catListToErasedOffsets;
1174
+ MapVector <ConcatInputSection *, std::set<uint64_t >> catListToErasedOffsets;
1196
1175
1197
- for (auto &catGroup : categoryGroups ) {
1198
- for (InfoInputCategory &catInfo : catGroup ) {
1176
+ for (auto &mapEntry : categoryMap ) {
1177
+ for (InfoInputCategory &catInfo : mapEntry. second ) {
1199
1178
if (catInfo.wasMerged ) {
1200
1179
eraseISec (catInfo.catListIsec );
1201
1180
catListToErasedOffsets[catInfo.catListIsec ].insert (
@@ -1210,8 +1189,8 @@ void ObjcCategoryMerger::eraseMergedCategories() {
1210
1189
generateCatListForNonErasedCategories (catListToErasedOffsets);
1211
1190
1212
1191
// Erase the old method lists & names of the categories that were merged
1213
- for (auto &catgroup : categoryGroups ) {
1214
- for (InfoInputCategory &catInfo : catgroup ) {
1192
+ for (auto &mapEntry : categoryMap ) {
1193
+ for (InfoInputCategory &catInfo : mapEntry. second ) {
1215
1194
if (!catInfo.wasMerged )
1216
1195
continue ;
1217
1196
@@ -1262,10 +1241,10 @@ void ObjcCategoryMerger::removeRefsToErasedIsecs() {
1262
1241
void ObjcCategoryMerger::doMerge () {
1263
1242
collectAndValidateCategoriesData ();
1264
1243
1265
- for (auto &catGroup : categoryGroups )
1266
- if (catGroup .size () > 1 )
1244
+ for (auto &entry : categoryMap )
1245
+ if (entry. second .size () > 1 )
1267
1246
// Merge all categories into a new, single category
1268
- mergeCategoriesIntoSingleCategory (catGroup );
1247
+ mergeCategoriesIntoSingleCategory (entry. second );
1269
1248
1270
1249
// Erase all categories that were merged
1271
1250
eraseMergedCategories ();
0 commit comments