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: a292fce8c9e0
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5e2f09510a4b
Choose a head ref
  • 4 commits
  • 10 files changed
  • 1 contributor

Commits on Jul 8, 2015

  1. Copy the full SHA
    a6749f2 View commit details
  2. Copy the full SHA
    7fc9a3c View commit details
  3. Copy the full SHA
    d4168f6 View commit details
  4. Copy the full SHA
    5e2f095 View commit details
Showing with 75 additions and 65 deletions.
  1. +8 −5 vm/capi/handles.cpp
  2. +2 −0 vm/gc/baker.cpp
  3. +5 −1 vm/gc/baker.hpp
  4. +11 −25 vm/gc/code_manager.cpp
  5. +9 −29 vm/gc/code_manager.hpp
  6. +5 −2 vm/gc/immix.cpp
  7. +12 −0 vm/gc/immix.hpp
  8. +15 −0 vm/gc/inflated_headers.cpp
  9. +7 −2 vm/gc/inflated_headers.hpp
  10. +1 −1 vm/gc/mark_sweep.cpp
13 changes: 8 additions & 5 deletions vm/capi/handles.cpp
Original file line number Diff line number Diff line change
@@ -26,7 +26,6 @@ namespace rubinius {
diagnostics_.collections_++;
state->memory()->collect_mature_now = true;
}
diagnostics_.objects_++;
atomic::memory_barrier();
return handle;
}
@@ -44,7 +43,6 @@ namespace rubinius {
diagnostics_.collections_++;
state->memory()->collect_mature_now = true;
}
diagnostics_.objects_++;
atomic::memory_barrier();

