|
Lines 81-87
static guint32 last_error_tls_id;
Link Here
|
| 81 |
static guint32 load_type_info_tls_id; |
81 |
static guint32 load_type_info_tls_id; |
| 82 |
|
82 |
|
| 83 |
static void |
83 |
static void |
| 84 |
delegate_hash_table_add (MonoDelegate *d, MonoObject **target_loc); |
84 |
delegate_hash_table_add (MonoDelegate *d); |
| 85 |
|
85 |
|
| 86 |
static void |
86 |
static void |
| 87 |
emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object); |
87 |
emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object); |
|
Lines 313-319
mono_delegate_to_ftnptr (MonoDelegate *delegate)
Link Here
|
| 313 |
{ |
313 |
{ |
| 314 |
MonoMethod *method, *wrapper; |
314 |
MonoMethod *method, *wrapper; |
| 315 |
MonoClass *klass; |
315 |
MonoClass *klass; |
| 316 |
MonoObject **target_loc; |
|
|
| 317 |
|
316 |
|
| 318 |
if (!delegate) |
317 |
if (!delegate) |
| 319 |
return NULL; |
318 |
return NULL; |
|
Lines 338-357
mono_delegate_to_ftnptr (MonoDelegate *delegate)
Link Here
|
| 338 |
return ftnptr; |
337 |
return ftnptr; |
| 339 |
} |
338 |
} |
| 340 |
|
339 |
|
| 341 |
if (delegate->target) { |
340 |
wrapper = mono_marshal_get_managed_wrapper (method, klass, delegate->target); |
| 342 |
/* Produce a location which can be embedded in JITted code */ |
|
|
| 343 |
target_loc = mono_gc_alloc_fixed (sizeof (MonoObject*), NULL); |
| 344 |
*target_loc = delegate->target; |
| 345 |
} else { |
| 346 |
target_loc = NULL; |
| 347 |
} |
| 348 |
|
| 349 |
wrapper = mono_marshal_get_managed_wrapper (method, klass, target_loc); |
| 350 |
|
341 |
|
| 351 |
delegate->delegate_trampoline = mono_compile_method (wrapper); |
342 |
delegate->delegate_trampoline = mono_compile_method (wrapper); |
| 352 |
|
343 |
|
| 353 |
// Add the delegate to the delegate hash table |
344 |
// Add the delegate to the delegate hash table |
| 354 |
delegate_hash_table_add (delegate, target_loc); |
345 |
delegate_hash_table_add (delegate); |
| 355 |
|
346 |
|
| 356 |
/* when the object is collected, collect the dynamic method, too */ |
347 |
/* when the object is collected, collect the dynamic method, too */ |
| 357 |
mono_object_register_finalizer ((MonoObject*)delegate); |
348 |
mono_object_register_finalizer ((MonoObject*)delegate); |
|
Lines 365-372
mono_delegate_to_ftnptr (MonoDelegate *delegate)
Link Here
|
| 365 |
* object pointer itself, otherwise we use a GC handle. |
356 |
* object pointer itself, otherwise we use a GC handle. |
| 366 |
*/ |
357 |
*/ |
| 367 |
static GHashTable *delegate_hash_table; |
358 |
static GHashTable *delegate_hash_table; |
| 368 |
/* Contains root locations pointing to the this arguments of delegates */ |
|
|
| 369 |
static MonoGHashTable *delegate_target_locations; |
| 370 |
|
359 |
|
| 371 |
static GHashTable * |
360 |
static GHashTable * |
| 372 |
delegate_hash_table_new (void) { |
361 |
delegate_hash_table_new (void) { |
|
Lines 376-382
delegate_hash_table_new (void) {
Link Here
|
| 376 |
static void |
365 |
static void |
| 377 |
delegate_hash_table_remove (MonoDelegate *d) |
366 |
delegate_hash_table_remove (MonoDelegate *d) |
| 378 |
{ |
367 |
{ |
| 379 |
MonoObject **target_loc; |
|
|
| 380 |
#ifdef HAVE_MOVING_COLLECTOR |
368 |
#ifdef HAVE_MOVING_COLLECTOR |
| 381 |
guint32 gchandle; |
369 |
guint32 gchandle; |
| 382 |
#endif |
370 |
#endif |
|
Lines 387-409
delegate_hash_table_remove (MonoDelegate *d)
Link Here
|
| 387 |
gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, d->delegate_trampoline)); |
375 |
gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, d->delegate_trampoline)); |
| 388 |
#endif |
376 |
#endif |
| 389 |
g_hash_table_remove (delegate_hash_table, d->delegate_trampoline); |
377 |
g_hash_table_remove (delegate_hash_table, d->delegate_trampoline); |
| 390 |
if (delegate_target_locations) |
|
|
| 391 |
target_loc = mono_g_hash_table_lookup (delegate_target_locations, d->delegate_trampoline); |
| 392 |
else |
| 393 |
target_loc = NULL; |
| 394 |
if (target_loc) |
| 395 |
mono_g_hash_table_remove (delegate_target_locations, d->delegate_trampoline); |
| 396 |
mono_marshal_unlock (); |
378 |
mono_marshal_unlock (); |
| 397 |
if (target_loc) { |
|
|
| 398 |
mono_gc_free_fixed (target_loc); |
| 399 |
} |
| 400 |
#ifdef HAVE_MOVING_COLLECTOR |
379 |
#ifdef HAVE_MOVING_COLLECTOR |
| 401 |
mono_gchandle_free (gchandle); |
380 |
mono_gchandle_free (gchandle); |
| 402 |
#endif |
381 |
#endif |
| 403 |
} |
382 |
} |
| 404 |
|
383 |
|
| 405 |
static void |
384 |
static void |
| 406 |
delegate_hash_table_add (MonoDelegate *d, MonoObject **target_loc) |
385 |
delegate_hash_table_add (MonoDelegate *d) |
| 407 |
{ |
386 |
{ |
| 408 |
#ifdef HAVE_MOVING_COLLECTOR |
387 |
#ifdef HAVE_MOVING_COLLECTOR |
| 409 |
guint32 gchandle = mono_gchandle_new_weakref ((MonoObject*)d, FALSE); |
388 |
guint32 gchandle = mono_gchandle_new_weakref ((MonoObject*)d, FALSE); |
|
Lines 412-422
delegate_hash_table_add (MonoDelegate *d, MonoObject **target_loc)
Link Here
|
| 412 |
mono_marshal_lock (); |
391 |
mono_marshal_lock (); |
| 413 |
if (delegate_hash_table == NULL) |
392 |
if (delegate_hash_table == NULL) |
| 414 |
delegate_hash_table = delegate_hash_table_new (); |
393 |
delegate_hash_table = delegate_hash_table_new (); |
| 415 |
if (delegate_target_locations == NULL) { |
|
|
| 416 |
/* Has to be conservative as the values are not object references */ |
| 417 |
delegate_target_locations = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_CONSERVATIVE_GC); |
| 418 |
MONO_GC_REGISTER_ROOT (delegate_target_locations); |
| 419 |
} |
| 420 |
#ifdef HAVE_MOVING_COLLECTOR |
394 |
#ifdef HAVE_MOVING_COLLECTOR |
| 421 |
old_gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, d->delegate_trampoline)); |
395 |
old_gchandle = GPOINTER_TO_UINT (g_hash_table_lookup (delegate_hash_table, d->delegate_trampoline)); |
| 422 |
g_hash_table_insert (delegate_hash_table, d->delegate_trampoline, GUINT_TO_POINTER (gchandle)); |
396 |
g_hash_table_insert (delegate_hash_table, d->delegate_trampoline, GUINT_TO_POINTER (gchandle)); |
|
Lines 425-433
delegate_hash_table_add (MonoDelegate *d, MonoObject **target_loc)
Link Here
|
| 425 |
#else |
399 |
#else |
| 426 |
g_hash_table_insert (delegate_hash_table, d->delegate_trampoline, d); |
400 |
g_hash_table_insert (delegate_hash_table, d->delegate_trampoline, d); |
| 427 |
#endif |
401 |
#endif |
| 428 |
if (target_loc) |
|
|
| 429 |
/* This keeps target_loc alive for Boehm */ |
| 430 |
mono_g_hash_table_insert (delegate_target_locations, d->delegate_trampoline, target_loc); |
| 431 |
mono_marshal_unlock (); |
402 |
mono_marshal_unlock (); |
| 432 |
} |
403 |
} |
| 433 |
|
404 |
|
|
Lines 7578-7583
emit_marshal_boolean (EmitMarshalContext *m, int argnum, MonoType *t,
Link Here
|
| 7578 |
|
7549 |
|
| 7579 |
case MARSHAL_ACTION_MANAGED_CONV_IN: { |
7550 |
case MARSHAL_ACTION_MANAGED_CONV_IN: { |
| 7580 |
MonoClass* conv_arg_class = mono_defaults.int32_class; |
7551 |
MonoClass* conv_arg_class = mono_defaults.int32_class; |
|
|
7552 |
gint variant_bool = 0; |
| 7581 |
guint8 ldop = CEE_LDIND_I4; |
7553 |
guint8 ldop = CEE_LDIND_I4; |
| 7582 |
int label_null, label_false; |
7554 |
int label_null, label_false; |
| 7583 |
|
7555 |
|
|
Lines 8272-8287
mono_marshal_get_native_func_wrapper (MonoImage *image, MonoMethodSignature *sig
Link Here
|
| 8272 |
return res; |
8244 |
return res; |
| 8273 |
} |
8245 |
} |
| 8274 |
|
8246 |
|
| 8275 |
/* |
8247 |
/* FIXME: moving GC */ |
| 8276 |
* mono_marshal_emit_managed_wrapper: |
|
|
| 8277 |
* |
| 8278 |
* Emit the body of a native-to-managed wrapper. INVOKE_SIG is the signature of |
| 8279 |
* the delegate which wraps the managed method to be called. For closed delegates, |
| 8280 |
* it could have fewer parameters than the method it wraps. |
| 8281 |
* THIS_LOC is the memory location where the target of the delegate is stored. |
| 8282 |
*/ |
| 8283 |
void |
8248 |
void |
| 8284 |
mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoObject** this_loc) |
8249 |
mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoObject* this) |
| 8285 |
{ |
8250 |
{ |
| 8286 |
MonoMethodSignature *sig, *csig; |
8251 |
MonoMethodSignature *sig, *csig; |
| 8287 |
int i, *tmp_locals; |
8252 |
int i, *tmp_locals; |
|
Lines 8339-8348
mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i
Link Here
|
| 8339 |
|
8304 |
|
| 8340 |
emit_thread_interrupt_checkpoint (mb); |
8305 |
emit_thread_interrupt_checkpoint (mb); |
| 8341 |
|
8306 |
|
|
|
8307 |
/* fixme: howto handle this ? */ |
| 8342 |
if (sig->hasthis) { |
8308 |
if (sig->hasthis) { |
| 8343 |
if (this_loc) { |
8309 |
if (this) { |
| 8344 |
mono_mb_emit_ptr (mb, this_loc); |
8310 |
/* FIXME: need a solution for the moving GC here */ |
| 8345 |
mono_mb_emit_byte (mb, CEE_LDIND_REF); |
8311 |
mono_mb_emit_ptr (mb, this); |
| 8346 |
} else { |
8312 |
} else { |
| 8347 |
/* fixme: */ |
8313 |
/* fixme: */ |
| 8348 |
g_assert_not_reached (); |
8314 |
g_assert_not_reached (); |
|
Lines 8497-8503
mono_marshal_set_callconv_from_modopt (MonoMethod *method, MonoMethodSignature *
Link Here
|
| 8497 |
* generates IL code to call managed methods from unmanaged code |
8463 |
* generates IL code to call managed methods from unmanaged code |
| 8498 |
*/ |
8464 |
*/ |
| 8499 |
MonoMethod * |
8465 |
MonoMethod * |
| 8500 |
mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, MonoObject **this_loc) |
8466 |
mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, MonoObject *this) |
| 8501 |
{ |
8467 |
{ |
| 8502 |
static MonoClass *UnmanagedFunctionPointerAttribute; |
8468 |
static MonoClass *UnmanagedFunctionPointerAttribute; |
| 8503 |
MonoMethodSignature *sig, *csig, *invoke_sig; |
8469 |
MonoMethodSignature *sig, *csig, *invoke_sig; |
|
Lines 8518-8524
mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass,
Link Here
|
| 8518 |
* options. |
8484 |
* options. |
| 8519 |
*/ |
8485 |
*/ |
| 8520 |
cache = get_cache (&method->klass->image->managed_wrapper_cache, mono_aligned_addr_hash, NULL); |
8486 |
cache = get_cache (&method->klass->image->managed_wrapper_cache, mono_aligned_addr_hash, NULL); |
| 8521 |
if (!this_loc && (res = mono_marshal_find_in_cache (cache, method))) |
8487 |
if (!this && (res = mono_marshal_find_in_cache (cache, method))) |
| 8522 |
return res; |
8488 |
return res; |
| 8523 |
|
8489 |
|
| 8524 |
invoke = mono_get_delegate_invoke (delegate_klass); |
8490 |
invoke = mono_get_delegate_invoke (delegate_klass); |
|
Lines 8532-8538
mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass,
Link Here
|
| 8532 |
mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_NATIVE_TO_MANAGED); |
8498 |
mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_NATIVE_TO_MANAGED); |
| 8533 |
|
8499 |
|
| 8534 |
/* we copy the signature, so that we can modify it */ |
8500 |
/* we copy the signature, so that we can modify it */ |
| 8535 |
if (this_loc) |
8501 |
if (this) |
| 8536 |
/* Need to free this later */ |
8502 |
/* Need to free this later */ |
| 8537 |
csig = mono_metadata_signature_dup (invoke_sig); |
8503 |
csig = mono_metadata_signature_dup (invoke_sig); |
| 8538 |
else |
8504 |
else |
|
Lines 8577-8585
mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass,
Link Here
|
| 8577 |
} |
8543 |
} |
| 8578 |
} |
8544 |
} |
| 8579 |
|
8545 |
|
| 8580 |
mono_marshal_emit_managed_wrapper (mb, invoke_sig, mspecs, &m, method, this_loc); |
8546 |
mono_marshal_emit_managed_wrapper (mb, invoke_sig, mspecs, &m, method, this); |
| 8581 |
|
8547 |
|
| 8582 |
if (!this_loc) |
8548 |
if (!this) |
| 8583 |
res = mono_mb_create_and_cache (cache, method, |
8549 |
res = mono_mb_create_and_cache (cache, method, |
| 8584 |
mb, csig, sig->param_count + 16); |
8550 |
mb, csig, sig->param_count + 16); |
| 8585 |
else { |
8551 |
else { |