Skip to content

Commit 6552ac8

Browse files
committed
Merge pull request #2556 from bitjammer/remote-mirror-generic-box
SwiftRemoteMirror: Dig into generic SIL boxes
2 parents 3c1a94f + 2799cab commit 6552ac8

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)