Commit cf07d3c1 authored by Joshua Haberman's avatar Joshua Haberman

layout_init() optimization works!

parent 78378dab
...@@ -495,7 +495,7 @@ VALUE Map_length(VALUE _self) { ...@@ -495,7 +495,7 @@ VALUE Map_length(VALUE _self) {
return ULL2NUM(upb_strtable_count(&self->table)); return ULL2NUM(upb_strtable_count(&self->table));
} }
static VALUE Map_new_this_type(VALUE _self) { VALUE Map_new_this_type(VALUE _self) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
VALUE new_map = Qnil; VALUE new_map = Qnil;
VALUE key_type = fieldtype_to_ruby(self->key_type); VALUE key_type = fieldtype_to_ruby(self->key_type);
......
...@@ -70,8 +70,6 @@ VALUE Message_alloc(VALUE klass) { ...@@ -70,8 +70,6 @@ VALUE Message_alloc(VALUE klass) {
msg = (MessageHeader*)ALLOC_N(uint8_t, msg = (MessageHeader*)ALLOC_N(uint8_t,
sizeof(MessageHeader) + desc->layout->size); sizeof(MessageHeader) + desc->layout->size);
memset(Message_data(msg), 0, desc->layout->size);
// We wrap first so that everything in the message object is GC-rooted in case // We wrap first so that everything in the message object is GC-rooted in case
// a collection happens during object creation in layout_init(). // a collection happens during object creation in layout_init().
ret = TypedData_Wrap_Struct(klass, &Message_type, msg); ret = TypedData_Wrap_Struct(klass, &Message_type, msg);
......
...@@ -419,6 +419,7 @@ extern VALUE cRepeatedField; ...@@ -419,6 +419,7 @@ extern VALUE cRepeatedField;
RepeatedField* ruby_to_RepeatedField(VALUE value); RepeatedField* ruby_to_RepeatedField(VALUE value);
VALUE RepeatedField_new_this_type(VALUE _self);
VALUE RepeatedField_each(VALUE _self); VALUE RepeatedField_each(VALUE _self);
VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self); VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self);
void* RepeatedField_index_native(VALUE _self, int index); void* RepeatedField_index_native(VALUE _self, int index);
...@@ -467,6 +468,7 @@ extern VALUE cMap; ...@@ -467,6 +468,7 @@ extern VALUE cMap;
Map* ruby_to_Map(VALUE value); Map* ruby_to_Map(VALUE value);
VALUE Map_new_this_type(VALUE _self);
VALUE Map_each(VALUE _self); VALUE Map_each(VALUE _self);
VALUE Map_keys(VALUE _self); VALUE Map_keys(VALUE _self);
VALUE Map_values(VALUE _self); VALUE Map_values(VALUE _self);
...@@ -522,11 +524,13 @@ struct MessageLayout { ...@@ -522,11 +524,13 @@ struct MessageLayout {
uint32_t size; uint32_t size;
uint32_t value_offset; uint32_t value_offset;
int value_count; int value_count;
int repeated_count;
int map_count;
}; };
#define ONEOF_CASE_MASK 0x80000000 #define ONEOF_CASE_MASK 0x80000000
MessageLayout* create_layout(Descriptor* desc); void create_layout(Descriptor* desc);
void free_layout(MessageLayout* layout); void free_layout(MessageLayout* layout);
bool field_contains_hasbit(MessageLayout* layout, bool field_contains_hasbit(MessageLayout* layout,
const upb_fielddef* field); const upb_fielddef* field);
......
...@@ -323,7 +323,7 @@ VALUE RepeatedField_length(VALUE _self) { ...@@ -323,7 +323,7 @@ VALUE RepeatedField_length(VALUE _self) {
return INT2NUM(self->size); return INT2NUM(self->size);
} }
static VALUE RepeatedField_new_this_type(VALUE _self) { VALUE RepeatedField_new_this_type(VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
VALUE new_rptfield = Qnil; VALUE new_rptfield = Qnil;
VALUE element_type = fieldtype_to_ruby(self->field_type); VALUE element_type = fieldtype_to_ruby(self->field_type);
......
...@@ -478,7 +478,7 @@ bool is_value_field(const upb_fielddef* f) { ...@@ -478,7 +478,7 @@ bool is_value_field(const upb_fielddef* f) {
upb_fielddef_isstring(f); upb_fielddef_isstring(f);
} }
MessageLayout* create_layout(Descriptor* desc) { void create_layout(Descriptor* desc) {
const upb_msgdef *msgdef = desc->msgdef; const upb_msgdef *msgdef = desc->msgdef;
MessageLayout* layout = ALLOC(MessageLayout); MessageLayout* layout = ALLOC(MessageLayout);
int nfields = upb_msgdef_numfields(msgdef); int nfields = upb_msgdef_numfields(msgdef);
...@@ -517,14 +517,49 @@ MessageLayout* create_layout(Descriptor* desc) { ...@@ -517,14 +517,49 @@ MessageLayout* create_layout(Descriptor* desc) {
off = align_up_to(off, sizeof(VALUE)); off = align_up_to(off, sizeof(VALUE));
layout->value_offset = off; layout->value_offset = off;
layout->repeated_count = 0;
layout->map_count = 0;
layout->value_count = 0; layout->value_count = 0;
// Place all (non-oneof) VALUE fields first. // Place all VALUE fields for repeated fields.
for (upb_msg_field_begin(&it, msgdef); for (upb_msg_field_begin(&it, msgdef);
!upb_msg_field_done(&it); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) { upb_msg_field_next(&it)) {
const upb_fielddef* field = upb_msg_iter_field(&it); const upb_fielddef* field = upb_msg_iter_field(&it);
if (upb_fielddef_containingoneof(field) || !is_value_field(field)) { if (upb_fielddef_containingoneof(field) || !upb_fielddef_isseq(field) ||
upb_fielddef_ismap(field)) {
continue;
}
layout->fields[upb_fielddef_index(field)].offset = off;
off += sizeof(VALUE);
layout->repeated_count++;
}
// Place all VALUE fields for map fields.
for (upb_msg_field_begin(&it, msgdef);
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* field = upb_msg_iter_field(&it);
if (upb_fielddef_containingoneof(field) || !upb_fielddef_isseq(field) ||
!upb_fielddef_ismap(field)) {
continue;
}
layout->fields[upb_fielddef_index(field)].offset = off;
off += sizeof(VALUE);
layout->map_count++;
}
layout->value_count = layout->repeated_count + layout->map_count;
// Next place all other (non-oneof) VALUE fields.
for (upb_msg_field_begin(&it, msgdef);
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* field = upb_msg_iter_field(&it);
if (upb_fielddef_containingoneof(field) || !is_value_field(field) ||
upb_fielddef_isseq(field)) {
continue; continue;
} }
...@@ -909,7 +944,19 @@ void layout_set(MessageLayout* layout, ...@@ -909,7 +944,19 @@ void layout_set(MessageLayout* layout,
} }
void layout_init(MessageLayout* layout, void* storage) { void layout_init(MessageLayout* layout, void* storage) {
VALUE* value = (VALUE*)CHARPTR_AT(storage, layout->value_offset);
int i;
memcpy(storage, layout->empty_template, layout->size); memcpy(storage, layout->empty_template, layout->size);
for (i = 0; i < layout->repeated_count; i++, value++) {
*value = RepeatedField_new_this_type(*value);
}
for (i = 0; i < layout->map_count; i++, value++) {
*value = Map_new_this_type(*value);
}
/* /*
upb_msg_field_iter it; upb_msg_field_iter it;
for (upb_msg_field_begin(&it, layout->msgdef); for (upb_msg_field_begin(&it, layout->msgdef);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment