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

1707 Коммитов

Автор SHA1 Сообщение Дата
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