Skip to content
Permalink
Browse files

Memory leaks

  • Loading branch information
graphitemaster committed Dec 27, 2016
1 parent c65ffe6 commit 41f8bf7cc76b9ffbd2694a35ed259e40221de34d
Showing with 52 additions and 14 deletions.
  1. +5 −0 engine.cpp
  2. +5 −8 s_gen.cpp
  3. +1 −0 s_instr.h
  4. +1 −4 s_memory.cpp
  5. +18 −0 s_object.cpp
  6. +8 −0 s_object.h
  7. +4 −1 s_optimize.cpp
  8. +10 −1 s_vm.cpp
@@ -1079,6 +1079,8 @@ static void exec(const u::string &script) {
u::Log::err("[script] => \e[1m\e[31merror:\e[0m \e[1m%s\e[0m\n", state.m_error);
s::VM::printBacktrace(&state);
}

s::UserFunction::destroy(module);
}

// Tear down the objects represented by this set
@@ -1087,6 +1089,9 @@ static void exec(const u::string &script) {
// Reclaim memory
s::GC::run(&state);

// No longer need the shared state
s::SharedState::destroy(state.m_shared);

// Reclaim any leaking memory
s::Memory::destroy();
}
@@ -299,14 +299,11 @@ UserFunction *Gen::buildFunction(Gen *gen) {
return function;
}

UserFunction *Gen::optimize(UserFunction *f0) {
UserFunction *f1 = Optimize::inlinePass(f0);
UserFunction *f2 = Optimize::predictPass(f1);
UserFunction *f3 = Optimize::fastSlotPass(f2);
Memory::free(f0);
Memory::free(f1);
Memory::free(f2);
return f3;
UserFunction *Gen::optimize(UserFunction *function) {
function = Optimize::inlinePass(function);
function = Optimize::predictPass(function);
function = Optimize::fastSlotPass(function);
return function;
}

Slot Gen::scopeEnter(Gen *gen) {
@@ -85,6 +85,7 @@ struct FunctionBody {

struct UserFunction {
static void dump(UserFunction *function, int level);
static void destroy(UserFunction *function);

size_t m_arity; // first slots are reserved for parameters
size_t m_slots; // generic slots
@@ -29,11 +29,8 @@ void Memory::oom(size_t requested) {
const size_t totalSize = (size_t)s_memory_max*1024*1024;
u::Log::err("[script] => \e[1m\e[31mOut of memory:\e[0m %s requested but only %s left (%s in use)\n",
u::sizeMetric(requested),
requested,
u::sizeMetric(totalSize >= m_bytesAllocated ? totalSize - m_bytesAllocated : 0_z),
totalSize - m_bytesAllocated,
u::sizeMetric(m_bytesAllocated),
m_bytesAllocated);
u::sizeMetric(m_bytesAllocated));
neoFatal("Out of memory");
}

@@ -234,6 +234,8 @@ void Object::mark(State *state, Object *object) {
}

void Object::free(Object *object) {
if (object->m_free)
object->m_free(object);
Memory::free(object->m_table.m_fields);
Memory::free(object);
}
@@ -406,6 +408,9 @@ Object *Object::newArray(State *state, Object **contents, IntObject *length) {
object->m_parent = state->m_shared->m_valueCache.m_arrayBase;
object->m_contents = contents;
object->m_length = length->m_value;
object->m_free = [](Object *object) {
Memory::free(((ArrayObject *)object)->m_contents);
};
setNormal(state, (Object *)object, "length", (Object *)length);
return (Object *)object;
}
@@ -418,4 +423,17 @@ Object *Object::newFunction(State *state, FunctionPointer function) {
return (Object *)object;
}

///! UserFunction
void UserFunction::destroy(UserFunction *function) {
Memory::free(function->m_body.m_blocks);
Memory::free(function->m_body.m_instructions);
Memory::free(function);
}

///! SharedState
void SharedState::destroy(SharedState *shared) {
Memory::free(shared->m_stackData);
Memory::free(shared);
}

}
@@ -128,6 +128,12 @@ struct Object {

// The GC mark function to mark this object during GC mark phase
void (*m_mark)(State *state, Object *object);

// Custom free function to call when Object is collected by the GC
// sweep phase. This is currently used to free memory backing array
// allocations but can be used for other things like fclose on a
// stdio stream if files are going to be supported.
void (*m_free)(Object *object);
};

// Doubly linked list of GC roots
@@ -258,6 +264,8 @@ struct SharedState {
void *m_stackData;
size_t m_stackLength;
size_t m_stackOffset;

static void destroy(SharedState *state);
};

struct State {
@@ -186,9 +186,10 @@ UserFunction *Optimize::predictPass(UserFunction *function) {
instruction = (Instruction *)((unsigned char *)instruction + Instruction::size(instruction));
}
}
Memory::free(info);
UserFunction *optimized = Gen::buildFunction(&gen);
copyFunctionStats(function, optimized);
UserFunction::destroy(function);
Memory::free(info);
u::Log::out("[script] => redirected %zu predictable lookup misses\n", count);
return optimized;
}
@@ -291,6 +292,7 @@ UserFunction *Optimize::fastSlotPass(UserFunction *function) {
UserFunction *fn = Gen::buildFunction(&gen);
const size_t newFastSlots = fn->m_fastSlots;
copyFunctionStats(function, fn);
UserFunction::destroy(function);
fn->m_fastSlots = newFastSlots;

u::Log::out("[script] => generated %zu fast slots (reads: %zu, writes: %zu)\n", defines, reads, writes);
@@ -382,6 +384,7 @@ UserFunction *Optimize::inlinePass(UserFunction *function) {
}
UserFunction *optimized = Gen::buildFunction(&gen);
copyFunctionStats(function, optimized);
UserFunction::destroy(function);
u::Log::out("[script] => inlined operations (assignments: %zu, accesses: %zu, constraints: %zu)\n", assignments, accesses, constraints);
Memory::free(primitiveSlots);
return optimized;
@@ -905,6 +905,7 @@ struct OpenRange {
OpenRange *m_prev;
static void pushRecord(OpenRange **range, ProfileRecord *record);
static void dropRecord(OpenRange **range);
static void dropRecords(OpenRange **range);
};

void OpenRange::pushRecord(OpenRange **range, ProfileRecord *record) {
@@ -920,8 +921,14 @@ void OpenRange::dropRecord(OpenRange **range) {
*range = prev;
}

void OpenRange::dropRecords(OpenRange **range) {
for (; *range; OpenRange::dropRecord(range))
;
}

void ProfileState::dump(SourceRange source, ProfileState *profileState) {
if (!s_profile) return;
if (!s_profile)
return;

Table *directTable = &profileState->m_directTable;
Table *indirectTable = &profileState->m_indirectTable;
@@ -1079,6 +1086,8 @@ void ProfileState::dump(SourceRange source, ProfileState *profileState) {
u::fprint(dump, "</pre>\n");
u::fprint(dump, "</body>\n");
u::fprint(dump, "</html>\n");

OpenRange::dropRecords(&openRangeHead);
}

}

0 comments on commit 41f8bf7

Please sign in to comment.
You can’t perform that action at this time.