* 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]
autoload_reset() can read this state.result. Because autoload_reset
is a function passed to rb_ensure, there is a chance when an
execption raises before actually filling this memory region.
test/ruby/test_defined.rb:test_autoload_noload is one of such case.
Found using memory sanitizer.
==54014==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x557a683f3e5a in autoload_reset variable.c:2372:9
#1 0x557a6707a93b in rb_ensure eval.c:1084:5
#2 0x557a683efbf5 in rb_autoload_load variable.c:2475:14
#3 0x557a685fc460 in vm_get_ev_const vm_insnhelper.c:938:4
#4 0x557a68448e0a in vm_exec_core insns.def:267:11
For some reason symbols (or classes) are being overridden in trunk
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67598 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit adds the new method `GC.compact` and compacting GC support.
Please see this issue for caveats:
https://bugs.ruby-lang.org/issues/15626
[Feature #15626]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67576 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Because hard to specify commits related to r67479 only.
So please commit again.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67499 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit adds the new method `GC.compact` and compacting GC support.
Please see this issue for caveats:
https://bugs.ruby-lang.org/issues/15626
[Feature #15626]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67479 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Especially over checking argc then calling rb_scan_args just to
raise an ArgumentError.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66238 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (obj_ivar_set): remove '//' style comments pointed out by the
following build log: https://travis-ci.org/ruby/ruby/jobs/448551951
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c: now instance variable space has theap supports.
obj_ivar_heap_alloc() tries to acquire memory from theap.
* debug_counter.h: add some counters for theap.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65451 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c: now instance variable space has theap supports.
obj_ivar_heap_alloc() tries to acquire memory from theap.
* debug_counter.h: add some counters for theap.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65446 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
An instruction is leaf if it has no rb_funcall inside. In order to
check this property, we introduce stack canary which is a random
number collected at runtime. Stack top is always filled with this
number and checked for stack smashing operations, when VM_CHECK_MODE.
[GH-1947]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64677 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Just refactoring. Despite its name, the function does NOT return a
boolean but raises an exception when the class given is frozen.
I don't think the new name "rb_class_modify_check" is the best, but
it follows the precedeint "rb_ary_modify_check", and is definitely
better than "*_p".
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64078 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* include/ruby/ruby.h (UNREACHABLE_RETURN): UNREACHABLE at the end
of non-void functions.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64025 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
It should be described that the string argument will be accept like Object#instance_variable_get.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63966 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_const_search): call #const_missing method on
private constants, as well as uninitialized constants.
[Feature #14328]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63871 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_const_search): fix NameError :receiver attribute
on private constant, should raise with the included module, not
the ICLASS.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63696 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We need to ensure autoload declarations pointing to the same
feature (aka "file") can wait on each other to avoid deadlock
situations.
So, reorganize autoload data structures to maintain a
feature => autoload_data_i mapping, and have module constant
tables point to the new autoload_const struct instead of
directly to autoload_data_i. This allows multiple
autoload_const structs to refer to the SAME autoload_data_i
struct, and with it, the on-stack autoload_state.waitq.
The end result is different constants can share the same waitq
(tied to the feature name), and not deadlock each other during
loading.
Thanks to Eugene Kenny for the bug report and reproducible test case.
Reported-by: Eugene Kenny <elkenny@gmail.com>
* variable.c (autoload_featuremap): new global
(struct autoload_const): new per-const struct
(struct autoload_state): reference autoload_const instead of autoload_data_i
(struct autoload_data_i): remove per-const
(autoload_i_mark): delete from autoload_featuremap if unreferenced
(autoload_c_mark): new dmark callback
(autoload_c_free): new dfree callback
(autoload_c_memsize): new memsize callback
(autoload_const_type): new data type
(get_autoload_data): set autoload_const as well
(rb_autoload_str): use new data structures
(autoload_delete): cleanup from autoload_featuremap
(check_autoload_required): adjust for new internals
(rb_autoloading_value): ditto
(struct autoload_const_set_args): remove, redundant with autoload_const
(const_tbl_update): adjust for new internals
(autoload_const_set): ditto
(autoload_require): ditto
(autoload_reset): ditto
(rb_autoload_load): ditto
(rb_const_set): ditto
(current_autoload_data): ditto
(set_const_visibility): ditto
* test/ruby/test_autoload.rb (test_autoload_same_file): new test
(test_no_leak): new test
[ruby-core:86935] [Bug #14742]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63392 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
I can't reproduce the problem on my 32-bit machine, and I have
connectivity problems to my 64-bit systems at the moment.
Will revisit in a few hours hopefully.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63390 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We must not call normal Hash methods inside GC free callback,
either, however identity hash may be used.
[ruby-core:86935] [Bug #14742]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63389 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We need to ensure autoload declarations pointing to the same
feature (aka "file") can wait on each other to avoid deadlock
situations.
So, reorganize autoload data structures to maintain a
feature => autoload_data_i mapping, and have module constant
tables point to the new autoload_const struct instead of
directly to autoload_data_i. This allows multiple
autoload_const structs to refer to the SAME autoload_data_i
struct, and with it, the on-stack autoload_state.waitq.
The end result is different constants can share the same waitq
(tied to the feature name), and not deadlock each other during
loading.
Thanks to Eugene Kenny for the bug report and reproducible test case.
Reported-by: Eugene Kenny <elkenny@gmail.com>
* variable.c (autoload_featuremap): new global
(struct autoload_const): new per-const struct
(struct autoload_state): reference autoload_const instead of autoload_data_i
(struct autoload_data_i): remove per-const
(autoload_i_mark): delete from autoload_featuremap if unreferenced
(autoload_c_mark): new dmark callback
(autoload_c_free): new dfree callback
(autoload_c_memsize): new memsize callback
(autoload_const_type): new data type
(get_autoload_data): set autoload_const as well
(rb_autoload_str): use new data structures
(autoload_delete): cleanup from autoload_featuremap
(check_autoload_required): adjust for new internals
(rb_autoloading_value): ditto
(struct autoload_const_set_args): remove, redundant with autoload_const
(const_tbl_update): adjust for new internals
(autoload_const_set): ditto
(autoload_require): ditto
(autoload_reset): ditto
(rb_autoload_load): ditto
(rb_const_set): ditto
(current_autoload_data): ditto
(set_const_visibility): ditto
* test/ruby/test_autoload.rb (test_autoload_same_file): new test
[ruby-core:86935] [Bug #14742]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63387 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This is fairly non-intrusive bugfix to prevent children
from trying to reach into thread stacks of the parent.
I will probably reuse this idea and redo r62934, too
(same bug).
* vm_core.h (typedef struct rb_vm_struct): add fork_gen counter
* thread.c (rb_thread_atfork_internal): increment fork_gen
* variable.c (struct autoload_data_i): store fork_gen
* variable.c (check_autoload_data): remove (replaced with get_...)
* variable.c (get_autoload_data): check fork_gen when retrieving
* variable.c (check_autoload_required): use get_autoload_data
* variable.c (rb_autoloading_value): ditto
* variable.c (rb_autoload_p): ditto
* variable.c (current_autoload_data): ditto
* variable.c (autoload_reset): reset fork_gen, adjust indent
* variable.c (rb_autoload_load): set fork_gen when setting state
* test/ruby/test_autoload.rb (test_autoload_fork): new test
[ruby-core:86410] [Bug #14634]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63210 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (const_tbl_update): flags by deprecate_constant /
private_constant set during autoloading should be preserved
after required. [ruby-core:85516] [Bug #14469]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62395 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
check the declaration of `rb_autoloading_value()` in vm_core.h and the call in
vm_insnhelper.c, and retry it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62393 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (const_tbl_update): flags by deprecate_constant /
private_constant set during autoloading should be preserved
after required. [ruby-core:85516] [Bug #14469]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62392 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
which has been developed by Takashi Kokubun <takashikkbn@gmail> as
YARV-MJIT. Many of its bugs are fixed by wanabe <s.wanabe@gmail.com>.
This JIT compiler is designed to be a safe migration path to introduce
JIT compiler to MRI. So this commit does not include any bytecode
changes or dynamic instruction modifications, which are done in original
MJIT.
This commit even strips off some aggressive optimizations from
YARV-MJIT, and thus it's slower than YARV-MJIT too. But it's still
fairly faster than Ruby 2.5 in some benchmarks (attached below).
Note that this JIT compiler passes `make test`, `make test-all`, `make
test-spec` without JIT, and even with JIT. Not only it's perfectly safe
with JIT disabled because it does not replace VM instructions unlike
MJIT, but also with JIT enabled it stably runs Ruby applications
including Rails applications.
I'm expecting this version as just "initial" JIT compiler. I have many
optimization ideas which are skipped for initial merging, and you may
easily replace this JIT compiler with a faster one by just replacing
mjit_compile.c. `mjit_compile` interface is designed for the purpose.
common.mk: update dependencies for mjit_compile.c.
internal.h: declare `rb_vm_insn_addr2insn` for MJIT.
vm.c: exclude some definitions if `-DMJIT_HEADER` is provided to
compiler. This avoids to include some functions which take a long time
to compile, e.g. vm_exec_core. Some of the purpose is achieved in
transform_mjit_header.rb (see `IGNORED_FUNCTIONS`) but others are
manually resolved for now. Load mjit_helper.h for MJIT header.
mjit_helper.h: New. This is a file used only by JIT-ed code. I'll
refactor `mjit_call_cfunc` later.
vm_eval.c: add some #ifdef switches to skip compiling some functions
like Init_vm_eval.
win32/mkexports.rb: export thread/ec functions, which are used by MJIT.
include/ruby/defines.h: add MJIT_FUNC_EXPORTED macro alis to clarify
that a function is exported only for MJIT.
array.c: export a function used by MJIT.
bignum.c: ditto.
class.c: ditto.
compile.c: ditto.
error.c: ditto.
gc.c: ditto.
hash.c: ditto.
iseq.c: ditto.
numeric.c: ditto.
object.c: ditto.
proc.c: ditto.
re.c: ditto.
st.c: ditto.
string.c: ditto.
thread.c: ditto.
variable.c: ditto.
vm_backtrace.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.
I would like to improve maintainability of function exports, but I
believe this way is acceptable as initial merging if we clarify the
new exports are for MJIT (so that we can use them as TODO list to fix)
and add unit tests to detect unresolved symbols.
I'll add unit tests of JIT compilations in succeeding commits.
Author: Takashi Kokubun <takashikkbn@gmail.com>
Contributor: wanabe <s.wanabe@gmail.com>
Part of [Feature #14235]
---
* Known issues
* Code generated by gcc is faster than clang. The benchmark may be worse
in macOS. Following benchmark result is provided by gcc w/ Linux.
* Performance is decreased when Google Chrome is running
* JIT can work on MinGW, but it doesn't improve performance at least
in short running benchmark.
* Currently it doesn't perform well with Rails. We'll try to fix this
before release.
---
* Benchmark reslts
Benchmarked with:
Intel 4.0GHz i7-4790K with 16GB memory under x86-64 Ubuntu 8 Cores
- 2.0.0-p0: Ruby 2.0.0-p0
- r62186: Ruby trunk (early 2.6.0), before MJIT changes
- JIT off: On this commit, but without `--jit` option
- JIT on: On this commit, and with `--jit` option
** Optcarrot fps
Benchmark: https://github.com/mame/optcarrot
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:--------|:--------|:--------|:--------|:--------|
|fps |37.32 |51.46 |51.31 |58.88 |
|vs 2.0.0 |1.00x |1.38x |1.37x |1.58x |
** MJIT benchmarks
Benchmark: https://github.com/benchmark-driver/mjit-benchmarks
(Original: https://github.com/vnmakarov/ruby/tree/rtl_mjit_branch/MJIT-benchmarks)
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:----------|:--------|:--------|:--------|:--------|
|aread |1.00 |1.09 |1.07 |2.19 |
|aref |1.00 |1.13 |1.11 |2.22 |
|aset |1.00 |1.50 |1.45 |2.64 |
|awrite |1.00 |1.17 |1.13 |2.20 |
|call |1.00 |1.29 |1.26 |2.02 |
|const2 |1.00 |1.10 |1.10 |2.19 |
|const |1.00 |1.11 |1.10 |2.19 |
|fannk |1.00 |1.04 |1.02 |1.00 |
|fib |1.00 |1.32 |1.31 |1.84 |
|ivread |1.00 |1.13 |1.12 |2.43 |
|ivwrite |1.00 |1.23 |1.21 |2.40 |
|mandelbrot |1.00 |1.13 |1.16 |1.28 |
|meteor |1.00 |2.97 |2.92 |3.17 |
|nbody |1.00 |1.17 |1.15 |1.49 |
|nest-ntimes|1.00 |1.22 |1.20 |1.39 |
|nest-while |1.00 |1.10 |1.10 |1.37 |
|norm |1.00 |1.18 |1.16 |1.24 |
|nsvb |1.00 |1.16 |1.16 |1.17 |
|red-black |1.00 |1.02 |0.99 |1.12 |
|sieve |1.00 |1.30 |1.28 |1.62 |
|trees |1.00 |1.14 |1.13 |1.19 |
|while |1.00 |1.12 |1.11 |2.41 |
** Discourse's script/bench.rb
Benchmark: https://github.com/discourse/discourse/blob/v1.8.7/script/bench.rb
NOTE: Rails performance was somehow a little degraded with JIT for now.
We should fix this.
(At least I know opt_aref is performing badly in JIT and I have an idea
to fix it. Please wait for the fix.)
*** JIT off
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 17
75: 18
90: 22
99: 29
home_admin:
50: 21
75: 21
90: 27
99: 40
topic_admin:
50: 17
75: 18
90: 22
99: 32
categories:
50: 35
75: 41
90: 43
99: 77
home:
50: 39
75: 46
90: 49
99: 95
topic:
50: 46
75: 52
90: 56
99: 101
*** JIT on
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 19
75: 21
90: 25
99: 33
home_admin:
50: 24
75: 26
90: 30
99: 35
topic_admin:
50: 19
75: 20
90: 25
99: 30
categories:
50: 40
75: 44
90: 48
99: 76
home:
50: 42
75: 48
90: 51
99: 89
topic:
50: 49
75: 55
90: 58
99: 99
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
r61560 ("offsetof(type, foo.bar) is (arguably) a GCCism")
introduced 16 bytes of stack overhead on 64-bit systems.
Remove that overhead and cast, instead. While we're at it,
restore the "waitq" name to clarify the purpose of the field.
(This is one unfortunate consequence of the CC0 ccan/list.h
implementation compared to the *GPL ones in glibc/urcu/linux)
* variable.c (struct autoload_state): remove head field, clarify naming
(autoload_reset): cast and adjust
(autoload_sleep_done): ditto
(rb_autoload_load): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61574 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
TL;DR see http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2031.htm
Suppose we have:
struct X {
struct Y {
z_t z;
} y;
} x;
then, you _cant_ infer offsetof(struct X, y.z). The ISO C99 section
7.17 says nothing about such situation. At least clang warns this
being an extension to the language (-Wextended-offsetof).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61560 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We do not need list_del_init in ensure callbacks, only list_del,
since it can only ever be called after list_del_init in
autoload_reset. So avoid the needless re-initialization.
* variable.c (autoload_sleep_done): s/list_del_init/list_del/
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58848 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We cannot assume autoload_provided/rb_feature_provided returning
TRUE means it is safe to proceed without waiting. Another
thread may call rb_provide_feature before setting the constant
(via autoload_const_set). So we must wait until autoload is
completed by another thread.
Note: this patch was tested with an explicit rb_thread_schedule
in rb_provide_feature to make the race condition more apparent
as suggested by <s.wanabe@gmail.com>:
> --- a/load.c
> +++ b/load.c
> @@ -563,6 +563,7 @@ rb_provide_feature(VALUE feature)
> rb_str_freeze(feature);
>
> rb_ary_push(features, rb_fstring(feature));
> +rb_thread_schedule();
> features_index_add(feature, INT2FIX(RARRAY_LEN(features)-1));
> reset_loaded_features_snapshot();
> }
* variable.c (check_autoload_required): do not assume a provided
feature means autoload is complete, always wait if autoload is
being performed by another thread.
[ruby-core:81105] [Bug #11384] Thanks to <s.wanabe@gmail.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58696 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (autoload_reset): use idempotent list_del_init
(autoload_sleep): moved code from rb_autoload_load
(autoload_sleep_done): cleanup for use with rb_ensure
(rb_autoload_load): ensure list delete happens in case the
thread dies during sleep
* test/ruby/bug-13526.rb: new script for separate execution
* test/ruby/test_autoload.rb (test_bug_13526): new test
[ruby-core:81016] [Bug #13526]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58587 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* How to enable this feature?
* define USE_DEBUG_COUNTER as 1.
* you can disable to output the result with
RUBY_DEBUG_COUNTER_DISABLE environment variable
even if USE_DEBUG_COUNTER == 1.
* How to add new counter?
* add COUNTER(<name>) line on debug_counter.h.
* include "debug_counter.h"
* insert RB_DEBUG_COUNTER_INC(<name>) line on your favorite place.
* counter output example:
[RUBY_DEBUG_COUNTER] mc_inline_hit 999
[RUBY_DEBUG_COUNTER] mc_inline_miss 3
[RUBY_DEBUG_COUNTER] mc_global_hit 23
[RUBY_DEBUG_COUNTER] mc_global_miss 273
[RUBY_DEBUG_COUNTER] mc_global_state_miss 3
[RUBY_DEBUG_COUNTER] mc_class_serial_miss 0
[RUBY_DEBUG_COUNTER] mc_cme_complement 0
[RUBY_DEBUG_COUNTER] mc_cme_complement_hit 0
[RUBY_DEBUG_COUNTER] mc_search_super 1384
[RUBY_DEBUG_COUNTER] ivar_get_hit 0
[RUBY_DEBUG_COUNTER] ivar_get_miss 0
[RUBY_DEBUG_COUNTER] ivar_set_hit 0
[RUBY_DEBUG_COUNTER] ivar_set_miss 0
[RUBY_DEBUG_COUNTER] ivar_get 431
[RUBY_DEBUG_COUNTER] ivar_set 465
* mc_... is related to method caching.
* ivar_... is related to instance variable accesses.
* compare with dtrace/system tap features, there are completely
no performacne penalties when it is disabled.
* This feature is supported only on __GNUC__ compilers.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57676 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_generic_ivar_table): declare as noreturn only in
GCC, which does not err on different attributes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57669 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_const_set): fix the condition to cache the class
path and cache permanent or temporary path corresponding to the
outer klass. [ruby-core:79039] [Bug #13120]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57305 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_const_set): resolve and cache class name
immediately only if the outer class/module has the name,
otherwise just set the ID. [ruby-core:79007] [Bug #13113]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57284 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
If you have code like this:
```ruby
class A
def initialize
@a = nil
@b = nil
@c = nil
@d = nil
@e = nil
end
end
x = A.new
y = x.clone
100.times { |z| x.instance_variable_set(:"@foo#{z}", nil) }
puts y.inspect
```
`x` and `y` will share `iv_index_tbl` hashes. However, the size of the
hash will grow larger than the number if entries in `ivptr` in `y`.
Before this commit, `rb_ivar_count` would use the size of the hash to
determine how far to read in to the array, but this means that it could
read past the end of the array and cause the program to segv
[ruby-core:78403]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56938 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_deprecate_constant): new function to deprecate a
constant by the name.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56119 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_const_search): warn with the actual class/module
name which defines the deprecated constant.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56118 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_const_search): raise with the actual class/module
name which defines the private constant.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56117 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_path_to_class): consider the string length
instead of a terminator.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55449 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_path_to_class): search the constant at once
instead of checking if defined and then getting it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55448 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (check_autoload_required): check length first before
checking the first byte.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55207 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_insnhelper.c (vm_get_ev_const): warn deprecated constant even
in the class context. [ruby-core:75505] [Bug #12382]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55005 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_f_global_variables): add matched back references
only, as well as defiend? operator.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53534 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_f_global_variables): add $1..$9 only if $~ is
set. fix the condition removed at r14014.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53530 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This further avoids class name resolution issues which came
about due to relying on hash table ordering before r53376.
Pre-caching the class name when it is never used raises memory
use, but the overall gain from moving away from st still gives
us a small gain. Reverting r53376 and this patch and testing with
"valgrind -v ./ruby -rrdoc -eexit" on x86 (32-bit) shows:
before:
in use at exit: 1,662,239 bytes in 25,286 blocks
total heap usage: 49,514 allocs, 24,228 frees, 6,005,561 bytes allocated
after, with this change:
in use at exit: 1,646,529 bytes in 24,572 blocks
total heap usage: 48,891 allocs, 24,319 frees, 6,003,921 bytes allocated
* class.c (Init_class_hierarchy): resolve name for rb_cObject ASAP
* object.c (rb_mod_const_set): move name resolution to rb_const_set
* variable.c (rb_const_set): do class resolution here
[ruby-core:72807] [Bug #11977]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53518 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
to avoid name conflict with /usr/include/floatingpoint.h on
Solaris. [Bug #11853] [ruby-dev:49448]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53230 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_autoload_str may be safer by preventing premature GC. It
can also be more efficient by passing a pre-frozen string that
can be deduped using rb_fstring. Common autoload callers (e.g.
rubygems, rdoc) already use string literals as the file
argument.
There seems to be no reason to expose rb_autoload_str to the
public C API since autoload is not performance-critical.
Applications may declare autoloads in Ruby code or via
rb_funcall; so merely deprecate rb_autoload without exposing
rb_autoload_str to new users.
Running: valgrind -v ruby -rrdoc -rubygems -e exit
shows a minor memory reduction (32-bit userspace)
before:
in use at exit: 1,600,621 bytes in 28,819 blocks
total heap usage: 55,786 allocs, 26,967 frees, 6,693,790 bytes allocated
after:
in use at exit: 1,599,778 bytes in 28,789 blocks
total heap usage: 55,739 allocs, 26,950 frees, 6,692,973 bytes allocated
* include/ruby/intern.h (rb_autoload): deprecate
* internal.h (rb_autoload_str): declare
* load.c (rb_mod_autoload): use rb_autoload_str
* variable.c (rb_autoload): become compatibility wrapper
(rb_autoload_str): hoisted out from old rb_autoload
[ruby-core:71369] [Feature #11664]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52909 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Removing the indirection helps me with readability, at
least. It doesn't seem like there are many other places
in the Ruby code where macros are used like this.
[ruby-core:71735] [Feature #11749]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52790 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (autoload_reset): initialize formally to suppress a
warning from container_off_var() by Visual C.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52446 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Casting any arguments of rb_class_ivar_set to st_data_t is wrong
as the function does not take any st_data_t parameters anymore.
There's no functional change, as ID, VALUE, and st_data_t are
all the same type, but this reduces confusion and improves
maintainability for future type changes.
* variable.c (find_class_path): remove cast for rb_class_ivar_set
(rb_ivar_set): ditto
(rb_cvar_set): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52427 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Mainly this is to reduce casting a tiny amount; and
probably nothing depends on the order of globals.
Likely no measurable memory usage improvement as globals
are not common, but maybe some weird code out there benefits.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52426 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_class_ivar_set): rename as class specific ivar
setter, and st_table is no longer involved.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52380 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This fixes a bug introduced in r50678
("variable.c: use indices for generic ivars")
and does not affect any released version of Ruby
* variable.c (generic_ivar_remove): adjust type, set valp
(rb_obj_remove_instance_variable): simplify call
* test/ruby/test_object.rb (test_remove_instance_variable):
expand for implementation details
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52378 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Minor simplification; this will hopefully make future patches
for switching to id_table easier-to-review.
* internal.h (rb_st_insert_id_and_value): update prototype
* variable.c (rb_st_insert_id_and_value): reduce args
(find_class_path): adjust call for less args
(rb_ivar_set): ditto
(rb_cvar_set): ditto
* class.c (rb_singleton_class_attached): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52374 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
For the loader (first thread which hits autoload, it is wasteful
to have extra elements on the stack. For the lifetime of the
process, it is wasteful to waste 2 words for every autoload
entry. So this makes full use of existing stack overhead
while reducing heap overhead for long-lived autoload_data_i
structs.
* variable.c (struct autoload_state): usable as wait-queue head
(struct autoload_data_i): remove 2 words of overhead
(autoload_i_mark): remove marking for thread
(autoload_reset): adjust for struct changes
(rb_autoload): ditto
(rb_autoloading_value): ditto
(rb_autoload_load): ditto
(const_update): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52335 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
[ruby-core:70075] [ruby-core:71239] [Bug #11384]
Note: this open-coding locking method may go into
rb_mutex/rb_thread_shield types. It is smaller and simpler and
based on the wait queue implementation of the Linux kernel.
When/if we get rid of GVL, native mutexes may be used as-is.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52332 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* error.c (name_err_mesg_to_str): quote the name if unprintable.
* object.c (check_setter_id): use rb_check_id to convert names.
* variable.c (uninitialized_constant): use NameError::message to
keep the receiver of uninitialized constant. [Feature #10881]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52321 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (set_const_visibility): fail if the class/module is
frozen. [ruby-core:70828] [Bug #11532]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51881 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Make code easier to read and hunt for bugs with my tiny terminal.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51479 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_const_get_0): warn deprecated constant reference.
* variable.c (rb_mod_deprecate_constant): mark constants to be
warned as deprecated. [Feature #11398]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51444 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Special constants are all frozen since [Feature #8923] and cannot
support ivars. Remove some unused code we had for supporting them.
* variable.c (special_generic_ivar): remove flag
(givar_i, rb_mark_generic_ivar_tbl): remove functions
(rb_free_generic_ivar, rb_ivar_lookup, rb_ivar_delete,
generic_ivar_set, rb_ivar_set, rb_ivar_defined,
rb_copy_generic_ivar, rb_ivar_foreach, rb_ivar_count,
rb_obj_remove_instance_variable):
adjust for lack of ivar support in special constants
* test/ruby/test_variable.rb: test ivars for special consts
* internal.h: remove rb_mark_generic_ivar_tbl decl
* gc.c (gc_mark_roots): remove rb_mark_generic_ivar_tbl call
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This recovers and improves performance of Marshal.dump/load on
Time objects compared to when we implemented generic ivars
entirely using st_table.
This also recovers some performance on other generic ivar objects,
but does not bring bring Marshal.dump/load performance up to
previous speeds.
benchmark results:
minimum results in each 10 measurements.
Execution time (sec)
name trunk geniv after
marshal_dump_flo 0.343 0.334 0.335
marshal_dump_load_geniv 0.487 0.527 0.495
marshal_dump_load_time 1.262 1.401 1.257
Speedup ratio: compare with the result of `trunk' (greater is better)
name geniv after
marshal_dump_flo 1.026 1.023
marshal_dump_load_geniv 0.925 0.985
marshal_dump_load_time 0.901 1.004
* include/ruby/intern.h (rb_generic_ivar_table): deprecate
* internal.h (rb_attr_delete): declare
* marshal.c (has_ivars): use rb_ivar_foreach
(w_ivar): ditto
(w_object): update for new interface
* time.c (time_mload): use rb_attr_delete
* variable.c (generic_ivar_delete): implement
(rb_ivar_delete): ditto
(rb_attr_delete): ditto
[ruby-core:69323] [Feature #11170]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50680 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This reduces memory overhead of ivars for common types such as
T_DATA the same way T_OBJECT does it.
For 9992 accepted clients on an OpenSSL server, this reduces
memory from 77160K to 69248K with the script in
https://bugs.ruby-lang.org/issues/11170
* variable.c (static int special_generic_ivar): move
(rb_generic_ivar_table): rewrite for compatibility
(gen_ivtbl_bytes): new function
(generic_ivar_get): update to use ivar index
(generic_ivar_update): ditto
(generic_ivar_set): ditto
(generic_ivar_defined): ditto
(generic_ivar_remove): ditto
(rb_mark_generic_ivar): ditto
(givar_i): ditto
(rb_free_generic_ivar): ditto
(rb_mark_generic_ivar_tbl): ditto
(rb_generic_ivar_memsize): ditto
(rb_copy_generic_ivar): ditto
(rb_ivar_set): ditto
(rb_ivar_foreach): ditto
(rb_ivar_count): ditto
(givar_mark_i): remove
(gen_ivtbl_mark): new function
(gen_ivar_each): ditto
(iv_index_tbl_extend): update for struct ivar_update
(iv_index_tbl_newsize): ditto
[ruby-core:69323] [Feature #11170]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50678 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
than directly calling `rb_require_safe`. This allows things like
RubyGems to intercept file loading done though `autoload`.
[Feature #11140]
* test/ruby/test_autoload.rb: Test for change.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50494 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_path_to_class): escape erred name. as precision
delimits the formatted result only, not region of an argument
string, need to make a substring for the particular region.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50056 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
and related functions from node.h to internal.h.
* variable.c: remove unused include pragma.
* common.mk: remove unused dependency.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49947 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_tmp_class_path): defer making temporary class
path string.
* variable.c (rb_search_class_path): search class path or return
Qnil or Qfalse if unnamed, not creating a temporary path.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49779 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_tmp_class_path): preserve name encoding of an
anonymous instance of module/class subclass.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49778 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_alias_variable): IDs are always immportal now, no
pin down is needed.
* vm_method.c (rb_method_entry_make): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49520 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (classname): ignore classid if it is a mortal symbol.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49519 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
use 0 for rb_data_type_t::reserved instead of NULL, since its type
may be changed in the future and possibly not a pointer type.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48662 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (rb_mod_const_get, rb_mod_const_defined): ditto.
* variable.c (rb_const_missing, rb_mod_const_missing): call
const_missing without new ID to get rid of inadvertent ID
creation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48533 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_ivar_get), vm_insnhelper.c (vm_getivar): improve
instance variable retrieval performance by checking ruby_verbose
before call of rb_warning and evaluation of its argument.
[ruby-core:65786] [Feature #10396]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48035 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (generic_ivar_set): use st_update to insert object
which does not have generic instance variables yet.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47849 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* process.c (free_exec_arg): remove
(memsize_exec_arg): ptr is never NULL
(exec_arg_data_type): use RUBY_TYPED_DEFAULT_FREE
* variable.c (autoload_i_free): remove
(autoload_data_i_type): use RUBY_TYPED_DEFAULT_FREE
(autoload_memsize): ptr is never NULL
* vm_backtrace.c (location_free): remove
(location_mark): ptr is never NULL
(location_data_type): use RUBY_TYPED_DEFAULT_FREE
(backtrace_mark): ditto
(backtrace_free): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47572 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This keeps ci->flag and ci->aux.index consistent across 32-bit
and 64-bit platforms.
ci->flag: VM_CALL_* flags only use 9 bits, currently
ci->aux.index: 2 billion ivars per class should be enough for anybody
This saves around 50K allocations on "valgrind ruby -e exit" on x86-64
before:
total heap usage: 48,122 allocs, 19,253 frees, 8,099,197 bytes allocated
after:
total heap usage: 48,069 allocs, 19,214 frees, 8,047,266 bytes allocated
* vm_core.h (rb_call_info_t): ci->flag becomes 32-bit unsigned int
ci->index becomes a 32-bit signed int (from signed long).
Reorder for better packing on 64-bit, giving an 8 byte reduction
from 104 to 96 bytes for each ci.
* compile.c (new_callinfo, setup_args, iseq_compile_each,
iseq_build_from_ary_body): adjust for type changes
* vm_insnhelper.c (vm_getivar): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47509 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c: cleanup to use rb_const_lookup
* vm_insnshelper.c: ditto
This reduces casting and long lines. This should make it easier to
switch to alternatives to st for constant storage.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47059 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
exposing IDs from collectable symbols.
[Bug #10014]
Now, rb_check_id() returns 0 if corresponding symbol is
pinned dynamic symbol.
There is remaining intern_cstr_without_pindown(), it can return
IDs from collectable symbols. We must be careful to use it
(only used in parse.y). I think it should be removed if
it does not have impact for performance.
* parse.y:
add:
* STATIC_SYM2ID()
* STATIC_ID2SYM()
rename:
* rb_pin_dynamic_symbol() -> dsymbol_pindown()
* internal.h:
remove:
* rb_check_id_without_pindown()
* rb_sym2id_without_pindown()
add:
* rb_check_symbol()
* rb_check_symbol_cstr()
* load.c: use rb_check_id() or rb_check_id_cstr().
* object.c: ditto.
* struct.c: ditto.
* thread.c: ditto.
* vm_method.c: ditto.
* string.c (sym_find): use only rb_check_symbol().
* sprintf.c (rb_str_format): use rb_check_symbol_cstr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46764 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
See this ticket about Symbol GC.
* include/ruby/ruby.h:
Declare few functions.
* rb_sym2id: almost same as old SYM2ID but support dynamic symbols.
* rb_id2sym: almost same as old ID2SYM but support dynamic symbols.
* rb_sym2str: almost same as `rb_id2str(SYM2ID(sym))` but not
pin down a dynamic symbol.
Declare a new struct.
* struct RSymbol: represents a dynamic symbol as object in
Ruby's heaps.
Add few macros.
* STATIC_SYM_P: check a static symbol.
* DYNAMIC_SYM_P: check a dynamic symbol.
* RSYMBOL: cast to RSymbol
* gc.c: declare RSymbol. support T_SYMBOL.
* internal.h: Declare few functions.
* rb_gc_free_dsymbol: free up a dynamic symbol. GC call this
function at a sweep phase.
* rb_str_dynamic_intern: convert a string to a dynamic symbol.
* rb_check_id_without_pindown: not pinning function.
* rb_sym2id_without_pindown: ditto.
* rb_check_id_cstr_without_pindown: ditto.
* string.c (Init_String): String#intern and String#to_sym use
rb_str_dynamic_intern.
* template/id.h.tmpl: use LSB of ID as a flag for determining a
static symbol, so we shift left other ruby_id_types.
* string.c: use rb_sym2str instead `rb_id2str(SYM2ID(sym))` to
avoid pinning.
* load.c: use xx_without_pindown function at creating temporary ID
to avoid pinning.
* object.c: ditto.
* sprintf.c: ditto.
* struct.c: ditto.
* thread.c: ditto.
* variable.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45426 b2dd03c8-39d4-4d8f-98ff-823fe69b080e