Skip to content

Commit 89db9e2

Browse files
committed
IRGen: Support dynamic offsets for various metadata fields
Not hooked up until some more MetadataLayout changes land.
1 parent 8ba060b commit 89db9e2

File tree

2 files changed

+60
-34
lines changed

2 files changed

+60
-34
lines changed

lib/IRGen/MetadataLayout.cpp

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,38 @@ void MetadataLayout::destroy() const {
134134

135135
/******************************* NOMINAL TYPES ********************************/
136136

137+
Offset NominalMetadataLayout::emitOffset(IRGenFunction &IGF,
138+
StoredOffset offset) const {
139+
assert(offset.isValid());
140+
141+
if (offset.isStatic())
142+
return Offset(offset.getStaticOffset());
143+
144+
Address offsetBaseAddr(
145+
IGF.IGM.getAddrOfClassMetadataBaseOffset(cast<ClassDecl>(getDecl()),
146+
NotForDefinition),
147+
IGF.IGM.getPointerAlignment());
148+
149+
// FIXME: Should this be an invariant load?
150+
auto *offsetBaseVal =
151+
IGF.Builder.CreateLoad(offsetBaseAddr, "base");
152+
153+
auto relativeOffset = offset.getRelativeOffset().getValue();
154+
auto *offsetVal =
155+
IGF.Builder.CreateAdd(offsetBaseVal,
156+
llvm::ConstantInt::get(IGF.IGM.SizeTy,
157+
relativeOffset));
158+
return Offset(offsetVal);
159+
}
160+
137161
Size
138162
NominalMetadataLayout::getStaticGenericRequirementsOffset() const {
139-
assert(GenericRequirements.isValid());
140-
assert(GenericRequirements.isStatic() && "resilient metadata layout unsupported!");
141163
return GenericRequirements.getStaticOffset();
142164
}
143165

144166
Offset
145167
NominalMetadataLayout::getGenericRequirementsOffset(IRGenFunction &IGF) const {
146-
assert(GenericRequirements.isValid());
147-
assert(GenericRequirements.isStatic() && "resilient metadata layout unsupported!");
148-
return Offset(GenericRequirements.getStaticOffset());
168+
return emitOffset(IGF, GenericRequirements);
149169
}
150170

151171
static llvm::Value *emitLoadOfGenericRequirement(IRGenFunction &IGF,
@@ -323,11 +343,7 @@ Size ClassMetadataLayout::getInstanceAlignMaskOffset() const {
323343
ClassMetadataLayout::MethodInfo
324344
ClassMetadataLayout::getMethodInfo(IRGenFunction &IGF, SILDeclRef method) const{
325345
auto &stored = getStoredMethodInfo(method);
326-
327-
assert(stored.TheOffset.isStatic() &&
328-
"resilient class metadata layout unsupported!");
329-
auto offset = Offset(stored.TheOffset.getStaticOffset());
330-
346+
auto offset = emitOffset(IGF, stored.TheOffset);
331347
return MethodInfo(offset);
332348
}
333349

@@ -339,45 +355,50 @@ Size ClassMetadataLayout::getStaticMethodOffset(SILDeclRef method) const{
339355
return stored.TheOffset.getStaticOffset();
340356
}
341357

342-
Size
343-
ClassMetadataLayout::getStaticVTableOffset() const {
344-
// TODO: if class is resilient, return the offset relative to the start
345-
// of immediate class metadata
346-
assert(VTableOffset.isStatic());
347-
return VTableOffset.getStaticOffset();
348-
}
349-
350358
Offset
351359
ClassMetadataLayout::getVTableOffset(IRGenFunction &IGF) const {
352-
// TODO: implement resilient metadata layout
353-
assert(VTableOffset.isStatic());
354-
return Offset(VTableOffset.getStaticOffset());
360+
return emitOffset(IGF, VTableOffset);
355361
}
356362

357363
Offset ClassMetadataLayout::getFieldOffset(IRGenFunction &IGF,
358364
VarDecl *field) const {
359-
// TODO: implement resilient metadata layout
360-
return Offset(getStaticFieldOffset(field));
365+
return emitOffset(IGF, getStoredFieldOffset(field));
361366
}
367+
362368
Size ClassMetadataLayout::getStaticFieldOffset(VarDecl *field) const {
363369
auto &stored = getStoredFieldOffset(field);
364370
assert(stored.isStatic() && "resilient class metadata layout unsupported!");
365371
return stored.getStaticOffset();
366372
}
367373

374+
Size
375+
ClassMetadataLayout::getRelativeGenericRequirementsOffset() const {
376+
return GenericRequirements.getRelativeOffset();
377+
}
378+
368379
Size
369380
ClassMetadataLayout::getStaticFieldOffsetVectorOffset() const {
370-
// TODO: if class is resilient, return the offset relative to the start
371-
// of immediate class metadata
372-
assert(FieldOffsetVector.isStatic());
373381
return FieldOffsetVector.getStaticOffset();
374382
}
375383

384+
Size
385+
ClassMetadataLayout::getRelativeFieldOffsetVectorOffset() const {
386+
return FieldOffsetVector.getRelativeOffset();
387+
}
388+
389+
Size
390+
ClassMetadataLayout::getStaticVTableOffset() const {
391+
return VTableOffset.getStaticOffset();
392+
}
393+
394+
Size
395+
ClassMetadataLayout::getRelativeVTableOffset() const {
396+
return VTableOffset.getRelativeOffset();
397+
}
398+
376399
Offset
377400
ClassMetadataLayout::getFieldOffsetVectorOffset(IRGenFunction &IGF) const {
378-
// TODO: implement resilient metadata layout
379-
assert(FieldOffsetVector.isStatic());
380-
return Offset(FieldOffsetVector.getStaticOffset());
401+
return emitOffset(IGF, FieldOffsetVector);
381402
}
382403

383404
Size irgen::getClassFieldOffsetOffset(IRGenModule &IGM, ClassDecl *theClass,
@@ -398,8 +419,8 @@ llvm::Value *irgen::emitClassFieldOffset(IRGenFunction &IGF,
398419

399420
Address irgen::emitAddressOfClassFieldOffset(IRGenFunction &IGF,
400421
llvm::Value *metadata,
401-
ClassDecl *theClass,
402-
VarDecl *field) {
422+
ClassDecl *theClass,
423+
VarDecl *field) {
403424
auto offset = IGF.IGM.getMetadataLayout(theClass).getFieldOffset(IGF, field);
404425
auto slot = IGF.emitAddressAtOffset(metadata, offset, IGF.IGM.SizeTy,
405426
IGF.IGM.getPointerAlignment());

lib/IRGen/MetadataLayout.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ class NominalMetadataLayout : public MetadataLayout {
134134
NominalMetadataLayout(Kind kind, NominalTypeDecl *nominal)
135135
: MetadataLayout(kind), Nominal(nominal) {}
136136

137+
Offset emitOffset(IRGenFunction &IGF, StoredOffset offset) const;
138+
137139
public:
138140
NominalTypeDecl *getDecl() const {
139141
return Nominal;
@@ -214,9 +216,6 @@ class ClassMetadataLayout : public NominalMetadataLayout {
214216

215217
Size getInstanceAlignMaskOffset() const;
216218

217-
/// Should only be used when emitting the nominal type descriptor.
218-
Size getStaticVTableOffset() const;
219-
220219
/// Returns the start of the vtable in the class metadata.
221220
Offset getVTableOffset(IRGenFunction &IGF) const;
222221

@@ -244,7 +243,13 @@ class ClassMetadataLayout : public NominalMetadataLayout {
244243
Size getStaticFieldOffset(VarDecl *field) const;
245244

246245
/// Should only be used when emitting the nominal type descriptor.
246+
Size getRelativeGenericRequirementsOffset() const;
247+
247248
Size getStaticFieldOffsetVectorOffset() const;
249+
Size getRelativeFieldOffsetVectorOffset() const;
250+
251+
Size getStaticVTableOffset() const;
252+
Size getRelativeVTableOffset() const;
248253

249254
Offset getFieldOffsetVectorOffset(IRGenFunction &IGF) const;
250255

0 commit comments

Comments
 (0)