@@ -77,26 +77,32 @@ static IndexOperandHashVecType getStableIndexOperandHashes(
7777 return IndexOperandHashes;
7878}
7979
80- void StableFunctionMapRecord::serialize (raw_ostream &OS) const {
81- serialize (OS, FunctionMap.get ());
80+ void StableFunctionMapRecord::serialize (
81+ raw_ostream &OS, std::vector<CGDataPatchItem> &PatchItems) const {
82+ serialize (OS, FunctionMap.get (), PatchItems);
8283}
8384
84- void StableFunctionMapRecord::serialize (raw_ostream &OS,
85- const StableFunctionMap *FunctionMap) {
85+ void StableFunctionMapRecord::serialize (
86+ raw_ostream &OS, const StableFunctionMap *FunctionMap,
87+ std::vector<CGDataPatchItem> &PatchItems) {
8688 support::endian::Writer Writer (OS, endianness::little);
8789
8890 // Write Names.
8991 ArrayRef<std::string> Names = FunctionMap->getNames ();
90- uint32_t ByteSize = 4 ;
9192 Writer.write <uint32_t >(Names.size ());
92- for (auto &Name : Names) {
93+ // Remember the position, write back the total size of Names, so we can skip
94+ // reading them if needed.
95+ const uint64_t NamesByteSizeOffset = Writer.OS .tell ();
96+ Writer.write <uint64_t >(0 );
97+ for (auto &Name : Names)
9398 Writer.OS << Name << ' \0 ' ;
94- ByteSize += Name.size () + 1 ;
95- }
96- // Align ByteSize to 4 bytes.
97- uint32_t Padding = offsetToAlignment (ByteSize, Align (4 ));
99+ // Align current position to 4 bytes.
100+ uint32_t Padding = offsetToAlignment (Writer.OS .tell (), Align (4 ));
98101 for (uint32_t I = 0 ; I < Padding; ++I)
99102 Writer.OS << ' \0 ' ;
103+ const auto NamesByteSize =
104+ Writer.OS .tell () - NamesByteSizeOffset - sizeof (NamesByteSizeOffset);
105+ PatchItems.emplace_back (NamesByteSizeOffset, &NamesByteSize, 1 );
100106
101107 // Write StableFunctionEntries whose pointers are sorted.
102108 auto FuncEntries = getStableFunctionEntries (*FunctionMap);
@@ -120,7 +126,8 @@ void StableFunctionMapRecord::serialize(raw_ostream &OS,
120126 }
121127}
122128
123- void StableFunctionMapRecord::deserialize (const unsigned char *&Ptr) {
129+ void StableFunctionMapRecord::deserialize (const unsigned char *&Ptr,
130+ bool ReadStableFunctionMapNames) {
124131 // Assert that Ptr is 4-byte aligned
125132 assert (((uintptr_t )Ptr % 4 ) == 0 );
126133 // Read Names.
@@ -129,13 +136,23 @@ void StableFunctionMapRecord::deserialize(const unsigned char *&Ptr) {
129136 // Early exit if there is no name.
130137 if (NumNames == 0 )
131138 return ;
132- for (unsigned I = 0 ; I < NumNames; ++I) {
133- StringRef Name (reinterpret_cast <const char *>(Ptr));
134- Ptr += Name.size () + 1 ;
135- FunctionMap->getIdOrCreateForName (Name);
139+ const auto NamesByteSize =
140+ endian::readNext<uint64_t , endianness::little, unaligned>(Ptr);
141+ const auto NamesOffset = reinterpret_cast <uintptr_t >(Ptr);
142+ if (ReadStableFunctionMapNames) {
143+ for (unsigned I = 0 ; I < NumNames; ++I) {
144+ StringRef Name (reinterpret_cast <const char *>(Ptr));
145+ Ptr += Name.size () + 1 ;
146+ FunctionMap->getIdOrCreateForName (Name);
147+ }
148+ // Align Ptr to 4 bytes.
149+ Ptr = reinterpret_cast <const uint8_t *>(alignAddr (Ptr, Align (4 )));
150+ assert (reinterpret_cast <uintptr_t >(Ptr) - NamesOffset == NamesByteSize &&
151+ " NamesByteSize does not match the actual size of names" );
152+ } else {
153+ // skip reading Names by advancing the pointer.
154+ Ptr = reinterpret_cast <const uint8_t *>(NamesOffset + NamesByteSize);
136155 }
137- // Align Ptr to 4 bytes.
138- Ptr = reinterpret_cast <const uint8_t *>(alignAddr (Ptr, Align (4 )));
139156
140157 // Read StableFunctionEntries.
141158 auto NumFuncs =
0 commit comments