Skip to content

Commit

Permalink
* parse.y: support Symbol GC. [ruby-trunk Feature #9634]
Browse files Browse the repository at this point in the history
  See this ticket about Symbol GC.

* include/ruby/ruby.h:
  Declare few functions.
  * rb_sym2id: almost same as old SYM2ID but support dynamic symbols.
  * rb_id2sym: almost same as old ID2SYM but support dynamic symbols.
  * rb_sym2str: almost same as `rb_id2str(SYM2ID(sym))` but not
    pin down a dynamic symbol.
  Declare a new struct.
  * struct RSymbol: represents a dynamic symbol as object in
    Ruby's heaps.
  Add few macros.
  * STATIC_SYM_P: check a static symbol.
  * DYNAMIC_SYM_P: check a dynamic symbol.
  * RSYMBOL: cast to RSymbol

* gc.c: declare RSymbol. support T_SYMBOL.

* internal.h: Declare few functions.
  * rb_gc_free_dsymbol: free up a dynamic symbol. GC call this
    function at a sweep phase.
  * rb_str_dynamic_intern: convert a string to a dynamic symbol.
  * rb_check_id_without_pindown: not pinning function.
  * rb_sym2id_without_pindown: ditto.
  * rb_check_id_cstr_without_pindown: ditto.

* string.c (Init_String): String#intern and String#to_sym use
  rb_str_dynamic_intern.

* template/id.h.tmpl: use LSB of ID as a flag for determining a
  static symbol, so we shift left other ruby_id_types.

* string.c: use rb_sym2str instead `rb_id2str(SYM2ID(sym))` to
  avoid pinning.

* load.c: use xx_without_pindown function at creating temporary ID
  to avoid pinning.

* object.c: ditto.

* sprintf.c: ditto.

* struct.c: ditto.

* thread.c: ditto.

* variable.c: ditto.

* vm_method.c: ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45426 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
authorNari committed Mar 26, 2014
1 parent 2bf56de commit 90b7073
Show file tree
Hide file tree
Showing 14 changed files with 390 additions and 92 deletions.
53 changes: 53 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,56 @@
Tue Mar 25 22:57:11 2014 Narihiro Nakamura <authornari@gmail.com>

* parse.y: support Symbol GC. [ruby-trunk Feature #9634]
See this ticket about Symbol GC.

* include/ruby/ruby.h:
Declare few functions.
* rb_sym2id: almost same as old SYM2ID but support dynamic symbols.
* rb_id2sym: almost same as old ID2SYM but support dynamic symbols.
* rb_sym2str: almost same as `rb_id2str(SYM2ID(sym))` but not
pin down a dynamic symbol.
Declare a new struct.
* struct RSymbol: represents a dynamic symbol as object in
Ruby's heaps.
Add few macros.
* STATIC_SYM_P: check a static symbol.
* DYNAMIC_SYM_P: check a dynamic symbol.
* RSYMBOL: cast to RSymbol

* gc.c: declare RSymbol. support T_SYMBOL.

* internal.h: Declare few functions.
* rb_gc_free_dsymbol: free up a dynamic symbol. GC call this
function at a sweep phase.
* rb_str_dynamic_intern: convert a string to a dynamic symbol.
* rb_check_id_without_pindown: not pinning function.
* rb_sym2id_without_pindown: ditto.
* rb_check_id_cstr_without_pindown: ditto.

* string.c (Init_String): String#intern and String#to_sym use
rb_str_dynamic_intern.

* template/id.h.tmpl: use LSB of ID as a flag for determining a
static symbol, so we shift left other ruby_id_types.

* string.c: use rb_sym2str instead `rb_id2str(SYM2ID(sym))` to
avoid pinning.

* load.c: use xx_without_pindown function at creating temporary ID
to avoid pinning.

* object.c: ditto.

* sprintf.c: ditto.

* struct.c: ditto.

* thread.c: ditto.

* variable.c: ditto.

* vm_method.c: ditto.

Wed Mar 26 13:25:54 2014 NARUSE, Yui <naruse@ruby-lang.org>

* addr2line.c (fill_lines): loop reverse order not to overwrite
Expand Down
11 changes: 10 additions & 1 deletion gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ typedef struct RVALUE {
struct RMatch match;
struct RRational rational;
struct RComplex complex;
struct RSymbol symbol;
struct {
struct RBasic basic;
VALUE v1;
Expand Down Expand Up @@ -1652,6 +1653,12 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
}
break;

case T_SYMBOL:
{
rb_gc_free_dsymbol(obj);
}
break;

default:
rb_bug("gc_sweep(): unknown data type 0x%x(%p) 0x%"PRIxVALUE,
BUILTIN_TYPE(obj), (void*)obj, RBASIC(obj)->flags);
Expand Down Expand Up @@ -2393,7 +2400,7 @@ rb_obj_id(VALUE obj)
* 24 if 32-bit, double is 8-byte aligned
* 40 if 64-bit
*/
if (SYMBOL_P(obj)) {
if (STATIC_SYM_P(obj)) {
return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
}
else if (FLONUM_P(obj)) {
Expand Down Expand Up @@ -2499,6 +2506,7 @@ obj_memsize_of(VALUE obj, int use_tdata)
break;

case T_FLOAT:
case T_SYMBOL:
break;

case T_BIGNUM:
Expand Down Expand Up @@ -3918,6 +3926,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr)

case T_FLOAT:
case T_BIGNUM:
case T_SYMBOL:
break;

case T_MATCH:
Expand Down
24 changes: 18 additions & 6 deletions include/ruby/ruby.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,13 @@ rb_long2int_inline(long n)

#define IMMEDIATE_P(x) ((VALUE)(x) & IMMEDIATE_MASK)

#define SYMBOL_P(x) (((VALUE)(x)&~((~(VALUE)0)<<RUBY_SPECIAL_SHIFT))==SYMBOL_FLAG)
#define ID2SYM(x) (((VALUE)(x)<<RUBY_SPECIAL_SHIFT)|SYMBOL_FLAG)
#define SYM2ID(x) RSHIFT((unsigned long)(x),RUBY_SPECIAL_SHIFT)
ID rb_sym2id(VALUE);
VALUE rb_id2sym(ID);
#define STATIC_SYM_P(x) (((VALUE)(x)&~((~(VALUE)0)<<RUBY_SPECIAL_SHIFT))==SYMBOL_FLAG)
#define DYNAMIC_SYM_P(x) (!SPECIAL_CONST_P(x) && BUILTIN_TYPE(x) == (T_SYMBOL))
#define SYMBOL_P(x) (STATIC_SYM_P(x)||DYNAMIC_SYM_P(x))
#define ID2SYM(x) (rb_id2sym(x))
#define SYM2ID(x) (rb_sym2id(x))

#ifndef USE_FLONUM
#if SIZEOF_VALUE >= SIZEOF_DOUBLE
Expand Down Expand Up @@ -957,6 +961,12 @@ struct RComplex {
#define RCOMPLEX_SET_REAL(cmp, r) RB_OBJ_WRITE((cmp), &((struct RComplex *)(cmp))->real,(r))
#define RCOMPLEX_SET_IMAG(cmp, i) RB_OBJ_WRITE((cmp), &((struct RComplex *)(cmp))->imag,(i))

struct RSymbol {
struct RBasic basic;
VALUE fstr;
ID type;
};

struct RData {
struct RBasic basic;
void (*dmark)(void*);
Expand Down Expand Up @@ -1093,6 +1103,7 @@ struct RStruct {
#define RFILE(obj) (R_CAST(RFile)(obj))
#define RRATIONAL(obj) (R_CAST(RRational)(obj))
#define RCOMPLEX(obj) (R_CAST(RComplex)(obj))
#define RSYMBOL(obj) (R_CAST(RSymbol)(obj))

#define FL_SINGLETON FL_USER0
#define FL_WB_PROTECTED (((VALUE)1)<<5)
Expand Down Expand Up @@ -1146,7 +1157,7 @@ struct RStruct {
(OBJ_TAINTABLE(x) && FL_ABLE(s)) ? \
RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT : 0)

#define OBJ_FROZEN(x) (!!(FL_ABLE(x)?(RBASIC(x)->flags&(FL_FREEZE)):(FIXNUM_P(x)||FLONUM_P(x)||SYMBOL_P(x))))
#define OBJ_FROZEN(x) (!!(FL_ABLE(x)?(RBASIC(x)->flags&(FL_FREEZE)):(FIXNUM_P(x)||FLONUM_P(x)||STATIC_SYM_P(x))))
#define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)

#if USE_RGENGC
Expand Down Expand Up @@ -1381,6 +1392,7 @@ const char *rb_id2name(ID);
ID rb_check_id(volatile VALUE *);
ID rb_to_id(VALUE);
VALUE rb_id2str(ID);
VALUE rb_sym2str(VALUE);

#define CONST_ID_CACHE(result, str) \
{ \
Expand Down Expand Up @@ -1597,7 +1609,7 @@ rb_class_of(VALUE obj)
if (FIXNUM_P(obj)) return rb_cFixnum;
if (FLONUM_P(obj)) return rb_cFloat;
if (obj == Qtrue) return rb_cTrueClass;
if (SYMBOL_P(obj)) return rb_cSymbol;
if (STATIC_SYM_P(obj)) return rb_cSymbol;
}
else if (!RTEST(obj)) {
if (obj == Qnil) return rb_cNilClass;
Expand All @@ -1613,7 +1625,7 @@ rb_type(VALUE obj)
if (FIXNUM_P(obj)) return T_FIXNUM;
if (FLONUM_P(obj)) return T_FLOAT;
if (obj == Qtrue) return T_TRUE;
if (SYMBOL_P(obj)) return T_SYMBOL;
if (STATIC_SYM_P(obj)) return T_SYMBOL;
if (obj == Qundef) return T_UNDEF;
}
else if (!RTEST(obj)) {
Expand Down
7 changes: 7 additions & 0 deletions internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,13 @@ int rb_is_junk_name(VALUE name);
void rb_gc_mark_parser(void);
void rb_gc_mark_symbols(int full_mark);
ID rb_make_internal_id(void);
void rb_gc_free_dsymbol(VALUE);
VALUE rb_str_dynamic_intern(VALUE);
ID rb_check_id_without_pindown(VALUE *);
ID rb_sym2id_without_pindown(VALUE);
#ifdef RUBY_ENCODING_H
ID rb_check_id_cstr_without_pindown(const char *, long, rb_encoding *);
#endif

/* proc.c */
VALUE rb_proc_location(VALUE self);
Expand Down
2 changes: 1 addition & 1 deletion load.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ rb_mod_autoload(VALUE mod, VALUE sym, VALUE file)
static VALUE
rb_mod_autoload_p(VALUE mod, VALUE sym)
{
ID id = rb_check_id(&sym);
ID id = rb_check_id_without_pindown(&sym);
if (!id) {
return Qnil;
}
Expand Down
12 changes: 6 additions & 6 deletions object.c
Original file line number Diff line number Diff line change
Expand Up @@ -2125,7 +2125,7 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod)

if (pbeg == p) goto wrong_name;

id = rb_check_id_cstr(pbeg, len = p-pbeg, enc);
id = rb_check_id_cstr_without_pindown(pbeg, len = p-pbeg, enc);
beglen = pbeg-path;

if (p < pend && p[0] == ':') {
Expand Down Expand Up @@ -2267,7 +2267,7 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)

if (pbeg == p) goto wrong_name;

id = rb_check_id_cstr(pbeg, len = p-pbeg, enc);
id = rb_check_id_cstr_without_pindown(pbeg, len = p-pbeg, enc);
beglen = pbeg-path;

if (p < pend && p[0] == ':') {
Expand Down Expand Up @@ -2338,7 +2338,7 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
static VALUE
rb_obj_ivar_get(VALUE obj, VALUE iv)
{
ID id = rb_check_id(&iv);
ID id = rb_check_id_without_pindown(&iv);

if (!id) {
if (rb_is_instance_name(iv)) {
Expand Down Expand Up @@ -2409,7 +2409,7 @@ rb_obj_ivar_set(VALUE obj, VALUE iv, VALUE val)
static VALUE
rb_obj_ivar_defined(VALUE obj, VALUE iv)
{
ID id = rb_check_id(&iv);
ID id = rb_check_id_without_pindown(&iv);

if (!id) {
if (rb_is_instance_name(iv)) {
Expand Down Expand Up @@ -2446,7 +2446,7 @@ rb_obj_ivar_defined(VALUE obj, VALUE iv)
static VALUE
rb_mod_cvar_get(VALUE obj, VALUE iv)
{
ID id = rb_check_id(&iv);
ID id = rb_check_id_without_pindown(&iv);

if (!id) {
if (rb_is_class_name(iv)) {
Expand Down Expand Up @@ -2512,7 +2512,7 @@ rb_mod_cvar_set(VALUE obj, VALUE iv, VALUE val)
static VALUE
rb_mod_cvar_defined(VALUE obj, VALUE iv)
{
ID id = rb_check_id(&iv);
ID id = rb_check_id_without_pindown(&iv);

if (!id) {
if (rb_is_class_name(iv)) {
Expand Down
Loading

0 comments on commit 90b7073

Please sign in to comment.