Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions .gdbinit
Original file line number Diff line number Diff line change
Expand Up @@ -185,19 +185,14 @@ define rp
print (struct RBasic *)($arg0)
else
if ($flags & RUBY_T_MASK) == RUBY_T_DATA
if ($flags & RUBY_TYPED_FL_IS_TYPED_DATA)
set $data = (struct RTypedData *)($arg0)
set $type = (const rb_data_type_t *)($data->type & ~1)
printf "%sT_DATA%s(%s): ", $color_type, $color_end, $type->wrap_struct_name
print *$type
if ($data->type & 1)
print (void *)&$data->data
else
print $data
end
set $data = (struct RTypedData *)($arg0)
set $type = (const rb_data_type_t *)($data->type & ~1)
printf "%sT_DATA%s(%s): ", $color_type, $color_end, $type->wrap_struct_name
print *$type
if ($data->type & 1)
print (void *)&$data->data
else
printf "%sT_DATA%s: ", $color_type, $color_end
print *(struct RData *)($arg0)
print $data
end
else
if ($flags & RUBY_T_MASK) == RUBY_T_MATCH
Expand Down
14 changes: 14 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ Ruby 4.0 bundled RubyGems and Bundler version 4. see the following links for det

[[Feature #21861]]

### Removed APIs

The following APIs, which have been deprecated for many years, are removed.
[[Feature #21768]]

* old postponed job functions,
* untyped data object type/functions,
* old APIs to allocate a data object,
* taintedness/trustedness enums/macros,
* `rb_gc_force_recycle` function,
* `rb_iterate` function,
* and some functions and constants for internal use.

## Implementation improvements

### Ractor
Expand All @@ -172,6 +185,7 @@ A lot of work has gone into making Ractors more stable, performant, and usable.
[Feature #8948]: https://bugs.ruby-lang.org/issues/8948
[Feature #15330]: https://bugs.ruby-lang.org/issues/15330
[Feature #21390]: https://bugs.ruby-lang.org/issues/21390
[Feature #21768]: https://bugs.ruby-lang.org/issues/21768
[Feature #21785]: https://bugs.ruby-lang.org/issues/21785
[Feature #21796]: https://bugs.ruby-lang.org/issues/21796
[Feature #21853]: https://bugs.ruby-lang.org/issues/21853
Expand Down
2 changes: 1 addition & 1 deletion encoding.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ static const rb_data_type_t encoding_data_type = {
};

#define is_encoding_type(obj) (RTYPEDDATA_TYPE(obj) == &encoding_data_type)
#define is_data_encoding(obj) (rbimpl_rtypeddata_p(obj) && is_encoding_type(obj))
#define is_data_encoding(obj) is_encoding_type(obj)
#define is_obj_encoding(obj) (rbimpl_obj_typeddata_p(obj) && is_encoding_type(obj))

int
Expand Down
7 changes: 5 additions & 2 deletions error.c
Original file line number Diff line number Diff line change
Expand Up @@ -1364,8 +1364,7 @@ rb_check_type(VALUE x, int t)
rb_bug(UNDEF_LEAKED);
}

xt = TYPE(x);
if (xt != t || (xt == T_DATA && rbimpl_rtypeddata_p(x))) {
if (t == T_DATA) {
/*
* Typed data is not simple `T_DATA`, but in a sense an
* extension of `struct RVALUE`, which are incompatible with
Expand All @@ -1374,6 +1373,10 @@ rb_check_type(VALUE x, int t)
* So it is not enough to just check `T_DATA`, it must be
* identified by its `type` using `Check_TypedStruct` instead.
*/
rb_unexpected_object_type(x, builtin_types[t]);
}
xt = TYPE(x);
if (xt != t) {
unexpected_type(x, xt, t);
}
}
Expand Down
2 changes: 1 addition & 1 deletion ext/objspace/objspace_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ dump_object(VALUE obj, struct dump_config *dc)
break;

case T_DATA:
if (RTYPEDDATA_P(obj)) {
{
const rb_data_type_t *type = RTYPEDDATA_TYPE(obj);
dump_append(dc, ", \"struct\":\"");
dump_append(dc, type->wrap_struct_name);
Expand Down
97 changes: 26 additions & 71 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,10 @@ rb_gc_shutdown_call_finalizer_p(VALUE obj)
{
switch (BUILTIN_TYPE(obj)) {
case T_DATA:
if (!ruby_free_at_exit_p() && !DATA_PTR(obj)) return false;
if (!ruby_free_at_exit_p() && !RTYPEDDATA_P(obj) && !RDATA(obj)->dfree) return false;
if (!ruby_free_at_exit_p()) {
if (!RDATA(obj)->type) return false;
if (!rbimpl_typeddata_embedded_p(obj) && !RTYPEDDATA(obj)->data) return false;
}
if (rb_obj_is_thread(obj)) return false;
if (rb_obj_is_mutex(obj)) return false;
if (rb_obj_is_fiber(obj)) return false;
Expand Down Expand Up @@ -374,7 +376,6 @@ void rb_vm_update_references(void *ptr);

#define rb_setjmp(env) RUBY_SETJMP(env)
#define rb_jmp_buf rb_jmpbuf_t
#undef rb_data_object_wrap

#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#define MAP_ANONYMOUS MAP_ANON
Expand Down Expand Up @@ -1138,33 +1139,6 @@ rb_data_object_check(VALUE klass)
}
}

VALUE
rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
{
RUBY_ASSERT_ALWAYS(dfree != (RUBY_DATA_FUNC)1);
if (klass) rb_data_object_check(klass);
VALUE obj = rb_newobj(GET_EC(), klass, T_DATA, ROOT_SHAPE_ID, !dmark, sizeof(struct RData));

rb_gc_register_pinning_obj(obj);

struct RData *data = (struct RData *)obj;
data->fields_obj = 0;
data->_reserved = 0;
data->data = datap;
data->dmark = dmark;
data->dfree = dfree;

return obj;
}

VALUE
rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
{
VALUE obj = rb_data_object_wrap(klass, 0, dmark, dfree);
DATA_PTR(obj) = xcalloc(1, size);
return obj;
}

#define RTYPEDDATA_EMBEDDED_P rbimpl_typeddata_embedded_p
#define RB_DATA_TYPE_EMBEDDABLE_P(type) ((type)->flags & RUBY_TYPED_EMBEDDABLE)
#define RTYPEDDATA_EMBEDDABLE_P(obj) RB_DATA_TYPE_EMBEDDABLE_P(RTYPEDDATA_TYPE(obj))
Expand All @@ -1175,7 +1149,7 @@ typed_data_alloc(VALUE klass, VALUE typed_flag, void *datap, const rb_data_type_
RBIMPL_NONNULL_ARG(type);
if (klass) rb_data_object_check(klass);
bool wb_protected = (type->flags & RUBY_FL_WB_PROTECTED) || !type->function.dmark;
VALUE obj = rb_newobj(GET_EC(), klass, T_DATA | RUBY_TYPED_FL_IS_TYPED_DATA, ROOT_SHAPE_ID, wb_protected, size);
VALUE obj = rb_newobj(GET_EC(), klass, T_DATA, ROOT_SHAPE_ID, wb_protected, size);

rb_gc_register_pinning_obj(obj);

Expand Down Expand Up @@ -1237,18 +1211,16 @@ static size_t
rb_objspace_data_type_memsize(VALUE obj)
{
size_t size = 0;
if (RTYPEDDATA_P(obj)) {
const void *ptr = RTYPEDDATA_GET_DATA(obj);
const void *ptr = RTYPEDDATA_GET_DATA(obj);

if (ptr) {
if (RTYPEDDATA_EMBEDDABLE_P(obj) && !RTYPEDDATA_EMBEDDED_P(obj)) {
size += ruby_xmalloc_usable_size((void *)ptr);
}
if (ptr) {
if (RTYPEDDATA_EMBEDDABLE_P(obj) && !RTYPEDDATA_EMBEDDED_P(obj)) {
size += ruby_xmalloc_usable_size((void *)ptr);
}

const rb_data_type_t *type = RTYPEDDATA_TYPE(obj);
if (type->function.dsize) {
size += type->function.dsize(ptr);
}
const rb_data_type_t *type = RTYPEDDATA_TYPE(obj);
if (type->function.dsize) {
size += type->function.dsize(ptr);
}
}

Expand All @@ -1258,12 +1230,7 @@ rb_objspace_data_type_memsize(VALUE obj)
const char *
rb_objspace_data_type_name(VALUE obj)
{
if (RTYPEDDATA_P(obj)) {
return RTYPEDDATA_TYPE(obj)->wrap_struct_name;
}
else {
return 0;
}
return RTYPEDDATA_TYPE(obj)->wrap_struct_name;
}

void
Expand All @@ -1285,7 +1252,7 @@ rb_gc_handle_weak_references(VALUE obj)
{
switch (BUILTIN_TYPE(obj)) {
case T_DATA:
if (RTYPEDDATA_P(obj)) {
{
const rb_data_type_t *type = RTYPEDDATA_TYPE(obj);

if (type->function.handle_weak_references) {
Expand All @@ -1298,9 +1265,6 @@ rb_gc_handle_weak_references(VALUE obj)
);
}
}
else {
rb_bug("rb_gc_handle_weak_references: unknown T_DATA");
}
break;

case T_IMEMO: {
Expand Down Expand Up @@ -1423,7 +1387,7 @@ rb_gc_obj_needs_cleanup_p(VALUE obj)
return false;

case T_DATA:
if (flags & RUBY_TYPED_FL_IS_TYPED_DATA) {
{
uintptr_t type = (uintptr_t)RTYPEDDATA(obj)->type;
if (type & TYPED_DATA_EMBEDDED) {
RUBY_DATA_FUNC dfree = ((const rb_data_type_t *)(type & TYPED_DATA_PTR_MASK))->function.dfree;
Expand Down Expand Up @@ -1485,22 +1449,17 @@ make_io_zombie(void *objspace, VALUE obj)
static bool
rb_data_free(void *objspace, VALUE obj)
{
void *data = RTYPEDDATA_P(obj) ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
void *data = RTYPEDDATA_GET_DATA(obj);
if (data) {
int free_immediately = false;
void (*dfree)(void *);

if (RTYPEDDATA_P(obj)) {
free_immediately = (RTYPEDDATA_TYPE(obj)->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0;
dfree = RTYPEDDATA_TYPE(obj)->function.dfree;
}
else {
dfree = RDATA(obj)->dfree;
}
free_immediately = (RTYPEDDATA_TYPE(obj)->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0;
dfree = RTYPEDDATA_TYPE(obj)->function.dfree;

if (dfree) {
if (dfree == RUBY_DEFAULT_FREE) {
if (!RTYPEDDATA_P(obj) || !RTYPEDDATA_EMBEDDED_P(obj)) {
if (!RTYPEDDATA_EMBEDDED_P(obj)) {
xfree(data);
RB_DEBUG_COUNTER_INC(obj_data_xfree);
}
Expand Down Expand Up @@ -3512,23 +3471,20 @@ rb_gc_mark_children(void *objspace, VALUE obj)
break;

case T_DATA: {
bool typed_data = RTYPEDDATA_P(obj);
void *const ptr = typed_data ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
void *const ptr = RTYPEDDATA_GET_DATA(obj);

gc_mark_internal(RTYPEDDATA(obj)->fields_obj);

if (ptr) {
if (typed_data && gc_declarative_marking_p(RTYPEDDATA_TYPE(obj))) {
if (gc_declarative_marking_p(RTYPEDDATA_TYPE(obj))) {
size_t *offset_list = TYPED_DATA_REFS_OFFSET_LIST(obj);

for (size_t offset = *offset_list; offset != RUBY_REF_END; offset = *offset_list++) {
gc_mark_internal(*(VALUE *)((char *)ptr + offset));
}
}
else {
RUBY_DATA_FUNC mark_func = typed_data ?
RTYPEDDATA_TYPE(obj)->function.dmark :
RDATA(obj)->dmark;
RUBY_DATA_FUNC mark_func = RTYPEDDATA_TYPE(obj)->function.dmark;
if (mark_func) (*mark_func)(ptr);
}
}
Expand Down Expand Up @@ -4460,21 +4416,20 @@ rb_gc_update_object_references(void *objspace, VALUE obj)
case T_DATA:
/* Call the compaction callback, if it exists */
{
bool typed_data = RTYPEDDATA_P(obj);
void *const ptr = typed_data ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
void *const ptr = RTYPEDDATA_GET_DATA(obj);

UPDATE_IF_MOVED(objspace, RTYPEDDATA(obj)->fields_obj);

if (ptr) {
if (typed_data && gc_declarative_marking_p(RTYPEDDATA_TYPE(obj))) {
if (gc_declarative_marking_p(RTYPEDDATA_TYPE(obj))) {
size_t *offset_list = TYPED_DATA_REFS_OFFSET_LIST(obj);

for (size_t offset = *offset_list; offset != RUBY_REF_END; offset = *offset_list++) {
VALUE *ref = (VALUE *)((char *)ptr + offset);
*ref = gc_location_internal(objspace, *ref);
}
}
else if (typed_data) {
else {
RUBY_DATA_FUNC compact_func = RTYPEDDATA_TYPE(obj)->function.dcompact;
if (compact_func) (*compact_func)(ptr);
}
Expand Down
Loading