mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
Tweaks to match OSX pointer array behaviors more accurately.
This commit is contained in:
parent
5699959d39
commit
a1514249f3
3 changed files with 223 additions and 125 deletions
|
@ -179,6 +179,9 @@ relinquishRetainedMemory(const void *item,
|
||||||
|
|
||||||
- (id) initWithOptions: (NSPointerFunctionsOptions)options
|
- (id) initWithOptions: (NSPointerFunctionsOptions)options
|
||||||
{
|
{
|
||||||
|
int memoryType = options & 0x00ff;
|
||||||
|
int personality = options & 0xff00;
|
||||||
|
|
||||||
#define Unsupported(X) ({\
|
#define Unsupported(X) ({\
|
||||||
NSLog(@"*** An unsupported PointerFunctions configuration was requested,"\
|
NSLog(@"*** An unsupported PointerFunctions configuration was requested,"\
|
||||||
@" probably for use by NSMapTable, NSHashTable, or NSPointerArray. %@",\
|
@" probably for use by NSMapTable, NSHashTable, or NSPointerArray. %@",\
|
||||||
|
@ -186,130 +189,155 @@ relinquishRetainedMemory(const void *item,
|
||||||
DESTROY(self);\
|
DESTROY(self);\
|
||||||
})
|
})
|
||||||
|
|
||||||
if (memoryType(options, NSPointerFunctionsZeroingWeakMemory))
|
/* Check that we have a valid memory management option.
|
||||||
|
*/
|
||||||
|
switch (memoryType)
|
||||||
|
{
|
||||||
|
case NSPointerFunctionsMachVirtualMemory:
|
||||||
|
case NSPointerFunctionsMallocMemory:
|
||||||
|
case NSPointerFunctionsOpaqueMemory:
|
||||||
|
case NSPointerFunctionsStrongMemory:
|
||||||
|
case NSPointerFunctionsWeakMemory:
|
||||||
|
case NSPointerFunctionsZeroingWeakMemory:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Unsupported(@"The requested configuration fails due to"
|
||||||
|
@" an unknown memory type being specified.");
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the supplied options (with modification if needed).
|
||||||
|
*/
|
||||||
|
if (NSPointerFunctionsZeroingWeakMemory == memoryType)
|
||||||
{
|
{
|
||||||
/* Garbage Collection is no longer supported, so we treat all weak
|
/* Garbage Collection is no longer supported, so we treat all weak
|
||||||
* memory the same way.
|
* memory the same way.
|
||||||
*/
|
*/
|
||||||
_x.options = (options & 0xffffff00) | NSPointerFunctionsWeakMemory;
|
memoryType = NSPointerFunctionsWeakMemory;
|
||||||
|
_x.options = (options & 0xffffff00) | memoryType;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_x.options = options;
|
_x.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First we look at the memory management options to see which function
|
/* Check for unsupported memory/personality combinations
|
||||||
* should be used to relinquish contents of a container with these
|
|
||||||
* options.
|
|
||||||
*/
|
*/
|
||||||
if (memoryType(options, NSPointerFunctionsWeakMemory)
|
if (NSPointerFunctionsIntegerPersonality == personality)
|
||||||
|| memoryType(options, NSPointerFunctionsZeroingWeakMemory))
|
|
||||||
{
|
{
|
||||||
_x.relinquishFunction = 0;
|
if (NSPointerFunctionsOpaqueMemory != memoryType)
|
||||||
}
|
|
||||||
else if (memoryType(options, NSPointerFunctionsOpaqueMemory))
|
|
||||||
{
|
|
||||||
_x.relinquishFunction = 0;
|
|
||||||
}
|
|
||||||
else if (memoryType(options, NSPointerFunctionsMallocMemory))
|
|
||||||
{
|
|
||||||
_x.relinquishFunction = relinquishMallocMemory;
|
|
||||||
}
|
|
||||||
else if (memoryType(options, NSPointerFunctionsMachVirtualMemory))
|
|
||||||
{
|
|
||||||
_x.relinquishFunction = relinquishMallocMemory;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* NSPointerFunctionsStrongMemory uses -release for objects
|
|
||||||
*/
|
|
||||||
if (personalityType(options, NSPointerFunctionsObjectPersonality)
|
|
||||||
|| personalityType(options, NSPointerFunctionsObjectPointerPersonality))
|
|
||||||
{
|
|
||||||
_x.relinquishFunction = relinquishRetainedMemory;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_x.relinquishFunction = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now we look at the personality options to determine other functions.
|
|
||||||
*/
|
|
||||||
if (personalityType(options, NSPointerFunctionsOpaquePersonality))
|
|
||||||
{
|
|
||||||
_x.acquireFunction = 0;
|
|
||||||
_x.descriptionFunction = describePointer;
|
|
||||||
_x.hashFunction = hashShifted;
|
|
||||||
_x.isEqualFunction = equalDirect;
|
|
||||||
}
|
|
||||||
else if (personalityType(options, NSPointerFunctionsObjectPointerPersonality))
|
|
||||||
{
|
|
||||||
if (memoryType(options, NSPointerFunctionsWeakMemory)
|
|
||||||
|| memoryType(options, NSPointerFunctionsZeroingWeakMemory))
|
|
||||||
{
|
|
||||||
_x.acquireFunction = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_x.acquireFunction = acquireRetainedObject;
|
|
||||||
}
|
|
||||||
_x.descriptionFunction = describeObject;
|
|
||||||
_x.hashFunction = hashShifted;
|
|
||||||
_x.isEqualFunction = equalDirect;
|
|
||||||
}
|
|
||||||
else if (personalityType(options, NSPointerFunctionsCStringPersonality))
|
|
||||||
{
|
|
||||||
if (memoryType(options, NSPointerFunctionsMallocMemory))
|
|
||||||
{
|
|
||||||
_x.acquireFunction = acquireMallocMemory;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_x.acquireFunction = NULL;
|
|
||||||
}
|
|
||||||
_x.descriptionFunction = describeString;
|
|
||||||
_x.hashFunction = hashString;
|
|
||||||
_x.isEqualFunction = equalString;
|
|
||||||
}
|
|
||||||
else if (personalityType(options, NSPointerFunctionsStructPersonality))
|
|
||||||
{
|
|
||||||
_x.acquireFunction = acquireMallocMemory;
|
|
||||||
_x.descriptionFunction = describePointer;
|
|
||||||
_x.hashFunction = hashMemory;
|
|
||||||
_x.isEqualFunction = equalMemory;
|
|
||||||
}
|
|
||||||
else if (personalityType(options, NSPointerFunctionsIntegerPersonality))
|
|
||||||
{
|
|
||||||
if (memoryType(options, NSPointerFunctionsOpaqueMemory))
|
|
||||||
{
|
|
||||||
_x.acquireFunction = 0;
|
|
||||||
_x.descriptionFunction = describeInteger;
|
|
||||||
_x.hashFunction = hashDirect;
|
|
||||||
_x.isEqualFunction = equalDirect;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Unsupported(@"The requested configuration fails due to"
|
Unsupported(@"The requested configuration fails due to"
|
||||||
@" integer personality not using opaque memory.");
|
@" integer personality not using opaque memory.");
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* objects */
|
|
||||||
{
|
|
||||||
if (memoryType(options, NSPointerFunctionsWeakMemory)
|
|
||||||
|| memoryType(options, NSPointerFunctionsZeroingWeakMemory))
|
|
||||||
{
|
|
||||||
_x.acquireFunction = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_x.acquireFunction = acquireRetainedObject;
|
|
||||||
}
|
|
||||||
_x.descriptionFunction = describeObject;
|
|
||||||
_x.hashFunction = hashObject;
|
|
||||||
_x.isEqualFunction = equalObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (NSPointerFunctionsObjectPersonality == personality
|
||||||
|
|| NSPointerFunctionsObjectPointerPersonality == personality)
|
||||||
|
{
|
||||||
|
if (NSPointerFunctionsMachVirtualMemory == memoryType
|
||||||
|
|| NSPointerFunctionsMallocMemory == memoryType)
|
||||||
|
{
|
||||||
|
Unsupported(@"The requested configuration fails due to"
|
||||||
|
@" integer personality not using opaque memory.");
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Now we look at the personality options to determine functions.
|
||||||
|
*/
|
||||||
|
switch (personality)
|
||||||
|
{
|
||||||
|
case NSPointerFunctionsCStringPersonality:
|
||||||
|
if (NSPointerFunctionsMachVirtualMemory == memoryType
|
||||||
|
|| NSPointerFunctionsMallocMemory == memoryType)
|
||||||
|
{
|
||||||
|
_x.acquireFunction = acquireMallocMemory;
|
||||||
|
_x.relinquishFunction = relinquishMallocMemory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_x.acquireFunction = 0;
|
||||||
|
_x.relinquishFunction = 0;
|
||||||
|
}
|
||||||
|
_x.descriptionFunction = describeString;
|
||||||
|
_x.hashFunction = hashString;
|
||||||
|
_x.isEqualFunction = equalString;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSPointerFunctionsIntegerPersonality:
|
||||||
|
_x.acquireFunction = 0;
|
||||||
|
_x.relinquishFunction = 0;
|
||||||
|
_x.descriptionFunction = describeInteger;
|
||||||
|
_x.hashFunction = hashDirect;
|
||||||
|
_x.isEqualFunction = equalDirect;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSPointerFunctionsObjectPersonality:
|
||||||
|
if (NSPointerFunctionsWeakMemory == memoryType)
|
||||||
|
{
|
||||||
|
_x.acquireFunction = 0;
|
||||||
|
_x.relinquishFunction = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_x.acquireFunction = acquireRetainedObject;
|
||||||
|
_x.relinquishFunction = relinquishRetainedMemory;
|
||||||
|
}
|
||||||
|
_x.descriptionFunction = describeObject;
|
||||||
|
_x.hashFunction = hashObject;
|
||||||
|
_x.isEqualFunction = equalObject;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSPointerFunctionsObjectPointerPersonality:
|
||||||
|
if (NSPointerFunctionsWeakMemory == memoryType)
|
||||||
|
{
|
||||||
|
_x.acquireFunction = 0;
|
||||||
|
_x.relinquishFunction = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_x.acquireFunction = acquireRetainedObject;
|
||||||
|
_x.relinquishFunction = 0;
|
||||||
|
}
|
||||||
|
_x.descriptionFunction = describeObject;
|
||||||
|
_x.hashFunction = hashShifted;
|
||||||
|
_x.isEqualFunction = equalDirect;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSPointerFunctionsOpaquePersonality:
|
||||||
|
_x.acquireFunction = 0;
|
||||||
|
_x.relinquishFunction = 0;
|
||||||
|
_x.descriptionFunction = describePointer;
|
||||||
|
_x.hashFunction = hashShifted;
|
||||||
|
_x.isEqualFunction = equalDirect;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSPointerFunctionsStructPersonality:
|
||||||
|
if (NSPointerFunctionsMachVirtualMemory == memoryType
|
||||||
|
|| NSPointerFunctionsMallocMemory == memoryType)
|
||||||
|
{
|
||||||
|
_x.acquireFunction = acquireMallocMemory;
|
||||||
|
_x.relinquishFunction = relinquishMallocMemory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_x.acquireFunction = 0;
|
||||||
|
_x.relinquishFunction = 0;
|
||||||
|
}
|
||||||
|
_x.descriptionFunction = describePointer;
|
||||||
|
_x.hashFunction = hashMemory;
|
||||||
|
_x.isEqualFunction = equalMemory;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Unsupported(@"The requested configuration fails due to"
|
||||||
|
@" an unknown personality being specified.");
|
||||||
|
return self;
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,15 @@ int main()
|
||||||
id testObj = [[[NSObject alloc] init] autorelease];
|
id testObj = [[[NSObject alloc] init] autorelease];
|
||||||
for (index = 0; index < 10; index++)
|
for (index = 0; index < 10; index++)
|
||||||
{
|
{
|
||||||
[array addPointer: testObj];
|
[array addPointer: testObj];
|
||||||
}
|
}
|
||||||
PASS([[array allObjects] count] == 10, "Array retains active weak reference");
|
PASS([[array allObjects] count] == index,
|
||||||
|
"Array retains active weak reference");
|
||||||
|
|
||||||
[arp2 release]; arp2 = nil;
|
[arp2 release]; arp2 = nil;
|
||||||
|
|
||||||
PASS([[array allObjects] count] == 0, "Array removes dead weak reference");
|
PASS([[array allObjects] count] == 0,
|
||||||
|
"Array removes dead weak reference");
|
||||||
|
|
||||||
[arp release]; arp = nil;
|
[arp release]; arp = nil;
|
||||||
END_SET("NSPointerArray weak objects")
|
END_SET("NSPointerArray weak objects")
|
||||||
|
|
|
@ -69,6 +69,10 @@ static NSUInteger aStructSize(const void *item)
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int code;
|
||||||
|
const char *name;
|
||||||
|
} OptInfo;
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
@ -83,6 +87,86 @@ int main()
|
||||||
(const void *item, NSUInteger (*size)(const void *item));
|
(const void *item, NSUInteger (*size)(const void *item));
|
||||||
NSUInteger (*sizeFunction)(const void *item);
|
NSUInteger (*sizeFunction)(const void *item);
|
||||||
|
|
||||||
|
START_SET("Combinations")
|
||||||
|
OptInfo MemoryType[] = {
|
||||||
|
{ NSPointerFunctionsMachVirtualMemory,
|
||||||
|
"NSPointerFunctionsMachVirtualMemory" },
|
||||||
|
{ NSPointerFunctionsMallocMemory,
|
||||||
|
"NSPointerFunctionsMallocMemory" },
|
||||||
|
{ NSPointerFunctionsOpaqueMemory,
|
||||||
|
"NSPointerFunctionsOpaqueMemory" },
|
||||||
|
{ NSPointerFunctionsStrongMemory,
|
||||||
|
"NSPointerFunctionsStrongMemory" },
|
||||||
|
{ NSPointerFunctionsWeakMemory,
|
||||||
|
"NSPointerFunctionsWeakMemory" },
|
||||||
|
{ NSPointerFunctionsZeroingWeakMemory,
|
||||||
|
"NSPointerFunctionsZeroingWeakMemory" },
|
||||||
|
{ 0x00ff, "Unknown/BadMemory" }
|
||||||
|
};
|
||||||
|
OptInfo Personality[] = {
|
||||||
|
{ NSPointerFunctionsCStringPersonality,
|
||||||
|
"NSPointerFunctionsCStringPersonality" },
|
||||||
|
{ NSPointerFunctionsIntegerPersonality,
|
||||||
|
"NSPointerFunctionsIntegerPersonality" },
|
||||||
|
{ NSPointerFunctionsObjectPersonality,
|
||||||
|
"NSPointerFunctionsObjectPersonality" },
|
||||||
|
{ NSPointerFunctionsObjectPointerPersonality,
|
||||||
|
"NSPointerFunctionsObjectPointerPersonality" },
|
||||||
|
{ NSPointerFunctionsOpaquePersonality,
|
||||||
|
"NSPointerFunctionsOpaquePersonality" },
|
||||||
|
{ NSPointerFunctionsStructPersonality,
|
||||||
|
"NSPointerFunctionsStructPersonality" },
|
||||||
|
{ 0xff00, "Unknown/BadPersonality" }
|
||||||
|
};
|
||||||
|
int mem;
|
||||||
|
int per;
|
||||||
|
|
||||||
|
for (mem = 0; mem < sizeof(MemoryType) / sizeof(*MemoryType); mem++)
|
||||||
|
{
|
||||||
|
for (per = 0; per < sizeof(Personality) / sizeof(*Personality); per++)
|
||||||
|
{
|
||||||
|
int mc = MemoryType[mem].code;
|
||||||
|
int pc = Personality[per].code;
|
||||||
|
BOOL ok = (0x00ff != mc && 0xff00 != pc);
|
||||||
|
const char *msg;
|
||||||
|
|
||||||
|
if (NSPointerFunctionsIntegerPersonality == pc)
|
||||||
|
{
|
||||||
|
if (NSPointerFunctionsOpaqueMemory != mc)
|
||||||
|
{
|
||||||
|
ok = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NSPointerFunctionsObjectPersonality == pc
|
||||||
|
|| NSPointerFunctionsObjectPointerPersonality == pc)
|
||||||
|
{
|
||||||
|
if (NSPointerFunctionsMachVirtualMemory == mc
|
||||||
|
|| NSPointerFunctionsMallocMemory == mc)
|
||||||
|
{
|
||||||
|
ok = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pf = [NSPointerFunctions pointerFunctionsWithOptions: mc | pc];
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
msg = [[NSString stringWithFormat: @"Create with %s %s allowed",
|
||||||
|
MemoryType[mem].name, Personality[per].name] UTF8String];
|
||||||
|
PASS(pf != nil, "%s", msg)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg = [[NSString stringWithFormat: @"Create with %s %s refused",
|
||||||
|
MemoryType[mem].name, Personality[per].name] UTF8String];
|
||||||
|
PASS(nil == pf, "%s", msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
END_SET("Combinations")
|
||||||
|
|
||||||
START_SET("GarbageCollection")
|
START_SET("GarbageCollection")
|
||||||
NSPointerFunctions *pf;
|
NSPointerFunctions *pf;
|
||||||
NSPointerFunctions *zpf;
|
NSPointerFunctions *zpf;
|
||||||
|
@ -101,27 +185,11 @@ int main()
|
||||||
|
|
||||||
END_SET("GarbageCollection")
|
END_SET("GarbageCollection")
|
||||||
|
|
||||||
START_SET("Personality/Memory")
|
|
||||||
PASS(nil == [NSPointerFunctions pointerFunctionsWithOptions:
|
|
||||||
NSPointerFunctionsZeroingWeakMemory
|
|
||||||
| NSPointerFunctionsIntegerPersonality],
|
|
||||||
"nil on create with integer personality and zeroing weak memory")
|
|
||||||
PASS(nil == [NSPointerFunctions pointerFunctionsWithOptions:
|
|
||||||
NSPointerFunctionsWeakMemory
|
|
||||||
| NSPointerFunctionsIntegerPersonality],
|
|
||||||
"nil on create with integer personality and weak memory")
|
|
||||||
PASS(nil == [NSPointerFunctions pointerFunctionsWithOptions:
|
|
||||||
NSPointerFunctionsStrongMemory
|
|
||||||
| NSPointerFunctionsIntegerPersonality],
|
|
||||||
"nil on create with integer personality and strong memory")
|
|
||||||
END_SET("Personality/Memory")
|
|
||||||
|
|
||||||
START_SET("CStringPersonality")
|
START_SET("CStringPersonality")
|
||||||
{
|
{
|
||||||
const char *cstr1 = "hello";
|
const char *cstr1 = "hello";
|
||||||
const char *cstr2 = "hello";
|
const char *cstr2 = "hello";
|
||||||
const char *cstr3 = "goodbye";
|
const char *cstr3 = "goodbye";
|
||||||
const char *cstr;
|
|
||||||
|
|
||||||
pf = [NSPointerFunctions pointerFunctionsWithOptions:
|
pf = [NSPointerFunctions pointerFunctionsWithOptions:
|
||||||
NSPointerFunctionsCStringPersonality];
|
NSPointerFunctionsCStringPersonality];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue