[macruby-changes] [623] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Thu Sep 25 22:11:32 PDT 2008


Revision: 623
          http://trac.macosforge.org/projects/ruby/changeset/623
Author:   lsansonetti at apple.com
Date:     2008-09-25 22:11:32 -0700 (Thu, 25 Sep 2008)
Log Message:
-----------
reimplemented the finalizing code in -[NSObject finalizer], enabled threaded GC cycles by default, misc fixes

Modified Paths:
--------------
    MacRuby/trunk/gc.c
    MacRuby/trunk/include/ruby/ruby.h
    MacRuby/trunk/objc.m
    MacRuby/trunk/parse.y
    MacRuby/trunk/thread.c

Modified: MacRuby/trunk/gc.c
===================================================================
--- MacRuby/trunk/gc.c	2008-09-26 01:28:50 UTC (rev 622)
+++ MacRuby/trunk/gc.c	2008-09-26 05:11:32 UTC (rev 623)
@@ -1225,9 +1225,6 @@
  *  are also available via the <code>ObjectSpace</code> module.
  */
 
-static void (*old_batch_invalidate)(auto_zone_t *, 
-    auto_zone_foreach_object_t, auto_zone_cursor_t, size_t);
-
 static VALUE
 run_single_final(VALUE arg)
 {
@@ -1274,41 +1271,50 @@
 }
 
 static void
-__rb_objc_finalize(void *obj, void *data)
+rb_obj_imp_finalize(void *obj, SEL sel)
 {
-    //printf("finalize %p <%s>\n",obj, class_getName(*(Class *)obj));
+    const bool need_protection = GET_THREAD()->thread_id != pthread_self();
+    void native_mutex_lock(pthread_mutex_t *lock);
+    void native_mutex_unlock(pthread_mutex_t *lock);
+
     if (NATIVE((VALUE)obj)) {
-	static SEL sel = NULL;
 	long flag;
+
+	if (need_protection) {
+	    native_mutex_lock(&GET_THREAD()->vm->global_interpreter_lock);
+	}
 	flag = rb_objc_remove_flags(obj);
-	if ((flag & FL_FINALIZE) == FL_FINALIZE)
+	if ((flag & FL_FINALIZE) == FL_FINALIZE) {
 	    rb_call_os_finalizer(obj);
-	if ((flag & FL_EXIVAR) == FL_EXIVAR)
+	}
+	if ((flag & FL_EXIVAR) == FL_EXIVAR) {
 	    rb_free_generic_ivar((VALUE)obj);
-	if (sel == NULL)
-	    sel = sel_registerName("finalize");
-	objc_msgSend(obj, sel);
+	}
+	if (need_protection) {
+	    native_mutex_unlock(&GET_THREAD()->vm->global_interpreter_lock);
+	}
     }
     else {
-	if (FL_TEST(obj, FL_FINALIZE))
+	bool call_finalize, free_ivar;
+
+	call_finalize = FL_TEST(obj, FL_FINALIZE);
+	free_ivar = FL_TEST(obj, FL_EXIVAR);
+
+	if (need_protection && (call_finalize || free_ivar)) {
+	    native_mutex_lock(&GET_THREAD()->vm->global_interpreter_lock);
+	}
+	if (call_finalize) {
 	    rb_call_os_finalizer(obj);
-	if (FL_TEST(obj, FL_EXIVAR))
+	}
+	if (free_ivar) {
 	    rb_free_generic_ivar((VALUE)obj);
+	}
+	if (need_protection && (call_finalize || free_ivar)) {
+	    native_mutex_unlock(&GET_THREAD()->vm->global_interpreter_lock);
+	}
     }
 }
 
-static void 
-rb_objc_batch_invalidate(auto_zone_t *zone, 
-			 auto_zone_foreach_object_t foreach, 
-			 auto_zone_cursor_t cursor, size_t cursor_size) 
-{
-    foreach(cursor, __rb_objc_finalize, NULL);
-    /* By incrementing the GC count here we make sure it will also be updated
-     * when a collection is triggered from the Objective-C world.
-     */
-    _gc_count++;
-}
-
 void
 Init_PreGC(void)
 {
@@ -1325,19 +1331,16 @@
     if (getenv("GC_DEBUG"))
 	control->log = AUTO_LOG_COLLECTIONS | AUTO_LOG_REGIONS 
 		       | AUTO_LOG_UNUSUAL;
-    old_batch_invalidate = control->batch_invalidate;
-    control->batch_invalidate = rb_objc_batch_invalidate;
+
+    Method m = class_getInstanceMethod((Class)objc_getClass("NSObject"), sel_registerName("finalize"));
+    assert(m != NULL);
+    method_setImplementation(m, (IMP)rb_obj_imp_finalize);
 }
 
 void
 Init_PostGC(void)
 {
-#if 0
-    /* It is better to let Foundation start the dedicated collection thread
-     * when necessary. 
-     */
     objc_startCollectorThread();
-#endif
 }
 
 void

Modified: MacRuby/trunk/include/ruby/ruby.h
===================================================================
--- MacRuby/trunk/include/ruby/ruby.h	2008-09-26 01:28:50 UTC (rev 622)
+++ MacRuby/trunk/include/ruby/ruby.h	2008-09-26 05:11:32 UTC (rev 623)
@@ -434,7 +434,7 @@
 #endif
 #define OBJSETUP(obj,c,t) do {\
     RBASIC(obj)->flags = (t);\
