Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

some work on garbage collecting singleton classes - disabled for now …

…since it breaks rubyspec
  • Loading branch information...
commit c1833dd1d2764711f3ea658d7e1108e62057dddb 1 parent 125dc53
Laurent Sansonetti authored
View
11 NSArray.m
@@ -51,16 +51,6 @@
}
static id
-nsary_clone(id rcv, SEL sel)
-{
- id clone = nsary_dup(rcv, 0);
- if (OBJ_FROZEN(rcv)) {
- OBJ_FREEZE(clone);
- }
- return clone;
-}
-
-static id
nsary_clear(id rcv, SEL sel)
{
CHECK_MUTABLE(rcv);
@@ -1000,7 +990,6 @@
rb_include_module(rb_cArray, rb_mEnumerable);
rb_objc_define_method(rb_cArray, "dup", nsary_dup, 0);
- rb_objc_define_method(rb_cArray, "clone", nsary_clone, 0);
rb_objc_define_method(rb_cArray, "clear", nsary_clear, 0);
rb_objc_define_method(rb_cArray, "to_s", nsary_inspect, 0);
rb_objc_define_method(rb_cArray, "inspect", nsary_inspect, 0);
View
11 NSDictionary.m
@@ -56,16 +56,6 @@
}
static id
-nshash_clone(id rcv, SEL sel)
-{
- id clone = nshash_dup(rcv, 0);
- if (OBJ_FROZEN(rcv)) {
- OBJ_FREEZE(clone);
- }
- return clone;
-}
-
-static id
nshash_rehash(id rcv, SEL sel)
{
CHECK_MUTABLE(rcv);
@@ -475,7 +465,6 @@
rb_include_module(rb_cHash, rb_mEnumerable);
rb_objc_define_method(rb_cHash, "dup", nshash_dup, 0);
- rb_objc_define_method(rb_cHash, "clone", nshash_clone, 0);
rb_objc_define_method(rb_cHash, "rehash", nshash_rehash, 0);
rb_objc_define_method(rb_cHash, "to_hash", nshash_to_hash, 0);
rb_objc_define_method(rb_cHash, "to_a", nshash_to_a, 0);
View
11 NSString.m
@@ -62,16 +62,6 @@
}
static id
-nsstr_clone(id rcv, SEL sel)
-{
- id clone = nsstr_dup(rcv, 0);
- if (OBJ_FROZEN(rcv)) {
- OBJ_FREEZE(clone);
- }
- return clone;
-}
-
-static id
nsstr_to_s(id rcv, SEL sel)
{
return rcv;
@@ -286,7 +276,6 @@
assert(rb_cNSMutableString != 0);
rb_objc_define_method(rb_cString, "dup", nsstr_dup, 0);
- rb_objc_define_method(rb_cString, "clone", nsstr_clone, 0);
rb_objc_define_method(rb_cString, "to_s", nsstr_to_s, 0);
rb_objc_define_method(rb_cString, "to_str", nsstr_to_s, 0);
rb_objc_define_method(rb_cString, "replace", nsstr_replace, 1);
View
18 array.c
@@ -1194,23 +1194,6 @@ rary_dup(VALUE ary, SEL sel)
return dup;
}
-static VALUE
-rary_clone(VALUE ary, SEL sel)
-{
- VALUE clone = rary_copy(ary, CLASS_OF(ary));
-
- if (OBJ_TAINTED(ary)) {
- OBJ_TAINT(clone);
- }
- if (OBJ_UNTRUSTED(ary)) {
- OBJ_UNTRUST(clone);
- }
- if (OBJ_FROZEN(ary)) {
- OBJ_FREEZE(clone);
- }
- return clone;
-}
-
/*
* call-seq:
* array.join(sep=$,) -> str
@@ -3761,7 +3744,6 @@ Init_Array(void)
rb_objc_define_method(rb_cRubyArray, "initialize_copy", rary_replace, 1);
rb_objc_define_method(rb_cRubyArray, "to_a", rary_to_a, 0);
rb_objc_define_method(rb_cRubyArray, "dup", rary_dup, 0);
- rb_objc_define_method(rb_cRubyArray, "clone", rary_clone, 0);
rb_objc_define_method(rb_cRubyArray, "to_s", rary_inspect, 0);
rb_objc_define_method(rb_cRubyArray, "inspect", rary_inspect, 0);
rb_objc_define_method(rb_cRubyArray, "==", rary_equal, 1);
View
187 class.c
@@ -27,7 +27,7 @@ extern VALUE rb_cModuleObject;
static bool
rb_class_hidden(VALUE klass)
{
- return klass == rb_cModuleObject || RCLASS_SINGLETON(klass);
+ return klass == rb_cModuleObject || klass == rb_cRubyObject || RCLASS_SINGLETON(klass);
}
VALUE
@@ -344,60 +344,90 @@ rb_singleton_class_clone(VALUE obj)
if (!RCLASS_SINGLETON(klass)) {
return klass;
}
- else {
- /* copy singleton(unnamed) class */
- VALUE clone = rb_objc_create_class(NULL, RCLASS_SUPER(klass));
- CFMutableDictionaryRef ivar_dict = rb_class_ivar_dict(klass);
- if (ivar_dict != NULL) {
- CFMutableDictionaryRef cloned_ivar_dict;
+ // Create new singleton class.
+ VALUE clone = rb_objc_create_class(NULL, RCLASS_SUPER(klass));
- cloned_ivar_dict = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)ivar_dict);
- rb_class_ivar_set_dict(clone, cloned_ivar_dict);
- CFMakeCollectable(cloned_ivar_dict);
- }
+ // Copy ivars.
+ CFMutableDictionaryRef ivar_dict = rb_class_ivar_dict(klass);
+ if (ivar_dict != NULL) {
+ CFMutableDictionaryRef cloned_ivar_dict =
+ CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)ivar_dict);
+ rb_class_ivar_set_dict(clone, cloned_ivar_dict);
+ CFMakeCollectable(cloned_ivar_dict);
+ }
- Method *methods;
- unsigned i, methods_count;
- methods = class_copyMethodList((Class)klass, &methods_count);
- if (methods != NULL) {
- for (i = 0; i < methods_count; i++) {
- Method method = methods[i], method2;
- method2 = class_getInstanceMethod((Class)clone, method_getName(method));
- if (method2 != class_getInstanceMethod((Class)RCLASS_SUPER(clone), method_getName(method))) {
- method_setImplementation(method2, method_getImplementation(method));
- }
- else {
- assert(class_addMethod((Class)clone,
- method_getName(method),
- method_getImplementation(method),
- method_getTypeEncoding(method)));
- }
- }
- free(methods);
- }
+ // Copy methods.
+ rb_vm_copy_methods((Class)klass, (Class)clone);
+
+ rb_singleton_class_attached(clone, obj);
+ if (RCLASS_SUPER(clone) == rb_cRubyObject) {
+ long v = RCLASS_VERSION(clone) ^ RCLASS_IS_OBJECT_SUBCLASS;
+ RCLASS_SET_VERSION(clone, v);
+ }
+ RCLASS_SET_VERSION_FLAG(clone, RCLASS_IS_SINGLETON);
+ return clone;
+}
- rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
- if (RCLASS_SUPER(clone) == rb_cRubyObject) {
- long v = RCLASS_VERSION(clone) ^ RCLASS_IS_OBJECT_SUBCLASS;
- RCLASS_SET_VERSION(clone, v);
+static void
+robj_sclass_finalize_imp(void *rcv, SEL sel)
+{
+ bool changed = false;
+ while (true) {
+ VALUE k = *(VALUE *)rcv;
+ if (!RCLASS_SINGLETON(k)
+ || !rb_singleton_class_attached_object(k) == (VALUE)rcv) {
+ break;
}
- RCLASS_SET_VERSION_FLAG(clone, RCLASS_IS_SINGLETON);
+ VALUE sk = RCLASS_SUPER(k);
+ if (sk == 0) {
+ // This can't happen, but we are never sure...
+ break;
+ }
+ *(VALUE *)rcv = sk;
+
+ rb_vm_dispose_class((Class)k);
+
+ changed = true;
+ }
- return clone;
+#if 0
+ if (changed) {
+ objc_msgSend(rcv, selFinalize);
}
+#endif
+}
+
+void
+rb_singleton_class_promote_for_gc(VALUE klass)
+{
+ rb_objc_install_method2((Class)klass, "finalize",
+ (IMP)robj_sclass_finalize_imp);
}
void
rb_singleton_class_attached(VALUE klass, VALUE obj)
{
if (RCLASS_SINGLETON(klass)) {
- static ID attachedId = 0;
- if (attachedId == 0) {
- attachedId = rb_intern("__attached__");
+ // Weak ref.
+ VALUE wobj = LONG2NUM((long)obj);
+ rb_ivar_set(klass, idAttached, wobj);
+ // FIXME commented for now as it breaks some RubySpecs.
+ //rb_singleton_class_promote_for_gc(klass);
+ }
+}
+
+VALUE
+rb_singleton_class_attached_object(VALUE klass)
+{
+ if (RCLASS_SINGLETON(klass)) {
+ // Weak ref.
+ VALUE obj = rb_ivar_get(klass, idAttached);
+ if (FIXNUM_P(obj)) {
+ return (VALUE)NUM2LONG(obj);
}
- rb_ivar_set(klass, attachedId, obj);
}
+ return Qnil;
}
VALUE
@@ -417,16 +447,24 @@ rb_make_singleton_class(VALUE super)
VALUE
rb_make_metaclass(VALUE obj, VALUE super)
{
+ VALUE klass;
if (TYPE(obj) == T_CLASS && RCLASS_SINGLETON(obj)) {
RBASIC(obj)->klass = rb_cClass;
- return rb_cClass;
+ klass = rb_cClass;
}
else {
- VALUE klass = rb_make_singleton_class(super);
- RBASIC(obj)->klass = klass;
- rb_singleton_class_attached(klass, obj);
- return klass;
+ VALUE objk = RBASIC(obj)->klass;
+ if (RCLASS_SINGLETON(objk)
+ && rb_singleton_class_attached_object(objk) == obj) {
+ klass = objk;
+ }
+ else {
+ klass = rb_make_singleton_class(super);
+ RBASIC(obj)->klass = klass;
+ rb_singleton_class_attached(klass, obj);
+ }
}
+ return klass;
}
VALUE
@@ -1115,8 +1153,6 @@ rb_undef_method(VALUE klass, const char *name)
VALUE
rb_singleton_class(VALUE obj)
{
- VALUE klass;
-
if (FIXNUM_P(obj) || SYMBOL_P(obj) || FIXFLOAT_P(obj)) {
rb_raise(rb_eTypeError, "can't define singleton");
}
@@ -1127,45 +1163,18 @@ rb_singleton_class(VALUE obj)
rb_bug("unknown immediate %ld", obj);
}
-#if 0
- DEFER_INTS;
- if (RCLASS_SINGLETON(RBASIC(obj)->klass) &&
- rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) {
- klass = RBASIC(obj)->klass;
- }
- else
-#endif
- {
- switch (TYPE(obj)) {
- case T_CLASS:
- case T_MODULE:
- klass = *(VALUE *)obj;
- break;
+ VALUE klass;
+ switch (TYPE(obj)) {
+ case T_CLASS:
+ case T_MODULE:
+ // FIXME we should really create a new metaclass here.
+ klass = *(VALUE *)obj;
+ break;
- default:
- if (RCLASS_SINGLETON(RBASIC(obj)->klass) &&
- rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) {
- klass = RBASIC(obj)->klass;
- }
- else {
- klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
- }
- break;
- }
- }
-#if 0
- if (OBJ_TAINTED(obj)) {
- OBJ_TAINT(klass);
- }
- else {
- OBJ_UNTAINT(klass);
- }
- if (OBJ_FROZEN(obj)) {
- OBJ_FREEZE(klass);
+ default:
+ klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
+ break;
}
-#endif
-// ALLOW_INTS;
-
return klass;
}
@@ -1292,6 +1301,16 @@ Init_PreClass(void)
assert(rb_class_flags != NULL);
}
+void
+Init_Class(void)
+{
+#if 0
+ rb_cSClassFinalizer = rb_define_class("__SClassFinalizer", rb_cObject);
+ sclass_finalize_imp_super = rb_objc_install_method2(
+ (Class)rb_cSClassFinalizer, "finalize", (IMP)sclass_finalize_imp);
+#endif
+}
+
static int
foundation_type(Class k)
{
View
16 class.h
@@ -20,6 +20,8 @@ void rb_objc_class_sync_version(Class klass, Class super_class);
void rb_define_object_special_methods(VALUE klass);
VALUE rb_class_new_instance_imp(VALUE, SEL, int, VALUE *);
VALUE rb_make_singleton_class(VALUE super);
+VALUE rb_singleton_class_attached_object(VALUE klass);
+void rb_singleton_class_promote_for_gc(VALUE klass);
#define RCLASS_IS_OBJECT_SUBCLASS (1<<1) /* class is a true RubyObject subclass */
#define RCLASS_IS_RUBY_CLASS (1<<2) /* class was created from Ruby */
@@ -63,6 +65,20 @@ rb_class_get_mask(Class k)
return 0;
}
+static inline bool
+rb_class_erase_mask(Class k)
+{
+ rb_class_flags_cache_t *e = &rb_class_flags[rb_class_flags_hash(k)];
+ while (e != NULL) {
+ if (e->klass == k) {
+ e->klass = 0;
+ return true;
+ }
+ e = e->next;
+ }
+ return false;
+}
+
static inline void
rb_class_set_mask(Class k, unsigned long mask)
{
View
5 gc.c
@@ -1066,8 +1066,9 @@ print_memory_object(task_t task, void *context, unsigned type_mask,
for (vm_range_t *r = ranges, *end = ranges + range_count; r < end; r++) {
const size_t size = auto_zone_size(__auto_zone, (void *)r->address);
if (size >= min_size) {
- printf("address %p size %ld layout type ",
- (void *)r->address, size);
+ printf("address %p size %ld rc %d layout type ",
+ (void *)r->address, size,
+ auto_zone_retain_count(__auto_zone, (void *)r->address));
switch (auto_zone_get_layout_type(__auto_zone,
(void *)r->address)) {
case AUTO_OBJECT:
View
23 hash.c
@@ -172,18 +172,6 @@ rhash_dup(VALUE rcv, SEL sel)
return dup;
}
-static VALUE
-rhash_clone(VALUE rcv, SEL sel)
-{
- VALUE clone = rhash_copy(rcv, CLASS_OF(rcv));
-
- OBJ_INFECT(clone, rcv);
- if (OBJ_FROZEN(rcv)) {
- OBJ_FREEZE(clone);
- }
- return clone;
-}
-
VALUE
rb_hash_new(void)
{
@@ -1001,13 +989,17 @@ rhash_replace(VALUE hash, SEL sel, VALUE hash2)
return hash;
}
- rhash_clear(hash, 0);
- rb_hash_foreach(hash2, replace_i, hash);
-
+ // Copy RubyHash properties.
if (IS_RHASH(hash2)) {
+ if (RHASH(hash2)->tbl->type == &identhash) {
+ RHASH(hash)->tbl->type = &identhash;
+ }
GC_WB(&RHASH(hash)->ifnone, RHASH(hash2)->ifnone);
RHASH(hash)->has_proc_default = RHASH(hash2)->has_proc_default;
}
+
+ rhash_clear(hash, 0);
+ rb_hash_foreach(hash2, replace_i, hash);
return hash;
}
@@ -1852,7 +1844,6 @@ Init_Hash(void)
rb_objc_define_method(rb_cRubyHash, "initialize", rhash_initialize, -1);
rb_objc_define_method(rb_cRubyHash, "initialize_copy", rhash_replace, 1);
rb_objc_define_method(rb_cRubyHash, "dup", rhash_dup, 0);
- rb_objc_define_method(rb_cRubyHash, "clone", rhash_clone, 0);
rb_objc_define_method(rb_cRubyHash, "rehash", rhash_rehash, 0);
rb_objc_define_method(rb_cRubyHash, "to_hash", rhash_to_hash, 0);
rb_objc_define_method(rb_cRubyHash, "to_a", rhash_to_a, 0);
View
3  id.c
@@ -37,7 +37,7 @@ Init_id(void)
idEqTilde = rb_intern("=~");
idNot = rb_intern("!");
idNeq = rb_intern("!=");
-
+ idAttached = rb_intern("__attached__");
#if WITH_OBJC
selPLUS = sel_registerName("+:");
selMINUS = sel_registerName("-:");
@@ -106,6 +106,7 @@ Init_id(void)
selLambda = sel_registerName("lambda");
selObjectForKey = sel_registerName("objectForKey:");
selSetObjectForKey = sel_registerName("setObject:forKey:");
+ selFinalize = sel_registerName("finalize");
sel__method__= sel_registerName("__method__");
sel__callee__ = sel_registerName("__callee__");
View
2  id.h
@@ -46,6 +46,7 @@ extern ID idSend;
extern ID id__send__;
extern ID idRespond_to;
extern ID idInitialize;
+extern ID idAttached;
#if WITH_OBJC
extern SEL selPLUS;
extern SEL selMINUS;
@@ -114,6 +115,7 @@ extern SEL selInherited;
extern SEL selLambda;
extern SEL selObjectForKey;
extern SEL selSetObjectForKey;
+extern SEL selFinalize;
extern SEL sel__method__;
extern SEL sel__callee__;
extern ID idIncludedModules;
View
2  inits.c
@@ -29,6 +29,7 @@ void Init_Math(void);
void Init_marshal(void);
void Init_Numeric(void);
void Init_Object(void);
+void Init_Class(void);
void Init_pack(void);
void Init_Precision(void);
void Init_Symbol(void);
@@ -65,6 +66,7 @@ rb_call_inits()
Init_id();
Init_var_tables();
Init_Object();
+ Init_Class();
Init_VM();
Init_Encoding();
Init_Comparable();
View
70 object.c
@@ -192,19 +192,14 @@ rb_obj_class(VALUE obj)
static void
init_copy(VALUE dest, VALUE obj)
{
- if (NATIVE(obj)) {
- if (OBJ_TAINTED(obj)) {
- OBJ_TAINT(dest);
- }
- goto call_init_copy;
- }
if (OBJ_FROZEN(dest)) {
- rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated", rb_obj_classname(dest));
+ rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated",
+ rb_obj_classname(dest));
}
- RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR);
- RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR|FL_TAINT);
+
rb_copy_generic_ivar(dest, obj);
rb_gc_copy_finalizer(dest, obj);
+
switch (TYPE(obj)) {
case T_OBJECT:
if (ROBJECT(obj)->num_slots > 0) {
@@ -221,28 +216,30 @@ init_copy(VALUE dest, VALUE obj)
}
ROBJECT(dest)->num_slots = ROBJECT(obj)->num_slots;
break;
+
case T_CLASS:
case T_MODULE:
{
- CFMutableDictionaryRef dest_dict, obj_dict;
-
- obj_dict = rb_class_ivar_dict(obj);
- dest_dict = rb_class_ivar_dict(dest);
- if (dest_dict != NULL)
+ CFMutableDictionaryRef dest_dict = rb_class_ivar_dict(dest);
+ if (dest_dict != NULL) {
CFDictionaryRemoveAllValues(dest_dict);
+ }
+ CFMutableDictionaryRef obj_dict = rb_class_ivar_dict(obj);
if (obj_dict != NULL) {
- dest_dict = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)obj_dict);
+ dest_dict = CFDictionaryCreateMutableCopy(NULL, 0,
+ (CFDictionaryRef)obj_dict);
CFMakeCollectable(dest_dict);
rb_class_ivar_set_dict(dest, dest_dict);
}
else {
- if (dest_dict)
+ if (dest_dict) {
rb_class_ivar_set_dict(dest, NULL);
+ }
}
}
break;
}
-call_init_copy:
+
rb_vm_call(dest, selInitializeCopy, 1, &obj);
}
@@ -275,32 +272,43 @@ static VALUE rb_class_s_alloc(VALUE, SEL);
static VALUE
rb_obj_clone_imp(VALUE obj, SEL sel)
{
- VALUE clone;
-
if (rb_special_const_p(obj)) {
rb_raise(rb_eTypeError, "can't clone %s", rb_obj_classname(obj));
}
+
+ // #alloc
+ VALUE clone;
switch (TYPE(obj)) {
- case T_NATIVE:
- clone = rb_obj_alloc(rb_obj_class(obj));
- RBASIC(clone)->klass = rb_singleton_class_clone(obj);
- break;
case T_CLASS:
case T_MODULE:
clone = rb_class_s_alloc(Qnil, 0);
break;
+
default:
clone = rb_obj_alloc(rb_obj_class(obj));
- RBASIC(clone)->klass = rb_singleton_class_clone(obj);
- RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~(FL_FREEZE|FL_FINALIZE);
+ do {
+ VALUE klass = rb_singleton_class_clone(obj);
+ if (klass != RBASIC(obj)->klass) {
+ RBASIC(clone)->klass = klass;
+ }
+ }
+ while (0);
break;
}
+ // #initialize_copy
init_copy(clone, obj);
+
+ // Copy flags.
+ if (OBJ_TAINTED(obj)) {
+ OBJ_TAINT(clone);
+ }
+ if (OBJ_UNTRUSTED(obj)) {
+ OBJ_UNTRUST(clone);
+ }
if (OBJ_FROZEN(obj)) {
OBJ_FREEZE(clone);
}
-
return clone;
}
@@ -338,9 +346,12 @@ rb_obj_dup(VALUE obj)
}
dup = rb_obj_alloc(rb_obj_class(obj));
init_copy(dup, obj);
- if (OBJ_UNTRUSTED(obj))
+ if (OBJ_TAINTED(obj)) {
+ OBJ_TAINT(dup);
+ }
+ if (OBJ_UNTRUSTED(obj)) {
OBJ_UNTRUST(dup);
-
+ }
return dup;
}
@@ -1616,7 +1627,7 @@ rb_mod_to_s(VALUE klass, SEL sel)
{
if (RCLASS_SINGLETON(klass)) {
VALUE s = rb_usascii_str_new2("#<");
- VALUE v = rb_iv_get(klass, "__attached__");
+ VALUE v = rb_singleton_class_attached_object(klass);
rb_str_cat2(s, "Class:");
switch (TYPE(v)) {
@@ -3020,7 +3031,6 @@ Init_Object(void)
rb_define_object_special_methods(rb_cModule);
rb_cClass = boot_defclass("Class", rb_cModule);
rb_cRubyObject = boot_defclass("RubyObject", rb_cObject);
- RCLASS_SET_VERSION_FLAG(rb_cRubyObject, RCLASS_IS_SINGLETON);
RCLASS_SET_VERSION_FLAG(rb_cRubyObject, RCLASS_IS_OBJECT_SUBCLASS);
rb_define_object_special_methods(rb_cRubyObject);
rb_objc_install_NSObject_special_methods((Class)rb_cRubyObject);
View
13 string.c
@@ -1837,18 +1837,6 @@ rstr_dup(VALUE str, SEL sel)
return dup;
}
-static VALUE
-rstr_clone(VALUE str, SEL sel)
-{
- VALUE clone = rstr_copy(str, CLASS_OF(str));
-
- OBJ_INFECT(clone, str);
- if (OBJ_FROZEN(str)) {
- OBJ_FREEZE(clone);
- }
- return clone;
-}
-
/*
* call-seq:
* string.clear -> string
@@ -6027,7 +6015,6 @@ Init_String(void)
rb_objc_define_method(rb_cRubyString, "initialize", rstr_initialize, -1);
rb_objc_define_method(rb_cRubyString, "initialize_copy", rstr_replace, 1);
rb_objc_define_method(rb_cRubyString, "dup", rstr_dup, 0);
- rb_objc_define_method(rb_cRubyString, "clone", rstr_clone, 0);
rb_objc_define_method(rb_cRubyString, "replace", rstr_replace, 1);
rb_objc_define_method(rb_cRubyString, "clear", rstr_clear, 0);
rb_objc_define_method(rb_cRubyString, "encoding", rstr_encoding, 0);
View
63 vm.cpp
@@ -969,7 +969,7 @@ RoxorCore::method_added(Class klass, SEL sel)
if (mid != 0) {
VALUE sym = ID2SYM(mid);
if (RCLASS_SINGLETON(klass)) {
- VALUE sk = rb_iv_get((VALUE)klass, "__attached__");
+ VALUE sk = rb_singleton_class_attached_object((VALUE)klass);
rb_vm_call(sk, selSingletonMethodAdded, 1, &sym);
}
else {
@@ -2395,6 +2395,7 @@ void
RoxorCore::get_methods(VALUE ary, Class klass, bool include_objc_methods,
int (*filter) (VALUE, ID, VALUE))
{
+ RoxorCoreLock lock;
// TODO take into account undefined methods
unsigned int count;
@@ -2437,7 +2438,7 @@ RoxorCore::get_methods(VALUE ary, Class klass, bool include_objc_methods,
extern "C"
void
rb_vm_push_methods(VALUE ary, VALUE mod, bool include_objc_methods,
- int (*filter) (VALUE, ID, VALUE))
+ int (*filter) (VALUE, ID, VALUE))
{
GET_CORE()->get_methods(ary, (Class)mod, include_objc_methods, filter);
}
@@ -2816,7 +2817,7 @@ RoxorCore::undef_method(Class klass, SEL sel)
if (mid != 0) {
VALUE sym = ID2SYM(mid);
if (RCLASS_SINGLETON(klass)) {
- VALUE sk = rb_iv_get((VALUE)klass, "__attached__");
+ VALUE sk = rb_singleton_class_attached_object((VALUE)klass);
rb_vm_call(sk, selSingletonMethodUndefined, 1, &sym);
}
else {
@@ -2880,7 +2881,7 @@ RoxorCore::remove_method(Class klass, SEL sel)
if (mid != 0) {
VALUE sym = ID2SYM(mid);
if (RCLASS_SINGLETON(klass)) {
- VALUE sk = rb_iv_get((VALUE)klass, "__attached__");
+ VALUE sk = rb_singleton_class_attached_object((VALUE)klass);
rb_vm_call(sk, selSingletonMethodRemoved, 1, &sym);
}
else {
@@ -5343,6 +5344,8 @@ Init_PreVM(void)
// To not corrupt stack pointer (essential for backtracing).
llvm::NoFramePointerElim = true;
+ llvm::UnwindTablesMandatory = true;
+
if (getenv("VM_STATS") != NULL) {
vm_enable_stats = true;
llvm::EnableStatistics();
@@ -5713,6 +5716,58 @@ rb_vm_load(const char *fname_str, int wrap)
rb_vm_run(fname_str, node, NULL, false);
}
+void
+RoxorCore::dispose_class(Class k)
+{
+//printf("%p %d\n", k, auto_zone_retain_count(__auto_zone, k));
+// if (auto_zone_retain_count(__auto_zone, k) > 1) {
+// return;
+// }
+//return;
+
+ RoxorCoreLock lock;
+
+ // Free ivars dict.
+ rb_class_ivar_set_dict((VALUE)k, NULL);
+
+ // Free class flags.
+ rb_class_erase_mask(k);
+
+#if !defined(MACRUBY_STATIC)
+ // Free lazy-JIT caches.
+ std::multimap<Class, SEL>::iterator iter =
+ method_source_sels.find(k);
+
+ if (iter != method_source_sels.end()) {
+ std::multimap<Class, SEL>::iterator first = iter;
+ std::multimap<Class, SEL>::iterator last =
+ method_source_sels.upper_bound(k);
+
+ for (; iter != last; iter++) {
+ SEL sel = iter->second;
+
+ std::map<SEL, std::map<Class, rb_vm_method_source_t *> *>::iterator
+ iter2 = method_sources.find(sel);
+ if (iter2 != method_sources.end()) {
+ delete iter2->second;
+ method_sources.erase(iter2);
+ }
+ }
+ method_source_sels.erase(first, last);
+ }
+#endif
+
+ // Free the runtime bits.
+ objc_disposeClassPair(k);
+}
+
+extern "C"
+void
+rb_vm_dispose_class(Class k)
+{
+ GET_CORE()->dispose_class(k);
+}
+
extern "C"
void
Init_PostVM(void)
View
4 vm.h
@@ -359,6 +359,8 @@ void rb_vm_push_methods(VALUE ary, VALUE mod, bool include_objc_methods,
VALUE rb_vm_catch(VALUE tag);
VALUE rb_vm_throw(VALUE tag, VALUE value);
+void rb_vm_dispose_class(Class k);
+
typedef struct {
ID name;
VALUE value;
@@ -986,6 +988,8 @@ class RoxorCore {
bool respond_to(VALUE obj, VALUE klass, SEL sel, bool priv,
bool check_override);
+ void dispose_class(Class k);
+
private:
bool register_bs_boxed(bs_element_type_t type, void *value);
void register_bs_class(bs_element_class_t *bs_class);

0 comments on commit c1833dd

Please sign in to comment.
Something went wrong with that request. Please try again.