the previous change related to module sharing between functions appears to have introduced memory leak - caught by asan; also apply fixes discussed in Lua mailing list

pull/81/head
Dibyendu Majumdar 8 years ago
parent 7adae06302
commit 5dc495720f

@ -424,6 +424,7 @@ typedef struct LocVar {
typedef enum {
RAVI_JIT_NOT_COMPILED = 0,
RAVI_JIT_CANT_COMPILE = 1,
RAVI_JIT_COMPILED = 2 /* But actual function pointer must be checked */
} ravi_jit_status_t;
typedef enum {

@ -1806,7 +1806,7 @@ static void labelstat (LexState *ls, TString *label, int line) {
checkrepeated(fs, ll, label); /* check for repeated labels */
checknext(ls, TK_DBCOLON); /* skip double colon */
/* create new entry for this label */
l = newlabelentry(ls, ll, label, line, fs->pc);
l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs));
skipnoopstat(ls); /* skip other no-op statements */
if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
/* assume that locals are already out of scope */

@ -688,6 +688,7 @@ typedef struct GMatchState {
static int gmatch_aux (lua_State *L) {
GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
const char *src;
gm->ms.L = L;
for (src = gm->src; src <= gm->ms.src_end; src++) {
const char *e;
reprepstate(&gm->ms);

@ -598,6 +598,7 @@ static int pmain (lua_State *L) {
return 1;
}
LUA_API int ravi_get_modulecount();
int main (int argc, char **argv) {
int status, result;
@ -624,6 +625,7 @@ int main (int argc, char **argv) {
result = lua_toboolean(L, -1); /* get result */
report(L, status);
lua_close(L);
fprintf(stderr, "NUM %d\n", ravi_get_modulecount());
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
}

@ -1300,12 +1300,17 @@ llvm::Value *RaviCodeGenerator::emit_gep_upval_value(
bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
std::shared_ptr<RaviJITModule> module,
ravi_compile_options_t *options) {
if (p->ravi_jit.jit_status == RAVI_JIT_COMPILED)
return true;
bool doVerify = options ? options->verification_level != 0 : 0;
bool omitArrayGetRangeCheck =
options ? options->omit_array_get_range_check != 0 : 0;
if (p->ravi_jit.jit_status != RAVI_JIT_NOT_COMPILED || !canCompile(p))
if (p->ravi_jit.jit_status != RAVI_JIT_NOT_COMPILED || !canCompile(p)) {
fprintf(stderr, "failed to compile!\n");
return false;
}
llvm::LLVMContext &context = jitState_->context();
llvm::IRBuilder<> builder(context);
@ -1878,6 +1883,7 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
ravi::RaviJITFunction *llvm_func = f.release();
p->ravi_jit.jit_data = reinterpret_cast<void *>(llvm_func);
p->ravi_jit.jit_function = nullptr;
p->ravi_jit.jit_status = RAVI_JIT_COMPILED;
return llvm_func != nullptr;
}

@ -23,6 +23,11 @@
#include <ravijit.h>
#include "ravi_llvmcodegen.h"
static int allocated_modules = 0;
extern "C" LUA_API int ravi_get_modulecount() {
return allocated_modules;
}
/*
* Implementation Notes:
* Each Lua function is compiled into an LLVM Module/Function
@ -86,6 +91,7 @@ void RaviJITState::dump() { types_->dump(); }
static std::atomic_int module_id;
RaviJITModule::RaviJITModule(RaviJITState *owner)
: owner_(owner), engine_(nullptr), module_(nullptr) {
int myid = module_id++;
@ -112,6 +118,7 @@ RaviJITModule::RaviJITModule(RaviJITState *owner)
std::string errStr;
builder.setErrorStr(&errStr);
engine_ = builder.create();
allocated_modules++;
if (!engine_) {
fprintf(stderr, "Could not create ExecutionEngine: %s\n", errStr.c_str());
// FIXME we need to handle this error somehow
@ -126,6 +133,8 @@ RaviJITModule::~RaviJITModule() {
// if engine was created then we don't need to delete the
// module as it would have been deleted by the engine
delete module_;
allocated_modules--;
//fprintf(stderr, "module destroyed\n");
}
int RaviJITModule::addFunction(RaviJITFunction *f) {
@ -155,6 +164,7 @@ RaviJITFunction::RaviJITFunction(lua_CFunction *p,
RaviJITFunction::~RaviJITFunction() {
// Remove this function from parent
//fprintf(stderr, "function destroyed\n");
module_->removeFunction(this);
}
@ -411,7 +421,7 @@ void raviV_freeproto(struct lua_State *L, struct Proto *p) {
// Dump the LLVM IR
void raviV_dumpIR(struct lua_State *L, struct Proto *p) {
if (p->ravi_jit.jit_function) /* compiled */ {
if (p->ravi_jit.jit_status == RAVI_JIT_COMPILED) /* compiled */ {
ravi::RaviJITFunction *f =
reinterpret_cast<ravi::RaviJITFunction *>(p->ravi_jit.jit_data);
if (f) f->dump();
@ -420,7 +430,7 @@ void raviV_dumpIR(struct lua_State *L, struct Proto *p) {
// Dump the LLVM ASM
void raviV_dumpASM(struct lua_State *L, struct Proto *p) {
if (p->ravi_jit.jit_function) /* compiled */ {
if (p->ravi_jit.jit_status == RAVI_JIT_COMPILED) /* compiled */ {
ravi::RaviJITFunction *f =
reinterpret_cast<ravi::RaviJITFunction *>(p->ravi_jit.jit_data);
if (f) f->dumpAssembly();

@ -46,7 +46,7 @@ static int ravi_is_compiled(lua_State *L) {
"argument must be a Lua function");
void *p = (void *)lua_topointer(L, 1);
LClosure *l = reinterpret_cast<LClosure *>(p);
lua_pushboolean(L, l->p->ravi_jit.jit_status == 2);
lua_pushboolean(L, l->p->ravi_jit.jit_status == RAVI_JIT_COMPILED);
return 1;
}

Loading…
Cancel
Save