summaryrefslogtreecommitdiff
path: root/gc.c
AgeCommit message (Collapse)Author
2021-05-16PAGE_SIZE is never used on msys/mingwNobuyoshi Nakada
2021-05-14Refix PAGE_SIZENobuyoshi Nakada
* honor actually used headers * include sys/user.h only when `PAGE_SIZE` is not defined
2021-05-14Make USE_MMAP_ALIGNED_ALLOC static constNobuyoshi Nakada
2021-05-13skip rb_bug for inconsistent zombies countKoichi Sasada
It seems a bug but it takes more time to debug. To stop CI failures, skip this rb_bug on `RGENGC_CHECK_MODE=2` temporarily.
2021-05-11Revert "Filling cache values on cvar write"Aaron Patterson
This reverts commit 08de37f9fa3469365e6b5c964689ae2bae0eb9f3. This reverts commit e8ae922b62adb00a80d3d4c49f7d7b0e6026eaba.
2021-05-11Add a cache for class variableseileencodes
This change implements a cache for class variables. Previously there was no cache for cvars. Cvar access is slow due to needing to travel all the way up th ancestor tree before returning the cvar value. The deeper the ancestor tree the slower cvar access will be. The benefits of the cache are more visible with a higher number of included modules due to the way Ruby looks up class variables. The benchmark here includes 26 modules and shows with the cache, this branch is 6.5x faster when accessing class variables. ``` compare-ruby: ruby 3.1.0dev (2021-03-15T06:22:34Z master 9e5105ca45) [x86_64-darwin19] built-ruby: ruby 3.1.0dev (2021-03-15T12:12:44Z add-cache-for-clas.. c6be0093ae) [x86_64-darwin19] | |compare-ruby|built-ruby| |:--------|-----------:|---------:| |vm_cvar | 5.681M| 36.980M| | | -| 6.51x| ``` Benchmark.ips calling `ActiveRecord::Base.logger` from within a Rails application. ActiveRecord::Base.logger has 71 ancestors. The more ancestors a tree has, the more clear the speed increase. IE if Base had only one ancestor we'd see no improvement. This benchmark is run on a vanilla Rails application. Benchmark code: ```ruby require "benchmark/ips" require_relative "config/environment" Benchmark.ips do |x| x.report "logger" do ActiveRecord::Base.logger end end ``` Ruby 3.0 master / Rails 6.1: ``` Warming up -------------------------------------- logger 155.251k i/100ms Calculating ------------------------------------- ``` Ruby 3.0 with cvar cache / Rails 6.1: ``` Warming up -------------------------------------- logger 1.546M i/100ms Calculating ------------------------------------- logger 14.857M (± 4.8%) i/s - 74.198M in 5.006202s ``` Lastly we ran a benchmark to demonstate the difference between master and our cache when the number of modules increases. This benchmark measures 1 ancestor, 30 ancestors, and 100 ancestors. Ruby 3.0 master: ``` Warming up -------------------------------------- 1 module 1.231M i/100ms 30 modules 432.020k i/100ms 100 modules 145.399k i/100ms Calculating ------------------------------------- 1 module 12.210M (± 2.1%) i/s - 61.553M in 5.043400s 30 modules 4.354M (± 2.7%) i/s - 22.033M in 5.063839s 100 modules 1.434M (± 2.9%) i/s - 7.270M in 5.072531s Comparison: 1 module: 12209958.3 i/s 30 modules: 4354217.8 i/s - 2.80x (± 0.00) slower 100 modules: 1434447.3 i/s - 8.51x (± 0.00) slower ``` Ruby 3.0 with cvar cache: ``` Warming up -------------------------------------- 1 module 1.641M i/100ms 30 modules 1.655M i/100ms 100 modules 1.620M i/100ms Calculating ------------------------------------- 1 module 16.279M (± 3.8%) i/s - 82.038M in 5.046923s 30 modules 15.891M (± 3.9%) i/s - 79.459M in 5.007958s 100 modules 16.087M (± 3.6%) i/s - 81.005M in 5.041931s Comparison: 1 module: 16279458.0 i/s 100 modules: 16087484.6 i/s - same-ish: difference falls within error 30 modules: 15891406.2 i/s - same-ish: difference falls within error ``` Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/4340
2021-05-07Protoized old pre-ANSI K&R style declarations and definitionsNobuyoshi Nakada
2021-05-06Conditionally used functionsNobuyoshi Nakada
2021-05-06Allow newobj_of0 and newobj_slowpath to allocate into multiple heap slotsMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/4391
2021-05-06Reuse sysconf resultNobuyoshi Nakada
2021-05-06Revised PAGE_MAX_SIZE caseNobuyoshi Nakada
2021-05-05Fall back to sysconf to determine page size during runtimePeter Zhu
On some platforms the PAGE_SIZE macro does not exist so we can fall back to `sysconf` to determine the page size at runtime. Notes: Merged: https://github.com/ruby/ruby/pull/4462
2021-05-05Fix PAGE_SIZE macro detection in autoconfPeter Zhu
The current fix for PAGE_SIZE macro detection in autoconf does not work correctly. I see the following output with running configure on Linux: ``` checking PAGE_SIZE is defined... no ``` Linux has PAGE_SIZE macro. This is happening because the macro exists in sys/user.h and not in the malloc headers. Notes: Merged: https://github.com/ruby/ruby/pull/4461
2021-05-06PAGE_SIZE is used only when mmap is availableNobuyoshi Nakada
2021-05-05Fix compilation on M1 MacNobuyoshi Nakada
As PAGE_SIZE may not be a preprocessor constant, dispatch at runtime in that case.
2021-05-04Fix -Wundef warnings for patterns `#if HAVE`Benoit Daloze
* See [Feature #17752] * Using this to detect them: git grep -P 'if\s+HAVE' | grep -Pv 'HAVE_LONG_LONG|/ChangeLog|HAVE_TYPEOF' Notes: Merged: https://github.com/ruby/ruby/pull/4428
2021-05-04Fix trivial -Wundef warningsBenoit Daloze
* See [Feature #17752] Co-authored-by: xtkoba (Tee KOBAYASHI) <xtkoba+ruby@gmail.com> Notes: Merged: https://github.com/ruby/ruby/pull/4428
2021-05-03Eagerly allocate instance variable tables along with objectAaron Patterson
This allows us to allocate the right size for the object in advance, meaning that we don't have to pay the cost of ivar table extension later. The idea is that if an object type ever became "extended" at some point, then it is very likely it will become extended again. So we may as well allocate the ivar table up front. Notes: Merged: https://github.com/ruby/ruby/pull/4216
2021-04-27Partially revert 2c7d3b3a722c4636ab1e9d289cbca47ddd168d3eYusuke Endoh
to make imemo_ast WB-protected again. Only the test is kept. Notes: Merged: https://github.com/ruby/ruby/pull/4419
2021-04-26node.c (rb_ast_new): imemo_ast is WB-unprotectedYusuke Endoh
Previously imemo_ast was handled as WB-protected which caused a segfault of the following code: # shareable_constant_value: literal M0 = {} M1 = {} ... M100000 = {} My analysis is here: `shareable_constant_value: literal` creates many Hash instances during parsing, and add them to node_buffer of imemo_ast. However, the contents are missed because imemo_ast is incorrectly WB-protected. This changeset makes imemo_ast as WB-unprotected. Notes: Merged: https://github.com/ruby/ruby/pull/4416
2021-04-26Fix some typos by spell checkerRyuta Kamizono
Notes: Merged: https://github.com/ruby/ruby/pull/4414
2021-04-20check ep during compaction because it can be nullAaron Patterson
This commit adds a check on the ep just like in the mark function. The env can contain null bytes if allocation tracing is enabled. We're seeing errors during autocompaction like this: ``` (lldb) bt 40 * thread #1, name = 'ruby', stop reason = signal SIGABRT frame #0: 0x00007f7d64b6018b libc.so.6`raise + 203 frame #1: 0x00007f7d64b3f859 libc.so.6`abort + 299 frame #2: 0x000055af5f2fefc9 ruby`die at error.c:764:5 frame #3: 0x000055af5f2ff1ac ruby`rb_bug_for_fatal_signal(default_sighandler=0x0000000000000000, sig=11, ctx=0x000055af60bc3340, fmt="") at error.c:804:5 frame #4: 0x000055af5f4bd08f ruby`sigsegv(sig=11, info=0x000055af60bc3470, ctx=0x000055af60bc3340) at signal.c:960:5 frame #5: 0x00007f7d64ebe3c0 libpthread.so.0`__restore_rt frame #6: 0x000055af5f339b0a ruby`gc_ref_update_imemo(objspace=0x000055af60b2b040, obj=0x00007f7d5b513fd0) at gc.c:9046:13 frame #7: 0x000055af5f339172 ruby`gc_update_object_references(objspace=0x000055af60b2b040, obj=0x00007f7d5b513fd0) at gc.c:9307:9 frame #8: 0x000055af5f338e79 ruby`gc_ref_update(vstart=0x00007f7d5b510010, vend=0x00007f7d5b513ff8, stride=40, objspace=0x000055af60b2b040, page=0x000055af62577aa0) at gc.c:9452:21 frame #9: 0x000055af5f337846 ruby`gc_update_references(objspace=0x000055af60b2b040, heap=0x000055af60b2b068) at gc.c:9481:9 frame #10: 0x000055af5f336569 ruby`gc_compact_finish(objspace=0x000055af60b2b040, heap=0x000055af60b2b068) at gc.c:4840:5 frame #11: 0x000055af5f335efb ruby`gc_page_sweep(objspace=0x000055af60b2b040, heap=0x000055af60b2b068, sweep_page=0x000055af63a1eb30) at gc.c:5046:13 frame #12: 0x000055af5f3355c5 ruby`gc_sweep_step(objspace=0x000055af60b2b040, heap=0x000055af60b2b068) at gc.c:5214:19 frame #13: 0x000055af5f33daf6 ruby`gc_sweep_rest(objspace=0x000055af60b2b040) at gc.c:5271:2 frame #14: 0x000055af5f33cacd ruby`gc_sweep(objspace=0x000055af60b2b040) at gc.c:5389:2 frame #15: 0x000055af5f33c21d ruby`gc_marks_rest(objspace=0x000055af60b2b040) at gc.c:7555:5 frame #16: 0x000055af5f324d41 ruby`gc_rest(objspace=0x000055af60b2b040) at gc.c:8457:13 frame #17: 0x000055af5f3297d8 ruby`garbage_collect(objspace=0x000055af60b2b040, reason=45568) at gc.c:8318:9 frame #18: 0x000055af5f344ece ruby`garbage_collect_with_gvl(objspace=0x000055af60b2b040, reason=45568) at gc.c:8632:9 frame #19: 0x000055af5f344e61 ruby`objspace_malloc_gc_stress(objspace=0x000055af60b2b040) at gc.c:10592:9 frame #20: 0x000055af5f32ced1 ruby`objspace_xmalloc0(objspace=0x000055af60b2b040, size=64) at gc.c:10767:5 frame #21: 0x000055af5f32ce11 ruby`ruby_xmalloc0(size=64) at gc.c:10988:12 frame #22: 0x000055af5f32cdac ruby`ruby_xmalloc_body(size=64) at gc.c:10997:12 frame #23: 0x000055af5f329415 ruby`ruby_xmalloc(size=64) at gc.c:12942:12 frame #24: 0x00007f7d611c4fe5 objspace.so`newobj_i(tpval=0x00007f7d5b553770, data=0x000055af639031a0) at object_tracing.c:101:35 frame #25: 0x000055af5f5b283f ruby`tp_call_trace(tpval=0x00007f7d5b553770, trace_arg=0x00007fff1016d398) at vm_trace.c:1115:2 frame #26: 0x000055af5f5b50ec ruby`exec_hooks_body(ec=0x000055af60b2b700, list=0x000055af60b2b920, trace_arg=0x00007fff1016d398) at vm_trace.c:304:3 frame #27: 0x000055af5f5b0f24 ruby`exec_hooks_unprotected(ec=0x000055af60b2b700, list=0x000055af60b2b920, trace_arg=0x00007fff1016d398) at vm_trace.c:333:5 frame #28: 0x000055af5f5b0da8 ruby`rb_exec_event_hooks(trace_arg=0x00007fff1016d398, hooks=0x000055af60b2b920, pop_p=0) at vm_trace.c:378:13 frame #29: 0x000055af5f33f8e2 ruby`rb_exec_event_hook_orig(ec=0x000055af60b2b700, hooks=0x000055af60b2b920, flag=1048576, self=0x00007f7d5b5c08c0, id=0, called_id=0, klass=0x0000000000000000, data=0x00007f7d5b513fd0, pop_p=0) at vm_core.h:1989:5 frame #30: 0x000055af5f334975 ruby`gc_event_hook_body(ec=0x000055af60b2b700, objspace=0x000055af60b2b040, event=1048576, data=0x00007f7d5b513fd0) at gc.c:2083:5 * frame #31: 0x000055af5f3342df ruby`newobj_slowpath_wb_protected [inlined] newobj_slowpath(klass=0x00007f7d5b9d19c8, flags=0x000000000000001a, objspace=0x000055af60b2b040, cr=0x000055af60b2b910, wb_protected=1) at gc.c:2284:9 frame #32: 0x000055af5f33410f ruby`newobj_slowpath_wb_protected(klass=0x00007f7d5b9d19c8, flags=0x000000000000001a, objspace=0x000055af60b2b040, cr=0x000055af60b2b910) at gc.c:2299 frame #33: 0x000055af5f333de9 ruby`newobj_of0(klass=0x00007f7d5b9d19c8, flags=0x000000000000001a, wb_protected=1, cr=0x000055af60b2b910) at gc.c:2338:11 frame #34: 0x000055af5f3227ae ruby`newobj_of(klass=0x00007f7d5b9d19c8, flags=0x000000000000001a, v1=0x000055af657d88a0, v2=0x000055af657d8890, v3=0x0000000000000000, wb_protected=1) at gc.c:2348:17 frame #35: 0x000055af5f322c5b ruby`rb_imemo_new(type=imemo_env, v1=0x000055af657d88a0, v2=0x000055af657d8890, v3=0x0000000000000000, v0=0x00007f7d5b9d19c8) at gc.c:2434:12 frame #36: 0x000055af5f5a3925 ruby`vm_env_new(env_ep=0x000055af657d88a0, env_body=0x000055af657d8890, env_size=4, iseq=0x00007f7d5b9d19c8) at vm_core.h:1363:33 frame #37: 0x000055af5f5a3808 ruby`vm_make_env_each(ec=0x000055af60b2b700, cfp=0x00007f7d6482fc90) at vm.c:801:11 frame #38: 0x000055af5f5a368d ruby`vm_make_env_each(ec=0x000055af60b2b700, cfp=0x00007f7d6482fc20) at vm.c:752:13 frame #39: 0x000055af5f5a368d ruby`vm_make_env_each(ec=0x000055af60b2b700, cfp=0x00007f7d6482fbb0) at vm.c:752:13 (lldb) f 31 frame #31: 0x000055af5f3342df ruby`newobj_slowpath_wb_protected [inlined] newobj_slowpath(klass=0x00007f7d5b9d19c8, flags=0x000000000000001a, objspace=0x000055af60b2b040, cr=0x000055af60b2b910, wb_protected=1) at gc.c:2284:9 2281 } 2282 GC_ASSERT(obj != 0); 2283 newobj_init(klass, flags, wb_protected, objspace, obj); -> 2284 gc_event_hook_prep(objspace, RUBY_INTERNAL_EVENT_NEWOBJ, obj, newobj_fill(obj, 0, 0, 0)); 2285 } 2286 RB_VM_LOCK_LEAVE_CR_LEV(cr, &lev); 2287 (lldb) p obj (VALUE) $3 = 0x00007f7d5b513fd0 (lldb) f 6 frame #6: 0x000055af5f339b0a ruby`gc_ref_update_imemo(objspace=0x000055af60b2b040, obj=0x00007f7d5b513fd0) at gc.c:9046:13 9043 { 9044 rb_env_t *env = (rb_env_t *)obj; 9045 TYPED_UPDATE_IF_MOVED(objspace, rb_iseq_t *, env->iseq); -> 9046 UPDATE_IF_MOVED(objspace, env->ep[VM_ENV_DATA_INDEX_ENV]); 9047 gc_update_values(objspace, (long)env->env_size, (VALUE *)env->env); 9048 } 9049 break; (lldb) p obj (VALUE) $4 = 0x00007f7d5b513fd0 (lldb) ``` Notes: Merged: https://github.com/ruby/ruby/pull/4392
2021-04-15Remove useless attribute set in init_mark_stackPeter Zhu
init_mark_stack already clears the mark stack so we do not need to set the attribute cache_size to zero. Notes: Merged: https://github.com/ruby/ruby/pull/4382
2021-04-13Add RSymbol struct back into RVALUEPeter Zhu
Commit 0ca714fa1aa3fbe4fb60ae1e5b730e544dabc27b removed RSymbol from RVALUE. This commit adds RSymbol back into RVALUE. Notes: Merged: https://github.com/ruby/ruby/pull/4378
2021-04-01Suppress a warningNobuyoshi Nakada
Loop variables of `list_for_each` need to be initialized.
2021-03-31skip marking for uninitialized imemo_env.Koichi Sasada
RUBY_INTERNAL_EVENT_NEWOBJ can expose uninitialized imemo_env objects and marking it will cause critical error. This patch skips marking on uninitialized imemo_env. See: http://rubyci.s3.amazonaws.com/centos7/ruby-master/log/20210329T183003Z.fail.html.gz Shortest repro-code is provided by mame-san. Notes: Merged: https://github.com/ruby/ruby/pull/4342
2021-03-24Change heap walking to be safe for object allocationPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/4263
2021-03-23Free iv index tableAaron Patterson
IV index tables weren't being freed. This program would leak memory: ```ruby loop do k = Class.new do def initialize @a = 1 @b = 1 @c = 1 @d = 1 @e = 1 @f = 1 @g = 1 end end k.new end ``` This commit fixes the leak. Notes: Merged: https://github.com/ruby/ruby/pull/4314
2021-03-20Remove unneeded declarationsS.H
Notes: Merged: https://github.com/ruby/ruby/pull/4295 Merged-By: nobu <nobu@ruby-lang.org>
2021-03-19gc.c: Use dedicated APIs for conservative GC in EmscriptenYusuke Endoh
Emscripten provides "emscripten_scan_stack" to get the beginning and end pointers of the stack for conservative GC. Also, "emscripten_scan_registers" allows the GC to mark local variables in WASM.
2021-03-12Constified variables for getenvNobuyoshi Nakada
2021-03-02Don't use mmap on platforms that have large OS page sizesPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/4235
2021-03-02Fix typoPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/4235
2021-02-25Disable auto compaction on platforms that do not support itPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/4227
2021-02-25Use mmap for allocating heap pagesPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/4227
2021-02-24Reverting PR #4221Aaron Patterson
It seems this breaks tests on Solaris, so I'm reverting it until we figure out the right fix. http://rubyci.s3.amazonaws.com/solaris11-sunc/ruby-master/log/20210224T210007Z.fail.html.gz
2021-02-24Disable auto compaction on platforms that do not support itPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/4221
2021-02-24Use mmap for allocating heap pagesPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/4221
2021-02-19show more information about imemo_mentKoichi Sasada
rb_obj_info(obj) (rp(obj)) doesn't show enough information for non-iseq methods, so this patch shows more. Notes: Merged: https://github.com/ruby/ruby/pull/4201
2021-02-18sync check_rvalue_consistency_force()Koichi Sasada
check_rvalue_consistency_force() uses is_pointer_to_heap() and it should be synchronized with other ractors. [Bug #17636] Notes: Merged: https://github.com/ruby/ruby/pull/4194
2021-02-18clear RVALUE on NEWOBJ event.Koichi Sasada
NEWOBJ event is called without clearing RVALUE values (v1, v2, v3). This patch clear them before NEWOBJ tracepoint internal hook. [Bug #17599] Notes: Merged: https://github.com/ruby/ruby/pull/4196
2021-02-18sync GC rest if neededKoichi Sasada
marking requires a barrier (stop all Ractors) and gc_enter() does it. However, it doesn't check rest event which can start marking. [Bug #17599] Notes: Merged: https://github.com/ruby/ruby/pull/4195
2021-02-17Removed no-longer used variableNobuyoshi Nakada
2021-02-16Remove unreachable if statement in gc_page_sweepPeter Zhu
This if statement is not reachable because `was_compacting` cannot be true when `heap->compact_cursor` is NULL. Notes: Merged: https://github.com/ruby/ruby/pull/4192
2021-02-04Don't register non-heap allocated objectsAaron Patterson
`rb_define_const` can add objects as "mark objects". This is to make code like this work: https://github.com/ruby/ruby/blob/33d6e92e0c6eaf1308ce7108e653c53bb5fb106c/ext/etc/etc.c#L1201 ``` rb_define_const(rb_cStruct, "Passwd", sPasswd); /* deprecated name */ ``` sPasswd is a heap allocated object that is also a C global, so we can't move it (it needs to be pinned). However, we have many calls to `rb_define_const` that just pass in an integer like this: ``` rb_define_const(rb_cDBM, "WRITER", INT2FIX(O_RDWR|RUBY_DBM_RW_BIT)); ``` Non heap allocated objects like integers will never move, so there is no reason to waste time in the GC marking / pinning them. Notes: Merged: https://github.com/ruby/ruby/pull/4152
2021-02-01Use RCLASS_EXT macro instead of directly accessing ptrMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/4124
2021-02-01Add RCLASS_SUBCLASSES MacroMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/4124
2021-01-31Removed static assertion about size of `RVALUE`Nobuyoshi Nakada
It is unable where unaligned word access is disallowed and `double` is wider than pointers.
2021-01-31Narrowed down the condition to pack RValueNobuyoshi Nakada
Because of `double` in `RFloat`, `RValue` would be packed by `sizeof(double)` by default, on platforms where `double` is wider than `VALUE`. Size of `RValue` is multiple of 5 now.
2021-01-27[Fixes #17538] Fix assertion failure when rincgc is turned offPeter Zhu
Co-Authored-By: Matt Valentine-House <31869+eightbitraptor@users.noreply.github.com> Notes: Merged: https://github.com/ruby/ruby/pull/4064