From fa0cdd6234aa73ab0680c37f23664ff8c73cc1cb Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 20 Jun 2009 06:08:23 +0000 Subject: Garbage collection of code-allocated stack frames. git-svn-id: http://svn.drobilla.net/resp/tuplr@130 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- llvm.cpp | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'llvm.cpp') diff --git a/llvm.cpp b/llvm.cpp index 85e4a14..80aaafb 100644 --- a/llvm.cpp +++ b/llvm.cpp @@ -241,11 +241,16 @@ AClosure::liftCall(CEnv& cenv, const AType& argsT) ATuple* protT = thisType->at(1)->as(); + vector argNames; + for (size_t i = 0; i < prot()->size(); ++i) { + argNames.push_back(prot()->at(i)->str()); + } + // Write function declaration const string name = (this->name == "") ? cenv.gensym("_fn") : this->name; Function* f = compileFunction(cenv, name, lltype(thisType->at(thisType->size()-1)->to()), - *protT, loc); + *protT, loc, argNames); llvm::IRBuilder<>& builder = llengine(cenv)->builder; @@ -253,12 +258,13 @@ AClosure::liftCall(CEnv& cenv, const AType& argsT) Subst oldSubst = cenv.tsubst; cenv.tsubst = Subst::compose(cenv.tsubst, Subst::compose(argsSubst, subst)); -//#define EXPLICIT_STACK_FRAME 1 +//#define EXPLICIT_STACK_FRAMES 1 #ifdef EXPLICIT_STACK_FRAMES vector types; - types.push_back(PointerType::get(Type::VoidTy, 0)); - size_t s = 0; + types.push_back(Type::Int8Ty); + types.push_back(Type::Int8Ty); + size_t s = 16; // stack frame size in bits #endif // Bind argument values in CEnv @@ -290,16 +296,20 @@ AClosure::liftCall(CEnv& cenv, const AType& argsT) } // Create stack frame - StructType* sT = StructType::get(types, false); - PointerType* pT = PointerType::get(sT, 0); - Value* frameSize = ConstantInt::get(Type::Int32Ty, (s + pT->getPrimitiveSizeInBits()) / 8); - Value* mem = builder.CreateCall(LLVal(cenv.alloc), frameSize, "mem"); - Value* frame = builder.CreateBitCast(mem, pT, "frame"); + StructType* frameT = StructType::get(types, false); + PointerType* framePtrT = PointerType::get(frameT, 0); + + Value* tag = ConstantInt::get(Type::Int8Ty, (uint8_t)GC::TAG_FRAME); + + Value* frameSize = ConstantInt::get(Type::Int32Ty, s / 8); + Value* frame = builder.CreateCall2(LLVal(cenv.alloc), frameSize, tag, "frame"); + + Value* framePtr = builder.CreateBitCast(frame, framePtrT, "frameptr"); // Bind parameter values in stack frame - i = 1; + i = 2; for (Function::arg_iterator a = f->arg_begin(); a != f->arg_end(); ++a, ++i) { - Value* v = builder.CreateStructGEP(frame, i); + Value* v = builder.CreateStructGEP(framePtr, i, "arg"); builder.CreateStore(&*a, v); } #endif @@ -550,7 +560,7 @@ eval(CEnv& cenv, const string& name, istream& is) cenv.out << call(resultType, llengine(cenv)->engine->getPointerToFunction(f)) << " : " << resultType << endl; - Object::pool.collect(cenv, Object::pool.roots()); + Object::pool.collect(Object::pool.roots()); if (cenv.args.find("-d") != cenv.args.end()) cenv.write(cenv.out); @@ -608,7 +618,7 @@ repl(CEnv& cenv) if (body->to()) cenv.lock(body); - Object::pool.collect(cenv, Object::pool.roots()); + Object::pool.collect(Object::pool.roots()); cenv.tsubst = oldSubst; if (cenv.args.find("-d") != cenv.args.end()) @@ -628,7 +638,8 @@ newCenv(PEnv& penv, TEnv& tenv) CEnv* cenv = new CEnv(penv, tenv, engine); // Host provided allocation primitive prototypes - std::vector argsT(1, Type::Int32Ty); + std::vector argsT(1, Type::Int32Ty); // size + argsT.push_back(Type::Int8Ty); // tag FunctionType* funcT = FunctionType::get(PointerType::get(Type::Int8Ty, 0), argsT, false); cenv->alloc = Function::Create(funcT, Function::ExternalLinkage, "tuplr_gc_allocate", engine->module); @@ -639,7 +650,7 @@ newCenv(PEnv& penv, TEnv& tenv) void freeCenv(CEnv* cenv) { - Object::pool.collect(*cenv, ::GC::Roots()); + Object::pool.collect(GC::Roots()); delete (LLVMEngine*)cenv->engine(); delete cenv; } -- cgit v1.2.1