Fix a bug in weak reference handling, where weak refers were being removed from

the table incorrectly, causing objects inserted at offsets due to hash
collisions to fail to be moved up and then fail to be found later.

Test by Eric Wasylishen!
This commit is contained in:
theraven 2014-03-04 09:59:24 +00:00
parent 58919f07d4
commit bd0728f393
3 changed files with 47 additions and 4 deletions

View File

@ -22,6 +22,7 @@ set(TESTS
ProtocolCreation.m
ResurrectInDealloc_arc.m
RuntimeTest.m
WeakReferences_arc.m
objc_msgSend.m
msgInterpose.m
)

45
Test/WeakReferences_arc.m Normal file
View File

@ -0,0 +1,45 @@
#include "Test.h"
#define SIZE 5000
int main(int argc, const char * argv[])
{
@autoreleasepool {
id __weak refs[SIZE];
id values[SIZE];
// Setup
for (int i=0; i<SIZE; i++)
{
values[i] = [Test new];
refs[i] = values[i];
}
// Sanity check
for (int i=0; i<SIZE; i++)
{
assert(refs[i] != nil);
assert(refs[i] == values[i]);
}
// Release the value, one by one
for (int indexToRelease=0; indexToRelease<SIZE; indexToRelease++)
{
values[indexToRelease] = nil;
// Check all refs
for (int i=0; i<SIZE; i++)
{
if (i <= indexToRelease)
{
assert(refs[i] == nil);
}
else
{
assert(refs[i] != nil);
assert(refs[i] == values[i]);
}
}
}
}
return 0;
}

5
arc.m
View File

@ -632,10 +632,6 @@ static void zeroRefs(WeakRef *ref, BOOL shouldFree)
{
free(ref);
}
else
{
memset(ref, 0, sizeof(WeakRef));
}
}
void objc_delete_weak_refs(id obj)
@ -645,6 +641,7 @@ void objc_delete_weak_refs(id obj)
if (0 != oldRef)
{
zeroRefs(oldRef, NO);
weak_ref_remove(weakRefs, obj);
}
}