summaryrefslogtreecommitdiff
path: root/yjit
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2022-07-11 10:09:39 -0400
committerPeter Zhu <peter@peterzhu.ca>2022-07-15 09:21:07 -0400
commit7424ea184f9d67c1c7f3ee97494ed3bd1aa60833 (patch)
tree822838e39d81cd2785c970cb45a86854823af6fe /yjit
parent7fda741f6e67b809b08423f0d4e903c078da2eed (diff)
Implement Objects on VWA
This commit implements Objects on Variable Width Allocation. This allows Objects with more ivars to be embedded (i.e. contents directly follow the object header) which improves performance through better cache locality.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6117
Diffstat (limited to 'yjit')
-rw-r--r--yjit/bindgen/src/main.rs6
-rw-r--r--yjit/src/codegen.rs21
-rw-r--r--yjit/src/cruby.rs4
-rw-r--r--yjit/src/cruby_bindings.inc.rs7
4 files changed, 24 insertions, 14 deletions
diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs
index 5d30d7b288..f54addc795 100644
--- a/yjit/bindgen/src/main.rs
+++ b/yjit/bindgen/src/main.rs
@@ -62,6 +62,9 @@ fn main() {
// Import YARV bytecode instruction constants
.allowlist_type("ruby_vminsn_type")
+ // From include/ruby/internal/config.h
+ .allowlist_var("USE_RVARGC")
+
// From include/ruby/internal/intern/string.h
.allowlist_function("rb_utf8_str_new")
.allowlist_function("rb_str_buf_append")
@@ -135,7 +138,8 @@ fn main() {
// From include/ruby/internal/core/robject.h
.allowlist_type("ruby_robject_flags")
- .allowlist_type("ruby_robject_consts")
+ // .allowlist_type("ruby_robject_consts") // Removed when USE_RVARGC
+ .allowlist_var("ROBJECT_OFFSET_.*")
// From include/ruby/internal/core/rarray.h
.allowlist_type("ruby_rarray_flags")
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 84f4ff4897..9cd69cd340 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -1966,9 +1966,17 @@ fn gen_get_ivar(
ctx.stack_pop(1);
}
+ if USE_RVARGC != 0 {
+ // Check that the ivar table is big enough
+ // Check that the slot is inside the ivar table (num_slots > index)
+ let num_slots = mem_opnd(32, REG0, ROBJECT_OFFSET_NUMIV);
+ cmp(cb, num_slots, uimm_opnd(ivar_index as u64));
+ jle_ptr(cb, counted_exit!(ocb, side_exit, getivar_idx_out_of_range));
+ }
+
// Compile time self is embedded and the ivar index lands within the object
let test_result = unsafe { FL_TEST_RAW(comptime_receiver, VALUE(ROBJECT_EMBED.as_usize())) != VALUE(0) };
- if test_result && ivar_index < (ROBJECT_EMBED_LEN_MAX.as_usize()) {
+ if test_result {
// See ROBJECT_IVPTR() from include/ruby/internal/core/robject.h
// Guard that self is embedded
@@ -1988,7 +1996,7 @@ fn gen_get_ivar(
);
// Load the variable
- let offs = RUBY_OFFSET_ROBJECT_AS_ARY + (ivar_index * SIZEOF_VALUE) as i32;
+ let offs = ROBJECT_OFFSET_AS_ARY + (ivar_index * SIZEOF_VALUE) as i32;
let ivar_opnd = mem_opnd(64, REG0, offs);
mov(cb, REG1, ivar_opnd);
@@ -2019,17 +2027,16 @@ fn gen_get_ivar(
side_exit,
);
- // Check that the extended table is big enough
- if ivar_index > (ROBJECT_EMBED_LEN_MAX.as_usize()) {
+ if USE_RVARGC == 0 {
+ // Check that the extended table is big enough
// Check that the slot is inside the extended table (num_slots > index)
- let num_slots = mem_opnd(32, REG0, RUBY_OFFSET_ROBJECT_AS_HEAP_NUMIV);
-
+ let num_slots = mem_opnd(32, REG0, ROBJECT_OFFSET_NUMIV);
cmp(cb, num_slots, uimm_opnd(ivar_index as u64));
jle_ptr(cb, counted_exit!(ocb, side_exit, getivar_idx_out_of_range));
}
// Get a pointer to the extended table
- let tbl_opnd = mem_opnd(64, REG0, RUBY_OFFSET_ROBJECT_AS_HEAP_IVPTR);
+ let tbl_opnd = mem_opnd(64, REG0, ROBJECT_OFFSET_AS_HEAP_IVPTR);
mov(cb, REG0, tbl_opnd);
// Read the ivar from the extended table
diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs
index 8cebfd58a5..7c21bd962b 100644
--- a/yjit/src/cruby.rs
+++ b/yjit/src/cruby.rs
@@ -739,10 +739,6 @@ mod manual_defs {
pub const RUBY_OFFSET_RSTRUCT_AS_HEAP_PTR: i32 = 24; // struct RStruct, subfield "as.heap.ptr"
pub const RUBY_OFFSET_RSTRUCT_AS_ARY: i32 = 16; // struct RStruct, subfield "as.ary"
- pub const RUBY_OFFSET_ROBJECT_AS_ARY: i32 = 16; // struct RObject, subfield "as.ary"
- pub const RUBY_OFFSET_ROBJECT_AS_HEAP_NUMIV: i32 = 16; // struct RObject, subfield "as.heap.numiv"
- pub const RUBY_OFFSET_ROBJECT_AS_HEAP_IVPTR: i32 = 24; // struct RObject, subfield "as.heap.ivptr"
-
// Constants from rb_control_frame_t vm_core.h
pub const RUBY_OFFSET_CFP_PC: i32 = 0;
pub const RUBY_OFFSET_CFP_SP: i32 = 8;
diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs
index 88ad8e563c..b9c239cd23 100644
--- a/yjit/src/cruby_bindings.inc.rs
+++ b/yjit/src/cruby_bindings.inc.rs
@@ -1,5 +1,6 @@
/* automatically generated by rust-bindgen 0.59.2 */
+pub const USE_RVARGC: u32 = 1;
pub const INTEGER_REDEFINED_OP_FLAG: u32 = 1;
pub const FLOAT_REDEFINED_OP_FLAG: u32 = 2;
pub const STRING_REDEFINED_OP_FLAG: u32 = 4;
@@ -110,8 +111,10 @@ extern "C" {
}
pub const ROBJECT_EMBED: ruby_robject_flags = 8192;
pub type ruby_robject_flags = u32;
-pub const ROBJECT_EMBED_LEN_MAX: ruby_robject_consts = 3;
-pub type ruby_robject_consts = u32;
+pub const ROBJECT_OFFSET_NUMIV: i32 = 16;
+pub const ROBJECT_OFFSET_AS_HEAP_IVPTR: i32 = 24;
+pub const ROBJECT_OFFSET_AS_HEAP_IV_INDEX_TBL: i32 = 32;
+pub const ROBJECT_OFFSET_AS_ARY: i32 = 24;
extern "C" {
pub static mut rb_mKernel: VALUE;
}