Title: [292513] trunk/Source/bmalloc
Revision
292513
Author
ysuz...@apple.com
Date
2022-04-06 15:47:34 -0700 (Wed, 06 Apr 2022)

Log Message

[libpas] Run TLC decommit rarely
https://bugs.webkit.org/show_bug.cgi?id=238855

Reviewed by Saam Barati.

We were running libpas TLC decommit every time. But it is too frequent. We should capture IsoHeap allocation pattern
with much more longer period, and perform TLC decommit in such a low-frequency rate.
This patch changes it so that we run it only once a 128 scavenger run. It is roughly once a 13 seconds.

* libpas/src/libpas/pas_scavenger.c:
(scavenger_thread_main):
(pas_scavenger_clear_all_caches):
* libpas/src/libpas/pas_thread_local_cache.c:
(pas_thread_local_cache_for_all):
* libpas/src/libpas/pas_thread_local_cache.h:
* libpas/src/test/TLCDecommitTests.cpp:
(std::testTLCDecommit):
(std::testTLCDecommitThenDestroyImpl):
(std::testTLCDecommitThenDeallocate):

Modified Paths

Diff

Modified: trunk/Source/bmalloc/ChangeLog (292512 => 292513)


--- trunk/Source/bmalloc/ChangeLog	2022-04-06 22:41:39 UTC (rev 292512)
+++ trunk/Source/bmalloc/ChangeLog	2022-04-06 22:47:34 UTC (rev 292513)
@@ -1,3 +1,25 @@
+2022-04-06  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [libpas] Run TLC decommit rarely
+        https://bugs.webkit.org/show_bug.cgi?id=238855
+
+        Reviewed by Saam Barati.
+
+        We were running libpas TLC decommit every time. But it is too frequent. We should capture IsoHeap allocation pattern
+        with much more longer period, and perform TLC decommit in such a low-frequency rate.
+        This patch changes it so that we run it only once a 128 scavenger run. It is roughly once a 13 seconds.
+
+        * libpas/src/libpas/pas_scavenger.c:
+        (scavenger_thread_main):
+        (pas_scavenger_clear_all_caches):
+        * libpas/src/libpas/pas_thread_local_cache.c:
+        (pas_thread_local_cache_for_all):
+        * libpas/src/libpas/pas_thread_local_cache.h:
+        * libpas/src/test/TLCDecommitTests.cpp:
+        (std::testTLCDecommit):
+        (std::testTLCDecommitThenDestroyImpl):
+        (std::testTLCDecommitThenDeallocate):
+
 2022-04-06  Commit Queue  <commit-qu...@webkit.org>
 
         Unreviewed, reverting r292450.

Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_scavenger.c (292512 => 292513)


--- trunk/Source/bmalloc/libpas/src/libpas/pas_scavenger.c	2022-04-06 22:41:39 UTC (rev 292512)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_scavenger.c	2022-04-06 22:47:34 UTC (rev 292513)
@@ -69,6 +69,10 @@
 uint64_t pas_scavenger_max_epoch_delta = 300ll * 1000ll * 1000ll;
 #endif
 
+static uint32_t pas_scavenger_tick_count = 0;
+/* Run thread-local-cache decommit once a N. It should be power of two. */
+#define PAS_THREAD_LOCAL_CACHE_DECOMMIT_PERIOD_COUNT 128 /* Roughly speaking, it runs once per 13 seconds. */
+
 #if PAS_OS(DARWIN)
 static _Atomic qos_class_t pas_scavenger_requested_qos_class = QOS_CLASS_USER_INITIATED;
 
@@ -192,6 +196,7 @@
         double time_in_milliseconds;
         double absolute_timeout_in_milliseconds_for_period_sleep;
         pas_scavenger_activity_callback completion_callback;
+        pas_thread_local_cache_decommit_action thread_local_cache_decommit_action;
         bool should_go_again;
         uint64_t epoch;
         uint64_t delta;
@@ -208,6 +213,7 @@
             pthread_set_qos_class_self_np(configured_qos_class, 0);
         }
 #endif
+        ++pas_scavenger_tick_count;
 
         should_go_again = false;
         
@@ -229,9 +235,16 @@
             pas_utility_heap_for_all_allocators(pas_allocator_scavenge_request_stop_action,
                                                 pas_lock_is_not_held);
         
