Skip to content

Commit e3d6a2b

Browse files
committed
IRGen: Correctly set class metadata base offset variable
We need to subtract the address point from the metadata size, since the metadata size includes prefix matter.
1 parent d41eedc commit e3d6a2b

File tree

4 files changed

+56
-10
lines changed

4 files changed

+56
-10
lines changed

lib/IRGen/GenMeta.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3529,11 +3529,20 @@ namespace {
35293529
IGF.Builder.CreateBitCast(superMetadata, IGF.IGM.Int8PtrTy),
35303530
IGM.getPointerAlignment());
35313531

3532-
Address slot = IGF.Builder.CreateConstByteArrayGEP(
3532+
Address sizeSlot = IGF.Builder.CreateConstByteArrayGEP(
35333533
metadataAsBytes,
35343534
layout.getMetadataSizeOffset());
3535-
slot = IGF.Builder.CreateBitCast(slot, IGM.Int32Ty->getPointerTo());
3536-
llvm::Value *size = IGF.Builder.CreateLoad(slot);
3535+
sizeSlot = IGF.Builder.CreateBitCast(sizeSlot, IGM.Int32Ty->getPointerTo());
3536+
llvm::Value *size = IGF.Builder.CreateLoad(sizeSlot);
3537+
3538+
Address addressPointSlot = IGF.Builder.CreateConstByteArrayGEP(
3539+
metadataAsBytes,
3540+
layout.getMetadataAddressPointOffset());
3541+
addressPointSlot = IGF.Builder.CreateBitCast(addressPointSlot, IGM.Int32Ty->getPointerTo());
3542+
llvm::Value *addressPoint = IGF.Builder.CreateLoad(addressPointSlot);
3543+
3544+
size = IGF.Builder.CreateSub(size, addressPoint);
3545+
35373546
if (IGM.SizeTy != IGM.Int32Ty)
35383547
size = IGF.Builder.CreateZExt(size, IGM.SizeTy);
35393548

lib/IRGen/MetadataLayout.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,11 @@ ClassMetadataLayout::ClassMetadataLayout(IRGenModule &IGM, ClassDecl *decl)
264264
super::addClassSize();
265265
}
266266

