Skip to content

Commit 1c26aa8

Browse files
committed
Merge pull request #2298 from bitjammer/closure-metadata
MetadataReader infrastructure for reading capture descriptors
2 parents 936d4e5 + 3a3cafc commit 1c26aa8

File tree

3 files changed

+104
-76
lines changed

3 files changed

+104
-76
lines changed

include/swift/Reflection/Records.h

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -341,63 +341,6 @@ class BuiltinTypeDescriptorIterator
341341
}
342342
};
343343

344-
/// A key-value pair in a TypeRef -> MetadataSource map.
345-
struct GenericMetadataSource {
346-
using Key = RelativeDirectPointer<const char>;
347-
using Value = Key;
348-
349-
const Key MangledTypeName;
350-
const Value EncodedMetadataSource;
351-
};
352-
353-
/// Describes the layout of a heap closure.
354-
///
355-
/// For simplicity's sake and other reasons, this shouldn't contain
356-
/// architecture-specifically sized things like direct pointers, uintptr_t, etc.
357-
struct CaptureDescriptor {
358-
public:
359-
360-
/// The number of captures in the closure and the number of typerefs that
361-
/// immediately follow this struct.
362-
const uint32_t NumCaptures;
363-
364-
/// The number of sources of metadata available in the MetadataSourceMap
365-
/// directly following the list of capture's typerefs.
366-
const uint32_t NumMetadataSources;
367-
368-
/// The number of items in the NecessaryBindings structure at the head of
369-
/// the closure.
370-
const uint32_t NumBindings;
371-
372-
/// Get the key-value pair for the ith generic metadata source.
373-
const GenericMetadataSource &getGenericMetadataSource(size_t i) const {
374-
assert(i <= NumMetadataSources &&
375-
"Generic metadata source index out of range");
376-
auto Begin = getGenericMetadataSourceBuffer();
377-
return Begin[i];
378-
}
379-
380-
/// Get the typeref (encoded as a mangled type name) of the ith
381-
/// closure capture.
382-
const RelativeDirectPointer<const char> &
383-
getCaptureMangledTypeName(size_t i) const {
384-
assert(i <= NumCaptures && "Capture index out of range");
385-
auto Begin = getCaptureTypeRefBuffer();
386-
return Begin[i];
387-
}
388-
389-
private:
390-
const GenericMetadataSource *getGenericMetadataSourceBuffer() const {
391-
auto BeginTR = reinterpret_cast<const char *>(getCaptureTypeRefBuffer());
392-
auto EndTR = BeginTR + NumCaptures * sizeof(GenericMetadataSource);
393-
return reinterpret_cast<const GenericMetadataSource *>(EndTR);
394-
}
395-
396-
const RelativeDirectPointer<const char> *getCaptureTypeRefBuffer() const {
397-
return reinterpret_cast<const RelativeDirectPointer<const char> *>(this+1);
398-
}
399-
};
400-
401344
} // end namespace reflection
402345
} // end namespace swift
403346

include/swift/Remote/MetadataReader.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ namespace remote {
3131
template <typename Runtime>
3232
using SharedTargetMetadataRef = std::shared_ptr<TargetMetadata<Runtime>>;
3333

34+
using SharedCaptureDescriptor = std::shared_ptr<const CaptureDescriptor>;
35+
3436
template <typename Runtime>
3537
using SharedTargetNominalTypeDescriptorRef
3638
= std::shared_ptr<TargetNominalTypeDescriptor<Runtime>>;
@@ -527,7 +529,7 @@ class MetadataReader {
527529
case MetadataKind::ForeignClass:
528530
return Builder.getUnnamedForeignClassType();
529531
case MetadataKind::HeapLocalVariable:
530-
return Builder.getUnnamedForeignClassType(); // FIXME?
532+
return Builder.getUnnamedForeignClassType(); // FIXME?
531533
case MetadataKind::HeapGenericLocalVariable:
532534
return Builder.getUnnamedForeignClassType(); // FIXME?
533535
case MetadataKind::ErrorObject:
@@ -805,6 +807,39 @@ class MetadataReader {
805807
TypeCache.insert({metadata.getAddress(), nominal});
806808
return nominal;
807809
}
810+
811+
/// Read the entire CaptureDescriptor in this address space, including
812+
/// trailing capture typeref relative offsets, and GenericMetadataSource
813+
/// pairs.
814+
SharedCaptureDescriptor readCaptureDescriptor(StoredPointer Address) {
815+
816+
uint32_t NumCaptures = 0;
817+
uint32_t NumMetadataSources = 0;
818+
819+
StoredSize Offset = 0;
820+
821+
if (!Reader->readInteger(Address + Offset, &NumCaptures))
822+
return nullptr;
823+
824+
Offset += sizeof(NumCaptures);
825+
826+
if (!Reader->readInteger(Address + Offset, &NumMetadataSources))
827+
return nullptr;
828+
829+
StoredSize Size = sizeof(CaptureDescriptor) +
830+
NumCaptures * sizeof(RelativeDirectPointer<const char>) +
831+
NumMetadataSources * sizeof(GenericMetadataSource);
832+
833+
auto Buffer = (uint8_t *)malloc(Size);
834+
835+
if (!Reader->readBytes(Address, Buffer, Size)) {
836+
free(Buffer);
837+
return nullptr;
838+
}
839+
840+
auto RawDescriptor = reinterpret_cast<const CaptureDescriptor *>(Buffer);
841+
return SharedCaptureDescriptor(RawDescriptor, /*deleter*/ free);
842+
}
808843
};
809844

810845
} // end namespace remote

