Permalink
Browse files

now deleting internal structures, IR and machinec code of main functi…

…ons created by #eval

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@2875 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
1 parent 96df0a7 commit e169c4d94163e0e5d17cd54fbefa5ab4909b710a @lrz lrz committed Oct 21, 2009
Showing with 79 additions and 11 deletions.
  1. +0 −4 compiler.cpp
  2. +10 −0 compiler.h
  3. +68 −7 vm.cpp
  4. +1 −0 vm.h
View
@@ -673,7 +673,6 @@ RoxorCompiler::compile_prepare_method(Value *classVal, Value *sel,
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 @@ RoxorCompiler::compile_node(NODE *node)
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 @@ RoxorCompiler::compile_node(NODE *node)
Function *
RoxorCompiler::compile_main_function(NODE *node)
{
- rb_objc_retain((void *)node);
-
current_instance_method = true;
Value *val = compile_node(node);
View
@@ -76,6 +76,16 @@ class RoxorCompiler {
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();
}
View
75 vm.cpp
@@ -64,6 +64,7 @@ struct RoxorFunction {
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 @@ class RoxorJITManager : public JITMemoryManager {
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 @@ class RoxorJITManager : public JITMemoryManager {
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 @@ RoxorCore::compile(Function *func)
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 @@ rb_vm_run(const char *fname, NODE *node, rb_vm_binding_t *binding,
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"
View
1 vm.h
@@ -633,6 +633,7 @@ class RoxorCore {
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);

0 comments on commit e169c4d

Please sign in to comment.