Move BOP macros to separate file

This commit moves ruby_basic_operators and the unredefined macros out of
vm_core.h and into basic_operators.h so that we can use them more
broadly in places where we currently use a method look up via
`rb_method_basic_definition_p` (e.g. object.c, numeric.c, complex.c,
enum.c, but also in internal/compar.h after introducing BOP_CMP and
elsewhere if we introduce more BOPs)

The most controversial part of this change is probably moving
redefined_flag out of rb_vm_t. [vm_opt_method_def_table and
vm_opt_mid_table](9da2a5204f/vm.c)
are not part of rb_vm_t either, and I think this fits well with those.
But more significantly it seems to result in one fewer instruction. For
example:

Before:

```
(lldb) disassemble -n vm_opt_str_freeze
miniruby`vm_exec_core:
miniruby[0x10028233e] <+14558>: movq   0x11a86b(%rip), %rax      ; ruby_current_vm_ptr
miniruby[0x100282345] <+14565>: testb  $0x4, 0x242c(%rax)
```

After:

```
(lldb) disassemble -n vm_opt_str_freeze
ruby`vm_exec_core:
ruby[0x100280ebe] <+14510>: testb  $0x4, 0x120147(%rip)      ; ruby_vm_redefined_flag + 43
```

Co-authored-by: John Hawthorn <jhawthorn@github.com>
This commit is contained in:
Daniel Colson 2022-11-30 20:28:14 -05:00 коммит произвёл John Hawthorn
Родитель 9d4483f24d
Коммит c43951e60e
4 изменённых файлов: 95 добавлений и 84 удалений

Просмотреть файл

@ -0,0 +1,62 @@
#ifndef INTERNAL_BOP_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_BOP_H
#include "internal.h"
#include "ruby/internal/dllexport.h"
enum ruby_basic_operators {
BOP_PLUS,
BOP_MINUS,
BOP_MULT,
BOP_DIV,
BOP_MOD,
BOP_EQ,
BOP_EQQ,
BOP_LT,
BOP_LE,
BOP_LTLT,
BOP_AREF,
BOP_ASET,
BOP_LENGTH,
BOP_SIZE,
BOP_EMPTY_P,
BOP_NIL_P,
BOP_SUCC,
BOP_GT,
BOP_GE,
BOP_NOT,
BOP_NEQ,
BOP_MATCH,
BOP_FREEZE,
BOP_UMINUS,
BOP_MAX,
BOP_MIN,
BOP_CALL,
BOP_AND,
BOP_OR,
BOP_LAST_
};
MJIT_SYMBOL_EXPORT_BEGIN
RUBY_EXTERN short ruby_vm_redefined_flag[BOP_LAST_];
MJIT_SYMBOL_EXPORT_END
/* optimize insn */
#define INTEGER_REDEFINED_OP_FLAG (1 << 0)
#define FLOAT_REDEFINED_OP_FLAG (1 << 1)
#define STRING_REDEFINED_OP_FLAG (1 << 2)
#define ARRAY_REDEFINED_OP_FLAG (1 << 3)
#define HASH_REDEFINED_OP_FLAG (1 << 4)
/* #define BIGNUM_REDEFINED_OP_FLAG (1 << 5) */
#define SYMBOL_REDEFINED_OP_FLAG (1 << 6)
#define TIME_REDEFINED_OP_FLAG (1 << 7)
#define REGEXP_REDEFINED_OP_FLAG (1 << 8)
#define NIL_REDEFINED_OP_FLAG (1 << 9)
#define TRUE_REDEFINED_OP_FLAG (1 << 10)
#define FALSE_REDEFINED_OP_FLAG (1 << 11)
#define PROC_REDEFINED_OP_FLAG (1 << 12)
#define BASIC_OP_UNREDEFINED_P(op, klass) (LIKELY(ruby_vm_redefined_flag[(op)]&(klass)) == 0)
#endif

2
vm.c
Просмотреть файл

