Skip to content

Declarative marking of RTypedData struct references #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ff3c1d9
SimpleCov is hosted under simplecov-ruby org now
hsbt Jan 17, 2023
d7af0f6
[rubygems/rubygems] Bump rb-sys
dependabot[bot] Jan 17, 2023
da7818e
Added test-syntax-suggest to help message
hsbt Jan 17, 2023
aad1563
Added make exam to help message
hsbt Jan 17, 2023
01e28af
test-syntax-suggest is now part of make check
hsbt Jan 17, 2023
dd510da
[ruby/psych] configure of libyaml couldn't detect "arm64-apple-darwin…
hsbt Jan 17, 2023
492d37f
[ruby/psych] Bump up 5.0.2.pre1 for testing
hsbt Jan 17, 2023
f8249eb
Update default gems list at 492d37fbbd3613b7fb180eec529860 [ci skip]
matzbot Jan 17, 2023
ed6fbb7
Fix crash when defining ivars on special constants
peterzhu2118 Jan 16, 2023
9399352
[rubygems/rubygems] Bump rb-sys in /test/rubygems/test_gem_ext_cargo_…
dependabot[bot] Jan 17, 2023
df6b72b
Avoid checking interrupt when loading iseq
st0012 Jan 16, 2023
a9bcc05
Update yjit.md
maximecb Jan 17, 2023
2fa3fda
Remove removed files from ext/.document [ci skip]
znz Jan 18, 2023
8ae4e3d
Clean up removed directories in ext/Setup* [ci skip]
znz Jan 18, 2023
8a771ef
[ruby/psych] Bump up 5.0.2
hsbt Jan 18, 2023
5ce3855
Update default gems list at 8a771efec21c9dacad5bb8bf14b81c [ci skip]
matzbot Jan 18, 2023
46066d0
Change ArgumentError message when Comparable#clamp receives min value…
kaiquekandykoga Jan 18, 2023
2d7e639
[ruby/reline] multiline_repl do not need to depend on RubyLex
tompng Jan 18, 2023
7e97e2b
Update RBS commit hash (#7143)
soutaro Jan 18, 2023
5fc97f3
benchmark_driver v0.16.3
k0kubun Jan 18, 2023
ba45be3
Supressing warnings messages like:
hsbt Jan 18, 2023
18d8333
Switch to use gem version of simplecov, not git clone
hsbt Jan 17, 2023
d275add
Pin simplecov-0.20.0
hsbt Jan 17, 2023
e3336e0
Define RUBY_VERSION_IS_3_3 macro in rubyspec.h
nobu Jan 17, 2023
4fa7d38
Don't redefine RB_OBJ_WRITE
peterzhu2118 Jan 16, 2023
a712f2a
[ruby/reline] Fix dialog scrollbar rendering position and disappearin…
tompng Oct 23, 2022
976d72a
[ruby/reline] Add scrollbar scroll-to-bottom test and fix existing sc…
tompng Dec 19, 2022
8e53f09
[ruby/reline] Add constant MINIMUM_SCROLLBAR_HEIGHT for scrollbar ren…
tompng Jan 8, 2023
03f5db0
Make installation messages verbose a little [ci skip]
nobu Jan 18, 2023
cd97976
Add stats so we can keep track of x86 rel32 vs register calls (#7142)
maximecb Jan 18, 2023
0fd5a66
Remove macro RHASH_ITER_LEV
peterzhu2118 Jan 17, 2023
6bb576f
YJIT: implement codegen for `String#empty?` (#7148)
maximecb Jan 18, 2023
3089429
[ruby/net-http] [DOC] Enhanced RDoc for set_form
BurdetteLamar Jan 18, 2023
edd0069
Test some missing coverage too. (#7041)
ioquatix Jan 18, 2023
4cf1d9b
YJIT: Set RUST_BACKTRACE=1 on YJIT GitHub Actions (#7152)
k0kubun Jan 19, 2023
4b42392
YJIT: Use .as_side_exit() for jumps to counted exits
XrXr Jan 18, 2023
f7b7246
String#bytesplice should return self
shugo Jan 19, 2023
9401707
wip declarative marking of RTypedData references
eightbitraptor Jul 21, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/yjit-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ jobs:
YJIT_BENCH_OPTS: ${{ matrix.yjit_bench_opts }}
RUBY_DEBUG: ci
BUNDLE_JOBS: 8 # for yjit-bench
RUST_BACKTRACE: 1
runs-on: ubuntu-20.04
if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The following default gems are updated.
* csv 3.2.7
* fiddle 1.1.2
* optparse 0.4.0.pre.1
* psych 5.0.2
* stringio 3.0.5
* strscan 3.0.6

Expand Down
16 changes: 8 additions & 8 deletions common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,7 @@ GEM_PATH =
GEM_VENDOR =

BENCHMARK_DRIVER_GIT_URL = https://github.com/benchmark-driver/benchmark-driver
BENCHMARK_DRIVER_GIT_REF = v0.16.0
SIMPLECOV_GIT_URL = https://github.com/colszowka/simplecov.git
SIMPLECOV_GIT_REF = v0.17.0
SIMPLECOV_HTML_GIT_URL = https://github.com/colszowka/simplecov-html.git
SIMPLECOV_HTML_GIT_REF = v0.10.2
DOCLIE_GIT_URL = https://github.com/ms-ati/docile.git
DOCLIE_GIT_REF = v1.3.2
BENCHMARK_DRIVER_GIT_REF = v0.16.3

STATIC_RUBY = static-ruby

Expand Down Expand Up @@ -1378,6 +1372,10 @@ update-config_files: PHONY
$(Q) $(BASERUBY) -C "$(srcdir)" tool/downloader.rb -d tool --cache-dir=$(CACHE_DIR) -e gnu \
config.guess config.sub

update-coverage: PHONY
$(XRUBY) -C "$(srcdir)" bin/gem install --no-document \
--install-dir .bundle --conservative "simplecov" -v "0.20.0"

refresh-gems: update-bundled_gems prepare-gems
prepare-gems: $(HAVE_BASERUBY:yes=update-gems) $(HAVE_BASERUBY:yes=extract-gems)
extract-gems: $(HAVE_BASERUBY:yes=update-gems)
Expand Down Expand Up @@ -1754,12 +1752,14 @@ help: PHONY
" runruby: runs test.rb by ruby you just built" \
" gdb: runs test.rb by miniruby under gdb" \
" gdb-ruby: runs test.rb by ruby under gdb" \
" check: equals make test test-tool test-all test-spec" \
" exam: equals make check test-bundler-parallel test-bundled-gems" \
" check: equals make test test-tool test-all test-spec test-syntax-suggest" \
" test: ruby core tests [BTESTS=<bootstraptest files>]" \
" test-all: all ruby tests [TESTOPTS=-j4 TESTS=<test files>]" \
" test-spec: run the Ruby spec suite [SPECOPTS=<specs, opts>]" \
" test-bundler: run the Bundler spec" \
" test-bundler-parallel: run the Bundler spec with parallel" \
" test-syntax-suggest: run the SyntaxSuggest spec" \
" test-bundled-gems: run the test suite of bundled gems" \
" test-tool: tests under the tool/test" \
" update-gems: download files of the bundled gems" \
Expand Down
2 changes: 1 addition & 1 deletion compar.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ cmp_clamp(int argc, VALUE *argv, VALUE x)
}
}
if (!NIL_P(min) && !NIL_P(max) && cmpint(min, max) > 0) {
rb_raise(rb_eArgError, "min argument must be smaller than max argument");
rb_raise(rb_eArgError, "min argument must be less than or equal to max argument");
}

if (!NIL_P(min)) {
Expand Down
2 changes: 1 addition & 1 deletion compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -12311,7 +12311,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
verify_call_cache(iseq);

RB_GC_GUARD(dummy_frame);
rb_vm_pop_frame(ec);
rb_vm_pop_frame_no_int(ec);
}

struct ibf_dump_iseq_list_arg
Expand Down
20 changes: 12 additions & 8 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,12 +465,12 @@ struct dir_data {
rb_encoding *enc;
};

static void
dir_mark(void *ptr)
{
struct dir_data *dir = ptr;
rb_gc_mark(dir->path);
}
/* static void */
/* dir_mark(void *ptr) */
/* { */
/* struct dir_data *dir = ptr; */
/* rb_gc_mark(dir->path); */
/* } */

static void
dir_free(void *ptr)
Expand All @@ -487,10 +487,14 @@ dir_memsize(const void *ptr)
return sizeof(struct dir_data);
}

#define END_REFS UINTPTR_MAX

static VALUE references[] = {offsetof(struct dir_data, path), END_REFS};

static const rb_data_type_t dir_data_type = {
"dir",
{dir_mark, dir_free, dir_memsize,},
0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
{NULL, dir_free, dir_memsize,},
0, references, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_DECL_MARKING
};

static VALUE dir_close(VALUE);
Expand Down
7 changes: 4 additions & 3 deletions doc/yjit/yjit.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,18 +172,19 @@ We have collected a set of benchmarks and implemented a simple benchmarking harn

### Performance Tips

This section contains tips on writing Ruby code that will run as fast as possible on YJIT. Some of this advice is based on current limitations of YJIT, while other advice is broadly applicable. It probably won't be practical to apply these tips everywhere in your codebase, but you can profile your code using a tool such as [stackprof](https://github.com/tmm1/stackprof) and refactor the specific methods that make up the largest fractions of the execution time.
This section contains tips on writing Ruby code that will run as fast as possible on YJIT. Some of this advice is based on current limitations of YJIT, while other advice is broadly applicable. It probably won't be practical to apply these tips everywhere in your codebase. You should ideally start by profiling your application using a tool such as [stackprof](https://github.com/tmm1/stackprof) so that you can determine which methods make up most of the execution time. You can then refactor the specific methods that make up the largest fractions of the execution time. We do not recommend modifying your entire codebase based on the current limitations of YJIT.

- Use exceptions for error recovery only, not as part of normal control-flow
- Avoid redefining basic integer operations (i.e. +, -, <, >, etc.)
- Avoid redefining the meaning of `nil`, equality, etc.
- Avoid allocating objects in the hot parts of your code
- Use while loops if you can, instead of `integer.times`
- Minimize layers of indirection
- Avoid classes that wrap objects if you can
- Avoid methods that just call another method, trivial one liner methods
- CRuby method calls are costly. Favor larger methods over smaller methods.
- Try to write code so that the same variables always have the same type
- Use while loops if you can, instead of `integer.times`
- This is not idiomatic Ruby, but could help in hot methods
- CRuby method calls are costly. Avoid things such as methods that only return a value from a hash or return a constant.

You can also use the `--yjit-stats` command-line option to see which bytecodes cause YJIT to exit, and refactor your code to avoid using these instructions in the hottest methods of your code.

Expand Down
3 changes: 0 additions & 3 deletions ext/.document
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ date/date_parse.c
date/date_strftime.c
date/date_strptime.c
date/lib
dbm/dbm.c
digest/bubblebabble/bubblebabble.c
digest/digest.c
digest/lib
Expand All @@ -22,7 +21,6 @@ digest/sha2/sha2init.c
digest/sha2/lib
etc/etc.c
fcntl/fcntl.c
fiber/fiber.c
fiddle/closure.c
fiddle/conversions.c
fiddle/fiddle.c
Expand All @@ -31,7 +29,6 @@ fiddle/pinned.c
fiddle/pointer.c
fiddle/handle.c
fiddle/lib
gdbm/gdbm.c
io/console/console.c
io/console/lib
io/nonblock/nonblock.c
Expand Down
3 changes: 0 additions & 3 deletions ext/Setup
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#continuation
#coverage
#date
#dbm
#digest/bubblebabble
#digest
#digest/md5
Expand All @@ -14,9 +13,7 @@
#digest/sha2
#etc
#fcntl
#fiber
#fiddle
#gdbm
#io/console
#io/nonblock
#io/wait
Expand Down
6 changes: 1 addition & 5 deletions ext/Setup.atheos
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
option nodynamic

#Win32API
bigdecimal
cgi/escape
dbm
digest
digest/md5
digest/rmd160
digest/sha1
digest/sha2
enumerator
etc
fcntl
gdbm
io/wait
nkf
#openssl
pty
racc/parse
racc/cparse
readline
ripper
socket
Expand Down
4 changes: 0 additions & 4 deletions ext/Setup.nt
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
#option platform cygwin|mingw|mswin
#option nodynamic

Win32API
bigdecimal
cgi/escape
#dbm
digest
digest/md5
digest/rmd160
digest/sha1
digest/sha2
enumerator
etc
fcntl
#gdbm
#io/wait
nkf
#openssl
Expand Down
2 changes: 1 addition & 1 deletion ext/psych/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
args = [
yaml_configure,
"--enable-#{shared ? 'shared' : 'static'}",
"--host=#{RbConfig::CONFIG['host'].sub(/-unknown-/, '-')}",
"--host=#{RbConfig::CONFIG['host'].sub(/-unknown-/, '-').sub(/arm64/, 'arm')}",
"CC=#{RbConfig::CONFIG['CC']}",
*(["CFLAGS=-w"] if RbConfig::CONFIG["GCC"] == "yes"),
]
Expand Down
2 changes: 1 addition & 1 deletion ext/psych/lib/psych/versions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module Psych
# The version of Psych you are using
VERSION = '5.0.1'
VERSION = '5.0.2'

if RUBY_ENGINE == 'jruby'
DEFAULT_SNAKEYAML_VERSION = '1.33'.freeze
Expand Down
38 changes: 32 additions & 6 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7208,6 +7208,19 @@ gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
}
}

