Skip to content

Commit

Permalink
IRGen: Another MetadataScanner => MetadataLayout refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
slavapestov committed Aug 15, 2017
1 parent 72c4974 commit 293f502
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 35 deletions.
42 changes: 7 additions & 35 deletions lib/IRGen/GenMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3872,50 +3872,22 @@ std::pair<llvm::Value *, llvm::Value *>
irgen::emitClassResilientInstanceSizeAndAlignMask(IRGenFunction &IGF,
ClassDecl *theClass,
llvm::Value *metadata) {
class FindClassSize
: public ClassMetadataScanner<FindClassSize> {
using super = ClassMetadataScanner<FindClassSize>;
public:
FindClassSize(IRGenModule &IGM, ClassDecl *theClass)
: ClassMetadataScanner(IGM, theClass) {}

Size InstanceSize = Size::invalid();
Size InstanceAlignMask = Size::invalid();

void noteAddressPoint() {
assert(InstanceSize.isInvalid() && InstanceAlignMask.isInvalid()
&& "found size or alignment before address point?!");
NextOffset = Size(0);
}

void addInstanceSize() {
InstanceSize = NextOffset;
super::addInstanceSize();
}

void addInstanceAlignMask() {
InstanceAlignMask = NextOffset;
super::addInstanceAlignMask();
}
};
auto &layout = IGF.IGM.getMetadataLayout(theClass);

FindClassSize scanner(IGF.IGM, theClass);
scanner.layout();
assert(!scanner.InstanceSize.isInvalid()
&& !scanner.InstanceAlignMask.isInvalid()
&& "didn't find size or alignment in metadata?!");
Address metadataAsBytes(IGF.Builder.CreateBitCast(metadata, IGF.IGM.Int8PtrTy),
IGF.IGM.getPointerAlignment());

Address slot = IGF.Builder.CreateConstByteArrayGEP(metadataAsBytes,
scanner.InstanceSize);
Address slot = IGF.Builder.CreateConstByteArrayGEP(
metadataAsBytes,
layout.getInstanceSizeOffset());
slot = IGF.Builder.CreateBitCast(slot, IGF.IGM.Int32Ty->getPointerTo());
llvm::Value *size = IGF.Builder.CreateLoad(slot);
if (IGF.IGM.SizeTy != IGF.IGM.Int32Ty)
size = IGF.Builder.CreateZExt(size, IGF.IGM.SizeTy);

slot = IGF.Builder.CreateConstByteArrayGEP(metadataAsBytes,
scanner.InstanceAlignMask);
slot = IGF.Builder.CreateConstByteArrayGEP(
metadataAsBytes,
layout.getInstanceAlignMaskOffset());
slot = IGF.Builder.CreateBitCast(slot, IGF.IGM.Int16Ty->getPointerTo());
llvm::Value *alignMask = IGF.Builder.CreateLoad(slot);
alignMask = IGF.Builder.CreateZExt(alignMask, IGF.IGM.SizeTy);
Expand Down
20 changes: 20 additions & 0 deletions lib/IRGen/MetadataLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,16 @@ ClassMetadataLayout::ClassMetadataLayout(IRGenModule &IGM, ClassDecl *decl)
Scanner(IRGenModule &IGM, ClassDecl *decl, ClassMetadataLayout &layout)
: super(IGM, decl), Layout(layout) {}

void addInstanceSize() {
Layout.InstanceSize = getNextOffset();
super::addInstanceSize();
}

void addInstanceAlignMask() {
Layout.InstanceAlignMask = getNextOffset();
super::addInstanceAlignMask();
}

void addParentMetadataRef(ClassDecl *forClass, Type classType) {
if (forClass == Target)
Layout.Parent = getNextOffset();
Expand Down Expand Up @@ -281,6 +291,16 @@ ClassMetadataLayout::ClassMetadataLayout(IRGenModule &IGM, ClassDecl *decl)
Scanner(IGM, decl, *this).layout();
}

Size ClassMetadataLayout::getInstanceSizeOffset() const {
assert(InstanceSize.isStatic());
return InstanceSize.getStaticOffset();
}

Size ClassMetadataLayout::getInstanceAlignMaskOffset() const {
assert(InstanceAlignMask.isStatic());
return InstanceAlignMask.getStaticOffset();
}

ClassMetadataLayout::MethodInfo
ClassMetadataLayout::getMethodInfo(IRGenFunction &IGF, SILDeclRef method) const{
auto &stored = getStoredMethodInfo(method);
Expand Down
7 changes: 7 additions & 0 deletions lib/IRGen/MetadataLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ class ClassMetadataLayout : public NominalMetadataLayout {
};

private:
StoredOffset InstanceSize;
StoredOffset InstanceAlignMask;

struct StoredMethodInfo {
StoredOffset TheOffset;
StoredMethodInfo(StoredOffset offset) : TheOffset(offset) {}
Expand Down Expand Up @@ -184,6 +187,10 @@ class ClassMetadataLayout : public NominalMetadataLayout {
ClassMetadataLayout(IRGenModule &IGM, ClassDecl *theClass);

public:
Size getInstanceSizeOffset() const;

Size getInstanceAlignMaskOffset() const;

/// Should only be used when emitting the nominal type descriptor.
Size getStaticVTableOffset() const;

Expand Down

0 comments on commit 293f502

Please sign in to comment.