Skip to content

Commit 2799cab

Browse files
committed
SwiftRemoteMirror: Dig into generic SIL boxes
Part 1: Generic SIL Boxes always have instatiated metadata with kind HeapGenericLocalVariable, which includes a metadata pointer for the boxed type. Part 2, after this, is to provide some kind of outgoing pointer map for fixed heap boxes, whose metadata may be shared among different but destructor-compatible types. rdar://problem/26240419
1 parent 05397e3 commit 2799cab

File tree

4 files changed

+74
-54
lines changed

4 files changed

+74
-54
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ class ReflectionContext
135135
if (!CDAddr.first)
136136
return nullptr;
137137

138+
// FIXME: Non-generic SIL boxes also use the HeapLocalVariable metadata
139+
// kind, but with a null capture descriptor right now (see
140+
// FixedBoxTypeInfoBase::allocate).
141+
//
142+
// Non-generic SIL boxes share metadata among types with compatible
143+
// layout, but we need some way to get an outgoing pointer map for them.
138144
auto *CD = getBuilder().getCaptureDescriptor(CDAddr.second);
139145
if (CD == nullptr)
140146
return nullptr;
@@ -144,9 +150,16 @@ class ReflectionContext
144150
return getClosureContextInfo(ObjectAddress, Info);
145151
}
146152

147-
case MetadataKind::HeapGenericLocalVariable:
148-
// SIL @box type
153+
case MetadataKind::HeapGenericLocalVariable: {
154+
// Generic SIL @box type - there is always an instantiated metadata
155+
// pointer for the boxed type.
156+
if (auto Meta = readMetadata(MetadataAddress.second)) {
157+
auto GenericHeapMeta =
158+
cast<TargetGenericBoxHeapMetadata<Runtime>>(Meta.getLocalBuffer());
159+
return getMetadataTypeInfo(GenericHeapMeta->BoxedType);
160+
}
149161
return nullptr;
162+
}
150163

151164
case MetadataKind::ErrorObject:
152165
// ErrorProtocol boxed existential on non-Objective-C runtime target

