Revision: 2875 http://trac.macosforge.org/projects/ruby/changeset/2875 Author: lsansonetti@apple.com Date: 2009-10-21 13:46:32 -0700 (Wed, 21 Oct 2009) Log Message: ----------- now deleting internal structures, IR and machinec code of main functions created by #eval Modified Paths: -------------- MacRuby/trunk/compiler.cpp MacRuby/trunk/compiler.h MacRuby/trunk/vm.cpp MacRuby/trunk/vm.h Modified: MacRuby/trunk/compiler.cpp =================================================================== --- MacRuby/trunk/compiler.cpp 2009-10-21 03:17:53 UTC (rev 2874) +++ MacRuby/trunk/compiler.cpp 2009-10-21 20:46:32 UTC (rev 2875) @@ -673,7 +673,6 @@ params.push_back(sel); params.push_back(compile_const_pointer(new_function)); - rb_objc_retain((void *)body); params.push_back(compile_arity(arity)); params.push_back(ConstantInt::get(Int32Ty, rb_vm_node_flags(body))); @@ -4969,7 +4968,6 @@ current_block_func = cast<Function>(block); current_block_node = node->nd_body; - rb_objc_retain((void *)current_block_node); Value *caller; assert(node->nd_iter != NULL); @@ -5177,8 +5175,6 @@ Function * RoxorCompiler::compile_main_function(NODE *node) { - rb_objc_retain((void *)node); - current_instance_method = true; Value *val = compile_node(node); Modified: MacRuby/trunk/compiler.h =================================================================== --- MacRuby/trunk/compiler.h 2009-10-21 03:17:53 UTC (rev 2874) +++ MacRuby/trunk/compiler.h 2009-10-21 20:46:32 UTC (rev 2875) @@ -76,6 +76,16 @@ return i == scopes.end() ? NULL : i->second; } + bool delete_scope(Function *f) { + std::map<Function *, RoxorScope *>::iterator i = scopes.find(f); + if (i != scopes.end()) { + scopes.erase(i); + delete i->second; + return true; + } + return false; + } + void clear_scopes(void) { scopes.clear(); } Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2009-10-21 03:17:53 UTC (rev 2874) +++ MacRuby/trunk/vm.cpp 2009-10-21 20:46:32 UTC (rev 2875) @@ -64,6 +64,7 @@ unsigned char *start; unsigned char *end; void *imp; + std::vector<unsigned char *> ehs; RoxorFunction(Function *_f, RoxorScope *_scope, unsigned char *_start, unsigned char *_end) { @@ -107,6 +108,20 @@ return NULL; } + RoxorFunction *delete_function(Function *func) { + std::vector<struct RoxorFunction *>::iterator iter = + functions.begin(); + while (iter != functions.end()) { + RoxorFunction *f = *iter; + if (f->f == func) { + functions.erase(iter); + return f; + } + ++iter; + } + return NULL; + } + void setMemoryWritable(void) { mm->setMemoryWritable(); } @@ -170,6 +185,8 @@ void endExceptionTable(const Function *F, uint8_t *TableStart, uint8_t *TableEnd, uint8_t* FrameRegister) { + assert(!functions.empty()); + functions.back()->ehs.push_back(FrameRegister); mm->endExceptionTable(F, TableStart, TableEnd, FrameRegister); } @@ -410,6 +427,42 @@ return imp; } +// in libgcc +extern "C" void __deregister_frame(const void *); + +void +RoxorCore::delenda(Function *func) +{ + assert(func->use_empty()); + + // Remove from cache. + std::map<Function *, IMP>::iterator iter = JITcache.find(func); + if (iter != JITcache.end()) { + JITcache.erase(iter); + } + + // Delete for JIT memory manager list. + RoxorFunction *f = jmm->delete_function(func); + assert(f != NULL); + + // Unregister each dwarf exception handler. + // XXX this should really be done by LLVM... + for (std::vector<unsigned char *>::iterator i = f->ehs.begin(); + i != f->ehs.end(); ++i) { + __deregister_frame((const void *)*i); + } + + // Remove the compiler scope. + RoxorCompiler::shared->delete_scope(func); + delete f; + + // Delete machine code. + ee->freeMachineCodeForFunction(func); + + // Delete IR. + func->eraseFromParent(); +} + bool RoxorCore::symbolize_call_address(void *addr, void **startp, char *path, size_t path_len, unsigned long *ln, char *name, size_t name_len) @@ -3289,35 +3342,43 @@ bool inside_eval) { RoxorVM *vm = GET_VM(); + RoxorCompiler *compiler = RoxorCompiler::shared; + // Compile IR. if (binding != NULL) { vm->push_current_binding(binding, false); } - - RoxorCompiler *compiler = RoxorCompiler::shared; - bool old_inside_eval = compiler->is_inside_eval(); compiler->set_inside_eval(inside_eval); compiler->set_fname(fname); Function *function = compiler->compile_main_function(node); compiler->set_fname(NULL); compiler->set_inside_eval(old_inside_eval); - if (binding != NULL) { vm->pop_current_binding(false); } + // JIT compile the function. IMP imp = GET_CORE()->compile(function); - // For symbolication. + // Register it for symbolication. rb_vm_method_node_t *mnode = GET_CORE()->method_node_get(imp, true); mnode->klass = 0; mnode->arity = rb_vm_arity(2); mnode->sel = sel_registerName("<main>"); mnode->objc_imp = mnode->ruby_imp = imp; mnode->flags = 0; - - return ((VALUE(*)(VALUE, SEL))imp)(vm->get_current_top_object(), 0); + + // Execute the function. + VALUE ret = ((VALUE(*)(VALUE, SEL))imp)(vm->get_current_top_object(), 0); + + if (inside_eval) { + // XXX We only delete functions created by #eval. In theory it should + // also work for other functions, but it makes spec:ci crash. + GET_CORE()->delenda(function); + } + + return ret; } extern "C" Modified: MacRuby/trunk/vm.h =================================================================== --- MacRuby/trunk/vm.h 2009-10-21 03:17:53 UTC (rev 2874) +++ MacRuby/trunk/vm.h 2009-10-21 20:46:32 UTC (rev 2875) @@ -633,6 +633,7 @@ void optimize(Function *func); IMP compile(Function *func); + void delenda(Function *func); void load_bridge_support(const char *path, const char *framework_path, int options);
participants (1)
-
source_changes@macosforge.org