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

2352 Коммитов

Автор SHA1 Сообщение Дата
Peter Zhu b77551adee Remove unneeded local variables 2023-12-01 15:21:01 -05:00
Peter Zhu 80ea7fbad8 Pin embedded shared strings
Embedded shared strings cannot be moved because strings point into the
slot of the shared string. There may be code using the RSTRING_PTR on
the stack, which would pin the string but not pin the shared string,
causing it to move.
2023-12-01 15:04:31 -05:00
Alan Wu fcabe2df39
Remove written-but-never-read `me->def.body.refined.owner`
This also removes aliasing rule violations; the anonymous structs were
distinct types from `rb_method_refined_t`.
2023-11-29 01:41:40 +00:00
Peter Zhu e3875dd0f8 Don't incremental mark when GC stressful
Incremental marking prevents the GC from fully executing, so it may fail
to catch certain bugs.
2023-11-27 11:13:47 -05:00
Peter Zhu 7835ebce97 Set compaction after major GC has been determined
do_full_mark can change in gc_start, so we want to set auto-compaction
only after do_full_mark has been properly set.
2023-11-27 10:23:43 -05:00
Peter Zhu 269c705f93 Fix compaction for generic ivars
When generic instance variable has a shape, it is marked movable. If it
it transitions to too complex, it needs to update references otherwise
it may have incorrect references.
2023-11-24 13:29:04 -05:00
KJ Tsanaktsidis e201b81f79 Mark cc->cme_ for refinement callcaches as well
This is required for the same reason that super CC needs it.
See 36023d5cb7.

Reproducer:

    def cached_foo_callsite(obj) = obj.foo

    class Foo
      def foo = :v1

      module R
        refine Foo do
          def foo = :unused
        end
      end
    end

    obj = Foo.new
    cached_foo_callsite(obj) # set up cc with cme for foo=:v1

    class Foo
      def foo = :v2
    end
    GC.start # cme for foo=:v1 collected, if not reachable by cached_foo_callsite

    cached_foo_callsite(obj)

