Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions include/swift/Reflection/ReflectionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ class ReflectionContext
if (!CDAddr.first)
return nullptr;

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

case MetadataKind::HeapGenericLocalVariable:
// SIL @box type
case MetadataKind::HeapGenericLocalVariable: {
// Generic SIL @box type - there is always an instantiated metadata
// pointer for the boxed type.
if (auto Meta = readMetadata(MetadataAddress.second)) {
auto GenericHeapMeta =
cast<TargetGenericBoxHeapMetadata<Runtime>>(Meta.getLocalBuffer());
return getMetadataTypeInfo(GenericHeapMeta->BoxedType);
}
return nullptr;
}

case MetadataKind::ErrorObject:
// ErrorProtocol boxed existential on non-Objective-C runtime target
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Remote/MetadataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ class MetadataReader {
case MetadataKind::Function:
return _readMetadata<TargetFunctionTypeMetadata>(address);
case MetadataKind::HeapGenericLocalVariable:
return _readMetadata<TargetHeapLocalVariableMetadata>(address);
return _readMetadata<TargetGenericBoxHeapMetadata>(address);
case MetadataKind::HeapLocalVariable:
return _readMetadata<TargetHeapLocalVariableMetadata>(address);
case MetadataKind::Metatype:
Expand Down
58 changes: 58 additions & 0 deletions include/swift/Runtime/Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "swift/Basic/Malloc.h"
#include "swift/Basic/FlaggedPointer.h"
#include "swift/Basic/RelativePointer.h"
#include "../../../stdlib/public/SwiftShims/HeapObject.h"

namespace swift {

Expand Down Expand Up @@ -2494,6 +2495,63 @@ struct TargetGenericMetadata {
};
using GenericMetadata = TargetGenericMetadata<InProcess>;

/// Heap metadata for a box, which may have been generated statically by the
/// compiler or by the runtime.
template <typename Runtime>
struct TargetBoxHeapMetadata : public TargetHeapMetadata<Runtime> {
/// The offset from the beginning of a box to its value.
unsigned Offset;

constexpr TargetBoxHeapMetadata(MetadataKind kind, unsigned offset)
: TargetHeapMetadata<Runtime>(kind), Offset(offset) {}
};
using BoxHeapMetadata = TargetBoxHeapMetadata<InProcess>;

/// Heap metadata for runtime-instantiated generic boxes.
template <typename Runtime>
struct TargetGenericBoxHeapMetadata : public TargetBoxHeapMetadata<Runtime> {
using super = TargetBoxHeapMetadata<Runtime>;
using super::Offset;

/// The type inside the box.
ConstTargetMetadataPointer<Runtime, TargetMetadata> BoxedType;

constexpr
TargetGenericBoxHeapMetadata(MetadataKind kind, unsigned offset,
ConstTargetMetadataPointer<Runtime, TargetMetadata> boxedType)
: TargetBoxHeapMetadata<Runtime>(kind, offset), BoxedType(boxedType)
{}

static unsigned getHeaderOffset(const Metadata *boxedType) {
// Round up the header size to alignment.
unsigned alignMask = boxedType->getValueWitnesses()->getAlignmentMask();
return (sizeof(HeapObject) + alignMask) & ~alignMask;
}

/// Project the value out of a box of this type.
OpaqueValue *project(HeapObject *box) const {
auto bytes = reinterpret_cast<char*>(box);
return reinterpret_cast<OpaqueValue *>(bytes + Offset);
}

/// Get the allocation size of this box.
unsigned getAllocSize() const {
return Offset + BoxedType->getValueWitnesses()->getSize();
}

/// Get the allocation alignment of this box.
unsigned getAllocAlignMask() const {
// Heap allocations are at least pointer aligned.
return BoxedType->getValueWitnesses()->getAlignmentMask()
| (alignof(void*) - 1);
}

static bool classof(const TargetMetadata<Runtime> *metadata) {
return metadata->getKind() == MetadataKind::HeapGenericLocalVariable;
}
};
using GenericBoxHeapMetadata = TargetGenericBoxHeapMetadata<InProcess>;

/// \brief The control structure of a generic or resilient protocol
/// conformance.
///
Expand Down
51 changes: 0 additions & 51 deletions stdlib/public/runtime/HeapObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,57 +133,6 @@ SWIFT_RUNTIME_EXPORT
extern "C" intptr_t swift_bufferHeaderSize() { return sizeof(HeapObject); }

namespace {
/// Heap metadata for a box, which may have been generated statically by the
/// compiler or by the runtime.
struct BoxHeapMetadata : public HeapMetadata {
/// The offset from the beginning of a box to its value.
unsigned Offset;

constexpr BoxHeapMetadata(MetadataKind kind,
unsigned offset)
: HeapMetadata{kind}, Offset(offset)
{}


};

/// Heap metadata for runtime-instantiated generic boxes.
struct GenericBoxHeapMetadata : public BoxHeapMetadata {
/// The type inside the box.
const Metadata *BoxedType;

constexpr GenericBoxHeapMetadata(MetadataKind kind,
unsigned offset,
const Metadata *boxedType)
: BoxHeapMetadata{kind, offset},
BoxedType(boxedType)
{}

static unsigned getHeaderOffset(const Metadata *boxedType) {
// Round up the header size to alignment.
unsigned alignMask = boxedType->getValueWitnesses()->getAlignmentMask();
return (sizeof(HeapObject) + alignMask) & ~alignMask;
}

/// Project the value out of a box of this type.
OpaqueValue *project(HeapObject *box) const {
auto bytes = reinterpret_cast<char*>(box);
return reinterpret_cast<OpaqueValue *>(bytes + Offset);
}

/// Get the allocation size of this box.
unsigned getAllocSize() const {
return Offset + BoxedType->getValueWitnesses()->getSize();
}

/// Get the allocation alignment of this box.
unsigned getAllocAlignMask() const {
// Heap allocations are at least pointer aligned.
return BoxedType->getValueWitnesses()->getAlignmentMask()
| (alignof(void*) - 1);
}
};

/// Heap object destructor for a generic box allocated with swift_allocBox.
static void destroyGenericBox(HeapObject *o) {
auto metadata = static_cast<const GenericBoxHeapMetadata *>(o->metadata);
Expand Down