summaryrefslogtreecommitdiff
path: root/ext/objspace/objspace_dump.c
AgeCommit message (Collapse)Author
2025-03-13Move object_id to flags for ObjectSpace dumpsPeter Zhu
Moving object_id dumping from ObjectSpace to the GC flags allows ObjectSpace to not assume the FL_SEEN_OBJ_ID flag and instead move it to the responsibility of the GC. Notes: Merged: https://github.com/ruby/ruby/pull/12915
2025-02-19Add rb_gc_object_metadata APIPeter Zhu
This function replaces the internal rb_obj_gc_flags API. rb_gc_object_metadata returns an array of name and value pairs, with the last element having 0 for the name. Notes: Merged: https://github.com/ruby/ruby/pull/12777
2025-01-30Output object_id in ObjectSpace.dumpPeter Zhu
Outputs the object ID in the dump for objects that have it seen. Notes: Merged: https://github.com/ruby/ruby/pull/12657
2024-12-19Prefix asan_poison_object with rbPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/12385
2024-12-09objspace_dump: Use FILE* to avoid crashing in mark functionsAlan Wu
We observed crashes from rb_io_bufwrite() thread switching (through rb_thread_check_ints()) in the middle of rb_execution_context_mark(). By the time rb_execution_context_mark() gets a timeslice again, it read garbage from a frame that was already popped in another thread, crashing the process in SEGV. Other mark functions probably have their own ways of breaking, but clearly, the usual IO code do too much for this perilous pseudo GC context. Use `FILE*` like before 5001cc47169614ea07d87651c95c2ee185e374e0 ("Optimize ObjectSpace.dump_all"). Also, add type checking for the private _dump methods. Co-authored-by: Peter Zhu <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/12285
2024-11-12ObjectSpace.dump: handle Module#set_temporary_nameJean Boussier
[Bug #20892] Until the introduction of that method, it was impossible for a Module name not to be valid JSON, hence it wasn't going through the slower escaping function. This assumption no longer hold. Notes: Merged: https://github.com/ruby/ruby/pull/12067
2024-03-19Implement chilled stringsÉtienne Barrié
[Feature #20205] As a path toward enabling frozen string literals by default in the future, this commit introduce "chilled strings". From a user perspective chilled strings pretend to be frozen, but on the first attempt to mutate them, they lose their frozen status and emit a warning rather than to raise a `FrozenError`. Implementation wise, `rb_compile_option_struct.frozen_string_literal` is no longer a boolean but a tri-state of `enabled/disabled/unset`. When code is compiled with frozen string literals neither explictly enabled or disabled, string literals are compiled with a new `putchilledstring` instruction. This instruction is identical to `putstring` except it marks the String with the `STR_CHILLED (FL_USER3)` and `FL_FREEZE` flags. Chilled strings have the `FL_FREEZE` flag as to minimize the need to check for chilled strings across the codebase, and to improve compatibility with C extensions. Notes: - `String#freeze`: clears the chilled flag. - `String#-@`: acts as if the string was mutable. - `String#+@`: acts as if the string was mutable. - `String#clone`: copies the chilled flag. Co-authored-by: Jean Boussier <[email protected]>
2024-03-06Move FL_SINGLETON to FL_USER1Jean Boussier
This frees FL_USER0 on both T_MODULE and T_CLASS. Note: prior to this, FL_SINGLETON was never set on T_MODULE, so checking for `FL_SINGLETON` without first checking that `FL_TYPE` was `T_CLASS` was valid. That's no longer the case.
2023-11-22objspace_dump.c: dump call cache ids with dump_append_idJean Boussier
Not all `ID` have an associated string. Fixes a SEGFAULT in ObjectSpace.dump_all spec.
2023-11-13Revert "Revert "Remove SHAPE_CAPACITY_CHANGE shapes""Peter Zhu
This reverts commit 5f3fb4f4e397735783743fe52a7899b614bece20.
2023-11-13Record more info from CALLCACHE in heap dumpsJohn Hawthorn
This records the called_id and klass from imemo_callcache objects in heap dumps.
2023-11-10Revert "Remove SHAPE_CAPACITY_CHANGE shapes"Peter Zhu
This reverts commit f6910a61122931e4193bcc0fad18d839c319b720. We're seeing crashes in the test suite of Shopify's core monolith after this change.
2023-11-09Remove SHAPE_CAPACITY_CHANGE shapesPeter Zhu
We don't need to create a shape to transition capacity as we can transition the capacity when the capacity of the SHAPE_IVAR changes.
2023-11-02Make every initial size pool shape a root shapePeter Zhu
This commit makes every initial size pool shape a root shape and assigns it a capacity of 0.
2023-10-12Switch mid dump to dump_append_string_valueJohn Hawthorn
I don't think it's possible to create a CI with a mid which would need escaping to be in a JSON string, but I think we might as well not rely on that assumption.
2023-10-12Fix ObjectSpace.dump with super() callinfoJohn Hawthorn
super() uses 0 as mid for its callinfo, so we need to check for that to avoid a segfault when using dump_all.
2023-10-02Dump name of method for imemo callinfoPeter Zhu
This commit dumps the `mid` of the imemo callinfo when calling `ObjectSpace.dump_all`.
2023-06-08Add deprecations for public `struct rb_io` members. (#7916)Samuel Williams
* Add deprecations for public struct rb_io members. Notes: Merged-By: ioquatix <[email protected]>
2023-06-01Revert "Hide most of the implementation of `struct rb_io`. (#6511)"NARUSE, Yui
This reverts commit 18e55fc1e1ec20e8f3166e3059e76c885fc9f8f2. fix [Bug #19704] https://bugs.ruby-lang.org/issues/19704 This breaks compatibility for extension libraries. Such changes need a discussion.
2023-05-30Hide most of the implementation of `struct rb_io`. (#6511)Samuel Williams
* Add rb_io_path and rb_io_open_descriptor. * Use rb_io_open_descriptor to create PTY objects * Rename FMODE_PREP -> FMODE_EXTERNAL and expose it FMODE_PREP I believe refers to the concept of a "pre-prepared" file, but FMODE_EXTERNAL is clearer about what the file descriptor represents and aligns with language in the IO::Buffer module. * Ensure that rb_io_open_descriptor closes the FD if it fails If FMODE_EXTERNAL is not set, then it's guaranteed that Ruby will be responsible for closing your file, eventually, if you pass it to rb_io_open_descriptor, even if it raises an exception. * Rename IS_EXTERNAL_FD -> RUBY_IO_EXTERNAL_P * Expose `rb_io_closed_p`. * Add `rb_io_mode` to get IO mode. --------- Co-authored-by: KJ Tsanaktsidis <[email protected]> Notes: Merged-By: ioquatix <[email protected]>
2023-02-09Merge gc.h and internal/gc.hMatt Valentine-House
[Feature #19425] Notes: Merged: https://github.com/ruby/ruby/pull/7273
2023-01-05Add embedded status to dumps of T_OBJECTPeter Zhu
This commit adds `"embedded":true` in ObjectSpace.dump for T_OBJECTs that are embedded. Notes: Merged: https://github.com/ruby/ruby/pull/7068
2022-12-15Indicate if a shape is too_complex in ObjectSpace#dumpJemma Issroff
Notes: Merged: https://github.com/ruby/ruby/pull/6939
2022-12-15Transition complex objects to "too complex" shapeJemma Issroff
When an object becomes "too complex" (in other words it has too many variations in the shape tree), we transition it to use a "too complex" shape and use a hash for storing instance variables. Without this patch, there were rare cases where shape tree growth could "explode" and cause performance degradation on what would otherwise have been cached fast paths. This patch puts a limit on shape tree growth, and gracefully degrades in the rare case where there could be a factorial growth in the shape tree. For example: ```ruby class NG; end HUGE_NUMBER.times do NG.new.instance_variable_set(:"@unique_ivar_#{_1}", 1) end ``` We consider objects to be "too complex" when the object's class has more than SHAPE_MAX_VARIATIONS (currently 8) leaf nodes in the shape tree and the object introduces a new variation (a new leaf node) associated with that class. For example, new variations on instances of the following class would be considered "too complex" because those instances create more than 8 leaves in the shape tree: ```ruby class Foo; end 9.times { Foo.new.instance_variable_set(":@uniq_#{_1}", 1) } ``` However, the following class is *not* too complex because it only has one leaf in the shape tree: ```ruby class Foo def initialize @a = @b = @c = @d = @e = @f = @g = @h = @i = nil end end 9.times { Foo.new } `` This case is rare, so we don't expect this change to impact performance of most applications, but it needs to be handled. Co-Authored-By: Aaron Patterson <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/6931
2022-12-15Add variation_count on classesJemma Issroff
Count how many "variations" each class creates. A "variation" is a a unique ordering of instance variables on a particular class. This can also be thought of as a branch in the shape tree. For example, the following Foo class will have 2 variations: ```ruby class Foo ; end Foo.new.instance_variable_set(:@a, 1) # case 1: creates one variation Foo.new.instance_variable_set(:@b, 1) # case 2: creates another variation foo = Foo.new foo.instance_variable_set(:@a, 1) # does not create a new variation foo.instance_variable_set(:@b, 1) # does not create a new variation (a continuation of the variation in case 1) ``` We will use this number to limit the amount of shapes that a class can create and fallback to using a hash iv lookup. Co-Authored-By: Aaron Patterson <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/6931
2022-12-14objspace_dump.c: don't dump class of T_IMEMOJean Boussier
They don't actually have a class. Notes: Merged: https://github.com/ruby/ruby/pull/6925
2022-12-12[DOC] Don't document private methods in objspacePeter Zhu
2022-12-09objspace_dump.c: dump the capacity field for INITIAL_CAPACITY shapesJean Boussier
We forgot about that one, it's quite useful to see which capacity we started from. Notes: Merged: https://github.com/ruby/ruby/pull/6891
2022-12-08ObjectSpace.dump_all: dump shapes as wellJean Boussier
I see several arguments in doing so. First they use a non trivial amount of memory, so for various memory profiling/mapping tools it is relevant to have visibility of the space occupied by shapes. Then, some pathological code can create a tons of shape, so it is valuable to have a way to have a way to observe shapes without having to compile Ruby with `SHAPE_DEBUG=1`. And additionally it's likely much faster to dump then this way than to use `RubyVM::Shape`. There are however a few open questions: - Shapes can't respect the `since:` argument. Not sure what to do when it is provided. Would probably make sense to not dump them. - Maybe it would make more sense to have a separate `ObjectSpace.dump_shapes`? - Maybe instead `dump_all` should take a `shapes: false` argument? Additionally, `ObjectSpace.dump_shapes` is added for the use case of debugging the evolution of the shape tree. Notes: Merged: https://github.com/ruby/ruby/pull/6868
2022-12-05Add shape_id to heap dumpJemma Issroff
Notes: Merged: https://github.com/ruby/ruby/pull/6864
2022-11-10Remove numiv from RObjectJemma Issroff
Since object shapes store the capacity of an object, we no longer need the numiv field on RObjects. This gives us one extra slot which we can use to give embedded objects one more instance variable (for a total of 3 ivs). This commit removes the concept of numiv from RObject. Notes: Merged: https://github.com/ruby/ruby/pull/6699
2022-11-02Use shared flags of the typePeter Zhu
The ELTS_SHARED flag is generic, so we should prefer to use the flags specific of the type (STR_SHARED for strings and RARRAY_SHARED_FLAG for arrays).
2022-07-22Adjust indents [ci skip]Nobuyoshi Nakada
2022-07-22Get rid of magic numbersNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6166
2022-07-22Dump non-ASCII char as unsignedNobuyoshi Nakada
Non-ASCII code may be negative on platforms plain char is signed. Notes: Merged: https://github.com/ruby/ruby/pull/6166
2022-07-21Revert "objspace_dump.c: skip dumping method name if not pure ASCII"Jean byroot Boussier
This reverts commit 79406e3600862bbb6dcdd7c5ef8de1978e6f916c. Notes: Merged: https://github.com/ruby/ruby/pull/6165
2022-07-21objspace_dump.c: skip dumping method name if not pure ASCIIJean Boussier
Sidekiq has a method named `❨╯°□°❩╯︵┻━┻`which corrupts heap dumps. Normally we could just dump is as is since it's valid UTF-8 and need no escaping. But our code to escape control characters isn't UTF-8 aware so it's more complicated than it seems. Ultimately since the overwhelming majority of method names are pure ASCII, it's not a big loss to just skip it. Notes: Merged: https://github.com/ruby/ruby/pull/6161
2022-07-21Expand tabs [ci skip]Takashi Kokubun
[Misc #18891] Notes: Merged: https://github.com/ruby/ruby/pull/6094
2022-07-05Local functions should be `static`Nobuyoshi Nakada
2022-07-04ObjectSpace.dump: Include string coderangeJean Boussier
I suspect that some shared pages are invalidated because some static string don't have their coderange set eagerly. So the first time they are scanned, the entire memory page is invalidated. Being able to see the coderange in `ObjectSpace` would help debug this. And in addition `dump` currently call `is_broken_string()` and `is_ascii_string()` which both end up scanning the string and assigning coderange. I think it's undesirable as `dump` should be read only. Notes: Merged: https://github.com/ruby/ruby/pull/6076
2022-03-01Show embed status of array when len is 0 in objspace dumpPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/5609
2022-02-03Add the size pool slot size to the output of ObjectSpace.dump/dump_allMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/5520
2021-04-26Fix compiler warnings in objspace_dump.c when assertions are turned onPeter Zhu
Example: ``` In file included from ../../../include/ruby/defines.h:72, from ../../../include/ruby/ruby.h:23, from ../../../gc.h:3, from ../../../ext/objspace/objspace_dump.c:15: ../../../ext/objspace/objspace_dump.c: In function ‘dump_append_ld’: ../../../ext/objspace/objspace_dump.c:95:26: warning: comparison of integer expressions of different signedness: ‘long unsigned int’ and ‘int’ [-Wsign-compare] 95 | RUBY_ASSERT(required <= width); | ^~ ``` Notes: Merged: https://github.com/ruby/ruby/pull/4417
2021-02-04objspace_dump.c: tag singleton classes and reference the superclassJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/4104
2021-01-20objspace_dump.c: Handle allocation path and line missingJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/4078
2020-09-28Make ext/objspace ASAN friendlyAaron Patterson
ext/objspace iterates over the heap, but some slots in the heap are poisoned, so we need to take care of that when running with ASAN Notes: Merged: https://github.com/ruby/ruby/pull/3592
2020-09-15Parse ObjectSpace.dump_all / dump arguments in Ruby to avoid allocation noiseJean Boussier
[Feature #17045] ObjectSpace.dump_all should allocate as little as possible in the GC heap Up until this commit ObjectSpace.dump_all allocates two Hash because of `rb_scan_args`. It also can allocate a `File` because of `rb_io_get_write_io`. These allocations are problematic because `dump_all` dumps the Ruby heap, so it should try modify as little as possible what it is observing. Notes: Merged: https://github.com/ruby/ruby/pull/3530
2020-09-11Add missing breakKazuhiro NISHIYAMA
pointed out by Coverity Scan
2020-09-09Optimize ObjectSpace.dump_allJean Boussier
The two main optimization are: - buffer writes for improved performance - avoid formatting functions when possible ``` | |compare-ruby|built-ruby| |:------------------|-----------:|---------:| |dump_all_string | 1.038| 195.925| | | -| 188.77x| |dump_all_file | 33.453| 139.645| | | -| 4.17x| |dump_all_dev_null | 44.030| 278.552| | | -| 6.33x| ``` Notes: Merged: https://github.com/ruby/ruby/pull/3420
2020-09-09Add a :since option to dump_allJean Boussier
This is useful to see what a block of code allocated, e.g. ``` GC.start GC.disable ObjectSpace.trace_object_allocations do # run some code end gc_gen = GC.count allocations = ObjectSpace.dump_all(output: :file, since: gc_gen) GC.enable GC.start retentions = ObjectSpace.dump_all(output: :file, since: gc_gen) ``` Notes: Merged: https://github.com/ruby/ruby/pull/3368