From a6962a708a1ec5b424a7eff3d8a2e0dcc4403ce3 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Thu, 8 Dec 2022 17:31:10 +0200 Subject: [PATCH] [mono][interp] Add intrinsic for string allocation (#79392) * [mono][metadata] Remove redundant use of coop handles mono_string_new_size_handle was making use of handles for no reason, while mono_string_new_size_checked was just ignoring the created handle. Make mono_string_new_size_checked fast again. * [mono][interp] Add intrinsic for string allocation --- src/mono/mono/metadata/gc-internals.h | 3 --- src/mono/mono/metadata/gc.c | 6 ------ src/mono/mono/metadata/object.c | 23 +++++++++++------------ src/mono/mono/mini/interp/interp.c | 8 ++++++++ src/mono/mono/mini/interp/mintops.def | 1 + src/mono/mono/mini/interp/transform.c | 3 +++ 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/mono/mono/metadata/gc-internals.h b/src/mono/mono/metadata/gc-internals.h index f7524104d92f0..b022b89c72ab1 100644 --- a/src/mono/mono/metadata/gc-internals.h +++ b/src/mono/mono/metadata/gc-internals.h @@ -154,9 +154,6 @@ mono_gc_alloc_handle_array (MonoVTable *vtable, gsize size, gsize max_length, gs MonoString* mono_gc_alloc_string (MonoVTable *vtable, size_t size, gint32 len); -MonoStringHandle -mono_gc_alloc_handle_string (MonoVTable *vtable, gsize size, gint32 len); - MonoObject* mono_gc_alloc_mature (MonoVTable *vtable, size_t size); diff --git a/src/mono/mono/metadata/gc.c b/src/mono/mono/metadata/gc.c index 9354641a63827..f5f74cfd5073c 100644 --- a/src/mono/mono/metadata/gc.c +++ b/src/mono/mono/metadata/gc.c @@ -1256,12 +1256,6 @@ mono_gc_alloc_handle_array (MonoVTable *vtable, gsize size, gsize max_length, gs return MONO_HANDLE_NEW (MonoArray, mono_gc_alloc_array (vtable, size, max_length, bounds_size)); } -MonoStringHandle -mono_gc_alloc_handle_string (MonoVTable *vtable, gsize size, gint32 len) -{ - return MONO_HANDLE_NEW (MonoString, mono_gc_alloc_string (vtable, size, len)); -} - MonoObjectHandle mono_gc_alloc_handle_mature (MonoVTable *vtable, gsize size) { diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index 752b913b1ada3..fef13f445d7ac 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -6142,10 +6142,16 @@ mono_string_new_size (MonoDomain *domain, gint32 len) MonoStringHandle mono_string_new_size_handle (gint32 len, MonoError *error) +{ + return MONO_HANDLE_NEW (MonoString, mono_string_new_size_checked (len, error)); +} + +MonoString* +mono_string_new_size_checked (gint32 len, MonoError *error) { MONO_REQ_GC_UNSAFE_MODE; - MonoStringHandle s; + MonoString *s; MonoVTable *vtable; size_t size; @@ -6154,30 +6160,23 @@ mono_string_new_size_handle (gint32 len, MonoError *error) /* check for overflow */ if (len < 0 || len > ((SIZE_MAX - G_STRUCT_OFFSET (MonoString, chars) - 8) / 2)) { mono_error_set_out_of_memory (error, "Could not allocate %i bytes", -1); - return NULL_HANDLE_STRING; + return NULL; } size = (G_STRUCT_OFFSET (MonoString, chars) + (((size_t)len + 1) * 2)); g_assert (size > 0); vtable = mono_class_vtable_checked (mono_defaults.string_class, error); - return_val_if_nok (error, NULL_HANDLE_STRING); + return_val_if_nok (error, NULL); - s = mono_gc_alloc_handle_string (vtable, size, len); + s = mono_gc_alloc_string (vtable, size, len); - if (G_UNLIKELY (MONO_HANDLE_IS_NULL (s))) + if (G_UNLIKELY (!s)) mono_error_set_out_of_memory (error, "Could not allocate %" G_GSIZE_FORMAT " bytes", size); return s; } -MonoString * -mono_string_new_size_checked (gint32 length, MonoError *error) -{ - HANDLE_FUNCTION_ENTER (); - HANDLE_FUNCTION_RETURN_OBJ (mono_string_new_size_handle (length, error)); -} - /** * mono_string_new_len: * \param text a pointer to an utf8 string diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index a4af2e6e1cfe6..22e9522de36cb 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -6185,6 +6185,14 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK; MINT_IN_BREAK; } + MINT_IN_CASE(MINT_NEWSTR) { + LOCAL_VAR (ip [1], MonoString*) = mono_string_new_size_checked (LOCAL_VAR (ip [2], gint32), error); + if (!is_ok (error)) { + THROW_EX (interp_error_convert_to_exception (frame, error, ip), ip); + } + ip += 3; + MINT_IN_BREAK; + } MINT_IN_CASE(MINT_LDLEN) { MonoObject *o = LOCAL_VAR (ip [2], MonoObject*); NULL_CHECK (o); diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index 7ad781d3d16eb..da0a71251a79d 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -360,6 +360,7 @@ OPDEF(MINT_ISINST_INTERFACE, "isinst.interface", 4, 1, 1, MintOpClassToken) OPDEF(MINT_CASTCLASS_COMMON, "castclass.common", 4, 1, 1, MintOpClassToken) OPDEF(MINT_ISINST_COMMON, "isinst.common", 4, 1, 1, MintOpClassToken) OPDEF(MINT_NEWARR, "newarr", 4, 1, 1, MintOpClassToken) +OPDEF(MINT_NEWSTR, "newstr", 3, 1, 1, MintOpNoArgs) OPDEF(MINT_BOX, "box", 4, 1, 1, MintOpShortInt) OPDEF(MINT_BOX_VT, "box.vt", 4, 1, 1, MintOpShortInt) OPDEF(MINT_BOX_PTR, "box.ptr", 4, 1, 1, MintOpShortInt) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 9d67dd0742a88..352cb643741af 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -1971,6 +1971,9 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas *op = MINT_GETCHR; else if (strcmp (tm, "get_Length") == 0) *op = MINT_STRLEN; + } else if (tm [0] == 'F') { + if (strcmp (tm, "FastAllocateString") == 0) + *op = MINT_NEWSTR; } } else if (mono_class_is_subclass_of_internal (target_method->klass, mono_defaults.array_class, FALSE)) { if (!strcmp (tm, "get_Rank")) {