[Bug #19994]
2023-11-24 13:16:15 -05:00
Peter Zhu 99e1f7b607 Abort GC on shutdown
On large Ruby applications, shutdown may be slow if a major GC has just
started because rb_objspace_call_finalizer completes the GC.

This commit adds gc_abort which discards the mark stack if during
incremental marking and stops sweeping if during lazy sweeping.
2023-11-24 09:28:34 -05:00
Alan Wu 1ffaff884e Allow ivars movement in too_complex RCLASSes to fix crash
Previously, because gc_update_object_references() did not update the
VALUEs in the too_complex ivar st_table for T_CLASS and T_MODULE
objects, GC compaction could finish with corrupted objects.

 - start with `klass`, not too_complex
 - GC incremental step marks `klass` and its ivars
 - ruby code makes `klass` too_complex
 - GC compaction runs and move `klass` ivars, but because `klass` is
   too_complex, its ivars are not updated by gc_update_object_references(),
   leaving T_NONE or T_MOVED objects in the ivar table.

Co-authored-by: Peter Zhu <peter@peterzhu.ca>
2023-11-23 20:30:18 -05:00
Alan Wu 22de08811e Avoid marking IDs in too_complex tables and rename gc_update_tbl_refs()
Marking both keys and values versus marking just values is an important
distinction, but previously, gc_update_tbl_refs() and gc_update_table_refs()
had names that were too similar.

The st_table storing ivars for too_complex T_OBJECTs have IDs as keys,
but we were marking the IDs unnecessary previously, maybe due to the
confusing naming.
2023-11-23 20:30:18 -05:00
Alan Wu ecdb112881 Fix `rp(too_complex_t_object)` tripping assert
Previously, it tripped the assert about too_complex in
ROBJECT_IV_CAPACITY(). This fixes double faults for some crashes and
helps with use during development.
2023-11-23 12:16:57 -05:00
Aaron Patterson 6fce8c7980 Don't try compacting ivars on Classes that are "too complex"
Too complex classes use a hash table to store ivs, and should always pin
their IVs.  We shouldn't touch those classes in compaction.
2023-11-20 16:09:48 -08:00
Peter Zhu ad03320743 Support declarative marked TypedData objects on VWA 2023-11-20 18:59:01 -05:00
Jean Boussier 940f2e7f18 size_pool_idx_for_size: Include debugging info in error message
We ran into that case on our CI, including some sizes would help
debug it much easier.
2023-11-17 14:22:07 +01:00
Jean Boussier f1b95095d6 Revert "Wrap rb_objspace_reachable_objects_from_root with RB_VM_LOCK"
This reverts commit 76dc327eef.
2023-11-13 08:57:57 +01:00
Jean Boussier a1887f4dc2 Revert "Fix crash caused by concurrent ObjectSpace.dump_all calls"
This reverts commit 9a62fd3cba.
2023-11-13 08:57:57 +01:00
KJ Tsanaktsidis 9a62fd3cba Fix crash caused by concurrent ObjectSpace.dump_all calls
Since the callback defined in the objspace module might give up the GVL,
we need to make sure the right cr->mfd value is set back after the GVL
is re-obtained.
2023-11-12 17:50:37 +01:00
KJ Tsanaktsidis 76dc327eef Wrap rb_objspace_reachable_objects_from_root with RB_VM_LOCK
rb_objspace_reachable_objects_from has it too, so I figure it's most
likely required for _from_root as well.
2023-11-12 17:50:37 +01:00
Nobuyoshi Nakada 1fe2bc4b22
RCLASS_EXT is never NULL now 2023-11-11 15:57:44 +09:00
Jean Boussier a9f45aac6e rb_data_free: Fix freeing embedded TypedData
The previous implementation was using the pointer given
by `DATA_PTR` in all cases. But in the case of an embedded
TypedData, that pointer is garbage, we need to use RTYPEDDATA_GET_DATA
to get the proper data pointer.

Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
2023-11-10 15:56:42 +01:00
Peter Zhu 392238e3fd Implement embedded TypedData objects
This commit adds a new flag RUBY_TYPED_EMBEDDABLE that allows the data
of a TypedData object to be embedded after the object itself. This will
improve cache locality and allow us to save the 8 byte data pointer.

Co-Authored-By: Jean Boussier <byroot@ruby-lang.org>
2023-11-07 15:48:06 -05:00
Peter Zhu 38ba040d8b Make every initial size pool shape a root shape
This commit makes every initial size pool shape a root shape and assigns
it a capacity of 0.
2023-11-02 13:42:11 -04:00
Peter Zhu 7979c009a7 Fix bug for removed weak references
rb_darray_foreach gives a pointer to the entry, so we need to deference
it to read the value.
2023-10-27 11:00:12 -04:00
Aaron Patterson a3f66e09f6 geniv objects can become too complex 2023-10-24 10:52:06 -07:00
Jean Boussier e5364ea496 rb_shape_transition_shape_capa: use optimal sizes transitions
Previously the growth was 3(embed), 6, 12, 24, ...

With this change it's now 3(embed), 8, 16, 32, 64, ... by default.

However, since power of two isn't the best size for all allocators,
if `malloc_usable_size` is vailable, we use it to discover the best
offset.

On Linux/glibc 2.35 for instance, the growth will be 3(embed), 7, 15, 31
to avoid wasting 8B per object.

Test program:

```c

size_t test(size_t slots) {
    size_t allocated = slots * VALUE_SIZE;
    void *test_ptr = malloc(allocated);
    size_t wasted = malloc_usable_size(test_ptr) - allocated;
    free(test_ptr);
    fprintf(stderr, "slots = %lu, wasted_bytes = %lu\n", slots, wasted);
    return wasted;
}

int main(int argc, char *argv[]) {
    size_t best_padding = 0;
    size_t padding = 0;
    for (padding = 0; padding <= 2; padding++) {
        size_t wasted = test(8 - padding);
        if (wasted == 0) {
            best_padding = padding;
            break;
        }
    }

    size_t index = 0;
    fprintf(stderr, "=============== naive ================\n");

    size_t list_size = 4;
    for (index = 0; index < 10; index++) {
        test(list_size);
        list_size *= 2;
    }

    fprintf(stderr, "=============== auto-padded (-%lu) ================\n", best_padding);

    list_size = 4;
    for (index = 0; index < 10; index ++) {
        test(list_size - best_padding);
        list_size *= 2;
    }

    fprintf(stderr, "\n\n");
    return 0;
}
```

```
===== glibc ======
slots = 8, wasted_bytes = 8
slots = 7, wasted_bytes = 0
=============== naive ================
slots = 4, wasted_bytes = 8
slots = 8, wasted_bytes = 8
slots = 16, wasted_bytes = 8
slots = 32, wasted_bytes = 8
slots = 64, wasted_bytes = 8
slots = 128, wasted_bytes = 8
slots = 256, wasted_bytes = 8
slots = 512, wasted_bytes = 8
slots = 1024, wasted_bytes = 8
slots = 2048, wasted_bytes = 8
=============== auto-padded (-1) ================
slots = 3, wasted_bytes = 0
slots = 7, wasted_bytes = 0
slots = 15, wasted_bytes = 0
slots = 31, wasted_bytes = 0
slots = 63, wasted_bytes = 0
slots = 127, wasted_bytes = 0
slots = 255, wasted_bytes = 0
slots = 511, wasted_bytes = 0
slots = 1023, wasted_bytes = 0
slots = 2047, wasted_bytes = 0
```

```
==========  jemalloc =======
slots = 8, wasted_bytes = 0
=============== naive ================
slots = 4, wasted_bytes = 0
slots = 8, wasted_bytes = 0
slots = 16, wasted_bytes = 0
slots = 32, wasted_bytes = 0
slots = 64, wasted_bytes = 0
slots = 128, wasted_bytes = 0
slots = 256, wasted_bytes = 0
slots = 512, wasted_bytes = 0
slots = 1024, wasted_bytes = 0
slots = 2048, wasted_bytes = 0
=============== auto-padded (-0) ================
slots = 4, wasted_bytes = 0
slots = 8, wasted_bytes = 0
slots = 16, wasted_bytes = 0
slots = 32, wasted_bytes = 0
slots = 64, wasted_bytes = 0
slots = 128, wasted_bytes = 0
slots = 256, wasted_bytes = 0
slots = 512, wasted_bytes = 0
slots = 1024, wasted_bytes = 0
slots = 2048, wasted_bytes = 0
```
2023-10-23 09:33:15 +02:00
Yusuke Endoh 833c930bd6 Remove unneeded checks
Follow up of 591336a0f2
2023-10-16 03:58:30 +09:00
Nobuyoshi Nakada a075c55d0c Manage `rb_strterm_t` without imemo 2023-10-14 11:08:43 +09:00
HParker c74dc8b4af Use reference counting to avoid memory leak in kwargs
Tracks other callinfo that references the same kwargs and frees them when all references are cleared.

[bug #19906]

Co-authored-by: Peter Zhu <peter@peterzhu.ca>
2023-10-01 10:55:19 -04:00
Nobuyoshi Nakada ac244938e8 Dump backtraces to an arbitrary stream 2023-09-25 22:57:28 +09:00
Peter Zhu f43dac0df2 Add rb_hash_free for the GC to use 2023-09-24 09:07:52 -04:00
Adam Hess 8b236e0c66 [Bug #19896]
fix memory leak in vm_method

This introduces a unified reference_count to clarify who is referencing a method.
This also allows us to treat the refinement method as the def owner since it counts itself as a reference

Co-authored-by: Peter Zhu <peter@peterzhu.ca>
2023-09-22 09:44:58 -04:00
Matt Valentine-House ec37636ab3 Only sort the heap on platforms with compaction 2023-09-18 14:34:38 +01:00
Matt Valentine-House 8792e421ce Allow pages to be sorted by pinned slot count
By compacting into slots with pinned objects first, we improve the
efficiency of compaction. As it is less likely that there will exist
pages containing only pinned objects after compaction. This will
increase the number of free pages left after compaction and enable us to
free them.

This used to be the default compaction method before it was removed
(inadvertently?) during the introduction of auto_compaction.

This commit will sort the pages by the pinned slot count at the start of
a major GC that has been triggered by explicitly calling GC.compact (and
thus setting objspace->flags.during_compaction).

It works using the same method by which we sort the heap by empty slot
count during GC.verify_compaction_references.
2023-09-18 14:34:38 +01:00
Matt Valentine-House 404a1c032a Move heap sorting into the main GC loop
Previously it was only being sorted during the verify compaction
references stage - so would only happen during testing.

This commit allows us to sort the heap prior to each explicit GC.compact
run
2023-09-18 14:34:38 +01:00
Matt Valentine-House d3852f71e4 Enable different heap sort methods during compaction
pass the sorting function in as a function pointer so we don't always
sort by how empty a page is
2023-09-18 14:34:38 +01:00
Peter Zhu 4aac7b1a9a Another try to fix build in emscripten
malloc_trim is defined in emscripten/emmalloc.h on emscripten.
2023-09-16 13:24:41 -04:00
Peter Zhu 209d5f8482 Fix malloc_trim on emscripten
```
gc.c:9746:5: error: implicit declaration of function 'malloc_trim' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    malloc_trim(0);
    ^
```

http://rubyci.s3.amazonaws.com/crossruby/crossruby-master-wasm32_emscripten/log/20230916T104311Z.fail.html.gz
2023-09-16 09:08:55 -04:00
Jean Boussier c3ef7a528b Fix malloc_trim() on wasm32
```
compiling gc.c
gc.c:9746:5: error: implicit declaration of function 'malloc_trim' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    malloc_trim(0);
    ^
1 error generated.
```
2023-09-16 09:52:46 +02:00
Adam Hess 4d86d932fd Free all heap pages at shutdown
previously heap_allocated_pages was decremented from heap_page_free causing only half the heap pages to be freed at shutdown
2023-09-15 13:24:32 -04:00
Jean Boussier efe2822708 Process.warmup: invoke `malloc_trim` if available
Similar to releasing free GC pages, releasing free malloc pages
reduce the amount of page faults post fork.
2023-09-15 17:45:21 +02:00
Peter Zhu b90272b3b6 Fix typo in gc.c 2023-09-12 11:20:22 -04:00
John Hawthorn 094f336a27 GC: Only force alloc slowpath for NEWOBJ hook
Previously, configuring any GC event hook would cause all allocations to
go through the newobj slowpath. We should only need to do that when the
newobj specifically is subscribed to.

This renames flags.has_hook to flags.has_newobj_hook, to make this new
usage clear. newobj_of0 was the only place which previously checked this
flag.
2023-09-07 13:51:56 -07:00
Peter Zhu 12102d101a Fix crash in WeakMap during compaction
WeakMap can crash during compaction because the st_insert could allocate
memory.
2023-09-06 14:20:23 -04:00
Peter Zhu 6778d2c582 Support freeing the lowest memory address page
This should help fix the following flaky test:

```
  1) Failure:
TestProcess#test_warmup_frees_pages [test/ruby/test_process.rb:2751]:
<0> expected but was
<1>.
```
2023-09-06 08:43:14 -04:00
Peter Zhu 9a8398a18f Introduce rb_gc_remove_weak
If we're during incremental marking, then Ruby code can execute that
deallocates certain memory buffers that have been called with
rb_gc_mark_weak, which can cause use-after-free bugs.
2023-09-05 14:32:15 -04:00
Peter Zhu ab9d1910ef Rename shady to uncollectible_wb_unprotected
The term "shady object" was renamed to "uncollectible write barrier
unprotected object", so rename `has_uncollectible_shady_objects` to
`has_uncollectible_wb_unprotected_objects` for consistency.
2023-09-05 10:55:23 -04:00
Peter Zhu 7a930cf0e4 Pool more slots for large size pools
We always sweep at least 2048 slots per sweep step, but only pool one
page. For large size pools, 2048 slots is many pages but one page is
very few slots. This commit changes it so that at least 1024 slots are
placed in the pooled pages per sweep step.
2023-09-05 10:52:35 -04:00
Peter Zhu ef65183692 Add check for T_NONE in rb_gc_mark_weak
This commit adds a check for T_NONE in rb_gc_mark_weak, just like
gc_mark_ptr. This will help debugging.
2023-09-05 09:27:11 -04:00
Peter Zhu bead539650 Incrementally mark even if we have free pages
We move all pooled pages to free pages at the start of incremental
marking, so we shouldn't run incremental marking only when we have run
out of free pages. This causes incremental marking to always complete
in a single step.
2023-09-01 11:58:50 -04:00
Peter Zhu 771576f021 Skip weak references to old objects in minor GC
If we are in a minor GC and the object to mark is old, then the old
object should already be marked and cannot be reclaimed in this GC cycle
so we don't need to add it to the weak refences list.
2023-09-01 09:31:59 -04:00