Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormonojenkins <jo.shields+jenkins@xamarin.com>2018-10-10 20:25:41 +0300
committerGitHub <noreply@github.com>2018-10-10 20:25:41 +0300
commitfb7ad92db918b2a217e4f21f8f46246a701ce8b0 (patch)
treed1729019ffb45e222711098b1335d92d9473ce99
parent61613246290ab634a02ba56c22b0d809f840fa0a (diff)
parent78455914e8ef1b1a871a134081a7e25f975727c5 (diff)
Merge pull request #11053 from BrzVlad/fix-interp-static-field
[interp] Optimize static field access Do most of the work on transform side and include the field address in the instruction stream. We need to run cctor at runtime to preserve expected order. This makes static field access 4 times faster. <!-- Thank you for your Pull Request! If you are new to contributing to Mono, please try to do your best at conforming to our coding guidelines http://www.mono-project.com/community/contributing/coding-guidelines/ but don't worry if you get something wrong. One of the project members will help you to get things landed. Does your pull request fix any of the existing issues? Please use the following format: Fixes #issue-number -->
-rw-r--r--mono/mini/interp/interp.c49
-rw-r--r--mono/mini/interp/mintops.def21
-rw-r--r--mono/mini/interp/transform.c32
3 files changed, 98 insertions, 4 deletions
diff --git a/mono/mini/interp/interp.c b/mono/mini/interp/interp.c
index 02526ec2705..2c2ab929eba 100644
--- a/mono/mini/interp/interp.c
+++ b/mono/mini/interp/interp.c
@@ -4468,6 +4468,31 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st
++sp;
MINT_IN_BREAK;
}
+
+/* We init class here to preserve cctor order */
+#define LDSFLD(datamem, fieldtype) { \
+ MonoVTable *vtable = (MonoVTable*) rtm->data_items [*(guint16*)(ip + 1)]; \
+ if (G_UNLIKELY (!vtable->initialized)) { \
+ mono_runtime_class_init_full (vtable, error); \
+ if (!mono_error_ok (error)) \
+ THROW_EX (mono_error_convert_to_exception (error), ip); \
+ } \
+ sp[0].data.datamem = * (fieldtype *)(rtm->data_items [* (guint16 *)(ip + 2)]) ; \
+ ip += 3; \
+ sp++; \
+ }
+
+ MINT_IN_CASE(MINT_LDSFLD_I1) LDSFLD(i, gint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_U1) LDSFLD(i, guint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_I2) LDSFLD(i, gint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_U2) LDSFLD(i, guint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_I4) LDSFLD(i, gint32); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_I8) LDSFLD(l, gint64); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_R4) LDSFLD(f_r4, float); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_R8) LDSFLD(f, double); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_O) LDSFLD(p, gpointer); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_P) LDSFLD(p, gpointer); MINT_IN_BREAK;
+
MINT_IN_CASE(MINT_LDSFLD) {
MonoClassField *field = (MonoClassField*)rtm->data_items [* (guint16 *)(ip + 1)];
gpointer addr = mono_class_static_field_address (rtm->domain, field);
@@ -4490,6 +4515,30 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st
++sp;
MINT_IN_BREAK;
}
+
+#define STSFLD(datamem, fieldtype) { \
+ MonoVTable *vtable = (MonoVTable*) rtm->data_items [*(guint16*)(ip + 1)]; \
+ if (G_UNLIKELY (!vtable->initialized)) { \
+ mono_runtime_class_init_full (vtable, error); \
+ if (!mono_error_ok (error)) \
+ THROW_EX (mono_error_convert_to_exception (error), ip); \
+ } \
+ sp --; \
+ * (fieldtype *)(rtm->data_items [* (guint16 *)(ip + 2)]) = sp[0].data.datamem; \
+ ip += 3; \
+ }
+
+ MINT_IN_CASE(MINT_STSFLD_I1) STSFLD(i, gint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_U1) STSFLD(i, guint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_I2) STSFLD(i, gint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_U2) STSFLD(i, guint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_I4) STSFLD(i, gint32); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_I8) STSFLD(l, gint64); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_R4) STSFLD(f_r4, float); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_R8) STSFLD(f, double); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_P) STSFLD(p, gpointer); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_O) STSFLD(p, gpointer); MINT_IN_BREAK;
+
MINT_IN_CASE(MINT_STSFLD) {
MonoClassField *field = (MonoClassField*)rtm->data_items [* (guint16 *)(ip + 1)];
gpointer addr = mono_class_static_field_address (rtm->domain, field);
diff --git a/mono/mini/interp/mintops.def b/mono/mini/interp/mintops.def
index 21d16b2cfa8..33fca0240d6 100644
--- a/mono/mini/interp/mintops.def
+++ b/mono/mini/interp/mintops.def
@@ -114,8 +114,29 @@ OPDEF(MINT_STRMFLD, "strmfld", 2, MintOpFieldToken)
OPDEF(MINT_STRMFLD_VT, "strmfld.vt", 2, MintOpUShortInt)
OPDEF(MINT_LDSFLD, "ldsfld", 2, MintOpFieldToken)
+OPDEF(MINT_LDSFLD_I1, "ldsfld.i1", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_U1, "ldsfld.u1", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_I2, "ldsfld.i2", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_U2, "ldsfld.u2", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_I4, "ldsfld.i4", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_I8, "ldsfld.i8", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_R4, "ldsfld.r4", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_R8, "ldsfld.r8", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_O, "ldsfld.o", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_P, "ldsfld.p", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_VT, "ldsfld.vt", 4, MintOpShortAndInt)
+
OPDEF(MINT_STSFLD, "stsfld", 2, MintOpUShortInt)
+OPDEF(MINT_STSFLD_I1, "stsfld.i1", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_U1, "stsfld.u1", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_I2, "stsfld.i2", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_U2, "stsfld.u2", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_I4, "stsfld.i4", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_I8, "stsfld.i8", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_R4, "stsfld.r4", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_R8, "stsfld.r8", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_O, "stsfld.o", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_P, "stsfld.p", 3, MintOpUShortInt)
OPDEF(MINT_STSFLD_VT, "stsfld.vt", 2, MintOpUShortInt)
OPDEF(MINT_LDSFLDA, "ldsflda", 2, MintOpUShortInt)
diff --git a/mono/mini/interp/transform.c b/mono/mini/interp/transform.c
index 8f7c9ac8959..6a336c99684 100644
--- a/mono/mini/interp/transform.c
+++ b/mono/mini/interp/transform.c
@@ -3636,15 +3636,26 @@ generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, unsig
goto_if_nok (error, exit);
MonoType *ftype = mono_field_get_type (field);
mt = mint_type (ftype);
- ADD_CODE(td, mt == MINT_TYPE_VT ? MINT_LDSFLD_VT : MINT_LDSFLD);
- ADD_CODE(td, get_data_item_index (td, field));
klass = NULL;
if (mt == MINT_TYPE_VT) {
+ ADD_CODE(td, MINT_LDSFLD_VT);
+ ADD_CODE(td, get_data_item_index (td, field));
klass = mono_class_from_mono_type (ftype);
int size = mono_class_value_size (klass, NULL);
PUSH_VT(td, size);
WRITE32(td, &size);
} else {
+ if (mono_class_field_is_special_static (field)) {
+ ADD_CODE(td, MINT_LDSFLD);
+ ADD_CODE(td, get_data_item_index (td, field));
+ } else {
+ MonoVTable *vtable = mono_class_vtable_checked (domain, field->parent, error);
+ goto_if_nok (error, exit);
+
+ ADD_CODE(td, MINT_LDSFLD_I1 + mt - MINT_TYPE_I1);
+ ADD_CODE(td, get_data_item_index (td, vtable));
+ ADD_CODE(td, get_data_item_index (td, (char*)mono_vtable_get_static_field_data (vtable) + field->offset));
+ }
if (mt == MINT_TYPE_O)
klass = mono_class_from_mono_type (ftype);
}
@@ -3659,8 +3670,6 @@ generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, unsig
goto_if_nok (error, exit);
MonoType *ftype = mono_field_get_type (field);
mt = mint_type (ftype);
- ADD_CODE(td, mt == MINT_TYPE_VT ? MINT_STSFLD_VT : MINT_STSFLD);
- ADD_CODE(td, get_data_item_index (td, field));
/* the vtable of the field might not be initialized at this point */
MonoClass *fld_klass = mono_class_from_mono_type (field->type);
@@ -3670,7 +3679,22 @@ generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, unsig
if (mt == MINT_TYPE_VT) {
MonoClass *klass = mono_class_from_mono_type (ftype);
int size = mono_class_value_size (klass, NULL);
+ ADD_CODE(td, MINT_STSFLD_VT);
+ ADD_CODE(td, get_data_item_index (td, field));
POP_VT (td, size);
+ } else {
+ if (mono_class_field_is_special_static (field)) {
+ ADD_CODE(td, MINT_STSFLD);
+ ADD_CODE(td, get_data_item_index (td, field));
+ } else {
+ MonoVTable *vtable = mono_class_vtable_checked (domain, field->parent, error);
+ goto_if_nok (error, exit);
+
+ ADD_CODE(td, MINT_STSFLD_I1 + mt - MINT_TYPE_I1);
+ ADD_CODE(td, get_data_item_index (td, vtable));
+ ADD_CODE(td, get_data_item_index (td, (char*)mono_vtable_get_static_field_data (vtable) + field->offset));
+ }
+
}
td->ip += 5;
--td->sp;