@@ -1050,6 +1050,22 @@ interp_throw (ThreadContext *context, MonoException *ex, InterpFrame *frame, con
1050
1050
} \
1051
1051
} while (0)
1052
1052
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
+
1053
1069
static MonoObject *
1054
1070
ves_array_create (MonoClass * klass , int param_count , stackval * values , MonoError * error )
1055
1071
{
@@ -4164,6 +4180,79 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
4164
4180
CONDBR (mono_isunordered (d1 , d2 ) || d1 < d2 )
4165
4181
MINT_IN_BREAK ;
4166
4182
}
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
+
4167
4256
MINT_IN_CASE (MINT_SWITCH ) {
4168
4257
guint32 val = LOCAL_VAR (ip [1 ], guint32 );
4169
4258
guint32 n = READ32 (ip + 2 );
@@ -5117,20 +5206,8 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
5117
5206
THROW_EX (ex , ip );
5118
5207
MINT_IN_BREAK ;
5119
5208
}
5120
- MINT_IN_CASE (MINT_CHECKPOINT )
5121
- /* Do synchronous checking of abort requests */
5122
- EXCEPTION_CHECKPOINT ;
5123
- ++ ip ;
5124
- MINT_IN_BREAK ;
5125
5209
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 ;
5134
5211
++ ip ;
5135
5212
MINT_IN_BREAK ;
5136
5213
MINT_IN_CASE (MINT_LDFLDA_UNSAFE ) {
@@ -5153,35 +5230,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
5153
5230
MINT_IN_BREAK ;
5154
5231
}
5155
5232
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
-
5185
5233
#define LDFLD_UNALIGNED (datatype , fieldtype , unaligned ) do { \
5186
5234
MonoObject * o = LOCAL_VAR (ip [2 ], MonoObject * ); \
5187
5235
NULL_CHECK (o ); \
@@ -5269,9 +5317,10 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
5269
5317
MINT_IN_BREAK ;
5270
5318
}
5271
5319
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 );
5275
5324
ip + = 4 ;
5276
5325
MINT_IN_BREAK ;
5277
5326
}
@@ -5306,38 +5355,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
5306
5355
MINT_IN_BREAK ;
5307
5356
}
5308
5357
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
- }
5341
5358
#define STSFLD (datatype , fieldtype ) { \
5342
5359
MonoVTable * vtable = (MonoVTable * ) frame - > imethod - > data_items [ip [2 ]]; \
5343
5360
INIT_VTABLE (vtable ); \
@@ -5364,40 +5381,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
5364
5381
MINT_IN_BREAK ;
5365
5382
}
5366
5383
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
-
5401
5384
MINT_IN_CASE (MINT_STOBJ_VT ) {
5402
5385
MonoClass * c = (MonoClass * )frame - > imethod - > data_items [ip [3 ]];
5403
5386
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
6211
6194
6212
6195
gboolean const short_offset = opcode == MINT_LEAVE_S || opcode == MINT_LEAVE_S_CHECK ;
6213
6196
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 ;
6217
6197
MINT_IN_BREAK ;
6218
6198
}
6219
6199
MINT_IN_CASE (MINT_ICALL_V_V )
@@ -6569,6 +6549,10 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs
6569
6549
ip + = 3 ;
6570
6550
MINT_IN_BREAK ;
6571
6551
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 ;
6572
6556
6573
6557
#define MOV (argtype1 ,argtype2 ) \
6574
6558
LOCAL_VAR (ip [1 ], argtype1 ) = LOCAL_VAR (ip [2 ], argtype2 ); \
0 commit comments