include/swift/Runtime/Metadata.h

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,29 +1750,79 @@ struct TargetClassMetadata : public TargetHeapMetadata<Runtime> {
17501750
};
17511751
using ClassMetadata = TargetClassMetadata<InProcess>;
17521752

1753+
/// A key-value pair in a TypeRef -> MetadataSource map.
1754+
struct GenericMetadataSource {
1755+
using Key = RelativeDirectPointer<const char>;
1756+
using Value = Key;
1757+
1758+
const Key MangledTypeName;
1759+
const Value EncodedMetadataSource;
1760+
};
1761+
1762+
/// Describes the layout of a heap closure.
1763+
///
1764+
/// For simplicity's sake and other reasons, this shouldn't contain
1765+
/// architecture-specifically sized things like direct pointers, uintptr_t, etc.
1766+
///
1767+
/// Following the CaptureDescriptor are:
1768+
/// - a list of direct relative offsets to the mangled type names of the
1769+
/// captures (these aren't in the DATA segment, however).
1770+
/// - a list of GenericMetadataSource objects - each element is a pair of:
1771+
/// - MangledTypeName (for a GenericTypeParameterTypeRef)
1772+
/// - EncodededMetadataSource (an encoded string like TypeRefs, but describe
1773+
/// the method of crawling to the metadata for that generic type parameter.
1774+
struct CaptureDescriptor {
1775+
public:
1776+
1777+
/// The number of captures in the closure and the number of typerefs that
1778+
/// immediately follow this struct.
1779+
const uint32_t NumCaptures;
1780+
1781+
/// The number of sources of metadata available in the MetadataSourceMap
1782+
/// directly following the list of capture's typerefs.
1783+
const uint32_t NumMetadataSources;
1784+
1785+
/// The number of items in the NecessaryBindings structure at the head of
1786+
/// the closure.
1787+
const uint32_t NumBindings;
1788+
1789+
/// Get the key-value pair for the ith generic metadata source.
1790+
const GenericMetadataSource &getGenericMetadataSource(size_t i) const {
1791+
assert(i <= NumMetadataSources &&
1792+
"Generic metadata source index out of range");
1793+
auto Begin = getGenericMetadataSourceBuffer();
1794+
return Begin[i];
1795+
}
1796+
1797+
/// Get the typeref (encoded as a mangled type name) of the ith
1798+
/// closure capture.
1799+
const RelativeDirectPointer<const char> &
1800+
getCaptureMangledTypeName(size_t i) const {
1801+
assert(i <= NumCaptures && "Capture index out of range");
1802+
auto Begin = getCaptureTypeRefBuffer();
1803+
return Begin[i];
1804+
}
1805+
1806+
private:
1807+
const GenericMetadataSource *getGenericMetadataSourceBuffer() const {
1808+
auto BeginTR = reinterpret_cast<const char *>(getCaptureTypeRefBuffer());
1809+
auto EndTR = BeginTR + NumCaptures * sizeof(GenericMetadataSource);
1810+
return reinterpret_cast<const GenericMetadataSource *>(EndTR);
1811+
}
1812+
1813+
const RelativeDirectPointer<const char> *getCaptureTypeRefBuffer() const {
1814+
return reinterpret_cast<const RelativeDirectPointer<const char> *>(this+1);
1815+
}
1816+
};
1817+
17531818
/// The structure of metadata for heap-allocated local variables.
17541819
/// This is non-type metadata.
1755-
///
1756-
/// It would be nice for tools to be able to dynamically discover the
1757-
/// type of a heap-allocated local variable. This should not require
1758-
/// us to aggressively produce metadata for the type, though. The
1759-
/// obvious solution is to simply place the mangling of the type after
1760-
/// the variable metadata.
1761-
///
1762-
/// One complication is that, in generic code, we don't want something
1763-
/// as low-priority (sorry!) as the convenience of tools to force us
1764-
/// to generate per-instantiation metadata for capturing variables.
1765-
/// In these cases, the heap-destructor function will be using
1766-
/// information stored in the allocated object (rather than in
1767-
/// metadata) to actually do the work of destruction, but even then,
1768-
/// that information needn't be metadata for the actual variable type;
1769-
/// consider the case of local variable of type (T, Int).
1770-
///
1771-
/// Anyway, that's all something to consider later.
17721820
template <typename Runtime>
17731821
struct TargetHeapLocalVariableMetadata
17741822
: public TargetHeapMetadata<Runtime> {
1775-
// No extra fields for now.
1823+
using StoredPointer = typename Runtime::StoredPointer;
1824+
uint32_t OffsetToFirstCapture;
1825+
TargetPointer<Runtime, CaptureDescriptor> CaptureDescription;
17761826
};
17771827
using HeapLocalVariableMetadata
17781828
= TargetHeapLocalVariableMetadata<InProcess>;

0 commit comments

Comments
 (0)