Skip to content

Commit

Permalink
* gc.c: add support to estimate increase of oldspace memory usage.
Browse files Browse the repository at this point in the history
  This is another approach to solve an issue discussed at r43530.
  This feature is diabled as default.
  This feature measures an increment of memory consuption by oldgen
  objects. It measures memory consumption for each objects when
  the object is promoted. However, measurement of memory consumption
  is not accurate now. So that this measurement is `estimation'.
  To implement this feature, move memsize_of() function from
  ext/objspace/objspace.c and expose rb_obj_memsize_of().
  Some memsize() functions for T_DATA (T_TYPEDDATA) have problem to
  measure memory size, so that we ignores T_DATA objects now.
  For example, some functions skip NULL check for pointer.
  The macro RGENGC_ESTIMATE_OLDSPACE enables/disables this feature,
  and turned off as default.
  We need to compare 3gen GC and this feature carefully.
  (it is possible to enable both feature)
  We need a help to compare them.
* internal.h: expose rb_obj_memsize_of().
* ext/objspace/objspace.c: use rb_obj_memsize_of() function.
* cont.c (fiber_memsize): fix to check NULL.
* variable.c (autoload_memsize): ditto.
* vm.c (vm_memsize): ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43532 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
ko1 committed Nov 5, 2013
1 parent 5ba5239 commit d1674ef
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 130 deletions.
35 changes: 35 additions & 0 deletions ChangeLog
@@ -1,3 +1,38 @@
Tue Nov 5 13:37:19 2013 Koichi Sasada <ko1@atdot.net>

* gc.c: add support to estimate increase of oldspace memory usage.
This is another approach to solve an issue discussed at r43530.
This feature is diabled as default.

This feature measures an increment of memory consuption by oldgen
objects. It measures memory consumption for each objects when
the object is promoted. However, measurement of memory consumption
is not accurate now. So that this measurement is `estimation'.

To implement this feature, move memsize_of() function from
ext/objspace/objspace.c and expose rb_obj_memsize_of().

Some memsize() functions for T_DATA (T_TYPEDDATA) have problem to
measure memory size, so that we ignores T_DATA objects now.
For example, some functions skip NULL check for pointer.

The macro RGENGC_ESTIMATE_OLDSPACE enables/disables this feature,
and turned off as default.

We need to compare 3gen GC and this feature carefully.
(it is possible to enable both feature)
We need a help to compare them.

* internal.h: expose rb_obj_memsize_of().

* ext/objspace/objspace.c: use rb_obj_memsize_of() function.

* cont.c (fiber_memsize): fix to check NULL.

* variable.c (autoload_memsize): ditto.

* vm.c (vm_memsize): ditto.

Tue Nov 5 04:03:07 2013 Koichi Sasada <ko1@atdot.net>

* gc.c (GC_MALLOC_LIMIT_MAX): fix default value 512MB -> 384MB.
Expand Down
3 changes: 2 additions & 1 deletion cont.c
Expand Up @@ -351,7 +351,8 @@ fiber_memsize(const void *ptr)
size_t size = 0;
if (ptr) {
size = sizeof(*fib);
if (fib->cont.type != ROOT_FIBER_CONTEXT) {
if (fib->cont.type != ROOT_FIBER_CONTEXT &&
fib->cont.saved_thread.local_storage != NULL) {
size += st_memsize(fib->cont.saved_thread.local_storage);
}
size += cont_memsize(&fib->cont);
Expand Down
132 changes: 5 additions & 127 deletions ext/objspace/objspace.c
Expand Up @@ -18,131 +18,9 @@
#include <ruby/re.h>
#include "node.h"
#include "gc.h"
#include "regint.h"
#include "internal.h"

size_t rb_str_memsize(VALUE);
size_t rb_ary_memsize(VALUE);
size_t rb_io_memsize(const rb_io_t *);
size_t rb_generic_ivar_memsize(VALUE);
size_t rb_objspace_data_type_memsize(VALUE obj);

static size_t
memsize_of(VALUE obj)
{
size_t size = 0;

if (SPECIAL_CONST_P(obj)) {
return 0;
}

if (FL_TEST(obj, FL_EXIVAR)) {
size += rb_generic_ivar_memsize(obj);
}

switch (BUILTIN_TYPE(obj)) {
case T_OBJECT:
if (!(RBASIC(obj)->flags & ROBJECT_EMBED) &&
ROBJECT(obj)->as.heap.ivptr) {
size += ROBJECT(obj)->as.heap.numiv * sizeof(VALUE);
}
break;
case T_MODULE:
case T_CLASS:
if (RCLASS_M_TBL(obj)) {
size += st_memsize(RCLASS_M_TBL(obj));
}
if (RCLASS_IV_TBL(obj)) {
size += st_memsize(RCLASS_IV_TBL(obj));
}
if (RCLASS_IV_INDEX_TBL(obj)) {
size += st_memsize(RCLASS_IV_INDEX_TBL(obj));
}
if (RCLASS(obj)->ptr->iv_tbl) {
size += st_memsize(RCLASS(obj)->ptr->iv_tbl);
}
if (RCLASS(obj)->ptr->const_tbl) {
size += st_memsize(RCLASS(obj)->ptr->const_tbl);
}
size += sizeof(rb_classext_t);
break;
case T_STRING:
size += rb_str_memsize(obj);
break;
case T_ARRAY:
size += rb_ary_memsize(obj);
break;
case T_HASH:
if (RHASH(obj)->ntbl) {
size += st_memsize(RHASH(obj)->ntbl);
}
break;
case T_REGEXP:
if (RREGEXP(obj)->ptr) {
size += onig_memsize(RREGEXP(obj)->ptr);
}
break;
case T_DATA:
size += rb_objspace_data_type_memsize(obj);
break;
case T_MATCH:
if (RMATCH(obj)->rmatch) {
struct rmatch *rm = RMATCH(obj)->rmatch;
size += onig_region_memsize(&rm->regs);
size += sizeof(struct rmatch_offset) * rm->char_offset_num_allocated;
size += sizeof(struct rmatch);
}
break;
case T_FILE:
if (RFILE(obj)->fptr) {
size += rb_io_memsize(RFILE(obj)->fptr);
}
break;
case T_RATIONAL:
case T_COMPLEX:
break;
case T_ICLASS:
/* iClass shares table with the module */
break;

case T_FLOAT:
break;

case T_BIGNUM:
if (!(RBASIC(obj)->flags & RBIGNUM_EMBED_FLAG) && RBIGNUM_DIGITS(obj)) {
size += RBIGNUM_LEN(obj) * sizeof(BDIGIT);
}
break;
case T_NODE:
switch (nd_type(obj)) {
case NODE_SCOPE:
if (RNODE(obj)->u1.tbl) {
/* TODO: xfree(RANY(obj)->as.node.u1.tbl); */
}
break;
case NODE_ALLOCA:
/* TODO: xfree(RANY(obj)->as.node.u1.node); */
;
}
break; /* no need to free iv_tbl */

case T_STRUCT:
if ((RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK) == 0 &&
RSTRUCT(obj)->as.heap.ptr) {
size += sizeof(VALUE) * RSTRUCT_LEN(obj);
}
break;

case T_ZOMBIE:
break;

default:
rb_bug("objspace/memsize_of(): unknown data type 0x%x(%p)",
BUILTIN_TYPE(obj), (void*)obj);
}

return size;
}
size_t rb_obj_memsize_of(VALUE);

/*
* call-seq:
Expand All @@ -160,7 +38,7 @@ memsize_of(VALUE obj)
static VALUE
memsize_of_m(VALUE self, VALUE obj)
{
return SIZET2NUM(memsize_of(obj));
return SIZET2NUM(rb_obj_memsize_of(obj));
}

struct total_data {
Expand All @@ -187,7 +65,7 @@ total_i(void *vstart, void *vend, size_t stride, void *ptr)
continue;
default:
if (data->klass == 0 || rb_obj_is_kind_of(v, data->klass)) {
data->total += memsize_of(v);
data->total += rb_obj_memsize_of(v);
}
}
}
Expand Down Expand Up @@ -254,7 +132,7 @@ cos_i(void *vstart, void *vend, size_t stride, void *data)

for (;v != (VALUE)vend; v += stride) {
if (RBASIC(v)->flags) {
counts[BUILTIN_TYPE(v)] += memsize_of(v);
counts[BUILTIN_TYPE(v)] += rb_obj_memsize_of(v);
}
}
return 0;
Expand Down Expand Up @@ -637,7 +515,7 @@ static size_t
iow_size(const void *ptr)
{
VALUE obj = (VALUE)ptr;
return memsize_of(obj);
return rb_obj_memsize_of(obj);
}

static const rb_data_type_t iow_data_type = {
Expand Down

0 comments on commit d1674ef

Please sign in to comment.