mono_memory_write_barrier ();
stack->top = stack->bottom = chunk;
stack->interior = interior;
-#ifdef MONO_HANDLE_TRACK_OWNER
+#ifdef MONO_HANDLE_TRACK_SP
stack->stackmark_sp = NULL;
#endif
return stack;
g_free (stack);
}
+void
+mono_handle_stack_free_domain (HandleStack *stack, MonoDomain *domain)
+{
+ /* Called by the GC while clearing out objects of the given domain from the heap. */
+ /* If there are no handles-related bugs, there is nothing to do: if a
+ * thread accessed objects from the domain it was aborted, so any
+ * threads left alive cannot have any handles that point into the
+ * unloading domain. However if there is a handle leak, the handle stack is not */
+ if (!stack)
+ return;
+ /* Root domain only unloaded when mono is shutting down, don't need to check anything */
+ if (domain == mono_get_root_domain () || mono_runtime_is_shutting_down ())
+ return;
+ HandleChunk *cur = stack->bottom;
+ HandleChunk *last = stack->top;
+ if (!cur)
+ return;
+ while (cur) {
+ for (int idx = 0; idx < cur->size; ++idx) {
+ HandleChunkElem *elem = &cur->elems[idx];
+ if (!elem->o)
+ continue;
+ g_assert (mono_object_domain (elem->o) != domain);
+ }
+ if (cur == last)
+ break;
+ cur = cur->next;
+ }
+ /* We don't examine the interior pointers here because the GC treats
+ * them conservatively and anyway we don't have enough information here to
+ * find the object's vtable.
+ */
+}
+
static void
check_handle_stack_monotonic (HandleStack *stack)
{
return mono_array_addr_with_size (raw, size, idx);
}
+gunichar2*
+mono_string_handle_pin_chars (MonoStringHandle handle, uint32_t *gchandle)
+{
+ g_assert (gchandle != NULL);
+ *gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, handle), TRUE);
+ MonoString *raw = MONO_HANDLE_RAW (handle);
+ return mono_string_chars (raw);
+}
+
void
mono_array_handle_memcpy_refs (MonoArrayHandle dest, uintptr_t dest_idx, MonoArrayHandle src, uintptr_t src_idx, uintptr_t len)
{