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

663 Коммитов

Автор SHA1 Сообщение Дата
HASUMI Hitoshi 2244c58b00 [Universal parser] Decouple IMEMO from rb_ast_t
This patch removes the `VALUE flags` member from the `rb_ast_t` structure making `rb_ast_t` no longer an IMEMO object.

## Background

We are trying to make the Ruby parser generated from parse.y a universal parser that can be used by other implementations such as mruby.
To achieve this, it is necessary to exclude VALUE and IMEMO from parse.y, AST, and NODE.

## Summary (file by file)

- `rubyparser.h`
  - Remove the `VALUE flags` member from `rb_ast_t`
- `ruby_parser.c` and `internal/ruby_parser.h`
  - Use TypedData_Make_Struct VALUE which wraps `rb_ast_t` `in ast_alloc()` so that GC can manage it
    - You can retrieve `rb_ast_t` from the VALUE by `rb_ruby_ast_data_get()`
  - Change the return type of `rb_parser_compile_XXXX()` functions from `rb_ast_t *` to `VALUE`
  - rb_ruby_ast_new() which internally `calls ast_alloc()` is to create VALUE vast outside ruby_parser.c
- `iseq.c` and `vm_core.h`
  - Amend the first parameter of `rb_iseq_new_XXXX()` functions from `rb_ast_body_t *` to `VALUE`
  - This keeps the VALUE of AST on the machine stack to prevent being removed by GC
- `ast.c`
  - Almost all change is replacement `rb_ast_t *ast` with `VALUE vast` (sorry for the big diff)
  - Fix `node_memsize()`
    - Now it includes `rb_ast_local_table_link`, `tokens` and script_lines
- `compile.c`, `load.c`, `node.c`, `parse.y`, `proc.c`, `ruby.c`, `template/prelude.c.tmpl`, `vm.c` and `vm_eval.c`
  - Follow-up due to the above changes
