Skip to content

Commit efa6dd9

Browse files
authored
Merge pull request #4688 from slavapestov/reflection-fixes-3.0
Remote reflection fixes (3.0)
2 parents b2d11b5 + f6bed48 commit efa6dd9

16 files changed

+270
-80
lines changed

docs/ABI.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,7 @@ Globals
739739
global ::= 'Mm' type // class metaclass
740740
global ::= 'Mn' nominal-type // nominal type descriptor
741741
global ::= 'Mp' protocol // protocol descriptor
742+
global ::= 'MR' remote-reflection-record // metadata for remote mirrors
742743
global ::= 'PA' .* // partial application forwarder
743744
global ::= 'PAo' .* // ObjC partial application forwarder
744745
global ::= 'w' value-witness-kind type // value witness
@@ -820,6 +821,10 @@ Globals
820821
addressor-kind ::= 'o' // owning addressor (native owner)
821822
addressor-kind ::= 'p' // pinning addressor (native owner)
822823

824+
remote-reflection-record ::= 'f' type // field descriptor
825+
remote-reflection-record ::= 'a' protocol-conformance // associated type descriptor
826+
remote-reflection-record ::= 'b' type // builtin type descriptor
827+
823828
An ``entity`` starts with a ``nominal-type-kind`` (``[COPV]``), a
824829
substitution (``[Ss]``) of a nominal type, or an ``entity-kind``
825830
(``[FIiv]``).

