Skip to content

Commit 9a38e60

Browse files
author
Greg Parker
authored
[IRGen][runtime] Reduce object header to 8 bytes on 32-bit platforms. (swiftlang#12790)
SR-4353, rdar://29765800
1 parent b12acc4 commit 9a38e60

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+190
-228
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class ReflectionContext
6666

6767
unsigned getSizeOfHeapObject() {
6868
// This must match sizeof(HeapObject) for the target.
69-
return sizeof(StoredPointer) + 8;
69+
return sizeof(StoredPointer) * 2;
7070
}
7171

7272
void dumpAllSections(std::ostream &OS) {
@@ -483,9 +483,8 @@ class ReflectionContext
483483
case MetadataSourceKind::ClosureBinding: {
484484
unsigned Index = cast<ClosureBindingMetadataSource>(MS)->getIndex();
485485

486-
// Skip the context's isa pointer (4 or 8 bytes) and reference counts
487-
// (4 bytes each regardless of platform word size). This is just
488-
// sizeof(HeapObject) in the target.
486+
// Skip the context's HeapObject header
487+
// (one word each for isa pointer and reference counts).
489488
//
490489
// Metadata and conformance tables are stored consecutively after
491490
// the heap object header, in the 'necessary bindings' area.

lib/IRGen/GenDecl.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3138,21 +3138,19 @@ IRGenModule::getAddrOfGlobalConstantString(StringRef utf8) {
31383138
metaclass = llvm::ConstantExpr::getBitCast(metaclass, TypeMetadataPtrTy);
31393139

31403140
// Get a reference count of two.
3141-
auto *strongRefCountInit = llvm::ConstantInt::get(
3142-
Int32Ty,
3143-
InlineRefCountBits(0 /*unowned ref count*/, 2 /*strong ref count*/)
3141+
auto *refCountInit = llvm::ConstantInt::get(
3142+
IntPtrTy,
3143+
InlineRefCountBits(1 /* "extra" strong ref count*/, 1 /* unowned count */)
31443144
.getBitsValue());
3145-
auto *unownedRefCountInit = llvm::ConstantInt::get(Int32Ty, 0);
31463145

31473146
auto *count = llvm::ConstantInt::get(Int32Ty, utf8.size());
31483147
// Capacity is length plus one because of the implicitly added '\0'
31493148
// character.
31503149
auto *capacity = llvm::ConstantInt::get(Int32Ty, utf8.size() + 1);
31513150
auto *flags = llvm::ConstantInt::get(Int8Ty, 0);
31523151

3153-
// FIXME: Big endian-ness.
31543152
llvm::Constant *heapObjectHeaderFields[] = {
3155-
metaclass, strongRefCountInit, unownedRefCountInit
3153+
metaclass, refCountInit
31563154
};
31573155

31583156
auto *initRefCountStruct = llvm::ConstantStruct::get(
@@ -3216,19 +3214,18 @@ IRGenModule::getAddrOfGlobalUTF16ConstantString(StringRef utf8) {
32163214
metaclass = llvm::ConstantExpr::getBitCast(metaclass, TypeMetadataPtrTy);
32173215

32183216
// Get a reference count of two.
3219-
auto *strongRefCountInit = llvm::ConstantInt::get(
3220-
Int32Ty,
3221-
InlineRefCountBits(0 /*unowned ref count*/, 2 /*strong ref count*/)
3217+
auto *refCountInit = llvm::ConstantInt::get(
3218+
IntPtrTy,
3219+
InlineRefCountBits(1 /* "extra" strong ref count*/, 1 /* unowned count */)
32223220
.getBitsValue());
3223-
auto *unownedRefCountInit = llvm::ConstantInt::get(Int32Ty, 0);
32243221

32253222
auto *count = llvm::ConstantInt::get(Int32Ty, utf16Length);
32263223
auto *capacity = llvm::ConstantInt::get(Int32Ty, utf16Length + 1);
32273224
auto *flags = llvm::ConstantInt::get(Int8Ty, 0);
32283225
auto *padding = llvm::ConstantInt::get(Int8Ty, 0);
32293226

32303227
llvm::Constant *heapObjectHeaderFields[] = {
3231-
metaclass, strongRefCountInit, unownedRefCountInit
3228+
metaclass, refCountInit
32323229
};
32333230

32343231
auto *initRefCountStruct = llvm::ConstantStruct::get(

lib/IRGen/GenExistential.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,7 +2128,7 @@ static llvm::Constant *getDeallocateBoxedOpaqueExistentialBufferFunction(
21282128

21292129
// Size = ((sizeof(HeapObject) + align) & ~align) + size
21302130
auto *heapHeaderSize = llvm::ConstantInt::get(
2131-
IGF.IGM.SizeTy, getHeapHeaderSize(IGM).getValue());
2131+
IGF.IGM.SizeTy, IGM.RefCountedStructSize.getValue());
21322132
size = Builder.CreateAdd(
21332133
Builder.CreateAnd(Builder.CreateAdd(heapHeaderSize, alignmentMask),
21342134
Builder.CreateNot(alignmentMask)),
@@ -2222,7 +2222,7 @@ getProjectBoxedOpaqueExistentialFunction(IRGenFunction &IGF,
22222222

22232223
// StartOffset = ((sizeof(HeapObject) + align) & ~align)
22242224
auto *heapHeaderSize = llvm::ConstantInt::get(
2225-
IGF.IGM.SizeTy, getHeapHeaderSize(IGM).getValue());
2225+
IGF.IGM.SizeTy, IGM.RefCountedStructSize.getValue());
22262226
auto *startOffset = Builder.CreateAnd(
22272227
Builder.CreateAdd(heapHeaderSize, alignmentMask),
22282228
Builder.CreateNot(alignmentMask));

lib/IRGen/GenKeyPath.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -700,11 +700,6 @@ IRGenModule::getAddrOfKeyPathPattern(KeyPathPattern *pattern,
700700
fields.add(emitMetadataGenerator(rootTy));
701701
fields.add(emitMetadataGenerator(valueTy));
702702

703-
// TODO: 32-bit heap object header still has an extra word
704-
if (SizeTy == Int32Ty) {
705-
fields.addInt32(0);
706-
}
707-
708703
#ifndef NDEBUG
709704
auto endOfObjectHeader = fields.getNextOffsetFromGlobal();
710705
unsigned expectedObjectHeaderSize;

lib/IRGen/GenValueWitness.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ static Address emitDefaultProjectBuffer(IRGenFunction &IGF, Address buffer,
242242
buffer.getAlignment());
243243
auto *boxStart = IGF.Builder.CreateLoad(boxAddress);
244244
auto *alignmentMask = type.getAlignmentMask(IGF, T);
245-
auto *heapHeaderSize =
246-
llvm::ConstantInt::get(IGM.SizeTy, getHeapHeaderSize(IGM).getValue());
245+
auto *heapHeaderSize = llvm::ConstantInt::get(
246+
IGM.SizeTy, IGM.RefCountedStructSize.getValue());
247247
auto *startOffset =
248248
Builder.CreateAnd(Builder.CreateAdd(heapHeaderSize, alignmentMask),
249249
Builder.CreateNot(alignmentMask));
@@ -820,7 +820,7 @@ getCopyOutOfLineBoxPointerFunction(IRGenModule &IGM,
820820
IGF.Builder.CreateStore(ptr, dest);
821821
auto *alignmentMask = fixedTI.getStaticAlignmentMask(IGM);
822822
auto *heapHeaderSize = llvm::ConstantInt::get(
823-
IGM.SizeTy, getHeapHeaderSize(IGM).getValue());
823+
IGM.SizeTy, IGM.RefCountedStructSize.getValue());
824824
auto *startOffset = IGF.Builder.CreateAnd(
825825
IGF.Builder.CreateAdd(heapHeaderSize, alignmentMask),
826826
IGF.Builder.CreateNot(alignmentMask));

lib/IRGen/IRGenModule.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,11 @@ IRGenModule::IRGenModule(IRGenerator &irgen,
264264
});
265265
FullBoxMetadataPtrTy = FullBoxMetadataStructTy->getPointerTo(DefaultAS);
266266

267-
llvm::Type *refCountedElts[] = {TypeMetadataPtrTy, Int32Ty, Int32Ty};
267+
// This must match struct HeapObject in the runtime.
268+
llvm::Type *refCountedElts[] = {TypeMetadataPtrTy, IntPtrTy};
268269
RefCountedStructTy->setBody(refCountedElts);
270+
RefCountedStructSize =
271+
Size(DataLayout.getStructLayout(RefCountedStructTy)->getSizeInBytes());
269272

270273
PtrSize = Size(DataLayout.getPointerSize(DefaultAS));
271274

lib/IRGen/IRGenModule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ class IRGenModule {
446446
llvm::PointerType *WitnessTablePtrTy;
447447
};
448448
llvm::StructType *RefCountedStructTy;/// %swift.refcounted = type { ... }
449+
Size RefCountedStructSize; /// sizeof(%swift.refcounted)
449450
llvm::PointerType *RefCountedPtrTy; /// %swift.refcounted*
450451
llvm::PointerType *WeakReferencePtrTy;/// %swift.weak_reference*
451452
llvm::PointerType *UnownedReferencePtrTy;/// %swift.unowned_reference*

lib/IRGen/StructLayout.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@ static bool requiresHeapHeader(LayoutKind kind) {
3838
llvm_unreachable("bad layout kind!");
3939
}
4040

41-
/// Return the size of the standard heap header.
42-
Size irgen::getHeapHeaderSize(IRGenModule &IGM) {
43-
return IGM.getPointerSize() + Size(8);
44-
}
45-
4641
/// Perform structure layout on the given types.
4742
StructLayout::StructLayout(IRGenModule &IGM, CanType astTy,
4843
LayoutKind layoutKind,
@@ -184,7 +179,7 @@ Address ElementLayout::project(IRGenFunction &IGF, Address baseAddr,
184179

185180
void StructLayoutBuilder::addHeapHeader() {
186181
assert(StructFields.empty() && "adding heap header at a non-zero offset");
187-
CurSize = getHeapHeaderSize(IGM);
182+
CurSize = IGM.RefCountedStructSize;
188183
CurAlignment = IGM.getPointerAlignment();
189184
StructFields.push_back(IGM.RefCountedStructTy);
190185
}

lib/IRGen/StructLayout.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,6 @@ class StructLayout {
395395
const llvm::Twine &name = "") const;
396396
};
397397

398-
Size getHeapHeaderSize(IRGenModule &IGM);
399-
400398
/// Different policies for accessing a physical field.
401399
enum class FieldAccess : uint8_t {
402400
/// Instance variable offsets are constant.

stdlib/public/SwiftShims/HeapObject.h

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
#include "System.h"
1717

1818
#define SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_64 16
19-
// TODO: Should be 8
20-
#define SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_32 12
19+
#define SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_32 8
2120

2221
#ifdef __cplusplus
2322
#include <type_traits>
@@ -39,12 +38,12 @@ typedef struct HeapMetadata HeapMetadata;
3938
InlineRefCounts refCounts
4039

4140
/// The Swift heap-object header.
41+
/// This must match RefCountedStructTy in IRGen.
4242
struct HeapObject {
4343
/// This is always a valid pointer to a metadata object.
4444
HeapMetadata const *metadata;
4545

4646
SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS;
47-
// FIXME: allocate two words of metadata on 32-bit platforms
4847

4948
#ifdef __cplusplus
5049
HeapObject() = default;
@@ -75,15 +74,8 @@ static_assert(swift::IsTriviallyConstructible<HeapObject>::value,
7574
static_assert(std::is_trivially_destructible<HeapObject>::value,
7675
"HeapObject must be trivially destructible");
7776

78-
// FIXME: small header for 32-bit
79-
//static_assert(sizeof(HeapObject) == 2*sizeof(void*),
80-
// "HeapObject must be two pointers long");
81-
//
82-
static_assert(sizeof(HeapObject) ==
83-
(sizeof(void*) == 8 ? SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_64 :
84-
sizeof(void*) == 4 ? SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_32 :
85-
0 && "unexpected pointer size"),
86-
"HeapObject must match ABI heap object header size");
77+
static_assert(sizeof(HeapObject) == 2*sizeof(void*),
78+
"HeapObject must be two pointers long");
8779

8880
static_assert(alignof(HeapObject) == alignof(void*),
8981
"HeapObject must be pointer-aligned");

0 commit comments

Comments
 (0)