diff options
Diffstat (limited to 'spec/ruby/optional/capi/ext/gc_spec.c')
| -rw-r--r-- | spec/ruby/optional/capi/ext/gc_spec.c | 160 |
1 files changed, 133 insertions, 27 deletions
diff --git a/spec/ruby/optional/capi/ext/gc_spec.c b/spec/ruby/optional/capi/ext/gc_spec.c index 05341bb01d..0baa114d7b 100644 --- a/spec/ruby/optional/capi/ext/gc_spec.c +++ b/spec/ruby/optional/capi/ext/gc_spec.c @@ -5,9 +5,44 @@ extern "C" { #endif -#ifdef HAVE_RB_GC_REGISTER_ADDRESS VALUE registered_tagged_value; VALUE registered_reference_value; +VALUE registered_before_rb_gc_register_address; +VALUE registered_before_rb_global_variable_string; +VALUE registered_before_rb_global_variable_bignum; +VALUE registered_before_rb_global_variable_float; +VALUE registered_after_rb_global_variable_string; +VALUE registered_after_rb_global_variable_bignum; +VALUE registered_after_rb_global_variable_float; +VALUE rb_gc_register_address_outside_init; + +VALUE rb_gc_register_mark_object_not_referenced_float; + +static VALUE spec_RB_GC_GUARD_keep_alive(VALUE self, VALUE array_with_string) { + VALUE string = rb_ary_entry(array_with_string, 0); + char* ptr = RSTRING_PTR(string); + // Without the RB_GC_GUARD(string) below, string could be GC'd, and ptr become invalid + rb_gc(); + char copy[4]; + copy[0] = ptr[0]; + copy[1] = ptr[1]; + copy[2] = ptr[2]; + copy[3] = '\0'; + RB_GC_GUARD(string); + return rb_str_new_cstr(copy); +} + +static VALUE spec_RB_GC_GUARD(VALUE self, VALUE object) { + RB_GC_GUARD(object); + return object; +} + +static VALUE spec_RB_GC_GUARD_raw(VALUE self, VALUE number) { + long l = NUM2LONG(number); + VALUE value = (VALUE) l; + RB_GC_GUARD(value); + return Qnil; +} static VALUE registered_tagged_address(VALUE self) { return registered_tagged_value; @@ -16,55 +51,126 @@ static VALUE registered_tagged_address(VALUE self) { static VALUE registered_reference_address(VALUE self) { return registered_reference_value; } -#endif -#ifdef HAVE_RB_GC_ENABLE -static VALUE gc_spec_rb_gc_enable() { +static VALUE get_registered_before_rb_gc_register_address(VALUE self) { + return registered_before_rb_gc_register_address; +} + +static VALUE get_registered_before_rb_global_variable_string(VALUE self) { + return registered_before_rb_global_variable_string; +} + +static VALUE get_registered_before_rb_global_variable_bignum(VALUE self) { + return registered_before_rb_global_variable_bignum; +} + +static VALUE get_registered_before_rb_global_variable_float(VALUE self) { + return registered_before_rb_global_variable_float; +} + +static VALUE get_registered_after_rb_global_variable_string(VALUE self) { + return registered_after_rb_global_variable_string; +} + +static VALUE get_registered_after_rb_global_variable_bignum(VALUE self) { + return registered_after_rb_global_variable_bignum; +} + +static VALUE get_registered_after_rb_global_variable_float(VALUE self) { + return registered_after_rb_global_variable_float; +} + +static VALUE gc_spec_rb_gc_register_address(VALUE self) { + rb_gc_register_address(&rb_gc_register_address_outside_init); + rb_gc_register_address_outside_init = rb_str_new_cstr("rb_gc_register_address() outside Init_"); + return rb_gc_register_address_outside_init; +} + +static VALUE gc_spec_rb_gc_unregister_address(VALUE self) { + rb_gc_unregister_address(&rb_gc_register_address_outside_init); + return Qnil; +} + +static VALUE gc_spec_rb_gc_enable(VALUE self) { return rb_gc_enable(); } -#endif -#ifdef HAVE_RB_GC_DISABLE -static VALUE gc_spec_rb_gc_disable() { +static VALUE gc_spec_rb_gc_disable(VALUE self) { return rb_gc_disable(); } -#endif -#ifdef HAVE_RB_GC -static VALUE gc_spec_rb_gc() { +static VALUE gc_spec_rb_gc(VALUE self) { rb_gc(); return Qnil; } -#endif +static VALUE gc_spec_rb_gc_latest_gc_info(VALUE self, VALUE hash_or_key) { + return rb_gc_latest_gc_info(hash_or_key); +} + +static VALUE gc_spec_rb_gc_adjust_memory_usage(VALUE self, VALUE diff) { + rb_gc_adjust_memory_usage(NUM2SSIZET(diff)); + return Qnil; +} + +static VALUE gc_spec_rb_gc_register_mark_object(VALUE self, VALUE obj) { + rb_gc_register_mark_object(obj); + return Qnil; +} + +static VALUE gc_spec_rb_gc_register_mark_object_not_referenced_float(VALUE self) { + return rb_gc_register_mark_object_not_referenced_float; +} void Init_gc_spec(void) { - VALUE cls; - cls = rb_define_class("CApiGCSpecs", rb_cObject); + VALUE cls = rb_define_class("CApiGCSpecs", rb_cObject); + + rb_gc_register_address(®istered_tagged_value); + rb_gc_register_address(®istered_reference_value); + rb_gc_register_address(®istered_before_rb_gc_register_address); + rb_global_variable(®istered_before_rb_global_variable_string); + rb_global_variable(®istered_before_rb_global_variable_bignum); + rb_global_variable(®istered_before_rb_global_variable_float); -#ifdef HAVE_RB_GC_REGISTER_ADDRESS registered_tagged_value = INT2NUM(10); registered_reference_value = rb_str_new2("Globally registered data"); + registered_before_rb_gc_register_address = rb_str_new_cstr("registered before rb_gc_register_address()"); - rb_gc_register_address(®istered_tagged_value); - rb_gc_register_address(®istered_reference_value); + registered_before_rb_global_variable_string = rb_str_new_cstr("registered before rb_global_variable()"); + registered_before_rb_global_variable_bignum = LL2NUM(INT64_MAX); + registered_before_rb_global_variable_float = DBL2NUM(3.14); + + registered_after_rb_global_variable_string = rb_str_new_cstr("registered after rb_global_variable()"); + rb_global_variable(®istered_after_rb_global_variable_string); + registered_after_rb_global_variable_bignum = LL2NUM(INT64_MAX); + rb_global_variable(®istered_after_rb_global_variable_bignum); + registered_after_rb_global_variable_float = DBL2NUM(6.28); + rb_global_variable(®istered_after_rb_global_variable_float); + rb_gc_register_mark_object_not_referenced_float = DBL2NUM(1.61); + rb_gc_register_mark_object(rb_gc_register_mark_object_not_referenced_float); + + rb_define_method(cls, "RB_GC_GUARD_keep_alive", spec_RB_GC_GUARD_keep_alive, 1); + rb_define_method(cls, "RB_GC_GUARD", spec_RB_GC_GUARD, 1); + rb_define_method(cls, "RB_GC_GUARD_raw", spec_RB_GC_GUARD_raw, 1); rb_define_method(cls, "registered_tagged_address", registered_tagged_address, 0); rb_define_method(cls, "registered_reference_address", registered_reference_address, 0); -#endif - -#ifdef HAVE_RB_GC_ENABLE + rb_define_method(cls, "registered_before_rb_gc_register_address", get_registered_before_rb_gc_register_address, 0); + rb_define_method(cls, "registered_before_rb_global_variable_string", get_registered_before_rb_global_variable_string, 0); + rb_define_method(cls, "registered_before_rb_global_variable_bignum", get_registered_before_rb_global_variable_bignum, 0); + rb_define_method(cls, "registered_before_rb_global_variable_float", get_registered_before_rb_global_variable_float, 0); + rb_define_method(cls, "registered_after_rb_global_variable_string", get_registered_after_rb_global_variable_string, 0); + rb_define_method(cls, "registered_after_rb_global_variable_bignum", get_registered_after_rb_global_variable_bignum, 0); + rb_define_method(cls, "registered_after_rb_global_variable_float", get_registered_after_rb_global_variable_float, 0); + rb_define_method(cls, "rb_gc_register_address", gc_spec_rb_gc_register_address, 0); + rb_define_method(cls, "rb_gc_unregister_address", gc_spec_rb_gc_unregister_address, 0); rb_define_method(cls, "rb_gc_enable", gc_spec_rb_gc_enable, 0); -#endif - -#ifdef HAVE_RB_GC_DISABLE rb_define_method(cls, "rb_gc_disable", gc_spec_rb_gc_disable, 0); -#endif - -#ifdef HAVE_RB_GC rb_define_method(cls, "rb_gc", gc_spec_rb_gc, 0); -#endif - + rb_define_method(cls, "rb_gc_adjust_memory_usage", gc_spec_rb_gc_adjust_memory_usage, 1); + rb_define_method(cls, "rb_gc_register_mark_object", gc_spec_rb_gc_register_mark_object, 1); + rb_define_method(cls, "rb_gc_register_mark_object_not_referenced_float", gc_spec_rb_gc_register_mark_object_not_referenced_float, 0); + rb_define_method(cls, "rb_gc_latest_gc_info", gc_spec_rb_gc_latest_gc_info, 1); } #ifdef __cplusplus |