include/swift/Remote/MetadataReader.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ class MetadataReader {
931931
// This is ABI.
932932
static constexpr auto OffsetToName =
933933
roundUpToAlignment(size_t(12), sizeof(StoredPointer))
934-
+ sizeof(StoredPointer);;
934+
+ sizeof(StoredPointer);
935935

936936
// Read the name pointer.
937937
StoredPointer namePtr;
@@ -963,15 +963,19 @@ class MetadataReader {
963963
return _readMetadata<TargetEnumMetadata>(address);
964964
case MetadataKind::Existential: {
965965
StoredPointer numProtocolsAddress = address +
966-
TargetExistentialTypeMetadata<Runtime>::OffsetToNumProtocols;
966+
TargetExistentialTypeMetadata<Runtime>::OffsetToNumProtocols;
967967
StoredPointer numProtocols;
968968
if (!Reader->readInteger(RemoteAddress(numProtocolsAddress),
969969
&numProtocols))
970970
return nullptr;
971971

972+
// Make sure the number of protocols is reasonable
973+
if (numProtocols >= 256)
974+
return nullptr;
975+
972976
auto totalSize = sizeof(TargetExistentialTypeMetadata<Runtime>)
973-
+ numProtocols *
974-
sizeof(ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor>);
977+
+ numProtocols *
978+
sizeof(ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor>);
975979

976980
return _readMetadata(address, totalSize);
977981
}
@@ -997,13 +1001,18 @@ class MetadataReader {
9971001
return _readMetadata<TargetStructMetadata>(address);
9981002
case MetadataKind::Tuple: {
9991003
auto numElementsAddress = address +
1000-
TargetTupleTypeMetadata<Runtime>::OffsetToNumElements;
1004+
TargetTupleTypeMetadata<Runtime>::OffsetToNumElements;
10011005
StoredSize numElements;
10021006
if (!Reader->readInteger(RemoteAddress(numElementsAddress),
10031007
&numElements))
10041008
return nullptr;
10051009
auto totalSize = sizeof(TargetTupleTypeMetadata<Runtime>)
1006-
+ numElements * sizeof(StoredPointer);
1010+
+ numElements * sizeof(StoredPointer);
1011+
1012+
// Make sure the number of elements is reasonable
1013+
if (numElements >= 256)
1014+
return nullptr;
1015+
10071016
return _readMetadata(address, totalSize);
10081017
}
10091018
}

lib/IRGen/GenDecl.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,19 @@ SILLinkage LinkEntity::getLinkage(IRGenModule &IGM,
11351135

11361136
case Kind::SILGlobalVariable:
11371137
return getSILGlobalVariable()->getLinkage();
1138+
1139+
case Kind::ReflectionBuiltinDescriptor:
1140+
case Kind::ReflectionFieldDescriptor:
1141+
// Reflection descriptors for imported types have shared linkage,
1142+
// since we may emit them in other TUs in the same module.
1143+
if (getTypeLinkage(getType()) == FormalLinkage::PublicNonUnique)
1144+
return SILLinkage::Shared;
1145+
return SILLinkage::Private;
1146+
case Kind::ReflectionAssociatedTypeDescriptor:
1147+
if (getConformanceLinkage(IGM, getProtocolConformance())
1148+
== SILLinkage::Shared)
1149+
return SILLinkage::Shared;
1150+
return SILLinkage::Private;
11381151
}
11391152
llvm_unreachable("bad link entity kind");
11401153
}
@@ -1198,6 +1211,9 @@ bool LinkEntity::isAvailableExternally(IRGenModule &IGM) const {
11981211
case Kind::GenericProtocolWitnessTableInstantiationFunction:
11991212
case Kind::SILFunction:
12001213
case Kind::SILGlobalVariable:
1214+
case Kind::ReflectionBuiltinDescriptor:
1215+
case Kind::ReflectionFieldDescriptor:
1216+
case Kind::ReflectionAssociatedTypeDescriptor:
12011217
llvm_unreachable("Relative reference to unsupported link entity");
12021218
}
12031219
llvm_unreachable("bad link entity kind");

lib/IRGen/GenReflection.cpp

Lines changed: 75 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "GenHeap.h"
3030
#include "GenProto.h"
3131
#include "IRGenModule.h"
32+
#include "Linking.h"
3233
#include "LoadableTypeInfo.h"
3334

3435
using namespace swift;
@@ -276,13 +277,13 @@ class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
276277
if (!init)
277278
return nullptr;
278279

279-
auto var = new llvm::GlobalVariable(*IGM.getModule(), init->getType(),
280-
/*isConstant*/ true,
281-
llvm::GlobalValue::PrivateLinkage,
282-
init,
283-
"\x01l__swift3_assocty_metadata");
280+
auto entity = LinkEntity::forReflectionAssociatedTypeDescriptor(Conformance);
281+
auto info = LinkInfo::get(IGM, entity, ForDefinition);
282+
283+
auto var = info.createVariable(IGM, init->getType(), Alignment(4));
284+
var->setConstant(true);
285+
var->setInitializer(init);
284286
var->setSection(IGM.getAssociatedTypeMetadataSectionName());
285-
var->setAlignment(4);
286287

287288
auto replacer = llvm::ConstantExpr::getBitCast(var, IGM.Int8PtrTy);
288289
tempBase->replaceAllUsesWith(replacer);
@@ -444,13 +445,14 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
444445
if (!init)
445446
return nullptr;
446447

447-
auto var = new llvm::GlobalVariable(*IGM.getModule(), init->getType(),
448-
/*isConstant*/ true,
449-
llvm::GlobalValue::PrivateLinkage,
450-
init,
451-
"\x01l__swift3_reflection_metadata");
448+
auto entity = LinkEntity::forReflectionFieldDescriptor(
449+
NTD->getDeclaredType()->getCanonicalType());
450+
auto info = LinkInfo::get(IGM, entity, ForDefinition);
451+
452+
auto var = info.createVariable(IGM, init->getType(), Alignment(4));
453+
var->setConstant(true);
454+
var->setInitializer(init);
452455
var->setSection(IGM.getFieldTypeMetadataSectionName());
453-
var->setAlignment(4);
454456

455457
auto replacer = llvm::ConstantExpr::getBitCast(var, IGM.Int8PtrTy);
456458
tempBase->replaceAllUsesWith(replacer);
@@ -460,61 +462,57 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
460462
};
461463

