Merge pull request #5002 from BrzVlad/feature-sgen-modes
[mono.git] / mono / metadata / handle.c
index a0f5c4459f1a90c215ace491307b2ede24d7fb80..59bde7fbe7750ef52ee801160bae8f94b6c87ba3 100644 (file)
@@ -252,7 +252,7 @@ mono_handle_stack_alloc (void)
        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;
@@ -276,6 +276,40 @@ mono_handle_stack_free (HandleStack *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)
 {
@@ -456,6 +490,15 @@ mono_array_handle_pin_with_size (MonoArrayHandle handle, int size, uintptr_t idx
        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)
 {