[macruby-changes] [3376] MacRuby/trunk/variable.c
source_changes at macosforge.org
source_changes at macosforge.org
Sat Jan 30 19:18:33 PST 2010
Revision: 3376
http://trac.macosforge.org/projects/ruby/changeset/3376
Author: lsansonetti at apple.com
Date: 2010-01-30 19:18:30 -0800 (Sat, 30 Jan 2010)
Log Message:
-----------
changed generic/native/class ivars to use GC associative references and keep the global hash for immediates
Modified Paths:
--------------
MacRuby/trunk/variable.c
Modified: MacRuby/trunk/variable.c
===================================================================
--- MacRuby/trunk/variable.c 2010-01-30 04:33:25 UTC (rev 3375)
+++ MacRuby/trunk/variable.c 2010-01-31 03:18:30 UTC (rev 3376)
@@ -840,24 +840,65 @@
entry1->var = entry2->var;
}
-// TODO: should use an associative reference instead.
static CFMutableDictionaryRef generic_iv_dict = NULL;
-static VALUE
-generic_ivar_get(VALUE obj, ID id, bool warn, bool undef)
+static CFMutableDictionaryRef
+generic_ivar_dict(VALUE obj, bool create)
{
- if (generic_iv_dict != NULL) {
- CFDictionaryRef obj_dict;
+ CFMutableDictionaryRef obj_dict = NULL;
+ if (SPECIAL_CONST_P(obj)) {
+ if (generic_iv_dict == NULL) {
+ generic_iv_dict = CFDictionaryCreateMutable(NULL, 0, NULL,
+ &kCFTypeDictionaryValueCallBacks);
+ }
+ if (!CFDictionaryGetValueIfPresent(generic_iv_dict,
+ (const void *)obj, (const void **)&obj_dict) && create) {
+ obj_dict = CFDictionaryCreateMutable(NULL, 0, NULL,
+ &rb_cfdictionary_value_cb);
+ CFMakeCollectable(obj_dict);
+ CFDictionarySetValue(generic_iv_dict, (const void *)obj,
+ (const void *)obj_dict);
+ }
+ }
+ else {
+ obj_dict = rb_objc_get_associative_ref((void *)obj, &generic_iv_dict);
+ if (obj_dict == NULL && create) {
+ obj_dict = CFDictionaryCreateMutable(NULL, 0, NULL,
+ &rb_cfdictionary_value_cb);
+ CFMakeCollectable(obj_dict);
+ rb_objc_set_associative_ref((void *)obj, &generic_iv_dict,
+ (void *)obj_dict);
+ }
+ }
+ return obj_dict;
+}
- if (CFDictionaryGetValueIfPresent(generic_iv_dict,
- (const void *)obj, (const void **)&obj_dict)
- && obj_dict != NULL) {
+static void
+generic_ivar_dict_set(VALUE obj, CFMutableDictionaryRef obj_dict)
+{
+ if (SPECIAL_CONST_P(obj)) {
+ if (generic_iv_dict == NULL) {
+ generic_iv_dict = CFDictionaryCreateMutable(NULL, 0, NULL,
+ &kCFTypeDictionaryValueCallBacks);
+ }
+ CFDictionarySetValue(generic_iv_dict, (const void *)obj,
+ (const void *)obj_dict);
+ }
+ else {
+ rb_objc_set_associative_ref((void *)obj, &generic_iv_dict,
+ (void *)obj_dict);
+ }
+}
- VALUE val;
- if (CFDictionaryGetValueIfPresent(obj_dict, (const void *)id,
- (const void **)&val)) {
- return val;
- }
+static VALUE
+generic_ivar_get(VALUE obj, ID id, bool warn, bool undef)
+{
+ CFDictionaryRef obj_dict = generic_ivar_dict(obj, false);
+ if (obj_dict != NULL) {
+ VALUE val;
+ if (CFDictionaryGetValueIfPresent(obj_dict, (const void *)id,
+ (const void **)&val)) {
+ return val;
}
}
if (warn) {
@@ -869,105 +910,53 @@
static void
generic_ivar_set(VALUE obj, ID id, VALUE val)
{
- CFMutableDictionaryRef obj_dict;
-
if (rb_special_const_p(obj)) {
- if (rb_obj_frozen_p(obj))
+ if (rb_obj_frozen_p(obj)) {
rb_error_frozen("object");
+ }
}
- if (generic_iv_dict == NULL) {
- generic_iv_dict = CFDictionaryCreateMutable(NULL, 0, NULL,
- &rb_cfdictionary_value_cb);
- rb_objc_retain(generic_iv_dict);
- obj_dict = NULL;
- }
- else {
- obj_dict = (CFMutableDictionaryRef)CFDictionaryGetValue(
- (CFDictionaryRef)generic_iv_dict, (const void *)obj);
- }
- if (obj_dict == NULL) {
- obj_dict = CFDictionaryCreateMutable(NULL, 0, NULL,
- &rb_cfdictionary_value_cb);
- CFDictionarySetValue(generic_iv_dict, (const void *)obj,
- (const void *)obj_dict);
- CFMakeCollectable(obj_dict);
- }
+ CFMutableDictionaryRef obj_dict = generic_ivar_dict(obj, true);
+//printf("generic_ivar_set %p %ld %p dict %p\n", (void*)obj,id,(void*)val,obj_dict);
CFDictionarySetValue(obj_dict, (const void *)id, (const void *)val);
}
static VALUE
generic_ivar_defined(VALUE obj, ID id)
{
- CFMutableDictionaryRef obj_dict;
-
- if (generic_iv_dict != NULL
- && CFDictionaryGetValueIfPresent((CFDictionaryRef)generic_iv_dict,
- (const void *)obj, (const void **)&obj_dict)
- && obj_dict != NULL) {
- if (CFDictionaryGetValueIfPresent(obj_dict, (const void *)id, NULL)) {
+ CFDictionaryRef obj_dict = generic_ivar_dict(obj, false);
+ if (obj_dict != NULL) {
+ if (CFDictionaryGetValueIfPresent(obj_dict, (const void *)id, NULL)) {
return Qtrue;
}
}
return Qfalse;
}
-static int
+static bool
generic_ivar_remove(VALUE obj, ID id, VALUE *valp)
{
- CFMutableDictionaryRef obj_dict;
- VALUE val;
-
- if (generic_iv_dict == NULL)
- return 0;
-
- obj_dict = (CFMutableDictionaryRef)CFDictionaryGetValue(
- (CFDictionaryRef)generic_iv_dict, (const void *)obj);
- if (obj_dict == NULL)
- return 0;
-
- if (CFDictionaryGetValueIfPresent(obj_dict, (const void *)id,
- (const void **)&val)) {
- *valp = val;
- CFDictionaryRemoveValue(obj_dict, (const void *)id);
- return 1;
+ CFMutableDictionaryRef obj_dict = generic_ivar_dict(obj, false);
+ if (obj_dict != NULL) {
+ VALUE val;
+ if (CFDictionaryGetValueIfPresent(obj_dict, (const void *)id,
+ (const void **)&val)) {
+ *valp = val;
+ CFDictionaryRemoveValue(obj_dict, (const void *)id);
+ return true;
+ }
}
-
- return 0;
+ return false;
}
void
-rb_free_generic_ivar(VALUE obj)
+rb_copy_generic_ivar(VALUE clone, VALUE obj)
{
- if (generic_iv_dict != NULL) {
- CFDictionaryRemoveValue(generic_iv_dict, (const void *)obj);
+ CFMutableDictionaryRef obj_dict = generic_ivar_dict(obj, false);
+ if (obj_dict != NULL) {
+ generic_ivar_dict_set(clone, obj_dict);
}
}
-void
-rb_copy_generic_ivar(VALUE clone, VALUE obj)
-{
- CFMutableDictionaryRef obj_dict;
- CFMutableDictionaryRef clone_dict;
-
- if (generic_iv_dict == NULL)
- return;
-
- obj_dict = (CFMutableDictionaryRef)CFDictionaryGetValue(
- (CFDictionaryRef)generic_iv_dict, (const void *)obj);
- if (obj_dict == NULL)
- return;
-
- if (CFDictionaryGetValueIfPresent((CFDictionaryRef)generic_iv_dict,
- (const void *)clone, (const void **)&clone_dict)
- && clone_dict != NULL)
- CFDictionaryRemoveValue(generic_iv_dict, (const void *)clone);
-
- clone_dict = CFDictionaryCreateMutableCopy(NULL, 0, obj_dict);
- CFDictionarySetValue(generic_iv_dict, (const void *)clone,
- (const void *)clone_dict);
- CFMakeCollectable(clone_dict);
-}
-
static inline bool
rb_class_has_ivar_dict(VALUE mod)
{
@@ -983,19 +972,10 @@
CFMutableDictionaryRef
rb_class_ivar_dict(VALUE mod)
{
- CFMutableDictionaryRef dict;
-
if (rb_class_has_ivar_dict(mod)) {
- dict = RCLASS_RUBY_IVAR_DICT(mod);
+ return RCLASS_RUBY_IVAR_DICT(mod);
}
- else {
- dict = NULL;
- if (generic_iv_dict != NULL) {
- CFDictionaryGetValueIfPresent(generic_iv_dict,
- (const void *)mod, (const void **)&dict);
- }
- }
- return dict;
+ return generic_ivar_dict(mod, false);
}
void
@@ -1005,18 +985,14 @@
CFMutableDictionaryRef old_dict = RCLASS_RUBY_IVAR_DICT(mod);
if (old_dict != dict) {
if (old_dict != NULL) {
- CFRelease(old_dict);
+ GC_RELEASE(old_dict);
}
- CFRetain(dict);
+ GC_RETAIN(dict);
RCLASS_RUBY_IVAR_DICT(mod) = dict;
}
}
else {
- if (generic_iv_dict == NULL) {
- generic_iv_dict = CFDictionaryCreateMutable(NULL, 0, NULL, &rb_cfdictionary_value_cb);
- rb_objc_retain(generic_iv_dict);
- }
- CFDictionarySetValue(generic_iv_dict, (const void *)mod, (const void *)dict);
+ generic_ivar_dict_set(mod, dict);
}
}
@@ -1193,8 +1169,6 @@
}
case T_NATIVE:
- return generic_ivar_defined(obj, id);
-
default:
return generic_ivar_defined(obj, id);
}
@@ -1224,19 +1198,15 @@
return;
case T_NATIVE:
- goto generic;
+ default:
+ {
+ CFDictionaryRef obj_dict = generic_ivar_dict(obj, false);
+ if (obj_dict != NULL) {
+ CFDictionaryApplyFunction(obj_dict, (CFDictionaryApplierFunction)func,
+ (void *)arg);
+ }
+ }
}
-generic:
- if (generic_iv_dict != NULL) {
- CFDictionaryRef obj_dict;
-
- obj_dict = (CFDictionaryRef)CFDictionaryGetValue(
- (CFDictionaryRef)generic_iv_dict, (const void *)obj);
- if (obj_dict != NULL) {
- CFDictionaryApplyFunction(obj_dict,
- (CFDictionaryApplierFunction)func, (void *)arg);
- }
- }
}
static int
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100130/0801d8af/attachment.html>
More information about the macruby-changes
mailing list