462464
class FixedTypeMetadataBuilder : public ReflectionMetadataBuilder {
463-
void addFixedType(Module *module, CanType type,
464-
const FixedTypeInfo &ti) {
465-
addTypeRef(module, type);
465+
ModuleDecl *module;
466+
CanType type;
467+
const FixedTypeInfo *ti;
466468

467-
addConstantInt32(ti.getFixedSize().getValue());
468-
addConstantInt32(ti.getFixedAlignment().getValue());
469-
addConstantInt32(ti.getFixedStride().getValue());
470-
addConstantInt32(ti.getFixedExtraInhabitantCount(IGM));
471-
}
472-
473-
void addBuiltinType(CanType builtinType) {
474-
auto &ti = cast<FixedTypeInfo>(IGM.getTypeInfoForUnlowered(builtinType));
475-
addFixedType(builtinType->getASTContext().TheBuiltinModule, builtinType, ti);
476-
}
477-
478-
void addOpaqueType(const NominalTypeDecl *nominalDecl) {
479-
auto &ti = cast<FixedTypeInfo>(IGM.getTypeInfoForUnlowered(
469+
public:
470+
FixedTypeMetadataBuilder(IRGenModule &IGM,
471+
CanType builtinType)
472+
: ReflectionMetadataBuilder(IGM) {
473+
module = builtinType->getASTContext().TheBuiltinModule;
474+
type = builtinType;
475+
ti = &cast<FixedTypeInfo>(IGM.getTypeInfoForUnlowered(builtinType));
476+
}
477+
478+
FixedTypeMetadataBuilder(IRGenModule &IGM,
479+
const NominalTypeDecl *nominalDecl)
480+
: ReflectionMetadataBuilder(IGM) {
481+
module = nominalDecl->getParentModule();
482+
type = nominalDecl->getDeclaredType()->getCanonicalType();
483+
ti = &cast<FixedTypeInfo>(IGM.getTypeInfoForUnlowered(
480484
nominalDecl->getDeclaredTypeInContext()->getCanonicalType()));
481-
482-
addFixedType(nominalDecl->getParentModule(),
483-
nominalDecl->getDeclaredType()->getCanonicalType(), ti);
484485
}
485486

486487
void layout() {
487-
for (auto builtinType : IGM.BuiltinTypes)
488-
addBuiltinType(builtinType);
488+
addTypeRef(module, type);
489489

490-
for (auto nominalDecl : IGM.OpaqueTypes)
491-
addOpaqueType(nominalDecl);
490+
addConstantInt32(ti->getFixedSize().getValue());
491+
addConstantInt32(ti->getFixedAlignment().getValue());
492+
addConstantInt32(ti->getFixedStride().getValue());
493+
addConstantInt32(ti->getFixedExtraInhabitantCount(IGM));
492494
}
493495

494-
public:
495-
FixedTypeMetadataBuilder(IRGenModule &IGM)
496-
: ReflectionMetadataBuilder(IGM) {}
497-
498496
llvm::GlobalVariable *emit() {
499-
500497
auto tempBase = std::unique_ptr<llvm::GlobalVariable>(
501498
new llvm::GlobalVariable(IGM.Int8Ty, /*isConstant*/ true,
502499
llvm::GlobalValue::PrivateLinkage));
503500
setRelativeAddressBase(tempBase.get());
504501

505502
layout();
503+
506504
auto init = getInit();
507505

508506
if (!init)
509507
return nullptr;
510508

511-
auto var = new llvm::GlobalVariable(*IGM.getModule(), init->getType(),
512-
/*isConstant*/ true,
513-
llvm::GlobalValue::PrivateLinkage,
514-
init,
515-
"\x01l__swift3_builtin_metadata");
509+
auto entity = LinkEntity::forReflectionBuiltinDescriptor(type);
510+
auto info = LinkInfo::get(IGM, entity, ForDefinition);
511+
512+
auto var = info.createVariable(IGM, init->getType(), Alignment(4));
513+
var->setConstant(true);
514+
var->setInitializer(init);
516515
var->setSection(IGM.getBuiltinTypeMetadataSectionName());
517-
var->setAlignment(4);
518516

519517
auto replacer = llvm::ConstantExpr::getBitCast(var, IGM.Int8PtrTy);
520518
tempBase->replaceAllUsesWith(replacer);
@@ -523,6 +521,20 @@ class FixedTypeMetadataBuilder : public ReflectionMetadataBuilder {
523521
}
524522
};
525523

524+
void IRGenModule::emitBuiltinTypeMetadataRecord(CanType builtinType) {
525+
FixedTypeMetadataBuilder builder(*this, builtinType);
526+
auto var = builder.emit();
527+
if (var)
528+
addUsedGlobal(var);
529+
}
530+
531+
void IRGenModule::emitOpaqueTypeMetadataRecord(const NominalTypeDecl *nominalDecl) {
532+
FixedTypeMetadataBuilder builder(*this, nominalDecl);
533+
auto var = builder.emit();
534+
if (var)
535+
addUsedGlobal(var);
536+
}
537+
526538
/// Builds a constant LLVM struct describing the layout of a fixed-size
527539
/// SIL @box. These look like closure contexts, but without any necessary
528540
/// bindings or metadata sources, and only a single captured value.
@@ -915,10 +927,17 @@ void IRGenModule::emitBuiltinReflectionMetadata() {
915927
for (auto PD : ImportedProtocols)
916928
emitFieldMetadataRecord(PD);
917929

918-
FixedTypeMetadataBuilder builder(*this);
919-
auto var = builder.emit();
920-
if (var)
921-
addUsedGlobal(var);
930+
for (auto builtinType : BuiltinTypes)
931+
emitBuiltinTypeMetadataRecord(builtinType);
932+
933+
for (auto nominalDecl : OpaqueTypes)
934+
emitOpaqueTypeMetadataRecord(nominalDecl);
935+
}
936+
937+
void IRGenerator::emitBuiltinReflectionMetadata() {
938+
for (auto &m : *this) {
939+
m.second->emitBuiltinReflectionMetadata();
940+
}
922941
}
923942

924943
void IRGenModule::emitFieldMetadataRecord(const NominalTypeDecl *Decl) {
@@ -941,3 +960,9 @@ void IRGenModule::emitReflectionMetadataVersion() {
941960
Version->setVisibility(llvm::GlobalValue::HiddenVisibility);
942961
addUsedGlobal(Version);
943962
}
963+
964+
void IRGenerator::emitReflectionMetadataVersion() {
965+
for (auto &m : *this) {
966+
m.second->emitReflectionMetadataVersion();
967+
}
968+
}

lib/IRGen/IRGen.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,11 @@ static void performParallelIRGeneration(IRGenOptions &Opts,
778778

779779
irgen.emitProtocolConformances();
780780

781+
irgen.emitReflectionMetadataVersion();
782+
783+
// Emit reflection metadata for builtin and imported types.
784+
irgen.emitBuiltinReflectionMetadata();
785+
781786
// Okay, emit any definitions that we suddenly need.
782787
irgen.emitLazyDefinitions();
783788

lib/IRGen/IRGenModule.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,13 @@ class IRGenerator {
275275
/// Emit type metadata records for types without explicit protocol conformance.
276276
void emitTypeMetadataRecords();
277277

278+
/// Emit reflection metadata records for builtin and imported types referenced
279+
/// from this module.
280+
void emitBuiltinReflectionMetadata();
281+
282+
/// Emit a symbol identifying the reflection metadata version.
283+
void emitReflectionMetadataVersion();
284+
278285
/// Emit everything which is reachable from already emitted IR.
279286
void emitLazyDefinitions();
280287

@@ -747,8 +754,22 @@ class IRGenModule {
747754

748755
void emitAssociatedTypeMetadataRecord(const ProtocolConformance *Conformance);
749756
void emitFieldMetadataRecord(const NominalTypeDecl *Decl);
757+
758+
/// Emit a reflection metadata record for a builtin type referenced
759+
/// from this module.
760+
void emitBuiltinTypeMetadataRecord(CanType builtinType);
761+
762+
/// Emit a reflection metadata record for an imported type referenced
763+
/// from this module.
764+
void emitOpaqueTypeMetadataRecord(const NominalTypeDecl *nominalDecl);
765+
766+
/// Emit reflection metadata records for builtin and imported types referenced
767+
/// from this module.
750768
void emitBuiltinReflectionMetadata();
769+
770+
/// Emit a symbol identifying the reflection metadata version.
751771
void emitReflectionMetadataVersion();
772+
752773
std::string getBuiltinTypeMetadataSectionName();
753774
std::string getFieldTypeMetadataSectionName();
754775
std::string getAssociatedTypeMetadataSectionName();

lib/IRGen/Linking.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,19 @@ void LinkEntity::mangle(raw_ostream &buffer) const {
315315
case Kind::SILGlobalVariable:
316316
mangler.appendSymbol(getSILGlobalVariable()->getName());
317317
return mangler.finalize(buffer);
318+
319+
case Kind::ReflectionBuiltinDescriptor:
320+
mangler.append("_TMRb");
321+
mangler.mangleType(getType(), getUncurryLevel());
322+
return mangler.finalize(buffer);
323+
case Kind::ReflectionFieldDescriptor:
324+
mangler.append("_TMRf");
325+
mangler.mangleType(getType(), getUncurryLevel());
326+
return mangler.finalize(buffer);
327+
case Kind::ReflectionAssociatedTypeDescriptor:
328+
mangler.append("_TMRa");
329+
mangler.mangleProtocolConformance(getProtocolConformance());
330+
return mangler.finalize(buffer);
318331
}
319332
llvm_unreachable("bad entity kind!");
320333
}

0 commit comments

Comments
 (0)