mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Reduce exposure of FL_FREEZE
The `FL_FREEZE` flag is redundant with `SHAPE_ID_FL_FROZEN`, so ideally it should be eliminated in favor of the later. Doing so would eliminate the risk of desync between the two, but also solve the problem of the frozen status being global in namespace context (See Bug #21330).
This commit is contained in:
parent
da10b956e0
commit
45a2c95d0f
8 changed files with 34 additions and 21 deletions
3
array.c
3
array.c
|
@ -3439,10 +3439,9 @@ rb_ary_sort_bang(VALUE ary)
|
|||
ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
|
||||
}
|
||||
/* tmp was lost ownership for the ptr */
|
||||
FL_UNSET(tmp, FL_FREEZE);
|
||||
FL_SET_EMBED(tmp);
|
||||
ARY_SET_EMBED_LEN(tmp, 0);
|
||||
FL_SET(tmp, FL_FREEZE);
|
||||
OBJ_FREEZE(tmp);
|
||||
}
|
||||
/* tmp will be GC'ed. */
|
||||
RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */
|
||||
|
|
3
class.c
3
class.c
|
@ -2771,7 +2771,8 @@ rb_freeze_singleton_class(VALUE x)
|
|||
if (!RCLASS_SINGLETON_P(x)) {
|
||||
VALUE klass = RBASIC_CLASS(x);
|
||||
if (klass && // no class when hidden from ObjectSpace
|
||||
FL_TEST(klass, (FL_SINGLETON|FL_FREEZE)) == FL_SINGLETON) {
|
||||
FL_TEST_RAW(klass, FL_SINGLETON) &&
|
||||
!OBJ_FROZEN_RAW(klass)) {
|
||||
OBJ_FREEZE(klass);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14456,7 +14456,7 @@ ibf_dump_object_object(struct ibf_dump *dump, VALUE obj)
|
|||
else {
|
||||
obj_header.internal = SPECIAL_CONST_P(obj) ? FALSE : (RBASIC_CLASS(obj) == 0) ? TRUE : FALSE;
|
||||
obj_header.special_const = FALSE;
|
||||
obj_header.frozen = FL_TEST(obj, FL_FREEZE) ? TRUE : FALSE;
|
||||
obj_header.frozen = OBJ_FROZEN(obj) ? TRUE : FALSE;
|
||||
ibf_dump_object_object_header(dump, obj_header);
|
||||
(*dump_object_functions[obj_header.type])(dump, obj);
|
||||
}
|
||||
|
|
4
object.c
4
object.c
|
@ -513,9 +513,7 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze)
|
|||
argv[0] = obj;
|
||||
argv[1] = freeze_true_hash;
|
||||
rb_funcallv_kw(clone, id_init_clone, 2, argv, RB_PASS_KEYWORDS);
|
||||
RBASIC(clone)->flags |= FL_FREEZE;
|
||||
shape_id_t next_shape_id = rb_shape_transition_frozen(clone);
|
||||
rb_obj_set_shape_id(clone, next_shape_id);
|
||||
OBJ_FREEZE(clone);
|
||||
break;
|
||||
}
|
||||
case Qfalse: {
|
||||
|
|
8
shape.c
8
shape.c
|
@ -818,6 +818,14 @@ rb_shape_transition_heap(VALUE obj, size_t heap_index)
|
|||
return (RBASIC_SHAPE_ID(obj) & (~SHAPE_ID_HEAP_INDEX_MASK)) | rb_shape_root(heap_index);
|
||||
}
|
||||
|
||||
void
|
||||
rb_set_namespaced_class_shape_id(VALUE obj, shape_id_t shape_id)
|
||||
{
|
||||
RBASIC_SET_SHAPE_ID(RCLASS_WRITABLE_ENSURE_FIELDS_OBJ(obj), shape_id);
|
||||
// FIXME: How to do multi-shape?
|
||||
RBASIC_SET_SHAPE_ID(obj, shape_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used for assertions where we don't want to increment
|
||||
* max_iv_count
|
||||
|
|
16
shape.h
16
shape.h
|
@ -146,6 +146,22 @@ RBASIC_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
|
|||
RUBY_ASSERT(rb_shape_verify_consistency(obj, shape_id));
|
||||
}
|
||||
|
||||
void rb_set_namespaced_class_shape_id(VALUE obj, shape_id_t shape_id);
|
||||
|
||||
static inline void
|
||||
RB_SET_SHAPE_ID(VALUE obj, shape_id_t shape_id)
|
||||
{
|
||||
switch (BUILTIN_TYPE(obj)) {
|
||||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
rb_set_namespaced_class_shape_id(obj, shape_id);
|
||||
break;
|
||||
default:
|
||||
RBASIC_SET_SHAPE_ID(obj, shape_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline rb_shape_t *
|
||||
RSHAPE(shape_id_t shape_id)
|
||||
{
|
||||
|
|
6
string.c
6
string.c
|
@ -1911,8 +1911,8 @@ rb_str_tmp_frozen_release(VALUE orig, VALUE tmp)
|
|||
if (STR_EMBED_P(tmp)) {
|
||||
RUBY_ASSERT(OBJ_FROZEN_RAW(tmp));
|
||||
}
|
||||
else if (FL_TEST_RAW(orig, STR_SHARED) &&
|
||||
!FL_TEST_RAW(orig, STR_TMPLOCK|RUBY_FL_FREEZE)) {
|
||||
else if (FL_TEST_RAW(orig, STR_SHARED | STR_TMPLOCK) == STR_TMPLOCK &&
|
||||
!OBJ_FROZEN_RAW(orig)) {
|
||||
VALUE shared = RSTRING(orig)->as.heap.aux.shared;
|
||||
|
||||
if (shared == tmp && !FL_TEST_RAW(tmp, STR_BORROWED)) {
|
||||
|
@ -2259,7 +2259,7 @@ str_duplicate_setup_heap(VALUE klass, VALUE str, VALUE dup)
|
|||
if (FL_TEST_RAW(str, STR_SHARED)) {
|
||||
root = RSTRING(str)->as.heap.aux.shared;
|
||||
}
|
||||
else if (UNLIKELY(!(flags & FL_FREEZE))) {
|
||||
else if (UNLIKELY(!OBJ_FROZEN_RAW(str))) {
|
||||
root = str = str_new_frozen(klass, str);
|
||||
flags = FL_TEST_RAW(str, flag_mask);
|
||||
}
|
||||
|
|
13
variable.c
13
variable.c
|
@ -2065,15 +2065,7 @@ rb_obj_set_shape_id(VALUE obj, shape_id_t shape_id)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE) {
|
||||
// Avoid creating the fields_obj just to freeze the class
|
||||
if (!(shape_id == SPECIAL_CONST_SHAPE_ID && old_shape_id == ROOT_SHAPE_ID)) {
|
||||
RBASIC_SET_SHAPE_ID(RCLASS_WRITABLE_ENSURE_FIELDS_OBJ(obj), shape_id);
|
||||
}
|
||||
}
|
||||
// FIXME: How to do multi-shape?
|
||||
RBASIC_SET_SHAPE_ID(obj, shape_id);
|
||||
|
||||
RB_SET_SHAPE_ID(obj, shape_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2085,8 +2077,7 @@ void rb_obj_freeze_inline(VALUE x)
|
|||
RB_FL_UNSET_RAW(x, FL_USER2 | FL_USER3); // STR_CHILLED
|
||||
}
|
||||
|
||||
shape_id_t next_shape_id = rb_shape_transition_frozen(x);
|
||||
rb_obj_set_shape_id(x, next_shape_id);
|
||||
RB_SET_SHAPE_ID(x, rb_shape_transition_frozen(x));
|
||||
|
||||
if (RBASIC_CLASS(x)) {
|
||||
rb_freeze_singleton_class(x);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue