@@ -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
41644180CONDBR (mono_isunordered (d1 ,d2 )|| d1 < d2 )
41654181MINT_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+
41674256MINT_IN_CASE (MINT_SWITCH ) {
41684257guint32 val = LOCAL_VAR (ip [1 ],guint32 );
41694258guint32 n = READ32 (ip + 2 );
@@ -5117,20 +5206,8 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
51175206THROW_EX (ex ,ip );
51185207MINT_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 ;
51255209MINT_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 ;
51355212MINT_IN_BREAK ;
51365213MINT_IN_CASE (MINT_LDFLDA_UNSAFE ) {
@@ -5153,35 +5230,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
51535230MINT_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 { \
51865234MonoObject * o = LOCAL_VAR (ip [2 ],MonoObject * ); \
51875235NULL_CHECK (o ); \
@@ -5269,9 +5317,10 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
52695317MINT_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 );
52755324ip + = 4 ;
52765325MINT_IN_BREAK ;
52775326}
@@ -5306,38 +5355,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
53065355MINT_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 ) { \
53425359MonoVTable * vtable = (MonoVTable * )frame - > imethod - > data_items [ip [2 ]]; \
53435360INIT_VTABLE (vtable ); \
@@ -5364,40 +5381,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
53645381MINT_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-
54015384MINT_IN_CASE (MINT_STOBJ_VT ) {
54025385MonoClass * c = (MonoClass * )frame - > imethod - > data_items [ip [3 ]];
54035386mono_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
62126195gboolean const short_offset = opcode == MINT_LEAVE_S || opcode == MINT_LEAVE_S_CHECK ;
62136196ip + = 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 ;
62176197MINT_IN_BREAK ;
62186198}
62196199MINT_IN_CASE (MINT_ICALL_V_V )
@@ -6569,6 +6549,10 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
65696549ip + = 3 ;
65706550MINT_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 ) \
65746558LOCAL_VAR (ip [1 ],argtype1 )= LOCAL_VAR (ip [2 ],argtype2 ); \