Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rubinius/rubinius
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6c2f41f7fcdf
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1f4f82d91880
Choose a head ref
  • 7 commits
  • 15 files changed
  • 1 contributor

Commits on Sep 5, 2015

  1. Copy the full SHA
    f8271d2 View commit details
  2. Improve triggering GC.

    brixen committed Sep 5, 2015
    Copy the full SHA
    5a588d5 View commit details
  3. Copy the full SHA
    10b38c2 View commit details
  4. Copy the full SHA
    6dc58e3 View commit details
  5. Copy the full SHA
    951aeb0 View commit details
  6. Copy the full SHA
    0521c3b View commit details
  7. Copy the full SHA
    1f4f82d View commit details
Showing with 169 additions and 71 deletions.
  1. +6 −0 vm/builtin/block_environment.cpp
  2. +2 −2 vm/builtin/thread.hpp
  3. +6 −5 vm/gc/immix.cpp
  4. +2 −2 vm/gc/immix.hpp
  5. +6 −6 vm/gc/mark_sweep.cpp
  6. +3 −3 vm/gc/mark_sweep.hpp
  7. +5 −0 vm/llvm/state.cpp
  8. +14 −2 vm/metrics.cpp
  9. +16 −1 vm/metrics.hpp
  10. +23 −11 vm/object_memory.cpp
  11. +1 −0 vm/object_memory.hpp
  12. +70 −36 vm/test/test_gc_immix.hpp
  13. +5 −0 vm/thread_nexus.cpp
  14. +5 −3 vm/util/immix.hpp
  15. +5 −0 vm/vm.hpp
6 changes: 6 additions & 0 deletions vm/builtin/block_environment.cpp
Original file line number Diff line number Diff line change
@@ -483,20 +483,26 @@ namespace rubinius {
// loop itself.
if(!state->check_interrupts(frame, frame)) return NULL;

state->vm()->checkpoint(state, frame);

tooling::BlockEntry method(state, env, mod);
return (*mcode->run)(state, mcode, frame);
} else {
// Check the stack and interrupts here rather than in the interpreter
// loop itself.
if(!state->check_interrupts(frame, frame)) return NULL;

state->vm()->checkpoint(state, frame);

return (*mcode->run)(state, mcode, frame);
}
#else
// Check the stack and interrupts here rather than in the interpreter
// loop itself.
if(!state->check_interrupts(frame, frame)) return NULL;

state->vm()->checkpoint(state, frame);