@ -466,7 +466,6 @@ VALUE rb_cThread;
VALUE rb_mRubyVMFrozenCore;
VALUE rb_block_param_proxy;
#define ruby_vm_redefined_flag GET_VM()->redefined_flag
VALUE ruby_vm_const_missing_count = 0;
rb_vm_t *ruby_current_vm_ptr = NULL;
rb_ractor_t *ruby_single_main_ractor;
@ -1894,6 +1893,7 @@ rb_iter_break_value(VALUE val)
/* optimization: redefine management */
short ruby_vm_redefined_flag[BOP_LAST_];
static st_table *vm_opt_method_def_table = 0;
static st_table *vm_opt_mid_table = 0;

Просмотреть файл

@ -91,6 +91,7 @@ extern int ruby_assert_critical_section_entered;
#include "id.h"
#include "internal.h"
#include "internal/array.h"
#include "internal/basic_operators.h"
#include "internal/serial.h"
#include "internal/vm.h"
#include "method.h"
@ -582,40 +583,6 @@ enum ruby_special_exceptions {
ruby_special_error_count
};
enum ruby_basic_operators {
BOP_PLUS,
BOP_MINUS,
BOP_MULT,
BOP_DIV,
BOP_MOD,
BOP_EQ,
BOP_EQQ,
BOP_LT,
BOP_LE,
BOP_LTLT,
BOP_AREF,
BOP_ASET,
BOP_LENGTH,
BOP_SIZE,
BOP_EMPTY_P,
BOP_NIL_P,
BOP_SUCC,
BOP_GT,
BOP_GE,
BOP_NOT,
BOP_NEQ,
BOP_MATCH,
BOP_FREEZE,
BOP_UMINUS,
BOP_MAX,
BOP_MIN,
BOP_CALL,
BOP_AND,
BOP_OR,
BOP_LAST_
};
#define GetVMPtr(obj, ptr) \
GetCoreDataFromValue((obj), rb_vm_t, (ptr))
@ -775,7 +742,6 @@ typedef struct rb_vm_struct {
size_t fiber_machine_stack_size;
} default_params;
short redefined_flag[BOP_LAST_];
} rb_vm_t;
/* default values */
@ -808,23 +774,6 @@ typedef struct rb_vm_struct {
#define RUBY_VM_FIBER_MACHINE_STACK_SIZE_MIN ( 128 * 1024 * sizeof(VALUE))
#endif
/* optimize insn */
#define INTEGER_REDEFINED_OP_FLAG (1 << 0)
#define FLOAT_REDEFINED_OP_FLAG (1 << 1)
#define STRING_REDEFINED_OP_FLAG (1 << 2)
#define ARRAY_REDEFINED_OP_FLAG (1 << 3)
#define HASH_REDEFINED_OP_FLAG (1 << 4)
/* #define BIGNUM_REDEFINED_OP_FLAG (1 << 5) */
#define SYMBOL_REDEFINED_OP_FLAG (1 << 6)
#define TIME_REDEFINED_OP_FLAG (1 << 7)
#define REGEXP_REDEFINED_OP_FLAG (1 << 8)
#define NIL_REDEFINED_OP_FLAG (1 << 9)
#define TRUE_REDEFINED_OP_FLAG (1 << 10)
#define FALSE_REDEFINED_OP_FLAG (1 << 11)
#define PROC_REDEFINED_OP_FLAG (1 << 12)
#define BASIC_OP_UNREDEFINED_P(op, klass) (LIKELY((GET_VM()->redefined_flag[(op)]&(klass)) == 0))
#ifndef VM_DEBUG_BP_CHECK
#define VM_DEBUG_BP_CHECK 0
#endif

Просмотреть файл

@ -691,6 +691,37 @@ extern "C" {
elts: *const VALUE,
) -> VALUE;
}
pub const BOP_PLUS: ruby_basic_operators = 0;
pub const BOP_MINUS: ruby_basic_operators = 1;
pub const BOP_MULT: ruby_basic_operators = 2;
pub const BOP_DIV: ruby_basic_operators = 3;
pub const BOP_MOD: ruby_basic_operators = 4;
pub const BOP_EQ: ruby_basic_operators = 5;
pub const BOP_EQQ: ruby_basic_operators = 6;
pub const BOP_LT: ruby_basic_operators = 7;
pub const BOP_LE: ruby_basic_operators = 8;
pub const BOP_LTLT: ruby_basic_operators = 9;
pub const BOP_AREF: ruby_basic_operators = 10;
pub const BOP_ASET: ruby_basic_operators = 11;
pub const BOP_LENGTH: ruby_basic_operators = 12;
pub const BOP_SIZE: ruby_basic_operators = 13;
pub const BOP_EMPTY_P: ruby_basic_operators = 14;
pub const BOP_NIL_P: ruby_basic_operators = 15;
pub const BOP_SUCC: ruby_basic_operators = 16;
pub const BOP_GT: ruby_basic_operators = 17;
pub const BOP_GE: ruby_basic_operators = 18;
pub const BOP_NOT: ruby_basic_operators = 19;
pub const BOP_NEQ: ruby_basic_operators = 20;
pub const BOP_MATCH: ruby_basic_operators = 21;
pub const BOP_FREEZE: ruby_basic_operators = 22;
pub const BOP_UMINUS: ruby_basic_operators = 23;
pub const BOP_MAX: ruby_basic_operators = 24;
pub const BOP_MIN: ruby_basic_operators = 25;
pub const BOP_CALL: ruby_basic_operators = 26;
pub const BOP_AND: ruby_basic_operators = 27;
pub const BOP_OR: ruby_basic_operators = 28;
pub const BOP_LAST_: ruby_basic_operators = 29;
pub type ruby_basic_operators = u32;
pub type rb_serial_t = ::std::os::raw::c_ulonglong;
extern "C" {
pub fn rb_class_allocate_instance(klass: VALUE) -> VALUE;
@ -837,37 +868,6 @@ pub struct rb_iseq_constant_body__bindgen_ty_1_rb_iseq_param_keyword {
pub table: *const ID,
pub default_values: *mut VALUE,
}
pub const BOP_PLUS: ruby_basic_operators = 0;
pub const BOP_MINUS: ruby_basic_operators = 1;
pub const BOP_MULT: ruby_basic_operators = 2;
pub const BOP_DIV: ruby_basic_operators = 3;
pub const BOP_MOD: ruby_basic_operators = 4;
pub const BOP_EQ: ruby_basic_operators = 5;
pub const BOP_EQQ: ruby_basic_operators = 6;
pub const BOP_LT: ruby_basic_operators = 7;
pub const BOP_LE: ruby_basic_operators = 8;
pub const BOP_LTLT: ruby_basic_operators = 9;
pub const BOP_AREF: ruby_basic_operators = 10;
pub const BOP_ASET: ruby_basic_operators = 11;
pub const BOP_LENGTH: ruby_basic_operators = 12;
pub const BOP_SIZE: ruby_basic_operators = 13;
pub const BOP_EMPTY_P: ruby_basic_operators = 14;
pub const BOP_NIL_P: ruby_basic_operators = 15;
pub const BOP_SUCC: ruby_basic_operators = 16;
pub const BOP_GT: ruby_basic_operators = 17;
pub const BOP_GE: ruby_basic_operators = 18;
pub const BOP_NOT: ruby_basic_operators = 19;
pub const BOP_NEQ: ruby_basic_operators = 20;
pub const BOP_MATCH: ruby_basic_operators = 21;
pub const BOP_FREEZE: ruby_basic_operators = 22;
pub const BOP_UMINUS: ruby_basic_operators = 23;
pub const BOP_MAX: ruby_basic_operators = 24;
pub const BOP_MIN: ruby_basic_operators = 25;
pub const BOP_CALL: ruby_basic_operators = 26;
pub const BOP_AND: ruby_basic_operators = 27;
pub const BOP_OR: ruby_basic_operators = 28;
pub const BOP_LAST_: ruby_basic_operators = 29;
pub type ruby_basic_operators = u32;
#[repr(C)]
pub struct rb_captured_block {
pub self_: VALUE,