Diff
Modified: trunk/Source/bmalloc/ChangeLog (282898 => 282899)
--- trunk/Source/bmalloc/ChangeLog 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/ChangeLog 2021-09-23 00:52:25 UTC (rev 282899)
@@ -1,3 +1,54 @@
+2021-09-22 Filip Pizlo <fpi...@apple.com>
+
+ [libpas] fix DebugHeap
+ https://bugs.webkit.org/show_bug.cgi?id=230658
+
+ Reviewed by Yusuke Suzuki.
+
+ The previous DebugHeap integration with libpas assumed we didn't have a jit_heap. Now that
+ we have a jit_heap, we need to be able to do DebugHeap from the bmalloc_heap while we still
+ use jit_heap.
+
+ This was tricky, since previously, libpas could just follow bmalloc and say that if TLC is
+ not initialized, then we go slow, and the slow path checks for DebugHeap. Now, we might have
+ a TLC. This means having to push down the debug heap checks into other slow paths.
+
+ * bmalloc/DebugHeap.cpp:
+ (pas_debug_heap_is_enabled):
+ (pas_debug_heap_malloc):
+ (pas_debug_heap_memalign):
+ (pas_debug_heap_realloc):
+ (pas_debug_heap_free):
+ * libpas/src/libpas/bmalloc_heap_config.c:
+ (bmalloc_heap_config_activate):
+ * libpas/src/libpas/jit_heap.c:
+ (jit_heap_add_fresh_memory):
+ (jit_heap_try_allocate):
+ * libpas/src/libpas/jit_heap_config.c:
+ * libpas/src/libpas/pas_deallocate.c:
+ (pas_try_deallocate_slow_no_cache):
+ * libpas/src/libpas/pas_deallocate.h:
+ (pas_try_deallocate_not_small):
+ * libpas/src/libpas/pas_debug_heap.h:
+ (pas_debug_heap_is_enabled):
+ (pas_debug_heap_allocate):
+ * libpas/src/libpas/pas_local_allocator_inlines.h:
+ (pas_local_allocator_try_allocate_small_segregated_slow_impl):
+ (pas_local_allocator_try_allocate_slow_impl):
+ (pas_local_allocator_try_allocate):
+ * libpas/src/libpas/pas_thread_local_cache.c:
+ (allocate_cache):
+ (pas_thread_local_cache_get_local_allocator_if_can_set_cache_slow):
+ * libpas/src/libpas/pas_try_allocate.h:
+ (pas_try_allocate_impl):
+ * libpas/src/libpas/pas_try_allocate_common.h:
+ (pas_try_allocate_common_impl_slow):
+ * libpas/src/libpas/pas_try_allocate_intrinsic_primitive.h:
+ (pas_try_allocate_intrinsic_primitive_impl_medium_slow_case):
+ (pas_try_allocate_intrinsic_primitive_impl_inline_only):
+ * libpas/src/libpas/pas_try_reallocate.h:
+ (pas_try_reallocate):
+
2021-09-21 Basuke Suzuki <basuke.suz...@sony.com>
[bmalloc] freeableMemory and footprint of Heap are completely broken
Modified: trunk/Source/bmalloc/bmalloc/DebugHeap.cpp (282898 => 282899)
--- trunk/Source/bmalloc/bmalloc/DebugHeap.cpp 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/bmalloc/DebugHeap.cpp 2021-09-23 00:52:25 UTC (rev 282899)
@@ -185,12 +185,49 @@
#if BENABLE(LIBPAS)
-// FIXME: Currently, we only use libpas for executable allocator. Thus libpas allocator is always enabled even when Malloc=1 is specified.
-// To make it work, we disable debug heap for libpas completely. We need additional code to enable libpas only for executable allocator when
-// Malloc=1 is specified when bmalloc is replaced with libpas.
+#if BUSE(LIBPAS)
-bool pas_debug_heap_is_enabled(void)
+using namespace bmalloc;
+
+bool pas_debug_heap_is_enabled(pas_heap_config_kind kind)
{
+ switch (kind) {
+ case pas_heap_config_kind_bmalloc:
+ return !!DebugHeap::tryGet();
+ case pas_heap_config_kind_jit:
+ case pas_heap_config_kind_pas_utility:
+ return false;
+ default:
+ BCRASH();
+ return false;
+ }
+}
+
+void* pas_debug_heap_malloc(size_t size)
+{
+ return DebugHeap::getExisting()->malloc(size, FailureAction::ReturnNull);
+}
+
+void* pas_debug_heap_memalign(size_t alignment, size_t size)
+{
+ return DebugHeap::getExisting()->memalign(alignment, size, FailureAction::ReturnNull);
+}
+
+void* pas_debug_heap_realloc(void* ptr, size_t size)
+{
+ return DebugHeap::getExisting()->realloc(ptr, size, FailureAction::ReturnNull);
+}
+
+void pas_debug_heap_free(void* ptr)
+{
+ DebugHeap::getExisting()->free(ptr);
+}
+
+#else // BUSE(LIBPAS) -> so !BUSE(LIBPAS)
+
+bool pas_debug_heap_is_enabled(pas_heap_config_kind kind)
+{
+ BUNUSED_PARAM(kind);
return false;
}
@@ -226,5 +263,7 @@
}
#pragma clang diagnostic pop
+#endif // BUSE(LIBPAS) -> so end of !BUSE(LIBPAS)
+
#endif // BENABLE(LIBPAS)
Modified: trunk/Source/bmalloc/libpas/src/libpas/bmalloc_heap_config.c (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/bmalloc_heap_config.c 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/bmalloc_heap_config.c 2021-09-23 00:52:25 UTC (rev 282899)
@@ -45,13 +45,12 @@
void bmalloc_heap_config_activate(void)
{
- // FIXME: Temporarily disable it for now until bmalloc is replaced with libpas.
- static const bool register_with_libmalloc = false;
+ static const bool register_with_libmalloc = true;
pas_designated_intrinsic_heap_initialize(&bmalloc_common_primitive_heap.segregated_heap,
&bmalloc_heap_config);
- if (register_with_libmalloc)
+ if (register_with_libmalloc && !pas_debug_heap_is_enabled(pas_heap_config_kind_bmalloc))
pas_root_ensure_for_libmalloc_enumeration();
}
Modified: trunk/Source/bmalloc/libpas/src/libpas/jit_heap.c (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/jit_heap.c 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/jit_heap.c 2021-09-23 00:52:25 UTC (rev 282899)
@@ -50,6 +50,11 @@
void jit_heap_add_fresh_memory(pas_range range)
{
+ static const bool verbose = false;
+
+ if (verbose)
+ pas_log("JIT heap at %p...%p\n", (void*)range.begin, (void*)range.end);
+
pas_heap_lock_lock();
jit_heap_config_add_fresh_memory(range);
pas_heap_lock_unlock();
@@ -67,7 +72,14 @@
void* jit_heap_try_allocate(size_t size)
{
- return (void*)jit_try_allocate_common_primitive_impl(size, 1).begin;
+ static const bool verbose = false;
+ void* result;
+ if (verbose)
+ pas_log("going to allocate in jit\n");
+ result = (void*)jit_try_allocate_common_primitive_impl(size, 1).begin;
+ if (verbose)
+ pas_log("done allocating in jit, returning %p\n", result);
+ return result;
}
void jit_heap_shrink(void* object, size_t new_size)
Modified: trunk/Source/bmalloc/libpas/src/libpas/jit_heap_config.c (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/jit_heap_config.c 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/jit_heap_config.c 2021-09-23 00:52:25 UTC (rev 282899)
@@ -38,6 +38,10 @@
#include "pas_heap_config_inlines.h"
#include "pas_root.h"
+#if defined(PAS_BMALLOC)
+#include "BPlatform.h"
+#endif
+
pas_heap_config jit_heap_config = JIT_HEAP_CONFIG;
pas_simple_large_free_heap jit_fresh_memory_heap = PAS_SIMPLE_LARGE_FREE_HEAP_INITIALIZER;
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_deallocate.c (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_deallocate.c 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_deallocate.c 2021-09-23 00:52:25 UTC (rev 282899)
@@ -98,7 +98,7 @@
if (verbose)
pas_log("Trying to deallocate %p.\n", ptr);
- if (PAS_UNLIKELY(pas_debug_heap_is_enabled())) {
+ if (PAS_UNLIKELY(pas_debug_heap_is_enabled(config_ptr->kind))) {
if (verbose)
pas_log("Deallocating %p with debug heap.\n", ptr);
PAS_ASSERT(deallocation_mode == pas_deallocate_mode);
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_deallocate.h (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_deallocate.h 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_deallocate.h 2021-09-23 00:52:25 UTC (rev 282899)
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020 Apple Inc. All rights reserved.
+ * Copyright (c) 2019-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
#include "pas_bitfit_page_inlines.h"
#include "pas_deallocation_mode.h"
+#include "pas_debug_heap.h"
#include "pas_heap_config.h"
#include "pas_heap_lock.h"
#include "pas_heap_ref.h"
@@ -84,6 +85,11 @@
{
pas_page_base* page_base;
+ if (pas_debug_heap_is_enabled(config.kind)) {
+ pas_debug_heap_free((void*)begin);
+ return true;
+ }
+
page_base = config.page_header_func(begin);
if (page_base) {
switch (pas_page_base_get_kind(page_base)) {
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_debug_heap.h (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_debug_heap.h 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_debug_heap.h 2021-09-23 00:52:25 UTC (rev 282899)
@@ -26,6 +26,9 @@
#ifndef PAS_DEBUG_HEAP_H
#define PAS_DEBUG_HEAP_H
+#include "pas_allocation_result.h"
+#include "pas_heap_config_kind.h"
+#include "pas_log.h"
#include "pas_utils.h"
PAS_BEGIN_EXTERN_C;
@@ -36,7 +39,7 @@
#if PAS_BMALLOC
/* The implementations are provided by bmalloc. */
-PAS_API extern bool pas_debug_heap_is_enabled(void);
+PAS_API extern bool pas_debug_heap_is_enabled(pas_heap_config_kind kind);
PAS_API extern void* pas_debug_heap_malloc(size_t size);
PAS_API extern void* pas_debug_heap_memalign(size_t alignment, size_t size);
PAS_API extern void* pas_debug_heap_realloc(void* ptr, size_t size);
@@ -44,8 +47,9 @@
#else /* PAS_BMALLOC -> so !PAS_BMALLOC */
-static inline bool pas_debug_heap_is_enabled(void)
+static inline bool pas_debug_heap_is_enabled(pas_heap_config_kind kind)
{
+ PAS_UNUSED_PARAM(kind);
return false;
}
@@ -80,6 +84,33 @@
#endif /* PAS_BMALLOC -> so end of !PAS_BMALLOC */
+static inline pas_allocation_result pas_debug_heap_allocate(size_t size, size_t alignment)
+{
+ static const bool verbose = false;
+
+ pas_allocation_result result;
+ void* raw_result;
+
+ if (alignment > sizeof(void*)) {
+ if (verbose)
+ pas_log("Going down debug memalign path.\n");
+ raw_result = pas_debug_heap_memalign(alignment, size);
+ } else {
+ if (verbose)
+ pas_log("Going down debug malloc path.\n");
+ raw_result = pas_debug_heap_malloc(size);
+ }
+
+ if (verbose)
+ pas_log("raw_result = %p\n", raw_result);
+
+ result.did_succeed = !!raw_result;
+ result.begin = (uintptr_t)raw_result;
+ result.zero_mode = pas_zero_mode_may_have_non_zero;
+
+ return result;
+}
+
PAS_END_EXTERN_C;
#endif /* PAS_DEBUG_HEAP_H */
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_local_allocator_inlines.h (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_local_allocator_inlines.h 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_local_allocator_inlines.h 2021-09-23 00:52:25 UTC (rev 282899)
@@ -31,6 +31,7 @@
#include "pas_bitfit_directory.h"
#include "pas_bitfit_size_class.h"
#include "pas_config.h"
+#include "pas_debug_heap.h"
#include "pas_epoch.h"
#include "pas_full_alloc_bits_inlines.h"
#include "pas_scavenger.h"
@@ -1489,6 +1490,8 @@
pas_heap_config config,
pas_allocator_counts* counts)
{
+ PAS_ASSERT(!pas_debug_heap_is_enabled(config.kind));
+
for (;;) {
pas_allocation_result result;
bool skip_bitfit;
@@ -1613,6 +1616,8 @@
pas_log("Called try_allocate_slow with kind = %s\n",
pas_local_allocator_config_kind_get_string(allocator->config_kind));
}
+
+ PAS_ASSERT(!pas_debug_heap_is_enabled(config.kind));
for (;;) {
pas_fast_path_allocation_result fast_result;
@@ -1745,6 +1750,9 @@
pas_allocation_result_create_success_with_zero_mode(result.begin, result.zero_mode));
}
+ if (PAS_UNLIKELY(pas_debug_heap_is_enabled(config.kind)))
+ return pas_debug_heap_allocate(size_thunk(size_thunk_arg), alignment);
+
if (config.small_segregated_config.base.is_enabled &&
allocator->config_kind == pas_local_allocator_config_kind_create_normal(
config.small_segregated_config.kind)) {
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c 2021-09-23 00:52:25 UTC (rev 282899)
@@ -101,8 +101,6 @@
size_t size;
pas_thread_local_cache* result;
- PAS_ASSERT(!pas_debug_heap_is_enabled());
-
size = pas_thread_local_cache_size_for_allocator_index_capacity(allocator_index_capacity);
if (verbose)
@@ -308,7 +306,7 @@
pas_thread_local_cache_get_local_allocator_if_can_set_cache_slow(unsigned allocator_index,
pas_heap_config* heap_config)
{
- if (!pas_thread_local_cache_can_set() || pas_debug_heap_is_enabled())
+ if (!pas_thread_local_cache_can_set() || pas_debug_heap_is_enabled(heap_config->kind))
return pas_local_allocator_result_create_failure();
return pas_thread_local_cache_get_local_allocator(
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_try_allocate.h (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_try_allocate.h 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_try_allocate.h 2021-09-23 00:52:25 UTC (rev 282899)
@@ -60,11 +60,14 @@
pas_try_allocate_common_fast try_allocate_common_fast,
pas_try_allocate_common_slow try_allocate_common_slow)
{
+ static const bool verbose = false;
+
pas_heap_type* type;
size_t type_size;
pas_local_allocator_result allocator;
unsigned allocator_index;
pas_thread_local_cache* cache;
+ pas_typed_allocation_result result;
allocator_index = heap_ref->allocator_index;
cache = pas_thread_local_cache_try_get();
@@ -72,6 +75,10 @@
allocator = pas_thread_local_cache_try_get_local_allocator(
cache,
allocator_index);
+
+ if (verbose)
+ pas_log("Got an allocator.\n");
+
if (PAS_LIKELY(allocator.did_succeed)) {
pas_allocation_result result;
pas_try_allocate_impl_size_thunk_data size_thunk_data;
@@ -90,14 +97,25 @@
return pas_typed_allocation_result_create_with_intrinsic_allocation_result(
result, type, config.get_type_size(type));
}
+
+ if (verbose)
+ pas_log("Did not succeed at getting an allocator.\n");
}
type = heap_ref->type;
type_size = config.get_type_size(type);
- return pas_typed_allocation_result_create_with_intrinsic_allocation_result(
+ if (verbose)
+ pas_log("Allocating the slow way.\n");
+
+ result = pas_typed_allocation_result_create_with_intrinsic_allocation_result(
try_allocate_common_slow(heap_ref, 1, type_size, 1),
type, type_size);
+
+ if (verbose)
+ pas_log("result.ptr = %p, result.did_succeed = %d\n", result.ptr, result.did_succeed);
+
+ return result;
}
#define PAS_CREATE_TRY_ALLOCATE(name, heap_config, runtime_config, allocator_counts, result_filter) \
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_try_allocate_common.h (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_try_allocate_common.h 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_try_allocate_common.h 2021-09-23 00:52:25 UTC (rev 282899)
@@ -107,23 +107,18 @@
type = heap_ref->type;
alignment = PAS_MAX(alignment, config.get_type_alignment(type));
- if (PAS_UNLIKELY(pas_debug_heap_is_enabled())) {
- void* raw_result;
-
- if (alignment != 1) {
- PAS_ASSERT(alignment > 1);
- raw_result = pas_debug_heap_memalign(alignment, size);
- } else
- raw_result = pas_debug_heap_malloc(size);
-
- if (raw_result) {
- result.did_succeed = true;
- result.begin = (uintptr_t)raw_result;
- }
-
+ if (PAS_UNLIKELY(pas_debug_heap_is_enabled(config.kind))) {
+ if (verbose)
+ pas_log("Debug heap enabled, asking debug heap.\n");
+ result = pas_debug_heap_allocate(size, alignment);
+ if (verbose)
+ pas_log("Got result.ptr = %p, did_succeed = %d\n", result.begin, result.did_succeed);
return result;
}
+ if (verbose)
+ pas_log("Not using debug heap.\n");
+
heap = pas_ensure_heap(heap_ref, heap_ref_kind, config.config_ptr, runtime_config);
switch (heap_ref_kind) {
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_try_allocate_intrinsic_primitive.h (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_try_allocate_intrinsic_primitive.h 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_try_allocate_intrinsic_primitive.h 2021-09-23 00:52:25 UTC (rev 282899)
@@ -80,9 +80,18 @@
PAS_ASSERT(alignment == 1 || !designation_mode);
+ if (verbose)
+ pas_log("in impl_medium_slow_case for %s\n", pas_heap_config_kind_get_string(config.kind));
+
if (!pas_is_power_of_2(alignment))
return pas_allocation_result_create_failure();
+ if (PAS_UNLIKELY(pas_debug_heap_is_enabled(config.kind)))
+ return pas_debug_heap_allocate(size, alignment);
+
+ if (verbose)
+ pas_log("not doing debug heap in impl_medium_slow_case for %s\n", pas_heap_config_kind_get_string(config.kind));
+
/* In the non-memalign case, we can happily handle zero-sized allocations with aligned_size
being 0. This works because the heap's 0 size class is just a copy of the minalign size
class. But we cannot do this properly if the 0 size class has to have some alignment. That's
@@ -184,6 +193,9 @@
PAS_ASSERT(alignment == 1 || !designation_mode);
+ if (verbose)
+ pas_log("in impl_inline_only for %s\n", pas_heap_config_kind_get_string(config.kind));
+
if (!pas_is_power_of_2(alignment))
return pas_allocation_result_create_failure();
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_try_reallocate.h (282898 => 282899)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_try_reallocate.h 2021-09-23 00:40:13 UTC (rev 282898)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_try_reallocate.h 2021-09-23 00:52:25 UTC (rev 282899)
@@ -311,7 +311,7 @@
if (!begin)
return allocate_callback(heap, new_count, allocate_callback_arg);
- if (PAS_UNLIKELY(pas_debug_heap_is_enabled())) {
+ if (PAS_UNLIKELY(pas_debug_heap_is_enabled(config.kind))) {
void* raw_result;
size_t size;
bool did_overflow;