@@ -1160,15 +1160,6 @@ interp_throw (ThreadContext *context, MonoException *ex, InterpFrame *frame, con
11601160 } \
11611161 } while (0)
11621162
1163- #define EXCEPTION_CHECKPOINT_IN_HELPER_FUNCTION \
1164- do { \
1165- if (mono_thread_interruption_request_flag && !mono_threads_is_critical_method (frame->imethod->method)) { \
1166- MonoException *exc = mono_thread_interruption_checkpoint (); \
1167- if (exc) \
1168- return exc; \
1169- } \
1170- } while (0)
1171-
11721163static MonoObject *
11731164ves_array_create (MonoDomain * domain , MonoClass * klass , int param_count , stackval * values , MonoError * error )
11741165{
@@ -3215,88 +3206,6 @@ mono_interp_leave (InterpFrame* child_frame)
32153206 return (MonoException * )tmp_sp .data .p ;
32163207}
32173208
3218- static MONO_NEVER_INLINE MonoException *
3219- mono_interp_newobj (
3220- // Parameters are sorted by name and parameter list is minimized
3221- // to reduce stack use in caller, on e.g. NT/AMD64 (up to 4 parameters
3222- // use no stack in caller).
3223- InterpFrame * child_frame ,
3224- ThreadContext * context ,
3225- MonoError * error ,
3226- guchar * vt_sp )
3227- {
3228- InterpFrame * const frame = child_frame -> parent ;
3229- InterpMethod * const imethod = frame -> imethod ;
3230- stackval * const sp = child_frame -> stack_args ;
3231-
3232- MonoObject * o = NULL ; // See the comment about GC safety.
3233- stackval valuetype_this ;
3234- stackval retval ;
3235-
3236- MonoClass * const newobj_class = child_frame -> imethod -> method -> klass ;
3237- /*if (profiling_classes) {
3238- guint count = GPOINTER_TO_UINT (g_hash_table_lookup (profiling_classes, newobj_class));
3239- count++;
3240- g_hash_table_insert (profiling_classes, newobj_class, GUINT_TO_POINTER (count));
3241- }*/
3242-
3243- /*
3244- * First arg is the object.
3245- */
3246- if (m_class_is_valuetype (newobj_class )) {
3247- MonoType * t = m_class_get_byval_arg (newobj_class );
3248- memset (& valuetype_this , 0 , sizeof (stackval ));
3249- if (!m_class_is_enumtype (newobj_class ) && (t -> type == MONO_TYPE_VALUETYPE || (t -> type == MONO_TYPE_GENERICINST && mono_type_generic_inst_is_valuetype (t )))) {
3250- sp -> data .p = vt_sp ;
3251- valuetype_this .data .p = vt_sp ;
3252- } else {
3253- sp -> data .p = & valuetype_this ;
3254- }
3255- } else {
3256- if (newobj_class != mono_defaults .string_class ) {
3257- MonoVTable * vtable = mono_class_vtable_checked (imethod -> domain , newobj_class , error );
3258- if (!is_ok (error ) || !mono_runtime_class_init_full (vtable , error )) {
3259- MonoException * const exc = mono_error_convert_to_exception (error );
3260- g_assert (exc );
3261- return exc ;
3262- }
3263- ERROR_DECL (error );
3264- OBJREF (o ) = mono_object_new_checked (imethod -> domain , newobj_class , error );
3265- mono_error_cleanup (error ); // FIXME: do not swallow the error
3266- EXCEPTION_CHECKPOINT_IN_HELPER_FUNCTION ;
3267- sp -> data .o = o ;
3268- #ifndef DISABLE_REMOTING
3269- if (mono_object_is_transparent_proxy (o )) {
3270- MonoMethod * remoting_invoke_method = mono_marshal_get_remoting_invoke_with_check (child_frame -> imethod -> method , error );
3271- mono_error_assert_ok (error );
3272- child_frame -> imethod = mono_interp_get_imethod (imethod -> domain , remoting_invoke_method , error );
3273- mono_error_assert_ok (error );
3274- }
3275- #endif
3276- } else {
3277- sp -> data .p = NULL ;
3278- child_frame -> retval = & retval ;
3279- }
3280- }
3281-
3282- interp_exec_method (child_frame , context , error );
3283-
3284- CHECK_RESUME_STATE (context );
3285-
3286- /*
3287- * a constructor returns void, but we need to return the object we created
3288- */
3289- if (m_class_is_valuetype (newobj_class ) && !m_class_is_enumtype (newobj_class )) {
3290- * sp = valuetype_this ;
3291- } else if (newobj_class == mono_defaults .string_class ) {
3292- * sp = retval ;
3293- } else {
3294- sp -> data .o = o ;
3295- }
3296- resume :
3297- return NULL ;
3298- }
3299-
33003209static MONO_NEVER_INLINE void
33013210mono_interp_enum_hasflag (stackval * sp , MonoClass * klass )
33023211{
@@ -5087,9 +4996,8 @@ call:;
50874996
50884997 MINT_IN_CASE (MINT_NEWOBJ ) {
50894998 int dummy ;
5090- // This is split up to:
5091- // - conserve stack
5092- // - keep exception handling and resume mostly in the main function
4999+
5000+ // FIXME: Clean this up and make it not recursive.
50935001
50945002 frame -> ip = ip ;
50955003
@@ -5107,11 +5015,75 @@ call:;
51075015
51085016 child_frame -> stack_args = sp ;
51095017
5110- // FIXME remove recursion
5111- MonoException * const exc = mono_interp_newobj (child_frame , context , error , vt_sp );
5112- if (exc )
5113- THROW_EX (exc , ip );
5018+ MonoException * exc = NULL ;
5019+
5020+ InterpMethod * const imethod = frame -> imethod ;
5021+
5022+ MonoObject * o = NULL ; // See the comment about GC safety.
5023+ stackval valuetype_this ;
5024+ stackval retval ;
5025+
5026+ MonoClass * const newobj_class = child_frame -> imethod -> method -> klass ;
5027+ /*if (profiling_classes) {
5028+ guint count = GPOINTER_TO_UINT (g_hash_table_lookup (profiling_classes, newobj_class));
5029+ count++;
5030+ g_hash_table_insert (profiling_classes, newobj_class, GUINT_TO_POINTER (count));
5031+ }*/
5032+
5033+ /*
5034+ * First arg is the object.
5035+ */
5036+ if (m_class_is_valuetype (newobj_class )) {
5037+ MonoType * t = m_class_get_byval_arg (newobj_class );
5038+ memset (& valuetype_this , 0 , sizeof (stackval ));
5039+ if (!m_class_is_enumtype (newobj_class ) && (t -> type == MONO_TYPE_VALUETYPE || (t -> type == MONO_TYPE_GENERICINST && mono_type_generic_inst_is_valuetype (t )))) {
5040+ sp -> data .p = vt_sp ;
5041+ valuetype_this .data .p = vt_sp ;
5042+ } else {
5043+ sp -> data .p = & valuetype_this ;
5044+ }
5045+ } else {
5046+ if (newobj_class != mono_defaults .string_class ) {
5047+ MonoVTable * vtable = mono_class_vtable_checked (imethod -> domain , newobj_class , error );
5048+ if (!is_ok (error ) || !mono_runtime_class_init_full (vtable , error )) {
5049+ exc = mono_error_convert_to_exception (error );
5050+ g_assert (exc );
5051+ THROW_EX (exc , ip );
5052+ }
5053+ ERROR_DECL (error );
5054+ OBJREF (o ) = mono_object_new_checked (imethod -> domain , newobj_class , error );
5055+ mono_error_cleanup (error ); // FIXME: do not swallow the error
5056+ EXCEPTION_CHECKPOINT ;
5057+ sp -> data .o = o ;
5058+ #ifndef DISABLE_REMOTING
5059+ if (mono_object_is_transparent_proxy (o )) {
5060+ MonoMethod * remoting_invoke_method = mono_marshal_get_remoting_invoke_with_check (child_frame -> imethod -> method , error );
5061+ mono_error_assert_ok (error );
5062+ child_frame -> imethod = mono_interp_get_imethod (imethod -> domain , remoting_invoke_method , error );
5063+ mono_error_assert_ok (error );
5064+ }
5065+ #endif
5066+ } else {
5067+ sp -> data .p = NULL ;
5068+ child_frame -> retval = & retval ;
5069+ }
5070+ }
5071+
5072+ interp_exec_method (child_frame , context , error );
5073+
51145074 CHECK_RESUME_STATE (context );
5075+
5076+ /*
5077+ * a constructor returns void, but we need to return the object we created
5078+ */
5079+ if (m_class_is_valuetype (newobj_class ) && !m_class_is_enumtype (newobj_class )) {
5080+ * sp = valuetype_this ;
5081+ } else if (newobj_class == mono_defaults .string_class ) {
5082+ * sp = retval ;
5083+ } else {
5084+ sp -> data .o = o ;
5085+ }
5086+
51155087 ++ sp ;
51165088 MINT_IN_BREAK ;
51175089 }
0 commit comments