Revision: 623 http://trac.macosforge.org/projects/ruby/changeset/623 Author: lsansonetti@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);
participants (1)
-
source_changes@macosforge.org