mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Serialization] Filter Objective-C methods by mangled name rather than type ID.
Module files store all of the Objective-C method entrypoints in a central table indexed by selector, then filter the results based on the specific class being requested. Rather than storing the class as a TypeID---which requires a bunch of deserialization---store its mangled name. This allows us to deserialize less, and causes circular deserialization in rdar://problem/31615640.
This commit is contained in:
@@ -543,7 +543,7 @@ class ModuleFile::ObjCMethodTableInfo {
|
||||
public:
|
||||
using internal_key_type = std::string;
|
||||
using external_key_type = ObjCSelector;
|
||||
using data_type = SmallVector<std::tuple<TypeID, bool, DeclID>, 8>;
|
||||
using data_type = SmallVector<std::tuple<std::string, bool, DeclID>, 8>;
|
||||
using hash_value_type = uint32_t;
|
||||
using offset_type = unsigned;
|
||||
|
||||
@@ -562,7 +562,7 @@ public:
|
||||
|
||||
static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&data) {
|
||||
unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
|
||||
unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
|
||||
unsigned dataLength = endian::readNext<uint32_t, little, unaligned>(data);
|
||||
return { keyLength, dataLength };
|
||||
}
|
||||
|
||||
@@ -573,14 +573,16 @@ public:
|
||||
static data_type ReadData(internal_key_type key, const uint8_t *data,
|
||||
unsigned length) {
|
||||
const constexpr auto recordSize = sizeof(uint32_t) + 1 + sizeof(uint32_t);
|
||||
assert(length % recordSize == 0 && "invalid length");
|
||||
data_type result;
|
||||
while (length > 0) {
|
||||
TypeID typeID = endian::readNext<uint32_t, little, unaligned>(data);
|
||||
unsigned ownerLen = endian::readNext<uint32_t, little, unaligned>(data);
|
||||
bool isInstanceMethod = *data++ != 0;
|
||||
DeclID methodID = endian::readNext<uint32_t, little, unaligned>(data);
|
||||
result.push_back(std::make_tuple(typeID, isInstanceMethod, methodID));
|
||||
length -= recordSize;
|
||||
std::string ownerName((const char *)data, ownerLen);
|
||||
result.push_back(
|
||||
std::make_tuple(std::move(ownerName), isInstanceMethod, methodID));
|
||||
data += ownerLen;
|
||||
length -= (recordSize + ownerLen);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1565,6 +1567,7 @@ void ModuleFile::loadObjCMethods(
|
||||
return;
|
||||
}
|
||||
|
||||
std::string ownerName = Mangle::ASTMangler().mangleNominalType(classDecl);
|
||||
auto results = *known;
|
||||
for (const auto &result : results) {
|
||||
// If the method is the wrong kind (instance vs. class), skip it.
|
||||
@@ -1572,8 +1575,7 @@ void ModuleFile::loadObjCMethods(
|
||||
continue;
|
||||
|
||||
// If the method isn't defined in the requested class, skip it.
|
||||
Type type = getType(std::get<0>(result));
|
||||
if (type->getClassOrBoundGenericClass() != classDecl)
|
||||
if (std::get<0>(result) != ownerName)
|
||||
continue;
|
||||
|
||||
// Deserialize the method and add it to the list.
|
||||
|
||||
Reference in New Issue
Block a user