Skip to content

Commit ea87a27

Browse files
committed
Redesign the spare bit mask calculation
This adds a `getSpareBits` method to all the TypeInfo classes that returns a suitable bitmask indicating the spare bits available in values of this type. This gives us a way to recursively explore the type tree and build up a full spare bit mask for an arbitrary type. Happily, it appears we actually do have enough information to do this calculation entirely from first principles, without requiring additional reflection information. So once this is stable, we should remove my earlier incomplete effort to publish spare bit mask info in the reflection data, as that adds unnecessary metadata to every binary. This doubtless still has plenty of holes, but seems sufficient to handle a few basic enum types, including the stdlib DecodingError which was used as an example to work out some key issues.
1 parent e546684 commit ea87a27

File tree

6 files changed

+368
-142
lines changed

6 files changed

+368
-142
lines changed

include/swift/RemoteInspection/BitMask.h

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class BitMask {
3535
~BitMask() {
3636
free(mask);
3737
}
38+
private:
3839
// Construct a bitmask of the appropriate number of bytes
3940
// initialized to all bits set
4041
BitMask(unsigned sizeInBytes = 0): size(sizeInBytes) {
@@ -58,6 +59,24 @@ class BitMask {
5859

5960
memset(mask, 0xff, size);
6061
}
62+
63+
public:
64+
static BitMask zeroMask(unsigned sizeInBytes) {
65+
auto mask = BitMask(sizeInBytes);
66+
mask.makeZero();
67+
return mask;
68+
}
69+
70+
static BitMask oneMask(unsigned sizeInBytes) {
71+
auto mask = BitMask(sizeInBytes);
72+
return mask;
73+
}
74+
75+
BitMask(unsigned sizeInBytes, uint64_t sourceMask): size(sizeInBytes) {
76+
mask = (uint8_t *)calloc(1, sizeInBytes);
77+
memcpy(mask, &sourceMask, sizeInBytes);
78+
}
79+
6180
// Construct a bitmask of the appropriate number of bytes
6281
// initialized with bits from the specified buffer
6382
BitMask(unsigned sizeInBytes, const uint8_t *initialValue,
@@ -184,13 +203,7 @@ class BitMask {
184203
}
185204

186205
int countZeroBits() const {
187-
static const int counter[] =
188-
{4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
189-
int bits = 0;
190-
for (unsigned i = 0; i < size; ++i) {
191-
bits += counter[mask[i] >> 4] + counter[mask[i] & 15];
192-
}
193-
return bits;
206+
return (size * 8) - countSetBits();
194207
}
195208

196209
// Treat the provided value as a mask, `and` it with
@@ -242,6 +255,12 @@ class BitMask {
242255
#endif
243256
}
244257

258+
void keepOnlyLeastSignificantBytes(unsigned n) {
259+
if (size > n) {
260+
size = n;
261+
}
262+
}
263+
245264
unsigned numBits() const {
246265
return size * 8;
247266
}

include/swift/RemoteInspection/TypeLowering.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "llvm/Support/Casting.h"
2424
#include "swift/Remote/MetadataReader.h"
2525
#include "swift/Remote/TypeInfoProvider.h"
26+
#include "swift/RemoteInspection/BitMask.h"
2627
#include "swift/RemoteInspection/DescriptorFinder.h"
2728

2829
#include <memory>
@@ -34,6 +35,7 @@ using llvm::cast;
3435
using llvm::dyn_cast;
3536
using remote::RemoteRef;
3637

38+
class TypeConverter;
3739
class TypeRef;
3840
class TypeRefBuilder;
3941
class BuiltinTypeDescriptor;
@@ -158,6 +160,11 @@ class TypeInfo {
158160
return false;
159161
}
160162

163+
// Calculate and return the spare bit mask for this type
164+
virtual BitMask getSpareBits(TypeConverter &TC, bool &hasAddrOnly) const {
165+
return BitMask::zeroMask(getSize());
166+
}
167+
161168
virtual ~TypeInfo() { }
162169
};
163170

@@ -195,6 +202,8 @@ class BuiltinTypeInfo : public TypeInfo {
195202
remote::RemoteAddress address,
196203
int *extraInhabitantIndex) const override;
197204

205+
BitMask getSpareBits(TypeConverter &TC, bool &hasAddrOnly) const override;
206+
198207
static bool classof(const TypeInfo *TI) {
199208
return TI->getKind() == TypeInfoKind::Builtin;
200209
}
@@ -222,6 +231,8 @@ class RecordTypeInfo : public TypeInfo {
222231
remote::RemoteAddress address,
223232
int *index) const override;
224233

234+
BitMask getSpareBits(TypeConverter &TC, bool &hasAddrOnly) const override;
235+
225236
static bool classof(const TypeInfo *TI) {
226237
return TI->getKind() == TypeInfoKind::Record;
227238
}
@@ -330,6 +341,8 @@ class ReferenceTypeInfo : public TypeInfo {
330341
return reader.readHeapObjectExtraInhabitantIndex(address, extraInhabitantIndex);
331342
}
332343

344+
BitMask getSpareBits(TypeConverter &TC, bool &hasAddrOnly) const override;
345+
333346
static bool classof(const TypeInfo *TI) {
334347
return TI->getKind() == TypeInfoKind::Reference;
335348
}

0 commit comments

Comments
 (0)