include/swift/Remote/MetadataReader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ class MetadataReader {
957957
case MetadataKind::Function:
958958
return _readMetadata<TargetFunctionTypeMetadata>(address);
959959
case MetadataKind::HeapGenericLocalVariable:
960-
return _readMetadata<TargetHeapLocalVariableMetadata>(address);
960+
return _readMetadata<TargetGenericBoxHeapMetadata>(address);
961961
case MetadataKind::HeapLocalVariable:
962962
return _readMetadata<TargetHeapLocalVariableMetadata>(address);
963963
case MetadataKind::Metatype:

include/swift/Runtime/Metadata.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "swift/Basic/Malloc.h"
3232
#include "swift/Basic/FlaggedPointer.h"
3333
#include "swift/Basic/RelativePointer.h"
34+
#include "../../../stdlib/public/SwiftShims/HeapObject.h"
3435

3536
namespace swift {
3637

@@ -2494,6 +2495,63 @@ struct TargetGenericMetadata {
24942495
};
24952496
using GenericMetadata = TargetGenericMetadata<InProcess>;
24962497

2498+
/// Heap metadata for a box, which may have been generated statically by the
2499+
/// compiler or by the runtime.
2500+
template <typename Runtime>
2501+
struct TargetBoxHeapMetadata : public TargetHeapMetadata<Runtime> {
2502+
/// The offset from the beginning of a box to its value.
2503+
unsigned Offset;
2504+
2505+
constexpr TargetBoxHeapMetadata(MetadataKind kind, unsigned offset)
2506+
: TargetHeapMetadata<Runtime>(kind), Offset(offset) {}
2507+
};
2508+
using BoxHeapMetadata = TargetBoxHeapMetadata<InProcess>;
2509+
2510+
/// Heap metadata for runtime-instantiated generic boxes.
2511+
template <typename Runtime>
2512+
struct TargetGenericBoxHeapMetadata : public TargetBoxHeapMetadata<Runtime> {
2513+
using super = TargetBoxHeapMetadata<Runtime>;
2514+
using super::Offset;
2515+
2516+
/// The type inside the box.
2517+
ConstTargetMetadataPointer<Runtime, TargetMetadata> BoxedType;
2518+
2519+
constexpr
2520+
TargetGenericBoxHeapMetadata(MetadataKind kind, unsigned offset,
2521+
ConstTargetMetadataPointer<Runtime, TargetMetadata> boxedType)
2522+
: TargetBoxHeapMetadata<Runtime>(kind, offset), BoxedType(boxedType)
2523+
{}
2524+
2525+
static unsigned getHeaderOffset(const Metadata *boxedType) {
2526+
// Round up the header size to alignment.
2527+
unsigned alignMask = boxedType->getValueWitnesses()->getAlignmentMask();
2528+
return (sizeof(HeapObject) + alignMask) & ~alignMask;
2529+
}
2530+
2531+
/// Project the value out of a box of this type.
2532+
OpaqueValue *project(HeapObject *box) const {
2533+
auto bytes = reinterpret_cast<char*>(box);
2534+
return reinterpret_cast<OpaqueValue *>(bytes + Offset);
2535+
}
2536+
2537+
/// Get the allocation size of this box.
2538+
unsigned getAllocSize() const {
2539+
return Offset + BoxedType->getValueWitnesses()->getSize();
2540+
}
2541+
2542+
/// Get the allocation alignment of this box.
2543+
unsigned getAllocAlignMask() const {
2544+
// Heap allocations are at least pointer aligned.
2545+
return BoxedType->getValueWitnesses()->getAlignmentMask()
2546+
| (alignof(void*) - 1);
2547+
}
2548+
2549+
static bool classof(const TargetMetadata<Runtime> *metadata) {
2550+
return metadata->getKind() == MetadataKind::HeapGenericLocalVariable;
2551+
}
2552+
};
2553+
using GenericBoxHeapMetadata = TargetGenericBoxHeapMetadata<InProcess>;
2554+
24972555
/// \brief The control structure of a generic or resilient protocol
24982556
/// conformance.
24992557
///

stdlib/public/runtime/HeapObject.cpp

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -133,57 +133,6 @@ SWIFT_RUNTIME_EXPORT
133133
extern "C" intptr_t swift_bufferHeaderSize() { return sizeof(HeapObject); }
134134

135135
namespace {
136-
/// Heap metadata for a box, which may have been generated statically by the
137-
/// compiler or by the runtime.
138-
struct BoxHeapMetadata : public HeapMetadata {
139-
/// The offset from the beginning of a box to its value.
140-
unsigned Offset;
141-
142-
constexpr BoxHeapMetadata(MetadataKind kind,
143-
unsigned offset)
144-
: HeapMetadata{kind}, Offset(offset)
145-
{}
146-
147-
148-
};
149-
150-
/// Heap metadata for runtime-instantiated generic boxes.
151-
struct GenericBoxHeapMetadata : public BoxHeapMetadata {
152-
/// The type inside the box.
153-
const Metadata *BoxedType;
154-
155-
constexpr GenericBoxHeapMetadata(MetadataKind kind,
156-
unsigned offset,
157-
const Metadata *boxedType)
158-
: BoxHeapMetadata{kind, offset},
159-
BoxedType(boxedType)
160-
{}
161-
162-
static unsigned getHeaderOffset(const Metadata *boxedType) {
163-
// Round up the header size to alignment.
164-
unsigned alignMask = boxedType->getValueWitnesses()->getAlignmentMask();
165-
return (sizeof(HeapObject) + alignMask) & ~alignMask;
166-
}
167-
168-
/// Project the value out of a box of this type.
169-
OpaqueValue *project(HeapObject *box) const {
170-
auto bytes = reinterpret_cast<char*>(box);
171-
return reinterpret_cast<OpaqueValue *>(bytes + Offset);
172-
}
173-
174-
/// Get the allocation size of this box.
175-
unsigned getAllocSize() const {
176-
return Offset + BoxedType->getValueWitnesses()->getSize();
177-
}
178-
179-
/// Get the allocation alignment of this box.
180-
unsigned getAllocAlignMask() const {
181-
// Heap allocations are at least pointer aligned.
182-
return BoxedType->getValueWitnesses()->getAlignmentMask()
183-
| (alignof(void*) - 1);
184-
}
185-
};
186-
187136
/// Heap object destructor for a generic box allocated with swift_allocBox.
188137
static void destroyGenericBox(HeapObject *o) {
189138
auto metadata = static_cast<const GenericBoxHeapMetadata *>(o->metadata);

0 commit comments

Comments
 (0)