Skip to content

Commit 14d5edf

Browse files
committed
IRGen: restrict generation of read-only static objects to Array buffers
Currently only arrays can be put into a read-only data section. "Regular" classes have dynamically initialized metadata, which needs to be stored into the isa field at runtime.
1 parent e2d2ca0 commit 14d5edf

File tree

6 files changed

+18
-8
lines changed

6 files changed

+18
-8
lines changed

lib/IRGen/GenConstant.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ llvm::Constant *irgen::emitConstantObject(IRGenModule &IGM, ObjectInst *OI,
432432
// Construct the object header.
433433
llvm::StructType *ObjectHeaderTy = cast<llvm::StructType>(sTy->getElementType(0));
434434

435-
if (IGM.canMakeStaticObjectsReadOnly()) {
435+
if (IGM.canMakeStaticObjectReadOnly(OI->getType())) {
436436
if (!IGM.swiftImmortalRefCount) {
437437
auto *var = new llvm::GlobalVariable(IGM.Module, IGM.Int8Ty,
438438
/*constant*/ true, llvm::GlobalValue::ExternalLinkage,

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2804,7 +2804,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
28042804
if (initVal) {
28052805
gvar->setInitializer(initVal);
28062806
if (var->isLet() ||
2807-
(var->isInitializedObject() && canMakeStaticObjectsReadOnly())) {
2807+
(var->isInitializedObject() && canMakeStaticObjectReadOnly(var->getLoweredType()))) {
28082808
gvar->setConstant(true);
28092809
}
28102810
} else {
@@ -2814,7 +2814,7 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
28142814
}
28152815

28162816
llvm::Constant *addr = gvar;
2817-
if (var->isInitializedObject() && !canMakeStaticObjectsReadOnly()) {
2817+
if (var->isInitializedObject() && !canMakeStaticObjectReadOnly(var->getLoweredType())) {
28182818
// Project out the object from the container.
28192819
llvm::Constant *Indices[2] = {
28202820
llvm::ConstantExpr::getIntegerValue(Int32Ty, APInt(32, 0)),
@@ -2842,7 +2842,7 @@ llvm::Constant *IRGenModule::getGlobalInitValue(SILGlobalVariable *var,
28422842
StructLayout *layout = StaticObjectLayouts[var].get();
28432843
ObjectInst *oi = cast<ObjectInst>(var->getStaticInitializerValue());
28442844
llvm::Constant *initVal = emitConstantObject(*this, oi, layout);
2845-
if (!canMakeStaticObjectsReadOnly()) {
2845+
if (!canMakeStaticObjectReadOnly(var->getLoweredType())) {
28462846
// A statically initialized object must be placed into a container struct
28472847
// because the swift_initStaticObject needs a swift_once_t at offset -1:
28482848
// struct Container {

lib/IRGen/IRGenModule.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2023,7 +2023,7 @@ bool IRGenModule::canUseObjCSymbolicReferences() {
20232023
context.getObjCSymbolicReferencesAvailability());
20242024
}
20252025

2026-
bool IRGenModule::canMakeStaticObjectsReadOnly() {
2026+
bool IRGenModule::canMakeStaticObjectReadOnly(SILType objectType) {
20272027
if (getOptions().DisableReadonlyStaticObjects)
20282028
return false;
20292029

@@ -2032,6 +2032,16 @@ bool IRGenModule::canMakeStaticObjectsReadOnly() {
20322032
if (!Triple.isOSDarwin())
20332033
return false;
20342034

2035+
auto *clDecl = objectType.getClassOrBoundGenericClass();
2036+
if (!clDecl)
2037+
return false;
2038+
2039+
// Currently only arrays can be put into a read-only data section.
2040+
// "Regular" classes have dynamically initialized metadata, which needs to be
2041+
// stored into the isa field at runtime.
2042+
if (clDecl->getNameStr() != "_ContiguousArrayStorage")
2043+
return false;
2044+
20352045
if (!getAvailabilityContext().isContainedIn(Context.getStaticReadOnlyArraysAvailability()))
20362046
return false;
20372047

lib/IRGen/IRGenModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ class IRGenModule {
925925

926926
bool shouldPrespecializeGenericMetadata();
927927

928-
bool canMakeStaticObjectsReadOnly();
928+
bool canMakeStaticObjectReadOnly(SILType objectType);
929929

930930
ClassDecl *getStaticArrayStorageDecl();
931931

lib/IRGen/IRGenSIL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3097,7 +3097,7 @@ void IRGenSILFunction::visitGlobalValueInst(GlobalValueInst *i) {
30973097
NotForDefinition).getAddress();
30983098
// We don't need to initialize the global object if it's never used for
30993099
// something which can access the object header.
3100-
if (!i->isBare() && !IGM.canMakeStaticObjectsReadOnly()) {
3100+
if (!i->isBare() && !IGM.canMakeStaticObjectReadOnly(var->getLoweredType())) {
31013101
auto ClassType = loweredTy.getASTType();
31023102
llvm::Value *Metadata =
31033103
emitClassHeapMetadataRef(*this, ClassType, MetadataValueType::TypeMetadata,

lib/IRGen/Linking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ LinkEntity LinkEntity::forSILGlobalVariable(SILGlobalVariable *G,
9797
LinkEntity entity;
9898
entity.Pointer = G;
9999
entity.SecondaryPointer = nullptr;
100-
auto kind = (G->isInitializedObject() && IGM.canMakeStaticObjectsReadOnly() ?
100+
auto kind = (G->isInitializedObject() && IGM.canMakeStaticObjectReadOnly(G->getLoweredType()) ?
101101
Kind::ReadOnlyGlobalObject : Kind::SILGlobalVariable);
102102
entity.Data = unsigned(kind) << KindShift;
103103
return entity;

0 commit comments

Comments
 (0)