mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
hide rb_funcallv_with_cc from public
Requested by ko1. Also, because now that this function is internal use only, why not just directly use struct rb_call_cache to purge the ZALLOC.
This commit is contained in:
parent
b005d7c2e2
commit
dd2b9d4a96
4 changed files with 62 additions and 67 deletions
|
@ -1892,10 +1892,6 @@ VALUE rb_funcallv_public(VALUE, ID, int, const VALUE*);
|
||||||
#define rb_funcall3 rb_funcallv_public
|
#define rb_funcall3 rb_funcallv_public
|
||||||
VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE*);
|
VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE*);
|
||||||
VALUE rb_funcall_with_block(VALUE, ID, int, const VALUE*, VALUE);
|
VALUE rb_funcall_with_block(VALUE, ID, int, const VALUE*, VALUE);
|
||||||
#if GCC_VERSION_SINCE(3, 3, 0)
|
|
||||||
__attribute__((__nonnull__ (1))) /* TODO: should check using configure */
|
|
||||||
#endif
|
|
||||||
VALUE rb_funcallv_with_cc(void**, VALUE, ID, int, const VALUE*);
|
|
||||||
int rb_scan_args(int, const VALUE*, const char*, ...);
|
int rb_scan_args(int, const VALUE*, const char*, ...);
|
||||||
VALUE rb_call_super(int, const VALUE*);
|
VALUE rb_call_super(int, const VALUE*);
|
||||||
VALUE rb_current_receiver(void);
|
VALUE rb_current_receiver(void);
|
||||||
|
@ -2611,19 +2607,10 @@ __extension__({ \
|
||||||
const VALUE rb_funcall_args[] = {__VA_ARGS__}; \
|
const VALUE rb_funcall_args[] = {__VA_ARGS__}; \
|
||||||
const int rb_funcall_nargs = \
|
const int rb_funcall_nargs = \
|
||||||
(int)(sizeof(rb_funcall_args) / sizeof(VALUE)); \
|
(int)(sizeof(rb_funcall_args) / sizeof(VALUE)); \
|
||||||
static void *rb_funcall_opaque_cc = NULL; \
|
rb_funcallv(recv, mid, \
|
||||||
rb_funcallv_with_cc(&rb_funcall_opaque_cc, \
|
|
||||||
recv, mid, \
|
|
||||||
rb_varargs_argc_check(rb_funcall_argc, rb_funcall_nargs), \
|
rb_varargs_argc_check(rb_funcall_argc, rb_funcall_nargs), \
|
||||||
rb_funcall_nargs ? rb_funcall_args : NULL); \
|
rb_funcall_nargs ? rb_funcall_args : NULL); \
|
||||||
})
|
})
|
||||||
|
|
||||||
# define rb_funcallv(recv, mid, argc, argv) \
|
|
||||||
__extension__({ \
|
|
||||||
static void *rb_funcallv_opaque_cc = NULL; \
|
|
||||||
rb_funcallv_with_cc(&rb_funcallv_opaque_cc, \
|
|
||||||
recv, mid, argc,argv); \
|
|
||||||
})
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RUBY_DONT_SUBST
|
#ifndef RUBY_DONT_SUBST
|
||||||
|
|
52
internal.h
52
internal.h
|
@ -2314,6 +2314,58 @@ void Init_vm_stack_canary(void);
|
||||||
/* vm_method.c */
|
/* vm_method.c */
|
||||||
void Init_eval_method(void);
|
void Init_eval_method(void);
|
||||||
|
|
||||||
|
enum method_missing_reason {
|
||||||
|
MISSING_NOENTRY = 0x00,
|
||||||
|
MISSING_PRIVATE = 0x01,
|
||||||
|
MISSING_PROTECTED = 0x02,
|
||||||
|
MISSING_FCALL = 0x04,
|
||||||
|
MISSING_VCALL = 0x08,
|
||||||
|
MISSING_SUPER = 0x10,
|
||||||
|
MISSING_MISSING = 0x20,
|
||||||
|
MISSING_NONE = 0x40
|
||||||
|
};
|
||||||
|
struct rb_callable_method_entry_struct;
|
||||||
|
struct rb_execution_context_struct;
|
||||||
|
struct rb_control_frame_struct;
|
||||||
|
struct rb_calling_info;
|
||||||
|
struct rb_call_info;
|
||||||
|
struct rb_call_cache {
|
||||||
|
/* inline cache: keys */
|
||||||
|
rb_serial_t method_state;
|
||||||
|
rb_serial_t class_serial;
|
||||||
|
|
||||||
|
/* inline cache: values */
|
||||||
|
const struct rb_callable_method_entry_struct *me;
|
||||||
|
|
||||||
|
VALUE (*call)(struct rb_execution_context_struct *ec,
|
||||||
|
struct rb_control_frame_struct *cfp,
|
||||||
|
struct rb_calling_info *calling,
|
||||||
|
const struct rb_call_info *ci,
|
||||||
|
struct rb_call_cache *cc);
|
||||||
|
|
||||||
|
union {
|
||||||
|
unsigned int index; /* used by ivar */
|
||||||
|
enum method_missing_reason method_missing_reason; /* used by method_missing */
|
||||||
|
int inc_sp; /* used by cfunc */
|
||||||
|
} aux;
|
||||||
|
};
|
||||||
|
struct rb_call_cache_and_mid {
|
||||||
|
struct rb_call_cache cc;
|
||||||
|
ID mid;
|
||||||
|
};
|
||||||
|
VALUE rb_funcallv_with_cc(struct rb_call_cache_and_mid*, VALUE, ID, int, const VALUE*)
|
||||||
|
#if GCC_VERSION_SINCE(3, 3, 0) && defined(__OPTIMIZE__)
|
||||||
|
__attribute__((__visibility__("default"), __nonnull__(1)))
|
||||||
|
# define rb_funcallv(recv, mid, argc, argv) \
|
||||||
|
__extension__({ \
|
||||||
|
static struct rb_call_cache_and_mid \
|
||||||
|
rb_funcallv_opaque_cc = { {0, }, 0, }; \
|
||||||
|
rb_funcallv_with_cc(&rb_funcallv_opaque_cc, \
|
||||||
|
recv, mid, argc,argv); \
|
||||||
|
})
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
/* miniprelude.c, prelude.c */
|
/* miniprelude.c, prelude.c */
|
||||||
void Init_prelude(void);
|
void Init_prelude(void);
|
||||||
|
|
||||||
|
|
29
vm_core.h
29
vm_core.h
|
@ -234,17 +234,6 @@ union iseq_inline_storage_entry {
|
||||||
struct iseq_inline_cache_entry cache;
|
struct iseq_inline_cache_entry cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum method_missing_reason {
|
|
||||||
MISSING_NOENTRY = 0x00,
|
|
||||||
MISSING_PRIVATE = 0x01,
|
|
||||||
MISSING_PROTECTED = 0x02,
|
|
||||||
MISSING_FCALL = 0x04,
|
|
||||||
MISSING_VCALL = 0x08,
|
|
||||||
MISSING_SUPER = 0x10,
|
|
||||||
MISSING_MISSING = 0x20,
|
|
||||||
MISSING_NONE = 0x40
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rb_call_info {
|
struct rb_call_info {
|
||||||
/* fixed at compile time */
|
/* fixed at compile time */
|
||||||
ID mid;
|
ID mid;
|
||||||
|
@ -268,27 +257,9 @@ struct rb_calling_info {
|
||||||
int argc;
|
int argc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rb_call_cache;
|
|
||||||
struct rb_execution_context_struct;
|
struct rb_execution_context_struct;
|
||||||
typedef VALUE (*vm_call_handler)(struct rb_execution_context_struct *ec, struct rb_control_frame_struct *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc);
|
typedef VALUE (*vm_call_handler)(struct rb_execution_context_struct *ec, struct rb_control_frame_struct *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc);
|
||||||
|
|
||||||
struct rb_call_cache {
|
|
||||||
/* inline cache: keys */
|
|
||||||
rb_serial_t method_state;
|
|
||||||
rb_serial_t class_serial;
|
|
||||||
|
|
||||||
/* inline cache: values */
|
|
||||||
const rb_callable_method_entry_t *me;
|
|
||||||
|
|
||||||
vm_call_handler call;
|
|
||||||
|
|
||||||
union {
|
|
||||||
unsigned int index; /* used by ivar */
|
|
||||||
enum method_missing_reason method_missing_reason; /* used by method_missing */
|
|
||||||
int inc_sp; /* used by cfunc */
|
|
||||||
} aux;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
#define CoreDataFromValue(obj, type) (type*)DATA_PTR(obj)
|
#define CoreDataFromValue(obj, type) (type*)DATA_PTR(obj)
|
||||||
#else
|
#else
|
||||||
|
|
33
vm_eval.c
33
vm_eval.c
|
@ -876,34 +876,19 @@ rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv)
|
||||||
* \param argv pointer to an array of method arguments
|
* \param argv pointer to an array of method arguments
|
||||||
*/
|
*/
|
||||||
VALUE
|
VALUE
|
||||||
rb_funcallv_with_cc(void **ptr, VALUE recv, ID mid, int argc, const VALUE *argv)
|
rb_funcallv_with_cc(struct rb_call_cache_and_mid *cc, VALUE recv, ID mid, int argc, const VALUE *argv)
|
||||||
{
|
{
|
||||||
VM_ASSERT(ptr);
|
if (LIKELY(cc->mid == mid)) {
|
||||||
struct opaque {
|
const struct rb_call_info ci = { mid, VM_CALL_ARGS_SIMPLE, argc, };
|
||||||
struct rb_call_cache cc;
|
|
||||||
ID mid;
|
|
||||||
} *cc;
|
|
||||||
if (UNLIKELY(! *ptr)) {
|
|
||||||
*ptr = ZALLOC(struct opaque);
|
|
||||||
}
|
|
||||||
cc = *ptr;
|
|
||||||
|
|
||||||
const struct rb_call_info ci = { mid, VM_CALL_ARGS_SIMPLE, argc, };
|
|
||||||
if (UNLIKELY(cc->mid != mid)) {
|
|
||||||
*cc = (struct opaque) /* reset */ { { 0, }, mid, };
|
|
||||||
return rb_funcallv(recv, mid, argc, argv);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vm_search_method(&ci, &cc->cc, recv);
|
vm_search_method(&ci, &cc->cc, recv);
|
||||||
|
|
||||||
|
if (LIKELY(! UNDEFINED_METHOD_ENTRY_P(cc->cc.me))) {
|
||||||
|
return rb_vm_call0(GET_EC(), recv, mid, argc, argv, cc->cc.me);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNLIKELY(UNDEFINED_METHOD_ENTRY_P(cc->cc.me))) {
|
*cc = (struct rb_call_cache_and_mid) /* reset */ { { 0, }, mid, };
|
||||||
/* :FIXME: this path can be made faster */
|
return rb_funcallv(recv, mid, argc, argv);
|
||||||
return rb_funcallv(recv, mid, argc, argv);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return rb_vm_call0(GET_EC(), recv, mid, argc, argv, cc->cc.me);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue