Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[mono] generic wrapper methods for unsafe accessors#101732

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
lambdageek merged 31 commits intodotnet:mainfromlambdageek:hack-generic-wrappers
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
31 commits
Select commitHold shift + click to select a range
81285fb
WIP HACK: always AOT wrappers, even for generics, not the actual acce…
lambdageekApr 25, 2024
3d59833
cleanup
lambdageekApr 29, 2024
fbd3b89
checkpoint generic wrapper methods
lambdageekApr 30, 2024
34381f7
fix msvc build
lambdageekApr 30, 2024
ecaff9e
hack
lambdageekApr 30, 2024
06be3b4
fix build
lambdageekMay 1, 2024
430f822
clean WIP printfs
lambdageekMay 1, 2024
5789ab7
use generic method owner caches
lambdageekMay 1, 2024
374c1e7
lookup unsafe accessor wrapper instances in aot-runtime
lambdageekMay 1, 2024
db8cbad
cleanup marshaling - dont' use ctx as a flag
lambdageekMay 1, 2024
f252a47
handle some generic field accessors
lambdageekMay 2, 2024
e424b64
issues.targets: enable some unsafe accessor AOT tests
lambdageekMay 2, 2024
03c72f7
WIP: looks like methods are working too?
lambdageekMay 2, 2024
6fcefc6
[metadata] add ability to inflate wrapper data
lambdageekMay 6, 2024
ccbd0ba
[marshal] refactor unsafe accessor; opt into inflate_wrapper_data
lambdageekMay 6, 2024
0c824fc
Merge remote-tracking branch 'origin/main' into hack-generic-wrappers
lambdageekMay 6, 2024
56516b2
comment out printfs
lambdageekMay 6, 2024
769ae55
inflate MonoMethod wrapper data; impl ctor generic unsafe accessors
lambdageekMay 6, 2024
9688f2b
fix windows build
lambdageekMay 6, 2024
70aaa2e
[aot] handle case of partial generic sharing for unsafe accessor
lambdageekMay 7, 2024
e814387
[aot] for unsafe accessor wrappers with no name, record a length 0
lambdageekMay 7, 2024
03208db
[aot-runtime] try to fix gsharedvt lookup
lambdageekMay 8, 2024
c244dd2
better comments; remove fied FIXMEs
lambdageekMay 9, 2024
2ff358b
update HelloWorld sample to support either normal AOT or FullAOT
lambdageekMay 9, 2024
25f9e99
revert HelloWorld sample code changes
lambdageekMay 9, 2024
0374f2b
rename helper methods
lambdageekMay 9, 2024
9786200
apply suggestions from code review
lambdageekMay 10, 2024
ceb5345
DRY. compute inflate_generic_data in one place
lambdageekMay 13, 2024
342fe1d
Just do one loop for inflating generic wrapper data
lambdageekMay 13, 2024
a667f53
better comments
lambdageekMay 13, 2024
0bf0f61
DRY. move common AOT code to mini.c
lambdageekMay 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
[metadata] add ability to inflate wrapper data
When we create generic wrappers (or wrappers in a generic class),if the wrapper data needs to refer to a field, method, or parametertype of the definition, that data might need to be inflated if thecontaining class is inflated (or the generic wrapper method isinflated).Add a new function to opt into inflation:```c    get_marshal_cb ()->mb_inflate_wrapper_data (mb);```Add a new function to be called after mono_mb_emit_op (or any othercall that calls mono_mb_add_data):```cmono_mb_emit_op (mb, CEE_LDFLDA, field);        mono_mb_set_wrapper_data_kind (mb, MONO_MB_ILGEN_WRAPPER_DATA_FIELD);```Note: mono_mb_set_wrapper_data_kind asserts if you haven't called mb_inflate_wrapper_data.TODO: add more wrapper data kinds for MonoMethod* and MonoClass* etc
  • Loading branch information