+        thread_local_cache_decommit_action = pas_thread_local_cache_decommit_no_action;
+        if ((pas_scavenger_tick_count % PAS_THREAD_LOCAL_CACHE_DECOMMIT_PERIOD_COUNT) == 0) {
+            if (verbose)
+                printf("Attempt to decommit unused TLC\n");
+            thread_local_cache_decommit_action = pas_thread_local_cache_decommit_if_possible_action;
+        }
         should_go_again |=
             pas_thread_local_cache_for_all(pas_allocator_scavenge_request_stop_action,
-                                           pas_deallocator_scavenge_flush_log_if_clean_action);
+                                           pas_deallocator_scavenge_flush_log_if_clean_action,
+                                           thread_local_cache_decommit_action);
 
         should_go_again |= handle_expendable_memory(pas_expendable_memory_scavenge_periodic);
 
@@ -502,7 +515,8 @@
     pas_scavenger_clear_all_caches_except_remote_tlcs();
     
     pas_thread_local_cache_for_all(pas_allocator_scavenge_force_stop_action,
-                                   pas_deallocator_scavenge_flush_log_action);
+                                   pas_deallocator_scavenge_flush_log_action,
+                                   pas_thread_local_cache_decommit_if_possible_action);
 }
 
 void pas_scavenger_decommit_expendable_memory(void)

Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c (292512 => 292513)