-    RBASIC(obj)->klass = (c);\
+    if (c != 0) RBASIC(obj)->klass = (c);\
     if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT);\
 } while (0)
 #define CLONESETUP(clone,obj) do {\

Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m	2008-09-26 01:28:50 UTC (rev 622)
+++ MacRuby/trunk/objc.m	2008-09-26 05:11:32 UTC (rev 623)
@@ -1602,26 +1602,25 @@
 	rb_ruby_to_objc_closure_handler_main(&ctx);
     }
     else {
-#if 0
-	if (GET_VM()->main_thread == GET_THREAD()) {
+	if (GET_THREAD()->thread_id == pthread_self()) {
 	    rb_ruby_to_objc_closure_handler_main(&ctx);
 	}
 	else {
+	    rb_thread_t *rb_thread_wrap_existing_native_thread(rb_thread_id_t id);
 	    void native_mutex_lock(pthread_mutex_t *lock);
 	    void native_mutex_unlock(pthread_mutex_t *lock);
 
+	    rb_thread_t *th, *old;
+
+	    th = rb_thread_wrap_existing_native_thread(pthread_self());
+
 	    native_mutex_lock(&GET_THREAD()->vm->global_interpreter_lock);
+	    old = ruby_current_thread;
+	    ruby_current_thread = th;
 	    rb_ruby_to_objc_closure_handler_main(&ctx);
 	    native_mutex_unlock(&GET_THREAD()->vm->global_interpreter_lock);
+	    ruby_current_thread = old;
 	}
-#else
-	if (GET_VM()->main_thread == GET_THREAD()) {
-	    rb_ruby_to_objc_closure_handler_main(&ctx);
-	}
-	else {
-	    rb_thread_blocking_region(rb_ruby_to_objc_closure_handler_main, &ctx, RB_UBF_DFL, 0);
-	}
-#endif
     }
 }
 

Modified: MacRuby/trunk/parse.y
===================================================================
--- MacRuby/trunk/parse.y	2008-09-26 01:28:50 UTC (rev 622)
+++ MacRuby/trunk/parse.y	2008-09-26 05:11:32 UTC (rev 623)
@@ -5112,8 +5112,8 @@
 	    }
 	    ruby_sourceline++;
 	    parser->line_count++;
-	    lex_pbeg = lex_p = RSTRING_BYTEPTR(v);
-	    lex_pend = lex_p + RSTRING_BYTELEN(v);
+	    lex_pbeg = lex_p = RSTRING_PTR(v);
+	    lex_pend = lex_p + RSTRING_LEN(v);
 #ifdef RIPPER
 	    ripper_flush(parser);
 #endif
@@ -10259,7 +10259,7 @@
     parser_initialize(parser);
 
     parser->parser_ruby_sourcefile_string = fname;
-    parser->parser_ruby_sourcefile = RSTRING_BYTEPTR(fname);
+    parser->parser_ruby_sourcefile = RSTRING_PTR(fname);
     parser->parser_ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
 
     return Qnil;

Modified: MacRuby/trunk/thread.c
===================================================================
--- MacRuby/trunk/thread.c	2008-09-26 01:28:50 UTC (rev 622)
+++ MacRuby/trunk/thread.c	2008-09-26 05:11:32 UTC (rev 623)
@@ -383,6 +383,56 @@
     return 0;
 }
 
+struct find_thread_ctx {
+    rb_thread_id_t id;
+    VALUE thval;    
+};
+
+static int
+find_thread(st_data_t key, st_data_t val, void *data)
+{
+    struct find_thread_ctx *ctx = (struct find_thread_ctx *)data;
+    if ((rb_thread_id_t)val == ctx->id) {
+	ctx->thval = (VALUE)key;
+	return ST_STOP;
+    }
+    return ST_CONTINUE;
+}
+
+rb_thread_t *
+rb_thread_wrap_existing_native_thread(rb_thread_id_t id)
+{
+    VALUE thval;
+    rb_thread_t *th;
+    struct find_thread_ctx ctx = {id, 0};
+
+    st_foreach(GET_THREAD()->vm->living_threads, find_thread, (st_data_t)&ctx);
+
+    if (ctx.thval != 0) {
+	GetThreadPtr(ctx.thval, th);
+	return th;
+    }
+
+    thval = rb_thread_alloc(rb_cThread);
+
+    GetThreadPtr(thval, th);
+
+    th->thread_id = id;
+
+    /* setup thread environment */
+    th->first_args = Qnil;
+    th->first_proc = Qfalse;
+    th->first_func = NULL;
+
+    th->priority = GET_THREAD()->priority;
+    th->thgroup = GET_THREAD()->thgroup;
+
+    native_mutex_initialize(&th->interrupt_lock);
+    st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id);
+
+    return th;
+}
+
 static VALUE
 thread_create_core(VALUE thval, VALUE args, VALUE (*fn)(ANYARGS))
 {
@@ -3219,6 +3269,8 @@
     rb_define_method(cThGroup, "enclosed?", thgroup_enclosed_p, 0);
     rb_define_method(cThGroup, "add", thgroup_add, 1);
 
+    rb_cBarrier = rb_define_class("Barrier", rb_cObject);
+
     {
 	rb_thread_t *th = GET_THREAD();
 	th->thgroup = th->vm->thgroup_default = rb_obj_alloc(cThGroup);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080925/5c0404bf/attachment-0001.html 


More information about the macruby-changes mailing list