ruby-changes:58639
From: Koichi <ko1@a...>
Date: Fri, 8 Nov 2019 15:29:24 +0900 (JST)
Subject: [ruby-changes:58639] 8fa41971c2 (master): use builtins for GC.
https://git.ruby-lang.org/ruby.git/commit/?id=8fa41971c2 From 8fa41971c204555b889c9722586b8baee55a0ca8 Mon Sep 17 00:00:00 2001 From: Koichi Sasada <ko1@a...> Date: Fri, 8 Nov 2019 15:27:32 +0900 Subject: use builtins for GC. Define a part of GC in gc.rb. diff --git a/.document b/.document index 2a76ac0..e4a19e9 100644 --- a/.document +++ b/.document @@ -14,6 +14,7 @@ rbconfig.rb https://github.com/ruby/ruby/blob/trunk/.document#L14 trace_point.rb ast.rb io.rb +gc.rb # the lib/ directory (which has its own .document file) lib diff --git a/common.mk b/common.mk index 2b9fe1d..70416e9 100644 --- a/common.mk +++ b/common.mk @@ -1108,6 +1108,9 @@ load_ast.inc: $(srcdir)/ast.rb $(srcdir)/tool/mk_builtin_loader.rb https://github.com/ruby/ruby/blob/trunk/common.mk#L1108 load_io.inc: $(srcdir)/io.rb $(srcdir)/tool/mk_builtin_loader.rb $(Q) $(BASERUBY) $(srcdir)/tool/mk_builtin_loader.rb $(srcdir)/io.rb +load_gc.inc: $(srcdir)/gc.rb $(srcdir)/tool/mk_builtin_loader.rb + $(Q) $(BASERUBY) $(srcdir)/tool/mk_builtin_loader.rb $(srcdir)/gc.rb + $(srcdir)/revision.h: $(Q)$(gnumake:yes=#) $(RM) $(@F) $(Q)$(gnumake:yes=#) exit > $@ || exit > $(@F) @@ -2090,6 +2093,7 @@ gc.$(OBJEXT): $(CCAN_DIR)/str/str.h https://github.com/ruby/ruby/blob/trunk/common.mk#L2093 gc.$(OBJEXT): $(hdrdir)/ruby.h gc.$(OBJEXT): $(hdrdir)/ruby/ruby.h gc.$(OBJEXT): {$(VPATH)}assert.h +gc.$(OBJEXT): {$(VPATH)}builtin.h gc.$(OBJEXT): {$(VPATH)}config.h gc.$(OBJEXT): {$(VPATH)}constant.h gc.$(OBJEXT): {$(VPATH)}debug.h @@ -2104,6 +2108,7 @@ gc.$(OBJEXT): {$(VPATH)}id_table.h https://github.com/ruby/ruby/blob/trunk/common.mk#L2108 gc.$(OBJEXT): {$(VPATH)}intern.h gc.$(OBJEXT): {$(VPATH)}internal.h gc.$(OBJEXT): {$(VPATH)}io.h +gc.$(OBJEXT): {$(VPATH)}load_gc.inc gc.$(OBJEXT): {$(VPATH)}method.h gc.$(OBJEXT): {$(VPATH)}missing.h gc.$(OBJEXT): {$(VPATH)}mjit.h diff --git a/gc.c b/gc.c index ee8f62e..06d9fee 100644 --- a/gc.c +++ b/gc.c @@ -24,6 +24,7 @@ https://github.com/ruby/ruby/blob/trunk/gc.c#L24 #include "internal.h" #include "eval_intern.h" #include "vm_core.h" +#include "builtin.h" #include "gc.h" #include "constant.h" #include "ruby_atomic.h" @@ -7459,61 +7460,18 @@ garbage_collect_with_gvl(rb_objspace_t *objspace, int reason) https://github.com/ruby/ruby/blob/trunk/gc.c#L7460 } } -/* - * call-seq: - * GC.start -> nil - * ObjectSpace.garbage_collect -> nil - * include GC; garbage_collect -> nil - * GC.start(full_mark: true, immediate_sweep: true) -> nil - * ObjectSpace.garbage_collect(full_mark: true, immediate_sweep: true) -> nil - * include GC; garbage_collect(full_mark: true, immediate_sweep: true) -> nil - * - * Initiates garbage collection, even if manually disabled. - * - * This method is defined with keyword arguments that default to true: - * - * def GC.start(full_mark: true, immediate_sweep: true); end - * - * Use full_mark: false to perform a minor GC. - * Use immediate_sweep: false to defer sweeping (use lazy sweep). - * - * Note: These keyword arguments are implementation and version dependent. They - * are not guaranteed to be future-compatible, and may be ignored if the - * underlying implementation does not support them. - */ - static VALUE -gc_start_internal(int argc, VALUE *argv, VALUE self) +gc_start_internal(rb_execution_context_t *ec, VALUE self, VALUE full_mark, VALUE immediate_mark, VALUE immediate_sweep) { rb_objspace_t *objspace = &rb_objspace; - int reason = GPR_FLAG_FULL_MARK | GPR_FLAG_IMMEDIATE_MARK | - GPR_FLAG_IMMEDIATE_SWEEP | GPR_FLAG_METHOD; - VALUE opt = Qnil; - static ID keyword_ids[3]; + int reason = GPR_FLAG_FULL_MARK | + GPR_FLAG_IMMEDIATE_MARK | + GPR_FLAG_IMMEDIATE_SWEEP | + GPR_FLAG_METHOD; - rb_scan_args(argc, argv, "0:", &opt); - - if (!NIL_P(opt)) { - VALUE kwvals[3]; - - if (!keyword_ids[0]) { - keyword_ids[0] = rb_intern("full_mark"); - keyword_ids[1] = rb_intern("immediate_mark"); - keyword_ids[2] = rb_intern("immediate_sweep"); - } - - rb_get_kwargs(opt, keyword_ids, 0, 3, kwvals); - - if (kwvals[0] != Qundef && !RTEST(kwvals[0])) { - reason &= ~GPR_FLAG_FULL_MARK; - } - if (kwvals[1] != Qundef && !RTEST(kwvals[1])) { - reason &= ~GPR_FLAG_IMMEDIATE_MARK; - } - if (kwvals[2] != Qundef && !RTEST(kwvals[2])) { - reason &= ~GPR_FLAG_IMMEDIATE_SWEEP; - } - } + if (!RTEST(full_mark)) reason &= ~GPR_FLAG_FULL_MARK; + if (!RTEST(immediate_mark)) reason &= ~GPR_FLAG_IMMEDIATE_MARK; + if (!RTEST(immediate_sweep)) reason &= ~GPR_FLAG_IMMEDIATE_SWEEP; garbage_collect(objspace, reason); gc_finalize_deferred(objspace); @@ -8479,7 +8437,7 @@ gc_compact(rb_objspace_t *objspace, int use_toward_empty, int use_double_pages, https://github.com/ruby/ruby/blob/trunk/gc.c#L8437 } static VALUE -rb_gc_compact(VALUE mod) +rb_gc_compact(rb_execution_context_t *ec, VALUE self) { rb_objspace_t *objspace = &rb_objspace; if (dont_gc) return Qnil; @@ -8728,18 +8686,8 @@ rb_gc_count(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L8686 return rb_objspace.profile.count; } -/* - * call-seq: - * GC.count -> Integer - * - * The number of times GC occurred. - * - * It returns the number of times GC occurred since the process started. - * - */ - static VALUE -gc_count(VALUE self) +gc_count(rb_execution_context_t *ec, VALUE self) { return SIZET2NUM(rb_gc_count()); } @@ -8844,30 +8792,17 @@ rb_gc_latest_gc_info(VALUE key) https://github.com/ruby/ruby/blob/trunk/gc.c#L8792 return gc_info_decode(objspace, key, 0); } -/* - * call-seq: - * GC.latest_gc_info -> {:gc_by=>:newobj} - * GC.latest_gc_info(hash) -> hash - * GC.latest_gc_info(:major_by) -> :malloc - * - * Returns information about the most recent garbage collection. - */ - static VALUE -gc_latest_gc_info(int argc, VALUE *argv, VALUE self) +gc_latest_gc_info(rb_execution_context_t *ec, VALUE self, VALUE arg) { rb_objspace_t *objspace = &rb_objspace; - VALUE arg = Qnil; - if (rb_check_arity(argc, 0, 1) == 1) { - arg = argv[0]; - if (!SYMBOL_P(arg) && !RB_TYPE_P(arg, T_HASH)) { - rb_raise(rb_eTypeError, "non-hash or symbol given"); - } - } - else { + if (NIL_P(arg)) { arg = rb_hash_new(); } + else if (!SYMBOL_P(arg) && !RB_TYPE_P(arg, T_HASH)) { + rb_raise(rb_eTypeError, "non-hash or symbol given"); + } return gc_info_decode(objspace, arg, 0); } @@ -9187,69 +9122,23 @@ gc_stat_internal(VALUE hash_or_sym) https://github.com/ruby/ruby/blob/trunk/gc.c#L9122 return 0; } -/* - * call-seq: - * GC.stat -> Hash - * GC.stat(hash) -> hash - * GC.stat(:key) -> Numeric - * - * Returns a Hash containing information about the GC. - * - * The hash includes information about internal statistics about GC such as: - * - * { - * :count=>0, - * :heap_allocated_pages=>24, - * :heap_sorted_length=>24, - * :heap_allocatable_pages=>0, - * :heap_available_slots=>9783, - * :heap_live_slots=>7713, - * :heap_free_slots=>2070, - * :heap_final_slots=>0, - * :heap_marked_slots=>0, - * :heap_eden_pages=>24, - * :heap_tomb_pages=>0, - * :total_allocated_pages=>24, - * :total_freed_pages=>0, - * :total_allocated_objects=>7796, - * :total_freed_objects=>83, - * :malloc_increase_bytes=>2389312, - * :malloc_increase_bytes_limit=>16777216, - * :minor_gc_count=>0, - * :major_gc_count=>0, - * :remembered_wb_unprotected_objects=>0, - * :remembered_wb_unprotected_objects_limit=>0, - * :old_objects=>0, - * :old_objects_limit=>0, - * :oldmalloc_increase_bytes=>2389760, - * :oldmalloc_increase_bytes_limit=>16777216 - * } - * - * The contents of the hash are implementation specific and may be changed in - * the future. - * - * This method is only expected to work on C Ruby. - * - */ - static VALUE -gc_stat(int argc, VALUE *argv, VALUE self) +gc_stat(rb_execution_context_t *ec, VALUE self, VALUE arg) // arg is (nil || hash || symbol) { - VALUE arg = Qnil; - - if (rb_check_arity(argc, 0, 1) == 1) { - arg = argv[0]; - if (SYMBOL_P(arg)) { - size_t value = gc_stat_internal(arg); - return SIZET2NUM(value); - } - else if (!RB_TYPE_P(arg, T_HASH)) { - rb_raise(rb_eTypeError, "non-hash or symbol given"); - } + if (NIL_P(arg)) { + arg = rb_hash_new(); + } + else if (SYMBOL_P(arg)) { + size_t value = gc_stat_internal(arg); + return SIZET2NUM(value); + } + else if (RB_TYPE_P(arg, T_HASH)) { + // ok } else { - arg = rb_hash_new(); + rb_raise(rb_eTypeError, "non-hash or symbol given"); } + gc_stat_internal(arg); return arg; } @@ -9267,15 +9156,8 @@ rb_gc_stat(VALUE key) https://github.com/ruby/ruby/blob/trunk/gc.c#L9156 } } -/* - * call-seq: - * GC.stress -> integer, true or false - * - * Returns current status of GC stress mode. - */ - static VALUE -gc_stress_get(VALUE self) +gc_stress_get(rb_execution_context_t *ec, VALUE self) { rb_objspace_t *objspace = &rb_objspace; return ruby_gc_stress_mode; @@ -9288,25 +9170,8 @@ gc_stress_set(rb_objspace_t *objspace, VALUE flag) https://github.com/ruby/ruby/blob/trunk/gc.c#L9170 objspace->gc_stress_mode = flag; } -/* - * call-seq: - * GC.stress = flag -> flag - * - * Updates the GC stress mode. - * - * When stress mode is enabled, the GC is invoked at every GC opportunity: - * all memory and object allocations. - * - * Enabling stress mode will degrade performance, it is only for debugging. - * - * flag can be true, false, or an integer bit-ORed following flags. - * 0x01:: no major GC - * (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/