mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
Avoid memory leak and improve performance for common structures.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@28939 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
b3a520b2fe
commit
3d9e3eee57
1 changed files with 91 additions and 44 deletions
|
@ -138,12 +138,10 @@ cifframe_from_signature (NSMethodSignature *info)
|
||||||
have custom ffi_types with are allocated separately. We should allocate
|
have custom ffi_types with are allocated separately. We should allocate
|
||||||
them in our cifframe so we don't leak memory. Or maybe we could
|
them in our cifframe so we don't leak memory. Or maybe we could
|
||||||
cache structure types? */
|
cache structure types? */
|
||||||
rtype = cifframe_type(
|
rtype = cifframe_type([info methodReturnType], NULL);
|
||||||
objc_skip_type_qualifiers ([info methodReturnType]), NULL);
|
|
||||||
for (i = 0; i < numargs; i++)
|
for (i = 0; i < numargs; i++)
|
||||||
{
|
{
|
||||||
arg_types[i] = cifframe_type(
|
arg_types[i] = cifframe_type([info getArgumentTypeAtIndex: i], NULL);
|
||||||
objc_skip_type_qualifiers([info getArgumentTypeAtIndex: i]), NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numargs > 0)
|
if (numargs > 0)
|
||||||
|
@ -255,39 +253,10 @@ cifframe_arg_addr(cifframe_t *cframe, int index)
|
||||||
ffi_type *
|
ffi_type *
|
||||||
cifframe_type(const char *typePtr, const char **advance)
|
cifframe_type(const char *typePtr, const char **advance)
|
||||||
{
|
{
|
||||||
BOOL flag;
|
|
||||||
const char *type;
|
const char *type;
|
||||||
ffi_type *ftype;
|
ffi_type *ftype;
|
||||||
|
|
||||||
/*
|
typePtr = objc_skip_type_qualifiers (typePtr);
|
||||||
* Skip past any type qualifiers
|
|
||||||
*/
|
|
||||||
flag = YES;
|
|
||||||
while (flag)
|
|
||||||
{
|
|
||||||
switch (*typePtr)
|
|
||||||
{
|
|
||||||
case _C_CONST:
|
|
||||||
case _C_IN:
|
|
||||||
case _C_INOUT:
|
|
||||||
case _C_OUT:
|
|
||||||
case _C_BYCOPY:
|
|
||||||
#ifdef _C_BYREF
|
|
||||||
case _C_BYREF:
|
|
||||||
#endif
|
|
||||||
case _C_ONEWAY:
|
|
||||||
#ifdef _C_GCINVISIBLE
|
|
||||||
case _C_GCINVISIBLE:
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default: flag = NO;
|
|
||||||
}
|
|
||||||
if (flag)
|
|
||||||
{
|
|
||||||
typePtr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type = typePtr;
|
type = typePtr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -368,6 +337,94 @@ cifframe_type(const char *typePtr, const char **advance)
|
||||||
const char *adv;
|
const char *adv;
|
||||||
unsigned align = __alignof(double);
|
unsigned align = __alignof(double);
|
||||||
|
|
||||||
|
/* Standard structures can be handled using cached type information.
|
||||||
|
*/
|
||||||
|
if (GSSelectorTypesMatch(typePtr, @encode(NSRange)))
|
||||||
|
{
|
||||||
|
static ffi_type *elems[3];
|
||||||
|
static ffi_type stype = { 0 };
|
||||||
|
|
||||||
|
if (stype.type == 0)
|
||||||
|
{
|
||||||
|
if (*typePtr == _C_ULNG)
|
||||||
|
{
|
||||||
|
elems[0] = &gsffi_type_ulong;
|
||||||
|
}
|
||||||
|
#ifdef _C_LNG_LNG
|
||||||
|
else if (*typePtr == _C_ULNG_LNG)
|
||||||
|
{
|
||||||
|
elems[0] = &gsffi_type_ulong_long;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elems[0] = &gsffi_type_uint;
|
||||||
|
}
|
||||||
|
elems[1] = elems[0];
|
||||||
|
elems[2] = 0;
|
||||||
|
stype.elements = elems;
|
||||||
|
stype.type = FFI_TYPE_STRUCT;
|
||||||
|
}
|
||||||
|
ftype = &stype;
|
||||||
|
typePtr = objc_skip_typespec (typePtr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (GSSelectorTypesMatch(typePtr, @encode(NSSize)))
|
||||||
|
{
|
||||||
|
static ffi_type *elems[3];
|
||||||
|
static ffi_type stype = { 0 };
|
||||||
|
|
||||||
|
if (stype.type == 0)
|
||||||
|
{
|
||||||
|
if (*@encode(CGFloat) == _C_DBL)
|
||||||
|
{
|
||||||
|
elems[0] = &ffi_type_double;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elems[0] = &ffi_type_float;
|
||||||
|
}
|
||||||
|
elems[1] = elems[0];
|
||||||
|
elems[2] = 0;
|
||||||
|
stype.elements = elems;
|
||||||
|
stype.type = FFI_TYPE_STRUCT;
|
||||||
|
}
|
||||||
|
ftype = &stype;
|
||||||
|
typePtr = objc_skip_typespec (typePtr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (GSSelectorTypesMatch(typePtr, @encode(NSRect)))
|
||||||
|
{
|
||||||
|
static ffi_type *elems[3];
|
||||||
|
static ffi_type stype = { 0 };
|
||||||
|
|
||||||
|
if (stype.type == 0)
|
||||||
|
{
|
||||||
|
/* An NSRect is an NSPoint and an NSSize, but those
|
||||||
|
* two structures are actually identical.
|
||||||
|
*/
|
||||||
|
elems[0] = cifframe_type(@encode(NSSize), NULL);
|
||||||
|
elems[1] = elems[0];
|
||||||
|
elems[2] = 0;
|
||||||
|
stype.elements = elems;
|
||||||
|
stype.type = FFI_TYPE_STRUCT;
|
||||||
|
}
|
||||||
|
ftype = &stype;
|
||||||
|
typePtr = objc_skip_typespec (typePtr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip "<name>=" stuff.
|
||||||
|
*/
|
||||||
|
while (*typePtr != _C_STRUCT_E)
|
||||||
|
{
|
||||||
|
if (*typePtr++ == '=')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
types = 0;
|
types = 0;
|
||||||
maxtypes = 4;
|
maxtypes = 4;
|
||||||
size = sizeof(ffi_type);
|
size = sizeof(ffi_type);
|
||||||
|
@ -380,16 +437,6 @@ cifframe_type(const char *typePtr, const char **advance)
|
||||||
ftype->alignment = 0;
|
ftype->alignment = 0;
|
||||||
ftype->type = FFI_TYPE_STRUCT;
|
ftype->type = FFI_TYPE_STRUCT;
|
||||||
ftype->elements = (void*)ftype + size;
|
ftype->elements = (void*)ftype + size;
|
||||||
/*
|
|
||||||
* Skip "<name>=" stuff.
|
|
||||||
*/
|
|
||||||
while (*typePtr != _C_STRUCT_E)
|
|
||||||
{
|
|
||||||
if (*typePtr++ == '=')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Continue accumulating structure size.
|
* Continue accumulating structure size.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue