Move retainCount out of Object.

Going by "standard" Objective-C, retainCount really doesn't belong in
Object itself. The way GNUStep does it is to stash retainCount in memory
just below the object by allocating extra bytes for the count and returning
a pointer just beyond those extra bytes. Now Ruamoko does the same. This
fixes the inconsistencies in structure layouts for Protocol and class
structs between qfcc generated (internal) structs and user visible structs.
This commit is contained in:
Bill Currie 2012-11-08 20:24:25 +09:00
parent 377f8f9d56
commit 6b46cde7c8
4 changed files with 43 additions and 11 deletions

View file

@ -1008,6 +1008,27 @@ rua_obj_msg_sendv (progs_t *pr)
PR_CallFunction (pr, imp);
}
static void
rua_obj_increment_retaincount (progs_t *pr)
{
pr_type_t *obj = &P_STRUCT (pr, pr_type_t, 0);
R_INT (pr) = ++(*--obj).integer_var;
}
static void
rua_obj_decrement_retaincount (progs_t *pr)
{
pr_type_t *obj = &P_STRUCT (pr, pr_type_t, 0);
R_INT (pr) = --(*--obj).integer_var;
}
static void
rua_obj_get_retaincount (progs_t *pr)
{
pr_type_t *obj = &P_STRUCT (pr, pr_type_t, 0);
R_INT (pr) = (*--obj).integer_var;
}
static void
rua_obj_malloc (progs_t *pr)
{
@ -1245,11 +1266,13 @@ rua_class_pose_as (progs_t *pr)
static inline pr_id_t *
class_create_instance (progs_t *pr, pr_class_t *class)
{
int size = class->instance_size * sizeof (pr_type_t);
int size = (class->instance_size + 1) * sizeof (pr_type_t);
pr_type_t *mem;
pr_id_t *id;
id = PR_Zone_Malloc (pr, size);
memset (id, 0, size);
mem = PR_Zone_Malloc (pr, size);
// redundant memset (id, 0, size);
id = (pr_id_t *) (mem + 1);
id->class_pointer = PR_SetPointer (pr, class);
return id;
}
@ -1363,7 +1386,8 @@ static void
rua_object_dispose (progs_t *pr)
{
pr_id_t *object = &P_STRUCT (pr, pr_id_t, 0);
PR_Zone_Free (pr, object);
pr_type_t *mem = (pr_type_t *) object;
PR_Zone_Free (pr, mem - 1);
}
static void
@ -1375,6 +1399,8 @@ rua_object_copy (progs_t *pr)
id = class_create_instance (pr, class);
memcpy (id, object, sizeof (pr_type_t) * class->instance_size);
// copy the retain count
((pr_type_t *) id)[-1] = ((pr_type_t *) object)[-1];
RETURN_POINTER (pr, id);
}
@ -1522,6 +1548,9 @@ static builtin_t obj_methods [] = {
{"obj_msg_lookup", rua_obj_msg_lookup, -1},
{"obj_msg_lookup_super", rua_obj_msg_lookup_super, -1},
{"obj_msg_sendv", rua_obj_msg_sendv, -1},
{"obj_increment_retaincount", rua_obj_increment_retaincount, -1},
{"obj_decrement_retaincount", rua_obj_decrement_retaincount, -1},
{"obj_get_retaincount", rua_obj_get_retaincount, -1},
{"obj_malloc", rua_obj_malloc, -1},
{"obj_atomic_malloc", rua_obj_atomic_malloc, -1},
{"obj_valloc", rua_obj_valloc, -1},

View file

@ -46,7 +46,6 @@
@interface Object <Object>
{
Class isa;
unsigned retainCount;
}
+ (id) alloc;

View file

@ -28,6 +28,8 @@ typedef enum {
@extern IMP obj_msg_lookup (id receiver, SEL op);
@extern IMP obj_msg_lookup_super (Super class, SEL op);
@extern @param obj_msg_sendv (id receiver, SEL op, @va_list args);
@extern BOOL obj_decrement_ref_was_zero (id object);
@extern BOOL obj_increment_ref_was_zero (id object);
@extern void *obj_malloc (int size);
@extern void *obj_atomic_malloc (int size);
@extern void *obj_valloc (int size);

View file

@ -10,6 +10,9 @@ IMP (Super class, SEL op) obj_msg_lookup_super = #0;
id (id receiver, SEL op, ...) obj_msgSend = #0;
id obj_msgSend_super (Super *class, SEL op, ...) = #0;
@param (id receiver, SEL op, @va_list args) obj_msg_sendv = #0;
int obj_decrement_retaincount (id object) = #0;
int obj_increment_retaincount (id object) = #0;
int obj_get_retaincount (id object) = #0;
void *obj_malloc (int size) = #0;
void *obj_atomic_malloc (int size) = #0;
void *obj_valloc (int size) = #0;
@ -149,8 +152,7 @@ BOOL (id object) object_is_meta_class = #0;
- (id) init
{
retainCount = 1;
[self retain];
return self;
}
@ -282,16 +284,16 @@ BOOL (id object) object_is_meta_class = #0;
*/
- (id) retain
{
retainCount = [self retainCount] + 1;
obj_increment_retaincount (self);
return self;
}
- (/*oneway*/ void) release
{
if ([self retainCount] == 1) // don't let retain count actually reach zero
if ([self retainCount] == 1) // don't let retain count reach zero
[self dealloc];
else
retainCount--;
obj_decrement_retaincount (self);
}
- (id) autorelease
@ -302,7 +304,7 @@ BOOL (id object) object_is_meta_class = #0;
- (unsigned) retainCount
{
return retainCount;
return obj_get_retaincount (self);
}
/*
CONVENIENCE METHODS