Revision: 645 http://trac.macosforge.org/projects/ruby/changeset/645 Author: lsansonetti@apple.com Date: 2008-10-05 20:18:10 -0700 (Sun, 05 Oct 2008) Log Message: ----------- adding initial dtrace support, improved the GC finalizers, let auto decide when collections must happen Modified Paths: -------------- MacRuby/trunk/Rakefile MacRuby/trunk/array.c MacRuby/trunk/compile.h MacRuby/trunk/eval.c MacRuby/trunk/gc.c MacRuby/trunk/include/ruby/intern.h MacRuby/trunk/insns.def MacRuby/trunk/objc.m MacRuby/trunk/regexec.c MacRuby/trunk/string.c MacRuby/trunk/test/ruby/test_array.rb MacRuby/trunk/vm.h MacRuby/trunk/vm_insnhelper.c Added Paths: ----------- MacRuby/trunk/dtrace.d MacRuby/trunk/sample-macruby/DTrace/ MacRuby/trunk/sample-macruby/DTrace/gc.d MacRuby/trunk/sample-macruby/DTrace/insns_count.d MacRuby/trunk/sample-macruby/DTrace/methods_count.d MacRuby/trunk/sample-macruby/DTrace/methods_duration.d Modified: MacRuby/trunk/Rakefile =================================================================== --- MacRuby/trunk/Rakefile 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/Rakefile 2008-10-06 03:18:10 UTC (rev 645) @@ -234,8 +234,19 @@ end end +desc "Create dtrace.h" +task :dtrace_h do + dtrace_h = 'dtrace.h' + if !File.exist?(dtrace_h) or File.mtime(dtrace_h) < File.mtime('dtrace.d') + sh "/usr/sbin/dtrace -h -s dtrace.d -o new_dtrace.h" + if !File.exist?(dtrace_h) or File.read(dtrace_h) != File.read('new_dtrace.h') + mv 'new_dtrace.h', dtrace_h + end + end +end + desc "Build known objects" -task :objects => :config_h do +task :objects => [:config_h, :dtrace_h] do sh "/usr/bin/ruby tool/compile_prelude.rb prelude.rb miniprelude.c.new" if !File.exist?('miniprelude.c') or File.read('miniprelude.c') != File.read('miniprelude.c.new') mv('miniprelude.c.new', 'miniprelude.c') Modified: MacRuby/trunk/array.c =================================================================== --- MacRuby/trunk/array.c 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/array.c 2008-10-06 03:18:10 UTC (rev 645) @@ -110,7 +110,6 @@ *(Class *)ary = (Class)klass; CFMakeCollectable(ary); - rb_gc_malloc_increase(sizeof(void *)); return (VALUE)ary; } Modified: MacRuby/trunk/compile.h =================================================================== --- MacRuby/trunk/compile.h 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/compile.h 2008-10-06 03:18:10 UTC (rev 645) @@ -167,6 +167,9 @@ ADD_INSN1(seq, line, trace, INT2FIX(event)); \ } +#define ADD_TRACE2(seq, line, event) \ + ADD_INSN1(seq, line, trace, INT2FIX(event)); + /* add label */ #define ADD_LABEL(seq, label) \ ADD_ELEM(seq, (LINK_ELEMENT *) label) Added: MacRuby/trunk/dtrace.d =================================================================== --- MacRuby/trunk/dtrace.d (rev 0) +++ MacRuby/trunk/dtrace.d 2008-10-06 03:18:10 UTC (rev 645) @@ -0,0 +1,8 @@ +provider macruby { + probe insn__entry(char *insnname, char *sourcefile, int sourceline); + probe insn__return(char *insnname, char *sourcefile, int sourceline); + probe method__entry(char *classname, char *methodname, char *sourcefile, int sourceline); + probe method__return(char *classname, char *methodname, char *sourcefile, int sourceline); + probe raise(char *classname, char *sourcefile, int sourceline); + probe rescue(char *sourcefile, int sourceline); +}; Modified: MacRuby/trunk/eval.c =================================================================== --- MacRuby/trunk/eval.c 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/eval.c 2008-10-06 03:18:10 UTC (rev 645) @@ -12,6 +12,7 @@ **********************************************************************/ #include "eval_intern.h" +#include "dtrace.h" VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE); VALUE rb_binding_new(void); @@ -444,6 +445,11 @@ rb_trap_restore_mask(); if (tag != TAG_FATAL) { + if (MACRUBY_RAISE_ENABLED()) { + MACRUBY_RAISE((char *)rb_obj_classname(mesg), + (char *)rb_sourcefile(), + rb_sourceline()); + } EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->cfp->self, 0 /* TODO: id */, 0 /* TODO: klass */); } Modified: MacRuby/trunk/gc.c =================================================================== --- MacRuby/trunk/gc.c 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/gc.c 2008-10-06 03:18:10 UTC (rev 645) @@ -44,7 +44,11 @@ #define AUTO_COLLECT_RATIO_COLLECTION (0 << 0) #define AUTO_COLLECT_GENERATIONAL_COLLECTION (1 << 0) #define AUTO_COLLECT_FULL_COLLECTION (1 << 0) +#define AUTO_COLLECT_EXHAUSTIVE_COLLECTION (3 << 0) +#define AUTO_COLLECT_SYNCHRONOUS (1 << 2) +#define AUTO_COLLECT_IF_NEEDED (1 << 3) #define AUTO_LOG_COLLECTIONS (1 << 1) +#define AUTO_LOG_COLLECT_DECISION (1 << 2) #define AUTO_LOG_REGIONS (1 << 4) #define AUTO_LOG_UNUSUAL (1 << 5) #define AUTO_LOG_WEAK (1 << 6) @@ -105,7 +109,6 @@ } auto_statistics_t; #endif static auto_zone_t *__auto_zone = NULL; -static long xmalloc_count = 0; int rb_io_fptr_finalize(struct rb_io_t*); @@ -124,7 +127,6 @@ #undef GC_DEBUG int ruby_gc_stress = 0; -static long malloc_increase = 0; bool dont_gc = false; #define malloc_limit GC_MALLOC_LIMIT VALUE *rb_gc_stack_start = 0; @@ -187,14 +189,6 @@ static int garbage_collect(void); -void -rb_gc_malloc_increase(size_t size) -{ - malloc_increase += size; - if (!dont_gc && (ruby_gc_stress || malloc_increase > malloc_limit)) - garbage_collect(); -} - static void rb_objc_no_gc_error(void) { @@ -214,13 +208,11 @@ rb_raise(rb_eNoMemError, "negative allocation size (or too big)"); } if (size == 0) size = 1; - rb_gc_malloc_increase(size); if (__auto_zone == NULL) rb_objc_no_gc_error(); mem = auto_zone_allocate_object(__auto_zone, size, AUTO_MEMORY_SCANNED, 0, 0); - xmalloc_count++; if (!mem) { rb_memerror(); } @@ -264,9 +256,6 @@ if (size == 0) size = 1; - rb_gc_malloc_increase(size); - if (ruby_gc_stress) - garbage_collect(); mem = malloc_zone_realloc(__auto_zone, ptr, size); if (mem == NULL) rb_memerror(); @@ -417,43 +406,17 @@ static void *__nsobject = NULL; -#define USE_OBJECTS_POOL 0 - -#if USE_OBJECTS_POOL -# define OBJECTS_POOL_SIZE 1000000 -static void **objects_pool = NULL; -static unsigned objects_pool_i = 0; -#endif - void * rb_objc_newobj(size_t size) { void *obj; - rb_gc_malloc_increase(size); -#if USE_OBJECTS_POOL - if (objects_pool == NULL) - objects_pool = malloc(sizeof(void *) * OBJECTS_POOL_SIZE); - if (objects_pool_i == 0) { - unsigned i; - //printf("repoll\n"); - for (i = 0; i < OBJECTS_POOL_SIZE; i++) { - objects_pool[i] = auto_zone_allocate_object(__auto_zone, sizeof(RVALUE), AUTO_OBJECT_SCANNED, 1, 0); - assert(objects_pool[i] != NULL); - } - objects_pool_i = OBJECTS_POOL_SIZE - 1; - } - //printf("get object %d from poll\n", objects_pool_i); - obj = objects_pool[objects_pool_i--]; - auto_zone_release(__auto_zone, obj); -#else obj = auto_zone_allocate_object(__auto_zone, size, AUTO_OBJECT_SCANNED, 0, 0); assert(obj != NULL); -#endif - if (__nsobject == NULL) + if (__nsobject == NULL) { __nsobject = (void *)objc_getClass("NSObject"); + } RBASIC(obj)->klass = (VALUE)__nsobject; - //DLOG("NEWOBJ", "size %ld -> %p", size, obj); return obj; } @@ -469,12 +432,14 @@ auto_zone_unregister_thread(__auto_zone); } -void +void native_mutex_lock(pthread_mutex_t *lock); +void native_mutex_unlock(pthread_mutex_t *lock); + +static void rb_objc_scan_external_callout(void *context, void (*scanner)(void *context, void *start, void *end)) { rb_thread_t *th = GET_THREAD(); (*scanner)(context, th->stack, th->cfp->sp); - //(*scanner)(context, th->stack, th->stack + th->stack_size); } NODE* @@ -582,7 +547,6 @@ if (dont_gc) return Qtrue; auto_collect(__auto_zone, AUTO_COLLECT_GENERATIONAL_COLLECTION, NULL); - malloc_increase = 0; return Qtrue; } @@ -1274,33 +1238,23 @@ rb_obj_imp_finalize(void *obj, SEL sel) { 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); + bool call_finalize, free_ivar; if (NATIVE((VALUE)obj)) { 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) { - rb_call_os_finalizer(obj); - } - if ((flag & FL_EXIVAR) == FL_EXIVAR) { - rb_free_generic_ivar((VALUE)obj); - } - if (need_protection) { - native_mutex_unlock(&GET_THREAD()->vm->global_interpreter_lock); - } + + call_finalize = (flag & FL_FINALIZE) == FL_FINALIZE; + free_ivar = (flag & FL_EXIVAR) == FL_EXIVAR; } else { - 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)) { + if (call_finalize || free_ivar) { + if (need_protection) { native_mutex_lock(&GET_THREAD()->vm->global_interpreter_lock); } if (call_finalize) { @@ -1309,7 +1263,7 @@ if (free_ivar) { rb_free_generic_ivar((VALUE)obj); } - if (need_protection && (call_finalize || free_ivar)) { + if (need_protection) { native_mutex_unlock(&GET_THREAD()->vm->global_interpreter_lock); } } @@ -1330,17 +1284,20 @@ rb_objc_scan_external_callout; if (getenv("GC_DEBUG")) control->log = AUTO_LOG_COLLECTIONS | AUTO_LOG_REGIONS - | AUTO_LOG_UNUSUAL; + | AUTO_LOG_UNUSUAL | AUTO_LOG_COLLECT_DECISION; Method m = class_getInstanceMethod((Class)objc_getClass("NSObject"), sel_registerName("finalize")); assert(m != NULL); method_setImplementation(m, (IMP)rb_obj_imp_finalize); + + auto_collector_disable(__auto_zone); } void Init_PostGC(void) { objc_startCollectorThread(); + auto_collector_reenable(__auto_zone); } void Modified: MacRuby/trunk/include/ruby/intern.h =================================================================== --- MacRuby/trunk/include/ruby/intern.h 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/include/ruby/intern.h 2008-10-06 03:18:10 UTC (rev 645) @@ -347,7 +347,6 @@ void *rb_objc_get_associative_ref(void *, void *); void rb_objc_retain(const void *); void rb_objc_release(const void *); -void rb_gc_malloc_increase(size_t); # define rb_gc_mark_locations(x,y) # define rb_mark_tbl(x) # define rb_mark_set(x) Modified: MacRuby/trunk/insns.def =================================================================== --- MacRuby/trunk/insns.def 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/insns.def 2008-10-06 03:18:10 UTC (rev 645) @@ -1153,6 +1153,16 @@ } RUBY_VM_CHECK_INTS(); + + if (MACRUBY_METHOD_RETURN_ENABLED()) { + if (reg_cfp->iseq != NULL && reg_cfp->iseq->type == ISEQ_TYPE_METHOD) { + MACRUBY_METHOD_RETURN((char *)rb_class2name(reg_cfp->iseq->klass), + (char *)RSTRING_PTR(reg_cfp->iseq->name), + (char *)rb_sourcefile(), + rb_sourceline()); + } + } + vm_pop_frame(th); RESTORE_REGS(); } Modified: MacRuby/trunk/objc.m =================================================================== --- MacRuby/trunk/objc.m 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/objc.m 2008-10-06 03:18:10 UTC (rev 645) @@ -2644,7 +2644,8 @@ for (j = 0; j < methods_count; j++) { \ if (methods[j].name == sel_ignored) \ continue; \ - st_insert(t, (st_data_t)methods[j].name, (st_data_t)methods[j].types); \ + st_insert(t, (st_data_t)methods[j].name, \ + (st_data_t)strdup(methods[j].types)); \ } \ free(methods); \ } \ @@ -2937,15 +2938,21 @@ return recv; } +#define FLAGS_AS_ASSOCIATIVE_REF 1 + static CFMutableDictionaryRef __obj_flags; long rb_objc_flag_get_mask(const void *obj) { +#if FLAGS_AS_ASSOCIATIVE_REF + return (long)rb_objc_get_associative_ref((void *)obj, &__obj_flags); +#else if (__obj_flags == NULL) return 0; return (long)CFDictionaryGetValue(__obj_flags, obj); +#endif } bool @@ -2963,6 +2970,16 @@ void rb_objc_flag_set(const void *obj, int flag, bool val) { +#if FLAGS_AS_ASSOCIATIVE_REF + long v = (long)rb_objc_get_associative_ref((void *)obj, &__obj_flags); + if (val) { + v |= flag; + } + else { + v ^= flag; + } + rb_objc_set_associative_ref((void *)obj, &__obj_flags, (void *)v); +#else long v; if (__obj_flags == NULL) { @@ -2976,11 +2993,17 @@ v ^= flag; } CFDictionarySetValue(__obj_flags, obj, (void *)v); +#endif } long rb_objc_remove_flags(const void *obj) { +#if FLAGS_AS_ASSOCIATIVE_REF + long flag = (long)rb_objc_get_associative_ref((void *)obj, &__obj_flags); + //rb_objc_set_associative_ref((void *)obj, &__obj_flags, (void *)0); + return flag; +#else long flag; if (CFDictionaryGetValueIfPresent(__obj_flags, obj, (const void **)&flag)) { @@ -2988,6 +3011,7 @@ return flag; } return 0; +#endif } static void Modified: MacRuby/trunk/regexec.c =================================================================== --- MacRuby/trunk/regexec.c 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/regexec.c 2008-10-06 03:18:10 UTC (rev 645) @@ -104,14 +104,14 @@ if (IS_NULL(parent->childs)) { n = HISTORY_TREE_INIT_ALLOC_SIZE; - parent->childs = - (OnigCaptureTreeNode** )xmalloc(sizeof(OnigCaptureTreeNode*) * n); + GC_WB(&parent->childs, + (OnigCaptureTreeNode** )xmalloc(sizeof(OnigCaptureTreeNode*) * n)); } else { n = parent->allocated * 2; - parent->childs = + GC_WB(&parent->childs, (OnigCaptureTreeNode** )xrealloc(parent->childs, - sizeof(OnigCaptureTreeNode*) * n); + sizeof(OnigCaptureTreeNode*) * n)); } CHECK_NULL_RETURN_MEMERR(parent->childs); for (i = parent->allocated; i < n; i++) { @@ -343,7 +343,7 @@ offset = ((offset) * (state_num)) >> 3;\ if (size > 0 && offset < size && size < STATE_CHECK_BUFF_MAX_SIZE) {\ if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {\ - (msa).state_check_buff = (void* )xmalloc(size);\ + GC_WB(&(msa).state_check_buff, (void* )xmalloc(size));\ CHECK_NULL_RETURN_MEMERR((msa).state_check_buff);\ }\ else \ Added: MacRuby/trunk/sample-macruby/DTrace/gc.d =================================================================== --- MacRuby/trunk/sample-macruby/DTrace/gc.d (rev 0) +++ MacRuby/trunk/sample-macruby/DTrace/gc.d 2008-10-06 03:18:10 UTC (rev 645) @@ -0,0 +1,22 @@ +#!/usr/sbin/dtrace -s + +#pragma D option quiet + +BEGIN +{ + printf("Target pid: %d\n\n", $target); + printf("%-10s %-10s %-10s %-10s\n", "OBJECTS", "BYTES", "DURATION", "TYPE"); + printf("--------------------------------------------------------------------------------\n"); +} + +pid$target::auto_trace_collection_begin:entry +{ + self->starttime = walltimestamp / 1000; +} + +pid$target::auto_trace_collection_end:entry +{ + printf("%-10d %-10d %-10d %-10s\n", arg2, arg3, + (walltimestamp / 1000) - self->starttime, + arg1 ? "generational" : "full"); +} Added: MacRuby/trunk/sample-macruby/DTrace/insns_count.d =================================================================== --- MacRuby/trunk/sample-macruby/DTrace/insns_count.d (rev 0) +++ MacRuby/trunk/sample-macruby/DTrace/insns_count.d 2008-10-06 03:18:10 UTC (rev 645) @@ -0,0 +1,21 @@ +#!/usr/sbin/dtrace -s + +#pragma D option quiet + +BEGIN +{ + printf("Target pid: %d\n\n", $target); +} + +macruby$target:::insn-entry +{ + @[copyinstr(arg0)] = count(); +} + +END +{ + printf("\n"); + printf("%30s %-30s\n", "INSN", "COUNT"); + printf("--------------------------------------------------------------------------------\n"); + printa("%30s %-30@d\n", @); +} Added: MacRuby/trunk/sample-macruby/DTrace/methods_count.d =================================================================== --- MacRuby/trunk/sample-macruby/DTrace/methods_count.d (rev 0) +++ MacRuby/trunk/sample-macruby/DTrace/methods_count.d 2008-10-06 03:18:10 UTC (rev 645) @@ -0,0 +1,23 @@ +#!/usr/sbin/dtrace -s + +#pragma D option quiet + +BEGIN +{ + printf("Target pid: %d\n\n", $target); +} + +macruby$target:::method-entry +{ + printf("%30s:%-5d %s#%s\n", copyinstr(arg2), arg3, + copyinstr(arg0), copyinstr(arg1)); + @methods_count[copyinstr(arg0), copyinstr(arg1)] = count(); +} + +END +{ + printf("\n"); + printf("%30s %-30s %s\n", "CLASS", "METHOD", "COUNT"); + printf("--------------------------------------------------------------------------------\n"); + printa("%30s %-30s %@d\n", @methods_count); +} Added: MacRuby/trunk/sample-macruby/DTrace/methods_duration.d =================================================================== --- MacRuby/trunk/sample-macruby/DTrace/methods_duration.d (rev 0) +++ MacRuby/trunk/sample-macruby/DTrace/methods_duration.d 2008-10-06 03:18:10 UTC (rev 645) @@ -0,0 +1,23 @@ +#!/usr/sbin/dtrace -s + +#pragma D option quiet + +BEGIN +{ + printf("Target pid: %d\n\n", $target); + printf("%20s %-5s %10s %-30s %10s\n", "FILE", "LINE", "CLASS", "METHOD", + "DURATION"); + printf("--------------------------------------------------------------------------------\n"); +} + +macruby$target:::method-entry +{ + self->starttime = walltimestamp / 1000; +} + +macruby$target:::method-return +{ + printf("%20s:%-5d %10s#%-30s %10d\n", copyinstr(arg2), arg3, + copyinstr(arg0), copyinstr(arg1), + (walltimestamp / 1000) - self->starttime); +} Modified: MacRuby/trunk/string.c =================================================================== --- MacRuby/trunk/string.c 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/string.c 2008-10-06 03:18:10 UTC (rev 645) @@ -75,7 +75,6 @@ return NULL; mdata = CFDataCreateMutableCopy(NULL, 0, data); len = CFDataGetLength(data); - rb_gc_malloc_increase(len); /* This is a hack to make sure a sentinel byte is created at the * end of the buffer. */ @@ -125,7 +124,6 @@ kCFStringEncodingUTF8, false, kCFAllocatorNull); - rb_gc_malloc_increase(datalen); if (bytestr != NULL) { if (CFStringGetLength(bytestr) == datalen) { CFStringReplaceAll((CFMutableStringRef)str, (CFStringRef)bytestr); @@ -198,7 +196,6 @@ data = CFDataCreateMutable(NULL, 0); CFDataAppendBytes(data, (const UInt8 *)dataptr, datalen); - rb_gc_malloc_increase(datalen); rb_str_cfdata_set(str, data); CFMakeCollectable(data); } @@ -232,8 +229,6 @@ substr = CFStringCreateWithBytes(NULL, (const UInt8 *)ptr, len, kCFStringEncodingUTF8, false); - rb_gc_malloc_increase(32 + (sizeof(UniChar) * len)); - if (substr != NULL) { CFStringAppend((CFMutableStringRef)str, substr); CFRelease(substr); @@ -247,7 +242,6 @@ } } } - rb_gc_malloc_increase(32 + (sizeof(UniChar) * len)); if (need_padding) CFStringPad((CFMutableStringRef)str, CFSTR(" "), len, 0); @@ -415,8 +409,6 @@ CFMakeCollectable((CFTypeRef)dup); - rb_gc_malloc_increase(32 + (sizeof(UniChar) * RSTRING_LEN(dup))); - return dup; } @@ -742,7 +734,6 @@ CFDataAppendBytes(subdata, bytes + beg, len); rb_str_cfdata_set((VALUE)substr, subdata); CFMakeCollectable(subdata); - rb_gc_malloc_increase(sizeof(UInt8) * len); RSTRING_SYNC(substr); } @@ -757,7 +748,6 @@ buffer); CFStringAppendCharacters(substr, buffer, len); } - rb_gc_malloc_increase(sizeof(UniChar) * len); } CFMakeCollectable(substr); return (VALUE)substr; @@ -826,7 +816,6 @@ data = (CFMutableDataRef)rb_str_cfdata2(str); if (data != NULL) { CFDataAppendBytes(data, (const UInt8 *)ptr, len); - rb_gc_malloc_increase(sizeof(UniChar) * len); } else { long slen; @@ -924,7 +913,6 @@ CFDataGetLength(data)); } } - rb_gc_malloc_increase(sizeof(UniChar) * str2len); return str; } @@ -965,7 +953,6 @@ buf[1] = '\0'; CFStringAppendCString((CFMutableStringRef)str1, buf, kCFStringEncodingUTF8); - rb_gc_malloc_increase(sizeof(UniChar)); return str1; } return rb_str_append(str1, str2); @@ -2246,12 +2233,10 @@ CFMutableDataRef mdata; mdata = CFDataCreateMutableCopy(NULL, 0, data); - rb_gc_malloc_increase(CFDataGetLength(data)); rb_str_cfdata_set(str, mdata); CFMakeCollectable(mdata); } CFStringReplaceAll((CFMutableStringRef)str, (CFStringRef)str2); - rb_gc_malloc_increase(CFStringGetLength((CFStringRef)str2) * sizeof(UniChar)); if (OBJ_TAINTED(str2)) OBJ_TAINT(str); return str; Modified: MacRuby/trunk/test/ruby/test_array.rb =================================================================== --- MacRuby/trunk/test/ruby/test_array.rb 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/test/ruby/test_array.rb 2008-10-06 03:18:10 UTC (rev 645) @@ -467,7 +467,7 @@ def test_collect a = @cls[ 1, 'cat', 1..1 ] - assert_equal([ Fixnum, NSCFString, Range], a.collect {|e| e.class} ) + assert_equal([ Fixnum, String, Range], a.collect {|e| e.class} ) assert_equal([ 99, 99, 99], a.collect { 99 } ) assert_equal([], @cls[].collect { 99 }) @@ -481,8 +481,8 @@ # also update map! def test_collect! a = @cls[ 1, 'cat', 1..1 ] - assert_equal([ Fixnum, NSCFString, Range], a.collect! {|e| e.class} ) - assert_equal([ Fixnum, NSCFString, Range], a) + assert_equal([ Fixnum, String, Range], a.collect! {|e| e.class} ) + assert_equal([ Fixnum, String, Range], a) a = @cls[ 1, 'cat', 1..1 ] assert_equal([ 99, 99, 99], a.collect! { 99 } ) @@ -821,8 +821,8 @@ # also update collect! def test_map! a = @cls[ 1, 'cat', 1..1 ] - assert_equal(@cls[ Fixnum, NSCFString, Range], a.map! {|e| e.class} ) - assert_equal(@cls[ Fixnum, NSCFString, Range], a) + assert_equal(@cls[ Fixnum, String, Range], a.map! {|e| e.class} ) + assert_equal(@cls[ Fixnum, String, Range], a) a = @cls[ 1, 'cat', 1..1 ] assert_equal(@cls[ 99, 99, 99], a.map! { 99 } ) @@ -1454,7 +1454,7 @@ klass = Class.new(Array) a = klass.new.to_a assert_equal([], a) - assert_equal(NSCFArray, a.class) + assert_equal(Array, a.class) end def test_values_at2 Modified: MacRuby/trunk/vm.h =================================================================== --- MacRuby/trunk/vm.h 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/vm.h 2008-10-06 03:18:10 UTC (rev 645) @@ -79,9 +79,11 @@ #else +extern void rb_enter_insn_trace(rb_control_frame_t *); +extern void rb_end_insn_trace(rb_control_frame_t *); #define debugs -#define DEBUG_ENTER_INSN(insn) //printf("enter insn %s\n", insn); -#define DEBUG_END_INSN() +#define DEBUG_ENTER_INSN(insn) rb_enter_insn_trace(GET_CFP()) +#define DEBUG_END_INSN() rb_end_insn_trace(GET_CFP()); #endif #define throwdebug if(0)printf Modified: MacRuby/trunk/vm_insnhelper.c =================================================================== --- MacRuby/trunk/vm_insnhelper.c 2008-10-01 04:03:14 UTC (rev 644) +++ MacRuby/trunk/vm_insnhelper.c 2008-10-06 03:18:10 UTC (rev 645) @@ -15,6 +15,7 @@ #if WITH_OBJC # include <dlfcn.h> +# include "dtrace.h" #endif /* control stack frame */ @@ -724,6 +725,13 @@ DLOG("RCALL", "%c[<%s %p> %s] node=%p cached=%d", class_isMetaClass((Class)klass) ? '+' : '-', class_getName((Class)klass), (void *)recv, (char *)rb_id2name(id), mn, cached); #endif + if (MACRUBY_METHOD_ENTRY_ENABLED()) { + MACRUBY_METHOD_ENTRY((char *)rb_class2name(klass), + (char *)rb_id2name(id), + (char *)rb_sourcefile(), + rb_sourceline()); + } + start_method_dispatch: if (mn != NULL) { @@ -1844,3 +1852,45 @@ return val; } + +#include "insns_info.inc" + +void +rb_enter_insn_trace(rb_control_frame_t *cfp) +{ + if (MACRUBY_INSN_ENTRY_ENABLED()) { + /* just to get rid of compilation warnings... */ + if (0) { + insn_op_types(0); + insn_op_type(0, 0); + } + + rb_iseq_t *iseq = cfp->iseq; + + if (iseq != NULL && VM_FRAME_TYPE(cfp) != FRAME_MAGIC_FINISH) { + VALUE *seq = iseq->iseq; + int pc = cfp->pc - iseq->iseq_encoded; + + MACRUBY_INSN_ENTRY((char *)insn_name(seq[pc]), + (char *)rb_sourcefile(), + rb_sourceline()); + } + } +} + +void +rb_end_insn_trace(rb_control_frame_t *cfp) +{ + if (MACRUBY_INSN_RETURN_ENABLED()) { + rb_iseq_t *iseq = cfp->iseq; + + if (iseq != NULL && VM_FRAME_TYPE(cfp) != FRAME_MAGIC_FINISH) { + VALUE *seq = iseq->iseq; + int pc = cfp->pc - iseq->iseq_encoded; + + MACRUBY_INSN_RETURN((char *)insn_name(seq[pc]), + (char *)rb_sourcefile(), + rb_sourceline()); + } + } +}
participants (1)
-
source_changes@macosforge.org