MonoMethod* mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box, gboolean known_instance_size) { int offset = -1; int atype; MONO_THREAD_VAR_OFFSET (GC_thread_tls, offset); /*g_print ("thread tls: %d\n", offset);*/ if (offset == -1) return NULL; if (!SMALL_ENOUGH (klass->instance_size)) return NULL; if (mono_class_has_finalizer (klass) || mono_class_is_marshalbyref (klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS)) return NULL; if (klass->rank) return NULL; if (mono_class_is_open_constructed_type (&klass->byval_arg)) return NULL; if (klass->byval_arg.type == MONO_TYPE_STRING) { atype = ATYPE_STRING; } else if (!known_instance_size) { return NULL; } else if (!klass->has_references) { if (for_box) atype = ATYPE_FREEPTR_FOR_BOX; else atype = ATYPE_FREEPTR; } else { return NULL; /* * disabled because we currently do a runtime choice anyway, to * deal with multiple appdomains. if (vtable->gc_descr != GC_NO_DESCRIPTOR) atype = ATYPE_GCJ; else atype = ATYPE_NORMAL; */ } return mono_gc_get_managed_allocator_by_type (atype, FALSE); }
/* * Generate an allocator method implementing the fast path of mono_gc_alloc_obj (). * The signature of the called method is: * object allocate (MonoVTable *vtable) */ MonoMethod* mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box) { #ifdef MANAGED_ALLOCATION #ifdef HAVE_KW_THREAD int tlab_next_offset = -1; int tlab_temp_end_offset = -1; MONO_THREAD_VAR_OFFSET (tlab_next, tlab_next_offset); MONO_THREAD_VAR_OFFSET (tlab_temp_end, tlab_temp_end_offset); if (tlab_next_offset == -1 || tlab_temp_end_offset == -1) return NULL; #endif if (!mono_runtime_has_tls_get ()) return NULL; if (klass->instance_size > tlab_size) return NULL; if (klass->has_finalize || mono_class_is_marshalbyref (klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS)) return NULL; if (klass->rank) return NULL; if (klass->byval_arg.type == MONO_TYPE_STRING) return mono_gc_get_managed_allocator_by_type (ATYPE_STRING); if (collect_before_allocs) return NULL; /* Generic classes have dynamic field and can go above MAX_SMALL_OBJ_SIZE. */ if (ALIGN_TO (klass->instance_size, ALLOC_ALIGN) < MAX_SMALL_OBJ_SIZE && !mono_class_is_open_constructed_type (&klass->byval_arg)) return mono_gc_get_managed_allocator_by_type (ATYPE_SMALL); else return mono_gc_get_managed_allocator_by_type (ATYPE_NORMAL); #else return NULL; #endif }