summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2020-11-05 08:51:40 -0800
committerAaron Patterson <tenderlove@ruby-lang.org>2020-11-05 08:51:40 -0800
commit68a3a2d90f96b46e5c20659ea3eef3f554fbf542 (patch)
tree81c49cc9908cf7a568345d17d8ba2df1bc4aad41 /gc.c
parent193edbde912ef44d48dc5f652326d6b923a5ec3a (diff)
take VM lock when mutating the heap
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/gc.c b/gc.c
index abc311a8e9..1c7945a156 100644
--- a/gc.c
+++ b/gc.c
@@ -8524,29 +8524,33 @@ gc_sort_heap_by_empty_slots(rb_execution_context_t *ec, VALUE self)
gc_rest(objspace);
- list_for_each(&heap_eden->pages, page, page_node) {
- page_list[i++] = page;
- GC_ASSERT(page != NULL);
- }
- GC_ASSERT(total_pages > 0);
- GC_ASSERT((size_t)i == total_pages);
+ RB_VM_LOCK_ENTER();
+ {
+ list_for_each(&heap_eden->pages, page, page_node) {
+ page_list[i++] = page;
+ GC_ASSERT(page != NULL);
+ }
+ GC_ASSERT(total_pages > 0);
+ GC_ASSERT((size_t)i == total_pages);
- /* Sort the heap so "filled pages" are first. `heap_add_page` adds to the
- * head of the list, so empty pages will end up at the start of the heap */
- ruby_qsort(page_list, total_pages, sizeof(struct heap_page *), compare_free_slots, NULL);
+ /* Sort the heap so "filled pages" are first. `heap_add_page` adds to the
+ * head of the list, so empty pages will end up at the start of the heap */
+ ruby_qsort(page_list, total_pages, sizeof(struct heap_page *), compare_free_slots, NULL);
- /* Reset the eden heap */
- list_head_init(&objspace->eden_heap.pages);
- heap_eden->free_pages = NULL;
+ /* Reset the eden heap */
+ list_head_init(&objspace->eden_heap.pages);
+ heap_eden->free_pages = NULL;
- for (i = 0; i < total_pages; i++) {
- list_add(&heap_eden->pages, &page_list[i]->page_node);
- if (page_list[i]->free_slots != 0) {
- heap_add_freepage(heap_eden, page_list[i]);
+ for (i = 0; i < total_pages; i++) {
+ list_add(&heap_eden->pages, &page_list[i]->page_node);
+ if (page_list[i]->free_slots != 0) {
+ heap_add_freepage(heap_eden, page_list[i]);
+ }
}
- }
- free(page_list);
+ free(page_list);
+ }
+ RB_VM_LOCK_LEAVE();
return Qnil;
}
@@ -8556,7 +8560,11 @@ gc_double_heap_size(rb_execution_context_t *ec, VALUE self)
{
rb_objspace_t *objspace = &rb_objspace;
- heap_add_pages(objspace, heap_eden, heap_allocated_pages);
+ RB_VM_LOCK_ENTER();
+ {
+ heap_add_pages(objspace, heap_eden, heap_allocated_pages);
+ }
+ RB_VM_LOCK_LEAVE();
return Qnil;
}