Skip to content

Commit

Permalink
Fix memory thrash and interrupt checks
Browse files Browse the repository at this point in the history
* calls to XMALLOC and friends now trigger a GC when they exceed
  10M of allocated memory.
* Instructions that are tagged as :check_interrupts actually do so
  now, preventing a fast loop from starving the system of events
  and GC.
  • Loading branch information
Evan Phoenix committed Oct 28, 2008
1 parent 6c29573 commit 3dc347c
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 3 deletions.
4 changes: 4 additions & 0 deletions vm/codegen/instructions_gen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ def generate_jump_implementations(methods, io, flow=false)
io.puts " return;"
end

if impl.name.check_interrupts?
io.puts " if(unlikely(state->interrupts.check)) return;"
end

io.puts " goto *insn_locations[stream[ctx->ip++]];"
io.puts " }"
end
Expand Down
5 changes: 4 additions & 1 deletion vm/llvm/instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,10 @@ void VMMethod::resume(Task* task, MethodContext* ctx) {
#ifdef USE_JUMP_TABLE

#undef RETURN
#define RETURN(val) if((val) == cExecuteRestart) { return; } else { goto *insn_locations[stream[ctx->ip++]]; }
#define RETURN(val) if((val) == cExecuteRestart) { return; } else { \
if(unlikely(state->interrupts.check)) return;\
goto *insn_locations[stream[ctx->ip++]]; \
}

#ruby <<CODE
io = StringIO.new
Expand Down
27 changes: 25 additions & 2 deletions vm/objectmemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,16 @@ namespace rubinius {

};

#define DEFAULT_MALLOC_THRESHOLD 10000000

static long bytes_until_collection = DEFAULT_MALLOC_THRESHOLD;

void* XMALLOC(size_t bytes) {
bytes_until_collection -= bytes;
if(bytes_until_collection <= 0) {
rubinius::VM::current_state()->run_gc_soon();
bytes_until_collection = DEFAULT_MALLOC_THRESHOLD;
}
return malloc(bytes);
}

Expand All @@ -219,10 +228,24 @@ void XFREE(void* ptr) {
}

void* XREALLOC(void* ptr, size_t bytes) {
bytes_until_collection -= bytes;
if(bytes_until_collection <= 0) {
rubinius::VM::current_state()->run_gc_soon();
bytes_until_collection = DEFAULT_MALLOC_THRESHOLD;
}

return realloc(ptr, bytes);
}

void* XCALLOC(size_t items, size_t bytes) {
return calloc(items, bytes);
void* XCALLOC(size_t items, size_t bytes_per) {
size_t bytes = bytes_per * items;

bytes_until_collection -= bytes;
if(bytes_until_collection <= 0) {
rubinius::VM::current_state()->run_gc_soon();
bytes_until_collection = DEFAULT_MALLOC_THRESHOLD;
}

return calloc(items, bytes_per);
}

6 changes: 6 additions & 0 deletions vm/vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,12 @@ namespace rubinius {
return globals.current_thread.get();
}

void VM::run_gc_soon() {
om->collect_young_now = true;
om->collect_mature_now = true;
interrupts.check = true;
}

void VM::collect() {
om->collect_young(globals.roots);
om->collect_mature(globals.roots);
Expand Down
3 changes: 3 additions & 0 deletions vm/vm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ namespace rubinius {
// Run in a seperate thread to provide preemptive thread
// scheduling.
void scheduler_loop();

// Run the garbage collectors as soon as you can
void run_gc_soon();
};
};

Expand Down

0 comments on commit 3dc347c

Please sign in to comment.