- `imemo.{c|h}`
  - If an object with `imemo_ast` appears, considers it a bug

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2024-04-26 11:21:08 +09:00
Nobuyoshi Nakada 58918788ab [Bug #20342] Consider wrapped load in `main` methods 2024-04-05 01:33:08 +09:00
Jean Boussier d4f3dcf4df Refactor VM root modules
This `st_table` is used to both mark and pin classes
defined from the C API. But `vm->mark_object_ary` already
does both much more efficiently.

Currently a Ruby process starts with 252 rooted classes,
which uses `7224B` in an `st_table` or `2016B` in an `RArray`.

So a baseline of 5kB saved, but since `mark_object_ary` is
preallocated with `1024` slots but only use `405` of them,
it's a net `7kB` save.

`vm->mark_object_ary` is also being refactored.

Prior to this changes, `mark_object_ary` was a regular `RArray`, but
since this allows for references to be moved, it was marked a second
time from `rb_vm_mark()` to pin these objects.

This has the detrimental effect of marking these references on every
minors even though it's a mostly append only list.

But using a custom TypedData we can save from having to mark
all the references on minor GC runs.

Addtionally, immediate values are now ignored and not appended
to `vm->mark_object_ary` as it's just wasted space.
2024-03-06 15:33:43 -05:00
Jean Boussier b4a69351ec Move FL_SINGLETON to FL_USER1
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.
2024-03-06 13:11:41 -05:00
Peter Zhu 330830dd1a Add IMEMO_NEW
Rather than exposing that an imemo has a flag and four fields, this
changes the implementation to only expose one field (the klass) and
fills the rest with 0. The type will have to fill in the values themselves.
2024-02-21 11:33:05 -05:00
Yusuke Endoh 25d74b9527 Do not include a backtick in error messages and backtraces
[Feature #16495]
2024-02-15 18:42:31 +09:00
Jean Boussier de1a586ecc proc.c: get rid of `CLONESETUP`
[Bug #20253]

All the way down to Ruby 1.9, `Proc`, `Method`, `UnboundMethod`
and `Binding` always had their own specific clone and dup routine.

This caused various discrepancies with how other objects behave
on `dup` and `clone. [Bug #20250], [Bug #20253].

This commit get rid of `CLONESETUP` and use the the same codepath
as all other types, so ensure consistency.

NB: It's still not accepting the `freeze` keyword argument on `clone`.

Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
2024-02-12 18:31:48 +01:00
Nobuyoshi Nakada 361b3efe16
Use `UNDEF_P` 2024-01-30 14:48:59 +09:00
Alan Wu 9f77eb1f5a Remove unused macros 2023-12-12 17:24:17 -05:00
Peter Zhu ed25f0bd5a Make env_clone compaction safe
The original order of events is:

1. Allocate new_body.
2. Peform memcpy into new_body.
3. Create new_env using new_body.

However, if GC compaction runs during step 3, then new_env would not
have yet been created and objects on new_body could move but it would
not be reference updated.

This commit changes the order of the last two events.
2023-12-05 08:42:25 -05:00
Jean Boussier b4f551686b Get rid of useless dsize functions
If we always return 0, we might as well not define
the function at all.
2023-11-21 15:15:03 +01:00
Jean Boussier ffb1eb37e7 proc.c: Make Method and UnboundMethod embded
Avoid some needless malloc churn

```
compare-ruby: ruby 3.3.0dev (2023-11-20T02:02:55Z master 701b0650de) [arm64-darwin22]
last_commit=[ruby/prism] feat: add encoding for IBM865 (https://github.com/ruby/prism/pull/1884)
built-ruby: ruby 3.3.0dev (2023-11-20T16:23:07Z embedded-methods e35284bfaa) [arm64-darwin22]
warming up..

|                         |compare-ruby|built-ruby|
|:------------------------|-----------:|---------:|
|allocate_method          |      8.413M|   12.333M|
|                         |           -|     1.47x|
|allocate_unbound_method  |      8.083M|   11.607M|
|                         |           -|     1.44x|
```

```
prelude: |
  class SomeClass
    def foo
    end
  end
  some_object = SomeClass.new
benchmark:
  allocate_method: some_object.method(:foo)
  allocate_unbound_method: SomeClass.instance_method(:foo)
```
2023-11-20 18:04:13 +01:00
Nobuyoshi Nakada 1507118f0b [Feature #19362] Call `#initialize_dup` hook at `Proc#dup` 2023-10-26 17:28:50 +09:00
Alan Wu 39ee3e22bd Make Kernel#lambda raise when given non-literal block
Previously, Kernel#lambda returned a non-lambda proc when given a
non-literal block and issued a warning under the `:deprecated` category.
With this change, Kernel#lambda will always return a lambda proc, if it
returns without raising.

Due to interactions with block passing optimizations, we previously had
two separate code paths for detecting whether Kernel#lambda got a
literal block. This change allows us to remove one path, the hack done
with rb_control_frame_t::block_code introduced in 85a337f for supporting
situations where Kernel#lambda returned a non-lambda proc.

[Feature #19777]

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-09-12 11:25:07 -04:00
Jeremy Evans 786a864900 Make {Nil,True,False}Class#singleton_method always raise NameError
{Nil,True,False}Class#singleton_methods always returns [] indicating
that there are no singleton methods defined, so #singleton_method
should be consistent with that.

Fixes [Bug #11064]
2023-07-26 07:27:15 -07:00
Alan Wu 5c219c1b7f proc.c: Remove unused parameter [ci skip] 2023-07-20 10:53:31 -04:00
Matt Valentine-House d426343418 Store object age in a bitmap
Closes [Feature #19729]

Previously 2 bits of the flags on each RVALUE are reserved to store the
number of GC cycles that each object has survived. This commit
introduces a new bit array on the heap page, called age_bits, to store
that information instead.

This patch still reserves one of the age bits in the flags (the old
FL_PROMOTED0 bit, now renamed FL_PROMOTED).

This is set to 0 for young objects and 1 for old objects, and is used as
a performance optimisation for the write barrier. Fetching the age_bits
from the heap page and doing the required math to calculate if the
object was old or not would slow down the write barrier. So we keep this
bit synced in the flags for fast access.
2023-07-13 09:21:36 +01:00
Takashi Kokubun 233ddfac54 Stop exporting symbols for MJIT 2023-03-06 21:59:23 -08:00
zverok 0258e92e43 [DOC] Improve Kernel#binding docs
* Add links to Binding class
* Make examples practical
* Extend possible usages description
2023-02-19 22:32:52 +02:00
Jean Boussier 7413079dae Encapsulate RCLASS_ATTACHED_OBJECT
Right now the attached object is stored as an instance variable
and all the call sites that either get or set it have to know how it's
stored.

It's preferable to hide this implementation detail behind accessors
so that it is easier to change how it's stored.
2023-02-15 15:24:22 +01:00
Koichi Sasada be94808282 use correct svar even if env is escaped
This patch is follo-up of 0a82bfe.
Without this patch, if env is escaped (Proc'ed), strange svar
can be touched.

This patch tracks escaped env and use it.
2023-02-10 17:55:25 +09:00
Matt Valentine-House 72aba64fff Merge gc.h and internal/gc.h
[Feature #19425]
2023-02-09 10:32:29 -05:00
Peter Zhu 046807102f Use rb_gc_mark_and_move for method objects 2023-02-07 08:39:48 -05:00
Peter Zhu df2e36aeeb Use rb_gc_mark_and_move for proc and binding
Also makes VM_ENV_ENVVAL movable.
2023-02-07 08:39:48 -05:00
Jean Boussier a8000d06cc Mark "method" objects as protected by write barrier
All its reference are set with RB_OBJ_WRITE, so they
can be marked as WB protected.
2023-02-03 23:31:23 +01:00
Koichi Sasada 0a82bfe5e1
use correct svar (#7225)
* use correct svar

Without this patch, svar location is used "nearest Ruby frame".
It is almost correct but it doesn't correct when the `each` method
is written in Ruby.

```ruby
class C
  include Enumerable
  def each
    %w(bar baz).each{|e| yield e}
  end
end

C.new.grep(/(b.)/){|e| p [$1, e]}
```

This patch fix this issue by traversing ifunc's cfp.

Note that if cfp doesn't specify this Thread's cfp stack, reserved
svar location (`ec->root_svar`) is used.

* make yjit-bindgen

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-02-01 16:13:19 -08:00
zverok 64cdf1936a Docs: Separate documentation for UnboundMethod#== 2022-12-23 18:09:49 +02:00
Koichi Sasada 59e389af28 UnboundMethod only refer defined_class
UnboundMethod records caller's class, like `D` or `E` on the
following case:

```ruby
class C
  def foo = :foo
end

class D < C
end

class E < C
end

d = D.instance_method(:foo)
e = E.instance_method(:foo)
```

But `d` and `e` only refers `C#foo` so that UnboundMethod doesn't
record `D` or `E`. This behavior changes the following methods:

* `UnboundMethod#inspect` (doesn't show caller's class)
* `UnboundMethod#==` (`d == e` for example)

fix https://bugs.ruby-lang.org/issues/18798
2022-12-03 08:53:12 +09:00
S-H-GAMELINKS 1f4f6c9832 Using UNDEF_P macro 2022-11-16 18:58:33 +09:00
Peter Zhu 93f364d65e Use RTEST to to check return value
rb_obj_is_kind_of returns a Ruby Qtrue or Qfalse. We should use RTEST
rather than assuming that Qfalse is 0.
2022-11-04 09:02:58 -04:00
Alexander Momchilov 76a6c5d6d1 Remove unnecessary branch in `UnboundMethod#bind`
Co-authored-by: Michael Herold <michael.herold@shopify.com>
2022-11-04 08:57:01 -04:00
Benoit Daloze b91f685a26 Mark struct METHOD->owner for the GC
* Fixes https://github.com/ruby/ruby/commit/6b7d32a5e5
* See [Bug #18729]
2022-10-03 12:03:46 +02:00
Benoit Daloze aa490f9442 Reduce diff to proc.c @ b0b9f7201a
* So it's easy to review https://github.com/ruby/ruby/pull/6242 +
  https://github.com/ruby/ruby/pull/6467 and there are less changes
  overall.
2022-09-29 15:48:35 +02:00
Benoit Daloze 6b7d32a5e5 Resolve zsuper method during lookup but preserve owner separately
* See https://bugs.ruby-lang.org/issues/18729#note-34
* See [Bug #18729]
2022-09-29 15:48:35 +02:00
Benoit Daloze 94cea3e4d0 Fix {Method,UnboundMethod}#super_method for zsuper methods
* We need to resolve the zsuper method first, and then look the super
  method of that.
2022-09-29 15:48:35 +02:00
Samuel Williams 22af2e9084 Rework vm_core to use `int first_lineno` struct member. 2022-09-26 00:41:16 +13:00
S-H-GAMELINKS 205c252ec7 Reuse rb_method_call_kw function 2022-09-25 11:11:06 +13:00
Nobuyoshi Nakada 92d2476208
Adjust styles [ci skip] 2022-09-02 14:49:42 +09:00
Benoit Daloze 209631a45f Consider resolved-through-zsuper methods equal for compatibility
* Fixes https://bugs.ruby-lang.org/issues/18751
2022-08-20 13:44:00 +02:00
Jeremy Evans 8212aab81a Make Object#method and Module#instance_method not skip ZSUPER methods
Based on c95e7e5329

Among other things, this fixes calling visibility methods (public?,
protected?, and private?) on them.  It also fixes #owner to show the
class the zsuper method entry is defined in, instead of the original
class it references.

For some backwards compatibility, adjust #parameters and #source_location,
to show the parameters and source location of the method originally
defined. Also have the parameters and source location still be shown
by #inspect.

Clarify documentation of {Method,UnboundMethod}#owner.

Add tests based on the description of https://bugs.ruby-lang.org/issues/18435
and based on https://github.com/ruby/ruby/pull/5356#issuecomment-1005298809

Fixes [Bug #18435] [Bug #18729]

Co-authored-by: Benoit Daloze <eregontp@gmail.com>
2022-08-20 13:44:00 +02:00
Penelope Phippen e49db0f760 Do not clone method entries when bind_call is used
I noticed that this site unconditionally clones the method entry, which
means that `bind_call` always allocates a `T_IMEMO`. While this clone
is necessary for `bind`, it is not necessary for `bind_call`.

I work at Stripe, and the sorbet_runtime gem uses bind call as part
of it's [call validation](https://github.com/sorbet/sorbet/blob/master/gems/sorbet-runtime/lib/types/private/methods/call_validation.rb#L157)
so this can save us a lot of allocations.

This patch adds a `clone` parameter to `convert_umethod_to_method_components`,
which then controls whether or not we do this cloning. This patch passed
Stripe CI and works in our QA environment. I reviewed it with @tenderlove
to talk about correctness also.
2022-08-15 15:41:35 -07:00
Jeremy Evans ff42e2359b Revert "Add {Method,UnboundMethod}#{public?,private?,protected?}"
This reverts commit 2727815068 and
58dc8bf8f1.

Visibility is an attribute of the method entry in a class, not an
attribute of the Method object.

Fixes [#18729]
Fixes [#18751]
Fixes [#18435]
2022-08-10 13:02:52 -07:00
Peter Zhu efb91ff19b Rename rb_ary_tmp_new to rb_ary_hidden_new
rb_ary_tmp_new suggests that the array is temporary in some way, but
that's not true, it just creates an array that's hidden and not on the
transient heap. This commit renames it to rb_ary_hidden_new.
2022-07-26 09:12:09 -04:00
Takashi Kokubun 5b21e94beb Expand tabs [ci skip]
[Misc #18891]
2022-07-21 09:42:04 -07:00
S.H 554befbf27
Reuse `rb_proc_arity` 2022-04-24 14:06:45 -07:00
Nobuyoshi Nakada 5d45afdbbf
[DOC] Move the documentations of moved Symbol methods 2022-04-14 11:17:37 +09:00
Kazuhiro NISHIYAMA 8da0b68a62
Fix a typo [ci skip] 2022-04-06 11:59:35 +09:00
Jeremy Evans 173a6b6a80 Make define_singleton_method always define a public method
In very unlikely cases, it could previously define a non-public method
starting in Ruby 2.1.

Fixes [Bug #18561]
2022-03-29 12:10:13 -07:00
Peter Zhu 5f10bd634f Add ISEQ_BODY macro
Use ISEQ_BODY macro to get the rb_iseq_constant_body of the ISeq. Using
this macro will make it easier for us to change the allocation strategy
of rb_iseq_constant_body when using Variable Width Allocation.
2022-03-24 10:03:51 -04:00
Jeremy Evans 634e0a97eb Encourage arity argument in Proc#curry documentation for procs with variable arguments
This uses similar language to that used in Method#curry.
2022-03-17 20:34:13 -07:00