From 13aa1311d72e97b5cbe1f529aa48b592d99b1091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Sat, 1 Oct 2022 00:54:05 +0200 Subject: [PATCH] Optimize array access and basic arithmetic operator on integer and floats. [INTERPRETER] * OPT: Optimize array access and basic arithmetic operator on integer and floats. --- main/gbx/gbx_exec_loop.c | 415 +++++++++++++++++++++++++++++++++++---- main/gbx/gbx_value.h | 2 +- main/share/gb_common.h | 3 +- main/share/gb_pcode.h | 15 ++ 4 files changed, 391 insertions(+), 44 deletions(-) diff --git a/main/gbx/gbx_exec_loop.c b/main/gbx/gbx_exec_loop.c index 9ed539008..26fc520e3 100644 --- a/main/gbx/gbx_exec_loop.c +++ b/main/gbx/gbx_exec_loop.c @@ -67,7 +67,7 @@ #define TEST_XX() (code & 1) static void my_VALUE_class_read(CLASS *class, VALUE *value, char *addr, CTYPE ctype, void *ref); -static void my_VALUE_class_constant(CLASS *class, VALUE *value, int ind); +//static void my_VALUE_class_constant(CLASS *class, VALUE *value, int ind); static void _break(ushort code); //static void _SUBR_comp(ushort code); @@ -366,20 +366,20 @@ void EXEC_loop(void) /* 9E MkInt$... */ &&_SUBR_CODE, /* 9F Byte@... */ &&_SUBR_CODE, /* A0 ADD QUICK */ &&_ADD_QUICK, - /* A1 ADD QUICK */ &&_ADD_QUICK, - /* A2 ADD QUICK */ &&_ADD_QUICK, - /* A3 ADD QUICK */ &&_ADD_QUICK, - /* A4 ADD QUICK */ &&_ADD_QUICK, - /* A5 ADD QUICK */ &&_ADD_QUICK, - /* A6 ADD QUICK */ &&_ADD_QUICK, - /* A7 ADD QUICK */ &&_ADD_QUICK, - /* A8 ADD QUICK */ &&_ADD_QUICK, - /* A9 ADD QUICK */ &&_ADD_QUICK, - /* AA ADD QUICK */ &&_ADD_QUICK, - /* AB ADD QUICK */ &&_ADD_QUICK, - /* AC ADD QUICK */ &&_ADD_QUICK, - /* AD ADD QUICK */ &&_ADD_QUICK, - /* AE ADD QUICK */ &&_ADD_QUICK, + /* A1 ADD QUICK */ &&_PUSH_ARRAY_NATIVE_INTEGER, + /* A2 ADD QUICK */ &&_POP_ARRAY_NATIVE_INTEGER, + /* A3 ADD QUICK */ &&_PUSH_ARRAY_NATIVE_FLOAT, + /* A4 ADD QUICK */ &&_POP_ARRAY_NATIVE_FLOAT, + /* A5 ADD QUICK */ &&_PUSH_ARRAY_NATIVE_COLLECTION, + /* A6 ADD QUICK */ &&_POP_ARRAY_NATIVE_COLLECTION, + /* A7 ADD QUICK */ &&_ADD_INTEGER, + /* A8 ADD QUICK */ &&_ADD_FLOAT, + /* A9 ADD QUICK */ &&_SUB_INTEGER, + /* AA ADD QUICK */ &&_SUB_FLOAT, + /* AB ADD QUICK */ &&_MUL_INTEGER, + /* AC ADD QUICK */ &&_MUL_FLOAT, + /* AD ADD QUICK */ &&_DIV_INTEGER, + /* AE ADD QUICK */ &&_DIV_FLOAT, /* AF ADD QUICK */ &&_ADD_QUICK, /* B0 PUSH CLASS */ &&_PUSH_CLASS, /* B1 PUSH CLASS */ &&_PUSH_CLASS, @@ -463,9 +463,38 @@ void EXEC_loop(void) /* FF PUSH QUICK */ &&_PUSH_QUICK }; + static bool not_3_18 = FALSE; + int NO_WARNING(ind); ushort code; + if (CP->not_3_18 != not_3_18) + { + not_3_18 = !not_3_18; + if (not_3_18) + { + for (int i = 0xA1; i <= 0xAE; i++) + jump_table[i] = &&_ADD_QUICK; + } + else + { + jump_table[0xA1] = &&_PUSH_ARRAY_NATIVE_INTEGER; + jump_table[0xA2] = &&_POP_ARRAY_NATIVE_INTEGER; + jump_table[0xA3] = &&_PUSH_ARRAY_NATIVE_FLOAT; + jump_table[0xA4] = &&_POP_ARRAY_NATIVE_FLOAT; + jump_table[0xA5] = &&_PUSH_ARRAY_NATIVE_COLLECTION; + jump_table[0xA6] = &&_POP_ARRAY_NATIVE_COLLECTION; + jump_table[0xA7] = &&_ADD_INTEGER; + jump_table[0xA8] = &&_ADD_FLOAT; + jump_table[0xA9] = &&_SUB_INTEGER; + jump_table[0xAA] = &&_SUB_FLOAT; + jump_table[0xAB] = &&_MUL_INTEGER; + jump_table[0xAC] = &&_MUL_FLOAT; + jump_table[0xAD] = &&_DIV_INTEGER; + jump_table[0xAE] = &&_DIV_FLOAT; + } + } + goto _MAIN; /*-----------------------------------------------*/ @@ -1732,24 +1761,24 @@ __WRITE: /*-----------------------------------------------*/ -_PUSH_CONST: - - ind = GET_UXX(); - my_VALUE_class_constant(CP, SP, ind); - SP++; - goto _NEXT; - - -/*-----------------------------------------------*/ - _PUSH_CONST_EX: PC++; - my_VALUE_class_constant(CP, SP, *PC); + ind = *PC; + goto _PUSH_CONSTANT; + +/*-----------------------------------------------*/ + +_PUSH_CONST: + + ind = GET_UXX(); + +_PUSH_CONSTANT: + + VALUE_class_constant_inline(CP, SP, ind); SP++; goto _NEXT; - /*-----------------------------------------------*/ _PUSH_QUICK: @@ -1860,6 +1889,238 @@ _ADD_QUICK: /*-----------------------------------------------*/ +_PUSH_ARRAY_NATIVE_INTEGER: + + { + VALUE *val; + CARRAY *array; + int i; + + val = &SP[-2]; + array = (CARRAY *)val->_object.object; + if (!array) + THROW_NULL(); + + VALUE_conv_integer(&val[1]); + i = val[1]._integer.value; + + if (i < 0 || i >= array->count) + THROW(E_BOUND); + + val->_integer.value = ((int *)(array->data))[i]; + val->type = GB_T_INTEGER; + + SP = val + 1; + OBJECT_UNREF(array); + goto _NEXT; + } + +_PUSH_ARRAY_NATIVE_FLOAT: + + { + VALUE *val; + CARRAY *array; + int i; + + val = &SP[-2]; + array = (CARRAY *)val->_object.object; + if (!array) + THROW_NULL(); + + VALUE_conv_integer(&val[1]); + i = val[1]._integer.value; + + if (i < 0 || i >= array->count) + THROW(E_BOUND); + + val->_float.value = ((double *)(array->data))[i]; + val->type = GB_T_FLOAT; + + SP = val + 1; + OBJECT_UNREF(array); + goto _NEXT; + } + +_PUSH_ARRAY_NATIVE_COLLECTION: + + { + VALUE *val; + GB_COLLECTION col; + + val = &SP[-2]; + col = (GB_COLLECTION)val->_object.object; + if (!col) + THROW_NULL(); + + VALUE_conv_string(&val[1]); + GB_CollectionGet(col, val[1]._string.addr + val[1]._string.start, val[1]._string.len, (GB_VARIANT *)val); + + RELEASE_STRING(&val[1]); + SP = val; + PUSH(); + OBJECT_UNREF(col); + goto _NEXT; + } + +/*-----------------------------------------------*/ + +_POP_ARRAY_NATIVE_INTEGER: + + { + VALUE *val; + CARRAY *array; + int i; + + val = &SP[-2]; + array = (CARRAY *)val->_object.object; + if (!array) + THROW(E_NULL); + + CARRAY_check_not_read_only(array); + + VALUE_conv_integer(&val[-1]); + VALUE_conv_integer(&val[1]); + + i = val[1]._integer.value; + if (i < 0 || i >= array->count) + THROW(E_BOUND); + + ((int *)(array->data))[i] = val[-1]._integer.value; + + SP = val + 1; + OBJECT_UNREF(array); + SP -= 2; + goto _NEXT; + } + +_POP_ARRAY_NATIVE_FLOAT: + + { + VALUE *val; + CARRAY *array; + int i; + + val = &SP[-2]; + array = (CARRAY *)val->_object.object; + if (!array) + THROW_NULL(); + + CARRAY_check_not_read_only(array); + + VALUE_conv_float(&val[-1]); + VALUE_conv_integer(&val[1]); + + i = val[1]._integer.value; + if (i < 0 || i >= array->count) + THROW(E_BOUND); + + ((double *)(array->data))[i] = val[-1]._float.value; + + SP = val + 1; + OBJECT_UNREF(array); + SP -= 2; + goto _NEXT; + } + +_POP_ARRAY_NATIVE_COLLECTION: + + { + VALUE *val; + GB_COLLECTION col; + + val = &SP[-2]; + col = (GB_COLLECTION)val->_object.object; + if (!col) + THROW_NULL(); + + VALUE_conv_variant(&val[-1]); + VALUE_conv_string(&val[1]); + + if (GB_CollectionSet((GB_COLLECTION)col, val[1]._string.addr + val[1]._string.start, val[1]._string.len, (GB_VARIANT *)&val[-1])) + PROPAGATE(); + + RELEASE_MANY(SP, 3); + goto _NEXT; + } + +/*-----------------------------------------------*/ + + { + VALUE *P1, *P2; + +_ADD_INTEGER: + + P1 = SP - 2; + P2 = P1 + 1; + P1->_integer.value += P2->_integer.value; + SP--; + goto _NEXT; + +_ADD_FLOAT: + + P1 = SP - 2; + P2 = P1 + 1; + P1->_float.value += P2->_float.value; + SP--; + goto _NEXT; + +_SUB_INTEGER: + + P1 = SP - 2; + P2 = P1 + 1; + P1->_integer.value -= P2->_integer.value; + SP--; + goto _NEXT; + +_SUB_FLOAT: + + P1 = SP - 2; + P2 = P1 + 1; + P1->_float.value -= P2->_float.value; + SP--; + goto _NEXT; + +_MUL_INTEGER: + + P1 = SP - 2; + P2 = P1 + 1; + P1->_integer.value *= P2->_integer.value; + SP--; + goto _NEXT; + +_MUL_FLOAT: + + P1 = SP - 2; + P2 = P1 + 1; + P1->_float.value *= P2->_float.value; + SP--; + goto _NEXT; + +_DIV_INTEGER: + + P1 = SP - 2; + P2 = P1 + 1; + VALUE_conv_float(P1); + VALUE_conv_float(P2); + goto _DIV_FLOAT_2; + +_DIV_FLOAT: + + P1 = SP - 2; + P2 = P1 + 1; + +_DIV_FLOAT_2: + + P1->_float.value /= P2->_float.value; + if (!isfinite(P1->_float.value)) + THROW(E_ZERO); + + SP--; + goto _NEXT; + } + +/*-----------------------------------------------*/ + _TRY: EP = SP; @@ -2658,12 +2919,12 @@ __END: result; \ })*/ -static void my_VALUE_class_constant(CLASS *class, VALUE *value, int ind) +/*static void my_VALUE_class_constant(CLASS *class, VALUE *value, int ind) { VALUE_class_constant_inline(class, value, ind); -} +}*/ -#define MANAGE_VARIANT_OBJECT(_func, _op) \ +#define MANAGE_VARIANT_OBJECT(_func, _op, _opcode) \ ({ \ type = Max(P1->type, P2->type); \ if (TYPE_is_void(P1->type) || TYPE_is_void(P2->type)) \ @@ -2673,7 +2934,13 @@ static void my_VALUE_class_constant(CLASS *class, VALUE *value, int ind) { \ *PC |= type; \ if (P1->type == P2->type) \ + { \ *PC |= 0x10; \ + if (type == T_INTEGER) \ + *PC = _opcode##_INTEGER; \ + else if (type == T_FLOAT) \ + *PC = _opcode##_FLOAT; \ + } \ goto *jump[type]; \ } \ \ @@ -2716,7 +2983,7 @@ static void my_VALUE_class_constant(CLASS *class, VALUE *value, int ind) } \ }) -#define MANAGE_VARIANT_POINTER_OBJECT(_func, _op) \ +#define MANAGE_VARIANT_POINTER_OBJECT(_func, _op, _opcode) \ ({ \ type = Max(P1->type, P2->type); \ if (TYPE_is_void(P1->type) || TYPE_is_void(P2->type)) \ @@ -2726,7 +2993,16 @@ static void my_VALUE_class_constant(CLASS *class, VALUE *value, int ind) { \ *PC |= type; \ if (P1->type == P2->type) \ + { \ *PC |= 0x10; \ + if (!CP->not_3_18) \ + { \ + if (type == T_INTEGER) \ + *PC = _opcode##_INTEGER; \ + else if (type == T_FLOAT) \ + *PC = _opcode##_FLOAT; \ + } \ + } \ goto *jump[type]; \ } \ \ @@ -2867,7 +3143,7 @@ __OBJECT: __VARIANT: - MANAGE_VARIANT_POINTER_OBJECT(_SUBR_add, CO_ADD); + MANAGE_VARIANT_POINTER_OBJECT(_SUBR_add, CO_ADD, C_ADD); goto __ERROR; __ERROR: @@ -2972,7 +3248,7 @@ __OBJECT: __VARIANT: - MANAGE_VARIANT_POINTER_OBJECT(_SUBR_sub, CO_SUB); + MANAGE_VARIANT_POINTER_OBJECT(_SUBR_sub, CO_SUB, C_SUB); goto __ERROR; __ERROR: @@ -3066,7 +3342,7 @@ __OBJECT: __VARIANT: - MANAGE_VARIANT_OBJECT(_SUBR_mul, CO_MUL); + MANAGE_VARIANT_OBJECT(_SUBR_mul, CO_MUL, C_MUL); goto __ERROR; __ERROR: @@ -3155,7 +3431,7 @@ __OBJECT: __VARIANT: - MANAGE_VARIANT_OBJECT(_SUBR_div, CO_DIV); + MANAGE_VARIANT_OBJECT(_SUBR_div, CO_DIV, C_DIV); goto __ERROR; __ERROR: @@ -3616,9 +3892,29 @@ __PUSH_GENERIC: { array = (CARRAY *)object; if (array->type == GB_T_INTEGER) - fast = 0xD0; + { + if (CP->not_3_18) + { + fast = 0xD0; + } + else + { + *PC = C_PUSH_ARRAY_NATIVE_INTEGER; + goto __PUSH_ARRAY_2; + } + } else if (array->type == GB_T_FLOAT) - fast = 0xE0; + { + if (CP->not_3_18) + { + fast = 0xE0; + } + else + { + *PC = C_PUSH_ARRAY_NATIVE_FLOAT; + goto __PUSH_ARRAY_2; + } + } else if (TYPE_is_object(array->type)) fast = 0xB0; else @@ -3639,7 +3935,15 @@ __PUSH_GENERIC: else if (np > 1) THROW(E_TMPARAM); - fast = 0xC0; + if (CP->not_3_18) + { + fast = 0xC0; + } + else + { + *PC = C_PUSH_ARRAY_NATIVE_COLLECTION; + goto __PUSH_ARRAY_2; + } } else { @@ -3781,7 +4085,6 @@ void EXEC_pop_array(ushort code) &&__POP_NATIVE_COLLECTION, &&__POP_NATIVE_ARRAY_INTEGER, &&__POP_NATIVE_ARRAY_FLOAT, NULL }; - CLASS *class; OBJECT *object; ushort np; @@ -3812,9 +4115,29 @@ __POP_GENERIC: { array = (CARRAY *)object; if (array->type == GB_T_INTEGER) - fast = 0xD0; + { + if (CP->not_3_18) + { + fast = 0xD0; + } + else + { + *PC = C_POP_ARRAY_NATIVE_INTEGER; + goto __POP_ARRAY_2; + } + } else if (array->type == GB_T_FLOAT) - fast = 0xE0; + { + if (CP->not_3_18) + { + fast = 0xE0; + } + else + { + *PC = C_POP_ARRAY_NATIVE_FLOAT; + goto __POP_ARRAY_2; + } + } else if (TYPE_is_object(array->type)) fast = 0xB0; else @@ -3835,7 +4158,15 @@ __POP_GENERIC: else if (np > 2) THROW(E_TMPARAM); - fast = 0xC0; + if (CP->not_3_18) + { + fast = 0xC0; + } + else + { + *PC = C_POP_ARRAY_NATIVE_COLLECTION; + goto __POP_ARRAY_2; + } } else { diff --git a/main/gbx/gbx_value.h b/main/gbx/gbx_value.h index 459afcee2..2738eb992 100644 --- a/main/gbx/gbx_value.h +++ b/main/gbx/gbx_value.h @@ -479,7 +479,7 @@ void THROW_TYPE(TYPE wanted, TYPE got) NORETURN; &&__ILLEGAL, &&__STRING, &&__CSTRING, &&__POINTER, &&__ILLEGAL, &&__ILLEGAL, &&__ILLEGAL, &&__ILLEGAL \ }; \ \ - CLASS_CONST *cc; \ + CLASS_CONST *NO_WARNING(cc); \ \ for(;;) \ { \ diff --git a/main/share/gb_common.h b/main/share/gb_common.h index 7031f28d0..01a86c43e 100644 --- a/main/share/gb_common.h +++ b/main/share/gb_common.h @@ -137,12 +137,13 @@ typedef size_t offset_t; #define PUBLIC -#define INLINE __inline__ +#define INLINE __attribute__((always_inline)) inline #define EXTERN extern #define PACKED __attribute__((packed)) #define NORETURN __attribute__((noreturn)) #define CONST __attribute__((const)) + #if __WORDSIZE == 64 #define OS_64BITS 1 #endif diff --git a/main/share/gb_pcode.h b/main/share/gb_pcode.h index 84692fce0..0edcd8e03 100644 --- a/main/share/gb_pcode.h +++ b/main/share/gb_pcode.h @@ -40,6 +40,21 @@ #define C_ADD_QUICK 0xA000 +#define C_PUSH_ARRAY_NATIVE_INTEGER 0xA100 +#define C_POP_ARRAY_NATIVE_INTEGER 0xA200 +#define C_PUSH_ARRAY_NATIVE_FLOAT 0xA300 +#define C_POP_ARRAY_NATIVE_FLOAT 0xA400 +#define C_PUSH_ARRAY_NATIVE_COLLECTION 0xA500 +#define C_POP_ARRAY_NATIVE_COLLECTION 0xA600 +#define C_ADD_INTEGER 0xA700 +#define C_ADD_FLOAT 0xA800 +#define C_SUB_INTEGER 0xA900 +#define C_SUB_FLOAT 0xAA00 +#define C_MUL_INTEGER 0xAB00 +#define C_MUL_FLOAT 0xAC00 +#define C_DIV_INTEGER 0xAD00 +#define C_DIV_FLOAT 0xAE00 + #define C_PUSH_LOCAL 0x0100 #define C_PUSH_PARAM 0x0200 #define C_PUSH_ARRAY 0x0300