static bool
gc_declarative_marking_p(const rb_data_type_t *type)
{
return (type->flags & RUBY_TYPED_DECL_MARKING) != 0;
}

static void
gc_mark_from_offset(rb_objspace_t *objspace, VALUE *data_struct, VALUE offset)
{
VALUE markable = *(data_struct + (offset / sizeof(VALUE)));
gc_mark_and_pin(objspace, markable);
}

static void
gc_mark_children(rb_objspace_t *objspace, VALUE obj)
{
Expand Down Expand Up @@ -7310,16 +7323,29 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
break;

case T_DATA:
{
{
void *const ptr = DATA_PTR(obj);
if (ptr) {
RUBY_DATA_FUNC mark_func = RTYPEDDATA_P(obj) ?
any->as.typeddata.type->function.dmark :
any->as.data.dmark;
if (mark_func) (*mark_func)(ptr);
if (RTYPEDDATA_P(obj) && gc_declarative_marking_p(any->as.typeddata.type)) {
VALUE *offset_list = any->as.typeddata.type->data;
VALUE *data_struct = (VALUE *)any->as.typeddata.data;
VALUE offset = *offset_list;

int n = 0;
while (offset != UINTPTR_MAX) {
gc_mark_from_offset(objspace, data_struct, offset);
n++;
offset = *(offset_list + n);
}
} else {
RUBY_DATA_FUNC mark_func = RTYPEDDATA_P(obj) ?
any->as.typeddata.type->function.dmark :
any->as.data.dmark;
if (mark_func) (*mark_func)(ptr);
}
}
}
break;
break;

case T_OBJECT:
{
Expand Down
2 changes: 1 addition & 1 deletion gems/bundled_gems
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ net-pop 0.1.2 https://github.com/ruby/net-pop
net-smtp 0.3.3 https://github.com/ruby/net-smtp
matrix 0.4.2 https://github.com/ruby/matrix
prime 0.1.2 https://github.com/ruby/prime
rbs 2.8.3 https://github.com/ruby/rbs eab5367add3469b3f614e663ba43a3debc62420a
rbs 2.8.3 https://github.com/ruby/rbs c822808a08ef86f3ab460d7aa7506da7783f0bef
typeprof 0.21.4 https://github.com/ruby/typeprof
debug 1.7.1 https://github.com/ruby/debug
13 changes: 0 additions & 13 deletions include/ruby/internal/core/rhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,6 @@
*/
#define RHASH_TBL(h) rb_hash_tbl(h, __FILE__, __LINE__)

/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*
* @internal
*
* Declaration of rb_hash_iter_lev() is at include/ruby/backward.h.
*/
#define RHASH_ITER_LEV(h) rb_hash_iter_lev(h)

/**
* @private
*
Expand Down
9 changes: 8 additions & 1 deletion include/ruby/internal/core/rtypeddata.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,14 @@ rbimpl_typeddata_flags {
* This flag is mysterious. It seems nobody is currently using it. The
* intention of this flag is also unclear. We need further investigations.
*/
RUBY_TYPED_PROMOTED1 = RUBY_FL_PROMOTED1 /* THIS FLAG DEPENDS ON Ruby version */
RUBY_TYPED_PROMOTED1 = RUBY_FL_PROMOTED1, /* THIS FLAG DEPENDS ON Ruby version */

/**
* This flag determines whether marking and compaction should be carried out
* using the dmark/dcompact callback functions or whether we should mark
* declaratively using a list of references defined inside the data struct we're wrapping
*/
RUBY_TYPED_DECL_MARKING = RUBY_FL_USER2
};

/**
Expand Down
1 change: 0 additions & 1 deletion internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
/* internal/gc.h */
#undef NEWOBJ_OF
#undef RB_NEWOBJ_OF
#undef RB_OBJ_WRITE

/* internal/hash.h */
#undef RHASH_IFNONE
Expand Down
1 change: 0 additions & 1 deletion internal/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
* @brief Internal header for Class.
*/
#include "id_table.h" /* for struct rb_id_table */
#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "internal/serial.h" /* for rb_serial_t */
#include "internal/static_assert.h"
#include "ruby/internal/stdbool.h" /* for bool */
Expand Down
4 changes: 0 additions & 4 deletions internal/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ struct rb_objspace; /* in vm_core.h */
#ifdef NEWOBJ_OF
# undef NEWOBJ_OF
# undef RB_NEWOBJ_OF
# undef RB_OBJ_WRITE
#endif

#define RVALUE_SIZE (sizeof(struct RBasic) + sizeof(VALUE[RBIMPL_RVALUE_EMBED_LEN_MAX]))
Expand Down Expand Up @@ -63,9 +62,6 @@ struct rb_objspace; /* in vm_core.h */
#endif

#define UNALIGNED_MEMBER_PTR(ptr, mem) UNALIGNED_MEMBER_ACCESS(&(ptr)->mem)
#define RB_OBJ_WRITE(a, slot, b) \
rb_obj_write((VALUE)(a), UNALIGNED_MEMBER_ACCESS((VALUE *)(slot)), \
(VALUE)(b), __FILE__, __LINE__)

// We use SIZE_POOL_COUNT number of shape IDs for transitions out of different size pools
// The next available shapd ID will be the SPECIAL_CONST_SHAPE_ID
Expand Down
1 change: 0 additions & 1 deletion internal/imemo.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include "ruby/internal/config.h"
#include <stddef.h> /* for size_t */
#include "internal/array.h" /* for rb_ary_hidden_new_fill */
#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "ruby/internal/stdbool.h" /* for bool */
#include "ruby/ruby.h" /* for rb_block_call_func_t */

Expand Down
1 change: 1 addition & 0 deletions internal/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#endif

#include "ruby/ruby.h" /* for VALUE */
#include "internal/compilers.h" /* for __has_warning */
#include "internal/imemo.h" /* for RB_IMEMO_TMPBUF_PTR */
#include "internal/warnings.h" /* for COMPILER_WARNING_PUSH */

Expand Down
1 change: 0 additions & 1 deletion internal/rational.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
*/
#include "ruby/internal/config.h" /* for HAVE_LIBGMP */
#include "ruby/ruby.h" /* for struct RBasic */
#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "internal/numeric.h" /* for INT_POSITIVE_P */
#include "ruby_assert.h" /* for assert */

Expand Down
Loading