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
30 changes: 30 additions & 0 deletions bootstraptest/test_ractor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2315,3 +2315,33 @@ def Warning.warn(msg)
raise unless $msg.all?{/Ractor#take/ =~ it}
$msg.size
}

# Cause lots of inline CC misses.
assert_equal 'ok', <<~'RUBY'
class A; def test; 1 + 1; end; end
class B; def test; 1 + 1; end; end
class C; def test; 1 + 1; end; end
class D; def test; 1 + 1; end; end
class E; def test; 1 + 1; end; end
class F; def test; 1 + 1; end; end
class G; def test; 1 + 1; end; end

objs = [A.new, B.new, C.new, D.new, E.new, F.new, G.new].freeze

def call_test(obj)
obj.test
end

ractors = 7.times.map do
Ractor.new(objs) do |objs|
objs = objs.shuffle
100_000.times do
objs.each do |o|
call_test(o)
end
end
end
end
ractors.each(&:join)
:ok
RUBY
2 changes: 1 addition & 1 deletion debug_counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ RB_DEBUG_COUNTER(cc_temp) // dummy CC (stack-allocated)
RB_DEBUG_COUNTER(cc_found_in_ccs) // count for CC lookup success in CCS
RB_DEBUG_COUNTER(cc_not_found_in_ccs) // count for CC lookup success in CCS

RB_DEBUG_COUNTER(cc_ent_invalidate) // count for invalidating cc (cc->klass = 0)
RB_DEBUG_COUNTER(cc_ent_invalidate) // count for invalidating cc (cc->klass = Qundef)
RB_DEBUG_COUNTER(cc_cme_invalidate) // count for invalidating CME

RB_DEBUG_COUNTER(cc_invalidate_leaf) // count for invalidating klass if klass has no-subclasses
Expand Down
60 changes: 39 additions & 21 deletions ext/openssl/ossl_pkcs7.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,19 @@ ossl_PKCS7_SIGNER_INFO_dup(PKCS7_SIGNER_INFO *si)
}

static PKCS7_RECIP_INFO *
ossl_PKCS7_RECIP_INFO_dup(PKCS7_RECIP_INFO *si)
ossl_PKCS7_RECIP_INFO_dup(PKCS7_RECIP_INFO *ri)
{
return ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO,
(d2i_of_void *)d2i_PKCS7_RECIP_INFO,
si);
PKCS7_RECIP_INFO *ri_new = ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO,
(d2i_of_void *)d2i_PKCS7_RECIP_INFO,
ri);
if (ri_new && ri->cert) {
if (!X509_up_ref(ri->cert)) {
PKCS7_RECIP_INFO_free(ri_new);
return NULL;
}
ri_new->cert = ri->cert;
}
return ri_new;
}

static VALUE
Expand Down Expand Up @@ -510,6 +518,8 @@ ossl_pkcs7_get_detached(VALUE self)
{
PKCS7 *p7;
GetPKCS7(self, p7);
if (!PKCS7_type_is_signed(p7))
return Qfalse;
return PKCS7_get_detached(p7) ? Qtrue : Qfalse;
}

Expand Down Expand Up @@ -838,30 +848,38 @@ ossl_pkcs7_add_data(VALUE self, VALUE data)
PKCS7 *pkcs7;
BIO *out, *in;
char buf[4096];
int len;
int len, ret;