--- trunk/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c	2022-04-06 22:41:39 UTC (rev 292512)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c	2022-04-06 22:47:34 UTC (rev 292513)
@@ -1022,7 +1022,8 @@
 }
 
 bool pas_thread_local_cache_for_all(pas_allocator_scavenge_action allocator_action,
-                                    pas_deallocator_scavenge_action deallocator_action)
+                                    pas_deallocator_scavenge_action deallocator_action,
+                                    pas_thread_local_cache_decommit_action thread_local_cache_decommit_action)
 {
     pas_thread_local_cache_node* node;
     bool result;
@@ -1087,8 +1088,6 @@
             pas_thread_local_cache_layout_segment* segment;
             pas_thread_local_cache_layout_segment* begin_segment;
             uintptr_t start_of_possible_decommit;
-            uintptr_t begin_page_index;
-            uintptr_t end_page_index;
             uintptr_t page_index;
             uintptr_t node_index;
             uintptr_t begin_node_index;
@@ -1106,9 +1105,7 @@
             node_index = 0;
             for (PAS_THREAD_LOCAL_CACHE_LAYOUT_EACH_ALLOCATOR_WITH_SEGMENT_AND_INDEX(layout_node, segment, node_index)) {
                 pas_allocator_index allocator_index;
-                pas_allocator_index end_allocator_index;
                 pas_local_allocator_scavenger_data* scavenger_data;
-                pas_decommit_exclusion_range decommit_exclusion_range;
 
                 allocator_index =
                     pas_thread_local_cache_layout_node_get_allocator_index_generic(layout_node);
@@ -1116,45 +1113,44 @@
                 if (allocator_index >= cache->allocator_index_upper_bound)
                     break;
 
-                end_allocator_index =
-                    allocator_index + pas_thread_local_cache_layout_node_num_allocator_indices(layout_node);
-
                 scavenger_data = (pas_local_allocator_scavenger_data*)
                     pas_thread_local_cache_get_local_allocator_direct(cache, allocator_index);
-                
-                decommit_exclusion_range = pas_thread_local_cache_compute_decommit_exclusion_range(
-                    cache, allocator_index, end_allocator_index);
-                PAS_ASSERT(start_of_possible_decommit
-                           <= decommit_exclusion_range.start_of_possible_decommit);
-                PAS_ASSERT(start_of_possible_decommit
-                           <= decommit_exclusion_range.end_of_possible_decommit);
-                if (pas_decommit_exclusion_range_is_contiguous(decommit_exclusion_range)) {
-                    stop_allocator(
-                        cache, allocator_action, allocator_index, scavenger_data, &result, &thread_suspend_data);
 
-                    if (pas_local_allocator_scavenger_data_is_stopped(scavenger_data)) {
-                        if (!begin_segment) {
-                            begin_segment = segment;
-                            begin_node_index = node_index;
+                if (thread_local_cache_decommit_action == pas_thread_local_cache_decommit_if_possible_action) {
+                    pas_allocator_index end_allocator_index = allocator_index + pas_thread_local_cache_layout_node_num_allocator_indices(layout_node);
+                    pas_decommit_exclusion_range decommit_exclusion_range = pas_thread_local_cache_compute_decommit_exclusion_range(cache, allocator_index, end_allocator_index);
+                    PAS_ASSERT(start_of_possible_decommit <= decommit_exclusion_range.start_of_possible_decommit);
+                    PAS_ASSERT(start_of_possible_decommit <= decommit_exclusion_range.end_of_possible_decommit);
+
+                    if (pas_decommit_exclusion_range_is_contiguous(decommit_exclusion_range)) {
+                        stop_allocator(
+                            cache, allocator_action, allocator_index, scavenger_data, &result, &thread_suspend_data);
+
+                        if (pas_local_allocator_scavenger_data_is_stopped(scavenger_data)) {
+                            if (!begin_segment) {
+                                begin_segment = segment;
+                                begin_node_index = node_index;
+                            } else {
+                                PAS_TESTING_ASSERT(
+                                    pas_thread_local_cache_layout_node_get_allocator_index_generic(pas_thread_local_cache_layout_segment_get_node(begin_segment, begin_node_index))
+                                    < allocator_index);
+                            }
                         } else {
-                            PAS_TESTING_ASSERT(
-                                pas_thread_local_cache_layout_node_get_allocator_index_generic(pas_thread_local_cache_layout_segment_get_node(begin_segment, begin_node_index))
-                                < allocator_index);
+                            decommit_exclusion_range =
+                                pas_decommit_exclusion_range_create_inverted(decommit_exclusion_range);
                         }
-                    } else {
-                        decommit_exclusion_range =
-                            pas_decommit_exclusion_range_create_inverted(decommit_exclusion_range);
                     }
-                }
 
-                if (pas_decommit_exclusion_range_is_inverted(decommit_exclusion_range)) {
-                    decommit_allocator_range(
-                        cache, begin_segment, begin_node_index, start_of_possible_decommit,
-                        decommit_exclusion_range.end_of_possible_decommit, segment, node_index);
-                    start_of_possible_decommit = decommit_exclusion_range.start_of_possible_decommit;
-                    begin_segment = NULL;
-                    begin_node_index = 0;
-                }
+                    if (pas_decommit_exclusion_range_is_inverted(decommit_exclusion_range)) {
+                        decommit_allocator_range(
+                            cache, begin_segment, begin_node_index, start_of_possible_decommit,
+                            decommit_exclusion_range.end_of_possible_decommit, segment, node_index);
+                        start_of_possible_decommit = decommit_exclusion_range.start_of_possible_decommit;
+                        begin_segment = NULL;
+                        begin_node_index = 0;
+                    }
+                } else
+                    stop_allocator(cache, allocator_action, allocator_index, scavenger_data, &result, &thread_suspend_data);
             }
             
 #if PAS_OS(DARWIN)
@@ -1162,29 +1158,31 @@
                 resume(cache, &thread_suspend_data);
 #endif
 
-            begin_page_index =
-                pas_round_up_to_power_of_2(start_of_possible_decommit, page_size)
-                >> page_size_shift;
-            end_page_index =
-                pas_thread_local_cache_size_for_allocator_index_capacity(cache->allocator_index_capacity)
-                >> page_size_shift;
+            if (thread_local_cache_decommit_action == pas_thread_local_cache_decommit_if_possible_action) {
+                uintptr_t begin_page_index =
+                    pas_round_up_to_power_of_2(start_of_possible_decommit, page_size)
+                    >> page_size_shift;
+                uintptr_t end_page_index =
+                    pas_thread_local_cache_size_for_allocator_index_capacity(cache->allocator_index_capacity)
+                    >> page_size_shift;
 
-            for (page_index = begin_page_index; page_index < end_page_index; ++page_index) {
-                if (!pas_bitvector_get(cache->pages_committed, page_index)) {
-                    decommit_allocator_range(
-                        cache, begin_segment, begin_node_index, start_of_possible_decommit,
-                        page_index << page_size_shift,
-                        segment, node_index);
-                    start_of_possible_decommit = (page_index + 1) << page_size_shift;
-                    begin_segment = NULL;
-                    begin_node_index = 0;
+                for (page_index = begin_page_index; page_index < end_page_index; ++page_index) {
+                    if (!pas_bitvector_get(cache->pages_committed, page_index)) {
+                        decommit_allocator_range(
+                            cache, begin_segment, begin_node_index, start_of_possible_decommit,
+                            page_index << page_size_shift,
+                            segment, node_index);
+                        start_of_possible_decommit = (page_index + 1) << page_size_shift;
+                        begin_segment = NULL;
+                        begin_node_index = 0;
+                    }
                 }
+
+                decommit_allocator_range(
+                    cache, begin_segment, begin_node_index, start_of_possible_decommit,
+                    pas_thread_local_cache_size_for_allocator_index_capacity(cache->allocator_index_capacity),
+                    segment, node_index);
             }
-            
-            decommit_allocator_range(
-                cache, begin_segment, begin_node_index, start_of_possible_decommit,
-                pas_thread_local_cache_size_for_allocator_index_capacity(cache->allocator_index_capacity),
-                segment, node_index);
         }
         
         pas_lock_unlock(&node->scavenger_lock);

Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.h (292512 => 292513)


--- trunk/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.h	2022-04-06 22:41:39 UTC (rev 292512)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.h	2022-04-06 22:47:34 UTC (rev 292513)
@@ -372,10 +372,17 @@
     pas_thread_local_cache* thread_local_cache,
     pas_lock_hold_mode heap_lock_hold_mode);
 
+enum pas_thread_local_cache_decommit_action {
+    pas_thread_local_cache_decommit_no_action,
+    pas_thread_local_cache_decommit_if_possible_action,
+};
+typedef enum pas_thread_local_cache_decommit_action pas_thread_local_cache_decommit_action;
+
 /* Returns true if it's possible that we'll be able to return more memory if this was called
    again. */
 PAS_API bool pas_thread_local_cache_for_all(pas_allocator_scavenge_action allocator_action,
-                                            pas_deallocator_scavenge_action deallocator_action);
+                                            pas_deallocator_scavenge_action deallocator_action,
+                                            pas_thread_local_cache_decommit_action thread_local_cache_decommit_action);
 
 PAS_API PAS_NEVER_INLINE void pas_thread_local_cache_append_deallocation_slow(
     pas_thread_local_cache* thread_local_cache,

Modified: trunk/Source/bmalloc/libpas/src/test/TLCDecommitTests.cpp (292512 => 292513)


--- trunk/Source/bmalloc/libpas/src/test/TLCDecommitTests.cpp	2022-04-06 22:41:39 UTC (rev 292512)
+++ trunk/Source/bmalloc/libpas/src/test/TLCDecommitTests.cpp	2022-04-06 22:47:34 UTC (rev 292513)
@@ -157,7 +157,8 @@
     pas_heap_lock_unlock();
 
     pas_thread_local_cache_for_all(pas_allocator_scavenge_request_stop_action,
-                                   pas_deallocator_scavenge_no_action);
+                                   pas_deallocator_scavenge_no_action,
+                                   pas_thread_local_cache_decommit_if_possible_action);
 
     CHECK_EQUAL(numCommittedPagesInTLC(), numCommittedPagesAfterDecommit);
 
@@ -296,7 +297,8 @@
     CHECK(pas_thread_local_cache_try_get()->deallocation_log_index);
 
     pas_thread_local_cache_for_all(pas_allocator_scavenge_force_stop_action,
-                                   pas_deallocator_scavenge_no_action);
+                                   pas_deallocator_scavenge_no_action,
+                                   pas_thread_local_cache_decommit_if_possible_action);
 
     CHECK_EQUAL(numCommittedPagesInTLC(), 1);
     CHECK(pas_thread_local_cache_try_get()->deallocation_log_index);
@@ -340,7 +342,8 @@
     CHECK(!pas_thread_local_cache_try_get()->deallocation_log_index);
 
     pas_thread_local_cache_for_all(pas_allocator_scavenge_force_stop_action,
-                                   pas_deallocator_scavenge_no_action);
+                                   pas_deallocator_scavenge_no_action,
+                                   pas_thread_local_cache_decommit_if_possible_action);
 
     for (void* object : objects)
         bmalloc_deallocate(object);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to