From cc5676fb66babff615fa6280fda26ed6bf756a27 Mon Sep 17 00:00:00 2001 From: Laurent Sansonetti Date: Fri, 3 Dec 2010 03:27:04 +0000 Subject: [PATCH] compile C-level blocks in the autozone heap and emit a write barrier to the original ruby Proc object, to avoid premature garbage collection of the Proc when calling the C-level block git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@4971 23306eb0-4c56-4727-a40e-e92c0eb68959 --- compiler.cpp | 9 +++++---- kernel.c | 15 +++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler.cpp b/compiler.cpp index 668c6b123..2cd33779d 100644 --- a/compiler.cpp +++ b/compiler.cpp @@ -5522,15 +5522,16 @@ RoxorCompiler::compile_conversion_to_c(const char *type, Value *val, return funcptr; } - // A C-level block. We allocate on the stack the literal + // A C-level block. We allocate on the auto heap the literal // structure following the ABI, initialize it then pass // a pointer to it. - Value *block_lit = new AllocaInst(BlockLiteralTy, "", bb); + Value *block_lit = compile_xmalloc(GET_CORE()->get_sizeof(BlockLiteralTy)); Value *args[] = { block_lit, - funcptr + funcptr, + val }; - CallInst::Create(initBlockFunc, args, args + 2, "", bb); + CallInst::Create(initBlockFunc, args, args + 3, "", bb); return new BitCastInst(block_lit, PtrTy, "", bb); } break; diff --git a/kernel.c b/kernel.c index 5ff2568cb..931a5fac5 100644 --- a/kernel.c +++ b/kernel.c @@ -1055,22 +1055,25 @@ struct ruby_block_literal { int reserved; void *imp; struct ruby_block_descriptor *descriptor; + VALUE ruby_proc; }; static struct ruby_block_descriptor ruby_block_descriptor_value = { 0, sizeof(struct ruby_block_literal) }; -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 -extern void *_NSConcreteStackBlock[32]; -#endif +extern void *_NSConcreteAutoBlock[32]; + +#define __MR_BLOCK_IS_GC (1 << 27) +#define __MR_BLOCK_HAS_DESCRIPTOR (1 << 29) PRIMITIVE void -vm_init_c_block(struct ruby_block_literal *b, void *imp) +vm_init_c_block(struct ruby_block_literal *b, void *imp, VALUE proc) { - b->isa = &_NSConcreteStackBlock; - b->flags = (1 << 29); + b->isa = &_NSConcreteAutoBlock; + b->flags = __MR_BLOCK_IS_GC | __MR_BLOCK_HAS_DESCRIPTOR; b->reserved = 0; b->imp = imp; b->descriptor = &ruby_block_descriptor_value; + GC_WB(&b->ruby_proc, proc); }