From db502912281f2bfa22c14a468dedd138469675bd Mon Sep 17 00:00:00 2001 From: Samantha McVey Date: Mon, 28 May 2018 09:11:22 -0400 Subject: [PATCH] Speed of at_pos, bind_key and at_key by about 4% by speeding up dispatch The compiler can optimize a little more if we add the functions in directly instead of using the pointer attached to the object. These are used a lot in core compilation which is why I decided to optimize these specific ops. --- src/6model/reprconv.c | 98 ++++++++++++++++++++++++++++++------- src/6model/reprs/MVMHash.c | 7 ++- src/6model/reprs/MVMHash.h | 3 ++ src/6model/reprs/P6opaque.c | 3 ++ src/6model/reprs/P6opaque.h | 1 + src/6model/reprs/VMArray.c | 3 ++ src/6model/reprs/VMArray.h | 1 + 7 files changed, 98 insertions(+), 18 deletions(-) diff --git a/src/6model/reprconv.c b/src/6model/reprconv.c index 664b20435d..799bbfa9a8 100644 --- a/src/6model/reprconv.c +++ b/src/6model/reprconv.c @@ -94,30 +94,58 @@ MVM_PUBLIC MVMint64 MVM_repr_exists_pos(MVMThreadContext *tc, MVMObject *obj, MV MVMint64 MVM_repr_at_pos_i(MVMThreadContext *tc, MVMObject *obj, MVMint64 idx) { MVMRegister value; - REPR(obj)->pos_funcs.at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), - idx, &value, MVM_reg_int64); + if (REPR(obj)->ID == MVM_REPR_ID_VMArray) { + MVM_VMArray_at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), + idx, &value, MVM_reg_int64); + } + else { + REPR(obj)->pos_funcs.at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), + idx, &value, MVM_reg_int64); + } return value.i64; } MVMnum64 MVM_repr_at_pos_n(MVMThreadContext *tc, MVMObject *obj, MVMint64 idx) { MVMRegister value; - REPR(obj)->pos_funcs.at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), - idx, &value, MVM_reg_num64); + if (REPR(obj)->ID == MVM_REPR_ID_VMArray) { + MVM_VMArray_at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), + idx, &value, MVM_reg_num64); + } + else { + REPR(obj)->pos_funcs.at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), + idx, &value, MVM_reg_num64); + } return value.n64; } MVMString * MVM_repr_at_pos_s(MVMThreadContext *tc, MVMObject *obj, MVMint64 idx) { MVMRegister value; - REPR(obj)->pos_funcs.at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), - idx, &value, MVM_reg_str); + if (REPR(obj)->ID == MVM_REPR_ID_VMArray) { + MVM_VMArray_at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), + idx, &value, MVM_reg_str); + } + else { + REPR(obj)->pos_funcs.at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), + idx, &value, MVM_reg_str); + } return value.s; } MVMObject * MVM_repr_at_pos_o(MVMThreadContext *tc, MVMObject *obj, MVMint64 idx) { - if (IS_CONCRETE(obj)) { + if (MVM_LIKELY(IS_CONCRETE(obj))) { MVMRegister value; - REPR(obj)->pos_funcs.at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), - idx, &value, MVM_reg_obj); + if (REPR(obj)->ID == MVM_REPR_ID_VMArray) { + MVM_VMArray_at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), + idx, &value, MVM_reg_obj); + } + else if (REPR(obj)->ID == MVM_REPR_ID_P6opaque) { + MVM_P6opaque_at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), + idx, &value, MVM_reg_obj); + } + else { + REPR(obj)->pos_funcs.at_pos(tc, STABLE(obj), obj, OBJECT_BODY(obj), + idx, &value, MVM_reg_obj); + } return value.o; } return tc->instance->VMNull; @@ -438,30 +466,54 @@ MVMObject * MVM_repr_shift_o(MVMThreadContext *tc, MVMObject *obj) { MVMint64 MVM_repr_at_key_i(MVMThreadContext *tc, MVMObject *obj, MVMString *key) { MVMRegister value; - REPR(obj)->ass_funcs.at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + if (REPR(obj)->ID == MVM_REPR_ID_MVMHash) { + MVMHash_at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + (MVMObject *)key, &value, MVM_reg_int64); + } + else { + REPR(obj)->ass_funcs.at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), (MVMObject *)key, &value, MVM_reg_int64); + } return value.i64; } MVMnum64 MVM_repr_at_key_n(MVMThreadContext *tc, MVMObject *obj, MVMString *key) { MVMRegister value; - REPR(obj)->ass_funcs.at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + if (REPR(obj)->ID == MVM_REPR_ID_MVMHash) { + MVMHash_at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + (MVMObject *)key, &value, MVM_reg_num64); + } + else { + REPR(obj)->ass_funcs.at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), (MVMObject *)key, &value, MVM_reg_num64); + } return value.n64; } MVMString * MVM_repr_at_key_s(MVMThreadContext *tc, MVMObject *obj, MVMString *key) { MVMRegister value; - REPR(obj)->ass_funcs.at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + if (REPR(obj)->ID == MVM_REPR_ID_MVMHash) { + MVMHash_at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + (MVMObject *)key, &value, MVM_reg_str); + } + else { + REPR(obj)->ass_funcs.at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), (MVMObject *)key, &value, MVM_reg_str); + } return value.s; } MVMObject * MVM_repr_at_key_o(MVMThreadContext *tc, MVMObject *obj, MVMString *key) { if (MVM_LIKELY(IS_CONCRETE(obj))) { MVMRegister value; - REPR(obj)->ass_funcs.at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + if (REPR(obj)->ID == MVM_REPR_ID_MVMHash) { + MVMHash_at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + (MVMObject *)key, &value, MVM_reg_obj); + } + else { + REPR(obj)->ass_funcs.at_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), (MVMObject *)key, &value, MVM_reg_obj); + } return value.o; } return tc->instance->VMNull; @@ -484,15 +536,27 @@ void MVM_repr_bind_key_n(MVMThreadContext *tc, MVMObject *obj, MVMString *key, M void MVM_repr_bind_key_s(MVMThreadContext *tc, MVMObject *obj, MVMString *key, MVMString *val) { MVMRegister value; value.s = val; - REPR(obj)->ass_funcs.bind_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), - (MVMObject *)key, value, MVM_reg_str); + if (REPR(obj)->ID == MVM_REPR_ID_MVMHash) { + MVMHash_bind_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + (MVMObject *)key, value, MVM_reg_str); + } + else { + REPR(obj)->ass_funcs.bind_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + (MVMObject *)key, value, MVM_reg_str); + } } void MVM_repr_bind_key_o(MVMThreadContext *tc, MVMObject *obj, MVMString *key, MVMObject *val) { MVMRegister value; value.o = val; - REPR(obj)->ass_funcs.bind_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), - (MVMObject *)key, value, MVM_reg_obj); + if (REPR(obj)->ID == MVM_REPR_ID_MVMHash) { + MVMHash_bind_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + (MVMObject *)key, value, MVM_reg_obj); + } + else { + REPR(obj)->ass_funcs.bind_key(tc, STABLE(obj), obj, OBJECT_BODY(obj), + (MVMObject *)key, value, MVM_reg_obj); + } } MVMint64 MVM_repr_exists_key(MVMThreadContext *tc, MVMObject *obj, MVMString *key) { diff --git a/src/6model/reprs/MVMHash.c b/src/6model/reprs/MVMHash.c index 94c0132b77..86ff108b3f 100644 --- a/src/6model/reprs/MVMHash.c +++ b/src/6model/reprs/MVMHash.c @@ -78,6 +78,9 @@ static void at_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *d MVM_exception_throw_adhoc(tc, "MVMHash representation does not support native type storage"); } +void MVMHash_at_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key_obj, MVMRegister *result, MVMuint16 kind) { + return at_key(tc, st, root, data, key_obj, result, kind); +} static void bind_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key_obj, MVMRegister value, MVMuint16 kind) { MVMHashBody *body = (MVMHashBody *)data; @@ -101,7 +104,9 @@ static void bind_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void MVM_ASSIGN_REF(tc, &(root->header), entry->value, value.o); } } - +void MVMHash_bind_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key_obj, MVMRegister value, MVMuint16 kind) { + return bind_key(tc, st, root, data, key_obj, value, kind); +} static MVMuint64 elems(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) { MVMHashBody *body = (MVMHashBody *)data; return HASH_CNT(hash_handle, body->hash_head); diff --git a/src/6model/reprs/MVMHash.h b/src/6model/reprs/MVMHash.h index 356b1f024e..4994fbabb1 100644 --- a/src/6model/reprs/MVMHash.h +++ b/src/6model/reprs/MVMHash.h @@ -55,3 +55,6 @@ const MVMREPROps * MVMHash_initialize(MVMThreadContext *tc); HASH_CLEAR(hash_handle, head_node); \ MVM_free(tmp); \ } while (0) + +void MVMHash_at_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key_obj, MVMRegister *result, MVMuint16 kind); +void MVMHash_bind_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key_obj, MVMRegister value, MVMuint16 kind); diff --git a/src/6model/reprs/P6opaque.c b/src/6model/reprs/P6opaque.c index 3f9f7f9477..cc2df94ad3 100644 --- a/src/6model/reprs/P6opaque.c +++ b/src/6model/reprs/P6opaque.c @@ -1235,6 +1235,9 @@ static void at_pos(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *d del = get_obj_at_offset(data, repr_data->attribute_offsets[repr_data->pos_del_slot]); REPR(del)->pos_funcs.at_pos(tc, STABLE(del), del, OBJECT_BODY(del), index, value, kind); } +void MVM_P6opaque_at_pos(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 index, MVMRegister *value, MVMuint16 kind) { + return at_pos(tc, st, root, data, index, value, kind); +} static void bind_pos(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 index, MVMRegister value, MVMuint16 kind) { MVMP6opaqueREPRData *repr_data = (MVMP6opaqueREPRData *)st->REPR_data; diff --git a/src/6model/reprs/P6opaque.h b/src/6model/reprs/P6opaque.h index 0ebe0e1b40..2881864cc8 100644 --- a/src/6model/reprs/P6opaque.h +++ b/src/6model/reprs/P6opaque.h @@ -123,3 +123,4 @@ MVM_STATIC_INLINE MVMint64 MVM_p6opaque_read_int64(MVMThreadContext *tc, size_t MVM_p6opaque_attr_offset(MVMThreadContext *tc, MVMObject *type, MVMObject *class_handle, MVMString *name); +void MVM_P6opaque_at_pos(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 index, MVMRegister *value, MVMuint16 kind); diff --git a/src/6model/reprs/VMArray.c b/src/6model/reprs/VMArray.c index 7a857bb8b9..f08083c5d9 100644 --- a/src/6model/reprs/VMArray.c +++ b/src/6model/reprs/VMArray.c @@ -241,6 +241,9 @@ static void at_pos(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *d MVM_exception_throw_adhoc(tc, "MVMArray: Unhandled slot type, got '%s'", MVM_reg_get_debug_name(tc, repr_data->slot_type)); } } +void MVM_VMArray_at_pos(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 index, MVMRegister *value, MVMuint16 kind) { + return at_pos(tc, st, root, data, index, value, kind); +} static MVMuint64 zero_slots(MVMThreadContext *tc, MVMArrayBody *body, MVMuint64 elems, MVMuint64 ssize, MVMuint8 slot_type) { diff --git a/src/6model/reprs/VMArray.h b/src/6model/reprs/VMArray.h index 6191356f9d..7f6dd175ab 100644 --- a/src/6model/reprs/VMArray.h +++ b/src/6model/reprs/VMArray.h @@ -75,3 +75,4 @@ struct MVMArrayREPRData { /* Type object for the element type. */ MVMObject *elem_type; }; +void MVM_VMArray_at_pos(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMint64 index, MVMRegister *value, MVMuint16 kind);