GetPKCS7(self, pkcs7);
if(PKCS7_type_is_signed(pkcs7)){
if(!PKCS7_content_new(pkcs7, NID_pkcs7_data))
ossl_raise(ePKCS7Error, NULL);
if (PKCS7_type_is_signed(pkcs7)) {
if (!PKCS7_content_new(pkcs7, NID_pkcs7_data))
ossl_raise(ePKCS7Error, "PKCS7_content_new");
}
in = ossl_obj2bio(&data);
if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err;
for(;;){
if((len = BIO_read(in, buf, sizeof(buf))) <= 0)
break;
if(BIO_write(out, buf, len) != len)
goto err;
if (!(out = PKCS7_dataInit(pkcs7, NULL))) {
BIO_free(in);
ossl_raise(ePKCS7Error, "PKCS7_dataInit");
}
if(!PKCS7_dataFinal(pkcs7, out)) goto err;
ossl_pkcs7_set_data(self, Qnil);

err:
for (;;) {
if ((len = BIO_read(in, buf, sizeof(buf))) <= 0)
break;
if (BIO_write(out, buf, len) != len) {
BIO_free_all(out);
BIO_free(in);
ossl_raise(ePKCS7Error, "BIO_write");
}
}
if (BIO_flush(out) <= 0) {
BIO_free_all(out);
BIO_free(in);
ossl_raise(ePKCS7Error, "BIO_flush");
}
ret = PKCS7_dataFinal(pkcs7, out);
BIO_free_all(out);
BIO_free(in);
if(ERR_peek_error()){
ossl_raise(ePKCS7Error, NULL);
}
if (!ret)
ossl_raise(ePKCS7Error, "PKCS7_dataFinal");
ossl_pkcs7_set_data(self, Qnil);

return data;
}
Expand Down
113 changes: 8 additions & 105 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@ classext_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
struct classext_foreach_args *args = (struct classext_foreach_args *)arg;

rb_id_table_free(RCLASSEXT_M_TBL(ext));
rb_cc_tbl_free(RCLASSEXT_CC_TBL(ext), args->klass);

if (!RCLASSEXT_SHARED_CONST_TBL(ext) && (tbl = RCLASSEXT_CONST_TBL(ext)) != NULL) {
rb_free_const_table(tbl);
}
Expand Down Expand Up @@ -1238,7 +1238,6 @@ classext_iclass_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *a
if (RCLASSEXT_CALLABLE_M_TBL(ext) != NULL) {
rb_id_table_free(RCLASSEXT_CALLABLE_M_TBL(ext));
}
rb_cc_tbl_free(RCLASSEXT_CC_TBL(ext), args->klass);

rb_class_classext_free_subclasses(ext, args->klass);

Expand Down Expand Up @@ -1743,7 +1742,7 @@ rb_objspace_free_objects(void *objspace)
int
rb_objspace_garbage_object_p(VALUE obj)
{
return rb_gc_impl_garbage_object_p(rb_gc_get_objspace(), obj);
return !SPECIAL_CONST_P(obj) && rb_gc_impl_garbage_object_p(rb_gc_get_objspace(), obj);
}

bool
Expand Down Expand Up @@ -1898,8 +1897,6 @@ object_id0(VALUE obj)
return object_id_get(obj, shape_id);
}

// rb_shape_object_id_shape may lock if the current shape has
// multiple children.
shape_id_t object_id_shape_id = rb_shape_transition_object_id(obj);

id = generate_next_object_id();
Expand Down Expand Up @@ -2262,24 +2259,6 @@ rb_gc_after_updating_jit_code(void)
#endif
}

static enum rb_id_table_iterator_result
cc_table_memsize_i(VALUE ccs_ptr, void *data_ptr)
{
size_t *total_size = data_ptr;
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
*total_size += sizeof(*ccs);
*total_size += sizeof(ccs->entries[0]) * ccs->capa;
return ID_TABLE_CONTINUE;
}

static size_t
cc_table_memsize(struct rb_id_table *cc_table)
{
size_t total = rb_id_table_memsize(cc_table);
rb_id_table_foreach_values(cc_table, cc_table_memsize_i, &total);
return total;
}

static void
classext_memsize(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
{
Expand All @@ -2295,9 +2274,6 @@ classext_memsize(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
if (RCLASSEXT_CONST_TBL(ext)) {
s += rb_id_table_memsize(RCLASSEXT_CONST_TBL(ext));
}
if (RCLASSEXT_CC_TBL(ext)) {
s += cc_table_memsize(RCLASSEXT_CC_TBL(ext));
}
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) {
s += (RCLASSEXT_SUPERCLASS_DEPTH(ext) + 1) * sizeof(VALUE);
}
Expand Down Expand Up @@ -2348,9 +2324,6 @@ rb_obj_memsize_of(VALUE obj)
size += rb_id_table_memsize(RCLASS_M_TBL(obj));
}
}
if (RCLASS_WRITABLE_CC_TBL(obj)) {
size += cc_table_memsize(RCLASS_WRITABLE_CC_TBL(obj));
}
break;
case T_STRING:
size += rb_str_memsize(obj);
Expand Down Expand Up @@ -2835,47 +2808,6 @@ mark_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
rb_id_table_foreach_values(tbl, mark_const_entry_i, objspace);
}

struct mark_cc_entry_args {
rb_objspace_t *objspace;
VALUE klass;
};

static enum rb_id_table_iterator_result
mark_cc_entry_i(VALUE ccs_ptr, void *data)
{
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;

VM_ASSERT(vm_ccs_p(ccs));

if (METHOD_ENTRY_INVALIDATED(ccs->cme)) {
rb_vm_ccs_free(ccs);
return ID_TABLE_DELETE;
}
else {
gc_mark_internal((VALUE)ccs->cme);

for (int i=0; i<ccs->len; i++) {
VM_ASSERT(((struct mark_cc_entry_args *)data)->klass == ccs->entries[i].cc->klass);
VM_ASSERT(vm_cc_check_cme(ccs->entries[i].cc, ccs->cme));

gc_mark_internal((VALUE)ccs->entries[i].cc);
}
return ID_TABLE_CONTINUE;
}
}

static void
mark_cc_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl, VALUE klass)
{
struct mark_cc_entry_args args;

if (!tbl) return;

args.objspace = objspace;
args.klass = klass;
rb_id_table_foreach_values(tbl, mark_cc_entry_i, (void *)&args);
}

