Skip to content

Commit

Permalink
internal/imemo.h rework
Browse files Browse the repository at this point in the history
Arrange contents and eliminate macros, to make them readable.

Macro IFUNC_NEW was deleted because there was only one usage.
  • Loading branch information
shyouhei committed Dec 26, 2019
1 parent 63c9f62 commit 989068c
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 98 deletions.
9 changes: 9 additions & 0 deletions debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
#include "symbol.h"
#include "id.h"

/* This is the only place struct RIMemo is actually used */
struct RIMemo {
VALUE flags;
VALUE v0;
VALUE v1;
VALUE v2;
VALUE v3;
};

/* for gdb */
const union {
enum ruby_special_consts special_consts;
Expand Down
2 changes: 2 additions & 0 deletions internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "internal/sanitizers.h"

#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
#define roomof(x, y) (((x) + (y) - 1) / (y))
#define type_roomof(x, y) roomof(sizeof(x), sizeof(y))

/* Prevent compiler from reordering access */
#define ACCESS_ONCE(type,x) (*((volatile type *)&(x)))
Expand Down
219 changes: 122 additions & 97 deletions internal/imemo.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,26 @@
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
*/
#include "ruby/config.h"
#include <stddef.h> /* for size_t */
#include "internal/array.h" /* for rb_ary_tmp_new_fill */
#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "internal/stdbool.h" /* for bool */
#include "ruby/ruby.h" /* for rb_block_call_func_t */

#ifndef IMEMO_DEBUG
#define IMEMO_DEBUG 0
# define IMEMO_DEBUG 0
#endif

struct RIMemo {
VALUE flags;
VALUE v0;
VALUE v1;
VALUE v2;
VALUE v3;
};
#define IMEMO_MASK 0x0f

/* FL_USER0 to FL_USER3 is for type */
#define IMEMO_FL_USHIFT (FL_USHIFT + 4)
#define IMEMO_FL_USER0 FL_USER4
#define IMEMO_FL_USER1 FL_USER5
#define IMEMO_FL_USER2 FL_USER6
#define IMEMO_FL_USER3 FL_USER7
#define IMEMO_FL_USER4 FL_USER8

enum imemo_type {
imemo_env = 0,
Expand All @@ -35,38 +43,6 @@ enum imemo_type {
imemo_ast = 9,
imemo_parser_strterm = 10
};
#define IMEMO_MASK 0x0f

static inline enum imemo_type
imemo_type(VALUE imemo)
{
return (RBASIC(imemo)->flags >> FL_USHIFT) & IMEMO_MASK;
}

static inline int
imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
{
if (LIKELY(!RB_SPECIAL_CONST_P(imemo))) {
/* fixed at compile time if imemo_type is given. */
const VALUE mask = (IMEMO_MASK << FL_USHIFT) | RUBY_T_MASK;
const VALUE expected_type = (imemo_type << FL_USHIFT) | T_IMEMO;
/* fixed at runtime. */
return expected_type == (RBASIC(imemo)->flags & mask);
}
else {
return 0;
}
}

VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);

/* FL_USER0 to FL_USER3 is for type */
#define IMEMO_FL_USHIFT (FL_USHIFT + 4)
#define IMEMO_FL_USER0 FL_USER4
#define IMEMO_FL_USER1 FL_USER5
#define IMEMO_FL_USER2 FL_USER6
#define IMEMO_FL_USER3 FL_USER7
#define IMEMO_FL_USER4 FL_USER8

/* CREF (Class REFerence) is defined in method.h */

Expand All @@ -79,9 +55,6 @@ struct vm_svar {
const VALUE others;
};


#define THROW_DATA_CONSUMED IMEMO_FL_USER0

/*! THROW_DATA */
struct vm_throw_data {
VALUE flags;
Expand All @@ -91,7 +64,7 @@ struct vm_throw_data {
int throw_state;
};

#define THROW_DATA_P(err) RB_TYPE_P((VALUE)(err), T_IMEMO)
#define THROW_DATA_CONSUMED IMEMO_FL_USER0

/* IFUNC (Internal FUNCtion) */

Expand All @@ -113,56 +86,13 @@ struct vm_ifunc {
struct vm_ifunc_argc argc;
};

#define IFUNC_NEW(a, b, c) ((struct vm_ifunc *)rb_imemo_new(imemo_ifunc, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0))
struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
static inline struct vm_ifunc *
rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data)
{
return rb_vm_ifunc_new(func, data, 0, UNLIMITED_ARGUMENTS);
}

typedef struct rb_imemo_tmpbuf_struct {
struct rb_imemo_tmpbuf_struct {
VALUE flags;
VALUE reserved;
VALUE *ptr; /* malloc'ed buffer */
struct rb_imemo_tmpbuf_struct *next; /* next imemo */
size_t cnt; /* buffer size in VALUE */
} rb_imemo_tmpbuf_t;

#define rb_imemo_tmpbuf_auto_free_pointer() rb_imemo_new(imemo_tmpbuf, 0, 0, 0, 0)
rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);

#define RB_IMEMO_TMPBUF_PTR(v) \
((void *)(((const struct rb_imemo_tmpbuf_struct *)(v))->ptr))

static inline void *
rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr)
{
return ((rb_imemo_tmpbuf_t *)v)->ptr = ptr;
}

