Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 48 additions & 23 deletions ext/objspace/objspace_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include "ruby/util.h"
#include "ruby/io.h"
#include "vm_callinfo.h"
#include "vm_core.h"
#include "vm_sync.h"

RUBY_EXTERN const char ruby_hexdigits[];

Expand Down Expand Up @@ -59,6 +59,7 @@ dump_flush(struct dump_config *dc)
{
if (dc->buffer_len) {
if (dc->stream) {
// use raw fwrite, don't allow context switch
size_t written = fwrite(dc->buffer, sizeof(dc->buffer[0]), dc->buffer_len, dc->stream);
if (written < dc->buffer_len) {
MEMMOVE(dc->buffer, dc->buffer + written, char, dc->buffer_len - written);
Expand Down Expand Up @@ -776,15 +777,23 @@ static VALUE
objspace_dump(VALUE os, VALUE obj, VALUE output)
{
struct dump_config dc = {0,};
if (!RB_SPECIAL_CONST_P(obj)) {
dc.cur_page_slot_size = rb_gc_obj_slot_size(obj);
}
VALUE result = Qnil;
RB_VM_LOCK_LOCK();
{
rb_vm_barrier();

if (!RB_SPECIAL_CONST_P(obj)) {
dc.cur_page_slot_size = rb_gc_obj_slot_size(obj);
}

dump_output(&dc, output, Qnil, Qnil, Qnil);
dump_output(&dc, output, Qnil, Qnil, Qnil);

dump_object(obj, &dc);
dump_object(obj, &dc);

return dump_result(&dc);
result = dump_result(&dc);
}
RB_VM_LOCK_UNLOCK();
return result;
}

static void
Expand Down Expand Up @@ -840,35 +849,51 @@ static VALUE
objspace_dump_all(VALUE os, VALUE output, VALUE full, VALUE since, VALUE shapes)
{
struct dump_config dc = {0,};
dump_output(&dc, output, full, since, shapes);
VALUE result = Qnil;
RB_VM_LOCK_LOCK();
{
rb_vm_barrier();

if (!dc.partial_dump || dc.since == 0) {
/* dump roots */
rb_objspace_reachable_objects_from_root(root_obj_i, &dc);
if (dc.roots) dump_append(&dc, "]}\n");
}
dump_output(&dc, output, full, since, shapes);

if (RTEST(shapes)) {
rb_shape_each_shape_id(shape_id_i, &dc);
}
if (!dc.partial_dump || dc.since == 0) {
/* dump roots */
rb_objspace_reachable_objects_from_root(root_obj_i, &dc);
if (dc.roots) dump_append(&dc, "]}\n");
}

if (RTEST(shapes)) {
rb_shape_each_shape_id(shape_id_i, &dc);
}

/* dump all objects */
rb_objspace_each_objects(heap_i, &dc);
/* dump all objects */
rb_objspace_each_objects(heap_i, &dc);

return dump_result(&dc);
result = dump_result(&dc);
}
RB_VM_LOCK_UNLOCK();
return result;
}

/* :nodoc: */
static VALUE
objspace_dump_shapes(VALUE os, VALUE output, VALUE shapes)
{
struct dump_config dc = {0,};
dump_output(&dc, output, Qfalse, Qnil, shapes);
VALUE result = Qnil;
RB_VM_LOCK_LOCK();
{
rb_vm_barrier();

dump_output(&dc, output, Qfalse, Qnil, shapes);

if (RTEST(shapes)) {
rb_shape_each_shape_id(shape_id_i, &dc);
if (RTEST(shapes)) {
rb_shape_each_shape_id(shape_id_i, &dc);
}
result = dump_result(&dc);
}
return dump_result(&dc);
RB_VM_LOCK_UNLOCK();
return result;
}

void
Expand Down
14 changes: 14 additions & 0 deletions vm_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,17 @@ rb_ec_vm_lock_rec_release(const rb_execution_context_t *ec,

VM_ASSERT(recorded_lock_rec == rb_ec_vm_lock_rec(ec));
}

// For extensions, to be used like: RB_VM_LOCK_LOCK()
void
rb_vm_lock_lock(const char *file, int line)
{
rb_vm_lock(file, line);
}


// for extensions, to be used like: RB_VM_LOCK_UNLOCK
void rb_vm_lock_unlock(const char *file, int line)
{
rb_vm_unlock(file, line);
}
9 changes: 8 additions & 1 deletion vm_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ NOINLINE(void rb_vm_lock_enter_body_nb(unsigned int *lev APPEND_LOCATION_ARGS));
NOINLINE(void rb_vm_lock_enter_body(unsigned int *lev APPEND_LOCATION_ARGS));
void rb_vm_lock_leave_body_nb(unsigned int *lev APPEND_LOCATION_ARGS);
void rb_vm_lock_leave_body(unsigned int *lev APPEND_LOCATION_ARGS);
void rb_vm_barrier(void);

RUBY_SYMBOL_EXPORT_BEGIN
NOINLINE(void rb_vm_barrier(void));
NOINLINE(void rb_vm_lock_lock(const char *file, int line));
NOINLINE(void rb_vm_lock_unlock(const char *file, int line));
RUBY_SYMBOL_EXPORT_END
#define RB_VM_LOCK_LOCK() rb_vm_lock_lock(__FILE__, __LINE__)
#define RB_VM_LOCK_UNLOCK() rb_vm_lock_unlock(__FILE__, __LINE__)

#if RUBY_DEBUG
// GET_VM()
Expand Down
Loading