Unverified Commit c53e5b8e authored by Paul Yang's avatar Paul Yang Committed by GitHub

Avoid too much overhead in layout_init (#6716)

* Avoid initializing primitive fields in layout_init

* Avoid initializing string/bytes/message fields in layout_init

* Lazily create map when needed

* Lazily create repeated fields

* Change layout_init to only do memcpy

* Fix test for php-7.0

* Fix conformance test where default value of string/message map is not encoded

* Fix test for zts

* Clean up

* Fix comments
parent 3fa17ca0
......@@ -139,6 +139,8 @@ composer.lock
php/tests/generated/
php/tests/old_protoc
php/tests/protobuf/
php/tests/core
php/tests/vgcore*
php/ext/google/protobuf/.libs/
php/ext/google/protobuf/Makefile.fragments
php/ext/google/protobuf/Makefile.global
......
......@@ -259,6 +259,19 @@ void repeated_field_push_native(RepeatedField *intern, void *value) {
}
}
void repeated_field_ensure_created(
const upb_fielddef *field,
CACHED_VALUE *repeated_field PHP_PROTO_TSRMLS_DC) {
if (ZVAL_IS_NULL(CACHED_PTR_TO_ZVAL_PTR(repeated_field))) {
zval_ptr_dtor(repeated_field);
#if PHP_MAJOR_VERSION < 7
MAKE_STD_ZVAL(CACHED_PTR_TO_ZVAL_PTR(repeated_field));
#endif
repeated_field_create_with_field(repeated_field_type, field,
repeated_field PHP_PROTO_TSRMLS_CC);
}
}
void repeated_field_create_with_field(
zend_class_entry *ce, const upb_fielddef *field,
CACHED_VALUE *repeated_field PHP_PROTO_TSRMLS_DC) {
......
This diff is collapsed.
......@@ -243,6 +243,18 @@ map_field_handlers->write_dimension = map_field_write_dimension;
map_field_handlers->get_gc = map_field_get_gc;
PHP_PROTO_INIT_CLASS_END
void map_field_ensure_created(const upb_fielddef *field,
CACHED_VALUE *map_field PHP_PROTO_TSRMLS_DC) {
if (ZVAL_IS_NULL(CACHED_PTR_TO_ZVAL_PTR(map_field))) {
zval_ptr_dtor(map_field);
#if PHP_MAJOR_VERSION < 7
MAKE_STD_ZVAL(CACHED_PTR_TO_ZVAL_PTR(map_field));
#endif
map_field_create_with_field(map_field_type, field,
map_field PHP_PROTO_TSRMLS_CC);
}
}
void map_field_create_with_field(const zend_class_entry *ce,
const upb_fielddef *field,
CACHED_VALUE *map_field PHP_PROTO_TSRMLS_DC) {
......
......@@ -178,7 +178,7 @@ static zval* message_get_property_internal(zval* object,
zend_get_property_info(Z_OBJCE_P(object), Z_STR_P(member), true);
#endif
return layout_get(
self->descriptor->layout, message_data(self), field,
self->descriptor->layout, self, field,
OBJ_PROP(Z_OBJ_P(object), property_info->offset) TSRMLS_CC);
}
......@@ -191,7 +191,7 @@ static void message_get_oneof_property_internal(zval* object, zval* member,
return;
}
layout_get(self->descriptor->layout, message_data(self), field,
layout_get(self->descriptor->layout, self, field,
ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC);
}
......@@ -255,7 +255,6 @@ void custom_data_init(const zend_class_entry* ce,
MessageHeader* intern PHP_PROTO_TSRMLS_DC) {
Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(ce));
intern->data = ALLOC_N(uint8_t, desc->layout->size);
memset(message_data(intern), 0, desc->layout->size);
// We wrap first so that everything in the message object is GC-rooted in
// case a collection happens during object creation in layout_init().
intern->descriptor = desc;
......@@ -575,9 +574,9 @@ PHP_METHOD(Message, readOneof) {
const upb_fielddef* field = upb_msgdef_itof(msg->descriptor->msgdef, index);
// Unlike singular fields, oneof fields share cached property. So we cannot
// let lay_get modify the cached property. Instead, we pass in the return
// let layout_get modify the cached property. Instead, we pass in the return
// value directly.
layout_get(msg->descriptor->layout, message_data(msg), field,
layout_get(msg->descriptor->layout, msg, field,
ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC);
}
......
......@@ -200,7 +200,7 @@
#define CACHED_VALUE zval*
#define CACHED_TO_ZVAL_PTR(VALUE) (VALUE)
#define CACHED_PTR_TO_ZVAL_PTR(VALUE) (*VALUE)
#define CACHED_PTR_TO_ZVAL_PTR(VALUE) (*(CACHED_VALUE*)(VALUE))
#define ZVAL_PTR_TO_CACHED_PTR(VALUE) (&VALUE)
#define ZVAL_PTR_TO_CACHED_VALUE(VALUE) (VALUE)
#define ZVAL_TO_CACHED_VALUE(VALUE) (&VALUE)
......@@ -475,7 +475,7 @@ static inline int php_proto_zend_hash_get_current_data_ex(HashTable* ht,
#define CACHED_VALUE zval
#define CACHED_TO_ZVAL_PTR(VALUE) (&VALUE)
#define CACHED_PTR_TO_ZVAL_PTR(VALUE) (VALUE)
#define CACHED_PTR_TO_ZVAL_PTR(VALUE) ((CACHED_VALUE*)(VALUE))
#define ZVAL_PTR_TO_CACHED_PTR(VALUE) (VALUE)
#define ZVAL_PTR_TO_CACHED_VALUE(VALUE) (*VALUE)
#define ZVAL_TO_CACHED_VALUE(VALUE) (VALUE)
......@@ -935,6 +935,7 @@ struct MessageField {
struct MessageLayout {
const upb_msgdef* msgdef;
void* empty_template; // Can memcpy() onto a layout to clear it.
MessageField* fields;
size_t size;
};
......@@ -948,7 +949,7 @@ PHP_PROTO_WRAP_OBJECT_END
MessageLayout* create_layout(const upb_msgdef* msgdef);
void layout_init(MessageLayout* layout, void* storage,
zend_object* object PHP_PROTO_TSRMLS_DC);
zval* layout_get(MessageLayout* layout, const void* storage,
zval* layout_get(MessageLayout* layout, MessageHeader* header,
const upb_fielddef* field, CACHED_VALUE* cache TSRMLS_DC);
void layout_set(MessageLayout* layout, MessageHeader* header,
const upb_fielddef* field, zval* val TSRMLS_DC);
......@@ -1089,6 +1090,8 @@ upb_value map_iter_value(MapIter* iter, int* len);
const upb_fielddef* map_entry_key(const upb_msgdef* msgdef);
const upb_fielddef* map_entry_value(const upb_msgdef* msgdef);
void map_field_ensure_created(const upb_fielddef *field,
CACHED_VALUE *map_field PHP_PROTO_TSRMLS_DC);
void map_field_create_with_field(const zend_class_entry* ce,
const upb_fielddef* field,
CACHED_VALUE* map_field PHP_PROTO_TSRMLS_DC);
......@@ -1147,6 +1150,9 @@ PHP_PROTO_WRAP_OBJECT_START(RepeatedFieldIter)
long position;
PHP_PROTO_WRAP_OBJECT_END
void repeated_field_ensure_created(
const upb_fielddef *field,
CACHED_VALUE *repeated_field PHP_PROTO_TSRMLS_DC);
void repeated_field_create_with_field(
zend_class_entry* ce, const upb_fielddef* field,
CACHED_VALUE* repeated_field PHP_PROTO_TSRMLS_DC);
......@@ -1489,6 +1495,9 @@ size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
#define FREE(object) efree(object)
#define PEFREE(object) pefree(object, 1)
// Find corresponding zval property for the field.
CACHED_VALUE* find_zval_property(MessageHeader* msg, const upb_fielddef* field);
// String argument.
#define STR(str) (str), strlen(str)
......
This diff is collapsed.
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