summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-06-16 21:36:50 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-06-16 21:36:50 +0000
commita74d12dc285ed07464d1272c7c15ab3eae4972be (patch)
tree15aa77a6191cf6223baa51fc7578b6e1fcd6a62b /gc.c
parenta0e0fafa0c45eba54689854d6c8d3ace9badefe0 (diff)
* include/ruby/ruby.h: New structure RTypedData, added.
This structure incldues more explicit type information for T_DATA objects. If RData(obj)->dfree is immediate value `1' on T_DATA object obj, obj is needed to be accessed with RTYPEDDATA(obj) instead of RDATA(obj). A RTypedData structure points the structure rb_typed_data_t. rb_typed_data_t includes information such as the type name of this data, mark and free function what RData includes, and memsize function show how data consuming the memory size. Note that you do not need any change existing T_DATA objects. If you use RDataType instead of RData on T_DATA object, you can specify explicit type information. * gc.c (rb_data_typed_object_alloc, rb_objspace_data_type_memsize, rb_objspace_data_type_name): added. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23710 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/gc.c b/gc.c
index 76b4053806..bb19fa38da 100644
--- a/gc.c
+++ b/gc.c
@@ -264,6 +264,7 @@ typedef struct RVALUE {
struct RRegexp regexp;
struct RHash hash;
struct RData data;
+ struct RTypedData typeddata;
struct RStruct rstruct;
struct RBignum bignum;
struct RFile file;
@@ -1177,6 +1178,44 @@ rb_data_object_alloc(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_F
return (VALUE)data;
}
+VALUE
+rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
+{
+ NEWOBJ(data, struct RTypedData);
+
+ if (klass) Check_Type(klass, T_CLASS);
+
+ OBJSETUP(data, klass, T_DATA);
+
+ data->data = datap;
+ data->typed_flag = 1;
+ data->type = type;
+
+ return (VALUE)data;
+}
+
+size_t
+rb_objspace_data_type_memsize(VALUE obj)
+{
+ if (RTYPEDDATA_P(obj)) {
+ return RTYPEDDATA_TYPE(obj)->dsize(RTYPEDDATA_DATA(obj));
+ }
+ else {
+ return 0;
+ }
+}
+
+const char *
+rb_objspace_data_type_name(VALUE obj)
+{
+ if (RTYPEDDATA_P(obj)) {
+ return RTYPEDDATA_TYPE(obj)->name;
+ }
+ else {
+ return 0;
+ }
+}
+
#ifdef __ia64
#define SET_STACK_END (SET_MACHINE_STACK_END(&th->machine_stack_end), th->machine_register_stack_end = rb_ia64_bsp())
#else
@@ -1695,7 +1734,12 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
break;
case T_DATA:
+ if (RTYPEDDATA_P(obj)) {
+ if (obj->as.typeddata.type->dmark) (*obj->as.typeddata.type->dmark)(DATA_PTR(obj));
+ }
+ else {
if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj));
+ }
break;
case T_OBJECT:
@@ -2058,6 +2102,9 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
break;
case T_DATA:
if (DATA_PTR(obj)) {
+ if (RTYPEDDATA_P(obj)) {
+ RDATA(obj)->dfree = RANY(obj)->as.typeddata.type->dfree;
+ }
if ((long)RANY(obj)->as.data.dfree == -1) {
xfree(DATA_PTR(obj));
}
@@ -2652,12 +2699,19 @@ run_final(rb_objspace_t *objspace, VALUE obj)
long i;
int status;
VALUE args[3], table, objid;
+ RUBY_DATA_FUNC free_func = 0;
objid = rb_obj_id(obj); /* make obj into id */
RBASIC(obj)->klass = 0;
- if (RDATA(obj)->dfree) {
- (*RDATA(obj)->dfree)(DATA_PTR(obj));
+ if (RTYPEDDATA_P(obj)) {
+ free_func = RTYPEDDATA_TYPE(obj)->dfree;
+ }
+ else {
+ free_func = RDATA(obj)->dfree;
+ }
+ if (free_func) {
+ (*free_func)(DATA_PTR(obj));
}
if (finalizer_table &&