diff --git a/compile.c b/compile.c index 628974ab07b..e761cd74627 100644 --- a/compile.c +++ b/compile.c @@ -2626,14 +2626,16 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) #ifdef USE_ISEQ_NODE_ID static void -add_node_id(uint8_t *node_ids, unsigned int *node_ids_size, int node_id) +add_node_id(uint8_t *node_ids, unsigned int *node_ids_size, int node_id, int *prev_node_id) { - uint32_t v = (uint32_t)node_id + 1; + int delta = node_id - *prev_node_id; + uint32_t zz = ((uint32_t)delta << 1) ^ (uint32_t)(delta >> 31); + *prev_node_id = node_id; do { - uint8_t byte = v & 0x7f; - v >>= 7; - node_ids[(*node_ids_size)++] = v ? (byte | 0x80) : byte; - } while (v); + uint8_t byte = zz & 0x7f; + zz >>= 7; + node_ids[(*node_ids_size)++] = zz ? (byte | 0x80) : byte; + } while (zz); } #endif @@ -2786,6 +2788,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) #ifdef USE_ISEQ_NODE_ID uint8_t *node_ids = ALLOC_N(uint8_t, (size_t)insn_num * 5); unsigned int node_ids_size = 0; + int prev_node_id = 0; #endif if (ISEQ_IS_SIZE(body)) { body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(body)); @@ -2965,7 +2968,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) } if (add_insn_info(insns_info, positions, insns_info_index, code_index, iobj)) insns_info_index++; #ifdef USE_ISEQ_NODE_ID - add_node_id(node_ids, &node_ids_size, iobj->insn_info.node_id); + add_node_id(node_ids, &node_ids_size, iobj->insn_info.node_id, &prev_node_id); #endif code_index += len; break; @@ -3003,7 +3006,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) } if (add_adjust_info(insns_info, positions, insns_info_index, code_index, adjust)) insns_info_index++; #ifdef USE_ISEQ_NODE_ID - add_node_id(node_ids, &node_ids_size, -1); + add_node_id(node_ids, &node_ids_size, -1, &prev_node_id); #endif } if (diff > 1) { @@ -12814,7 +12817,7 @@ typedef uint32_t ibf_offset_t; #define IBF_MAJOR_VERSION ISEQ_MAJOR_VERSION #ifdef RUBY_DEVEL -#define IBF_DEVEL_VERSION 11 +#define IBF_DEVEL_VERSION 12 #define IBF_MINOR_VERSION (ISEQ_MINOR_VERSION * 10000 + IBF_DEVEL_VERSION) #else #define IBF_MINOR_VERSION ISEQ_MINOR_VERSION diff --git a/iseq.c b/iseq.c index f719d9ffac6..5ab6998e69b 100644 --- a/iseq.c +++ b/iseq.c @@ -2581,16 +2581,16 @@ rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos) static int node_id_stream_read(const uint8_t **ptr, const uint8_t *end) { - uint32_t v = 0; + uint32_t zz = 0; unsigned int shift = 0; while (*ptr < end) { uint8_t byte = **ptr; (*ptr)++; - v |= (uint32_t)(byte & 0x7f) << shift; + zz |= (uint32_t)(byte & 0x7f) << shift; if (!(byte & 0x80)) break; shift += 7; } - return (int)v - 1; + return (int)(zz >> 1) ^ -(int)(zz & 1); } int @@ -2605,10 +2605,11 @@ rb_iseq_node_id(const rb_iseq_t *iseq, size_t pos) const uint8_t *ptr = body->insns_info.node_ids; const uint8_t *end = ptr + body->insns_info.node_ids_size; size_t code_pos = 0; + int node_id = 0; while (ptr < end && code_pos < body->iseq_size) { size_t len = (size_t)insn_len(code[code_pos]); - int node_id = node_id_stream_read(&ptr, end); + node_id += node_id_stream_read(&ptr, end); if (pos < code_pos + len) { return node_id; } @@ -3798,10 +3799,9 @@ iseq_data_to_ary(const rb_iseq_t *iseq) prev_insn_info = NULL; #ifdef USE_ISEQ_NODE_ID VALUE node_ids = rb_ary_new(); - /* The node id stream holds one varint per instruction, in the same - * order as the instructions in nbody. */ const uint8_t *nid_ptr = iseq_body->insns_info.node_ids; const uint8_t *nid_end = nid_ptr ? nid_ptr + iseq_body->insns_info.node_ids_size : NULL; + int node_id = 0; #endif for (l=0, pos=0; l