Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge remote-tracking branch 'origin' into mcjit
  • Loading branch information
brixen committed Mar 28, 2016
2 parents 2dd51a1 + ffd3943 commit 1a0d3cb
Show file tree
Hide file tree
Showing 19 changed files with 200 additions and 85 deletions.
1 change: 1 addition & 0 deletions core/rubinius.rb
Expand Up @@ -288,6 +288,7 @@ def self.version
end
end

extra << "C" if Rubinius::CONCURRENT_GC
extra << "D" if Rubinius::DEBUG_BUILD

rev = BUILD_REV[0..7]
Expand Down
3 changes: 3 additions & 0 deletions machine/builtin/code_db.cpp
Expand Up @@ -2,6 +2,7 @@

#include "memory.hpp"
#include "object_utils.hpp"
#include "on_stack.hpp"
#include "ontology.hpp"
#include "marshal.hpp"
#include "thread_phase.hpp"
Expand Down Expand Up @@ -130,6 +131,8 @@ namespace rubinius {
if(m_id.empty()) break;

CompiledCode* code = load(state, m_id.c_str());
OnStack<1> os(state, code);

if(code->nil_p()) {
Exception::raise_runtime_error(state, "unable to resolve method in CodeDB initialize");
}
Expand Down
8 changes: 6 additions & 2 deletions machine/builtin/string.cpp
Expand Up @@ -768,8 +768,12 @@ namespace rubinius {
ascii_only(state, cFalse);
}

if(CBOOL(valid_encoding_) && !CBOOL(other->valid_encoding_p(state))) {
valid_encoding(state, cFalse);
if(!CBOOL(other->valid_encoding_p(state))) {
if(CBOOL(valid_encoding_)) {
valid_encoding(state, cFalse);
} else {
valid_encoding(state, cNil);
}
}

if(unlikely(length > data_length)) {
Expand Down
2 changes: 2 additions & 0 deletions machine/builtin/system.cpp
Expand Up @@ -394,6 +394,7 @@ namespace rubinius {
int pid;

state->vm()->become_managed();
state->memory()->set_interrupt();

{
LockPhase locked(state);
Expand Down Expand Up @@ -825,6 +826,7 @@ namespace rubinius {
utilities::thread::SpinLock::LockGuard guard(state->shared().env()->fork_exec_lock());

state->shared().internal_threads()->before_fork(state);
state->memory()->set_interrupt();

LockPhase locked(state);

Expand Down
2 changes: 2 additions & 0 deletions machine/builtin/thread.cpp
Expand Up @@ -156,6 +156,7 @@ namespace rubinius {
call_frame->line(state));

if(!thread->send(state, state->symbol("initialize"), args, block, true)) {
thread->vm()->set_zombie(state);
return NULL;
}

Expand All @@ -175,6 +176,7 @@ namespace rubinius {
call_frame->line(state));

if(!thread->send(state, state->symbol("__thread_initialize__"), args, block, true)) {
thread->vm()->set_zombie(state);
return NULL;
}

Expand Down
21 changes: 14 additions & 7 deletions machine/bytecode_verification.cpp
Expand Up @@ -40,27 +40,27 @@ namespace rubinius {
if(Fixnum* fix = try_as<Fixnum>(method_->local_count())) {
locals_ = fix->to_native();
} else {
fail("method not initialized properly", -1);
fail("local_count is not a Fixnum", -1);
return false;
}

InstructionSequence* iseq = try_as<InstructionSequence>(method_->iseq());
if(!iseq) {
fail("method not initialized properly", -1);
fail("iseq is not an InstructionSequence", -1);
return false;
}

if(Tuple* tup = try_as<Tuple>(iseq->opcodes())) {
ops_ = tup;
} else {
fail("method not initialized properly", -1);
fail("opcodes is not a Tuple", -1);
return false;
}

if(Fixnum* fix = try_as<Fixnum>(method_->stack_size())) {
max_stack_allowed_ = fix->to_native();
} else {
fail("method not initialized properly", -1);
fail("stack_size is not a Fixnum", -1);
return false;
}

Expand All @@ -72,11 +72,18 @@ namespace rubinius {
}

Fixnum* tot = try_as<Fixnum>(method_->total_args());
if(!tot) {
fail("total_args is not a Fixnum", -1);
return false;
}
Fixnum* req = try_as<Fixnum>(method_->required_args());
if(!req) {
fail("required_args is not a Fixnum", -1);
return false;
}
Fixnum* post = try_as<Fixnum>(method_->post_args());

if(!tot || !req || !post) {
fail("method not initialized properly (missing arg counts)", -1);
if(!post) {
fail("post_args is not a Fixnum", -1);
return false;
}

Expand Down
52 changes: 40 additions & 12 deletions machine/memory.cpp
Expand Up @@ -71,6 +71,7 @@ namespace rubinius {
, mature_mark_concurrent_(shared.config.gc_immix_concurrent)
, mature_gc_in_progress_(false)
, slab_size_(4096)
, interrupt_flag_(false)
, collect_young_flag_(false)
, collect_full_flag_(false)
, shared_(vm->shared)
Expand Down Expand Up @@ -519,6 +520,7 @@ namespace rubinius {
if(!can_gc()) {
collect_young_flag_ = false;
collect_full_flag_ = false;
interrupt_flag_ = false;
return;
}

Expand All @@ -543,6 +545,9 @@ namespace rubinius {
} else {
collect_young(state, &gc_data);
}

if(!collect_full_flag_) interrupt_flag_ = false;

RUBINIUS_GC_END(0);
}

Expand Down Expand Up @@ -610,12 +615,12 @@ namespace rubinius {
}

void Memory::collect_full(STATE) {
timer::StopWatch<timer::milliseconds> timerx(
state->vm()->metrics().gc.immix_concurrent_ms);

// If we're already collecting, ignore this request
if(mature_gc_in_progress_) return;

timer::StopWatch<timer::milliseconds> timerx(
state->vm()->metrics().gc.immix_stop_ms);

if(state->shared().config.memory_collection_log.value) {
logger::write("memory: full collection");
}
Expand All @@ -624,21 +629,34 @@ namespace rubinius {

immix_->reset_stats();

// TODO: GC hacks hacks hacks fix fix fix.
if(mature_mark_concurrent_) {
memory::GCData* data = new memory::GCData(state->vm());

clear_fiber_marks(data);
immix_->start_marker(state);
immix_->collect_start(data);
mature_gc_in_progress_ = true;
} else {
{
memory::GCData data(state->vm());

clear_fiber_marks(&data);
immix_->collect(&data);
collect_full_finish(state, &data);
}

if(mature_mark_concurrent_) {
memory::GCData* data = new memory::GCData(state->vm());

mature_gc_in_progress_ = true;

immix_->collect_start(data);
immix_->start_marker(state, data);
}
}

void Memory::collect_full_restart(STATE, memory::GCData* data) {
if(state->shared().config.memory_collection_log.value) {
logger::write("memory: concurrent collection restart");
}

code_manager_.clear_marks();

immix_->reset_stats();

immix_->collect_start(data);
}

void Memory::collect_full_finish(STATE, memory::GCData* data) {
Expand Down Expand Up @@ -672,6 +690,7 @@ namespace rubinius {
}

collect_full_flag_ = false;
interrupt_flag_ = false;

RUBINIUS_GC_END(1);
}
Expand Down Expand Up @@ -783,6 +802,15 @@ namespace rubinius {
schedule_full_collection(
"mature region allocate object",
state->vm()->metrics().gc.immix_set);

if(mature_mark_concurrent_) {
/* Spilling allocations to the Large Object Space can be costly
* because that region and collector are less efficient. To mitigate
* spilling, we sleep for a very small random interval to allow the
* concurrent marking thread to catch up and complete the GC cycle.
*/
state->vm()->blocking_suspend(state, state->vm()->metrics().memory.suspend_ms);
}
}

collect_flag = false;
Expand Down
29 changes: 26 additions & 3 deletions machine/memory.hpp
Expand Up @@ -18,6 +18,7 @@
#include "memory/write_barrier.hpp"
#include "memory/immix_collector.hpp"

#include "util/atomic.hpp"
#include "util/thread.hpp"

#include "shared_state.hpp"
Expand Down Expand Up @@ -117,6 +118,9 @@ namespace rubinius {
/// allocations.
size_t slab_size_;

/// Flag indicating that a Memory condition exists
bool interrupt_flag_;

/// Flag indicating whether a young collection should be performed soon
bool collect_young_flag_;

Expand Down Expand Up @@ -188,7 +192,7 @@ namespace rubinius {

// Don't trigger GC if currently prohibited so we don't thrash checking.
if(can_gc()) {
collect_young_flag_ = true;
interrupt_flag_ = collect_young_flag_ = true;
shared_.thread_nexus()->set_stop();
}
}
Expand All @@ -208,7 +212,7 @@ namespace rubinius {
}

if(can_gc()) {
collect_full_flag_ = true;
interrupt_flag_ = collect_full_flag_ = true;
shared_.thread_nexus()->set_stop();
} else if(shared_.config.memory_collection_log.value) {
logger::write("memory: collection: disabled");
Expand Down Expand Up @@ -538,6 +542,7 @@ namespace rubinius {
void collect(STATE) {
collect_young_flag_ = true;
collect_full_flag_ = true;
interrupt_flag_ = true;
collect_maybe(state);
}

Expand Down Expand Up @@ -568,12 +573,30 @@ namespace rubinius {

memory::MarkStack& mature_mark_stack();

bool& collect_young_flag() {
void set_interrupt() {
interrupt_flag_ = true;
atomic::memory_barrier();
}

void reset_interrupt() {
interrupt_flag_ = false;
}

bool& interrupt_p() {
return interrupt_flag_;
}

bool& collect_young_p() {
return collect_young_flag_;
}

bool& collect_full_p() {
return collect_full_flag_;
}

void collect_young(STATE, memory::GCData* data);
void collect_full(STATE);
void collect_full_restart(STATE, memory::GCData* data);
void collect_full_finish(STATE, memory::GCData* data);

public:
Expand Down
5 changes: 2 additions & 3 deletions machine/memory/immix_collector.cpp
Expand Up @@ -200,7 +200,6 @@ namespace memory {
void ImmixGC::collect_start(GCData* data) {
gc_.clear_marks();
collect_scan(data);
marker_->concurrent_mark(data);
}

void ImmixGC::collect_scan(GCData* data) {
Expand Down Expand Up @@ -361,9 +360,9 @@ namespace memory {
diagnostics_.total_bytes_ - diagnostics_.bytes_);
}

void ImmixGC::start_marker(STATE) {
void ImmixGC::start_marker(STATE, GCData* data) {
if(!marker_) {
marker_ = new ImmixMarker(state, this);
marker_ = new ImmixMarker(state, this, data);
}
}

Expand Down
2 changes: 1 addition & 1 deletion machine/memory/immix_collector.hpp
Expand Up @@ -172,7 +172,7 @@ namespace memory {
return diagnostics_;
}

void start_marker(STATE);
void start_marker(STATE, GCData* data);
bool process_mark_stack();
bool process_mark_stack(bool& exit);
MarkStack& mark_stack();
Expand Down

0 comments on commit 1a0d3cb

Please sign in to comment.