mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
Make union for positions and succ_index_table in rb_iseq_constant_body
We only use either positions and succ_index_table (when VM_INSN_INFO_TABLE_IMPL == 2, positions is converted to succ_index_table), so we waste 8 bytes in rb_iseq_constant_body. This changes it so that they are in a union.
This commit is contained in:
1 parent
53bc085645
commit
b548f16e30
5 files changed
+62
-73
Notes:
git
2026-08-24 13:34:39 +00:00
No files matched your search
@@ -983,49 +983,35 @@ define print_lineno
|
||||
set $index = 0
|
||||
set $size = $iseq->body->insns_info.size
|
||||
set $table = $iseq->body->insns_info.body
|
||||
set $positions = $iseq->body->insns_info.positions
|
||||
#printf "size: %d\n", $size
|
||||
if $size == 0
|
||||
else
|
||||
if $size == 1
|
||||
printf "%d", $table[0].line_no
|
||||
else
|
||||
if $positions
|
||||
# get_insn_info_linear_search
|
||||
set $index = 1
|
||||
while $index < $size
|
||||
#printf "table[%d]: position: %d, line: %d, pos: %d\n", $i, $positions[$i], $table[$i].line_no, $pos
|
||||
if $positions[$index] > $pos
|
||||
loop_break
|
||||
end
|
||||
set $index = $index + 1
|
||||
if $positions[$index] == $pos
|
||||
loop_break
|
||||
end
|
||||
end
|
||||
# get_insn_info_succinct_bitvector (VM_INSN_INFO_TABLE_IMPL == 2).
|
||||
# insns_info.positions and insns_info.succ_index_table share a union, and
|
||||
# an iseq running on the stack always has succ_index_table.
|
||||
set $sd = $iseq->body->insns_info.positions_or_succ_index_table.succ_index_table
|
||||
set $immediate_table_size = sizeof($sd->imm_part) / sizeof(uint64_t) * 9
|
||||
if $pos < $immediate_table_size
|
||||
set $i = $pos / 9
|
||||
set $j = $pos % 9
|
||||
set $index = ((int)($sd->imm_part[$i] >> ($j * 7))) & 0x7f
|
||||
else
|
||||
# get_insn_info_succinct_bitvector
|
||||
set $sd = $iseq->body->insns_info.succ_index_table
|
||||
set $immediate_table_size = sizeof($sd->imm_part) / sizeof(uint64_t) * 9
|
||||
if $pos < $immediate_table_size
|
||||
set $i = $pos / 9
|
||||
set $j = $pos % 9
|
||||
set $index = ((int)($sd->imm_part[$i] >> ($j * 7))) & 0x7f
|
||||
else
|
||||
set $block_index = ($pos - $immediate_table_size) / 512
|
||||
set $block = &$sd->succ_part[$block_index]
|
||||
set $block_bit_index = ($pos - $immediate_table_size) % 512
|
||||
set $small_block_index = $block_bit_index / 64
|
||||
set $small_block_popcount = $small_block_index == 0 ? 0 : (((int)($block->small_block_ranks >> (($small_block_index - 1) * 9))) & 0x1ff)
|
||||
set $x = $block->bits[$small_block_index] << (63 - $block_bit_index % 64)
|
||||
set $x = ($x & 0x5555555555555555) + ($x >> 1 & 0x5555555555555555)
|
||||
set $x = ($x & 0x3333333333333333) + ($x >> 2 & 0x3333333333333333)
|
||||
set $x = ($x & 0x0707070707070707) + ($x >> 4 & 0x0707070707070707)
|
||||
set $x = ($x & 0x001f001f001f001f) + ($x >> 8 & 0x001f001f001f001f)
|
||||
set $x = ($x & 0x0000003f0000003f) + ($x >>16 & 0x0000003f0000003f)
|
||||
set $popcnt = ($x & 0x7f) + ($x >>32 & 0x7f)
|
||||
set $index = $block->rank + $small_block_popcount + $popcnt
|
||||
end
|
||||
set $block_index = ($pos - $immediate_table_size) / 512
|
||||
set $block = &$sd->succ_part[$block_index]
|
||||
set $block_bit_index = ($pos - $immediate_table_size) % 512
|
||||
set $small_block_index = $block_bit_index / 64
|
||||
set $small_block_popcount = $small_block_index == 0 ? 0 : (((int)($block->small_block_ranks >> (($small_block_index - 1) * 9))) & 0x1ff)
|
||||
set $x = $block->bits[$small_block_index] << (63 - $block_bit_index % 64)
|
||||
set $x = ($x & 0x5555555555555555) + ($x >> 1 & 0x5555555555555555)
|
||||
set $x = ($x & 0x3333333333333333) + ($x >> 2 & 0x3333333333333333)
|
||||
set $x = ($x & 0x0707070707070707) + ($x >> 4 & 0x0707070707070707)
|
||||
set $x = ($x & 0x001f001f001f001f) + ($x >> 8 & 0x001f001f001f001f)
|
||||
set $x = ($x & 0x0000003f0000003f) + ($x >>16 & 0x0000003f0000003f)
|
||||
set $popcnt = ($x & 0x7f) + ($x >>32 & 0x7f)
|
||||
set $index = $block->rank + $small_block_popcount + $popcnt
|
||||
end
|
||||
printf "%d", $table[$index-1].line_no
|
||||
end
|
||||
|
||||
@@ -1700,10 +1700,8 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
|
||||
}
|
||||
|
||||
#if VM_INSN_INFO_TABLE_IMPL == 2
|
||||
if (ISEQ_BODY(iseq)->insns_info.succ_index_table == NULL) {
|
||||
debugs("[compile step 7 (rb_iseq_insns_info_encode_positions)] \n");
|
||||
rb_iseq_insns_info_encode_positions(iseq);
|
||||
}
|
||||
debugs("[compile step 7 (rb_iseq_insns_info_encode_positions)] \n");
|
||||
rb_iseq_insns_info_encode_positions(iseq);
|
||||
#endif
|
||||
|
||||
if (compile_debug > 1) {
|
||||
@@ -2976,12 +2974,12 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
|
||||
|
||||
/* get rid of memory leak when REALLOC failed */
|
||||
body->insns_info.body = insns_info;
|
||||
body->insns_info.positions = positions;
|
||||
body->insns_info.positions_or_succ_index_table.positions = positions;
|
||||
|
||||
SIZED_REALLOC_N(insns_info, struct iseq_insn_info_entry, insns_info_index, insns_info_size);
|
||||
body->insns_info.body = insns_info;
|
||||
SIZED_REALLOC_N(positions, unsigned int, insns_info_index, positions_size);
|
||||
body->insns_info.positions = positions;
|
||||
body->insns_info.positions_or_succ_index_table.positions = positions;
|
||||
body->insns_info.size = insns_info_index;
|
||||
|
||||
return COMPILE_OK;
|
||||
@@ -14044,7 +14042,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
|
||||
load_body->param.keyword = ibf_load_param_keyword(load, param_keyword_offset);
|
||||
load_body->param.flags.has_kw = (param_flags >> 4) & 1;
|
||||
load_body->insns_info.body = ibf_load_insns_info_body(load, insns_info_body_offset, insns_info_size);
|
||||
load_body->insns_info.positions = ibf_load_insns_info_positions(load, insns_info_positions_offset, insns_info_size);
|
||||
load_body->insns_info.positions_or_succ_index_table.positions = ibf_load_insns_info_positions(load, insns_info_positions_offset, insns_info_size);
|
||||
load_body->local_table = ibf_load_local_table(load, local_table_offset, local_table_size);
|
||||
load_body->lvar_states = ibf_load_lvar_states(load, lvar_states_offset, local_table_size, load_body->local_table);
|
||||
ibf_load_catch_table(load, catch_table_offset, catch_table_size, iseq);
|
||||
|
||||
@@ -203,9 +203,10 @@ rb_iseq_free(const rb_iseq_t *iseq)
|
||||
#endif
|
||||
SIZED_FREE_N(body->iseq_encoded, body->iseq_size);
|
||||
SIZED_FREE_N(body->insns_info.body, body->insns_info.size);
|
||||
SIZED_FREE_N(body->insns_info.positions, body->insns_info.size);
|
||||
#if VM_INSN_INFO_TABLE_IMPL == 2
|
||||
ruby_xfree(body->insns_info.succ_index_table);
|
||||
ruby_xfree(body->insns_info.positions_or_succ_index_table.succ_index_table);
|
||||
#else
|
||||
SIZED_FREE_N(body->insns_info.positions_or_succ_index_table.positions, body->insns_info.size);
|
||||
#endif
|
||||
SIZED_FREE_N(body->is_entries, ISEQ_IS_SIZE(body));
|
||||
SIZED_FREE_N(body->call_data, body->ci_size);
|
||||
@@ -806,13 +807,10 @@ rb_iseq_insns_info_encode_positions(const rb_iseq_t *iseq)
|
||||
struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
|
||||
int size = body->insns_info.size;
|
||||
int max_pos = body->iseq_size;
|
||||
int *data = (int *)body->insns_info.positions;
|
||||
if (body->insns_info.succ_index_table) ruby_xfree(body->insns_info.succ_index_table);
|
||||
body->insns_info.succ_index_table = succ_index_table_create(max_pos, data, size);
|
||||
#if VM_CHECK_MODE == 0
|
||||
SIZED_FREE_N(body->insns_info.positions, body->insns_info.size);
|
||||
body->insns_info.positions = NULL;
|
||||
#endif
|
||||
unsigned int *positions = body->insns_info.positions_or_succ_index_table.positions;
|
||||
struct succ_index_table *sd = succ_index_table_create(max_pos, (int *)positions, size);
|
||||
SIZED_FREE_N(positions, size);
|
||||
body->insns_info.positions_or_succ_index_table.succ_index_table = sd;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -822,7 +820,7 @@ rb_iseq_insns_info_decode_positions(const struct rb_iseq_constant_body *body)
|
||||
{
|
||||
int size = body->insns_info.size;
|
||||
int max_pos = body->iseq_size;
|
||||
struct succ_index_table *sd = body->insns_info.succ_index_table;
|
||||
struct succ_index_table *sd = body->insns_info.positions_or_succ_index_table.succ_index_table;
|
||||
return succ_index_table_invert(max_pos, sd, size);
|
||||
}
|
||||
#endif
|
||||
@@ -2364,7 +2362,7 @@ get_insn_info_binary_search(const rb_iseq_t *iseq, size_t pos)
|
||||
const struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
|
||||
size_t size = body->insns_info.size;
|
||||
const struct iseq_insn_info_entry *insns_info = body->insns_info.body;
|
||||
const unsigned int *positions = body->insns_info.positions;
|
||||
const unsigned int *positions = body->insns_info.positions_or_succ_index_table.positions;
|
||||
const int debug = 0;
|
||||
|
||||
if (debug) {
|
||||
@@ -2420,16 +2418,9 @@ get_insn_info_succinct_bitvector(const rb_iseq_t *iseq, size_t pos)
|
||||
const int debug = 0;
|
||||
|
||||
if (debug) {
|
||||
#if VM_CHECK_MODE > 0
|
||||
const unsigned int *positions = body->insns_info.positions;
|
||||
printf("size: %"PRIuSIZE"\n", size);
|
||||
printf("insns_info[%"PRIuSIZE"]: position: %d, line: %d, pos: %"PRIuSIZE"\n",
|
||||
(size_t)0, positions[0], insns_info[0].line_no, pos);
|
||||
#else
|
||||
printf("size: %"PRIuSIZE"\n", size);
|
||||
printf("insns_info[%"PRIuSIZE"]: line: %d, pos: %"PRIuSIZE"\n",
|
||||
(size_t)0, insns_info[0].line_no, pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
@@ -2440,8 +2431,8 @@ get_insn_info_succinct_bitvector(const rb_iseq_t *iseq, size_t pos)
|
||||
}
|
||||
else {
|
||||
int index;
|
||||
VM_ASSERT(body->insns_info.succ_index_table != NULL);
|
||||
index = succ_index_lookup(body->insns_info.succ_index_table, (int)pos);
|
||||
VM_ASSERT(body->insns_info.positions_or_succ_index_table.succ_index_table != NULL);
|
||||
index = succ_index_lookup(body->insns_info.positions_or_succ_index_table.succ_index_table, (int)pos);
|
||||
return &insns_info[index-1];
|
||||
}
|
||||
}
|
||||
@@ -2455,12 +2446,11 @@ get_insn_info(const rb_iseq_t *iseq, size_t pos)
|
||||
|
||||
#if VM_CHECK_MODE > 0 || VM_INSN_INFO_TABLE_IMPL == 0
|
||||
static const struct iseq_insn_info_entry *
|
||||
get_insn_info_linear_search(const rb_iseq_t *iseq, size_t pos)
|
||||
get_insn_info_linear_search(const rb_iseq_t *iseq, const unsigned int *positions, size_t pos)
|
||||
{
|
||||
const struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
|
||||
size_t i = 0, size = body->insns_info.size;
|
||||
const struct iseq_insn_info_entry *insns_info = body->insns_info.body;
|
||||
const unsigned int *positions = body->insns_info.positions;
|
||||
const int debug = 0;
|
||||
|
||||
if (debug) {
|
||||
@@ -2496,7 +2486,7 @@ get_insn_info_linear_search(const rb_iseq_t *iseq, size_t pos)
|
||||
static const struct iseq_insn_info_entry *
|
||||
get_insn_info(const rb_iseq_t *iseq, size_t pos)
|
||||
{
|
||||
return get_insn_info_linear_search(iseq, pos);
|
||||
return get_insn_info_linear_search(iseq, ISEQ_BODY(iseq)->insns_info.positions_or_succ_index_table.positions, pos);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2506,11 +2496,19 @@ validate_get_insn_info(const rb_iseq_t *iseq)
|
||||
{
|
||||
const struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
|
||||
size_t i;
|
||||
#if VM_INSN_INFO_TABLE_IMPL == 2
|
||||
unsigned int *positions = rb_iseq_insns_info_decode_positions(body);
|
||||
#else
|
||||
const unsigned int *positions = body->insns_info.positions_or_succ_index_table.positions;
|
||||
#endif
|
||||
for (i = 0; i < body->iseq_size; i++) {
|
||||
if (get_insn_info_linear_search(iseq, i) != get_insn_info(iseq, i)) {
|
||||
if (get_insn_info_linear_search(iseq, positions, i) != get_insn_info(iseq, i)) {
|
||||
rb_bug("validate_get_insn_info: get_insn_info_linear_search(iseq, %"PRIuSIZE") != get_insn_info(iseq, %"PRIuSIZE")", i, i);
|
||||
}
|
||||
}
|
||||
#if VM_INSN_INFO_TABLE_IMPL == 2
|
||||
SIZED_FREE_N(positions, body->insns_info.size);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -504,11 +504,13 @@ struct rb_iseq_constant_body {
|
||||
/* insn info, must be freed */
|
||||
struct iseq_insn_info {
|
||||
const struct iseq_insn_info_entry *body;
|
||||
unsigned int *positions;
|
||||
unsigned int size;
|
||||
union {
|
||||
unsigned int *positions;
|
||||
#if VM_INSN_INFO_TABLE_IMPL == 2
|
||||
struct succ_index_table *succ_index_table;
|
||||
struct succ_index_table *succ_index_table;
|
||||
#endif
|
||||
} positions_or_succ_index_table;
|
||||
unsigned int size;
|
||||
} insns_info;
|
||||
|
||||
const ID *local_table; /* must free */
|
||||
|
||||
Generated
+8
-3
@@ -1260,11 +1260,16 @@ pub struct rb_iseq_constant_body_rb_iseq_parameters_rb_iseq_param_keyword {
|
||||
pub default_values: *mut VALUE,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct rb_iseq_constant_body_iseq_insn_info {
|
||||
pub body: *const iseq_insn_info_entry,
|
||||
pub positions: *mut ::std::os::raw::c_uint,
|
||||
pub positions_or_succ_index_table: rb_iseq_constant_body_iseq_insn_info__bindgen_ty_1,
|
||||
pub size: ::std::os::raw::c_uint,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub union rb_iseq_constant_body_iseq_insn_info__bindgen_ty_1 {
|
||||
pub positions: *mut ::std::os::raw::c_uint,
|
||||
pub succ_index_table: *mut succ_index_table,
|
||||
}
|
||||
#[repr(C)]
|
||||
@@ -2094,7 +2099,7 @@ pub struct zjit_jit_frame {
|
||||
pub stack: __IncompleteArrayField<VALUE>,
|
||||
}
|
||||
pub const ISEQ_BODY_OFFSET_PARAM: zjit_struct_offsets = 16;
|
||||
pub const ISEQ_BODY_OFFSET_OUTER_VARIABLES: zjit_struct_offsets = 288;
|
||||
pub const ISEQ_BODY_OFFSET_OUTER_VARIABLES: zjit_struct_offsets = 280;
|
||||
pub const RUBY_OFFSET_THREAD_RACTOR: zjit_struct_offsets = 24;
|
||||
pub type zjit_struct_offsets = u32;
|
||||
#[repr(C)]
|
||||
|
||||
Reference in new issue
Block a user