@@ -1050,6 +1050,22 @@ interp_throw (ThreadContext *context, MonoException *ex, InterpFrame *frame, con
10501050 } \
10511051 } while (0)
10521052
1053+ // Reduce duplicate code in interp_exec_method
1054+ static void
1055+ do_safepoint (InterpFrame * frame , ThreadContext * context )
1056+ {
1057+ context_set_safepoint_frame (context , frame );
1058+ /* Poll safepoint */
1059+ mono_threads_safepoint ();
1060+ context_clear_safepoint_frame (context );
1061+ }
1062+
1063+ #define SAFEPOINT \
1064+ do { \
1065+ if (G_UNLIKELY (mono_polling_required)) \
1066+ do_safepoint (frame, context); \
1067+ } while (0)
1068+
10531069static MonoObject *
10541070ves_array_create (MonoClass * klass , int param_count , stackval * values , MonoError * error )
10551071{
@@ -4164,6 +4180,79 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
41644180 CONDBR (mono_isunordered (d1 , d2 ) || d1 < d2 )
41654181 MINT_IN_BREAK ;
41664182 }
4183+
4184+ #define ZEROP_SP (datatype , op ) \
4185+ if (LOCAL_VAR (ip [1 ], datatype ) op 0 ) { \
4186+ gint16 br_offset = (gint16 ) ip [2 ]; \
4187+ BACK_BRANCH_PROFILE (br_offset ); \
4188+ SAFEPOINT ; \
4189+ ip + = br_offset ; \
4190+ } else \
4191+ ip + = 3 ;
4192+
4193+ MINT_IN_CASE (MINT_BRFALSE_I4_SP ) ZEROP_SP (gint32 , == ); MINT_IN_BREAK ;
4194+ MINT_IN_CASE (MINT_BRFALSE_I8_SP ) ZEROP_SP (gint64 , == ); MINT_IN_BREAK ;
4195+ MINT_IN_CASE (MINT_BRTRUE_I4_SP ) ZEROP_SP (gint32 , != ); MINT_IN_BREAK ;
4196+ MINT_IN_CASE (MINT_BRTRUE_I8_SP ) ZEROP_SP (gint64 , != ); MINT_IN_BREAK ;
4197+
4198+ #define CONDBR_SP (cond ) \
4199+ if (cond ) { \
4200+ gint16 br_offset = (gint16 ) ip [3 ]; \
4201+ BACK_BRANCH_PROFILE (br_offset ); \
4202+ SAFEPOINT ; \
4203+ ip + = br_offset ; \
4204+ } else \
4205+ ip + = 4 ;
4206+ #define BRELOP_SP (datatype , op ) \
4207+ CONDBR_SP (LOCAL_VAR (ip [1 ], datatype ) op LOCAL_VAR (ip [2 ], datatype ))
4208+
4209+ MINT_IN_CASE (MINT_BEQ_I4_SP ) BRELOP_SP (gint32 , == ); MINT_IN_BREAK ;
4210+ MINT_IN_CASE (MINT_BEQ_I8_SP ) BRELOP_SP (gint64 , == ); MINT_IN_BREAK ;
4211+ MINT_IN_CASE (MINT_BGE_I4_SP ) BRELOP_SP (gint32 , >=); MINT_IN_BREAK ;
4212+ MINT_IN_CASE (MINT_BGE_I8_SP ) BRELOP_SP (gint64 , >=); MINT_IN_BREAK ;
4213+ MINT_IN_CASE (MINT_BGT_I4_SP ) BRELOP_SP (gint32 , > ); MINT_IN_BREAK ;
4214+ MINT_IN_CASE (MINT_BGT_I8_SP ) BRELOP_SP (gint64 , > ); MINT_IN_BREAK ;
4215+ MINT_IN_CASE (MINT_BLT_I4_SP ) BRELOP_SP (gint32 , < ); MINT_IN_BREAK ;
4216+ MINT_IN_CASE (MINT_BLT_I8_SP ) BRELOP_SP (gint64 , < ); MINT_IN_BREAK ;
4217+ MINT_IN_CASE (MINT_BLE_I4_SP ) BRELOP_SP (gint32 , <=); MINT_IN_BREAK ;
4218+ MINT_IN_CASE (MINT_BLE_I8_SP ) BRELOP_SP (gint64 , <=); MINT_IN_BREAK ;
4219+
4220+ MINT_IN_CASE (MINT_BNE_UN_I4_SP ) BRELOP_SP (guint32 , != ); MINT_IN_BREAK ;
4221+ MINT_IN_CASE (MINT_BNE_UN_I8_SP ) BRELOP_SP (guint64 , != ); MINT_IN_BREAK ;
4222+ MINT_IN_CASE (MINT_BGE_UN_I4_SP ) BRELOP_SP (guint32 , >=); MINT_IN_BREAK ;
4223+ MINT_IN_CASE (MINT_BGE_UN_I8_SP ) BRELOP_SP (guint64 , >=); MINT_IN_BREAK ;
4224+ MINT_IN_CASE (MINT_BGT_UN_I4_SP ) BRELOP_SP (guint32 , > ); MINT_IN_BREAK ;
4225+ MINT_IN_CASE (MINT_BGT_UN_I8_SP ) BRELOP_SP (guint64 , > ); MINT_IN_BREAK ;
4226+ MINT_IN_CASE (MINT_BLE_UN_I4_SP ) BRELOP_SP (guint32 , <=); MINT_IN_BREAK ;
4227+ MINT_IN_CASE (MINT_BLE_UN_I8_SP ) BRELOP_SP (guint64 , <=); MINT_IN_BREAK ;
4228+ MINT_IN_CASE (MINT_BLT_UN_I4_SP ) BRELOP_SP (guint32 , < ); MINT_IN_BREAK ;
4229+ MINT_IN_CASE (MINT_BLT_UN_I8_SP ) BRELOP_SP (guint64 , < ); MINT_IN_BREAK ;
4230+
4231+ #define BRELOP_IMM_SP (datatype , op ) \
4232+ CONDBR_SP (LOCAL_VAR (ip [1 ], datatype ) op (datatype )(gint16 )ip [2 ])
4233+
4234+ MINT_IN_CASE (MINT_BEQ_I4_IMM_SP ) BRELOP_IMM_SP (gint32 , == ); MINT_IN_BREAK ;
4235+ MINT_IN_CASE (MINT_BEQ_I8_IMM_SP ) BRELOP_IMM_SP (gint64 , == ); MINT_IN_BREAK ;
4236+ MINT_IN_CASE (MINT_BGE_I4_IMM_SP ) BRELOP_IMM_SP (gint32 , >=); MINT_IN_BREAK ;
4237+ MINT_IN_CASE (MINT_BGE_I8_IMM_SP ) BRELOP_IMM_SP (gint64 , >=); MINT_IN_BREAK ;
4238+ MINT_IN_CASE (MINT_BGT_I4_IMM_SP ) BRELOP_IMM_SP (gint32 , > ); MINT_IN_BREAK ;
4239+ MINT_IN_CASE (MINT_BGT_I8_IMM_SP ) BRELOP_IMM_SP (gint64 , > ); MINT_IN_BREAK ;
4240+ MINT_IN_CASE (MINT_BLT_I4_IMM_SP ) BRELOP_IMM_SP (gint32 , < ); MINT_IN_BREAK ;
4241+ MINT_IN_CASE (MINT_BLT_I8_IMM_SP ) BRELOP_IMM_SP (gint64 , < ); MINT_IN_BREAK ;
4242+ MINT_IN_CASE (MINT_BLE_I4_IMM_SP ) BRELOP_IMM_SP (gint32 , <=); MINT_IN_BREAK ;
4243+ MINT_IN_CASE (MINT_BLE_I8_IMM_SP ) BRELOP_IMM_SP (gint64 , <=); MINT_IN_BREAK ;
4244+
4245+ MINT_IN_CASE (MINT_BNE_UN_I4_IMM_SP ) BRELOP_IMM_SP (guint32 , != ); MINT_IN_BREAK ;
4246+ MINT_IN_CASE (MINT_BNE_UN_I8_IMM_SP ) BRELOP_IMM_SP (guint64 , != ); MINT_IN_BREAK ;
4247+ MINT_IN_CASE (MINT_BGE_UN_I4_IMM_SP ) BRELOP_IMM_SP (guint32 , >=); MINT_IN_BREAK ;
4248+ MINT_IN_CASE (MINT_BGE_UN_I8_IMM_SP ) BRELOP_IMM_SP (guint64 , >=); MINT_IN_BREAK ;
4249+ MINT_IN_CASE (MINT_BGT_UN_I4_IMM_SP ) BRELOP_IMM_SP (guint32 , > ); MINT_IN_BREAK ;
4250+ MINT_IN_CASE (MINT_BGT_UN_I8_IMM_SP ) BRELOP_IMM_SP (guint64 , > ); MINT_IN_BREAK ;
4251+ MINT_IN_CASE (MINT_BLE_UN_I4_IMM_SP ) BRELOP_IMM_SP (guint32 , <=); MINT_IN_BREAK ;
4252+ MINT_IN_CASE (MINT_BLE_UN_I8_IMM_SP ) BRELOP_IMM_SP (guint64 , <=); MINT_IN_BREAK ;
4253+ MINT_IN_CASE (MINT_BLT_UN_I4_IMM_SP ) BRELOP_IMM_SP (guint32 , < ); MINT_IN_BREAK ;
4254+ MINT_IN_CASE (MINT_BLT_UN_I8_IMM_SP ) BRELOP_IMM_SP (guint64 , < ); MINT_IN_BREAK ;
4255+
41674256 MINT_IN_CASE (MINT_SWITCH ) {
41684257 guint32 val = LOCAL_VAR (ip [1 ], guint32 );
41694258 guint32 n = READ32 (ip + 2 );
@@ -5117,20 +5206,8 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
51175206 THROW_EX (ex , ip );
51185207 MINT_IN_BREAK ;
51195208 }
5120- MINT_IN_CASE (MINT_CHECKPOINT )
5121- /* Do synchronous checking of abort requests */
5122- EXCEPTION_CHECKPOINT ;
5123- ++ ip ;
5124- MINT_IN_BREAK ;
51255209 MINT_IN_CASE (MINT_SAFEPOINT )
5126- /* Do synchronous checking of abort requests */
5127- EXCEPTION_CHECKPOINT ;
5128- if (G_UNLIKELY (mono_polling_required )) {
5129- context_set_safepoint_frame (context , frame );
5130- /* Poll safepoint */
5131- mono_threads_safepoint ();
5132- context_clear_safepoint_frame (context );
5133- }
5210+ SAFEPOINT ;
51345211 ++ ip ;
51355212 MINT_IN_BREAK ;
51365213 MINT_IN_CASE (MINT_LDFLDA_UNSAFE ) {
@@ -5153,35 +5230,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
51535230 MINT_IN_BREAK ;
51545231 }
51555232
5156- // FIXME squash to load directly field type, LDFLD_VT is just a LDLOC
5157- #define LDFLD_VT_UNALIGNED (datatype , fieldtype , unaligned ) do { \
5158- if (unaligned ) \
5159- memcpy (locals + ip [1 ], (char * )locals + ip [2 ] + ip [3 ], sizeof (fieldtype )); \
5160- else \
5161- LOCAL_VAR (ip [1 ], datatype ) = LOCAL_VAR (ip [2 ] + ip [3 ], fieldtype ); \
5162- ip + = 4 ; \
5163- } while (0 )
5164-
5165- #define LDFLD_VT (datatype , fieldtype ) LDFLD_VT_UNALIGNED (datatype , fieldtype , FALSE )
5166-
5167- MINT_IN_CASE (MINT_LDFLD_VT_I1 ) LDFLD_VT (gint32 , gint8 ); MINT_IN_BREAK ;
5168- MINT_IN_CASE (MINT_LDFLD_VT_U1 ) LDFLD_VT (gint32 , guint8 ); MINT_IN_BREAK ;
5169- MINT_IN_CASE (MINT_LDFLD_VT_I2 ) LDFLD_VT (gint32 , gint16 ); MINT_IN_BREAK ;
5170- MINT_IN_CASE (MINT_LDFLD_VT_U2 ) LDFLD_VT (gint32 , guint16 ); MINT_IN_BREAK ;
5171- MINT_IN_CASE (MINT_LDFLD_VT_I4 ) LDFLD_VT (gint32 , gint32 ); MINT_IN_BREAK ;
5172- MINT_IN_CASE (MINT_LDFLD_VT_I8 ) LDFLD_VT (gint64 , gint64 ); MINT_IN_BREAK ;
5173- MINT_IN_CASE (MINT_LDFLD_VT_R4 ) LDFLD_VT (float , float ); MINT_IN_BREAK ;
5174- MINT_IN_CASE (MINT_LDFLD_VT_R8 ) LDFLD_VT (double , double ); MINT_IN_BREAK ;
5175- MINT_IN_CASE (MINT_LDFLD_VT_O ) LDFLD_VT (gpointer , gpointer ); MINT_IN_BREAK ;
5176- MINT_IN_CASE (MINT_LDFLD_VT_I8_UNALIGNED ) LDFLD_VT_UNALIGNED (gint64 , gint64 , TRUE ); MINT_IN_BREAK ;
5177- MINT_IN_CASE (MINT_LDFLD_VT_R8_UNALIGNED ) LDFLD_VT_UNALIGNED (double , double , TRUE ); MINT_IN_BREAK ;
5178-
5179- MINT_IN_CASE (MINT_LDFLD_VT_VT ) {
5180- memmove (locals + ip [1 ], locals + ip [2 ] + ip [3 ], ip [4 ]);
5181- ip + = 5 ;
5182- MINT_IN_BREAK ;
5183- }
5184-
51855233#define LDFLD_UNALIGNED (datatype , fieldtype , unaligned ) do { \
51865234 MonoObject * o = LOCAL_VAR (ip [2 ], MonoObject * ); \
51875235 NULL_CHECK (o ); \
@@ -5269,9 +5317,10 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
52695317 MINT_IN_BREAK ;
52705318 }
52715319
5272- MINT_IN_CASE (MINT_LDSSFLDA ) {
5273- guint32 offset = READ32 (ip + 2 );
5274- LOCAL_VAR (ip [1 ], gpointer ) = mono_get_special_static_data (offset );
5320+ MINT_IN_CASE (MINT_LDTSFLDA ) {
5321+ MonoInternalThread * thread = mono_thread_internal_current ();
5322+ guint32 offset = READ32 (ip + 2 );
5323+ LOCAL_VAR (ip [1 ], gpointer ) = ((char * )thread - > static_data [offset & 0x3f ]) + (offset >> 6 );
52755324 ip + = 4 ;
52765325 MINT_IN_BREAK ;
52775326 }
@@ -5306,38 +5355,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
53065355 MINT_IN_BREAK ;
53075356 }
53085357
5309- #define LDTSFLD (datatype , fieldtype ) { \
5310- MonoInternalThread * thread = mono_thread_internal_current (); \
5311- guint32 offset = READ32 (ip + 2 ); \
5312- gpointer addr = ((char * )thread - > static_data [offset & 0x3f ]) + (offset >> 6 ); \
5313- LOCAL_VAR (ip [1 ], datatype ) = * (fieldtype * )addr ; \
5314- ip + = 4 ; \
5315- }
5316- MINT_IN_CASE (MINT_LDTSFLD_I1 ) LDTSFLD (gint32 , gint8 ); MINT_IN_BREAK ;
5317- MINT_IN_CASE (MINT_LDTSFLD_U1 ) LDTSFLD (gint32 , guint8 ); MINT_IN_BREAK ;
5318- MINT_IN_CASE (MINT_LDTSFLD_I2 ) LDTSFLD (gint32 , gint16 ); MINT_IN_BREAK ;
5319- MINT_IN_CASE (MINT_LDTSFLD_U2 ) LDTSFLD (gint32 , guint16 ); MINT_IN_BREAK ;
5320- MINT_IN_CASE (MINT_LDTSFLD_I4 ) LDTSFLD (gint32 , gint32 ); MINT_IN_BREAK ;
5321- MINT_IN_CASE (MINT_LDTSFLD_I8 ) LDTSFLD (gint64 , gint64 ); MINT_IN_BREAK ;
5322- MINT_IN_CASE (MINT_LDTSFLD_R4 ) LDTSFLD (float , float ); MINT_IN_BREAK ;
5323- MINT_IN_CASE (MINT_LDTSFLD_R8 ) LDTSFLD (double , double ); MINT_IN_BREAK ;
5324- MINT_IN_CASE (MINT_LDTSFLD_O ) LDTSFLD (gpointer , gpointer ); MINT_IN_BREAK ;
5325-
5326- MINT_IN_CASE (MINT_LDSSFLD ) {
5327- guint32 offset = READ32 (ip + 3 );
5328- gpointer addr = mono_get_special_static_data (offset );
5329- MonoClassField * field = (MonoClassField * )frame - > imethod - > data_items [ip [2 ]];
5330- stackval_from_data (field - > type , (stackval * )(locals + ip [1 ]), addr , FALSE );
5331- ip + = 5 ;
5332- MINT_IN_BREAK ;
5333- }
5334- MINT_IN_CASE (MINT_LDSSFLD_VT ) {
5335- guint32 offset = READ32 (ip + 2 );
5336- gpointer addr = mono_get_special_static_data (offset );
5337- memcpy (locals + ip [1 ], addr , ip [4 ]);
5338- ip + = 5 ;
5339- MINT_IN_BREAK ;
5340- }
53415358#define STSFLD (datatype , fieldtype ) { \
53425359 MonoVTable * vtable = (MonoVTable * ) frame - > imethod - > data_items [ip [2 ]]; \
53435360 INIT_VTABLE (vtable ); \
@@ -5364,40 +5381,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
53645381 MINT_IN_BREAK ;
53655382 }
53665383
5367- #define STTSFLD (datatype , fieldtype ) { \
5368- MonoInternalThread * thread = mono_thread_internal_current (); \
5369- guint32 offset = READ32 (ip + 2 ); \
5370- gpointer addr = ((char * )thread - > static_data [offset & 0x3f ]) + (offset >> 6 ); \
5371- * (fieldtype * )addr = LOCAL_VAR (ip [1 ], datatype ); \
5372- ip + = 4 ; \
5373- }
5374-
5375- MINT_IN_CASE (MINT_STTSFLD_I1 ) STTSFLD (gint32 , gint8 ); MINT_IN_BREAK ;
5376- MINT_IN_CASE (MINT_STTSFLD_U1 ) STTSFLD (gint32 , guint8 ); MINT_IN_BREAK ;
5377- MINT_IN_CASE (MINT_STTSFLD_I2 ) STTSFLD (gint32 , gint16 ); MINT_IN_BREAK ;
5378- MINT_IN_CASE (MINT_STTSFLD_U2 ) STTSFLD (gint32 , guint16 ); MINT_IN_BREAK ;
5379- MINT_IN_CASE (MINT_STTSFLD_I4 ) STTSFLD (gint32 , gint32 ); MINT_IN_BREAK ;
5380- MINT_IN_CASE (MINT_STTSFLD_I8 ) STTSFLD (gint64 , gint64 ); MINT_IN_BREAK ;
5381- MINT_IN_CASE (MINT_STTSFLD_R4 ) STTSFLD (float , float ); MINT_IN_BREAK ;
5382- MINT_IN_CASE (MINT_STTSFLD_R8 ) STTSFLD (double , double ); MINT_IN_BREAK ;
5383- MINT_IN_CASE (MINT_STTSFLD_O ) STTSFLD (gpointer , gpointer ); MINT_IN_BREAK ;
5384-
5385- MINT_IN_CASE (MINT_STSSFLD ) {
5386- guint32 offset = READ32 (ip + 3 );
5387- gpointer addr = mono_get_special_static_data (offset );
5388- MonoClassField * field = (MonoClassField * )frame - > imethod - > data_items [ip [2 ]];
5389- stackval_to_data (field - > type , (stackval * )(locals + ip [1 ]), addr , FALSE );
5390- ip + = 5 ;
5391- MINT_IN_BREAK ;
5392- }
5393- MINT_IN_CASE (MINT_STSSFLD_VT ) {
5394- guint32 offset = READ32 (ip + 2 );
5395- gpointer addr = mono_get_special_static_data (offset );
5396- memcpy (addr , locals + ip [1 ], ip [4 ]);
5397- ip + = 5 ;
5398- MINT_IN_BREAK ;
5399- }
5400-
54015384 MINT_IN_CASE (MINT_STOBJ_VT ) {
54025385 MonoClass * c = (MonoClass * )frame - > imethod - > data_items [ip [3 ]];
54035386 mono_value_copy_internal (LOCAL_VAR (ip [1 ], gpointer ), locals + ip [2 ], c );
@@ -6211,9 +6194,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
62116194
62126195 gboolean const short_offset = opcode == MINT_LEAVE_S || opcode == MINT_LEAVE_S_CHECK ;
62136196 ip + = short_offset ? (gint16 )* (ip + 1 ) : (gint32 )READ32 (ip + 1 );
6214- // Check for any abort requests, once all finally blocks were invoked
6215- if (!check )
6216- EXCEPTION_CHECKPOINT ;
62176197 MINT_IN_BREAK ;
62186198 }
62196199 MINT_IN_CASE (MINT_ICALL_V_V )
@@ -6569,6 +6549,10 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
65696549 ip + = 3 ;
65706550 MINT_IN_BREAK ;
65716551
6552+ MINT_IN_CASE (MINT_MOV_OFF )
6553+ // This opcode is resolved to a normal MINT_MOV when emitting compacted instructions
6554+ g_assert_not_reached ();
6555+ MINT_IN_BREAK ;
65726556
65736557#define MOV (argtype1 ,argtype2 ) \
65746558 LOCAL_VAR (ip [1 ], argtype1 ) = LOCAL_VAR (ip [2 ], argtype2 ); \
0 commit comments