static enum rb_id_table_iterator_result
mark_cvc_tbl_i(VALUE cvc_entry, void *objspace)
{
Expand Down Expand Up @@ -3113,7 +3045,6 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE namespace, void *a
{
struct gc_mark_classext_foreach_arg *foreach_arg = (struct gc_mark_classext_foreach_arg *)arg;
rb_objspace_t *objspace = foreach_arg->objspace;
VALUE obj = foreach_arg->obj;

if (RCLASSEXT_SUPER(ext)) {
gc_mark_internal(RCLASSEXT_SUPER(ext));
Expand All @@ -3124,7 +3055,7 @@ gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE namespace, void *a
mark_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
}
mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
mark_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext), obj);
gc_mark_internal(RCLASSEXT_CC_TBL(ext));
mark_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext));
gc_mark_internal(RCLASSEXT_CLASSPATH(ext));
}
Expand All @@ -3134,7 +3065,6 @@ gc_mark_classext_iclass(rb_classext_t *ext, bool prime, VALUE namespace, void *a
{
struct gc_mark_classext_foreach_arg *foreach_arg = (struct gc_mark_classext_foreach_arg *)arg;
rb_objspace_t *objspace = foreach_arg->objspace;
VALUE iclass = foreach_arg->obj;

if (RCLASSEXT_SUPER(ext)) {
gc_mark_internal(RCLASSEXT_SUPER(ext));
Expand All @@ -3146,7 +3076,7 @@ gc_mark_classext_iclass(rb_classext_t *ext, bool prime, VALUE namespace, void *a
gc_mark_internal(RCLASSEXT_INCLUDER(ext));
}
mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
mark_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext), iclass);
gc_mark_internal(RCLASSEXT_CC_TBL(ext));
}

#define TYPED_DATA_REFS_OFFSET_LIST(d) (size_t *)(uintptr_t)RTYPEDDATA_TYPE(d)->function.dmark
Expand Down Expand Up @@ -3710,33 +3640,6 @@ update_m_tbl(void *objspace, struct rb_id_table *tbl)
}
}

static enum rb_id_table_iterator_result
update_cc_tbl_i(VALUE ccs_ptr, void *objspace)
{
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
VM_ASSERT(vm_ccs_p(ccs));

if (rb_gc_impl_object_moved_p(objspace, (VALUE)ccs->cme)) {
ccs->cme = (const rb_callable_method_entry_t *)gc_location_internal(objspace, (VALUE)ccs->cme);
}

for (int i=0; i<ccs->len; i++) {
if (rb_gc_impl_object_moved_p(objspace, (VALUE)ccs->entries[i].cc)) {
ccs->entries[i].cc = (struct rb_callcache *)gc_location_internal(objspace, (VALUE)ccs->entries[i].cc);
}
}

// do not replace
return ID_TABLE_CONTINUE;
}

static void
update_cc_tbl(void *objspace, struct rb_id_table *tbl)
{
if (!tbl) return;
rb_id_table_foreach_values(tbl, update_cc_tbl_i, objspace);
}

static enum rb_id_table_iterator_result
update_cvc_tbl_i(VALUE cvc_entry, void *objspace)
{
Expand Down Expand Up @@ -3835,7 +3738,7 @@ update_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
if (!RCLASSEXT_SHARED_CONST_TBL(ext)) {
update_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
}
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
UPDATE_IF_MOVED(objspace, RCLASSEXT_CC_TBL(ext));
update_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext));
update_superclasses(objspace, ext);
update_subclasses(objspace, ext);
Expand All @@ -3854,7 +3757,7 @@ update_iclass_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void
}
update_m_tbl(objspace, RCLASSEXT_M_TBL(ext));
update_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
UPDATE_IF_MOVED(objspace, RCLASSEXT_CC_TBL(ext));
update_subclasses(objspace, ext);

update_classext_values(objspace, ext, true);
Expand Down Expand Up @@ -4924,11 +4827,11 @@ rb_raw_obj_info_buitin_type(char *const buff, const size_t buff_size, const VALU
case imemo_callcache:
{
const struct rb_callcache *cc = (const struct rb_callcache *)obj;
VALUE class_path = cc->klass ? rb_class_path_cached(cc->klass) : Qnil;
VALUE class_path = vm_cc_valid(cc) ? rb_class_path_cached(cc->klass) : Qnil;
const rb_callable_method_entry_t *cme = vm_cc_cme(cc);

APPEND_F("(klass:%s cme:%s%s (%p) call:%p",
NIL_P(class_path) ? (cc->klass ? "??" : "<NULL>") : RSTRING_PTR(class_path),
NIL_P(class_path) ? (vm_cc_valid(cc) ? "??" : "<NULL>") : RSTRING_PTR(class_path),
cme ? rb_id2name(cme->called_id) : "<NULL>",
cme ? (METHOD_ENTRY_INVALIDATED(cme) ? " [inv]" : "") : "",
(void *)cme,
Expand Down
Loading