mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
KeyPaths: Take a bit for encoding "let"-ness of stored properties.
If we know a key path component can be accessed as a stored property, then we should also know whether it's a `let` or not, so it should be safe to encode this in the key path pattern. Stage this change in by changing the number of bits used to store in-line offsets, fixing up the parts of the key path implementation that assumed that it took up the entire payload bitfield.
This commit is contained in:
@@ -773,22 +773,23 @@ emitKeyPathComponent(IRGenModule &IGM,
|
||||
case KeyPathPatternComponent::Kind::StoredProperty: {
|
||||
auto property = cast<VarDecl>(component.getStoredPropertyDecl());
|
||||
|
||||
auto addFixedOffset = [&](bool isStruct, llvm::Constant *offset) {
|
||||
auto addFixedOffset = [&](bool isStruct, bool isLet,
|
||||
llvm::Constant *offset) {
|
||||
if (auto offsetInt = dyn_cast_or_null<llvm::ConstantInt>(offset)) {
|
||||
auto offsetValue = offsetInt->getValue().getZExtValue();
|
||||
if (KeyPathComponentHeader::offsetCanBeInline(offsetValue)) {
|
||||
auto header = isStruct
|
||||
? KeyPathComponentHeader
|
||||
::forStructComponentWithInlineOffset(offsetValue)
|
||||
::forStructComponentWithInlineOffset(isLet, offsetValue)
|
||||
: KeyPathComponentHeader
|
||||
::forClassComponentWithInlineOffset(offsetValue);
|
||||
::forClassComponentWithInlineOffset(isLet, offsetValue);
|
||||
fields.addInt32(header.getData());
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto header = isStruct
|
||||
? KeyPathComponentHeader::forStructComponentWithOutOfLineOffset()
|
||||
: KeyPathComponentHeader::forClassComponentWithOutOfLineOffset();
|
||||
? KeyPathComponentHeader::forStructComponentWithOutOfLineOffset(isLet)
|
||||
: KeyPathComponentHeader::forClassComponentWithOutOfLineOffset(isLet);
|
||||
fields.addInt32(header.getData());
|
||||
fields.add(llvm::ConstantExpr::getTruncOrBitCast(offset, IGM.Int32Ty));
|
||||
};
|
||||
@@ -801,7 +802,7 @@ emitKeyPathComponent(IRGenModule &IGM,
|
||||
loweredBaseTy,
|
||||
property)) {
|
||||
// We have a known constant fixed offset.
|
||||
addFixedOffset(/*struct*/ true, offset);
|
||||
addFixedOffset(/*struct*/ true, property->isLet(), offset);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -811,7 +812,7 @@ emitKeyPathComponent(IRGenModule &IGM,
|
||||
auto fieldOffset = metadataLayout.getStaticFieldOffset(property);
|
||||
|
||||
auto header = KeyPathComponentHeader
|
||||
::forStructComponentWithUnresolvedFieldOffset();
|
||||
::forStructComponentWithUnresolvedFieldOffset(property->isLet());
|
||||
fields.addInt32(header.getData());
|
||||
fields.addInt32(fieldOffset.getValue());
|
||||
break;
|
||||
@@ -829,14 +830,14 @@ emitKeyPathComponent(IRGenModule &IGM,
|
||||
loweredBaseTy,
|
||||
property);
|
||||
assert(offset && "no constant offset for ConstantDirect field?!");
|
||||
addFixedOffset(/*struct*/ false, offset);
|
||||
addFixedOffset(/*struct*/ false, property->isLet(), offset);
|
||||
break;
|
||||
}
|
||||
case FieldAccess::NonConstantDirect: {
|
||||
// A constant offset that's determined at class realization time.
|
||||
// We have to load the offset from a global ivar.
|
||||
auto header = KeyPathComponentHeader
|
||||
::forClassComponentWithUnresolvedIndirectOffset();
|
||||
::forClassComponentWithUnresolvedIndirectOffset(property->isLet());
|
||||
fields.addInt32(header.getData());
|
||||
fields.addAlignmentPadding(IGM.getPointerAlignment());
|
||||
auto offsetVar = IGM.getAddrOfFieldOffset(property, NotForDefinition);
|
||||
@@ -846,8 +847,8 @@ emitKeyPathComponent(IRGenModule &IGM,
|
||||
case FieldAccess::ConstantIndirect: {
|
||||
// An offset that depends on the instance's generic parameterization,
|
||||
// but whose field offset is at a known vtable offset.
|
||||
auto header =
|
||||
KeyPathComponentHeader::forClassComponentWithUnresolvedFieldOffset();
|
||||
auto header = KeyPathComponentHeader
|
||||
::forClassComponentWithUnresolvedFieldOffset(property->isLet());
|
||||
fields.addInt32(header.getData());
|
||||
auto fieldOffset =
|
||||
getClassFieldOffsetOffset(IGM,
|
||||
|
||||
Reference in New Issue
Block a user