@lambdageek
lambdageek committedMay 6, 2024
commit6fcefc69f5920d8e82514d7a74fc30837b5810ef
1 change: 1 addition & 0 deletionssrc/mono/mono/metadata/class-internals.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -96,6 +96,7 @@ struct _MonoMethodWrapper {
MonoMethodHeader *header;
MonoMemoryManager *mem_manager;
void *method_data;
unsigned int inflate_wrapper_data : 1; /* method_data[MONO_MB_ILGEN_INFLATE_WRAPPER_INFO_IDX] is an MonoMethodBuilderInflateWrapperData array */
};

struct _MonoDynamicMethod {
Expand Down
12 changes: 12 additions & 0 deletionssrc/mono/mono/metadata/class.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -41,6 +41,7 @@
#include <mono/metadata/gc-internals.h>
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/metadata-update.h>
#include <mono/metadata/method-builder-ilgen.h>
#include <mono/utils/mono-string.h>
#include <mono/utils/mono-error-internals.h>
#include <mono/utils/mono-logger-internals.h>
Expand DownExpand Up@@ -1263,6 +1264,17 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k

resw->method_data = (void **)g_malloc (sizeof (gpointer) * (len + 1));
memcpy (resw->method_data, mw->method_data, sizeof (gpointer) * (len + 1));
if (mw->inflate_wrapper_data) {
mono_mb_inflate_generic_wrapper_data (context, (gpointer*)resw->method_data, error);
if (!is_ok (error)) {
g_free (resw->method_data);
goto fail;
}
// we can't set inflate_wrapper_data to 0 on the result, it's possible it
// will need to be inflated again (for example in the method_inst ==
// generic_container->context.method_inst case, below)
resw->inflate_wrapper_data = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Nit: Consistency between1 andTRUE.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

MonoMethodWrapper:inflate_wrapper_data is a bitfield, so I use1

MonoMethodBuilder:inflate_wrapper_data is a gboolean, so I useTRUE

kotlarmilos reacted with thumbs up emoji
}
}

if (iresult->context.method_inst) {
Expand Down
11 changes: 11 additions & 0 deletionssrc/mono/mono/metadata/marshal-lightweight.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2136,6 +2136,16 @@ mb_skip_visibility_ilgen (MonoMethodBuilder *mb)
mb->skip_visibility = 1;
}

static void
mb_inflate_wrapper_data_ilgen (MonoMethodBuilder *mb)
{
g_assert (!mb->dynamic); // dynamic methods with inflated data not implemented yet - needs at least mono_free_method changes, probably more
mb->inflate_wrapper_data = TRUE;
int idx = mono_mb_add_data (mb, NULL);
// note: match index used in create_method_ilgen
g_assertf (idx == MONO_MB_ILGEN_INFLATE_WRAPPER_INFO_IDX, "mb_inflate_wrapper_data called after data already added");
}

