Граф коммитов

1998 Коммитов

Автор SHA1 Сообщение Дата
Alan Wu d4585e7470 Avoid potential for rb_raise() while crashing
rb_obj_raw_info is called while printing out crash messages and
sometimes called during garbage collection. Calling rb_raise() in these
situations is undesirable because it can start executing ensure blocks.
2020-09-03 17:41:58 -04:00
Koichi Sasada 79df14c04b Introduce Ractor mechanism for parallel execution
This commit introduces Ractor mechanism to run Ruby program in
parallel. See doc/ractor.md for more details about Ractor.
See ticket [Feature #17100] to see the implementation details
and discussions.

[Feature #17100]

This commit does not complete the implementation. You can find
many bugs on using Ractor. Also the specification will be changed
so that this feature is experimental. You will see a warning when
you make the first Ractor with `Ractor.new`.

I hope this feature can help programmers from thread-safety issues.
2020-09-03 21:11:06 +09:00
John Hawthorn 0b81a484f3 Initialize new T_OBJECT as ROBJECT_EMBED
Previously, when an object is first initialized, ROBJECT_EMBED isn't
set. This means that for brand new objects, ROBJECT_NUMIV(obj) is 0 and
ROBJECT_IV_INDEX_TBL(obj) is NULL.

Previously, this combination meant that the inline cache would never be
initialized when setting an ivar on an object for the first time since
iv_index_tbl was NULL, and if it were it would never be used because
ROBJECT_NUMIV was 0. Both cases always fell through to the generic
rb_ivar_set which would then set the ROBJECT_EMBED flag and initialize
the ivar array.

This commit changes rb_class_allocate_instance to set the ROBJECT_EMBED
flag on the object initially and to initialize all members of the
embedded array to Qundef. This allows the inline cache to be set
correctly on first use and to be used on future uses.

This moves rb_class_allocate_instance to gc.c, so that it has access to
newobj_of. This seems appropriate given that there are other allocating
methods in this file (ex. rb_data_object_wrap, rb_imemo_new).
2020-09-02 14:54:29 -07:00
Peter Zhu 11922b5e03 Fix error message for wb unprotected objects count
This error is about wb unprotected objects, not old objects.
2020-09-01 22:03:13 -04:00
Nobuyoshi Nakada 41cf17bef0
Fixed argument types 2020-09-02 01:41:20 +09:00
Nobuyoshi Nakada f6822e4ed0
Format with proper conversion specifiers instead of casts 2020-09-02 01:41:18 +09:00
Nobuyoshi Nakada 8d1de3154c
Use RSTRING_LENINT for overflow check 2020-09-01 19:03:41 +09:00
Peter Zhu 21ad4075a7
Don't read past the end of the Ruby string
Ruby strings don't always have a null terminator, so we can't use
it as a regular C string. By reading only the first len bytes of
the Ruby string, we won't read past the end of the Ruby string.
2020-09-01 19:01:32 +09:00
卜部昌平 cd1d6d9029 include/ruby/backward/2/r_cast.h: deprecate
Remove all usages of RCAST() so that the header file can be excluded
from ruby/ruby.h's dependency.
2020-08-27 15:03:36 +09:00
Peter Zhu 326d89b7ce Correctly account for heap_pages_final_slots so it does not underflow
`rb_objspace_call_finalizer` creates zombies, but does not do the correct accounting (it should increment `heap_pages_final_slots` whenever it creates a zombie). When we do correct accounting, `heap_pages_final_slots` should never underflow (the check for underflow was introduced in 39725a4db6).

The implementation moves the accounting from the functions that call `make_zombie` into `make_zombie` itself, which reduces code duplication.
2020-08-25 10:14:10 -07:00
Alan Wu 264e4cd04f Remove write barrier exemption for T_ICLASS
Before this commit, iclasses were "shady", or not protected by write
barriers. Because of that, the GC needs to spend more time marking these
objects than otherwise.

Applications that make heavy use of modules should see reduction in GC
time as they have a significant number of live iclasses on the heap.

 - Put logic for iclass method table ownership into a function
 - Remove calls to WB_UNPROTECT and insert write barriers for iclasses

This commit relies on the following invariant: for any non oirigin
iclass `I`, `RCLASS_M_TBL(I) == RCLASS_M_TBL(RBasic(I)->klass)`. This
invariant did not hold prior to 98286e9 for classes and modules that
have prepended modules.

[Feature #16984]
2020-08-17 17:17:47 -04:00
AGSaidi 511b55bcef
Enable arm64 optimizations that exist for power/x86 (#3393)
* Enable unaligned accesses on arm64

64-bit Arm platforms support unaligned accesses.

Running the string benchmarks this change improves performance
by an average of 1.04x, min .96x, max 1.21x, median 1.01x

* arm64 enable gc optimizations

Similar to x86 and powerpc optimizations.

|       |compare-ruby|built-ruby|
|:------|-----------:|---------:|
|hash1  |       0.225|     0.237|
|       |           -|     1.05x|
|hash2  |       0.110|     0.110|
|       |       1.00x|         -|

* vm_exec.c: improve performance for arm64

|                               |compare-ruby|built-ruby|
|:------------------------------|-----------:|---------:|
|vm_array                       |     26.501M|   27.959M|
|                               |           -|     1.06x|
|vm_attr_ivar                   |     21.606M|   31.429M|
|                               |           -|     1.45x|
|vm_attr_ivar_set               |     21.178M|   26.113M|
|                               |           -|     1.23x|
|vm_backtrace                   |       6.621|     6.668|
|                               |           -|     1.01x|
|vm_bigarray                    |     26.205M|   29.958M|
|                               |           -|     1.14x|
|vm_bighash                     |    504.155k|  479.306k|
|                               |       1.05x|         -|
|vm_block                       |     16.692M|   21.315M|
|                               |           -|     1.28x|
|block_handler_type_iseq        |       5.083|     7.004|
|                               |           -|     1.38x|
2020-08-14 02:15:54 +09:00
Aaron Patterson 3dc313a239 Don't pin objects if we're just walking the heap
Walking the heap can inadvertently pin objects.  Only mark the object's
pin bit if the mark_func_data pointer is NULL (similar to the mark bits)
2020-08-03 12:28:00 -07:00
Koichi Sasada f7cf600c8b fix mark bit operation.
To optimize the sweep phase, there is bit operation to set mark
bits for out-of-range bits in the last bit_t.
However, if there is no out-of-ragnge bits, it set all last bit_t
as mark bits and it braek the assumption (unmarked objects will
be swept).
GC_DEBUG=1 makes sizeof(RVALUE)=64 on my machine and this condition
happens.

It took me one Saturday to debug this.
2020-08-02 03:31:58 +09:00
Alan Wu 73ee1295a3 Add memsize support for the call cache table
Each class/module/iclass can potentially have their own cc table.
Count their malloc usage.
2020-07-20 20:20:08 -04:00
Alan Wu cbf52087a2 Fix missing imemo cases in objspace_dump by refactoring
imemo_callcache and imemo_callinfo were not handled by the `objspace`
module and were showing up as "unknown" in the dump. Extract the code for
naming imemos and use that in both the GC and the `objspace` module.
2020-07-10 22:42:35 -04:00
Yusuke Endoh ecfc09d053 gc.c: Cast int literal "1" to bits_t
... because shifting by more than 31 bits has undefined behavior
(depending upon platform). Coverity Scan found this issue.
2020-07-08 09:58:48 +09:00
Aaron Patterson b06a4dc6f1
Expand heap pages to be exactly 16kb
This commit expands heap pages to be exactly 16KiB and eliminates the
`REQUIRED_SIZE_BY_MALLOC` constant.

I believe the goal of `REQUIRED_SIZE_BY_MALLOC` was to make the heap
pages consume some multiple of OS page size.  16KiB is convenient because
OS page size is typically 4KiB, so one Ruby page is four OS pages.

Do not guess how malloc works
=============================

We should not try to guess how `malloc` works and instead request (and
use) four OS pages.

Here is my reasoning:

1. Not all mallocs will store metadata in the same region as user requested
memory.  jemalloc specifically states[1]:

> Information about the states of the runs is stored as a page map at the beginning of each chunk.

2. We're using `posix_memalign` to request memory.  This means that the
   first address must be divisible by the alignment.  Our allocation is
   page aligned, so if malloc is storing metadata *before* the page,
   then we've already crossed page boundaries.

3. Some allocators like glibc will use the memory at the end of the
   page.  I am able to demonstrate that glibc will return pointers
   within the page boundary that contains `heap_page_body`[2].  We
   *expected* the allocation to look like this:

![Expected alignment](https://user-images.githubusercontent.com/3124/85803661-8a81d600-b6fc-11ea-8cb6-7dbdb434a43b.png)

   But since `heap_page` is allocated immediately after
   `heap_page_body`[3], instead the layout looks like this:

![Actual alignment](https://user-images.githubusercontent.com/3124/85803714-a1c0c380-b6fc-11ea-8c17-8b37369e17ee.png)

   This is not optimal because `heap_page` gets allocated immediately
   after `heap_page_body`.  We frequently write to `heap_page`, so the
   bottom OS page of `heap_page_body` is very likely to be copied.

One more object per page
========================

In jemalloc, allocation requests are rounded to the nearest boundary,
which in this case is 16KiB[4], so `REQUIRED_SIZE_BY_MALLOC` space is
just wasted on jemalloc.

On glibc, the space is not wasted, but instead it is very likely to
cause page faults.

Instead of wasting space or causing page faults, lets just use the space
to store one more Ruby object.  Using the space to store one more Ruby
object will prevent page faults, stop wasting space, decrease memory
usage, decrease GC time, etc.

1. https://people.freebsd.org/~jasone/jemalloc/bsdcan2006/jemalloc.pdf
2. 33390d15e7
3  289a28e68f/gc.c (L1757-L1763)
4. https://people.freebsd.org/~jasone/jemalloc/bsdcan2006/jemalloc.pdf page 4

Co-authored-by: John Hawthorn <john@hawthorn.email>
2020-07-06 14:17:54 -07:00
卜部昌平 c5f4345138 get_envparam_double: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
卜部昌平 228118482e gc_marks_finish: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
Aaron Patterson e2d94f61c8 Convert RMoved to a doubly linked list
This commit converts RMoved slots to a doubly linked list. I want to
convert this to a doubly linked list because the read barrier (currently
in development) must remove nodes from the moved list sometimes.
Removing nodes from the list is much easier if the list is doubly
linked.  In addition, we can reuse the list manipulation routines.
2020-06-22 16:27:35 -07:00
Nobuyoshi Nakada 26c179d7e7
Check argument to ObjectSpace._id2ref
Ensure that the argument is an Integer or implicitly convert to,
before dereferencing as a Bignum.  Addressed a regression in
b99833baec.

Reported by u75615 at https://hackerone.com/reports/898614
2020-06-16 18:25:35 +09:00
Nobuyoshi Nakada 1fb16dbb6e
Adjusted indents [ci skip] 2020-06-11 10:20:08 +09:00
Peter Zhu 0213f5b08a Fix ASan crash 2020-06-10 16:36:44 -07:00
Aaron Patterson 62ce8f96cd
Revert "Combine sweeping and moving"
This reverts commit 02b216e5a7.
This reverts commit 9b8825b6f9.

I found that combining sweep and move is not safe.  I don't think that
we can do compaction concurrently with _anything_ unless there is a read
barrier installed.

Here is a simple example.  A class object is freed, and during it's free
step, it tries to remove itself from its parent's subclass list.
However, during the sweep step, the parent class was moved and the
"currently being freed" class didn't have references updated yet.  So we
get a segv like this:

```
(lldb) bt
* thread #1, name = 'ruby', stop reason = signal SIGSEGV
  * frame #0: 0x0000560763e344cb ruby`rb_st_lookup at st.c:320:43
    frame #1: 0x0000560763e344cb ruby`rb_st_lookup(tab=0x2f7469672f6e6f72, key=3809, value=0x0000560765bf2270) at st.c:1010
    frame #2: 0x0000560763e8f16a ruby`rb_search_class_path at variable.c:99:9
    frame #3: 0x0000560763e8f141 ruby`rb_search_class_path at variable.c:145
    frame #4: 0x0000560763e8f141 ruby`rb_search_class_path(klass=94589785585880) at variable.c:191
    frame #5: 0x0000560763ec744e ruby`rb_vm_bugreport at vm_dump.c:996:17
    frame #6: 0x0000560763f5b958 ruby`rb_bug_for_fatal_signal at error.c:675:5
    frame #7: 0x0000560763e27dad ruby`sigsegv(sig=<unavailable>, info=<unavailable>, ctx=<unavailable>) at signal.c:955:5
    frame #8: 0x00007f8b891d33c0 libpthread.so.0`___lldb_unnamed_symbol1$$libpthread.so.0 + 1
    frame #9: 0x0000560763efa8bb ruby`rb_class_remove_from_super_subclasses(klass=94589790314280) at class.c:93:56
    frame #10: 0x0000560763d10cb7 ruby`gc_sweep_step at gc.c:2674:2
    frame #11: 0x0000560763d1187b ruby`gc_sweep at gc.c:4540:2
    frame #12: 0x0000560763d101f0 ruby`gc_start at gc.c:6797:6
    frame #13: 0x0000560763d15153 ruby`rb_gc_compact at gc.c:7479:12
    frame #14: 0x0000560763eb4eb8 ruby`vm_exec_core at vm_insnhelper.c:5183:13
    frame #15: 0x0000560763ea9bae ruby`rb_vm_exec at vm.c:1953:22
    frame #16: 0x0000560763eac08d ruby`rb_yield at vm.c:1132:9
    frame #17: 0x0000560763edb4f2 ruby`rb_ary_collect at array.c:3186:9
    frame #18: 0x0000560763e9ee15 ruby`vm_call_cfunc_with_frame at vm_insnhelper.c:2575:12
    frame #19: 0x0000560763eb2e66 ruby`vm_exec_core at vm_insnhelper.c:4177:11
    frame #20: 0x0000560763ea9bae ruby`rb_vm_exec at vm.c:1953:22
    frame #21: 0x0000560763eac08d ruby`rb_yield at vm.c:1132:9
    frame #22: 0x0000560763edb4f2 ruby`rb_ary_collect at array.c:3186:9
    frame #23: 0x0000560763e9ee15 ruby`vm_call_cfunc_with_frame at vm_insnhelper.c:2575:12
    frame #24: 0x0000560763eb2e66 ruby`vm_exec_core at vm_insnhelper.c:4177:11
    frame #25: 0x0000560763ea9bae ruby`rb_vm_exec at vm.c:1953:22
    frame #26: 0x0000560763ceee01 ruby`rb_ec_exec_node(ec=0x0000560765afa530, n=0x0000560765b088e0) at eval.c:296:2
    frame #27: 0x0000560763cf3b7b ruby`ruby_run_node(n=0x0000560765b088e0) at eval.c:354:12
    frame #28: 0x0000560763cee4a3 ruby`main(argc=<unavailable>, argv=<unavailable>) at main.c:50:9
    frame #29: 0x00007f8b88e560b3 libc.so.6`__libc_start_main + 243
    frame #30: 0x0000560763cee4ee ruby`_start + 46
(lldb) f 9
frame #9: 0x0000560763efa8bb ruby`rb_class_remove_from_super_subclasses(klass=94589790314280) at class.c:93:56
   90
   91  		*RCLASS_EXT(klass)->parent_subclasses = entry->next;
   92  		if (entry->next) {
-> 93  		    RCLASS_EXT(entry->next->klass)->parent_subclasses = RCLASS_EXT(klass)->parent_subclasses;
   94  		}
   95  		xfree(entry);
   96  	    }
(lldb) command script import -r misc/lldb_cruby.py
lldb scripts for ruby has been installed.
(lldb) rp entry->next->klass
(struct RMoved) $1 = (flags = 30, destination = 94589792806680, next = 94589784369160)
(lldb)
```
2020-06-09 13:53:18 -07:00
Aaron Patterson 2ba2b32d9e
Freeing cc tables doesn't need access to ID
We don't need to resolve symbols when freeing cc tables, so this commit
just changes the id table iterator to look at values rather than keys
and values.
2020-06-09 10:44:52 -07:00
Aaron Patterson 42a2fa3b17
fix debugging output 2020-06-08 15:08:27 -07:00
Aaron Patterson 02b216e5a7
Combine sweeping and moving
This commit combines the sweep step with moving objects.  With this
commit, we can do:

```ruby
GC.start(compact: true)
```

This code will do the following 3 steps:

1. Fully mark the heap
2. Sweep + Move objects
3. Update references

By default, this will compact in order that heap pages are allocated.
In other words, objects will be packed towards older heap pages (as
opposed to heap pages with more pinned objects like `GC.compact` does).
2020-05-29 15:24:32 -07:00
Aaron Patterson c7ceaa6d3c
Extract "free moved list" function
Extract a function to free the moved list.  We'll use this function
later on to compact at the same time as sweep.
2020-05-28 15:01:10 -07:00
Jeremy Evans ad729a1d11 Fix origin iclass pointer for modules
If a module has an origin, and that module is included in another
module or class, previously the iclass created for the module had
an origin pointer to the module's origin instead of the iclass's
origin.

Setting the origin pointer correctly requires using a stack, since
the origin iclass is not created until after the iclass itself.
Use a hidden ruby array to implement that stack.

Correctly assigning the origin pointers in the iclass caused a
use-after-free in GC.  If a module with an origin is included
in a class, the iclass shares a method table with the module
and the iclass origin shares a method table with module origin.

Mark iclass origin with a flag that notes that even though the
iclass is an origin, it shares a method table, so the method table
should not be garbage collected.  The shared method table will be
garbage collected when the module origin is garbage collected.
I've tested that this does not introduce a memory leak.

This change caused a VM assertion failure, which was traced to callable
method entries using the incorrect defined_class.  Update
rb_vm_check_redefinition_opt_method and find_defined_class_by_owner
to treat iclass origins different than class origins to avoid this
issue.

This also includes a fix for Module#included_modules to skip
iclasses with origins.

Fixes [Bug #16736]
2020-05-22 20:31:23 -07:00
Jeremy Evans 8d798e7c53 Revert "Fix origin iclass pointer for modules"
This reverts commit c745a60634.

This triggers a VM assertion.  Reverting until the issue can be
debugged.
2020-05-22 07:54:34 -07:00
Jeremy Evans c745a60634 Fix origin iclass pointer for modules
If a module has an origin, and that module is included in another
module or class, previously the iclass created for the module had
an origin pointer to the module's origin instead of the iclass's
origin.

Setting the origin pointer correctly requires using a stack, since
the origin iclass is not created until after the iclass itself.
Use a hidden ruby array to implement that stack.

Correctly assigning the origin pointers in the iclass caused a
use-after-free in GC.  If a module with an origin is included
in a class, the iclass shares a method table with the module
and the iclass origin shares a method table with module origin.

Mark iclass origin with a flag that notes that even though the
iclass is an origin, it shares a method table, so the method table
should not be garbage collected.  The shared method table will be
garbage collected when the module origin is garbage collected.
I've tested that this does not introduce a memory leak.

This also includes a fix for Module#included_modules to skip
iclasses with origins.

Fixes [Bug #16736]
2020-05-22 07:36:52 -07:00
Aaron Patterson 6e7e7c1e57
Only marked objects should be considered movable
Ruby's GC is incremental, meaning that during the mark phase (and also
the sweep phase) programs are allowed to run.  This means that programs
can allocate objects before the mark or sweep phase have actually
completed.  Those objects may not have had a chance to be marked, so we
can't know if they are movable or not. Something that references the
newly created object might have called the pinning function during the
mark phase, but since the mark phase hasn't run we can't know if there
is a "pinning" relationship.

To be conservative, we must only allow objects that are not pinned but
also marked to move.
2020-05-20 15:00:32 -07:00
Aaron Patterson 6efb9fe042
Allow references stored in the VM stack to move
We can update these references too, so lets allow them to move.
2020-05-18 16:57:10 -07:00
卜部昌平 15e977349e more on NULL versus functions
Function pointers are not void*.  See also
115fec062c
ce4ea956d2
8427fca49b
2020-05-11 16:47:25 +09:00
卜部昌平 9e41a75255 sed -i 's|ruby/impl|ruby/internal|'
To fix build failures.
2020-05-11 09:24:08 +09:00
卜部昌平 122f96c362 sed -i s/ruby3/rbimpl/g 2020-05-11 09:24:08 +09:00
卜部昌平 97672f669a sed -i s/RUBY3/RBIMPL/g
Devs do not love "3".  The only exception is RUBY3_KEYWORDS in parse.y,
which seems unrelated to our interests.
2020-05-11 09:24:08 +09:00
卜部昌平 d7f4d732c1 sed -i s|ruby/3|ruby/impl|g
This shall fix compile errors.
2020-05-11 09:24:08 +09:00
Nobuyoshi Nakada 5d430c1b34
Added more NORETURN declarations 2020-05-11 00:40:14 +09:00
Aaron Patterson ff4f9cf95d
Allow global variables to move
This patch allows global variables that have been assigned in Ruby to
move.  I added a new function for the GC to call that will update
global references and introduced a new callback in the global variable
struct for updating references.

Only pure Ruby global variables are supported right now, other
references will be pinned.
2020-05-07 11:42:39 -07:00
Aaron Patterson 00698f26a9
`T_MOVED` should never be pushed on the mark stack
No objects should ever reference a `T_MOVED` slot.  If they do, it's
absolutely a bug.  If we kill the process when `T_MOVED` is pushed on
the mark stack it will make it easier to identify which object holds a
reference that hasn't been updated.
2020-05-07 08:44:11 -07:00
Aaron Patterson 5ef019e8af
Output compaction stats in one loop / eliminate 0 counts
We only need to loop `T_MASK` times once.  Also, not every value between
0 and `T_MASK` is an actual Ruby type.  Before this change, some
integers were being added to the result hash even though they aren't
actual types.  This patch omits considered / moved entries that total 0,
cleaning up the result hash and eliminating these "fake types".
2020-05-04 13:50:21 -07:00
Benoit Daloze c2dc52e18b Rename arguments for ObjectSpace::WeakMap#[]= for clarity 2020-05-02 16:16:56 +02:00
Benoit Daloze a2be428c5f Fix ObjectSpace::WeakMap#key? to work if the value is nil
* Fixes [Bug #16826]
2020-05-02 16:08:36 +02:00
Nobuyoshi Nakada ac0c760843
Mark ruby_memerror as NORETURN 2020-04-29 00:34:14 +09:00
Yusuke Endoh 1994ed90e4 Remove debugging code from gc.c
Partially revert adab82b9a7 and
c63b5c6179.
The issue that these commits attempt to address was maybe fixed with
1c7f5a5712.
2020-04-29 00:05:46 +09:00
Kazuhiro NISHIYAMA fd2df58451
Fix a typo [ci skip] 2020-04-27 09:41:45 +09:00
Nobuyoshi Nakada 42ac3f79ba
Assert that typed data is distinguished from non-typed 2020-04-25 09:29:27 +09:00
卜部昌平 c63b5c6179 rb_memerror: abort immediately
Ditto for adab82b9a7.  TRY_WITH_GC was
found innocent.
2020-04-21 16:30:33 +09:00
Nobuyoshi Nakada dc9089b51f
Fixed a typo [ci skip] 2020-04-21 13:35:31 +09:00
卜部昌平 adab82b9a7 TRY_WITH_GC: abort immediately
NoMemoryError is observed on icc but I fail to reproduce so far.  Let me
see the backtrace on CI.
2020-04-21 12:59:35 +09:00
Nobuyoshi Nakada 693378f105
Moved noreturn call to end of noreturn function 2020-04-16 18:02:11 +09:00
Nobuyoshi Nakada e474c189da
Suppress -Wswitch warnings 2020-04-08 15:13:37 +09:00
卜部昌平 9e6e39c351
Merge pull request #2991 from shyouhei/ruby.h
Split ruby.h
2020-04-08 13:28:13 +09:00
Nobuyoshi Nakada 2a4049b23c
Bail out before pushing unexpected object 2020-04-03 01:16:57 +09:00
Koichi Sasada d05455d083 fix type cast 2020-03-11 02:55:07 +09:00
Koichi Sasada ec78b8b62a show method entry with iseq details 2020-03-11 02:50:44 +09:00
卜部昌平 97fa6468dc fix compile error w/ -DCALC_EXACT_MALLOC_SIZE 2020-03-04 12:30:42 +09:00
卜部昌平 62c2b8c74e kill USE_RGENGC=0
This compile-time option has been broken for years (at least since
commit 49369ef173, according to git
bisect).  Let's delete codes that no longer works.
2020-02-26 16:00:10 +09:00
卜部昌平 e7bcb416af avoid #if inside of rb_str_new_cstr
ISO/IEC 9899:1999 section 6.10.3 paragraph 11 explicitly states that
"If there are sequences of preprocessing tokens within the list of
arguments that would otherwise act as preprocessing directives, the
behavior is undefined."

rb_str_new_cstr is in fact a macro.  We cannot do this.
2020-02-26 16:00:10 +09:00
Koichi Sasada b9007b6c54 Introduce disposable call-cache.
This patch contains several ideas:

(1) Disposable inline method cache (IMC) for race-free inline method cache
    * Making call-cache (CC) as a RVALUE (GC target object) and allocate new
      CC on cache miss.
    * This technique allows race-free access from parallel processing
      elements like RCU.
(2) Introduce per-Class method cache (pCMC)
    * Instead of fixed-size global method cache (GMC), pCMC allows flexible
      cache size.
    * Caching CCs reduces CC allocation and allow sharing CC's fast-path
      between same call-info (CI) call-sites.
(3) Invalidate an inline method cache by invalidating corresponding method
    entries (MEs)
    * Instead of using class serials, we set "invalidated" flag for method
      entry itself to represent cache invalidation.
    * Compare with using class serials, the impact of method modification
      (add/overwrite/delete) is small.
    * Updating class serials invalidate all method caches of the class and
      sub-classes.
    * Proposed approach only invalidate the method cache of only one ME.

See [Feature #16614] for more details.
2020-02-22 09:58:59 +09:00
Koichi Sasada f2286925f0 VALUE size packed callinfo (ci).
Now, rb_call_info contains how to call the method with tuple of
(mid, orig_argc, flags, kwarg). Most of cases, kwarg == NULL and
mid+argc+flags only requires 64bits. So this patch packed
rb_call_info to VALUE (1 word) on such cases. If we can not
represent it in VALUE, then use imemo_callinfo which contains
conventional callinfo (rb_callinfo, renamed from rb_call_info).

iseq->body->ci_kw_size is removed because all of callinfo is VALUE
size (packed ci or a pointer to imemo_callinfo).

To access ci information, we need to use these functions:
vm_ci_mid(ci), _flag(ci), _argc(ci), _kwarg(ci).

struct rb_call_info_kw_arg is renamed to rb_callinfo_kwarg.

rb_funcallv_with_cc() and rb_method_basic_definition_p_with_cc()
is temporary removed because cd->ci should be marked.
2020-02-22 09:58:59 +09:00
卜部昌平 984e0233fe TestTime#test_memsize: skip when on GC_DEBUG
GC_DEBUG=1 makes this test fail because it changes the size of struct
RVALUE.  I don't think the test is useful then.  Let's just skip.
2020-02-20 11:46:54 +09:00
Yusuke Endoh 912ef0b559 Revert "gc.c: make the stack overflow detection earlier under s390x"
This reverts commit a28c166f78.

This change didn't help.
According to odaira, the issue was fixed by increasing `ulimit -s`.
2020-02-10 14:13:48 +09:00
Nobuyoshi Nakada 0f05b234fb
Disable GC until VM objects get initialized [Bug #16616] 2020-02-09 17:15:55 +09:00
Nobuyoshi Nakada aeaf0dc555
Separate objspace argument for rb_gc_disable and rb_gc_enable 2020-02-09 17:06:31 +09:00
Yusuke Endoh a28c166f78 gc.c: make the stack overflow detection earlier under s390x
On s390x, TestFiber#test_stack_size fails with SEGV.

https://rubyci.org/logs/rubyci.s3.amazonaws.com/rhel_zlinux/ruby-master/log/20200205T223421Z.fail.html.gz

```
TestFiber#test_stack_size [/home/chkbuild/build/20200205T223421Z/ruby/test/ruby/test_fiber.rb:356]:
pid 23844 killed by SIGABRT (signal 6) (core dumped)
| -e:1:in `times': stack level too deep (SystemStackError)
| 	from -e:1:in `rec'
| 	from -e:1:in `block (3 levels) in rec'
| 	from -e:1:in `times'
| 	from -e:1:in `block (2 levels) in rec'
| 	from -e:1:in `times'
| 	from -e:1:in `block in rec'
| 	from -e:1:in `times'
| 	from -e:1:in `rec'
| 	 ... 172 levels...
| 	from -e:1:in `block in rec'
| 	from -e:1:in `times'
| 	from -e:1:in `rec'
| 	from -e:1:in `block in <main>'
| -e: [BUG] Segmentation fault at 0x0000000000000000
```

This change tries a similar fix with
ef64ab917e and
3ddbba84b5.
2020-02-09 12:55:44 +09:00
Nobuyoshi Nakada 0c4bbb46f1
Removed type-punning pointer casts around `st_data_t` 2020-01-31 12:13:00 +09:00
Nobuyoshi Nakada af899503a6
Moved `GC.verify_compaction_references` to gc.rb
And fixed a segfault by coercion of `Qundef`, when any keyword
argument without `toward:` option is given.
2020-01-27 10:52:37 +09:00
Lourens Naudé 61ff5cd5fd Fix syntax error in obj_free with hash size debug counter when USE_DEBUG_COUNTER is enabled 2020-01-13 08:03:01 +09:00
Kenta Murata e082f41611
Introduce BIGNUM_EMBED_P to check BIGNUM_EMBED_FLAG (#2802)
* bignum.h: Add BIGNUM_EMBED_P

* bignum.c: Use macros for handling BIGNUM_EMBED_FLAG
2019-12-31 22:48:23 +09:00
Nobuyoshi Nakada d7bef803ac Separate builtin initialization calls 2019-12-29 12:34:55 +09:00
卜部昌平 5e22f873ed decouple internal.h headers
Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead.  This would significantly
speed up incremental builds.

We take the following inclusion order in this changeset:

1.  "ruby/config.h", where _GNU_SOURCE is defined (must be the very
    first thing among everything).
2.  RUBY_EXTCONF_H if any.
3.  Standard C headers, sorted alphabetically.
4.  Other system headers, maybe guarded by #ifdef
5.  Everything else, sorted alphabetically.

Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
2019-12-26 20:45:12 +09:00
卜部昌平 b739a63eb4 split internal.h into files
One day, I could not resist the way it was written.  I finally started
to make the code clean.  This changeset is the beginning of a series of
housekeeping commits.  It is a simple refactoring; split internal.h into
files, so that we can divide and concur in the upcoming commits.  No
lines of codes are either added or removed, except the obvious file
headers/footers.  The generated binary is identical to the one before.
2019-12-26 20:45:12 +09:00
Koichi Sasada 100fc2750b fix wmap_finalize.
wmap_finalize expects id2ref() returns a corresponding object
even if the object is dead. Make id2ref_obj_tbl() for this
purpose.
2019-12-23 17:04:31 +09:00
Koichi Sasada 9eeaae432b add more debug counters to count numeric objects. 2019-12-23 16:31:17 +09:00
Koichi Sasada a96f8cecc2 ObjectSpace._id2ref should check liveness.
objspace->id_to_obj_tbl can contain died objects because of lazy
sweep, so that it should check liveness.
2019-12-23 15:04:56 +09:00
Nobuyoshi Nakada db16629008
Fixed misspellings
Fixed misspellings reported at [Bug #16437], only in ruby and rubyspec.
2019-12-20 09:32:42 +09:00
Aaron Patterson 1e88f6eb95
Refactor free page insertion
I am trying to fix this error:

  http://ci.rvm.jp/results/trunk-gc_compact@silicon-docker/2491596

Somehow we have a page in the `free_pages` list that is full.  This
commit refactors the code so that any time we add a page to the
`free_pages` list, we do it via `heap_add_freepage`.  That function then
asserts that the free slots on that page are not 0.
2019-12-18 09:08:25 -08:00
卜部昌平 1a4a9bdb5d proper initialization of struct RVALUE
This changeset makes no difference unless GC_DEBUG is on.  When that flag is
set, struct RVALUE is bigger than struct RObject.  We have to take care of the
additional fields.  Otherwise we get a SIGSEGV like shown below.

The way obj is initialized in this patch works for both GC_DEBUG is on and off.
See also ISO/IEC 9899:1999 section 6.7.8 paragraph #21.

```
Program received signal SIGSEGV, Segmentation fault.
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:62
62      ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory
(gdb) bt
#0  __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:62
#1  0x00005555557dd9a7 in BSD_vfprintf (fp=0x7fffffff6be0, fmt0=0x5555558f3059 "@%s:%d", ap=0x7fffffff6dd0) at vsnprintf.c:1027
#2  0x00005555557db6f5 in ruby_do_vsnprintf (str=0x555555bfc58d <obj_info_buffers+1325> "", n=211, fmt=0x5555558f3059 "@%s:%d", ap=0x7fffffff6dd0) at sprintf.c:1022
#3  0x00005555557db909 in ruby_snprintf (str=0x555555bfc58d <obj_info_buffers+1325> "", n=211, fmt=0x5555558f3059 "@%s:%d") at sprintf.c:1040
#4  0x0000555555661ef4 in rb_raw_obj_info (buff=0x555555bfc560 <obj_info_buffers+1280> "0x0000555555d2bfa0 [0     ] T_STRING (String)", buff_size=256, obj=93825000456096) at gc.c:11449
#5  0x000055555565baaf in obj_info (obj=93825000456096) at gc.c:11612
#6  0x000055555565bae1 in rgengc_remembered (objspace=0x555555c0a1c0, obj=93825000456096) at gc.c:6618
#7  0x0000555555666987 in newobj_init (klass=93824999964192, flags=5, v1=0, v2=0, v3=0, wb_protected=1, objspace=0x555555c0a1c0, obj=93825000456096) at gc.c:2134
#8  0x0000555555666e49 in newobj_slowpath (klass=93824999964192, flags=5, v1=0, v2=0, v3=0, objspace=0x555555c0a1c0, wb_protected=1) at gc.c:2209
#9  0x0000555555666b94 in newobj_slowpath_wb_protected (klass=93824999964192, flags=5, v1=0, v2=0, v3=0, objspace=0x555555c0a1c0) at gc.c:2220
#10 0x000055555565751b in newobj_of (klass=93824999964192, flags=5, v1=0, v2=0, v3=0, wb_protected=1) at gc.c:2256
#11 0x00005555556575ca in rb_wb_protected_newobj_of (klass=93824999964192, flags=5) at gc.c:2272
#12 0x00005555557f36ea in str_alloc (klass=93824999964192) at string.c:728
#13 0x00005555557f2128 in rb_str_buf_new (capa=0) at string.c:1317
#14 0x000055555578c66d in rb_reg_preprocess (p=0x555555cc8148 "^-(.)(.+)?", end=0x555555cc8152 "", enc=0x555555cc7c80, fixed_enc=0x7fffffff74e8, err=0x7fffffff75f0 "") at re.c:2682
#15 0x000055555578ea13 in rb_reg_initialize (obj=93825000046736, s=0x555555cc8148 "^-(.)(.+)?", len=10, enc=0x555555cc7c80, options=0, err=0x7fffffff75f0 "", sourcefile=0x555555d1a5c0 "lib/optparse.rb", sourceline=1460) at re.c:2808
#16 0x000055555578e285 in rb_reg_initialize_str (obj=93825000046736, str=93825000046904, options=0, err=0x7fffffff75f0 "", sourcefile=0x555555d1a5c0 "lib/optparse.rb", sourceline=1460) at re.c:2869
#17 0x000055555578ee02 in rb_reg_compile (str=93825000046904, options=0, sourcefile=0x555555d1a5c0 "lib/optparse.rb", sourceline=1460) at re.c:2958
#18 0x0000555555748dfb in rb_parser_reg_compile (p=0x555555d1f760, str=93825000046904, options=0) at parse.y:12157
#19 0x00005555557581c3 in parser_reg_compile (p=0x555555d1f760, str=93825000046904, options=0) at parse.y:12151
#20 0x00005555557580ac in reg_compile (p=0x555555d1f760, str=93825000046904, options=0) at parse.y:12167
#21 0x0000555555746ebb in new_regexp (p=0x555555d1f760, node=0x555555dece68, options=0, loc=0x7fffffff89e8) at parse.y:10072
#22 0x000055555573d1f5 in ruby_yyparse (p=0x555555d1f760) at parse.y:4395
#23 0x000055555574a582 in yycompile0 (arg=93825000404832) at parse.y:5945
#24 0x00005555558c6898 in rb_suppress_tracing (func=0x55555574a470 <yycompile0>, arg=93825000404832) at vm_trace.c:427
#25 0x0000555555748290 in yycompile (vparser=93824999283456, p=0x555555d1f760, fname=93824999283624, line=1) at parse.y:5994
#26 0x00005555557481ae in rb_parser_compile_file_path (vparser=93824999283456, fname=93824999283624, file=93824999283400, start=1) at parse.y:6098
#27 0x00005555557cdd35 in load_file_internal (argp_v=140737488331760) at ruby.c:2023
#28 0x00005555556438c5 in rb_ensure (b_proc=0x5555557cd610 <load_file_internal>, data1=140737488331760, e_proc=0x5555557cddd0 <restore_load_file>, data2=140737488331760) at eval.c:1128
#29 0x00005555557cb68b in load_file (parser=93824999283456, fname=93824999283624, f=93824999283400, script=0, opt=0x7fffffffa468) at ruby.c:2142
#30 0x00005555557cb339 in rb_parser_load_file (parser=93824999283456, fname_v=93824999283624) at ruby.c:2164
#31 0x00005555556ba3e1 in load_iseq_eval (ec=0x555555c0a650, fname=93824999283624) at load.c:579
#32 0x00005555556b857a in require_internal (ec=0x555555c0a650, fname=93824999284352, exception=1) at load.c:1016
#33 0x00005555556b7967 in rb_require_string (fname=93824999284464) at load.c:1105
#34 0x00005555556b7939 in rb_f_require (obj=93824999994824, fname=93824999284464) at load.c:811
#35 0x00005555558b7ae0 in call_cfunc_1 (recv=93824999994824, argc=1, argv=0x7ffff7ecd0a8, func=0x5555556b7920 <rb_f_require>) at vm_insnhelper.c:2348
#36 0x00005555558a8889 in vm_call_cfunc_with_frame (ec=0x555555c0a650, reg_cfp=0x7ffff7fccfa0, calling=0x7fffffffaab0, cd=0x555555d76a10, empty_kw_splat=0) at vm_insnhelper.c:2513
#37 0x000055555589fb5c in vm_call_cfunc (ec=0x555555c0a650, reg_cfp=0x7ffff7fccfa0, calling=0x7fffffffaab0, cd=0x555555d76a10) at vm_insnhelper.c:2538
#38 0x000055555589f22e in vm_call_method_each_type (ec=0x555555c0a650, cfp=0x7ffff7fccfa0, calling=0x7fffffffaab0, cd=0x555555d76a10) at vm_insnhelper.c:2924
#39 0x000055555589ef47 in vm_call_method (ec=0x555555c0a650, cfp=0x7ffff7fccfa0, calling=0x7fffffffaab0, cd=0x555555d76a10) at vm_insnhelper.c:3038
#40 0x0000555555866dbd in vm_call_general (ec=0x555555c0a650, reg_cfp=0x7ffff7fccfa0, calling=0x7fffffffaab0, cd=0x555555d76a10) at vm_insnhelper.c:3075
#41 0x00005555558ae557 in vm_sendish (ec=0x555555c0a650, reg_cfp=0x7ffff7fccfa0, cd=0x555555d76a10, block_handler=0, method_explorer=0x5555558ae5d0 <vm_search_method_wrap>) at vm_insnhelper.c:4021
#42 0x000055555587745b in vm_exec_core (ec=0x555555c0a650, initial=0) at insns.def:801
#43 0x0000555555899b9c in rb_vm_exec (ec=0x555555c0a650, mjit_enable_p=1) at vm.c:1907
#44 0x000055555589aaf0 in rb_iseq_eval_main (iseq=0x555555c1da80) at vm.c:2166
#45 0x0000555555641f0b in rb_ec_exec_node (ec=0x555555c0a650, n=0x555555c1da80) at eval.c:277
#46 0x0000555555641d62 in ruby_run_node (n=0x555555c1da80) at eval.c:335
#47 0x000055555557a188 in main (argc=11, argv=0x7fffffffc848) at main.c:50
(gdb) fr 7
#7  0x0000555555666987 in newobj_init (klass=93824999964192, flags=5, v1=0, v2=0, v3=0, wb_protected=1, objspace=0x555555c0a1c0, obj=93825000456096) at gc.c:2134
2134        if (rgengc_remembered(objspace, (VALUE)obj)) rb_bug("newobj: %s is remembered.", obj_info(obj));
(gdb) p ((struct RVALUE*)obj)->file
$1 = 0x65a5992b0fb25ce7 <error: Cannot access memory at address 0x65a5992b0fb25ce7>
(gdb)
```
2019-12-12 14:19:36 +09:00
卜部昌平 f40143fe7c fix arity mismatch
I missed this in bc3e7924bc because the
function is inside of a #ifdef.
2019-12-12 14:19:36 +09:00
Aaron Patterson 0f90630983
Update method tables only if there is a class ext pointer
This makes reference updating look similar to marking, and may avoid
dereferencing a wrong pointer.
2019-12-11 10:12:14 -08:00
Koichi Sasada edb80dfe3e add additional CF info for CI env
Introduce new RUBY_DEBUG option 'ci' to inform Ruby interpreter
that an interpreter is running on CI environment.

With this option, `rb_bug()` shows more information includes
method entry information, local variables information for each
control frame.
2019-12-05 14:47:31 +09:00
卜部昌平 6f27fa4f7d prefer class_serial over m_tbl
Decades ago, among all the data that a class has, its method
table was no doubt the most frequently accessed data.  Previous
data structures were based on that assumption.

Today that is no longer true.  The most frequently accessed field
moved to class_serial.  That field is not always as wide as VALUE
but if it is, let us swap m_tbl and class_serial.

Calculating -------------------------------------
                               ours       trunk
Optcarrot Lan_Master.nes     47.363      46.630 fps

Comparison:
             Optcarrot Lan_Master.nes
                    ours:        47.4 fps
                   trunk:        46.6 fps - 1.02x  slower
2019-11-27 21:38:07 +09:00
John Hawthorn 8e743fad4e Count pinned slots using only bitmap
This is significantly faster than checking BUILTIN_TYPEs because we
access significantly less memory. We also use popcount to count entire
words at a time.

The only functional difference from the previous implementation is that
T_ZOMBIE objects will no longer be counted. However those are temporary
objects which should be small in number, and this method has always been
an estimate.
2019-11-22 12:42:24 -08:00
John Hawthorn 26fd8d962c Optimize pinned page sorting
Previously we would count the pinned objects on each comparison. Since
sorting is O(N log N) and we calculated this on both left and right
pages on each comparison this resulted in a extra iterations over the
slots.
2019-11-22 12:42:24 -08:00
John Hawthorn 3f4199b0af Use value of use_verifier in gc_compact 2019-11-22 12:42:24 -08:00
卜部昌平 0e8219f591 make functions static
These functions are used from within a compilation unit so we can
make them static, for better binary size.  This changeset reduces
the size of generated ruby binary from 26,590,128 bytes to
26,584,472 bytes on my macihne.
2019-11-19 12:36:19 +09:00
Jeremy Evans ffd0820ab3 Deprecate taint/trust and related methods, and make the methods no-ops
This removes the related tests, and puts the related specs behind
version guards.  This affects all code in lib, including some
libraries that may want to support older versions of Ruby.
2019-11-18 01:00:25 +02:00
Jeremy Evans c5c05460ac Warn on access/modify of $SAFE, and remove effects of modifying $SAFE
This removes the security features added by $SAFE = 1, and warns for access
or modification of $SAFE from Ruby-level, as well as warning when calling
all public C functions related to $SAFE.

This modifies some internal functions that took a safe level argument
to no longer take the argument.

rb_require_safe now warns, rb_require_string has been added as a
version that takes a VALUE and does not warn.

One public C function that still takes a safe level argument and that
this doesn't warn for is rb_eval_cmd.  We may want to consider
adding an alternative method that does not take a safe level argument,
and warn for rb_eval_cmd.
2019-11-18 01:00:25 +02:00
John Hawthorn 3b6954f8b9 Fix passing actual object_id to finalizer
Previously we were passing the memory_id. This was broken previously if
compaction was run (which changes the memory_id) and now that object_id
is a monotonically increasing number it was always broken.

This commit fixes this by defering removal from the object_id table
until finalizers have run (for objects with finalizers) and also copying
the SEEN_OBJ_ID flag onto the zombie objects.
2019-11-08 12:41:05 -08:00
Nobuyoshi Nakada 20971799f2
Renamed `load_*.inc` as `*.rbinc` to utilize a suffix rule 2019-11-08 16:30:28 +09:00
Koichi Sasada 8fa41971c2 use builtins for GC.
Define a part of GC in gc.rb.
2019-11-08 15:29:02 +09:00
Aaron Patterson dddf5afb79
Add a counter for compaction
Keep track of the number of times the compactor ran.  I would like to
use this as a way to keep track of inline cache reference updates.
2019-11-07 12:46:14 -08:00
John Hawthorn b99833baec
Use a monotonically increasing number for object_id
This changes object_id from being based on the objects location in
memory (or a nearby memory location in the case of a conflict) to be
based on an always increasing number.

This number is a Ruby Integer which allows it to overflow the size of a
pointer without issue (very unlikely to happen in real programs
especially on 64-bit, but a nice guarantee).

This changes obj_to_id_tbl and id_to_obj_tbl to both be maps of Ruby
objects to Ruby objects (previously they were Ruby object to C integer)
which simplifies updating them after compaction as we can run them
through gc_update_table_refs.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2019-11-07 09:31:07 -08:00
Aaron Patterson d0d743ad45
Remove duplicate code
These functions are the same, so remove one.

Co-authored-by: John Hawthorn <john@hawthorn.email>
2019-11-06 16:31:55 -08:00
Aaron Patterson e58814d150
Revert "Use a monotonically increasing number for object_id"
This reverts commit bd2b314a05.
2019-11-06 15:12:28 -08:00
John Hawthorn bd2b314a05 Use a monotonically increasing number for object_id
This changes object_id from being based on the objects location in
memory (or a nearby memory location in the case of a conflict) to be
based on an always increasing number.

This number is a Ruby Integer which allows it to overflow the size of a
pointer without issue (very unlikely to happen in real programs
especially on 64-bit, but a nice guarantee).

This changes obj_to_id_tbl and id_to_obj_tbl to both be maps of Ruby
objects to Ruby objects (previously they were Ruby object to C integer)
which simplifies updating them after compaction as we can run them
through gc_update_table_refs.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2019-11-06 14:59:53 -08:00
Aaron Patterson ec54261b01
Fix zero free objects assertion
This commit is to attempt fixing this error:

  http://ci.rvm.jp/results/trunk-gc-asserts@ruby-sky1/2353281

Each non-full heap_page struct contains a reference to the next page
that contains free slots.  Compaction could fill any page, including
pages that happen to be linked to as "pages which contain free slots".

To fix this, we'll iterate each page, and rebuild the "free page list"
depending on the number of actual free slots on that page.  If there are
no free slots on the page, we'll set the free_next pointer to NULL.

Finally we'll pop one page off the "free page list" and set it as the
"using page" for the next allocation.
2019-11-04 08:58:52 -08:00
卜部昌平 f5e4063272 ruby_mimmalloc can return NULL
malloc can fail.  Should treat such situations.
2019-11-01 16:58:19 +09:00
Aaron Patterson 79d96b42df
Revert "Fix zero free objects assertion"
This reverts commit e1bf29314f.

I'm not sure why this broke stuff, I need to investigate later.
2019-10-30 18:05:32 -07:00
Aaron Patterson e1bf29314f
Fix zero free objects assertion
This commit is to attempt fixing this error:

  http://ci.rvm.jp/results/trunk-gc-asserts@ruby-sky1/2353281

Each non-full heap_page struct contains a reference to the next page
that contains free slots.  Compaction could fill any page, including
pages that happen to be linked to as "pages which contain free slots".

To fix this, we'll iterate each page, and rebuild the "free page list"
depending on the number of actual free slots on that page.  If there are
no free slots on the page, we'll set the free_next pointer to NULL.

Finally we'll pop one page off the "free page list" and set it as the
"using page" for the next allocation.
2019-10-30 17:28:55 -07:00
Aaron Patterson 22dbbbeb32
Compacting the heap can cause GC, so disable it
When we compact the heap, various st tables are updated, particularly
the table that contains the object id map.  Updating an st table can
cause a GC to occur, and we need to prevent any GC from happening while
moving or updating references.
2019-10-29 08:13:38 -07:00
Aaron Patterson da3774e5eb
Revert "Protect finalizer references during execution"
This reverts commit 60a7f9f446.

We can't have Ruby objects pointing at T_ZOMBIE objects otherwise we get
an error in the GC.  We need to find a different way to update
references.
2019-10-28 16:14:50 -07:00
Aaron Patterson 60a7f9f446
Protect finalizer references during execution
When we run finalizers we have to copy all of the finalizers to a new
data structure because a finalizer could add another finalizer and we
need to keep draining the "real" finalizer table until it's empty.
We don't want Ruby programs to mutate the finalizers that we're
iterating over as well.

Before this commit we would copy the finalizers in to a linked list.
The problem with this approach is that if compaction happens, the linked
list will need to be updated.  But the GC doesn't know about the
existence of the linked list, so it could not update references.  This
commit changes the linked list to be a Ruby array so that when
compaction happens, the arrays will automatically be updated and all
references remain valid.
2019-10-28 14:50:36 -07:00
Aaron Patterson aec16b7540
Marshal is calling functions that should pin things 2019-10-28 11:18:56 -07:00
Nobuyoshi Nakada 095cdca15b
Make weakmap finalizer an ifunc lambda
Simple comparison between proc/ifunc/method invocations:

```
  proc     15.209M (± 1.6%) i/s -     76.138M in   5.007413s
 ifunc     15.195M (± 1.7%) i/s -     76.257M in   5.020106s
method      9.836M (± 1.2%) i/s -     49.272M in   5.009984s
```

As `proc` and `ifunc` have no significant difference, chosen the
latter for arity check.
2019-10-18 14:53:52 +09:00
Nobuyoshi Nakada ce7942361d
Use identhash as WeakMap
As ObjectSpace::WeakMap allows FLONUM as a key, needs the special
deal for its hash.  [Feature #16035]
2019-10-18 14:53:51 +09:00
卜部昌平 f1ce4897f2 make rb_raise a GVL-only function again
Requested by ko1 that ability of calling rb_raise from anywhere
outside of GVL is "too much".  Give up that part, move the GVL
aquisition routine into gc.c, and make our new gc_raise().
2019-10-10 17:10:21 +09:00
Nobuyoshi Nakada a23b639050
negative_size_allocation_error never returns 2019-10-10 14:07:45 +09:00
卜部昌平 9c3153e0da allow rb_raise from outside of GVL
Now that allocation routines like ALLOC_N() can raise exceptions
on integer overflows.  This is a problem when the calling thread
has no GVL.  Memory allocations has been allowed without it, but
can still fail.

Let's just relax rb_raise's restriction so that we can call it
with or without GVL.  With GVL the behaviour is unchanged.  With
no GVL, wait for it.

Also, integer overflows can theoretically occur during GC when
we expand the object space.  We cannot do so much then.  Call
rb_memerror and let that routine abort the process.
2019-10-10 12:07:38 +09:00
卜部昌平 9b919885a0 fix memory corruption in old GCC
This typo introduced memory corruption when __builtin_add_overflow
is not available but uint128_t is.  GCC before 5 are one of such
situatins.

See also https://rubyci.org/logs/rubyci.s3.amazonaws.com/opensuseleap/ruby-master/log/20191009T120004Z.log.html.gz
2019-10-10 00:13:30 +09:00
Ben Woosley bb71a128eb Prefer st_is_member over st_lookup with 0
The st_is_member DEFINE has simpler semantics, for more readable code.
2019-10-09 23:46:50 +09:00
卜部昌平 a14cc07f2f avoid returning NULL from xrealloc
This changeset is to kill future possibility of bugs similar to
CVE-2019-11932.   The vulnerability occurs when reallocarray(3)
(which is a variant of realloc(3) and roughly resembles our
ruby_xmalloc2()) returns NULL.  In our C API, ruby_xmalloc()
never returns NULL to raise NoMemoryError instead.  ruby_xfree()
does not return NULL by definition.  ruby_xrealloc() on the other
hand, _did_ return NULL, _and_ also raised sometimes.  It is very
confusing.  Let's not do that.  x-series APIs shall raise on
error and shall not return NULL.
2019-10-09 12:12:28 +09:00
卜部昌平 7e0ae1698d avoid overflow in integer multiplication
This changeset basically replaces `ruby_xmalloc(x * y)` into
`ruby_xmalloc2(x, y)`.  Some convenient functions are also
provided for instance `rb_xmalloc_mul_add(x, y, z)` which allocates
x * y + z byes.
2019-10-09 12:12:28 +09:00
Aaron Patterson 6abcd35762
Do not free too many pages.
Sweep step checks `heap_pages_freeable_pages`, so compaction should do
the same.
2019-10-07 12:28:21 -07:00
Aaron Patterson 058db33c5e
Move empty pages to the tomb
I think we need to be moving empty pages to the tomb after they become
empty.
2019-10-07 12:10:24 -07:00
Aaron Patterson 0a2f04e156
Eliminate second GC pass for eliminating T_MOVED
`T_MOVED` is a linked list, so we can just iterate through the `T_MOVED`
objects, clearing them out and adding them to respective free lists.
2019-10-07 10:57:30 -07:00
Aaron Patterson bd4b65f4b0
IMEMO objects don't have a class, so return early
IMEMO objects don't have a class field to update, so we need to return
early, otherwise it can cause a segv.
2019-10-04 12:02:41 -07:00
Aaron Patterson a20ed0565e
Don't allocate objects in `gc_compact`
I'd like to call `gc_compact` after major GC, but before the GC
finishes.  This means we can't allocate any objects inside `gc_compact`.
So in this commit I'm just pulling the compaction statistics allocation
outside the `gc_compact` function so we can safely call it.
2019-10-04 11:11:59 -07:00
Nobuyoshi Nakada cbbe198c89
Fix potential memory leaks by `rb_imemo_tmpbuf_auto_free_pointer`
This function has been used wrongly always at first, "allocate a
buffer then wrap it with tmpbuf".  This order can cause a memory
leak, as tmpbuf creation also can raise a NoMemoryError exception.
The right order is "create a tmpbuf then allocate&wrap a buffer".
So the argument of this function is rather harmful than just
useless.

TODO:
* Rename this function to more proper name, as it is not used
  "temporary" (function local) purpose.
* Allocate and wrap at once safely, like `ALLOCV`.
2019-10-05 03:02:09 +09:00
卜部昌平 eb92159d72 Revert https://github.com/ruby/ruby/pull/2486
This reverts commits: 10d6a3aca7 8ba48c1b85 fba8627dc1 dd883de5ba
6c6a25feca 167e6b48f1 7cb96d41a5 3207979278 595b3c4fdd 1521f7cf89
c11c5e69ac cf33608203 3632a812c0 f56506be0d 86427a3219 .

The reason for the revert is that we observe ABA problem around
inline method cache.  When a cache misshits, we search for a
method entry.  And if the entry is identical to what was cached
before, we reuse the cache.  But the commits we are reverting here
introduced situations where a method entry is freed, then the
identical memory region is used for another method entry.  An
inline method cache cannot detect that ABA.

Here is a code that reproduce such situation:

```ruby
require 'prime'

class << Integer
  alias org_sqrt sqrt
  def sqrt(n)
    raise
  end

  GC.stress = true
  Prime.each(7*37){} rescue nil # <- Here we populate CC
  class << Object.new; end

  # These adjacent remove-then-alias maneuver
  # frees a method entry, then immediately
  # reuses it for another.
  remove_method :sqrt
  alias sqrt org_sqrt
end

Prime.each(7*37).to_a # <- SEGV
```
2019-10-03 12:45:24 +09:00
卜部昌平 dd883de5ba refactor constify most of rb_method_entry_t
Now that we have eliminated most destructive operations over the
rb_method_entry_t / rb_callable_method_entry_t, let's make them
mostly immutabe and mark them const.

One exception is rb_export_method(), which destructively modifies
visibilities of method entries.  I have left that operation as is
because I suspect that destructiveness is the nature of that
function.
2019-09-30 10:26:38 +09:00
卜部昌平 cf33608203 refactor constify most of rb_method_definition_t
Most (if not all) of the fields of rb_method_definition_t are never
meant to be modified once after they are stored.  Marking them const
makes it possible for compilers to warn on unintended modifications.
2019-09-30 10:26:38 +09:00
Nobuyoshi Nakada 8d0ff88727
Adjusted spaces [ci skip] 2019-09-27 14:06:07 +09:00
Aaron Patterson 293c6c8cc3
Add compaction support to `rb_ast_t`
This commit adds compaction support to `rb_ast_t`.
2019-09-26 15:41:46 -07:00
Jean Boussier a4a19b114b Allow non-finalizable objects in ObjectSpace::WeakMap
[feature #16035]

This goes one step farther than what nobu did in [feature #13498]

With this patch, special objects such as static symbols, integers, etc can be used as either key or values inside WeakMap. They simply don't have a finalizer defined on them.

This is useful if you need to deduplicate value objects
2019-08-29 20:40:52 +09:00
卜部昌平 3df37259d8 drop-in type check for rb_define_singleton_method
We can check the function pointer passed to
rb_define_singleton_method like how we do so in rb_define_method.
Doing so revealed many arity mismatches.
2019-08-29 18:34:09 +09:00
卜部昌平 6dd60cf114 st_foreach now free from ANYARGS
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct.  This commit deletes ANYARGS from
st_foreach.  I strongly believe that this commit should have had come
with b0af0592fd, which added extra
parameter to st_foreach callbacks.
2019-08-27 15:52:26 +09:00
卜部昌平 bc3e7924bc rb_proc_new / rb_fiber_new now free from ANYARGS
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct.  This commit deletes ANYARGS from
rb_proc_new / rb_fiber_new, and applies RB_BLOCK_CALL_FUNC_ARGLIST
wherever necessary.
2019-08-27 15:52:26 +09:00
卜部昌平 703783324c rb_ensure now free from ANYARGS
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct.  This commit deletes ANYARGS from
rb_ensure, which also revealed many arity / type mismatches.
2019-08-27 15:52:26 +09:00
Aaron Patterson 9f0f777173
this iv table should also use the new update function 2019-08-26 13:42:16 -07:00
Aaron Patterson 09d8e06b33
Try only updating hash value references
I'm afraid the keys to this hash are just integers, and those integers
may look like VALUE pointers when they are not.  Since we don't mark the
keys to this hash, it's probably safe to say that none of them have
moved, so we shouldn't try to update the references either.
2019-08-26 11:31:52 -07:00
Aaron Patterson d9bfbe363d
Make `gc_update_table_refs` match `mark_tbl_no_pin` a little more closely
This commit just makes `gc_update_table_refs` match `mark_tbl_no_pin`
more closely.
2019-08-26 11:14:03 -07:00
Koichi Sasada 88b1f2dac4
`rp(obj)` shows func, file and line. (#2394)
rp() macro for debug also shows file location and function name
such as:

  [OBJ_INFO:rb_call_inits@inits.c:73] 0x000056147741b248 ...
2019-08-21 01:04:08 +09:00
Masataka Pocke Kuwabara 6b42b0c60c Fix document of `GC.start` (#2382) 2019-08-18 15:39:19 +09:00
git f78916e3c1 * expand tabs. 2019-08-13 11:20:39 +09:00
Nobuyoshi Nakada c215a6f282
Removed non-VM_OBJSPACE code
It has not been used for 4 years, since r60856,
e33b1690d0.
2019-08-13 11:03:54 +09:00
Nobuyoshi Nakada 2f744f53c1
Refactored `objspace_each_objects`
As `rb_objspace_each_objects_without_setup` doesn't reset and
restore `dont_incremental` flag, renamed the bare iterator as
`objspace_each_objects_without_setup`.  `objspace_each_objects`
calls it when called with the flag disabled, wrap the arguments
otherwise only.
2019-08-13 10:56:21 +09:00
Nobuyoshi Nakada 0c1c42c43a
Move rb_objspace_t* in objspace_reachable_objects_from_root to an argument 2019-08-13 10:33:19 +09:00
git aec93417f0 * expand tabs. 2019-08-13 09:50:34 +09:00
Nobuyoshi Nakada ac656bc2bd
Hoisted out GPR_DEFAULT_REASON 2019-08-13 09:47:08 +09:00
Nobuyoshi Nakada 917d766508
Move rb_objspace_t* in gc_verify_internal_consistency to an argument 2019-08-13 09:47:08 +09:00
Nobuyoshi Nakada 0c2d81dada
Renamed ruby_finalize_{0,1}
And pass rb_execution_context_t as an argument.
2019-08-13 09:47:08 +09:00
Aaron Patterson aac4d9d6c7
Rename rb_gc_mark_no_pin -> rb_gc_mark_movable
Renaming this function.  "No pin" leaks some implementation details.  We
just want users to know that if they mark this object, the reference may
move and they'll need to update the reference accordingly.
2019-08-12 16:44:54 -04:00
Aaron Patterson 6749682f82
also unpin `final` on weak maps 2019-08-12 12:34:09 -04:00
Yusuke Endoh 3ddbba84b5 gc.c: Double STACKFRAME_FOR_CALL_CFUNC (1024->2048)
ef64ab917e didn't fix the issue, so the
size seems not enough yet.

https://rubyci.org/logs/rubyci.s3.amazonaws.com/osx1014/ruby-master/log/20190809T114503Z.fail.html.gz
2019-08-09 22:48:20 +09:00
Yusuke Endoh ef64ab917e gc.c: Increase STACKFRAME_FOR_CALL_CFUNC
On macOS Mojave, the child process invoked in TestFiber#test_stack_size
gets stuck because the stack overflow detection is too late.
(ko1 figured out the mechanism of the failure.)

This change attempts to detect stack overflow earlier.
2019-08-09 17:31:19 +09:00
Nobuyoshi Nakada a04e3585d3
Extracted wmap_live_p 2019-08-06 23:00:29 +09:00
Aaron Patterson 81252c5ccd
Let prev EP move again
The last time we committed this, we were asking the VM to write to the
ep.  But VM assertions check if the ENV data is the correct type, which
if it's a T_MOVED pointer it's not the correct type.  So the vm
assertions would fail.  This time we just directly write to it from the
GC and that bypasses the vm assertion checks.
2019-08-05 13:31:58 -07:00
git c9192ef2e8 * expand tabs. 2019-08-06 00:56:05 +09:00
Aaron Patterson 33d7a58ffb
add compaction support to weak maps 2019-08-05 08:55:34 -07:00
Koichi Sasada e03b3b4ae0 add debug_counters to check details.
add debug_counters to check the Hash object statistics.
2019-08-02 15:59:47 +09:00
Nobuyoshi Nakada 8b162ce9d1
Fix assertion failure when VM_CHECK_MODE
Some VM frames (dummy and top pushed by `rb_vm_call_cfunc`) has
iseq but has no pc.
2019-08-01 20:55:03 +09:00
卜部昌平 5d33f78716 fix tracepoint + backtrace SEGV
PC modification in gc_event_hook_body was careless.  There are (so
to say) abnormal iseqs stored in the cfp.  We have to check sanity
before we touch the PC.

This has not been fixed because there was no way to (ab)use the
setup from pure-Ruby.  However by using our official C APIs it is
possible to touch such frame(s), resulting in SEGV.

Fixes [Bug #14834].
2019-08-01 16:00:59 +09:00
Aaron Patterson 5ad2dfd8dc
Revert "Let prev EP move"
This reverts commit e352445863.

This is breaking CI and I'm not sure why yet, so I'll revert for now.
2019-07-31 10:34:23 -07:00
Aaron Patterson e352445863
Let prev EP move
This commit allows the previos EP pointer to move, then updates its
location
2019-07-31 09:42:43 -07:00
Koichi Sasada 82b02c131e pass to obj_info().
obj_info() has a routine to show SPECIAL_CONST_P() objects so
we don't need to check it here.
2019-07-26 11:45:25 +09:00
Lourens Naudé 90c4bd2d2b
Let memory sizes of the various IMEMO object types be reflected correctly
[Feature #15805]

Closes: https://github.com/ruby/ruby/pull/2140
2019-07-23 16:22:34 +09:00
Jeremy Evans 01995df645 Document BasicObject does not implement #object_id and #send [ci skip]
Fixes [Bug #10422]
2019-07-22 15:07:22 -07:00
Koichi Sasada f75561b8d4 constify RHash::ifnone.
RHash::ifnone should be protected by write-barriers so this field
should be const. However, to introduce GC.compact, the const was
removed. This commit revert this removing `const` and modify
gc.c `TYPED_UPDATE_IF_MOVED` to remove `const` forcely by a type cast.
2019-07-22 17:01:31 +09:00
Aaron Patterson d304f77c58
Only disable GC around reference updating
This is the only place that can change the size of the object id tables
and cause a GC.
2019-07-19 15:12:50 -07:00
Koichi Sasada fba3e76e3f fix debug counter for Hash counts.
Change debug_counters for Hash object counts:

* obj_hash_under4 (1-3) -> obj_hash_1_4 (1-4)
* obj_hash_ge4 (4-7)    -> obj_hash_5_8 (5-8)
* obj_hash_ge8 (>=8)    -> obj_hash_g8  (> 8)

For example on rdoc benchmark:

[RUBY_DEBUG_COUNTER]    obj_hash_empty                         554,900
[RUBY_DEBUG_COUNTER]    obj_hash_under4                        572,998
[RUBY_DEBUG_COUNTER]    obj_hash_ge4                             1,825
[RUBY_DEBUG_COUNTER]    obj_hash_ge8                             2,344
[RUBY_DEBUG_COUNTER]    obj_hash_empty                         553,097
[RUBY_DEBUG_COUNTER]    obj_hash_1_4                           571,880
[RUBY_DEBUG_COUNTER]    obj_hash_5_8                               982
[RUBY_DEBUG_COUNTER]    obj_hash_g8                              2,189
2019-07-19 16:24:14 +09:00
Koichi Sasada 182ae1407b fix shared array terminology.
Shared arrays created by Array#dup and so on points
a shared_root object to manage lifetime of Array buffer.
However, sometimes shared_root is called only shared so
it is confusing. So I fixed these wording "shared" to "shared_root".

* RArray::heap::aux::shared -> RArray::heap::aux::shared_root
* ARY_SHARED() -> ARY_SHARED_ROOT()
* ARY_SHARED_NUM() -> ARY_SHARED_ROOT_REFCNT()

Also, add some debug_counters to count shared array objects.

* ary_shared_create: shared ary by Array#dup and so on.
* ary_shared: finished in shard.
* ary_shared_root_occupied: shared_root but has only 1 refcnt.
  The number (ary_shared - ary_shared_root_occupied) is meaningful.
2019-07-19 13:07:59 +09:00
Koichi Sasada f326b4f4af simplify around GC_ASSERT() 2019-07-15 10:39:57 +09:00
Samuel Williams 5c8061a9e2
Make `stack_check` slightly easier to use in debugger. 2019-07-12 11:56:51 +12:00
Nobuyoshi Nakada 26d674fdc7
Suppress warning on x64-mingw 2019-07-11 11:58:35 +09:00
Aaron Patterson 12762b76cb
Don't manipulate GC flags directly
We need to disable the GC around compaction (for now) because object id
book keeping can cause malloc to happen and that can trigger GC.
2019-07-10 11:12:28 -05:00
Nobuyoshi Nakada 23c92b6f82
Revert self-referencing finalizer warning [Feature #15974]
It has caused CI failures.

* d0cd0866d8

  Disable GC during rb_objspace_reachable_object_p

* 89cef1c56b

  Version guard for [Feature #15974]

* 796eeb6339.

  Fix up [Feature #15974]

* 928260c2a6.

  Warn in verbose mode on defining a finalizer that captures the object
2019-07-04 04:01:06 +09:00
git c62aac1086 * expand tabs. 2019-07-04 01:04:44 +09:00
Nobuyoshi Nakada d0cd0866d8
Disable GC during rb_objspace_reachable_object_p
Try to fix CI breakage by [Feature #15974].
2019-07-04 00:58:52 +09:00
Nobuyoshi Nakada 9f1d67a68f
Renamed to rb_objspace_reachable_object_p 2019-07-03 23:52:52 +09:00
Aaron Patterson 6bd49b33c8
Ensure that GC is disabled during compaction
Various things can cause GC to occur when compaction is running, for
example resizing the object identity map:

```
    frame #24: 0x000000010c784a10 ruby`gc_grey [inlined] push_mark_stack(stack=<unavailable>, data=<unavailable>) at gc.c:4311:42
    frame #25: 0x000000010c7849ff ruby`gc_grey(objspace=0x00007fc56c804400, obj=140485906037400) at gc.c:4907
    frame #26: 0x000000010c78f881 ruby`gc_start at gc.c:6464:8
    frame #27: 0x000000010c78f5d1 ruby`gc_start [inlined] gc_marks_start(objspace=0x00007fc56c804400, full_mark=<unavailable>) at gc.c:6009
    frame #28: 0x000000010c78f3c0 ruby`gc_start at gc.c:6291
    frame #29: 0x000000010c78f399 ruby`gc_start(objspace=0x00007fc56c804400, reason=<unavailable>) at gc.c:7104
    frame #30: 0x000000010c78930c ruby`objspace_xmalloc0 [inlined] objspace_malloc_fixup(objspace=<unavailable>, mem=0x000000011372a000, size=<unavailable>) at gc.c:9665:5
    frame #31: 0x000000010c7892f5 ruby`objspace_xmalloc0(objspace=0x00007fc56c804400, size=12582912) at gc.c:9707
    frame #32: 0x000000010c89bc13 ruby`st_init_table_with_size(type=<unavailable>, size=<unavailable>) at st.c:605:39
    frame #33: 0x000000010c89c5e2 ruby`rebuild_table_if_necessary [inlined] rebuild_table(tab=0x00007fc56c40b250) at st.c:780:19
    frame #34: 0x000000010c89c5ac ruby`rebuild_table_if_necessary(tab=0x00007fc56c40b250) at st.c:1142
    frame #35: 0x000000010c89c379 ruby`st_insert(tab=0x00007fc56c40b250, key=140486132605040, value=140485922918920) at st.c:1161:5
    frame #36: 0x000000010c794a16 ruby`gc_compact_heap [inlined] gc_move(objspace=0x00007fc56c804400, scan=<unavailable>, free=<unavailable>, moved_list=140485922918960) at gc.c:7441:9
    frame #37: 0x000000010c794917 ruby`gc_compact_heap(objspace=0x00007fc56c804400, comparator=<unavailable>) at gc.c:7695
    frame #38: 0x000000010c79410d ruby`gc_compact [inlined] gc_compact_after_gc(objspace=0x00007fc56c804400, use_toward_empty=1, use_double_pages=<unavailable>, use_verifier=1) at gc.c:0:22
```

We *definitely* need the heap to be in a consistent state during
compaction, so this commit sets the current state to "during_gc" so that
nothing will trigger a GC until the heap finishes compacting.

This fixes the bug we saw when running the tests for https://github.com/ruby/ruby/pull/2264
2019-07-03 14:45:50 +01:00
git 9f26242411 * expand tabs. 2019-07-03 04:26:53 +09:00
Nobuyoshi Nakada 796eeb6339
Fix up [Feature #15974]
* Fixed warning condition
* Fixed function signature
* Use ident hash
2019-07-03 04:22:41 +09:00
Chris Seaton 928260c2a6
Warn in verbose mode on defining a finalizer that captures the object
[Feature #15974]

Closes: https://github.com/ruby/ruby/pull/2264
2019-07-03 04:05:22 +09:00
Nobuyoshi Nakada f3c81b4e90
Frozen objects in WeakMap
* gc.c (wmap_aset): bypass check for frozen and allow frozen
  object in WeakMap.  [Bug #13498]
2019-06-23 00:31:16 +09:00
Nobuyoshi Nakada ab6d8d0b65
Adjust indent 2019-06-19 20:40:49 +09:00
Samuel Williams d17344cfc5 Remove IA64 support. 2019-06-19 23:30:04 +12:00
Samuel Williams 3e5b885cd2 Rework debug conditional. 2019-06-19 20:39:10 +12:00
Samuel Williams b24603adff Move vm stack init into thread. 2019-06-19 20:39:10 +12:00
Nobuyoshi Nakada 09a2189c1b
Adjust indent 2019-06-07 01:56:31 +09:00
Aaron Patterson c9b74f9fd9
Pin keys in "compare by identity" hashes
Hashes that compare by identity care about the location of the object in
memory.  Since they care about the memory location, we can't let them
move.
2019-06-03 15:15:48 -07:00
Aaron Patterson 790a1b1790
object id is stable now for all objects, so we can let hash keys move 2019-06-03 13:38:47 -07:00
Aaron Patterson 2de3d92844
allow objects in imemo envs to move 2019-06-03 13:38:47 -07:00
NAKAMURA Usaku ca22cccc14
get rid of a warning of VC++ 2019-06-04 03:52:53 +09:00
Koichi Sasada c280519256 remove `rb_objspace_pinned_object_p()`
Nobody uses this function other than gc.c. We only need
RVALUE_PINNED().
2019-06-03 15:40:38 +09:00
git 106843d839 * expand tabs. 2019-05-30 17:12:53 +09:00
Koichi Sasada 5fc9f0008f reorder bitmap clearing. 2019-05-30 17:12:26 +09:00
Koichi Sasada dd63d7da61 move pinned_bits[] position in struct heap_page.
pinned_bits are not used frequently (only GC.compact use it) so
move it at the end of struct heap_page.
2019-05-30 09:10:17 +01:00
Koichi Sasada e15de86583 introduce `during_compacting` flag.
Usually PINNED_BITS are not needed (only for GC.compact need it)
so skip updating PINNED_BITS if the marking is not by GC.compact.
2019-05-30 16:52:42 +09:00
Takashi Kokubun 797d7efde1
Prevent MJIT compilation from running while moving
pointers.

Instead of 4fe908c164, just locking the MJIT
worker may be fine for this case. And also we might have the same issue
in all `gc_compact_after_gc` calls.
2019-05-29 08:56:27 +09:00
Takashi Kokubun 462a63c39e
Drop MJIT debug code from GC.compact
As ko1 added some improvements on GC.compact, I want to check if it
solved the problem too.
2019-05-29 05:10:12 +09:00
Koichi Sasada 8a2b497e3b remove obsolete rb_gc_finalize_deferred().
rb_gc_finalize_deferred() is remained for compatibility with
C-extensions. However, this function is no longer working
from Ruby 2.4 (crash with SEGV immediately).
So remove it completely.
2019-05-28 15:57:20 +09:00
Koichi Sasada f3bddc103d use malloc() instead of calloc().
Here malloc() is enough because all elements of the page_list
will be overwrite.
2019-05-28 11:44:08 +09:00
Koichi Sasada f9401d5d44 should skip T_ZOMBIE here. 2019-05-28 11:44:08 +09:00
Koichi Sasada 2229acaa54 should use heap_eden->total_pages.
The size of page_list is heap_eden->total_pages, but
init_cursors() assumes the size of page_list is `heap_allocated_pages`.
This patch fix it.
2019-05-28 11:44:08 +09:00
Koichi Sasada 7f211bfe6c use only eden_heaps on GC.compact.
`heap_pages_sorted` includes eden and tomb pages, so we should not
use tomb pages for GC.compact (or we should move all of tomb pages
into eden pages). Now, I choose only eden pages. If we allow to
move Zombie objects (objects waiting for finalizers), we should
use both type of pages (TODO).
2019-05-28 10:31:02 +09:00
Koichi Sasada cfd839c140 Suppress warning (uninitialized variable). 2019-05-28 10:31:02 +09:00
Koichi Sasada b3602f1d20 check the object is in tomb_heap. 2019-05-27 08:19:30 +01:00
Koichi Sasada 35146c4368 add a space between type and others 2019-05-27 08:12:30 +01:00
Koichi Sasada b3a6469e46 add a line break for each error message 2019-05-27 08:09:47 +01:00
Koichi Sasada 6c1a07555c fix GC.verify_internal_consistency.
Fix debug output to dump more useful information on GC.compact
debugging.

check_rvalue_consistency_force() now accepts `terminate` flag
to terminate a program with rb_bug() or only print error message.
GC.verify_internal_consistency use this flag (== FALSE) to dump
all of debug output.
2019-05-27 14:53:38 +09:00
Koichi Sasada 61da57c76a is_pointer_to_heap() checks also tomb or not.
is_pointer_to_heap(obj) checks this obj belong to a heap page.
However, this function returns TRUE even if the page is tomb page.
This is re-commit of [712c027524].

heap_page_add_freeobj() should not use is_pointer_to_heap(), but
should check more explicitly.
2019-05-27 14:53:37 +09:00
git a4da223c9a * expand tabs. 2019-05-24 19:00:50 +09:00
Kazuhiro NISHIYAMA 6ae9d5c85f
Revert "check it in eden or tomb."
This reverts commit 712c027524.
2019-05-24 18:59:58 +09:00
Koichi Sasada b0a4d81fc3 check RVALUE on verifier.
GC.verify_internal_consistency() checks health of each RVALUE with
check_rvalue_consistency(). However, this function is enabled
only on debug environment (RGENGC_CHECK_MODE>1). So introduce
new function check_rvalue_consistency_force() and use it
in GC.verify_internal_consistency.
2019-05-24 17:52:58 +09:00
Koichi Sasada 712c027524 check it in eden or tomb.
is_pointer_to_heap() checks if it is in valid pointer to the
RVALUE in any heap_page_body. However, it returns true if it
points tomb pages. This patch check it points to eden pages.
2019-05-24 17:35:22 +09:00
Koichi Sasada 10927b5925 add separation char on rb_obj_info(imemo obj) 2019-05-24 17:08:15 +09:00
Takashi Kokubun 4fe908c164
gc.c: Try pausing MJIT worker during GC.verify_compaction_references
for debugging
http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/2048247
2019-05-23 07:53:42 -07:00
Koichi Sasada dc95b57a68 add verifier before compact 2019-05-23 17:31:14 +09:00
Urabe, Shyouhei 763989c6c5 prefix ASAN related inline functions asan_
requested by Ko1.
2019-05-23 17:24:53 +09:00
Koichi Sasada 6be0ab73c3 gc_pin() doesn't check is_markable_object().
Caller of gc_pin() should check it is a mark-able object.
So gc_pin() doesn't need to check it. With this fix,
we can refactoring around it.
2019-05-23 16:58:21 +09:00
Koichi Sasada 4814f17361 skip zombies.
rb_gc() no longer invokes finalizers, so there are T_ZOMBE objects.
2019-05-23 13:21:40 +09:00
Koichi Sasada 02973d3ba8 pin `maybe` pointers.
Objects pointed by "maybe" pointers because of conservative marking
should be pinned down.
2019-05-23 11:42:15 +09:00
Koichi Sasada 136ae55892 Do not kick finalizers on rb_gc().
rb_gc() kicks gc_finalize_deferred(), which invokes finalizers.
This means that any Ruby program can be run this point and
it may be thread switching points and so on.

However, it is difficult to think it invokes any Ruby programs.
For example, `GC.compact` use `rb_gc()` to implement it, howver,
any Ruby program must not be run on this timing.

For this reason (it is difficult to image it run any Ruby program),
I removed `gc_finalize_deferred()` line in rb_gc().

This patch solves GC.compact issue.
[Bug #15809] and re-enable GC.compact test.
2019-05-23 11:26:33 +09:00
git 2fb69b3296 * expand tabs. 2019-05-22 16:54:47 +09:00
Nobuyoshi Nakada 32dd1a798a
gc.c: revert b00f280d4b "Eagerly name modules and classes"
* gc.c (rb_raw_obj_info): new string objects cannot allocate to
  create new class path name during GC.
2019-05-22 16:52:19 +09:00
Alan Wu b00f280d4b
Eagerly name modules and classes
* variable.c: make the hidden ivars `classpath` and `tmp_classpath` the source
  of truth for module and constant names. Assign to them when modules are bind
  to constants.

* variable.c: remove references to module name cache, as what used to be the cache
  is now the source of truth. Remove rb_class_path_no_cache().

* variable.c: remove the hidden ivar `classid`. This existed for the purposes of
  module name search, which is now replaced. Also, remove the associated
  rb_name_class().

* class.c: use rb_set_class_path_string to set the name of Object during boot.
  Must use a fstring as this runs before rb_cString is initialized and
  creating a normal string leads to a VALUE without a class.

* spec/ruby/core/module/name_spec.rb: add a few specs to specify what happens
  to Module#name across multiple operations. These specs pass without other
  code changes in this commit.

[Feature #15765]
2019-05-22 15:46:47 +09:00
Koichi Sasada 7ff4abe650 unify normal and verify ver. 2019-05-21 07:45:21 +01:00
git 583ecd5fc5 * expand tabs. 2019-05-20 22:08:27 +09:00
Nobuyoshi Nakada e83f10b368
Get rid of undefined behavior that source and destination buffers overlap 2019-05-20 21:58:06 +09:00
Aaron Patterson 154a67f140
Rename rb_gc_new_location to rb_gc_location
The function will return new or existing locations depending on whether
or not the object actually moved, so give it a more appropriate name.
2019-05-18 12:24:28 +03:00
Kazuhiro NISHIYAMA bbb84a16fa
Add fall through comment for Coverity Scan 2019-05-18 14:20:33 +09:00
Aaron Patterson ea3e7e2685
Prevent Dynamic -> Static symbols from moving
If a dynamic symbol has been converted to a static symbol, it gets added
to the global ID list and should no longer move.  C extensions can pass
symbols to rb_sym2id and those symbols should no longer be movable.
When the symbol is passed to rb_sym2id, the `id` member is set, so we
can use its existence to prevent movement.
2019-05-17 17:08:31 +03:00
Koichi Sasada 88449100bc don't need to sweep rest.
`transient_heap_evacuate()` disables GC using `rb_gc_disable()`
to prohibt GC invocation because of new allocation for evacuated
memory. However, `rb_gc_disable()` sweep all rest of unswept pages.
We don't need to cancel lazy sweep so this patch introduce
`rb_gc_disable_no_rest()` which doesn't cancel lazy sweep.
2019-05-16 17:18:50 +09:00
Nobuyoshi Nakada 7069f64c41
Prefix global_symbols with `ruby_` 2019-05-16 15:43:16 +09:00
Nobuyoshi Nakada 973431c059
Make internal functions static 2019-05-16 15:41:33 +09:00
Takashi Kokubun 82332c7d8b
Rename mjit_gc_finish_hook to mjit_gc_exit_hook
because @ko1 said "gc_finish" is confusing like a finish of entire GC
process
2019-05-15 23:14:07 -07:00
Nobuyoshi Nakada e970ab3339
Suppress unused-but-set-variable warning 2019-05-15 23:17:18 +09:00
Aaron Patterson 3cf767ee35
unpin finalizers and update references 2019-05-15 10:56:15 +02:00
git e8b929b9df * expand tabs. 2019-05-15 12:21:53 +09:00
Aaron Patterson c70ceb5992
Add object packing strategies for compaction
This commit adds an alternative packing strategy for compaction.
Instead of packing towards "most pinned" pages, we can pack towards
"most empty" pages.  The idea is that we can double the heap size, then
pack all objects towards the empty side of the heap.  This will ensure
maximum chaos for testing / verification.
2019-05-14 20:21:03 -07:00
Aaron Patterson 2ca537ba4b
Fixing function name
This function is used for marking / pinning vm stack values, so it
should have "vm" in the function name to be more clear.
2019-05-14 08:18:43 -07:00
Aaron Patterson a1ecf07dff
turn T_MOVED in to a linked list 2019-05-13 14:00:36 -07:00
Aaron Patterson 66a7c92938
Don't run the compactor if GC is disabled
GC is required for pinning / marking objects.  If the compactor runs
without pinning everything, then it will blow up, so just return early
if the GC is disabled.
2019-05-13 12:59:30 -07:00
Kazuhiro NISHIYAMA b42303b151
Fix typos 2019-05-13 21:14:52 +09:00
Aaron Patterson dc405eb737
Pin finalizer table
Objects in the finalizer table stay pinned for now.  In some cases, the
key could move which would cause a miss when removing the object from
the table (leading to a T_MOVED reference staying in the table).
2019-05-08 15:56:07 -07:00
git 8b12db6e19 * expand tabs. 2019-05-09 07:26:29 +09:00
Aaron Patterson c53f87943e
Calling `obj_info` during sweep is unsafe
`obj_info` will look at references of objects in some cases (for example
it will try to access path information on ISeq objects).  But during the
sweep phase, if the referenced object is collected before `obj_info` is
called, then it could be a bad ref and a segv will occur.

For example:

A -> B

Sweep phase:

1. obj_info(B)
2. Sweep and free B
3. obj_info(A); A tries to read B
4. SEGV

This commit simply removes the call to `obj_info` during the sweep
phase.
2019-05-08 15:19:59 -07:00
Lourens Naudé a47f598d77
Reduce ONIG_NREGION from 10 to 4: power of 2 and testing revealed most pattern matches are less than or equal to 4 results
Closes: https://github.com/ruby/ruby/pull/2135
2019-05-07 21:58:55 +09:00
Koichi Sasada 4dc5d3c5dd add new debug_counters about is_pointer_to_heap().
is_pointer_to_heap() is used for conservative marking. To analyze
this function's behavior, introduce some debug_counters.
2019-05-07 14:10:43 +09:00
Urabe, Shyouhei f95f07dad3 avoid passing NULL to memset
`GC::Profiler.enable; GC::Profiler.clear` tries to clear
objspace->profile.records but it has never been allocated before.
Thus the MEMCPY took NULL argument before this changeset.

The objspace->profile.records is allocated appropriately elsewhere.
Why not juts free it if any?  That should work.
2019-04-29 21:52:44 +09:00
Urabe, Shyouhei 3ba485c0bf zero-fill before GC mark
Depending on architectures, setjmp might not fully fill a jmp_buf.
On such machines the union can contain wobbly bits. They are then
scanned during mark_locations_array().  This is bad.
2019-04-26 15:59:40 +09:00
Urabe, Shyouhei 1f4204a762 disable assertion when MSAN is active
These assertions check if a newly allocated object (which is marked
as an uninitialized memory region in MSAN) is in fact a T_NONE.

Thus they intentionally read uninitialized memory regions, which do
not interface well with MSAN.  Just disalbe them.
2019-04-26 15:59:40 +09:00
Nobuyoshi Nakada 1613917ae6
Defer setting gc_stress instead of setting dont_gc
[Bug #15784]
2019-04-24 17:34:21 +09:00
Nobuyoshi Nakada f1a52d96a5
Defer setting gc_stress until inits done
[Bug #15784]
2019-04-24 13:02:01 +09:00
Aaron Patterson 2e1ac22089
Oops, bad merge 🙇‍♂️ 2019-04-22 20:39:03 -07:00
Aaron Patterson ea520ca927
Prevent rb_define_(class|module) classes from moving
Before this commit, classes and modules would be registered with the
VM's `defined_module_hash`.  The key was the ID of the class, but that
meant that it was possible for hash collisions to occur.  The compactor
doesn't allow classes in the `defined_module_hash` to move, but if there
is a conflict, then it's possible a class would be removed from the hash
and not get pined.

This commit changes the key / value of the hash just to be the class
itself, thus preventing movement.
2019-04-22 20:08:01 -07:00