267+
void addClassAddressPoint() {
268+
Layout.MetadataAddressPoint = getNextOffset();
269+
super::addClassAddressPoint();
270+
}
271+
267272
void addInstanceSize() {
268273
Layout.InstanceSize = getNextOffset();
269274
super::addInstanceSize();
@@ -345,6 +350,11 @@ Size ClassMetadataLayout::getMetadataSizeOffset() const {
345350
return MetadataSize.getStaticOffset();
346351
}
347352

353+
Size ClassMetadataLayout::getMetadataAddressPointOffset() const {
354+
assert(MetadataAddressPoint.isStatic());
355+
return MetadataAddressPoint.getStaticOffset();
356+
}
357+
348358
Size ClassMetadataLayout::getInstanceSizeOffset() const {
349359
assert(InstanceSize.isStatic());
350360
return InstanceSize.getStaticOffset();

lib/IRGen/MetadataLayout.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ class ClassMetadataLayout : public NominalMetadataLayout {
170170
bool HasResilientSuperclass = false;
171171

172172
StoredOffset MetadataSize;
173+
StoredOffset MetadataAddressPoint;
173174

174175
StoredOffset InstanceSize;
175176
StoredOffset InstanceAlignMask;
@@ -218,6 +219,8 @@ class ClassMetadataLayout : public NominalMetadataLayout {
218219

219220
Size getMetadataSizeOffset() const;
220221

222+
Size getMetadataAddressPointOffset() const;
223+
221224
Size getInstanceSizeOffset() const;
222225

223226
Size getInstanceAlignMaskOffset() const;

test/IRGen/class_resilience.swift

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
33
// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
44
// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_class.swiftmodule -module-name=resilient_class -I %t %S/../Inputs/resilient_class.swift
5-
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience %s | %FileCheck %s
5+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
66
// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience -O %s
77

88
// CHECK: %swift.type = type { [[INT:i32|i64]] }
@@ -364,16 +364,24 @@ extension ResilientGenericOutsideParent {
364364

365365
// CHECK-LABEL: define private void @initialize_metadata_ResilientChild(i8*)
366366

367-
// Get the superclass...
367+
// Get the superclass size and address point...
368368

369369
// CHECK: [[SUPER:%.*]] = call %swift.type* @_T015resilient_class22ResilientOutsideParentCMa()
370370
// CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER]] to i8*
371371
// CHECK: [[SIZE_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{36|56}}
372372
// CHECK: [[SIZE_ADDR:%.*]] = bitcast i8* [[SIZE_TMP]] to i32*
373373
// CHECK: [[SIZE:%.*]] = load i32, i32* [[SIZE_ADDR]]
374+
// CHECK: [[ADDRESS_POINT_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{40|60}}
375+
// CHECK: [[ADDRESS_POINT_ADDR:%.*]] = bitcast i8* [[ADDRESS_POINT_TMP]] to i32*
376+
// CHECK: [[ADDRESS_POINT:%.*]] = load i32, i32* [[ADDRESS_POINT_ADDR]]
377+
378+
// CHECK: [[OFFSET:%.*]] = sub i32 [[SIZE]], [[ADDRESS_POINT]]
374379

375380
// Initialize class metadata base offset...
376-
// CHECK: store [[INT]] {{.*}}, [[INT]]* @_T016class_resilience14ResilientChildCMo
381+
// CHECK-32: store [[INT]] [[OFFSET]], [[INT]]* @_T016class_resilience14ResilientChildCMo
382+
383+
// CHECK-64: [[OFFSET_ZEXT:%.*]] = zext i32 [[OFFSET]] to i64
384+
// CHECK-64: store [[INT]] [[OFFSET_ZEXT]], [[INT]]* @_T016class_resilience14ResilientChildCMo
377385

378386
// Initialize the superclass field...
379387
// CHECK: store %swift.type* [[SUPER]], %swift.type** getelementptr inbounds ({{.*}})
@@ -385,16 +393,24 @@ extension ResilientGenericOutsideParent {
385393

386394
// CHECK-LABEL: define private void @initialize_metadata_FixedLayoutChild(i8*)
387395

388-
// Get the superclass...
396+
// Get the superclass size and address point...
389397

390398
// CHECK: [[SUPER:%.*]] = call %swift.type* @_T015resilient_class22ResilientOutsideParentCMa()
391399
// CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER]] to i8*
392400
// CHECK: [[SIZE_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{36|56}}
393401
// CHECK: [[SIZE_ADDR:%.*]] = bitcast i8* [[SIZE_TMP]] to i32*
394402
// CHECK: [[SIZE:%.*]] = load i32, i32* [[SIZE_ADDR]]
403+
// CHECK: [[ADDRESS_POINT_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{40|60}}
404+
// CHECK: [[ADDRESS_POINT_ADDR:%.*]] = bitcast i8* [[ADDRESS_POINT_TMP]] to i32*
405+
// CHECK: [[ADDRESS_POINT:%.*]] = load i32, i32* [[ADDRESS_POINT_ADDR]]
406+
407+
// CHECK: [[OFFSET:%.*]] = sub i32 [[SIZE]], [[ADDRESS_POINT]]
395408

396409
// Initialize class metadata base offset...
397-
// CHECK: store [[INT]] {{.*}}, [[INT]]* @_T016class_resilience16FixedLayoutChildCMo
410+
// CHECK-32: store [[INT]] [[OFFSET]], [[INT]]* @_T016class_resilience16FixedLayoutChildCMo
411+
412+
// CHECK-64: [[OFFSET_ZEXT:%.*]] = zext i32 [[OFFSET]] to i64
413+
// CHECK-64: store [[INT]] [[OFFSET_ZEXT]], [[INT]]* @_T016class_resilience16FixedLayoutChildCMo
398414

399415
// Initialize the superclass field...
400416
// CHECK: store %swift.type* [[SUPER]], %swift.type** getelementptr inbounds ({{.*}})
@@ -406,17 +422,25 @@ extension ResilientGenericOutsideParent {
406422

407423
// CHECK-LABEL: define private %swift.type* @create_generic_metadata_ResilientGenericChild(%swift.type_pattern*, i8**)
408424

409-
// Get the superclass...
425+
// Get the superclass size and address point...
410426

411427
// CHECK: [[SUPER:%.*]] = call %swift.type* @_T015resilient_class29ResilientGenericOutsideParentCMa(%swift.type* %T)
412428
// CHECK: [[SUPER_TMP:%.*]] = bitcast %swift.type* [[SUPER]] to %objc_class*
413429
// CHECK: [[SUPER_ADDR:%.*]] = bitcast %objc_class* [[SUPER_TMP]] to i8*
414430
// CHECK: [[SIZE_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{36|56}}
415431
// CHECK: [[SIZE_ADDR:%.*]] = bitcast i8* [[SIZE_TMP]] to i32*
416432
// CHECK: [[SIZE:%.*]] = load i32, i32* [[SIZE_ADDR]]
433+
// CHECK: [[ADDRESS_POINT_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{40|60}}
434+
// CHECK: [[ADDRESS_POINT_ADDR:%.*]] = bitcast i8* [[ADDRESS_POINT_TMP]] to i32*
435+
// CHECK: [[ADDRESS_POINT:%.*]] = load i32, i32* [[ADDRESS_POINT_ADDR]]
436+
437+
// CHECK: [[OFFSET:%.*]] = sub i32 [[SIZE]], [[ADDRESS_POINT]]
417438

418439
// Initialize class metadata base offset...
419-
// CHECK: store [[INT]] {{.*}}, [[INT]]* @_T016class_resilience21ResilientGenericChildCMo
440+
// CHECK-32: store [[INT]] [[OFFSET]], [[INT]]* @_T016class_resilience21ResilientGenericChildCMo
441+
442+
// CHECK-64: [[OFFSET_ZEXT:%.*]] = zext i32 [[OFFSET]] to i64
443+
// CHECK-64: store [[INT]] [[OFFSET_ZEXT]], [[INT]]* @_T016class_resilience21ResilientGenericChildCMo
420444

421445
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[SUPER_TMP]], [[INT]] 5)
422446
// CHECK: ret %swift.type* [[METADATA]]

0 commit comments

Comments
 (0)