This commit is contained in:
Joshua Haberman 2019-08-16 06:42:13 -07:00
parent 63f324a993
commit 1c9fb9d45b
5 changed files with 25 additions and 8 deletions

View File

@ -487,6 +487,9 @@ void Descriptor_mark(void* _self) {
Descriptor* self = _self;
rb_gc_mark(self->klass);
rb_gc_mark(self->descriptor_pool);
if (self->layout && self->layout->empty_template) {
layout_mark(self->layout, self->layout->empty_template);
}
}
void Descriptor_free(void* _self) {

View File

@ -690,7 +690,7 @@ void add_handlers_for_message(const void *closure, upb_handlers *h) {
// class is actually built, so to work around this, we just create the layout
// (and handlers, in the class-building function) on-demand.
if (desc->layout == NULL) {
desc->layout = create_layout(desc);
create_layout(desc);
}
// If this is a mapentry message type, set up a special set of handlers and

View File

@ -64,7 +64,7 @@ VALUE Message_alloc(VALUE klass) {
VALUE ret;
if (desc->layout == NULL) {
desc->layout = create_layout(desc);
create_layout(desc);
}
msg = (MessageHeader*)ALLOC_N(uint8_t,

View File

@ -509,11 +509,12 @@ struct MessageField {
struct MessageLayout {
const Descriptor* desc;
const upb_msgdef* msgdef;
void* empty_template; // Can memcpy() onto a layout to clear it.
MessageField* fields;
size_t size;
};
MessageLayout* create_layout(const Descriptor* desc);
void create_layout(Descriptor* desc);
void free_layout(MessageLayout* layout);
bool field_contains_hasbit(MessageLayout* layout,
const upb_fielddef* field);

View File

@ -473,7 +473,7 @@ static size_t align_up_to(size_t offset, size_t granularity) {
return (offset + granularity - 1) & ~(granularity - 1);
}
MessageLayout* create_layout(const Descriptor* desc) {
void create_layout(Descriptor* desc) {
const upb_msgdef *msgdef = desc->msgdef;
MessageLayout* layout = ALLOC(MessageLayout);
int nfields = upb_msgdef_numfields(msgdef);
@ -482,7 +482,10 @@ MessageLayout* create_layout(const Descriptor* desc) {
size_t off = 0;
size_t hasbit = 0;
layout->empty_template = NULL;
layout->desc = desc;
desc->layout = layout;
layout->fields = ALLOC_N(MessageField, nfields);
for (upb_msg_field_begin(&it, msgdef);
@ -584,10 +587,19 @@ MessageLayout* create_layout(const Descriptor* desc) {
layout->size = off;
layout->msgdef = msgdef;
return layout;
// Create the empty message template.
layout->empty_template = ALLOC_N(char, layout->size);
memset(layout->empty_template, 0, layout->size);
for (upb_msg_field_begin(&it, layout->msgdef);
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
layout_clear(layout, layout->empty_template, upb_msg_iter_field(&it));
}
}
void free_layout(MessageLayout* layout) {
xfree(layout->empty_template);
xfree(layout->fields);
xfree(layout);
}
@ -868,15 +880,16 @@ void layout_set(MessageLayout* layout,
}
}
void layout_init(MessageLayout* layout,
void* storage) {
void layout_init(MessageLayout* layout, void* storage) {
memcpy(storage, layout->empty_template, layout->size);
/*
upb_msg_field_iter it;
for (upb_msg_field_begin(&it, layout->msgdef);
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
layout_clear(layout, storage, upb_msg_iter_field(&it));
}
*/
}
void layout_mark(MessageLayout* layout, void* storage) {