Revision: 3441 http://trac.macosforge.org/projects/ruby/changeset/3441 Author: lsansonetti@apple.com Date: 2010-02-08 01:10:54 -0800 (Mon, 08 Feb 2010) Log Message: ----------- get rid of bad allocas, disable frame pointer elimination, simplified const lookup primitive Modified Paths: -------------- MacRuby/trunk/MacRuby.m MacRuby/trunk/compiler.cpp MacRuby/trunk/compiler.h MacRuby/trunk/dispatcher.cpp MacRuby/trunk/objc.m MacRuby/trunk/sprintf.cpp MacRuby/trunk/variable.c MacRuby/trunk/vm.cpp Modified: MacRuby/trunk/MacRuby.m =================================================================== --- MacRuby/trunk/MacRuby.m 2010-02-07 05:48:53 UTC (rev 3440) +++ MacRuby/trunk/MacRuby.m 2010-02-08 09:10:54 UTC (rev 3441) @@ -71,9 +71,8 @@ { VALUE *rargv = NULL; if (argc > 0) { - rargv = (VALUE *)alloca(sizeof(VALUE) * argc); - int i; - for (i = 0; i < argc; i++) { + rargv = (VALUE *)xmalloc(sizeof(VALUE) * argc); + for (int i = 0; i < argc; i++) { rargv[i] = OC2RB(argv[i]); } } @@ -88,18 +87,16 @@ id *argv; if (firstArg != nil) { - int i; - argc = 1; va_start(args, firstArg); while (va_arg(args, id) != NULL) { argc++; } va_end(args); - argv = alloca(sizeof(id) * argc); + argv = xmalloc(sizeof(id) * argc); va_start(args, firstArg); argv[0] = firstArg; - for (i = 1; i < argc; i++) { + for (int i = 1; i < argc; i++) { argv[i] = va_arg(args, id); } va_end(args); Modified: MacRuby/trunk/compiler.cpp =================================================================== --- MacRuby/trunk/compiler.cpp 2010-02-07 05:48:53 UTC (rev 3440) +++ MacRuby/trunk/compiler.cpp 2010-02-08 09:10:54 UTC (rev 3441) @@ -239,27 +239,14 @@ RoxorCompiler::compile_protected_call(Value *imp, std::vector<Value *> ¶ms) { if (rescue_invoke_bb == NULL) { - CallInst *dispatch = CallInst::Create(imp, - params.begin(), - params.end(), - "", - bb); - return dispatch; + return CallInst::Create(imp, params.begin(), params.end(), "", bb); } else { BasicBlock *normal_bb = BasicBlock::Create(context, "normal", bb->getParent()); - - InvokeInst *dispatch = InvokeInst::Create(imp, - normal_bb, - rescue_invoke_bb, - params.begin(), - params.end(), - "", - bb); - + InvokeInst *dispatch = InvokeInst::Create(imp, normal_bb, + rescue_invoke_bb, params.begin(), params.end(), "", bb); bb = normal_bb; - return dispatch; } } @@ -1374,22 +1361,29 @@ } if (getConstFunc == NULL) { - // VALUE rb_vm_get_const(VALUE mod, unsigned char lexical_lookup, - // struct ccache *cache, ID id, unsigned char dynamic_class); + // VALUE rb_vm_get_const(VALUE mod, struct ccache *cache, ID id, + // int flags); getConstFunc = cast<Function>(module->getOrInsertFunction( "rb_vm_get_const", - RubyObjTy, RubyObjTy, Int8Ty, PtrTy, IntTy, Int8Ty, + RubyObjTy, RubyObjTy, PtrTy, IntTy, Int32Ty, NULL)); } std::vector<Value *> params; params.push_back(outer); - params.push_back(ConstantInt::get(Int8Ty, outer_given ? 0 : 1)); params.push_back(compile_ccache(id)); params.push_back(compile_id(id)); - params.push_back(ConstantInt::get(Int8Ty, dynamic_class ? 1 : 0)); + int flags = 0; + if (!outer_given) { + flags |= CONST_LOOKUP_LEXICAL; + } + if (dynamic_class) { + flags |= CONST_LOOKUP_DYNAMIC_CLASS; + } + params.push_back(ConstantInt::get(Int32Ty, flags)); + return compile_protected_call(getConstFunc, params); } @@ -2804,16 +2798,22 @@ else { UniChar *buf = (UniChar *)CFStringGetCharactersPtr( (CFStringRef)val); - + bool free_buf = false; if (buf == NULL) { - buf = (UniChar *)alloca(sizeof(UniChar) * str_len); + buf = (UniChar *)malloc(sizeof(UniChar) * str_len); CFStringGetCharacters((CFStringRef)val, CFRangeMake(0, str_len), buf); + free_buf = true; } GlobalVariable *str_gvar = compile_const_global_ustring(buf, str_len, CFHash((CFTypeRef)val)); + if (free_buf) { + free(buf); + buf = NULL; + } + std::vector<Value *> idxs; idxs.push_back(ConstantInt::get(Int32Ty, 0)); idxs.push_back(ConstantInt::get(Int32Ty, 0)); Modified: MacRuby/trunk/compiler.h =================================================================== --- MacRuby/trunk/compiler.h 2010-02-07 05:48:53 UTC (rev 3440) +++ MacRuby/trunk/compiler.h 2010-02-08 09:10:54 UTC (rev 3441) @@ -18,6 +18,10 @@ #define DISPATCH_SELF_ATTRASGN 4 // self attribute assignment #define SPLAT_ARG_FOLLOWS 0xdeadbeef +// For const lookup. +#define CONST_LOOKUP_LEXICAL 1 +#define CONST_LOOKUP_DYNAMIC_CLASS 2 + // For defined? #define DEFINED_IVAR 1 #define DEFINED_GVAR 2 Modified: MacRuby/trunk/dispatcher.cpp =================================================================== --- MacRuby/trunk/dispatcher.cpp 2010-02-07 05:48:53 UTC (rev 3440) +++ MacRuby/trunk/dispatcher.cpp 2010-02-08 09:10:54 UTC (rev 3441) @@ -76,7 +76,7 @@ IMP pimp, const rb_vm_arity_t &arity, int argc, const VALUE *argv) { if ((arity.real != argc) || (arity.max == -1)) { - VALUE *new_argv = (VALUE *)alloca(sizeof(VALUE) * arity.real); + VALUE *new_argv = (VALUE *)xmalloc(sizeof(VALUE) * arity.real); __rb_vm_fix_args(argv, new_argv, arity, argc); argv = new_argv; argc = arity.real; @@ -117,7 +117,7 @@ int argc, const VALUE *argv) { if ((arity.real != argc) || (arity.max == -1)) { - VALUE *new_argv = (VALUE *)alloca(sizeof(VALUE) * arity.real); + VALUE *new_argv = (VALUE *)xmalloc(sizeof(VALUE) * arity.real); __rb_vm_fix_args(argv, new_argv, arity, argc); argv = new_argv; argc = arity.real; @@ -337,7 +337,7 @@ GET_VM()->set_method_missing_reason(call_status); - VALUE *new_argv = (VALUE *)alloca(sizeof(VALUE) * (argc + 1)); + VALUE *new_argv = (VALUE *)xmalloc(sizeof(VALUE) * (argc + 1)); char buf[100]; int n = snprintf(buf, sizeof buf, "%s", sel_getName(sel)); @@ -639,10 +639,11 @@ if (argc > 1) { const char *p = strchr(selname, ':'); if (p != NULL && p + 1 != '\0') { - char *tmp = (char *)alloca(selname_len); + char *tmp = (char *)malloc(selname_len); strncpy(tmp, selname, p - selname + 1); tmp[p - selname + 1] = '\0'; sel = sel_registerName(tmp); + free(tmp); VALUE h = rb_hash_new(); bool ok = true; p += 1; @@ -1477,9 +1478,9 @@ VALUE *new_argv; if (argc == 1 && TYPE(argv[0]) == T_ARRAY && (arity.min > 1 || (arity.min == 1 && arity.min != arity.max))) { - // Expand the array + // Expand the array. long ary_len = RARRAY_LEN(argv[0]); - new_argv = (VALUE *)alloca(sizeof(VALUE) * ary_len); + new_argv = (VALUE *)xmalloc(sizeof(VALUE) * ary_len); for (int i = 0; i < ary_len; i++) { new_argv[i] = RARRAY_AT(argv[0], i); } @@ -1499,7 +1500,7 @@ else { new_argc = argc; } - new_argv = (VALUE *)alloca(sizeof(VALUE) * new_argc); + new_argv = (VALUE *)xmalloc(sizeof(VALUE) * new_argc); for (int i = 0; i < new_argc; i++) { new_argv[i] = i < argc ? argv[i] : Qnil; } Modified: MacRuby/trunk/objc.m =================================================================== --- MacRuby/trunk/objc.m 2010-02-07 05:48:53 UTC (rev 3440) +++ MacRuby/trunk/objc.m 2010-02-08 09:10:54 UTC (rev 3441) @@ -247,18 +247,16 @@ reload_class_constants(void) { static int class_count = 0; - int i, count; - Class *buf; - count = objc_getClassList(NULL, 0); + const int count = objc_getClassList(NULL, 0); if (count == class_count) { return; } - buf = (Class *)alloca(sizeof(Class) * count); + Class *buf = (Class *)malloc(sizeof(Class) * count); objc_getClassList(buf, count); - for (i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { Class k = buf[i]; if (!RCLASS_RUBY(k)) { long v = RCLASS_VERSION(k); @@ -291,6 +289,8 @@ } class_count = count; + + free(buf); } static void Modified: MacRuby/trunk/sprintf.cpp =================================================================== --- MacRuby/trunk/sprintf.cpp 2010-02-07 05:48:53 UTC (rev 3440) +++ MacRuby/trunk/sprintf.cpp 2010-02-08 09:10:54 UTC (rev 3441) @@ -479,7 +479,7 @@ fmt = rb_str_new2(new_fmt); } - VALUE *stub_args = (VALUE *)alloca(sizeof(VALUE) * argc + 4); + VALUE *stub_args = (VALUE *)malloc(sizeof(VALUE) * (argc + 4)); stub_args[0] = Qnil; // allocator stub_args[1] = Qnil; // format options stub_args[2] = fmt; // format string @@ -492,6 +492,7 @@ VALUE str = (*stub)((IMP)&CFStringCreateWithFormat, argc + 3, stub_args); CFMakeCollectable((void *)str); + free(stub_args); return str; } Modified: MacRuby/trunk/variable.c =================================================================== --- MacRuby/trunk/variable.c 2010-02-07 05:48:53 UTC (rev 3440) +++ MacRuby/trunk/variable.c 2010-02-08 09:10:54 UTC (rev 3441) @@ -31,25 +31,26 @@ } static void -ivar_dict_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg) +ivar_dict_foreach(CFDictionaryRef dict, int (*func)(ANYARGS), VALUE farg) { - CFIndex i, count; - const void **keys; - const void **values; - - count = CFDictionaryGetCount((CFDictionaryRef)hash); - if (count == 0) + const long count = CFDictionaryGetCount(dict); + if (count == 0) { return; + } - keys = (const void **)alloca(sizeof(void *) * count); - values = (const void **)alloca(sizeof(void *) * count); + const void **keys = (const void **)malloc(sizeof(void *) * count); + const void **values = (const void **)malloc(sizeof(void *) * count); - CFDictionaryGetKeysAndValues((CFDictionaryRef)hash, keys, values); + CFDictionaryGetKeysAndValues(dict, keys, values); - for (i = 0; i < count; i++) { - if ((*func)(keys[i], values[i], farg) != ST_CONTINUE) + for (long i = 0; i < count; i++) { + if ((*func)(keys[i], values[i], farg) != ST_CONTINUE) { break; + } } + + free(keys); + free(values); } static CFDictionaryValueCallBacks rb_cfdictionary_value_cb = { @@ -134,7 +135,7 @@ arg.klass = res->klass; arg.track = value; arg.prev = res; - ivar_dict_foreach((VALUE)iv_dict, fc_i, (VALUE)&arg); + ivar_dict_foreach(iv_dict, fc_i, (VALUE)&arg); if (arg.path) { res->path = arg.path; return ST_STOP; @@ -162,7 +163,7 @@ CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(rb_cObject); if (iv_dict != NULL) { - ivar_dict_foreach((VALUE)iv_dict, fc_i, (VALUE)&arg); + ivar_dict_foreach(iv_dict, fc_i, (VALUE)&arg); } if (arg.path == 0) { st_foreach_safe(rb_class_tbl, fc_i, (st_data_t)&arg); @@ -1192,7 +1193,7 @@ { CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(obj); if (iv_dict != NULL) { - ivar_dict_foreach((VALUE)iv_dict, func, arg); + ivar_dict_foreach(iv_dict, func, arg); } } return; @@ -1673,7 +1674,7 @@ } CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(mod); if (iv_dict != NULL) { - ivar_dict_foreach((VALUE)iv_dict, sv_i, (VALUE)tbl); + ivar_dict_foreach(iv_dict, sv_i, (VALUE)tbl); } return tbl; } @@ -2016,7 +2017,7 @@ VALUE ary = rb_ary_new(); CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(klass); if (iv_dict != NULL) { - ivar_dict_foreach((VALUE)iv_dict, cv_i, (VALUE)ary); + ivar_dict_foreach(iv_dict, cv_i, (VALUE)ary); } return ary; } Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2010-02-07 05:48:53 UTC (rev 3440) +++ MacRuby/trunk/vm.cpp 2010-02-08 09:10:54 UTC (rev 3441) @@ -1286,9 +1286,11 @@ extern "C" VALUE -rb_vm_get_const(VALUE outer, unsigned char lexical_lookup, - struct ccache *cache, ID path, unsigned char dynamic_class) +rb_vm_get_const(VALUE outer, struct ccache *cache, ID path, int flags) { + const bool lexical_lookup = (flags & CONST_LOOKUP_LEXICAL); + const bool dynamic_class = (flags & CONST_LOOKUP_DYNAMIC_CLASS); + if (dynamic_class) { Class k = GET_VM()->get_current_class(); if (lexical_lookup && k != NULL) { @@ -3047,7 +3049,8 @@ return; use_found: - rb_vm_kept_local *locals = (rb_vm_kept_local *)alloca(sizeof(rb_vm_kept_local)*lvars_size); + rb_vm_kept_local *locals = (rb_vm_kept_local *)malloc( + sizeof(rb_vm_kept_local)*lvars_size); va_list ar; va_start(ar, lvars_size); @@ -3105,6 +3108,7 @@ use_index = 0; free(old_current); } + free(locals); } static inline rb_vm_local_t ** @@ -4880,10 +4884,14 @@ void Init_PreVM(void) { - llvm::DwarfExceptionHandling = true; // required! - llvm::JITEmitDebugInfo = true; - // because pretty stack trace uses signal handling and thus breaks ours + // To emit DWARF exception tables. + llvm::DwarfExceptionHandling = true; + // To emit DWARF debug metadata. + llvm::JITEmitDebugInfo = true; + // To not interfere with our signal handling mechanism. llvm::DisablePrettyStackTrace = true; + // To not corrupt stack pointer (essential for backtracing). + llvm::NoFramePointerElim = true; RoxorCompiler::module = new llvm::Module("Roxor", getGlobalContext()); RoxorCompiler::module->setTargetTriple(TARGET_TRIPLE);