static void
emit_synchronized_wrapper_ilgen (MonoMethodBuilder *mb, MonoMethod *method, MonoGenericContext *ctx, MonoGenericContainer *container, MonoMethod *enter_method, MonoMethod *exit_method, MonoMethod *gettypefromhandle_method)
{
Expand DownExpand Up@@ -3467,6 +3477,7 @@ mono_marshal_lightweight_init (void)
cb.emit_return = emit_return_ilgen;
cb.emit_vtfixup_ftnptr = emit_vtfixup_ftnptr_ilgen;
cb.mb_skip_visibility = mb_skip_visibility_ilgen;
cb.mb_inflate_wrapper_data = mb_inflate_wrapper_data_ilgen;
cb.mb_emit_exception = mb_emit_exception_ilgen;
cb.mb_emit_exception_for_error = mb_emit_exception_for_error_ilgen;
cb.mb_emit_byte = mb_emit_byte_ilgen;
Expand Down
1 change: 1 addition & 0 deletionssrc/mono/mono/metadata/marshal.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -351,6 +351,7 @@ typedef struct {
void (*emit_return) (MonoMethodBuilder *mb);
void (*emit_vtfixup_ftnptr) (MonoMethodBuilder *mb, MonoMethod *method, int param_count, guint16 type);
void (*mb_skip_visibility) (MonoMethodBuilder *mb);
void (*mb_inflate_wrapper_data) (MonoMethodBuilder *mb);
void (*mb_emit_exception) (MonoMethodBuilder *mb, const char *exc_nspace, const char *exc_name, const char *msg);
void (*mb_emit_exception_for_error) (MonoMethodBuilder *mb, const MonoError *emitted_error);
void (*mb_emit_byte) (MonoMethodBuilder *mb, guint8 op);
Expand Down
19 changes: 19 additions & 0 deletionssrc/mono/mono/metadata/method-builder-ilgen-internals.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,25 @@ struct _MonoMethodBuilder {
const gchar **param_names;
MonoBitSet *volatile_args;
MonoBitSet *volatile_locals;
gboolean inflate_wrapper_data;
GList *wrapper_data_inflate_info;
};

typedef struct MonoMethodBuilderInflateWrapperData
{
uint16_t idx;
uint16_t kind; // MonoILGenWrapperDataKind
} MonoMethodBuilderInflateWrapperData;

enum MonoILGenWrapperDataKind
{
MONO_MB_ILGEN_WRAPPER_DATA_NONE = 0,
MONO_MB_ILGEN_WRAPPER_DATA_FIELD,
};

// index in MonoMethodWrapper:wrapper_data where the inflate info will be stored
// notes:
// - idx 1 is the wrapper info (see mono_method_get_wrapper_info)
#define MONO_MB_ILGEN_INFLATE_WRAPPER_INFO_IDX 2

#endif
105 changes: 100 additions & 5 deletionssrc/mono/mono/metadata/method-builder-ilgen.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,7 +52,7 @@ new_base_ilgen (MonoClass *klass, MonoWrapperType type, gboolean dynamic)
mb->init_locals = TRUE;
mb->dynamic = dynamic;

/* placeholder for the wrapper always at index 1 */
/* placeholder for the wrapper always at index 1, see mono_marshal_set_wrapper_info */
mono_mb_add_data (mb, NULL);

return mb;
Expand All@@ -61,9 +61,15 @@ new_base_ilgen (MonoClass *klass, MonoWrapperType type, gboolean dynamic)
static void
free_ilgen (MonoMethodBuilder *mb)
{
GList *l;
if (mb->wrapper_data_inflate_info) {
for (GList *p = mb->wrapper_data_inflate_info; p && p->data; p = p->next) {
g_free (p->data);
}
g_list_free (mb->wrapper_data_inflate_info);
mb->wrapper_data_inflate_info = NULL;
}

for (l = mb->locals_list; l; l = l->next) {
for (GList *l = mb->locals_list; l; l = l->next) {
/* Allocated in mono_mb_add_local () */
g_free (l->data);
}
Expand DownExpand Up@@ -172,14 +178,44 @@ create_method_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *signature, int

i = g_list_length ((GList *)mw->method_data);
if (i) {
MonoMethodBuilderInflateWrapperData *inflate_data = NULL;
if (mb->inflate_wrapper_data) {
int count = g_list_length (mb->wrapper_data_inflate_info);
inflate_data = (MonoMethodBuilderInflateWrapperData *) mb_alloc0 (mb, sizeof(MonoMethodBuilderInflateWrapperData) * (count + 1));
int j = 0;
for (GList *p = mb->wrapper_data_inflate_info; p && p->data; p = p->next) {
inflate_data[j++] = *(MonoMethodBuilderInflateWrapperData*)p->data;
}
// trailing idx 0 element to mark the end
inflate_data[j].idx = 0;
inflate_data[j].kind = MONO_MB_ILGEN_WRAPPER_DATA_NONE;
mw->inflate_wrapper_data = 1;
}
GList *tmp;
void **data;
l = g_list_reverse ((GList *)mw->method_data);
data = (void **)mb_alloc0 (mb, sizeof (gpointer) * (i + 1));
int data_count = i + (inflate_data ? 2 : 1);
data = (void **)mb_alloc0 (mb, sizeof (gpointer) * data_count);
/* store the size in the first element */
data [0] = GUINT_TO_POINTER (i);
i = 1;
for (tmp = l; tmp; tmp = tmp->next) {

// manually peel off the first 1 or 2 iterations of the loop since they're special
tmp = l;
g_assert (tmp);
// wrapper info is in slot 1
g_assert (tmp->data == NULL);
data [i++] = NULL;
tmp = tmp->next;
// inflate data is in slot 2
if (inflate_data) {
g_assert (tmp);
g_assert (MONO_MB_ILGEN_INFLATE_WRAPPER_INFO_IDX == i);
g_assert (tmp->data == NULL);
data[i++] = inflate_data;
tmp = tmp->next;
}
for (;tmp; tmp = tmp->next) {
data [i++] = tmp->data;
}
g_list_free (l);
Expand DownExpand Up@@ -664,3 +700,62 @@ mono_mb_set_param_names (MonoMethodBuilder *mb, const char **param_names)
{
mb->param_names = param_names;
}

void
mono_mb_set_wrapper_data_kind (MonoMethodBuilder *mb, uint16_t wrapper_data_kind)
{
g_assert (mb->inflate_wrapper_data);
MonoMethodWrapper *mw = (MonoMethodWrapper*)mb->method;
// index of the data added by most recent mono_mb_add_data
int idx = g_list_length((GList *)mw->method_data);
g_assert (idx > 0 && idx <= UINT16_MAX);

MonoMethodBuilderInflateWrapperData *info = g_new (MonoMethodBuilderInflateWrapperData, 1);
info->idx = (uint16_t)idx;
info->kind = wrapper_data_kind;
mb->wrapper_data_inflate_info = g_list_prepend (mb->wrapper_data_inflate_info, info);
}

gboolean
mono_mb_inflate_generic_wrapper_data (MonoGenericContext *context, gpointer *method_data, MonoError *error)
{
MonoMethodBuilderInflateWrapperData* inflate_info = (MonoMethodBuilderInflateWrapperData*)method_data[MONO_MB_ILGEN_INFLATE_WRAPPER_INFO_IDX];
MonoMethodBuilderInflateWrapperData* p = inflate_info;
int count = 0;
while (p->idx != 0) {p++; count++;}

for (int i = 0; i < count; i++) {
int idx = inflate_info[i].idx;
uint16_t kind = inflate_info[i].kind;
gpointer *pdata = &method_data[idx];
switch (kind) {
case MONO_MB_ILGEN_WRAPPER_DATA_NONE:
continue;
case MONO_MB_ILGEN_WRAPPER_DATA_FIELD: {
MonoClassField *field = (MonoClassField*)*pdata;
MonoType *inflated_type = mono_class_inflate_generic_type_checked (m_class_get_byval_arg (m_field_get_parent (field)), context, error);
if (!is_ok (error))
return FALSE;

MonoClass *inflated_class = mono_class_from_mono_type_internal (inflated_type);
// TODO: EnC metadata-update
g_assert (!m_field_is_from_update (field));
int i = GPTRDIFF_TO_INT (field - m_class_get_fields (m_field_get_parent (field)));
gpointer dummy = NULL;

mono_metadata_free_type (inflated_type);

mono_class_get_fields_internal (inflated_class, &dummy);
g_assert (m_class_get_fields (inflated_class));

MonoClassField *inflated_field = &m_class_get_fields (inflated_class) [i];

*pdata = inflated_field;
break;
}
default:
g_assert_not_reached();
}
}
return TRUE;
}
7 changes: 7 additions & 0 deletionssrc/mono/mono/metadata/method-builder-ilgen.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -139,4 +139,11 @@ mono_mb_set_param_names (MonoMethodBuilder *mb, const char **param_names);
char*
mono_mb_strdup (MonoMethodBuilder *mb, const char *s);

void
mono_mb_set_wrapper_data_kind (MonoMethodBuilder *mb, uint16_t wrapper_data_kind);

gboolean
mono_mb_inflate_generic_wrapper_data (MonoGenericContext *context, gpointer *method_data, MonoError *error);


#endif

[8]ページ先頭

©2009-2025 Movatter.jp