static inline VALUE
rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
{
const void *src;
VALUE imemo;
rb_imemo_tmpbuf_t *tmpbuf;
void *dst;
size_t len;

SafeStringValue(str);
/* create tmpbuf to keep the pointer before xmalloc */
imemo = rb_imemo_tmpbuf_auto_free_pointer();
tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
len = RSTRING_LEN(str);
src = RSTRING_PTR(str);
dst = ruby_xmalloc(len);
memcpy(dst, src, len);
tmpbuf->ptr = dst;
return imemo;
}

void rb_strterm_mark(VALUE obj);
};

/*! MEMO
*
Expand All @@ -181,15 +111,11 @@ struct MEMO {
} u3;
};

#define MEMO_V1_SET(m, v) RB_OBJ_WRITE((m), &(m)->v1, (v))
#define MEMO_V2_SET(m, v) RB_OBJ_WRITE((m), &(m)->v2, (v))

#define MEMO_CAST(m) ((struct MEMO *)m)
/* ment is in method.h */

#define THROW_DATA_P(err) imemo_throw_data_p((VALUE)err)
#define MEMO_CAST(m) (R_CAST(MEMO)(m))
#define MEMO_NEW(a, b, c) ((struct MEMO *)rb_imemo_new(imemo_memo, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0))

#define roomof(x, y) (((x) + (y) - 1) / (y))
#define type_roomof(x, y) roomof(sizeof(x), sizeof(y))
#define MEMO_FOR(type, value) ((type *)RARRAY_PTR(value))
#define NEW_MEMO_FOR(type, value) \
((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value))
Expand All @@ -198,7 +124,21 @@ struct MEMO {
rb_ary_set_len((value), offsetof(type, member) / sizeof(VALUE)), \
MEMO_FOR(type, value))

/* ment is in method.h */
typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);
rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
void rb_strterm_mark(VALUE obj);
static inline enum imemo_type imemo_type(VALUE imemo);
static inline int imemo_type_p(VALUE imemo, enum imemo_type imemo_type);
static inline bool imemo_throw_data_p(VALUE imemo);
static inline struct vm_ifunc *rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data);
static inline VALUE rb_imemo_tmpbuf_auto_free_pointer(void);
static inline void *RB_IMEMO_TMPBUF_PTR(VALUE v);
static inline void *rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr);
static inline VALUE rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str);
static inline void MEMO_V1_SET(struct MEMO *m, VALUE v);
static inline void MEMO_V2_SET(struct MEMO *m, VALUE v);

RUBY_SYMBOL_EXPORT_BEGIN
#if IMEMO_DEBUG
Expand All @@ -209,4 +149,89 @@ VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
#endif
RUBY_SYMBOL_EXPORT_END

static inline enum imemo_type
imemo_type(VALUE imemo)
{
return (RBASIC(imemo)->flags >> FL_USHIFT) & IMEMO_MASK;
}

static inline int
imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
{
if (LIKELY(!RB_SPECIAL_CONST_P(imemo))) {
/* fixed at compile time if imemo_type is given. */
const VALUE mask = (IMEMO_MASK << FL_USHIFT) | RUBY_T_MASK;
const VALUE expected_type = (imemo_type << FL_USHIFT) | T_IMEMO;
/* fixed at runtime. */
return expected_type == (RBASIC(imemo)->flags & mask);
}
else {
return 0;
}
}

static inline bool
imemo_throw_data_p(VALUE imemo)
{
return RB_TYPE_P(imemo, T_IMEMO);
}

static inline struct vm_ifunc *
rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data)
{
return rb_vm_ifunc_new(func, data, 0, UNLIMITED_ARGUMENTS);
}

static inline VALUE
rb_imemo_tmpbuf_auto_free_pointer(void)
{
return rb_imemo_new(imemo_tmpbuf, 0, 0, 0, 0);
}

static inline void *
RB_IMEMO_TMPBUF_PTR(VALUE v)
{
const struct rb_imemo_tmpbuf_struct *p = (const void *)v;
return p->ptr;
}

static inline void *
rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr)
{
return ((rb_imemo_tmpbuf_t *)v)->ptr = ptr;
}

static inline VALUE
rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
{
const void *src;
VALUE imemo;
rb_imemo_tmpbuf_t *tmpbuf;
void *dst;
size_t len;

SafeStringValue(str);
/* create tmpbuf to keep the pointer before xmalloc */
imemo = rb_imemo_tmpbuf_auto_free_pointer();
tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
len = RSTRING_LEN(str);
src = RSTRING_PTR(str);
dst = ruby_xmalloc(len);
memcpy(dst, src, len);
tmpbuf->ptr = dst;
return imemo;
}

static inline void
MEMO_V1_SET(struct MEMO *m, VALUE v)
{
RB_OBJ_WRITE(m, &m->v1, v);
}

static inline void
MEMO_V2_SET(struct MEMO *m, VALUE v)
{
RB_OBJ_WRITE(m, &m->v2, v);
}

#endif /* INTERNAL_IMEMO_H */
3 changes: 2 additions & 1 deletion proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,8 @@ rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int m
}
arity.argc.min = min_argc;
arity.argc.max = max_argc;
return IFUNC_NEW(func, data, arity.packed);
VALUE ret = rb_imemo_new(imemo_ifunc, (VALUE)func, (VALUE)data, arity.packed, 0);
return (struct vm_ifunc *)ret;
}

MJIT_FUNC_EXPORTED VALUE
Expand Down

0 comments on commit 989068c

Please sign in to comment.