if(handle_index > UINT32_MAX) {
@@ -77,6 +75,8 @@ namespace rubinius {
{
std::vector<bool> chunk_marks(allocator_->chunks_.size(), false);

diagnostics_.objects_ = 0;

for(std::vector<int>::size_type i = 0; i < allocator_->chunks_.size(); ++i) {
Handle* chunk = allocator_->chunks_[i];

@@ -92,6 +92,7 @@ namespace rubinius {
// Strong references will already have been updated.
if(!handle->weak_p()) {
chunk_marks[i] = true;
diagnostics_.objects_++;
continue;
}

@@ -103,27 +104,29 @@ namespace rubinius {
// a collection. In this state, valid objects are only in current.
if(young->in_current_p(obj)) {
chunk_marks[i] = true;
diagnostics_.objects_++;
// A weakref pointing to a forwarded young object
} else if(obj->forwarded_p()) {
handle->set_object(obj->forward());
chunk_marks[i] = true;
diagnostics_.objects_++;
// A weakref pointing to a dead young object
} else {
handle->clear();
diagnostics_.objects_--;
}
} else {
// Not a young object, so won't be GC'd so mark
// chunk as still active
chunk_marks[i] = true;
diagnostics_.objects_++;
}

// A weakref pointing to a dead mature object
} else if(!obj->marked_p(mark)) {
handle->clear();
diagnostics_.objects_--;
} else {
chunk_marks[i] = true;
diagnostics_.objects_++;
}
}
}
@@ -141,7 +144,7 @@ namespace rubinius {

allocator_->rebuild_freelist(&chunk_marks);

diagnostics_.bytes_ = allocator_->in_use_;
diagnostics_.bytes_ = allocator_->in_use_ * sizeof(Handle);
diagnostics_.modify();
}
}
2 changes: 2 additions & 0 deletions vm/gc/baker.cpp
Original file line number Diff line number Diff line change
@@ -60,8 +60,10 @@ namespace rubinius {
diagnostics::Diagnostics::log();

utilities::logger::write("baker: diagnostics: " \
"collections: %ld, " \
"10%%: %ld, 20%%: %ld, 30%%: %ld, 40%%: %ld, 50%%: %ld, " \
"60%%: %ld, 70%%: %ld, 80%%: %ld, 90%%: %ld",
collections_,
occupancy_histo_[0], occupancy_histo_[1], occupancy_histo_[2],
occupancy_histo_[3], occupancy_histo_[4], occupancy_histo_[5],
occupancy_histo_[6], occupancy_histo_[7], occupancy_histo_[8]);
6 changes: 5 additions & 1 deletion vm/gc/baker.hpp
Original file line number Diff line number Diff line change
@@ -62,21 +62,25 @@ namespace rubinius {
public:
const static int cPercentTiles = 10;

int64_t collections_;
int64_t occupancy_histo_[cPercentTiles];

Diagnostics()
: diagnostics::Diagnostics()
, collections_(0)
{
for(int i = 0; i < cPercentTiles; i++) {
occupancy_histo_[i] = 0;
}
}

void record_occupancy(double percentage) {
modify();
collections_++;

if(percentage < 0.0 || percentage > 100.0) return;

occupancy_histo_[int(percentage / cPercentTiles)]++;
modify();
}

void log();
36 changes: 11 additions & 25 deletions vm/gc/code_manager.cpp
Original file line number Diff line number Diff line change
@@ -11,8 +11,8 @@ namespace rubinius {
diagnostics::Diagnostics::log();

utilities::logger::write("code manager: diagnostics: " \
"chunks: %ld, objects: %ld, bytes: %ld",
chunks_, objects_, bytes_);
"collections: %ld, chunks: %ld, objects: %ld, bytes: %ld",
collections_, chunks_, objects_, bytes_);
}

CodeManager::Chunk::Chunk(int size)
@@ -33,11 +33,6 @@ namespace rubinius {
, last_chunk_(0)
, current_chunk_(0)
, current_index_(0)
, freed_resources_(0)
, total_allocated_(0)
, total_freed_(0)
, gc_triggered_(0)
, bytes_used_(0)
, diagnostics_(Diagnostics())
{
first_chunk_ = new Chunk(chunk_size_);
@@ -68,20 +63,11 @@ namespace rubinius {
last_chunk_->next = c;
last_chunk_ = c;
current_chunk_ = c;
diagnostics_.chunks_++;
}

void CodeManager::add_resource(CodeResource* cr, bool* collect_now) {
utilities::thread::Mutex::LockGuard guard(mutex_);

total_allocated_ += cr->size();
bytes_used_ += cr->size();

if(total_allocated_ - gc_triggered_ > cGCTriggerThreshold) {
gc_triggered_ = total_allocated_;
*collect_now = true;
}

for(;;) {
while(current_index_ < chunk_size_) {
if(current_chunk_->resources[current_index_] == 0) {
@@ -95,15 +81,19 @@ namespace rubinius {
// Move on to the next one or add a new one
current_index_ = 0;
current_chunk_ = current_chunk_->next;
if(!current_chunk_) add_chunk();
if(!current_chunk_) {
add_chunk();
*collect_now = true;
diagnostics_.collections_++;
}
}
}

void CodeManager::sweep() {
Chunk* chunk = first_chunk_;
Chunk* prev = NULL;

freed_resources_ = 0;
diagnostics_ = Diagnostics(diagnostics_.collections_);

State state(shared_->root_vm());

@@ -112,10 +102,6 @@ namespace rubinius {
for(int i = 0; i < chunk_size_; i++) {
if(CodeResource* cr = chunk->resources[i]) {
if(!cr->marked()) {
total_freed_ += cr->size();
bytes_used_ -= cr->size();

freed_resources_++;
cr->cleanup(&state, this);
delete cr;
chunk->resources[i] = 0;
@@ -148,14 +134,14 @@ namespace rubinius {
}
delete chunk;
chunk = prev->next;
diagnostics_.chunks_--;
} else {
prev = chunk;
chunk = chunk->next;
diagnostics_.chunks_++;
}

diagnostics_.modify();
}

diagnostics_.modify();
}

void CodeManager::clear_marks() {
38 changes: 9 additions & 29 deletions vm/gc/code_manager.hpp
Original file line number Diff line number Diff line change
@@ -31,18 +31,25 @@ namespace rubinius {
class Diagnostics : public diagnostics::MemoryDiagnostics {
public:
int64_t chunks_;
int64_t collections_;

Diagnostics()
: diagnostics::MemoryDiagnostics()
, chunks_(0)
, collections_(0)
{ }

Diagnostics(int64_t collections)
: diagnostics::MemoryDiagnostics()
, chunks_(0)
, collections_(collections)
{ }

void log();
};

private:
const static int cDefaultChunkSize = 64;
const static int cGCTriggerThreshold = 64 * 1024 * 1024;
const static int cDefaultChunkSize = 1024 * 1024;

/**
* A chunk of memory used to store an array of references to CodeResource
@@ -70,40 +77,13 @@ namespace rubinius {
Chunk* current_chunk_;
int current_index_;

int freed_resources_;
int total_allocated_;
int total_freed_;
int gc_triggered_;

size_t bytes_used_;

Diagnostics diagnostics_;

public:
int freed_resources() const {
return freed_resources_;
}

int total_allocated() const {
return total_allocated_;
}

int total_freed() const {
return total_freed_;
}

SharedState* shared() const {
return shared_;
}

size_t& size() {
return bytes_used_;
}

size_t size() const {
return bytes_used_;
}

Diagnostics& diagnostics() {
return diagnostics_;
}
7 changes: 5 additions & 2 deletions vm/gc/immix.cpp
Original file line number Diff line number Diff line change
@@ -23,14 +23,16 @@ namespace rubinius {
diagnostics::Diagnostics::log();

utilities::logger::write("immix: diagnostics: " \
"collections: %ld, " \
"objects: %ld, " \
"bytes: %ld, " \
"total_bytes: %ld, " \
"chunks: %ld, " \
"blocks: %ld, " \
"holes: %ld, " \
"percentage: %f",
objects_, bytes_, total_bytes_, chunks_, blocks_, holes_, percentage_);
collections_, objects_, bytes_, total_bytes_,
chunks_, blocks_, holes_, percentage_);
}

void ImmixGC::ObjectDescriber::added_chunk(int count) {
@@ -309,7 +311,7 @@ namespace rubinius {
timer::StopWatch<timer::microseconds> timer(
vm()->metrics().gc.immix_diagnostics_us);

diagnostics_ = Diagnostics();
diagnostics_ = Diagnostics(diagnostics_.collections_);

// Now, calculate how much space we're still using.
immix::Chunks& chunks = gc_.block_allocator().chunks();
@@ -328,6 +330,7 @@ namespace rubinius {
diagnostics_.percentage_ =
(double)diagnostics_.bytes_ / (double)diagnostics_.total_bytes_;

diagnostics_.collections_++;
diagnostics_.modify();
}

12 changes: 12 additions & 0 deletions vm/gc/immix.hpp
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ namespace rubinius {
public:
class Diagnostics : public diagnostics::MemoryDiagnostics {
public:
int64_t collections_;
int64_t total_bytes_;
int64_t chunks_;
int64_t blocks_;
@@ -30,6 +31,17 @@ namespace rubinius {

Diagnostics()
: diagnostics::MemoryDiagnostics()
, collections_(0)
, total_bytes_(0)
, chunks_(0)
, blocks_(0)
, holes_(0)
, percentage_(0.0)
{ }

Diagnostics(int64_t collections)
: diagnostics::MemoryDiagnostics()
, collections_(collections)
, total_bytes_(0)
, chunks_(0)
, blocks_(0)
15 changes: 15 additions & 0 deletions vm/gc/inflated_headers.cpp
Original file line number Diff line number Diff line change
@@ -7,6 +7,13 @@

namespace rubinius {
void InflatedHeaders::Diagnostics::log() {
if(!modified_p()) return;

diagnostics::Diagnostics::log();

utilities::logger::write("inflated headers: diagnostics: " \
"objects: %ld, bytes: %ld, collections: %ld\n",
objects_, bytes_, collections_);
}

InflatedHeader* InflatedHeaders::allocate(STATE, ObjectHeader* obj, uint32_t* index) {
@@ -18,6 +25,7 @@ namespace rubinius {
*index = (uint32_t)header_index;
InflatedHeader* header = allocator_->from_index(header_index);
if(needs_gc) {
diagnostics_.collections_++;
state->memory()->collect_mature_now = true;
}
atomic::memory_barrier();
@@ -26,6 +34,9 @@ namespace rubinius {

void InflatedHeaders::deallocate_headers(unsigned int mark) {
std::vector<bool> chunk_marks(allocator_->chunks_.size(), false);

diagnostics_.objects_ = 0;

for(std::vector<int>::size_type i = 0; i < allocator_->chunks_.size(); ++i) {
InflatedHeader* chunk = allocator_->chunks_[i];

@@ -34,12 +45,16 @@ namespace rubinius {

if(header->marked_p(mark)) {
chunk_marks[i] = true;
diagnostics_.objects_++;
} else {
header->clear();
}
}
}

allocator_->rebuild_freelist(&chunk_marks);

diagnostics_.bytes_ = allocator_->in_use_ * sizeof(InflatedHeader);
diagnostics_.modify();
}
}
Loading