return (*mcode->run)(state, mcode, frame);
#endif
}
4 changes: 2 additions & 2 deletions vm/builtin/thread.hpp
Original file line number Diff line number Diff line change
@@ -58,11 +58,11 @@ namespace rubinius {
obj->alive_ = nil<Object>();
obj->sleep_ = cFalse;
obj->control_channel_ = nil<Channel>();
obj->recursive_objects_ = LookupTable::create(state);
obj->recursive_objects(state, LookupTable::create(state));
obj->debugger_thread_ = nil<Thread>();
obj->thread_id_ = nil<Fixnum>();
obj->randomizer_ = nil<Randomizer>();
obj->locals_ = LookupTable::create(state);
obj->locals(state, LookupTable::create(state));
obj->group_ = nil<Object>();
obj->result_ = cFalse;
obj->exception_ = nil<Exception>();
11 changes: 6 additions & 5 deletions vm/gc/immix.cpp
Original file line number Diff line number Diff line change
@@ -82,7 +82,8 @@ namespace rubinius {
Object* orig = original.as<Object>();

memory::Address copy_addr = alloc.allocate(
orig->size_in_bytes(object_memory_->vm()));
orig->size_in_bytes(object_memory_->vm()),
object_memory_->collect_mature_now);

Object* copy = copy_addr.as<Object>();

@@ -98,20 +99,20 @@ namespace rubinius {
return addr.as<Object>()->size_in_bytes(object_memory_->vm());
}

Object* ImmixGC::allocate(uint32_t bytes) {
Object* ImmixGC::allocate(uint32_t bytes, bool& collect_now) {
if(bytes > immix::cMaxObjectSize) return 0;

Object* obj = allocator_.allocate(bytes).as<Object>();
Object* obj = allocator_.allocate(bytes, collect_now).as<Object>();
obj->init_header(MatureObjectZone, InvalidType);
obj->set_in_immix();

return obj;
}

Object* ImmixGC::move_object(Object* orig, uint32_t bytes) {
Object* ImmixGC::move_object(Object* orig, uint32_t bytes, bool& collect_now) {
if(bytes > immix::cMaxObjectSize) return 0;

Object* obj = allocator_.allocate(bytes).as<Object>();
Object* obj = allocator_.allocate(bytes, collect_now).as<Object>();

memcpy(obj, orig, bytes);

4 changes: 2 additions & 2 deletions vm/gc/immix.hpp
Original file line number Diff line number Diff line change
@@ -155,8 +155,8 @@ namespace rubinius {
ImmixGC(ObjectMemory* om);
virtual ~ImmixGC();

Object* allocate(uint32_t bytes);
Object* move_object(Object* orig, uint32_t bytes);
Object* allocate(uint32_t bytes, bool& collect_now);
Object* move_object(Object* orig, uint32_t bytes, bool& collect_now);

virtual Object* saw_object(Object*);
virtual void scanned_object(Object*);
12 changes: 6 additions & 6 deletions vm/gc/mark_sweep.cpp
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ namespace rubinius {
}
}

Object* MarkSweepGC::allocate(size_t bytes, bool *collect_now) {
Object* MarkSweepGC::allocate(size_t bytes, bool& collect_now) {
void* mem = malloc(bytes);
if(!mem) rubinius::abort();

@@ -68,7 +68,8 @@ namespace rubinius {

next_collection_bytes -= bytes;
if(next_collection_bytes < 0) {
*collect_now = true;
object_memory_->vm()->metrics().gc.large_set++;
collect_now = true;
next_collection_bytes = collection_threshold;
}

@@ -91,7 +92,7 @@ namespace rubinius {
}

Object* MarkSweepGC::move_object(Object* orig, size_t bytes,
bool* collect_now)
bool& collect_now)
{
Object* obj = allocate(bytes, collect_now);
memcpy(obj, orig, bytes);
@@ -104,9 +105,8 @@ namespace rubinius {
return obj;
}

Object* MarkSweepGC::copy_object(Object* orig) {
bool collect;
Object* obj = allocate(orig->size_in_bytes(object_memory_->vm()), &collect);
Object* MarkSweepGC::copy_object(Object* orig, bool& collect_now) {
Object* obj = allocate(orig->size_in_bytes(object_memory_->vm()), collect_now);

obj->initialize_full_state(object_memory_->vm(), orig, 0);

6 changes: 3 additions & 3 deletions vm/gc/mark_sweep.hpp
Original file line number Diff line number Diff line change
@@ -46,9 +46,9 @@ namespace rubinius {
MarkSweepGC(ObjectMemory *om, Configuration& config);
virtual ~MarkSweepGC();
void free_objects();
Object* allocate(size_t bytes, bool *collect_now);
Object* move_object(Object* orig, size_t bytes, bool *collect_now);
Object* copy_object(Object* obj);
Object* allocate(size_t bytes, bool& collect_now);
Object* move_object(Object* orig, size_t bytes, bool& collect_now);
Object* copy_object(Object* obj, bool& collect_now);
void sweep_objects();
void free_object(Object* obj, bool fast = false);
virtual Object* saw_object(Object* obj);
5 changes: 5 additions & 0 deletions vm/llvm/state.cpp
Original file line number Diff line number Diff line change
@@ -100,6 +100,11 @@ namespace rubinius {
, enabled_(false)
, current_compiler_(0)
{
/* The JIT is not necessarily activated when it is created so we have to
* be in an unmanaged phase to prevent blocking GC checkpointing.
*/
vm()->become_unmanaged();

if(state->shared().config.jit_log.value.size() == 0) {
log_ = &std::cerr;
} else {
16 changes: 14 additions & 2 deletions vm/metrics.cpp
Original file line number Diff line number Diff line change
@@ -40,12 +40,16 @@ namespace rubinius {
using namespace utilities;

namespace metrics {
FileEmitter::FileEmitter(MetricsMap& map, std::string path)
FileEmitter::FileEmitter(STATE, MetricsMap& map, std::string path)
: MetricsEmitter()
, metrics_map_(map)
, path_(path)
, fd_(-1)
{
// TODO: Make this a proper feature of the config facility.
state->shared().env()->expand_config_value(
path_, "$PID", state->shared().pid.c_str());

initialize();
}

@@ -255,7 +259,7 @@ namespace rubinius {
state->shared().config.system_metrics_statsd_server.value,
state->shared().config.system_metrics_statsd_prefix.value);
} else if(state->shared().config.system_metrics_target.value.compare("none")) {
emitter_ = new FileEmitter(metrics_map_,
emitter_ = new FileEmitter(state, metrics_map_,
state->shared().config.system_metrics_target.value);
}
}
@@ -284,10 +288,14 @@ namespace rubinius {
"console.responses.sent", metrics_data_.console.responses_sent));

// GC metrics
metrics_map_.push_back(new MetricsItem(
"gc.young.set", metrics_data_.gc.young_set));
metrics_map_.push_back(new MetricsItem(
"gc.young.count", metrics_data_.gc.young_count));
metrics_map_.push_back(new MetricsItem(
"gc.young.ms", metrics_data_.gc.young_ms));
metrics_map_.push_back(new MetricsItem(
"gc.immix.set", metrics_data_.gc.immix_set));
metrics_map_.push_back(new MetricsItem(
"gc.immix.count", metrics_data_.gc.immix_count));
metrics_map_.push_back(new MetricsItem(
@@ -296,6 +304,8 @@ namespace rubinius {
"gc.immix.concurrent.ms", metrics_data_.gc.immix_concurrent_ms));
metrics_map_.push_back(new MetricsItem(
"gc.immix.diagnostics.us", metrics_data_.gc.immix_diagnostics_us));
metrics_map_.push_back(new MetricsItem(
"gc.large.set", metrics_data_.gc.large_set));
metrics_map_.push_back(new MetricsItem(
"gc.large.count", metrics_data_.gc.large_count));
metrics_map_.push_back(new MetricsItem(
@@ -328,6 +338,8 @@ namespace rubinius {
"lock.stop_the_world.ns", metrics_data_.lock.stop_the_world_ns));

// Machine metrics
metrics_map_.push_back(new MetricsItem(
"machine.checkpoints", metrics_data_.machine.checkpoints));
metrics_map_.push_back(new MetricsItem(
"machine.inline_cache.resets", metrics_data_.machine.inline_cache_resets));
metrics_map_.push_back(new MetricsItem(
17 changes: 16 additions & 1 deletion vm/metrics.hpp
Original file line number Diff line number Diff line change
@@ -49,37 +49,46 @@ namespace rubinius {
};

struct GCMetrics {
metric young_set;
metric young_count;
metric young_ms;
metric immix_set;
metric immix_count;
metric immix_stop_ms;
metric immix_concurrent_ms;
metric immix_diagnostics_us;
metric large_set;
metric large_count;
metric large_sweep_us;
metric objects_queued;
metric objects_finalized;

GCMetrics() {
young_set = 0;
young_count = 0;
young_ms = 0;
immix_set = 0;
immix_count = 0;
immix_stop_ms = 0;
immix_concurrent_ms = 0;
immix_diagnostics_us = 0;
large_set = 0;
large_count = 0;
large_sweep_us = 0;
objects_queued = 0;
objects_finalized = 0;
}

void add(GCMetrics& data) {
young_set += data.young_set;
young_count += data.young_count;
young_ms += data.young_ms;
immix_set += data.immix_set;
immix_count += data.immix_count;
immix_stop_ms += data.immix_stop_ms;
immix_concurrent_ms += data.immix_concurrent_ms;
immix_diagnostics_us += data.immix_diagnostics_us;
large_set += data.large_set;
large_count += data.large_count;
large_sweep_us += data.large_sweep_us;
objects_queued += data.objects_queued;
@@ -139,17 +148,23 @@ namespace rubinius {
};

struct MachineMetrics {
metric checkpoints;
metric stops;
metric inline_cache_resets;
metric methods_invoked;
metric blocks_invoked;

MachineMetrics() {
checkpoints = 0;
stops = 0;
inline_cache_resets = 0;
methods_invoked = 0;
blocks_invoked = 0;
}

void add(MachineMetrics& data) {
checkpoints += data.checkpoints;
stops += data.stops;
inline_cache_resets += data.inline_cache_resets;
methods_invoked += data.methods_invoked;
blocks_invoked += data.blocks_invoked;
@@ -299,7 +314,7 @@ namespace rubinius {
int fd_;

public:
FileEmitter(MetricsMap& map, std::string path);
FileEmitter(STATE, MetricsMap& map, std::string path);
virtual ~FileEmitter();

void send_metrics();
34 changes: 23 additions & 11 deletions vm/object_memory.cpp
Original file line number Diff line number Diff line change
@@ -477,16 +477,15 @@ namespace rubinius {
/* Garbage collection */

Object* ObjectMemory::promote_object(Object* obj) {

size_t sz = obj->size_in_bytes(vm());

Object* copy = immix_->move_object(obj, sz);
Object* copy = immix_->move_object(obj, sz, collect_mature_now);

vm()->metrics().memory.promoted_objects++;
vm()->metrics().memory.promoted_bytes += sz;

if(unlikely(!copy)) {
copy = mark_sweep_->move_object(obj, sz, &collect_mature_now);
copy = mark_sweep_->move_object(obj, sz, collect_mature_now);
}

#ifdef ENABLE_OBJECT_WATCH
@@ -742,22 +741,35 @@ namespace rubinius {
utilities::thread::SpinLock::LockGuard guard(allocation_lock_);

Object* obj = 0;
collect_mature_now = false;

// TODO: check if immix_ needs to trigger GC
if(likely(obj = immix_->allocate(bytes))) {
if(likely(obj = immix_->allocate(bytes, collect_mature_now))) {
vm()->metrics().memory.immix_objects++;
vm()->metrics().memory.immix_bytes += bytes;
} else if(likely(obj = mark_sweep_->allocate(bytes, &collect_mature_now))) {

return obj;
}

if(collect_mature_now) {
vm()->metrics().gc.immix_set++;
state->shared().gc_soon();
}

if(likely(obj = mark_sweep_->allocate(bytes, collect_mature_now))) {
vm()->metrics().memory.large_objects++;
vm()->metrics().memory.large_bytes += bytes;
} else {
Exception::memory_error(state);
return NULL;
}

if(collect_mature_now) state->shared().gc_soon();
if(collect_mature_now) {
vm()->metrics().gc.large_set++;
state->shared().gc_soon();
}

return obj;
return obj;
}

Exception::memory_error(state);
return NULL;
}

TypeInfo* ObjectMemory::find_type_info(Object* obj) {
1 change: 1 addition & 0 deletions vm/object_memory.hpp
Original file line number Diff line number Diff line change
@@ -270,6 +270,7 @@ namespace rubinius {
goto allocate;
} else {
// TODO: set young collection
state->vm()->metrics().gc.young_set++;
collect_young_now = true;
state->shared().gc_soon();
}
Loading