Skip to content

Commit b925063

Browse files
committed
Checkpoint
1 parent 4ec659f commit b925063

File tree

4 files changed

+68
-16
lines changed

4 files changed

+68
-16
lines changed

include/swift/ABI/Metadata.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -1562,7 +1562,7 @@ struct TargetEnumMetadata : public TargetValueMetadata<Runtime> {
15621562
using StoredSize = typename Runtime::StoredSize;
15631563
using TargetValueMetadata<Runtime>::TargetValueMetadata;
15641564

1565-
const TargetEnumDescriptor<Runtime> *getDescription() const {
1565+
const swift::TargetEnumDescriptor<Runtime> *getDescription() const {
15661566
return llvm::cast<TargetEnumDescriptor<Runtime>>(this->Description);
15671567
}
15681568

@@ -1617,6 +1617,14 @@ struct TargetEnumMetadata : public TargetValueMetadata<Runtime> {
16171617
return trailingFlags->isCanonicalStaticSpecialization();
16181618
}
16191619

1620+
bool hasSpareBits() const {
1621+
return getDescription()->hasSpareBits();
1622+
}
1623+
1624+
size_t getEnumSpareBits() const {
1625+
return getDescription()->getEnumSpareBits();
1626+
}
1627+
16201628
const MetadataTrailingFlags *getTrailingFlags() const {
16211629
auto description = getDescription();
16221630
auto flags = description->getFullGenericContextHeader()
@@ -4821,8 +4829,9 @@ class TargetEnumDescriptor final
48214829
size_t getEnumSpareBits() const {
48224830
assert(hasSpareBits());
48234831
auto header = *this->template getTrailingObjects<EnumSpareBitsHeader>();
4824-
size_t length = header.bytes;
4825-
EnumSpareBitsChunk *chunks = this->template getTrailingObjects<EnumSpareBitsChunk>();
4832+
size_t length = header.bytesCount;
4833+
// EnumSpareBitsChunk *chunks = this->template getTrailingObjects<EnumSpareBitsChunk>();
4834+
auto chunks = this->template getTrailingObjects<EnumSpareBitsChunk>();
48264835
// TODO: Convert mask data into some sort of SpareBits object
48274836

48284837
return length;

include/swift/ABI/MetadataValues.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -1458,7 +1458,11 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
14581458
Class_HasVTable = 15,
14591459

14601460
/// Set if the context descriptor includes a spare bit mask
1461-
Enum_HasSpareBits = 9
1461+
Enum_HasSpareBits = 9,
1462+
1463+
/// Set if this is a "simple" Multi-payload enum that uses
1464+
/// a trailing tag to discriminate cases (no XIs or spare bits)
1465+
Enum_SimpleMPE = 10
14621466
};
14631467

14641468
public:
@@ -1529,6 +1533,9 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
15291533
FLAGSET_DEFINE_FLAG_ACCESSORS(Enum_HasSpareBits,
15301534
enum_hasSpareBits,
15311535
enum_setHasSpareBits)
1536+
FLAGSET_DEFINE_FLAG_ACCESSORS(Enum_SimpleMPE,
1537+
enum_simpleMPE,
1538+
enum_setSimpleMPE)
15321539
};
15331540

15341541
/// Extra flags for resilient classes, since we need more than 16 bits of

include/swift/Remote/MetadataReader.h

+44-11
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
#include <vector>
3434
#include <unordered_map>
35-
35+
#include <iostream>
3636
#include <inttypes.h>
3737

3838
namespace swift {
@@ -781,9 +781,17 @@ class MetadataReader {
781781
case MetadataKind::Class:
782782
return readNominalTypeFromClassMetadata(Meta, skipArtificialSubclasses);
783783
case MetadataKind::Struct:
784-
case MetadataKind::Enum:
785784
case MetadataKind::Optional:
786785
return readNominalTypeFromMetadata(Meta);
786+
case MetadataKind::Enum: {
787+
auto d = readNominalTypeFromMetadata(Meta);
788+
auto enumMeta = cast<TargetEnumMetadata<Runtime>>(Meta);
789+
// auto hasSpareBits = enumMeta->hasSpareBits();
790+
// auto spareBitsLength = enumMeta->getEnumSpareBits();
791+
//
792+
//
793+
return d;
794+
}
787795
case MetadataKind::Tuple: {
788796
auto tupleMeta = cast<TargetTupleTypeMetadata<Runtime>>(Meta);
789797

@@ -1020,24 +1028,36 @@ class MetadataReader {
10201028
auto buffer = (uint8_t *)nullptr;
10211029
unsigned available = 0; // Size of data in buffer
10221030

1023-
// In the first read, just grab the initial flag value...
1024-
unsigned sizeEstimate = sizeof(ContextDescriptorFlags);
1031+
// We get a big perf win by reading more data initially,
1032+
// but we don't want to overrun a page. Here's a conservative
1033+
// guess of how much space is left in the page.
1034+
unsigned long spaceInPage = 256UL - (address & 0xff);
1035+
1036+
// TODO: Some clients (`heap`) map an entire VM region; for
1037+
// those clients, it would be best to just tell them the
1038+
// starting remote address and have them tell us the local
1039+
// address and number of available bytes. That would always
1040+
// obtain the entire descriptor with a single `readBytes` call.
1041+
1042+
// Initial read: At least enough to get all the flags. More if we can.
1043+
unsigned sizeEstimate = std::max(sizeof(ContextDescriptorFlags), spaceInPage);
10251044
while (available < sizeEstimate) {
10261045
// The first `available` bytes have already been read, so grow
1027-
// the buffer and read more bytes to fulfill `sizeEstimate`
1028-
auto newbuffer = (uint8_t *)realloc(buffer, sizeEstimate);
1046+
// the buffer and read at least enough bytes to fulfill `sizeEstimate`
1047+
auto newSize = sizeEstimate;
1048+
auto newbuffer = (uint8_t *)realloc(buffer, newSize);
10291049
if (!newbuffer) {
10301050
free(buffer);
10311051
return nullptr;
10321052
}
10331053
buffer = newbuffer;
10341054
if (!Reader->readBytes(RemoteAddress(address + available),
10351055
buffer + available,
1036-
sizeEstimate - available)) {
1056+
newSize - available)) {
10371057
free(buffer);
10381058
return nullptr;
10391059
}
1040-
available = sizeEstimate;
1060+
available = newSize;
10411061

10421062
// Based on the data so far, update our guess of the full descriptor size.
10431063

@@ -1053,7 +1073,7 @@ class MetadataReader {
10531073
break;
10541074

10551075
// For types that use trailing objects, ask the trailing object logic to
1056-
// look at what we have so far and tell us whether we're done or not.
1076+
// estimate the total size based on what we have so far.
10571077
case ContextDescriptorKind::Extension: {
10581078
sizeEstimate = TargetExtensionContextDescriptor<Runtime>::totalSizeOfPartialObject(buffer, available);
10591079
break;
@@ -1085,13 +1105,26 @@ class MetadataReader {
10851105

10861106
// We don't know about this kind of context.
10871107
default:
1108+
free(buffer);
10881109
return nullptr;
10891110
}
10901111
}
10911112

10921113
// After exiting loop above, `sizeEstimate` is the true size of the
1093-
// descriptor with all trailing objects and buffer holds at least that much
1094-
// data.
1114+
// descriptor with all trailing objects and buffer holds `available` bytes
1115+
// (which is at least as large as `sizeEstimate`)
1116+
1117+
// If we're significantly over-allocated, copy to a more
1118+
// appropriately-sized buffer.
1119+
if (sizeEstimate < (available - available / 4)) {
1120+
auto newbuffer = (uint8_t *)malloc(sizeEstimate);
1121+
if (newbuffer != nullptr) {
1122+
memcpy(newbuffer, buffer, sizeEstimate);
1123+
free(buffer);
1124+
buffer = newbuffer;
1125+
available = sizeEstimate;
1126+
}
1127+
}
10951128

10961129
// Insert the final object into the descriptor cache and return it
10971130
OwnedContextDescriptorRef readResult(buffer);

lib/IRGen/GenMeta.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -1518,7 +1518,7 @@ namespace {
15181518

15191519
bool needsSpareBitMask() const {
15201520
// TODO: Fix this
1521-
return false;
1521+
return true;
15221522
}
15231523

15241524

@@ -1599,6 +1599,8 @@ namespace {
15991599
void maybeAddSpareBitMask() {
16001600
if (needsSpareBitMask()) {
16011601
// TODO: Add spare bit mask data
1602+
B.addInt32(4); // Number of bytes in mask
1603+
B.addInt32(0x11223300); // First 32 bits of mask
16021604
}
16031605
}
16041606
};
@@ -4834,6 +4836,7 @@ namespace {
48344836
if (hasTrailingFlags()) {
48354837
init.addInt64(0);
48364838
}
4839+
// TODO: Add spare bits if appropriate
48374840
Size structSize = init.getNextOffsetFromGlobal();
48384841

48394842
auto global = init.finishAndCreateGlobal("", IGM.getPointerAlignment(),

0 commit comments

Comments
 (0)