Skip to content

Commit

Permalink
organize the table so that unique suffixes get a single entry instead…
Browse files Browse the repository at this point in the history
… of a huge linked list of mostly-empty 2kB tables, to improve speed and reduce table size
  • Loading branch information
mikeash committed Oct 16, 2011
1 parent fb4083c commit 8ac17d1
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 4,965 deletions.
16 changes: 11 additions & 5 deletions NativeZWRChecker/sourcedumper.py
Original file line number Diff line number Diff line change
Expand Up @@ -1142,13 +1142,18 @@ def PrintArray(hashesToNames, indent):
for hash in matching:
if len(hash) > 1:
d[hash[1:]] = hashesToNames[hash]
if d:
print '%s[0x%x] = (void *[256]) { // %d' % (indentStr, byte, indent)
if len(d) > 1:
print '%s[0x%x] = { 1, (struct _NativeZWRTableEntry[256]) { // %d' % (indentStr, byte, indent)
PrintArray(d, indent + 1)
print indentStr + '},'
print indentStr + '}},'
elif d:
hash = d.keys()[0]
hashBytes = ['0x%x' % ord(x) for x in hash]
hashC = ', '.join(hashBytes)
print '%s[0x%x] = { 0, (unsigned char[]){ %s } }, // %s' % (indentStr, byte, hashC, d[hash])
else:
for hash in matching:
print '%s[0x%x] = &_MAZeroingWeakRefClassPresentToken, // %s' % (indentStr, byte, hashesToNames[hash])
print '%s[0x%x] = { 0, &_MAZeroingWeakRefClassPresentToken }, // %s' % (indentStr, byte, hashesToNames[hash])



Expand All @@ -1157,6 +1162,7 @@ def PrintArray(hashesToNames, indent):
hashesToNames[x['sha'].data] = x['name']

print 'static void *_MAZeroingWeakRefClassPresentToken = &_MAZeroingWeakRefClassPresentToken;'
print 'static void *_MAZeroingWeakRefClassNativeWeakReferenceNotAllowedTable[256] = {'
print 'struct _NativeZWRTableEntry { BOOL isTable; void *ptr; };'
print 'static struct _NativeZWRTableEntry _MAZeroingWeakRefClassNativeWeakReferenceNotAllowedTable[256] = {'
PrintArray(hashesToNames, 1)
print '};'
33 changes: 14 additions & 19 deletions Source/MAZeroingWeakRef.m
Original file line number Diff line number Diff line change
Expand Up @@ -476,37 +476,32 @@ static BOOL IsKVOSubclass(id obj)
// removing all private classes from the table is a lot of work. Using
// hashes allows for reasonably quick checks and no private API names.
// It's implemented as a tree of tables, where each individual table
// maps to a single byte. The top level of the tree is a 256-entry table
// whose entries are either NULL (for leading bytes which aren't present
// at all) or point to another 256-entry table. This continues 20 levels
// deep (the number of bytes in a SHA1 hash), at which point the special
// pointer _MAZeroingWeakRefClassPresentToken is used to indicate the
// final bytes which are present. HashPresentInTable therefore checks
// the first byte of the hash to see if there's a table for it in the
// global table, checks the second byte to see if there's a table in
// the child table, etc., all the way down until it hits the end. This
// design makes for a good compromise between initialization efficiency
// (the table is completely static data) and runtime efficiency (the
// entry check does a bit of pointer chasing but is just 20 checks,
// and the common case of no entry usually exits really early).
static BOOL HashPresentInTable(unsigned char *hash, int length, void **table)
// maps to a single byte. The top level of the tree is a 256-entry table.
// Table entries are a NULL pointer for leading bytes which aren't present
// at all. Other table entries can either contain a pointer to another
// table (in which case the process continues recursively), or they can
// contain a pointer to a single hash. In this second case, this indicates
// that this hash is the only one present in the table with that prefix
// and so a simple comparison can be used to check for membership at
// that point.
static BOOL HashPresentInTable(unsigned char *hash, int length, struct _NativeZWRTableEntry *table)
{
while(length)
{
void *entry = table[hash[0]];
if(entry == NULL)
struct _NativeZWRTableEntry entry = table[hash[0]];
if(entry.ptr == NULL)
{
return NO;
}
else if(entry == _MAZeroingWeakRefClassPresentToken)
else if(!entry.isTable)
{
return YES;
return memcmp(entry.ptr, hash + 1, length - 1) == 0;
}
else
{
hash++;
length--;
table = entry;
table = entry.ptr;
}
}
return NO;
Expand Down
Loading

0 comments on commit 8ac17d1

Please sign in to comment.